From d7ea636fe47884161e12e55314d32e337def0546 Mon Sep 17 00:00:00 2001 From: Evgeny Kovalev Date: Sat, 22 Jul 2023 19:19:30 +0300 Subject: [PATCH] fix to Websockets, working player, working sync, working server --- internal/gameServer/gameServer.go | 24 +++++++++++++++++-- internal/player/player.go | 25 ++++++++++++++++++-- internal/room/room.go | 19 ++++++++-------- internal/server/server.go | 35 +++++++++++++++++----------- main.go | 38 ++++++++++++++++++++++++++++++- 5 files changed, 114 insertions(+), 27 deletions(-) diff --git a/internal/gameServer/gameServer.go b/internal/gameServer/gameServer.go index 7ac0a54..f8fea47 100644 --- a/internal/gameServer/gameServer.go +++ b/internal/gameServer/gameServer.go @@ -24,11 +24,14 @@ type GameServer struct { playerConns map[*player.Player]bool // Notify Game Server a New Player - connection chan *player.Player + Connection chan *player.Player //Quit the loops correctly and shut down the Game Server Shutdown chan bool + //1 Second Update planning + OneSecond chan bool + //sync threads WG sync.WaitGroup } @@ -41,20 +44,37 @@ func (m *GameServer) Init(logger *utils.Logger, config *config.S_Config) { m.maxPlayers = m.Config.MaxPlayers m.Shutdown = make(chan bool) + m.OneSecond = make(chan bool) m.currentLobbies = 0 m.currentPlayers = 0 - m.WG.Add(1) + m.Connection = make(chan *player.Player) + + m.playerConns = make(map[*player.Player]bool) + + m.WG.Add(2) } func (m *GameServer) Update() { for { select { + case pl := <-m.Connection: + m.playerConns[pl] = true + + go pl.Receiver() + case <-m.Shutdown: m.ShutdownServer() m.WG.Done() + + case <-m.OneSecond: + fmt.Println("OneSecond yikes") + fmt.Println(m.playerConns) + default: + // default actions + } } } diff --git a/internal/player/player.go b/internal/player/player.go index 1fe6313..504e2af 100644 --- a/internal/player/player.go +++ b/internal/player/player.go @@ -1,12 +1,16 @@ package player -import "github.com/gorilla/websocket" +import ( + "fmt" + + "github.com/gorilla/websocket" +) type Player struct { Name string `json:"Name"` Password string `json:"Password"` - //Connection WS variable TODO + //Connection Conn *websocket.Conn AuthString string `json:"AuthString"` @@ -22,3 +26,20 @@ type Player struct { Health int `json:"Health"` } + +func (pc *Player) Receiver() { + for { + + fmt.Println("ticker") + + _, command, err := pc.Conn.ReadMessage() + + if err != nil { + fmt.Println("pc err: " + err.Error()) + } + + pc.Conn.WriteMessage(websocket.TextMessage, []byte("otvet")) + fmt.Println(command) + + } +} diff --git a/internal/room/room.go b/internal/room/room.go index 6d9eac9..b8b8d7c 100644 --- a/internal/room/room.go +++ b/internal/room/room.go @@ -52,15 +52,16 @@ func (r *Room) TextAnnounce() { func (r *Room) Update() { for { - select { - case pj := <-r.join: - // player joins - case pl := <-r.leave: - // player leaves - case <-r.updateAll: - // update the room - } - + /* + select { + case pj := <-r.join: + // player joins + case pl := <-r.leave: + // player leaves + case <-r.updateAll: + // update the room + } + */ } } diff --git a/internal/server/server.go b/internal/server/server.go index 31e8fe3..36e0a8f 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -6,10 +6,13 @@ import ( "log" "net/http" + "daydev.org/shipsgs/internal/gameServer" "daydev.org/shipsgs/internal/player" "github.com/gorilla/websocket" ) +var GS *gameServer.GameServer + type Health struct { Health string `json:"Health"` Lobbies int `json:"Lobbies"` @@ -40,24 +43,28 @@ func wsEndpoint(w http.ResponseWriter, r *http.Request) { return } - player := player.Player{ + player := &player.Player{ Conn: conn, } player.Name = "Yale" - log.Println(r.RemoteAddr) + GS.Connection <- player - for { - messageType, p, err := conn.ReadMessage() - if err != nil { - log.Println(err) - return - } - if err := conn.WriteMessage(messageType, p); err != nil { - log.Println(err) - return + /* + log.Println(r.RemoteAddr) + + for { + messageType, p, err := conn.ReadMessage() + if err != nil { + log.Println(err) + return + } + if err := conn.WriteMessage(messageType, p); err != nil { + log.Println(err) + return + } } - } + */ } @@ -67,9 +74,11 @@ func setupRoutes() { } -func SetupAndRun(port string, sighup *chan bool) { +func SetupAndRun(port string, sighup *chan bool, gs *gameServer.GameServer) { setupRoutes() + GS = gs + srv := &http.Server{Addr: port} go func() { diff --git a/main.go b/main.go index 523656d..7740204 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,7 @@ import ( "fmt" "log" "os" + "time" "daydev.org/shipsgs/internal/config" "daydev.org/shipsgs/internal/gameServer" @@ -15,6 +16,9 @@ import ( var Logger *utils.Logger var ch_sighup *chan bool +//channel to shutdown oneSecUpdater +var ch_oneSecUpdaterShutdown chan bool + //GameServer Public Global Instance var GS *gameServer.GameServer @@ -33,6 +37,8 @@ func main() { sighup := make(chan bool) ch_sighup = &sighup + ch_oneSecUpdaterShutdown = make(chan bool) + //If debug - fill Stdout too - LOG to use? //Logger = utils.New(os.Stdout, utils.LevelInfo) @@ -42,10 +48,15 @@ func main() { GS.Init(Logger, &config.Config) go GS.Update() + //Starting oneSecUpdater after GameServer is ready, because oneSecUpdater + // is depending on GameServer.Shutdown channel which + // is IF uninitialized we will get "invalid memory address or nil pointer dereference" + go oneSecUpdater() + log.Println("Starting Healthy") //closer.Hold() - server.SetupAndRun(":8080", ch_sighup) + server.SetupAndRun(":8080", ch_sighup, GS) GS.WG.Wait() @@ -54,6 +65,9 @@ func main() { func cleanup() { fmt.Println("Shutting down ") + //Shutting down oneSecUpdater + ch_oneSecUpdaterShutdown <- true + //Investigate why no messages on correct closing GS.Shutdown <- true @@ -65,3 +79,25 @@ func cleanup() { }) } + +func oneSecUpdater() { + //The intention here is to awake after 1 second and send an update to GameServer to update everything + for { + select { + case <-ch_oneSecUpdaterShutdown: + fmt.Println("Shutdown One Sec Updater") + GS.WG.Done() + // Goroutine will wait untill the DEFAULT: will happen before shutdown will take + // any effect + case <-time.After(time.Second * 1): + fmt.Println("1 Sec Timer") + default: + //*** maybe try this 10 secs in a CASE segment ? + // This blocks whole goroutine + <-time.After(time.Second * 2) + + GS.OneSecond <- true + } + } + +}