summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSanto Cariotti <santo@dcariotti.me>2025-04-18 16:09:32 +0200
committerSanto Cariotti <santo@dcariotti.me>2025-04-18 16:09:32 +0200
commit7c5a6176b27b6b0c0c3ef8a4aedbdec871391a80 (patch)
tree5ebfc9b402b8aa941ab9617b5f3842071edafedf
parent0b4fb251efdfd2fba7cd6154f5f59bd61ede15f1 (diff)
Add type on messages between peers
-rw-r--r--pkg/p2p/network.go4
-rw-r--r--pkg/p2p/network_test.go6
-rw-r--r--pkg/ui/multiplayer/multiplayer.go20
-rw-r--r--pkg/ui/views/game.go6
-rw-r--r--pkg/ui/views/game_keymap.go2
-rw-r--r--pkg/ui/views/game_moves.go12
6 files changed, 34 insertions, 16 deletions
diff --git a/pkg/p2p/network.go b/pkg/p2p/network.go
index 0acbdfa..13c99b0 100644
--- a/pkg/p2p/network.go
+++ b/pkg/p2p/network.go
@@ -14,6 +14,7 @@ import (
// `Message` represents a structured message on this network.
type Message struct {
+ Type []byte `json:"type"`
Timestamp int64 `json:"timestamp"`
Source NetworkID `json:"source"`
Payload []byte `json:"payload"`
@@ -107,7 +108,7 @@ func (n *TCPNetwork) AddPeer(remoteID NetworkID, addr string) {
}
// Send methods is used to send a message to a specified remote peer
-func (n *TCPNetwork) Send(remoteID NetworkID, payload []byte) error {
+func (n *TCPNetwork) Send(remoteID NetworkID, messageType []byte, payload []byte) error {
n.Lock()
peerConn, exists := n.connections[remoteID]
n.Unlock()
@@ -123,6 +124,7 @@ func (n *TCPNetwork) Send(remoteID NetworkID, payload []byte) error {
}
message := Message{
+ Type: messageType,
Payload: payload,
Source: n.id,
Timestamp: time.Now().Unix(),
diff --git a/pkg/p2p/network_test.go b/pkg/p2p/network_test.go
index fd5dde0..15d0d8e 100644
--- a/pkg/p2p/network_test.go
+++ b/pkg/p2p/network_test.go
@@ -44,10 +44,10 @@ func TestPeerToPeerCommunication(t *testing.T) {
time.Sleep(5 * time.Second)
// Send a message from peer-1 to peer-2
- err := peer1.Send("peer-2", []byte("Hey from peer-1!"))
+ err := peer1.Send("peer-2", []byte("simple-msg"), []byte("Hey from peer-1!"))
assert.NoError(t, err)
- err = peer2.Send("peer-1", []byte("Hey from peer-2!"))
+ err = peer2.Send("peer-1", []byte("simple-msg"), []byte("Hey from peer-2!"))
assert.NoError(t, err)
// Allow some time for the message to be received and handled
@@ -74,6 +74,6 @@ func TestSendFailure(t *testing.T) {
_ = NewTCPNetwork("peer-2", peer2Opts)
// Attempt to send a message without establishing a connection first
- err := peer1.Send("peer-2", []byte("Message without connection"))
+ err := peer1.Send("peer-2", []byte("msg"), []byte("Message without connection"))
assert.Error(t, err, "Expected error when sending to a non-connected peer")
}
diff --git a/pkg/ui/multiplayer/multiplayer.go b/pkg/ui/multiplayer/multiplayer.go
index ac3bc7a..98ccfb4 100644
--- a/pkg/ui/multiplayer/multiplayer.go
+++ b/pkg/ui/multiplayer/multiplayer.go
@@ -8,6 +8,18 @@ import (
"go.uber.org/zap"
)
+type MoveType string
+
+const (
+ AbandonGameMessage MoveType = "abandon"
+ MoveGameMessage MoveType = "new-move"
+)
+
+type GameMove struct {
+ Type []byte `json:"type"`
+ Payload []byte `json:"payload"`
+}
+
type GameNetwork struct {
server *p2p.TCPNetwork
me p2p.NetworkID
@@ -37,8 +49,8 @@ func (n *GameNetwork) Me() p2p.NetworkID {
return n.me
}
-func (n *GameNetwork) Send(payload []byte) error {
- return n.server.Send(n.peer, payload)
+func (n *GameNetwork) Send(messageType []byte, payload []byte) error {
+ return n.server.Send(n.peer, messageType, payload)
}
func (n *GameNetwork) AddPeer(remoteID p2p.NetworkID, addr string) {
@@ -55,9 +67,9 @@ func (n *GameNetwork) Close() error {
logger, _ := logger.GetLogger()
if err != nil {
- logger.Sugar().Errorf("Can't close connection for network '%+v': %s", n, err.Error())
+ logger.Sugar().Errorf("can't close connection for network '%+v': %s", n, err.Error())
} else {
- logger.Sugar().Infof("Connection closed for network '%+v'", n)
+ logger.Sugar().Infof("connection closed for network '%+v'", n)
}
return err
diff --git a/pkg/ui/views/game.go b/pkg/ui/views/game.go
index 4e8cc87..3742101 100644
--- a/pkg/ui/views/game.go
+++ b/pkg/ui/views/game.go
@@ -28,7 +28,7 @@ type GameModel struct {
game *database.Game
network *multiplayer.GameNetwork
chessGame *chess.Game
- incomingMoves chan string
+ incomingMoves chan multiplayer.GameMove
turn int
availableMovesList list.Model
}
@@ -56,7 +56,7 @@ func NewGameModel(width, height int, currentGameID int, network *multiplayer.Gam
currentGameID: currentGameID,
network: network,
chessGame: chess.NewGame(chess.UseNotation(chess.UCINotation{})),
- incomingMoves: make(chan string),
+ incomingMoves: make(chan multiplayer.GameMove),
turn: 0,
availableMovesList: moveList,
}
@@ -122,7 +122,7 @@ func (m GameModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.err = err
} else {
m.turn++
- m.network.Send([]byte(moveStr))
+ m.network.Send([]byte("new-move"), []byte(moveStr))
m.err = nil
}
cmds = append(cmds, m.getMoves(), m.updateMovesListCmd())
diff --git a/pkg/ui/views/game_keymap.go b/pkg/ui/views/game_keymap.go
index 00b062f..283a69c 100644
--- a/pkg/ui/views/game_keymap.go
+++ b/pkg/ui/views/game_keymap.go
@@ -44,7 +44,7 @@ func (m GameModel) handleKeyMsg(msg tea.KeyMsg) (GameModel, tea.Cmd) {
outcome = string(chess.WhiteWon)
}
- m.network.Send([]byte("🏳️"))
+ m.network.Send([]byte("abandon"), []byte("🏳️"))
return m, m.endGame(outcome)
}
case key.Matches(msg, m.keys.Quit):
diff --git a/pkg/ui/views/game_moves.go b/pkg/ui/views/game_moves.go
index daf24e6..ea1fa02 100644
--- a/pkg/ui/views/game_moves.go
+++ b/pkg/ui/views/game_moves.go
@@ -4,6 +4,7 @@ import (
"fmt"
"github.com/boozec/rahanna/pkg/p2p"
+ "github.com/boozec/rahanna/pkg/ui/multiplayer"
"github.com/charmbracelet/bubbles/list"
tea "github.com/charmbracelet/bubbletea"
"github.com/notnil/chess"
@@ -25,16 +26,19 @@ func (i item) FilterValue() string { return i.title }
func (m *GameModel) getMoves() tea.Cmd {
m.network.AddReceiveFunction(func(msg p2p.Message) {
- payload := string(msg.Payload)
- m.incomingMoves <- payload
+ gm := multiplayer.GameMove{
+ Type: msg.Type,
+ Payload: msg.Payload,
+ }
+ m.incomingMoves <- gm
})
return func() tea.Msg {
move := <-m.incomingMoves
- if move == "🏳️" {
+ if multiplayer.MoveType(string(move.Type)) == multiplayer.AbandonGameMessage {
return EndGameMsg{abandoned: true}
}
- return ChessMoveMsg(move)
+ return ChessMoveMsg(string(move.Payload))
}
}