diff --git a/client/cmd/main.go b/client/cmd/main.go index 3961872..7247b82 100644 --- a/client/cmd/main.go +++ b/client/cmd/main.go @@ -5,6 +5,7 @@ import ( "errors" "flag" "fmt" + "io" "log" "time" @@ -21,6 +22,53 @@ var ( serverHostOverride = flag.String("server_host_override", "x.test.example.com", "The server name used to verify the hostname returned by the TLS handshake") ) +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) + } + }) +} + func _main() error { var opts []grpc.DialOption if *tls { @@ -47,17 +95,31 @@ func _main() error { client := proto.NewGameWorldClient(conn) + // 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{}, + } + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - pong, err := client.Ping(ctx, &proto.SessionInfo{}) + pong, err := cs.Client.Ping(ctx, cs.SessionInfo) if err != nil { - log.Fatalf("%v.Ping -> %v", client, err) + log.Fatalf("%v.Ping -> %v", cs.Client, err) } + //stream, err := messageStream(client, sessionInfo) + log.Printf("%#v", pong) - app := tview.NewApplication() pages := tview.NewPages() pages.AddPage("splash", @@ -82,6 +144,9 @@ func _main() error { pages.AddPage("main", mainPage, true, false) + msgView := tview.NewTextView() + cs.messagesView = msgView + gamePage := tview.NewGrid(). SetRows(1, 40, 3). SetColumns(-1, -1). @@ -93,7 +158,7 @@ func _main() error { tview.NewTextView().SetTextAlign(tview.AlignRight).SetText("TODO server status"), 0, 1, 1, 1, 1, 1, false). AddItem( - tview.NewTextView().SetText("TODO game messages"), + msgView, 1, 0, 1, 1, 10, 20, false). AddItem( tview.NewTextView().SetText("TODO detail window"), @@ -104,6 +169,8 @@ func _main() error { pages.AddPage("game", gamePage, true, false) + go messages(cs) + return app.SetRoot(pages, true).SetFocus(pages).Run() } diff --git a/proto/hermeticum.proto b/proto/hermeticum.proto index 36d52d7..3194c75 100644 --- a/proto/hermeticum.proto +++ b/proto/hermeticum.proto @@ -62,8 +62,9 @@ message ClientMessage { GLOBAL = 4; // the system sent out a PSA } - ClientMessageType cmt = 1; + ClientMessageType type = 1; optional string speaker = 2; + string text = 3; } message MapData { diff --git a/server/cmd/main.go b/server/cmd/main.go index bbc0c17..0edf93c 100644 --- a/server/cmd/main.go +++ b/server/cmd/main.go @@ -6,6 +6,7 @@ import ( "fmt" "log" "net" + "time" "github.com/vilmibm/hermeticum/proto" "google.golang.org/grpc" @@ -68,6 +69,19 @@ func (s *gameWorldServer) Ping(ctx context.Context, _ *proto.SessionInfo) (*prot return pong, nil } +func (s *gameWorldServer) Messages(si *proto.SessionInfo, stream proto.GameWorld_MessagesServer) error { + for x := 0; x < 20; x++ { + msg := &proto.ClientMessage{} + speaker := "snoozy" + msg.Speaker = &speaker + msg.Type = proto.ClientMessage_WHISPER + msg.Text = fmt.Sprintf("have message %d", x) + stream.Send(msg) + time.Sleep(2 * time.Second) + } + return nil +} + func (s *gameWorldServer) Register(ctx context.Context, auth *proto.AuthInfo) (*proto.SessionInfo, error) { // TODO return nil, nil