Scrap 2-player waiting room and make it simple.
This commit is contained in:
parent
aac428baab
commit
78ddd4f90f
1
api_types/player_info.go
Normal file
1
api_types/player_info.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package api_types
|
@ -8,8 +8,8 @@ import (
|
|||||||
|
|
||||||
type Game struct {
|
type Game struct {
|
||||||
id uuid.UUID
|
id uuid.UUID
|
||||||
players [2]Player
|
players []*Player
|
||||||
currentTurnPlayer Player
|
currentTurnPlayer *Player
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -26,23 +26,24 @@ func NewGame() *Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (game Game) getPlayer1() *Player {
|
func (game Game) getPlayer1() *Player {
|
||||||
return &game.players[0]
|
return game.players[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (game Game) getPlayer2() *Player {
|
func (game Game) getPlayer2() *Player {
|
||||||
return &game.players[1]
|
return game.players[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (game *Game) handle() {
|
func (game *Game) Handle() {
|
||||||
defer log.Println("Game ", game.id, ": handle() ended")
|
defer log.Println("Game ", game.id, ": handle() ended")
|
||||||
|
|
||||||
|
log.Println("Game ", game.id, " started")
|
||||||
<-game.getPlayer1().wsConnEstablished
|
<-game.getPlayer1().wsConnEstablished
|
||||||
log.Println("WS connection for player 1 established")
|
log.Println("WS connection for player 1 established")
|
||||||
<-game.getPlayer2().wsConnEstablished
|
<-game.getPlayer2().wsConnEstablished
|
||||||
log.Println("WS connection for player 2 established")
|
log.Println("WS connection for player 2 established")
|
||||||
|
|
||||||
gameState := PlayerToMove
|
gameState := PlayerToMove
|
||||||
game.currentTurnPlayer = *game.getPlayer1()
|
game.currentTurnPlayer = game.getPlayer1()
|
||||||
var move *Move
|
var move *Move
|
||||||
var receivedMessage []byte
|
var receivedMessage []byte
|
||||||
|
|
||||||
@ -96,14 +97,6 @@ func (game *Game) handle() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (game *Game) addPlayersToGame(players [2]Player) {
|
func (game *Game) AddPlayersToGame(player *Player) {
|
||||||
log.Printf("Adding players %s and %s to new game", players[0].Uuid.String(), players[1].Uuid.String())
|
game.players = append(game.players, player)
|
||||||
|
|
||||||
for i := range players {
|
|
||||||
players[i].InGame = true
|
|
||||||
}
|
|
||||||
|
|
||||||
game.players = players
|
|
||||||
|
|
||||||
go game.handle()
|
|
||||||
}
|
}
|
@ -1,60 +0,0 @@
|
|||||||
package chess
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Lobby struct {
|
|
||||||
players map[uuid.UUID]*Player
|
|
||||||
mutex sync.Mutex
|
|
||||||
}
|
|
||||||
|
|
||||||
var lobbyInstance *Lobby = nil
|
|
||||||
|
|
||||||
func GetLobby() *Lobby {
|
|
||||||
if lobbyInstance == nil {
|
|
||||||
lobbyInstance = newLobby()
|
|
||||||
}
|
|
||||||
|
|
||||||
return lobbyInstance
|
|
||||||
}
|
|
||||||
|
|
||||||
func newLobby() *Lobby {
|
|
||||||
return &Lobby{
|
|
||||||
players: make(map[uuid.UUID]*Player, 0),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Lobby) RegisterPlayer(player *Player) {
|
|
||||||
l.players[player.Uuid] = player
|
|
||||||
|
|
||||||
var playersToBeAddedToGame []Player
|
|
||||||
|
|
||||||
for _, player := range l.players {
|
|
||||||
if !player.InGame {
|
|
||||||
playersToBeAddedToGame = append(playersToBeAddedToGame, *player)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(playersToBeAddedToGame) < 2 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
game := NewGame()
|
|
||||||
game.addPlayersToGame([2]Player(playersToBeAddedToGame[:2]))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Lobby) GetPlayer(playerID uuid.UUID) (*Player, bool) {
|
|
||||||
player, found := l.players[playerID]
|
|
||||||
return player, found
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Lobby) Lock() {
|
|
||||||
l.mutex.Lock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Lobby) Unlock() {
|
|
||||||
l.mutex.Unlock()
|
|
||||||
}
|
|
@ -14,12 +14,11 @@ type Player struct {
|
|||||||
InGame bool
|
InGame bool
|
||||||
wsConnEstablished chan bool
|
wsConnEstablished chan bool
|
||||||
context context.Context
|
context context.Context
|
||||||
|
|
||||||
JoinedLobby chan bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type PlayerInfo struct {
|
type PlayerInfo struct {
|
||||||
PlayerID uuid.UUID `json:"playerID"`
|
PlayerID uuid.UUID `json:"playerID"`
|
||||||
|
LobbyID uuid.UUID `json:"lobbyID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPlayer(uuid uuid.UUID) *Player {
|
func NewPlayer(uuid uuid.UUID) *Player {
|
||||||
@ -28,7 +27,6 @@ func NewPlayer(uuid uuid.UUID) *Player {
|
|||||||
Conn: nil,
|
Conn: nil,
|
||||||
InGame: false,
|
InGame: false,
|
||||||
wsConnEstablished: make(chan bool),
|
wsConnEstablished: make(chan bool),
|
||||||
JoinedLobby: make(chan bool),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,23 +7,43 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Lobby struct {
|
type Lobby struct {
|
||||||
uuid uuid.UUID
|
Uuid uuid.UUID
|
||||||
players []*chess.Player
|
players []*chess.Player
|
||||||
|
|
||||||
|
Game chess.Game
|
||||||
|
|
||||||
|
PlayerJoined chan bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEmptyLobbyByUUID(uuid uuid.UUID) *Lobby {
|
func NewEmptyLobbyWithUUID(uuid uuid.UUID) *Lobby {
|
||||||
return &Lobby{uuid: uuid}
|
return &Lobby{
|
||||||
|
Uuid: uuid,
|
||||||
|
Game: *chess.NewGame(),
|
||||||
|
PlayerJoined: make(chan bool),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Lobby) AddPlayer(player *chess.Player) {
|
func (w *Lobby) AddPlayerAndStartGameIfFull(player *chess.Player) {
|
||||||
w.players = append(w.players, player)
|
w.players = append(w.players, player)
|
||||||
player.JoinedLobby <- true
|
w.Game.AddPlayersToGame(player)
|
||||||
|
if w.IsFull() {
|
||||||
|
go w.Game.Handle()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Lobby) IsFull() bool {
|
func (w *Lobby) IsFull() bool {
|
||||||
return len(w.players) == 2
|
return len(w.players) == 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *Lobby) GetPlayerByUUID(uuid uuid.UUID) (*chess.Player, bool) {
|
||||||
|
for _, player := range l.players {
|
||||||
|
if player.Uuid == uuid {
|
||||||
|
return player, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
func (l *Lobby) GetPlayer1() *chess.Player {
|
func (l *Lobby) GetPlayer1() *chess.Player {
|
||||||
return l.players[0]
|
return l.players[0]
|
||||||
}
|
}
|
||||||
|
@ -29,13 +29,16 @@ func (r *LobbyRegistry) GetLobbyForPlayer() *Lobby {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newLobby := NewEmptyLobbyByUUID(uuid.New())
|
newLobby := NewEmptyLobbyWithUUID(uuid.New())
|
||||||
r.addNewLobby(newLobby)
|
r.addNewLobby(newLobby)
|
||||||
return newLobby
|
return newLobby
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *LobbyRegistry) addNewLobby(lobby *Lobby) uuid.UUID {
|
func (r *LobbyRegistry) GetLobbyByUUID(uuid uuid.UUID) *Lobby {
|
||||||
uuid := uuid.New()
|
return r.lobbies[uuid]
|
||||||
r.lobbies[uuid] = lobby
|
}
|
||||||
return uuid
|
|
||||||
|
func (r *LobbyRegistry) addNewLobby(lobby *Lobby) uuid.UUID {
|
||||||
|
r.lobbies[lobby.Uuid] = lobby
|
||||||
|
return lobby.Uuid
|
||||||
}
|
}
|
||||||
|
72
main.go
72
main.go
@ -2,11 +2,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"local/m/mchess_server/chess"
|
"local/m/mchess_server/chess"
|
||||||
|
lobbies "local/m/mchess_server/lobby_registry"
|
||||||
"local/m/mchess_server/usher"
|
"local/m/mchess_server/usher"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/gin-gonic/autotls"
|
"github.com/gin-gonic/autotls"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@ -37,41 +41,29 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var mut sync.Mutex
|
||||||
|
|
||||||
func registerForRandomGame(c *gin.Context) {
|
func registerForRandomGame(c *gin.Context) {
|
||||||
|
|
||||||
/*
|
|
||||||
What should be done:
|
|
||||||
1. Register player
|
|
||||||
2. Check if there is a game open that lacks one player
|
|
||||||
3. Fill open game, then respond with player id and game id.
|
|
||||||
OR
|
|
||||||
|
|
||||||
1. Register player
|
|
||||||
2. If there is no open game, open a game and wait for a second player to join
|
|
||||||
3. Only after a second player joins, respond with player id and game id.
|
|
||||||
*/
|
|
||||||
|
|
||||||
player := chess.NewPlayer(uuid.New())
|
player := chess.NewPlayer(uuid.New())
|
||||||
|
|
||||||
usher := usher.GetUsher()
|
usher := usher.GetUsher()
|
||||||
|
|
||||||
|
mut.Lock()
|
||||||
lobby := usher.WelcomeNewPlayer(player)
|
lobby := usher.WelcomeNewPlayer(player)
|
||||||
usher.AddPlayerToLobby(player, lobby)
|
usher.AddPlayerToLobbyAndStartGameIfFull(player, lobby)
|
||||||
|
mut.Unlock()
|
||||||
|
|
||||||
// Counter point to this approach:
|
info := chess.PlayerInfo{
|
||||||
// Waiting for two players might not be necessary.
|
|
||||||
// Just open the lobby and respond with lobby/game id and player id
|
|
||||||
// The waiting can be done in the game handler until both players opened a ws connection
|
|
||||||
usher.WaitForTwoPlayersInLobby(lobby)
|
|
||||||
|
|
||||||
log.Println("responding with player id ", player.Uuid)
|
|
||||||
|
|
||||||
c.IndentedJSON(http.StatusOK, chess.PlayerInfo{
|
|
||||||
PlayerID: player.Uuid,
|
PlayerID: player.Uuid,
|
||||||
})
|
LobbyID: lobby.Uuid,
|
||||||
|
}
|
||||||
|
log.Println("responding with info ", info)
|
||||||
|
|
||||||
|
c.Header("Access-Control-Allow-Origin", "*")
|
||||||
|
c.IndentedJSON(http.StatusOK, info)
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerWebSocketConnection(c *gin.Context) {
|
func registerWebSocketConnection(c *gin.Context) {
|
||||||
webSocketConn, err := websocket.Accept(c.Writer, c.Request, nil)
|
webSocketConn, err := websocket.Accept(c.Writer, c.Request, &websocket.AcceptOptions{OriginPatterns: []string{"localhost:*"}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
return
|
return
|
||||||
@ -80,23 +72,27 @@ func registerWebSocketConnection(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func waitForAndHandlePlayerID(ctx context.Context, conn websocket.Conn) {
|
func waitForAndHandlePlayerID(ctx context.Context, conn websocket.Conn) {
|
||||||
msgType, id, err := conn.Read(ctx)
|
msgType, msg, err := conn.Read(ctx)
|
||||||
|
|
||||||
log.Println("read from websocket: ", msgType, id, err)
|
|
||||||
log.Println("id as string", string(id))
|
|
||||||
|
|
||||||
uuid, err := uuid.ParseBytes(id)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
errorMessage := fmt.Sprintf("Reading from websocket connection did not work: %s", err)
|
||||||
conn.Close(websocket.StatusCode(400), err.Error())
|
log.Println(errorMessage)
|
||||||
|
conn.Close(websocket.StatusCode(400), errorMessage)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// since we cannot use the lobby anymore (it does not exist anymore after this change) the client needs to
|
log.Println("read from websocket: ", msgType, string(msg), err)
|
||||||
// send game id and player id so we can make the connection to the player
|
|
||||||
//lobby := chess.GetLobby()
|
|
||||||
|
|
||||||
player, found := lobby.GetPlayer(uuid)
|
var info chess.PlayerInfo
|
||||||
|
err = json.Unmarshal(msg, &info)
|
||||||
|
if err != nil {
|
||||||
|
errorMessage := fmt.Sprintf("Unmarshaling message did not work: %s", err)
|
||||||
|
log.Println(errorMessage)
|
||||||
|
conn.Close(websocket.StatusCode(400), errorMessage)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
lobby := lobbies.GetLobbyRegistry().GetLobbyByUUID(info.LobbyID)
|
||||||
|
player, found := lobby.GetPlayerByUUID(info.PlayerID)
|
||||||
if !found {
|
if !found {
|
||||||
conn.Close(websocket.StatusCode(400), "player not found")
|
conn.Close(websocket.StatusCode(400), "player not found")
|
||||||
return
|
return
|
||||||
|
@ -26,14 +26,6 @@ func (u *Usher) WelcomeNewPlayer(player *chess.Player) *lobbies.Lobby {
|
|||||||
return lobby
|
return lobby
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *Usher) AddPlayerToLobby(player *chess.Player, lobby *lobbies.Lobby) {
|
func (u *Usher) AddPlayerToLobbyAndStartGameIfFull(player *chess.Player, lobby *lobbies.Lobby) {
|
||||||
lobby.AddPlayer(player)
|
lobby.AddPlayerAndStartGameIfFull(player)
|
||||||
}
|
|
||||||
|
|
||||||
func (u *Usher) WaitForTwoPlayersInLobby(lobby *lobbies.Lobby) {
|
|
||||||
player1 := lobby.GetPlayer1()
|
|
||||||
<-player1.JoinedLobby
|
|
||||||
|
|
||||||
player2 := lobby.GetPlayer2()
|
|
||||||
<-player2.JoinedLobby
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user