Skip to content

Commit

Permalink
chore: extract for loop logic
Browse files Browse the repository at this point in the history
  • Loading branch information
djpiper28 committed Sep 19, 2024
1 parent 4ac8bca commit 3fc0c2b
Showing 1 changed file with 163 additions and 154 deletions.
317 changes: 163 additions & 154 deletions backend/network/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,195 +173,204 @@ func (c *WsConnection) listenAndHandle() error {

// Start listening and handling
for {
msg, err := c.conn.Receive()
err := c.readMessage(gid)
if err != nil {
c.Close()
return errors.New("Cannot read from websocket")
return err
}
}
}

handler := UnknownCommand
startTime := time.Now()
err = DecodeRpcMessage(msg, RpcCommandHandlers{
ChangeSettingsHandler: func(msg RpcChangeSettingsMsg) error {
handler = "Change Settings"
game, err := gameRepo.Repo.GetGame(gid)
if err != nil {
return errors.New("Cannot find the game")
}
func (c *WsConnection) readMessage(gid uuid.UUID) error {
msg, err := c.conn.Receive()
if err != nil {
c.Close()
return errors.New("Cannot read from websocket")
}

if game.GameOwnerId != c.PlayerId {
return errors.New("You cannot change the settings as you are not the game owner")
}
handler := UnknownCommand
startTime := time.Now()
err = DecodeRpcMessage(msg, RpcCommandHandlers{
ChangeSettingsHandler: func(msg RpcChangeSettingsMsg) error {
handler = "Change Settings"
game, err := gameRepo.Repo.GetGame(gid)
if err != nil {
return errors.New("Cannot find the game")
}

err = gameRepo.Repo.ChangeSettings(gid, msg.Settings)
if err != nil {
return err
}
if game.GameOwnerId != c.PlayerId {
return errors.New("You cannot change the settings as you are not the game owner")
}

broadcastMessage, err := EncodeRpcMessage(msg)
if err != nil {
return err
}
err = gameRepo.Repo.ChangeSettings(gid, msg.Settings)
if err != nil {
return err
}

go GlobalConnectionManager.Broadcast(gid, broadcastMessage)
return nil
},
PingHandler: func() error {
handler = PingCommand
c.lock.Lock()
defer c.lock.Unlock()
broadcastMessage, err := EncodeRpcMessage(msg)
if err != nil {
return err
}

c.LastPingTime = time.Now()
c.PingFlag = false
return nil
},
StartGameHandler: func() error {
handler = "Start Game"
game, err := gameRepo.Repo.GetGame(gid)
if err != nil {
return errors.New("Cannot find the game")
}
go GlobalConnectionManager.Broadcast(gid, broadcastMessage)
return nil
},
PingHandler: func() error {
handler = PingCommand
c.lock.Lock()
defer c.lock.Unlock()

c.LastPingTime = time.Now()
c.PingFlag = false
return nil
},
StartGameHandler: func() error {
handler = "Start Game"
game, err := gameRepo.Repo.GetGame(gid)
if err != nil {
return errors.New("Cannot find the game")
}

if game.GameOwnerId != c.PlayerId {
return errors.New("Only the game owner can start the game")
}
if game.GameOwnerId != c.PlayerId {
return errors.New("Only the game owner can start the game")
}

info, err := gameRepo.Repo.StartGame(gid)
if err != nil {
return err
}
info, err := gameRepo.Repo.StartGame(gid)
if err != nil {
return err
}

totalPlays := 0
for _, plays := range info.PlayersPlays {
if len(plays) > 0 {
totalPlays++
}
totalPlays := 0
for _, plays := range info.PlayersPlays {
if len(plays) > 0 {
totalPlays++
}
}

for playerId, hand := range info.PlayerHands {
handCopy := make([]gameLogic.WhiteCard, len(hand))
for i, val := range hand {
handCopy[i] = *val
}

playsCopy := make([]gameLogic.WhiteCard, 0)
for i, val := range info.PlayersPlays[playerId] {
playsCopy[i] = *val
}

roundInfo := RpcRoundInformationMsg{
CurrentCardCzarId: info.CurrentCardCzarId,
YourHand: handCopy,
RoundNumber: info.RoundNumber,
BlackCard: *info.CurrentBlackCard,
YourPlays: playsCopy,
TotalPlays: totalPlays,
}

encodedMessage, err := EncodeRpcMessage(roundInfo)
if err != nil {
return err
}

go GlobalConnectionManager.SendToPlayer(c.GameId, playerId, encodedMessage)
for playerId, hand := range info.PlayerHands {
handCopy := make([]gameLogic.WhiteCard, len(hand))
for i, val := range hand {
handCopy[i] = *val
}
return nil
},
PlayCardsHandler: func(msg RpcPlayCardsMsg) error {
handler = "Play Cards"

info, err := gameRepo.Repo.PlayerPlayCards(c.GameId, c.PlayerId, msg.CardIds)
if err != nil {
return err
playsCopy := make([]gameLogic.WhiteCard, 0)
for i, val := range info.PlayersPlays[playerId] {
playsCopy[i] = *val
}

cardPlayedMsg := RpcOnCardPlayedMsg{
PlayerId: c.PlayerId,
roundInfo := RpcRoundInformationMsg{
CurrentCardCzarId: info.CurrentCardCzarId,
YourHand: handCopy,
RoundNumber: info.RoundNumber,
BlackCard: *info.CurrentBlackCard,
YourPlays: playsCopy,
TotalPlays: totalPlays,
}

broadcastMessage, err := EncodeRpcMessage(cardPlayedMsg)
encodedMessage, err := EncodeRpcMessage(roundInfo)
if err != nil {
return err
}

go GlobalConnectionManager.Broadcast(gid, broadcastMessage)
if info.MovedToNextCardCzarPhase {
go GlobalConnectionManager.MoveToCzarJudgingPhase(gid, info.CzarJudingPhaseInfo)
}
return nil
},
CzarSelectCardHandler: func(msg RpcCzarSelectCardMsg) error {
handler = "Czar Selects A Card"
go GlobalConnectionManager.SendToPlayer(c.GameId, playerId, encodedMessage)
}
return nil
},
PlayCardsHandler: func(msg RpcPlayCardsMsg) error {
handler = "Play Cards"

res, err := gameRepo.Repo.CzarSelectsCard(c.GameId, c.PlayerId, msg.Cards)
if err != nil {
return err
}
info, err := gameRepo.Repo.PlayerPlayCards(c.GameId, c.PlayerId, msg.CardIds)
if err != nil {
return err
}

var wg sync.WaitGroup
for pid, hand := range res.Hands {
wg.Add(1)
go func(pid uuid.UUID, hand []*gameLogic.WhiteCard) {
defer wg.Done()

var msg RpcMessage
if res.GameEnded {
msg = RpcOnGameEnd{
WinnerId: res.WinnerId,
}
} else {
msg = RpcOnWhiteCardPlayPhase{YourHand: hand,
BlackCard: res.NewBlackCard,
CardCzarId: res.NewCzarId,
WinnerId: res.WinnerId}
}
encodedMsg, err := EncodeRpcMessage(msg)
if err != nil {
logger.Logger.Error("Cannot encode message to send to player")
}
cardPlayedMsg := RpcOnCardPlayedMsg{
PlayerId: c.PlayerId,
}

go GlobalConnectionManager.SendToPlayer(c.GameId, pid, encodedMsg)
}(pid, hand)
}
broadcastMessage, err := EncodeRpcMessage(cardPlayedMsg)
if err != nil {
return err
}

wg.Wait()
return nil
},
})
go GlobalConnectionManager.Broadcast(gid, broadcastMessage)
if info.MovedToNextCardCzarPhase {
go GlobalConnectionManager.MoveToCzarJudgingPhase(gid, info.CzarJudingPhaseInfo)
}
return nil
},
CzarSelectCardHandler: func(msg RpcCzarSelectCardMsg) error {
handler = "Czar Selects A Card"

microSeconds := time.Since(startTime).Microseconds()
go gameRepo.AddCommandExecuted(int(time.Since(startTime).Microseconds()))
res, err := gameRepo.Repo.CzarSelectsCard(c.GameId, c.PlayerId, msg.Cards)
if err != nil {
return err
}

if handler != PingCommand {
logger.Logger.Infof("Command Handler \"%s\" | %s | %dµs",
handler,
gid,
microSeconds)
}
var wg sync.WaitGroup
for pid, hand := range res.Hands {
wg.Add(1)
go func(pid uuid.UUID, hand []*gameLogic.WhiteCard) {
defer wg.Done()

if handler == UnknownCommand {
go gameRepo.AddUnknownCommand()
}
var msg RpcMessage
if res.GameEnded {
msg = RpcOnGameEnd{
WinnerId: res.WinnerId,
}
} else {
msg = RpcOnWhiteCardPlayPhase{YourHand: hand,
BlackCard: res.NewBlackCard,
CardCzarId: res.NewCzarId,
WinnerId: res.WinnerId}
}
encodedMsg, err := EncodeRpcMessage(msg)
if err != nil {
logger.Logger.Error("Cannot encode message to send to player")
}

if err != nil {
logger.Logger.Error("Error processing message",
"err", err,
"gameId", c.GameId,
"playerId", c.PlayerId)
go gameRepo.AddCommandFailed()

var message RpcCommandErrorMsg
message.Reason = err.Error()
encodedMessage, err := EncodeRpcMessage(message)
if err != nil {
logger.Logger.Error("Cannot encode the error message",
"err", err)
continue
go GlobalConnectionManager.SendToPlayer(c.GameId, pid, encodedMsg)
}(pid, hand)
}

go c.Send(encodedMessage)
wg.Wait()
return nil
},
})

microSeconds := time.Since(startTime).Microseconds()
go gameRepo.AddCommandExecuted(int(time.Since(startTime).Microseconds()))

if handler != PingCommand {
logger.Logger.Infof("Command Handler \"%s\" | %s | %dµs",
handler,
gid,
microSeconds)
}

if handler == UnknownCommand {
go gameRepo.AddUnknownCommand()
}

if err != nil {
logger.Logger.Error("Error processing message",
"err", err,
"gameId", c.GameId,
"playerId", c.PlayerId)
go gameRepo.AddCommandFailed()

var message RpcCommandErrorMsg
message.Reason = err.Error()
encodedMessage, err := EncodeRpcMessage(message)
if err != nil {
logger.Logger.Error("Cannot encode the error message",
"err", err)
return nil
}

go c.Send(encodedMessage)
}

return nil
}

func (c *WsConnection) ListenAndHandle(g *ConnectionManager) {
Expand Down

0 comments on commit 3fc0c2b

Please sign in to comment.