Skip to content

Commit

Permalink
send player move when both selected
Browse files Browse the repository at this point in the history
  • Loading branch information
loan-mgt committed May 19, 2024
1 parent 53e129a commit ca7dd88
Show file tree
Hide file tree
Showing 13 changed files with 469 additions and 893 deletions.
69 changes: 51 additions & 18 deletions internal/controllers/wsController.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"log"
"net/http"
"rcp/elite/internal/handlers"
"rcp/elite/internal/services"

"github.com/gorilla/websocket"
)
Expand All @@ -31,43 +32,75 @@ func MainController(w http.ResponseWriter, r *http.Request) {
}
defer conn.Close()

handleWebSocket(conn)
}

func handleWebSocket(conn *websocket.Conn) {
for {
messageType, message, err := conn.ReadMessage()
if err != nil {
log.Println(err)
return
handleReadError(err, conn)
break
}

log.Printf("Received message: %s type: %s\n", message, string(rune(messageType)))

var response []byte

var msg Message
err = json.Unmarshal(message, &msg)
if err != nil {
if err := json.Unmarshal(message, &msg); err != nil {
log.Println("Error parsing message:", err)
continue
}

switch msg.Type {
case "game-search":
response, err = handlers.HandleGameSearch(message)
case "move":
response, err = handlers.HandleMove(message)
default:
log.Println("Unknown message type:", msg.Type)
err = handleMessage(msg, message, conn)
if err != nil {
handleWriteError(err, conn)
continue
}
}
}

func handleReadError(err error, conn *websocket.Conn) {
if websocket.IsCloseError(err, websocket.CloseGoingAway) {
log.Println("Client disconnected: going away")
player, err := services.GetPlayerFromConn(conn)
if err != nil {
log.Println("Error writing response to client:", err)
continue
log.Printf("Uanble to find player to remove: %v", err)
} else {
err = services.RemovePlayer(player.Name)
log.Printf("Unable to remove player: %v", err)
}
} else if websocket.IsUnexpectedCloseError(err, websocket.CloseAbnormalClosure, websocket.CloseNormalClosure, websocket.CloseNoStatusReceived) {
log.Printf("Client disconnected unexpectedly: %v", err)
} else {
log.Printf("Error reading message: %v", err)
}
}

err = conn.WriteMessage(websocket.TextMessage, response)
func handleWriteError(err error, conn *websocket.Conn) {
if websocket.IsCloseError(err, websocket.CloseGoingAway) {
log.Println("Client disconnected: going away")
player, err := services.GetPlayerFromConn(conn)
if err != nil {
log.Println("Error writing response to client:", err)
continue
log.Printf("Uanble to find player to remove: %v", err)
} else {
err = services.RemovePlayer(player.Name)
log.Printf("Unable to remove player: %v", err)
}
} else if websocket.IsUnexpectedCloseError(err, websocket.CloseAbnormalClosure, websocket.CloseNormalClosure, websocket.CloseNoStatusReceived) {
log.Printf("Client disconnected while sending message: %v", err)
} else {
log.Printf("Error writing response to client: %v", err)
}
}

func handleMessage(msg Message, originalMessage []byte, conn *websocket.Conn) error {
switch msg.Type {
case "game-search":
return handlers.HandleGameSearch(originalMessage, conn)
case "move":
return handlers.HandleMove(originalMessage, conn)
default:
log.Println("Unknown message type:", msg.Type)
return nil
}
}
99 changes: 61 additions & 38 deletions internal/handlers/gameSearchHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,77 +3,100 @@ package handlers
import (
"bytes"
"encoding/json"
"fmt"
"errors"
"log"

"github.com/gorilla/websocket"

"rcp/elite/internal/services"
"rcp/elite/internal/types"
"rcp/elite/internal/utils"
)

type Player struct {
ID string `json:"id"`
Name string `json:"name"`
Move string `json:"move"`
Flag string `json:"flag"`
Score int `json:"score"`
Conn *websocket.Conn `json:"conn"`
}
"github.com/gorilla/websocket"
)

func (p Player) String() string {
return fmt.Sprintf("Player{ID: %s, Name: %s, Move: %s, Flag: %s, Score: %d}", p.ID, p.Name, p.Move, p.Flag, p.Score)
type OpponentInfo struct {
Opponent *types.Player
}

type PlayersData struct {
Player Player
Opponent Player
Player *types.Player
Opponent *types.Player
Messenger
}

type GameSearchRequest struct {
Username string `json:"username"`
}

func HandleGameSearch(message []byte) ([]byte, error) {

func HandleGameSearch(message []byte, conn *websocket.Conn) error {
var request GameSearchRequest
err := json.Unmarshal(message, &request)
if err != nil {
log.Println("Error parsing message:", err)
return nil, err
return err
}

player1 := Player{
ID: "1",
Name: "Player 1",
Move: "rock",
Flag: "BE",
Score: 0,
Conn: nil, // Add the appropriate connection
}

player2 := Player{
ID: "2",
player := &types.Player{
Name: request.Username,
Move: "paper",
Move: "",
Flag: "FR",
Score: 0,
Conn: nil, // Add the appropriate connection
Conn: conn,
}

if !services.IsPlayerInGame(request.Username) && services.IsGameFull() {
return errors.New("no game available")
} else if !services.IsPlayerInGame(request.Username) {
err := services.AddPlayer(player)
if err != nil {
log.Println("Error adding player:", err)
return err
}
}

opponent, err := services.GetOpponent(request.Username)
if err != nil {
log.Println("Error getting opponent:", err)
} else {
log.Println("Opponent:", opponent)

opponentInfo := OpponentInfo{
Opponent: player,
}

var tplBuffer bytes.Buffer
err = utils.Templates.ExecuteTemplate(&tplBuffer, "opponent-info", opponentInfo)
if err != nil {
log.Println("Error executing template:", err)
return err
}

opponent.Conn.WriteMessage(websocket.TextMessage, tplBuffer.Bytes())

var tplBuffer2 bytes.Buffer
err = utils.Templates.ExecuteTemplate(&tplBuffer2, "opponent-panel", opponentInfo)
if err != nil {
log.Println("Error executing template:", err)
return err
}

opponent.Conn.WriteMessage(websocket.TextMessage, tplBuffer2.Bytes())
}

// Create a struct containing both players
players := PlayersData{
Player: player1,
Opponent: player2,
Player: player,
Opponent: opponent,
Messenger: Messenger{
Message: "Welcome",
},
}

// Parse the template
var tplBuffer bytes.Buffer
err = utils.Templates.ExecuteTemplate(&tplBuffer, "gameHome", players)
if err != nil {
log.Println("Error executing template:", err)
return nil, err
return err
}

return tplBuffer.Bytes(), nil

return conn.WriteMessage(websocket.TextMessage, tplBuffer.Bytes())
}
117 changes: 110 additions & 7 deletions internal/handlers/moveHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,135 @@ import (
"bytes"
"encoding/json"
"errors"
"fmt"
"log"
"rcp/elite/internal/services"
"rcp/elite/internal/utils"

"github.com/gorilla/websocket"
)

type MoveRequest struct {
Move string `json:"move"`
Move string
}

type MoveData struct {
TargetId string
Move string
}

type Messenger struct {
Message string
}

func HandleMove(message []byte) ([]byte, error) {
func HandleMove(message []byte, conn *websocket.Conn) error {
var request MoveRequest
err := json.Unmarshal(message, &request)
if err != nil {
log.Println("Error parsing message:", err)
return nil, err
return err
}

if request.Move != "rock" && request.Move != "paper" && request.Move != "scissor" {
return nil, errors.New("invalid move")
return errors.New("invalid move")
}

player, err := services.GetPlayerFromConn(conn)
if err != nil {
log.Println("Error unable to find player:", err)
return err
}

services.SetPlayerMove(player.Name, request.Move)

playerMoveData := MoveData{
TargetId: "player-selected-move",
Move: request.Move,
}

var tplBuffer bytes.Buffer
err = utils.Templates.ExecuteTemplate(&tplBuffer, "move", request)
err = utils.Templates.ExecuteTemplate(&tplBuffer, "move", playerMoveData)
if err != nil {
log.Println("Error executing template:", err)
return nil, err
return err
}

opponent, err := services.GetOpponent(player.Name)
if err != nil {
log.Println("Unalbe to get oppoent infos:", err)
} else {

if opponent.Move != "" {

opponent, err := services.GetOpponent(player.Name)
if err != nil {
log.Println("Failed getting opponent:", err)
} else {
err = sendMove(opponent.Conn, "opponent", request.Move)
if err != nil {
log.Println("Failed to send opponent move:", err)
}
err = sendMove(player.Conn, "opponent", opponent.Move)
if err != nil {
log.Println("Failed to send opponent move:", err)
}

}

} else {
messagePlayer := "Waiting for your opponent to make a move"
messageOpponent := fmt.Sprintf("%s is waiting on you, please select a move", player.Name)

if err := sendMessage(conn, messagePlayer); err != nil {
log.Println("Error sending message to player:", err)
}

opponent, err := services.GetOpponent(player.Name)
if err != nil {
log.Println("Failed getting opponent:", err)
} else {
if err := sendMessage(opponent.Conn, messageOpponent); err != nil {
log.Println("Error sending message to opponent:", err)
}
}

}

}

return conn.WriteMessage(websocket.TextMessage, tplBuffer.Bytes())
}

func sendMessage(conn *websocket.Conn, message string) error {

messenger := Messenger{
Message: message,
}

var tplBuffer bytes.Buffer
err := utils.Templates.ExecuteTemplate(&tplBuffer, "messenger", messenger)
if err != nil {
log.Println("Error executing template for opponent:", err)
return err
}

return conn.WriteMessage(websocket.TextMessage, tplBuffer.Bytes())

}

func sendMove(conn *websocket.Conn, to string, move string) error {
moveData := MoveData{
TargetId: fmt.Sprintf("%s-selected-move", to),
Move: move,
}

return tplBuffer.Bytes(), nil
var tplBufferOpponent bytes.Buffer
err := utils.Templates.ExecuteTemplate(&tplBufferOpponent, "move", moveData)
if err != nil {
log.Println("Error executing template for opponent:", err)
return err
}

return conn.WriteMessage(websocket.TextMessage, tplBufferOpponent.Bytes())

}
Loading

0 comments on commit ca7dd88

Please sign in to comment.