diff options
Diffstat (limited to 'pkg/ui/views/play_api.go')
-rw-r--r-- | pkg/ui/views/play_api.go | 93 |
1 files changed, 79 insertions, 14 deletions
diff --git a/pkg/ui/views/play_api.go b/pkg/ui/views/play_api.go index 62cd523..3846abe 100644 --- a/pkg/ui/views/play_api.go +++ b/pkg/ui/views/play_api.go @@ -8,6 +8,7 @@ import ( "os" "strconv" "strings" + "sync" "github.com/boozec/rahanna/internal/api/database" "github.com/boozec/rahanna/internal/logger" @@ -18,6 +19,7 @@ import ( type responseOk struct { Name string `json:"name"` + Type string `json:"type"` GameID int `json:"id"` IP string `json:"ip"` Port int `json:"int"` @@ -45,14 +47,31 @@ func (m *PlayModel) handlePlayResponse(msg playResponse) (tea.Model, tea.Cmd) { m.currentGameId = msg.Ok.GameID logger, _ := logger.GetLogger() - callbackCompleted := make(chan bool) - m.network = multiplayer.NewGameNetwork(fmt.Sprintf("%s-1", m.playName), fmt.Sprintf("%s:%d", msg.Ok.IP, msg.Ok.Port), p2p.DefaultHandshake, func(net.Conn) error { - close(callbackCompleted) + var wg sync.WaitGroup + var expectedPeers int + + switch msg.Ok.Type { + case string(database.SingleGameType): + expectedPeers = 1 + case string(database.PairGameType): + expectedPeers = 3 + default: + logger.Fatal("Type not recognized") + } + wg.Add(expectedPeers) + + handshakeCounter := 0 + m.network = multiplayer.NewGameNetwork(fmt.Sprintf("%s-1", m.playName), fmt.Sprintf("%s:%d", msg.Ok.IP, msg.Ok.Port), func(net.Conn) error { + handshakeCounter++ + if handshakeCounter <= expectedPeers && expectedPeers > 0 { + wg.Done() + } return nil - }, logger) + }, p2p.DefaultHandshake, logger) return m, func() tea.Msg { - <-callbackCompleted + wg.Wait() + return StartGameMsg{} } } @@ -67,21 +86,65 @@ func (m *PlayModel) handleGameResponse(msg database.Game) (tea.Model, tea.Cmd) { var ip []string var localID string + var expectedPeers int - if m.game.LastPlayer == 2 { - ip = strings.Split(m.game.IP2, ":") - localID = fmt.Sprintf("%s-2", m.game.Name) - } else { + switch m.game.LastPlayer { + case 1: ip = strings.Split(m.game.IP1, ":") localID = fmt.Sprintf("%s-1", m.game.Name) + + switch m.game.Type { + case database.SingleGameType: + expectedPeers = 1 + case database.PairGameType: + expectedPeers = 3 + } + + case 2: + ip = strings.Split(m.game.IP2, ":") + localID = fmt.Sprintf("%s-2", m.game.Name) + switch m.game.Type { + case database.SingleGameType: + expectedPeers = 0 + case database.PairGameType: + expectedPeers = 2 + } + + case 3: + ip = strings.Split(m.game.IP3, ":") + localID = fmt.Sprintf("%s-3", m.game.Name) + expectedPeers = 1 + + case 4: + ip = strings.Split(m.game.IP4, ":") + localID = fmt.Sprintf("%s-4", m.game.Name) + expectedPeers = 0 } + var wg sync.WaitGroup + + if m.gameToRestore != nil { + expectedPeers = 0 + } + + wg.Add(expectedPeers) + if len(ip) == 2 { localIP := ip[0] localPort, _ := strconv.ParseInt(ip[1], 10, 32) logger, _ := logger.GetLogger() - network := multiplayer.NewGameNetwork(localID, fmt.Sprintf("%s:%d", localIP, localPort), p2p.DefaultHandshake, p2p.DefaultHandshake, logger) + + handshakeCounter := 0 + network := multiplayer.NewGameNetwork(localID, fmt.Sprintf("%s:%d", localIP, localPort), func(conn net.Conn) error { + handshakeCounter++ + if handshakeCounter <= expectedPeers && expectedPeers > 0 { + wg.Done() + } + return nil + }, p2p.DefaultHandshake, logger) + + wg.Wait() return m, SwitchModelCmd(NewGameModel(m.width, m.height+1, m.game.ID, network, m.gameToRestore != nil)) } @@ -96,7 +159,7 @@ func (m *PlayModel) handleGamesResponse(msg []database.Game) (tea.Model, tea.Cmd return m, nil } -func (m *PlayModel) newGameCallback() tea.Cmd { +func (m *PlayModel) newGameCallback(gameType database.GameType) tea.Cmd { return func() tea.Msg { // Get authorization token authorization, err := getAuthorizationToken() @@ -114,7 +177,8 @@ func (m *PlayModel) newGameCallback() tea.Cmd { // Prepare request payload payload, err := json.Marshal(map[string]string{ - "ip": fmt.Sprintf("%s:%d", ip, port), + "ip": fmt.Sprintf("%s:%d", ip, port), + "type": string(gameType), }) if err != nil { return playResponse{Error: err.Error()} @@ -140,6 +204,7 @@ func (m *PlayModel) newGameCallback() tea.Cmd { // Decode successful response var response struct { Name string `json:"name"` + Type string `json:"type"` ID int `json:"id"` Error string `json:"error"` } @@ -147,7 +212,7 @@ func (m *PlayModel) newGameCallback() tea.Cmd { return playResponse{Error: fmt.Sprintf("Error decoding JSON: %v", err)} } - return playResponse{Ok: responseOk{Name: response.Name, GameID: response.ID, IP: ip, Port: port}} + return playResponse{Ok: responseOk{Name: response.Name, Type: response.Type, GameID: response.ID, IP: ip, Port: port}} } } @@ -169,8 +234,8 @@ func (m PlayModel) enterGame() tea.Cmd { // Prepare request payload payload, err := json.Marshal(map[string]string{ - "ip": fmt.Sprintf("%s:%d", ip, port), "name": m.namePrompt.Value(), + "ip": fmt.Sprintf("%s:%d", ip, port), }) if err != nil { return playResponse{Error: err.Error()} |