summaryrefslogtreecommitdiff
path: root/pkg/ui/views/play_api.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/ui/views/play_api.go')
-rw-r--r--pkg/ui/views/play_api.go93
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()}