Handle reconnection
reconnection works now if the rejoining player enters the passphrase again. Some bugs are still happening: 1. The rejoining client is not told the state of the board 2. Invalid moves are not handled by the client (not sure why though) 3. The still-connected client should be told, that the opponent disconnected. Then the client should show the passphrase again
This commit is contained in:
parent
efefa4ced5
commit
cce0aa8162
@ -7,6 +7,7 @@ import (
|
||||
"mchess_server/types"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
type Game struct {
|
||||
@ -15,6 +16,7 @@ type Game struct {
|
||||
players []*Player
|
||||
currentTurnPlayer *Player
|
||||
gameState int
|
||||
isBeingHandled bool
|
||||
}
|
||||
|
||||
const (
|
||||
@ -57,16 +59,28 @@ func (game *Game) prepare() {
|
||||
game.players[0].color = types.White
|
||||
game.players[1].color = types.Black
|
||||
|
||||
game.players[0].SetDisconnectCallback(game.playerDisconnected)
|
||||
game.players[1].SetDisconnectCallback(game.playerDisconnected)
|
||||
|
||||
err := game.notifyPlayersAboutGameStart()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (game *Game) StartHandling() {
|
||||
if game.isBeingHandled {
|
||||
return
|
||||
}
|
||||
|
||||
game.isBeingHandled = true
|
||||
go game.Handle()
|
||||
}
|
||||
|
||||
func (game *Game) Handle() {
|
||||
defer game.killGame()
|
||||
|
||||
game.prepare()
|
||||
game.prepare()
|
||||
|
||||
var receivedMove types.Move
|
||||
var err error
|
||||
@ -161,3 +175,11 @@ func (game Game) broadcastMove(move types.Move) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (game *Game) playerDisconnected(p *Player) {
|
||||
log.Println(string(p.color), " disconnected")
|
||||
playerLeft := lo.Filter(game.players, func(player *Player, _ int) bool {
|
||||
return player.color != p.color
|
||||
})
|
||||
game.players = playerLeft
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"errors"
|
||||
"log"
|
||||
"mchess_server/api"
|
||||
conn "mchess_server/connection"
|
||||
"mchess_server/connection"
|
||||
"mchess_server/types"
|
||||
|
||||
"github.com/google/uuid"
|
||||
@ -14,18 +14,22 @@ import (
|
||||
)
|
||||
|
||||
type Player struct {
|
||||
Uuid uuid.UUID
|
||||
Conn *conn.Connection
|
||||
InGame bool
|
||||
color types.ChessColor
|
||||
Uuid uuid.UUID
|
||||
Conn *connection.Connection
|
||||
InGame bool
|
||||
color types.ChessColor
|
||||
disconnectCallback func(p *Player)
|
||||
}
|
||||
|
||||
func NewPlayer(uuid uuid.UUID) *Player {
|
||||
return &Player{
|
||||
Uuid: uuid,
|
||||
Conn: conn.NewConnection(conn.WithContext(context.Background())),
|
||||
player := &Player{
|
||||
Uuid: uuid,
|
||||
Conn: connection.NewConnection(
|
||||
connection.WithContext(context.Background())),
|
||||
InGame: false,
|
||||
}
|
||||
|
||||
return player
|
||||
}
|
||||
|
||||
func (p Player) HasWebsocketConnection() bool {
|
||||
@ -36,6 +40,16 @@ func (p *Player) SetWebsocketConnection(ctx context.Context, ws *websocket.Conn)
|
||||
p.Conn.SetWebsocketConnection(ws)
|
||||
}
|
||||
|
||||
func (p *Player) SetDisconnectCallback(cb func(*Player)) {
|
||||
// Todo: Fucking complicated
|
||||
p.Conn.SetDisconnectCallback(p.PlayerDisconnectedCallback)
|
||||
p.disconnectCallback = cb
|
||||
}
|
||||
|
||||
func (p *Player) PlayerDisconnectedCallback() {
|
||||
p.disconnectCallback(p)
|
||||
}
|
||||
|
||||
func (p *Player) SendMoveAndPosition(move types.Move, boardPosition string) error {
|
||||
messageToSend, err := json.Marshal(api.WebsocketMessage{
|
||||
Type: api.MoveMessage,
|
||||
|
@ -12,6 +12,7 @@ type Connection struct {
|
||||
wsConnectionEstablished chan bool
|
||||
ctx context.Context
|
||||
buffer MessageBuffer
|
||||
disconnectCallback func()
|
||||
}
|
||||
|
||||
func NewConnection(options ...func(*Connection)) *Connection {
|
||||
@ -39,6 +40,18 @@ func WithContext(ctx context.Context) func(*Connection) {
|
||||
}
|
||||
}
|
||||
|
||||
func WithDisconnectCallback(cb func()) func(*Connection) {
|
||||
return func(c *Connection) {
|
||||
if cb != nil {
|
||||
c.disconnectCallback = cb
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (conn *Connection) SetDisconnectCallback(cb func()) {
|
||||
conn.disconnectCallback = cb
|
||||
}
|
||||
|
||||
func (conn *Connection) HasWebsocketConnection() bool {
|
||||
return conn.ws != nil
|
||||
}
|
||||
@ -57,7 +70,14 @@ func (conn *Connection) SetWebsocketConnection(ws *websocket.Conn) {
|
||||
|
||||
go func() {
|
||||
for {
|
||||
_, msg, _ := conn.ws.Read(conn.ctx)
|
||||
_, msg, err := conn.ws.Read(conn.ctx)
|
||||
if err != nil {
|
||||
log.Println("while reading from websocket: %w", err)
|
||||
if conn.disconnectCallback != nil {
|
||||
conn.disconnectCallback()
|
||||
}
|
||||
return
|
||||
}
|
||||
conn.buffer.Insert(string(msg))
|
||||
}
|
||||
}()
|
||||
|
@ -32,7 +32,7 @@ func newEmptyLobbyWithPassphrase() *Lobby {
|
||||
func (l *Lobby) AddPlayerAndStartGameIfFull(player *chess.Player) {
|
||||
l.Game.AddPlayersToGame(player)
|
||||
if l.IsFull() {
|
||||
go l.Game.Handle()
|
||||
l.Game.StartHandling()
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user