From 45fac78e068f3a4f4832cab441b61c6ffd42dea0 Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 9 Dec 2023 14:45:57 +0100 Subject: [PATCH] Introduce method to send status of board and player --- api/move.go | 14 ++++++++------ chess/game.go | 10 ++++++++-- chess/player.go | 37 +++++++++++++++++++++++++++++++++++-- main.go | 3 ++- 4 files changed, 53 insertions(+), 11 deletions(-) diff --git a/api/move.go b/api/move.go index 8d18031..b721482 100644 --- a/api/move.go +++ b/api/move.go @@ -6,16 +6,18 @@ import ( ) type WebsocketMessage struct { - Type MessageType `json:"messageType"` - Move *types.Move `json:"move,omitempty"` - Color *types.ChessColor `json:"color,omitempty"` - Reason *string `json:"reason,omitempty"` - Position *string `json:"position,omitempty"` + Type MessageType `json:"messageType"` + Move *types.Move `json:"move,omitempty"` + TurnColor *types.ChessColor `json:"turnColor,omitempty"` + PlayerColor *types.ChessColor `json:"playerColor,omitempty"` + Reason *string `json:"reason,omitempty"` + Position *string `json:"position,omitempty"` } type MessageType string const ( + PositionMessage MessageType = "position" MoveMessage MessageType = "move" InvalidMoveMessage MessageType = "invalidMove" ColorDetermined MessageType = "colorDetermined" @@ -36,7 +38,7 @@ func (m WebsocketMessage) IsValidMoveMessage() bool { } func GetColorDeterminedMessage(color types.ChessColor) ([]byte, error) { - return json.Marshal(WebsocketMessage{Type: ColorDetermined, Color: &color}) + return json.Marshal(WebsocketMessage{Type: ColorDetermined, TurnColor: &color}) } func GetInvalidMoveMessage(move types.Move, reason string) ([]byte, error) { diff --git a/chess/game.go b/chess/game.go index 800357a..ae6f0c5 100644 --- a/chess/game.go +++ b/chess/game.go @@ -1,6 +1,7 @@ package chess import ( + "context" "log" "math/rand" "mchess_server/api" @@ -8,6 +9,7 @@ import ( "github.com/google/uuid" "github.com/samber/lo" + "nhooyr.io/websocket" ) type Game struct { @@ -178,8 +180,12 @@ func (game Game) broadcastMove(move types.Move) error { func (game *Game) playerDisconnected(p *Player) { log.Println(string(p.color), " disconnected") - playerLeft := lo.Filter(game.players, func(player *Player, _ int) bool { + playerStillInGame := lo.Filter(game.players, func(player *Player, _ int) bool { return player.color != p.color }) - game.players = playerLeft + game.players = playerStillInGame +} + +func (game *Game) SetWebsocketConnectionFor(ctx context.Context, p *Player, ws *websocket.Conn) { + p.SetWebsocketConnectionAndSendBoardState(ctx, ws, game.board.PGN(), game.board.colorToMove) } diff --git a/chess/player.go b/chess/player.go index 8202fac..7d40491 100644 --- a/chess/player.go +++ b/chess/player.go @@ -16,7 +16,6 @@ import ( type Player struct { Uuid uuid.UUID Conn *connection.Connection - InGame bool color types.ChessColor disconnectCallback func(p *Player) } @@ -26,7 +25,6 @@ func NewPlayer(uuid uuid.UUID) *Player { Uuid: uuid, Conn: connection.NewConnection( connection.WithContext(context.Background())), - InGame: false, } return player @@ -40,6 +38,16 @@ func (p *Player) SetWebsocketConnection(ctx context.Context, ws *websocket.Conn) p.Conn.SetWebsocketConnection(ws) } +func (p *Player) SetWebsocketConnectionAndSendBoardState( + ctx context.Context, + ws *websocket.Conn, + boardPosition string, + turnColor types.ChessColor, +) { + p.SetWebsocketConnection(ctx, ws) + p.SendPosition(boardPosition, turnColor) +} + func (p *Player) SetDisconnectCallback(cb func(*Player)) { // Todo: Fucking complicated p.Conn.SetDisconnectCallback(p.PlayerDisconnectedCallback) @@ -50,6 +58,31 @@ func (p *Player) PlayerDisconnectedCallback() { p.disconnectCallback(p) } +func (p *Player) SendPosition(boardPosition string, turnColor types.ChessColor) error { + var pColor = p.color + if p.color == "" { // we default to white if we do not know the color yet + pColor = types.White + } + + messageToSend, err := json.Marshal(api.WebsocketMessage{ + Type: api.PositionMessage, + TurnColor: &turnColor, + PlayerColor: &pColor, + Position: &boardPosition, + }) + if err != nil { + log.Println("Error while marshalling: ", err) + return err + } + + err = p.writeMessage(messageToSend) + if err != nil { + log.Println("Error during message writing:", err) + return err + } + return nil +} + func (p *Player) SendMoveAndPosition(move types.Move, boardPosition string) error { messageToSend, err := json.Marshal(api.WebsocketMessage{ Type: api.MoveMessage, diff --git a/main.go b/main.go index fbc24f0..bd19b4f 100644 --- a/main.go +++ b/main.go @@ -151,6 +151,7 @@ func waitForAndHandlePlayerID(ctx context.Context, conn *websocket.Conn) { lobby := lobbies.GetLobbyRegistry().GetLobbyByUUID(*info.LobbyID) if lobby == nil { conn.Close(websocket.StatusCode(400), "lobby not found") + return } player, found := lobby.GetPlayerByUUID(*info.PlayerID) @@ -161,6 +162,6 @@ func waitForAndHandlePlayerID(ctx context.Context, conn *websocket.Conn) { if player.Conn.HasWebsocketConnection() { player.Conn.Close("closing existing connection") } - player.SetWebsocketConnection(ctx, conn) + lobby.Game.SetWebsocketConnectionFor(ctx, player, conn) log.Println("player after setting connection: ", player) }