diff --git a/client/cmd/main.go b/client/cmd/main.go index f82b011..b6338fc 100644 --- a/client/cmd/main.go +++ b/client/cmd/main.go @@ -24,7 +24,17 @@ 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 { +type ClientState struct { + App *tview.Application + Client proto.GameWorldClient + SessionInfo *proto.SessionInfo + MaxMessages int + messagesView *tview.TextView + messages []*proto.ClientMessage + cmdStream proto.GameWorld_CommandsClient +} + +func (cs *ClientState) Messages() error { ctx, cancel := context.WithCancel(context.Background()) defer cancel() stream, err := cs.Client.Messages(ctx, cs.SessionInfo) @@ -46,16 +56,6 @@ func messages(cs *ClientState) error { return nil } -type ClientState struct { - App *tview.Application - Client proto.GameWorldClient - SessionInfo *proto.SessionInfo - MaxMessages int - messagesView *tview.TextView - messages []*proto.ClientMessage - cmdStream proto.GameWorld_CommandsClient -} - func (cs *ClientState) HandleInput(input string) error { var verb string rest := input @@ -213,6 +213,8 @@ func _main() error { pages.SwitchToPage("game") app.SetFocus(commandInput) + // TODO error handle + go cs.Messages() } // TODO login and register pages should refuse blank entries @@ -278,8 +280,6 @@ func _main() error { pages.AddPage("game", gamePage, true, false) - go messages(cs) - return app.SetRoot(pages, true).SetFocus(pages).Run() } diff --git a/server/cmd/main.go b/server/cmd/main.go index 33987ce..fe724d4 100644 --- a/server/cmd/main.go +++ b/server/cmd/main.go @@ -7,7 +7,7 @@ import ( "io" "log" "net" - "time" + "sync" "github.com/vilmibm/hermeticum/proto" "github.com/vilmibm/hermeticum/server/db" @@ -56,10 +56,15 @@ func _main() (err error) { type gameWorldServer struct { proto.UnimplementedGameWorldServer + + mu sync.Mutex // for msgRouter + msgRouter map[string]func(*proto.ClientMessage) error } func newServer() *gameWorldServer { - s := &gameWorldServer{} + s := &gameWorldServer{ + msgRouter: make(map[string]func(*proto.ClientMessage) error), + } return s } @@ -73,15 +78,28 @@ func (s *gameWorldServer) Commands(stream proto.GameWorld_CommandsServer) error if err != nil { return err } - fmt.Printf("DBG %#v\n", cmd) - // TODO FOR NOW, just find the session's associated message stream and do an echo (which requires doing a session storage solution first) + sid := cmd.SessionInfo.SessionID + send := s.msgRouter[sid] + + msg := &proto.ClientMessage{ + Type: proto.ClientMessage_OVERHEARD, + Text: fmt.Sprintf("%s sent command %s with args %s", + sid, cmd.Verb, cmd.Rest), + } + + speaker := "ECHO" + msg.Speaker = &speaker + + err = send(msg) + if err != nil { + log.Printf("failed to send %v to %s: %s", msg, sid, err) + } // TODO find the user who ran action via SessionInfo // TODO get area of effect, which should include the sender // TODO dispatch the command to each affected object } - return nil } func (s *gameWorldServer) Ping(ctx context.Context, _ *proto.SessionInfo) (*proto.Pong, error) { @@ -93,16 +111,13 @@ func (s *gameWorldServer) Ping(ctx context.Context, _ *proto.SessionInfo) (*prot } func (s *gameWorldServer) Messages(si *proto.SessionInfo, stream proto.GameWorld_MessagesServer) error { - for x := 0; x < 100; x++ { - msg := &proto.ClientMessage{} - speaker := "snoozy" - msg.Speaker = &speaker - msg.Type = proto.ClientMessage_WHISPER - msg.Text = fmt.Sprintf("hi this is message %d. by the way i am a horse. neigh neigh neigh neigh neigh neigh neigh neigh neigh neigh neigh neigh", x) - stream.Send(msg) - time.Sleep(500 * time.Millisecond) + s.mu.Lock() + s.msgRouter[si.SessionID] = stream.Send + s.mu.Unlock() + + // TODO this is clearly bad but it works. I should refactor this so that messages are received on a channel. + for { } - return nil } func (s *gameWorldServer) Register(ctx context.Context, auth *proto.AuthInfo) (si *proto.SessionInfo, err error) {