2022-07-07 22:12:22 +00:00
package main
import (
2022-07-08 04:07:34 +00:00
"context"
"errors"
"flag"
2022-07-07 22:12:22 +00:00
"fmt"
2022-07-09 07:15:24 +00:00
"io"
2022-07-07 22:12:22 +00:00
"log"
2022-07-08 04:07:34 +00:00
"time"
2022-07-08 05:18:52 +00:00
"github.com/rivo/tview"
2022-07-08 04:07:34 +00:00
"github.com/vilmibm/hermeticum/proto"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
var (
tls = flag . Bool ( "tls" , false , "Connection uses TLS if true, else plain TCP" )
caFile = flag . String ( "ca_file" , "" , "The file containing the CA root cert file" )
serverAddr = flag . String ( "addr" , "localhost:6666" , "The server address in the format of host:port" )
serverHostOverride = flag . String ( "server_host_override" , "x.test.example.com" , "The server name used to verify the hostname returned by the TLS handshake" )
2022-07-07 22:12:22 +00:00
)
2022-07-09 07:15:24 +00:00
func messages ( cs * ClientState ) error {
ctx , cancel := context . WithTimeout ( context . Background ( ) , 10 * time . Second )
defer cancel ( )
stream , err := cs . Client . Messages ( ctx , cs . SessionInfo )
if err != nil {
return err
}
for {
msg , err := stream . Recv ( )
if err == io . EOF {
break
}
if err != nil {
return err
}
cs . AddMessage ( msg )
}
return nil
}
type ClientState struct {
App * tview . Application
Client proto . GameWorldClient
SessionInfo * proto . SessionInfo
MaxMessages int
messagesView * tview . TextView
messages [ ] * proto . ClientMessage
}
func ( cs * ClientState ) AddMessage ( msg * proto . ClientMessage ) {
// TODO i don't like this function
cs . messages = append ( cs . messages , msg )
if len ( cs . messages ) > cs . MaxMessages {
cs . messages = cs . messages [ 1 : len ( cs . messages ) - 1 ]
}
cs . App . QueueUpdateDraw ( func ( ) {
cs . messagesView . SetText ( "" )
for _ , msg := range cs . messages {
fmt . Fprintf ( cs . messagesView , "%#v\n" , msg )
}
} )
}
2022-07-07 22:12:22 +00:00
func _main ( ) error {
2022-07-08 04:07:34 +00:00
var opts [ ] grpc . DialOption
if * tls {
return errors . New ( "TODO tls unsupported" )
/ *
if * caFile == "" {
* caFile = data . Path ( "x509/ca_cert.pem" )
}
creds , err := credentials . NewClientTLSFromFile ( * caFile , * serverHostOverride )
if err != nil {
log . Fatalf ( "Failed to create TLS credentials %v" , err )
}
opts = append ( opts , grpc . WithTransportCredentials ( creds ) )
* /
} else {
opts = append ( opts , grpc . WithTransportCredentials ( insecure . NewCredentials ( ) ) )
}
conn , err := grpc . Dial ( * serverAddr , opts ... )
if err != nil {
return fmt . Errorf ( "fail to dial: %w" , err )
}
defer conn . Close ( )
client := proto . NewGameWorldClient ( conn )
2022-07-09 07:15:24 +00:00
// TODO registration and login stuff
app := tview . NewApplication ( )
// TODO make a NewClientState
cs := & ClientState {
App : app ,
SessionInfo : & proto . SessionInfo { } ,
Client : client ,
MaxMessages : 15 , // TODO for testing
messages : [ ] * proto . ClientMessage { } ,
}
2022-07-08 04:07:34 +00:00
ctx , cancel := context . WithTimeout ( context . Background ( ) , 10 * time . Second )
defer cancel ( )
2022-07-09 07:15:24 +00:00
pong , err := cs . Client . Ping ( ctx , cs . SessionInfo )
2022-07-08 04:07:34 +00:00
if err != nil {
2022-07-09 07:15:24 +00:00
log . Fatalf ( "%v.Ping -> %v" , cs . Client , err )
2022-07-08 04:07:34 +00:00
}
2022-07-07 22:12:22 +00:00
2022-07-09 07:15:24 +00:00
//stream, err := messageStream(client, sessionInfo)
2022-07-08 04:07:34 +00:00
log . Printf ( "%#v" , pong )
2022-07-07 22:12:22 +00:00
2022-07-08 05:18:52 +00:00
pages := tview . NewPages ( )
pages . AddPage ( "splash" ,
tview . NewModal ( ) .
AddButtons ( [ ] string { "hey. let's go" } ) .
SetDoneFunc ( func ( _ int , _ string ) {
pages . SwitchToPage ( "main" )
2022-07-08 05:56:47 +00:00
app . ResizeToFullScreen ( pages )
2022-07-08 05:18:52 +00:00
} ) . SetText ( "h e r m e t i c u m" ) ,
2022-07-08 05:56:47 +00:00
true ,
2022-07-08 05:18:52 +00:00
true )
mainPage := tview . NewList ( ) .
2022-07-08 05:56:47 +00:00
AddItem ( "jack in" , "connect using an existing account" , '1' , func ( ) {
pages . SwitchToPage ( "game" )
} ) .
2022-07-08 05:18:52 +00:00
AddItem ( "rez a toon" , "create a new account" , '2' , nil ) .
AddItem ( "open the hood" , "client configuration" , '3' , nil ) .
AddItem ( "get outta here" , "quit the client" , '4' , func ( ) {
app . Stop ( )
} )
2022-07-08 05:56:47 +00:00
pages . AddPage ( "main" , mainPage , true , false )
2022-07-09 07:15:24 +00:00
msgView := tview . NewTextView ( )
cs . messagesView = msgView
2022-07-08 05:56:47 +00:00
gamePage := tview . NewGrid ( ) .
SetRows ( 1 , 40 , 3 ) .
SetColumns ( - 1 , - 1 ) .
SetBorders ( true ) .
AddItem (
tview . NewTextView ( ) . SetTextAlign ( tview . AlignLeft ) . SetText ( "h e r m e t i c u m" ) ,
0 , 0 , 1 , 1 , 1 , 1 , false ) .
AddItem (
tview . NewTextView ( ) . SetTextAlign ( tview . AlignRight ) . SetText ( "TODO server status" ) ,
0 , 1 , 1 , 1 , 1 , 1 , false ) .
AddItem (
2022-07-09 07:15:24 +00:00
msgView ,
2022-07-08 05:56:47 +00:00
1 , 0 , 1 , 1 , 10 , 20 , false ) .
AddItem (
tview . NewTextView ( ) . SetText ( "TODO detail window" ) ,
1 , 1 , 1 , 1 , 10 , 10 , false ) .
AddItem (
tview . NewTextView ( ) . SetText ( "TODO input" ) ,
2 , 0 , 1 , 2 , 1 , 30 , false )
pages . AddPage ( "game" , gamePage , true , false )
2022-07-08 05:18:52 +00:00
2022-07-09 07:15:24 +00:00
go messages ( cs )
2022-07-08 05:18:52 +00:00
return app . SetRoot ( pages , true ) . SetFocus ( pages ) . Run ( )
2022-07-07 22:12:22 +00:00
}
func main ( ) {
err := _main ( )
if err != nil {
log . Fatal ( err . Error ( ) )
}
}