From 0b73e74af371c466ec1daf68e4e05d4d08ca7aa5 Mon Sep 17 00:00:00 2001 From: Alex Constantin-Gomez <ac3419@ic.ac.uk> Date: Sat, 8 Feb 2020 17:37:32 +0000 Subject: [PATCH] backend v1 --- main.go | 104 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 91 insertions(+), 13 deletions(-) diff --git a/main.go b/main.go index 73eebfb..45923ab 100644 --- a/main.go +++ b/main.go @@ -3,8 +3,11 @@ package main import ( "encoding/json" "fmt" + "io/ioutil" "log" "net/http" + "strconv" + "sync" ) /******************** DATA STRUCTS ***********************/ @@ -19,8 +22,8 @@ type Player struct { type Game struct { ID int Channels [2]chan string - Player1 string - Player2 string + Player1 string + Player2 string } // Move represents a move in the game @@ -32,21 +35,25 @@ type Move struct { } var ( - gameData map[int]Game - idCounter int + gameData map[int]*Game + gameDataMutex sync.RWMutex + + idCounter int + idCounterMutex sync.RWMutex ) /************** MAIN FUNCTION **********************/ func main() { // Initialise global variables - gameData = make(map[int]Game) + gameData = make(map[int]*Game) http.HandleFunc("/", hello) http.HandleFunc("/move", move) http.HandleFunc("/create", createGame) http.HandleFunc("/join", joinGame) + http.HandleFunc("/wait", checkJoinGame) err := http.ListenAndServe(":8080", nil) if err != nil { @@ -69,7 +76,9 @@ func move(w http.ResponseWriter, r *http.Request) { log.Println("could not decode json data into Move struct") } + gameDataMutex.RLock() game := gameData[move.GameID] + gameDataMutex.RUnlock() sendChan := game.Channels[move.Player] recChan := game.Channels[1-move.Player] sendChan <- move.MoveData @@ -83,26 +92,95 @@ func move(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, response) } +// Creates a game with one player func createGame(w http.ResponseWriter, r *http.Request) { - //jsonData := readJsonFromRequest(r) + jsonData := readJsonFromRequest(r) + + var playerData struct { + Player string `json:"player"` + } + err := json.Unmarshal(jsonData, &playerData) + if err != nil { + log.Println("could not decode json data into Move struct") + } newGameID := generateID() - newGame := Game{ - ID: newGameID, - // Player1: , - // Player2: , + newGame := &Game{ + ID: newGameID, + Channels: [2]chan string{make(chan string, 1), make(chan string, 1)}, + Player1: playerData.Player, } + gameDataMutex.Lock() gameData[newGameID] = newGame + gameDataMutex.Unlock() - fmt.Fprintf(w, "hello") + fmt.Fprintf(w, strconv.Itoa(newGame.ID)) } +// Adds a 2nd player to a game, given the game id func joinGame(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, "hello") + jsonData := readJsonFromRequest(r) + + var join struct { + GameID int `json:"game_id"` + Player string `json:"player"` + } + err := json.Unmarshal(jsonData, &join) + if err != nil { + log.Println("could not decode json data") + } + + gameDataMutex.RLock() + game, found := gameData[join.GameID] + gameDataMutex.RUnlock() + if !found { + fmt.Fprintf(w, "error: could not find game ID in checkJoinGame endpoint") + return + } + + game.Player2 = join.Player + game.Channels[0] <- join.Player + fmt.Fprintf(w, game.Player1) +} + +// Returns if the 2nd player has joined the game yet +func checkJoinGame(w http.ResponseWriter, r *http.Request) { + jsonData := readJsonFromRequest(r) + + var gameID struct { + GameID int `json:"game_id"` + } + err := json.Unmarshal(jsonData, &gameID) + if err != nil { + log.Println("could not decode json data") + } + + // check if player 2 joined + gameDataMutex.RLock() + game, found := gameData[gameID.GameID] + gameDataMutex.RUnlock() + if !found { + log.Println("error: could not find game ID in checkJoinGame endpoint") + return + } + p2 := <-game.Channels[0] + + fmt.Fprintf(w, p2) // send player2's name } /************** Helper functions *******************/ func generateID() int { - return idCounter + 1 + idCounterMutex.Lock() + defer idCounterMutex.Unlock() + idCounter++ + return idCounter +} + +func readJsonFromRequest(r *http.Request) []byte { + data, err := ioutil.ReadAll(r.Body) + if err != nil { + log.Println("could not read json from body") + } + return data } -- GitLab