diff --git a/ui.go b/exampleclient/ui.go similarity index 99% rename from ui.go rename to exampleclient/ui.go index 21716ed..022ba6c 100644 --- a/ui.go +++ b/exampleclient/ui.go @@ -1,4 +1,4 @@ -package main +package exampleclient import ( "encoding/json" diff --git a/websocket_client.go b/exampleclient/websocket_client.go similarity index 75% rename from websocket_client.go rename to exampleclient/websocket_client.go index 75e0e50..11c9ab1 100644 --- a/websocket_client.go +++ b/exampleclient/websocket_client.go @@ -1,15 +1,16 @@ -package main +package exampleclient import ( "fmt" "log" "github.com/gorilla/websocket" + "github.com/marianogappa/truco/server" "github.com/marianogappa/truco/truco" "github.com/nsf/termbox-go" ) -func player(playerID int, address string) { +func Player(playerID int, address string) { ui := NewUI() err := termbox.Init() @@ -26,14 +27,14 @@ func player(playerID int, address string) { } defer conn.Close() - if err := wsSend(conn, NewMessageHello(playerID)); err != nil { + if err := server.WsSend(conn, server.NewMessageHello(playerID)); err != nil { log.Println(err) return } lastRound := 0 for { - gameState, err := wsReadMessage[truco.GameState, MessageHeresGameState](conn, MessageTypeHeresGameState) + gameState, err := server.WsReadMessage[truco.GameState, server.MessageHeresGameState](conn, server.MessageTypeHeresGameState) if err != nil { log.Println(err) return @@ -68,8 +69,8 @@ func player(playerID int, address string) { break } - msg, _ := NewMessageAction(action) - if err := wsSend(conn, msg); err != nil { + msg, _ := server.NewMessageAction(action) + if err := server.WsSend(conn, msg); err != nil { log.Println(err) return } diff --git a/main.go b/main.go index 49b8c3b..06e74fa 100644 --- a/main.go +++ b/main.go @@ -4,15 +4,17 @@ import ( "fmt" "os" -) -// TODO: there's a bug that exists in most Truco games: it should be possible to throw a card and say truco at the same time + "github.com/marianogappa/truco/exampleclient" + "github.com/marianogappa/truco/server" +) func main() { if len(os.Args) < 2 { - fmt.Println("usage: truco server|player1|player2 [address]") - fmt.Println("Define the PORT environment variable to change the default port (8080).") - return + fmt.Println("usage: truco server") + fmt.Println("usage: truco player1|player2 [address]") + fmt.Println("Define the PORT environment variable for truco server to change the default port (8080).") + os.Exit(0) } port := os.Getenv("PORT") if port == "" { @@ -27,11 +29,11 @@ func main() { arg := os.Args[1] switch arg { case "server": - serve(port) + server.New(port).Start() case "player1": - player(0, address) + exampleclient.Player(0, address) case "player2": - player(1, address) + exampleclient.Player(1, address) default: fmt.Println("Invalid argument. Please provide either server or client.") } diff --git a/websocket_common.go b/server/websocket_common.go similarity index 79% rename from websocket_common.go rename to server/websocket_common.go index c219537..162e53b 100644 --- a/websocket_common.go +++ b/server/websocket_common.go @@ -1,4 +1,4 @@ -package main +package server import ( "encoding/json" @@ -8,7 +8,7 @@ import ( "github.com/gorilla/websocket" ) -func wsSend(conn *websocket.Conn, message any) error { +func WsSend(conn *websocket.Conn, message any) error { bs, err := json.Marshal(message) if err != nil { log.Printf("Failed to marshal message: %v", err) @@ -19,7 +19,7 @@ func wsSend(conn *websocket.Conn, message any) error { return err } -func wsReadMessage[U any, T IWebsocketMessage[U]](conn *websocket.Conn, expectedType int) (*U, error) { +func WsReadMessage[U any, T IWebsocketMessage[U]](conn *websocket.Conn, expectedType int) (*U, error) { messageType, message, err := conn.ReadMessage() if messageType != websocket.TextMessage { return nil, fmt.Errorf("Expected text message, got %d", messageType) @@ -27,10 +27,10 @@ func wsReadMessage[U any, T IWebsocketMessage[U]](conn *websocket.Conn, expected if err != nil { return nil, fmt.Errorf("Failed to read message from client: %v", err) } - return wsDeserializeMessage[U, T](message, expectedType) + return WsDeserializeMessage[U, T](message, expectedType) } -func wsDeserializeMessage[U any, T IWebsocketMessage[U]](message []byte, expectedType int) (*U, error) { +func WsDeserializeMessage[U any, T IWebsocketMessage[U]](message []byte, expectedType int) (*U, error) { var m T if err := json.Unmarshal(message, &m); err != nil { return nil, fmt.Errorf("Failed to unmarshal message: %v", err) diff --git a/websocket_messages.go b/server/websocket_messages.go similarity index 99% rename from websocket_messages.go rename to server/websocket_messages.go index 8ee9d44..af20e31 100644 --- a/websocket_messages.go +++ b/server/websocket_messages.go @@ -1,4 +1,4 @@ -package main +package server import ( "encoding/json" diff --git a/websocket_server.go b/server/websocket_server.go similarity index 86% rename from websocket_server.go rename to server/websocket_server.go index 41ce613..e4a4472 100644 --- a/websocket_server.go +++ b/server/websocket_server.go @@ -1,4 +1,4 @@ -package main +package server import ( "encoding/json" @@ -10,17 +10,12 @@ import ( "github.com/marianogappa/truco/truco" ) -// Define WebSocket upgrader var upgrader = websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true }, } -func serve(port string) { - NewServer(port).Start() -} - // TODO: resources shouldn't be shared between goroutines! It's not panicking due to insufficient testing for now. type server struct { gameState *truco.GameState @@ -28,7 +23,7 @@ type server struct { players []*websocket.Conn } -func NewServer(port string) *server { +func New(port string) *server { return &server{gameState: truco.New(), port: port, players: []*websocket.Conn{nil, nil}} } @@ -48,7 +43,7 @@ func (s *server) handleWebSocket(w http.ResponseWriter, r *http.Request) { } defer conn.Close() - playerID, err := wsReadMessage[int, MessageHello](conn, MessageTypeHello) + playerID, err := WsReadMessage[int, MessageHello](conn, MessageTypeHello) if err != nil { log.Println(err) return @@ -65,7 +60,7 @@ func (s *server) handleWebSocket(w http.ResponseWriter, r *http.Request) { s.players[*playerID] = conn msg, _ := NewMessageHeresGameState(*s.gameState) - if err := wsSend(conn, msg); err != nil { + if err := WsSend(conn, msg); err != nil { log.Println(err) return } @@ -89,7 +84,7 @@ func (s *server) handleWebSocket(w http.ResponseWriter, r *http.Request) { switch wsMessage.Type { case MessageTypeAction: log.Println("Got action message:", string(message)) - action, err := wsDeserializeMessage[truco.Action, MessageAction](message, MessageTypeAction) + action, err := WsDeserializeMessage[truco.Action, MessageAction](message, MessageTypeAction) if err != nil { log.Println(err) return @@ -106,7 +101,7 @@ func (s *server) handleWebSocket(w http.ResponseWriter, r *http.Request) { msg, _ := NewMessageHeresGameState(*s.gameState) for i, playerConn := range s.players { log.Println("Sending game state to player", i) - if err := wsSend(playerConn, msg); err != nil { + if err := WsSend(playerConn, msg); err != nil { log.Println(err) return } @@ -115,7 +110,7 @@ func (s *server) handleWebSocket(w http.ResponseWriter, r *http.Request) { log.Println("Got state request message:", string(message)) msg, _ := NewMessageHeresGameState(*s.gameState) - if err := wsSend(conn, msg); err != nil { + if err := WsSend(conn, msg); err != nil { log.Println(err) return }