Compare commits

..

No commits in common. 'master' and 'incorrect_closing_investigation' have entirely different histories.

  1. 70
      internal/gameServer/gameServer.go
  2. 52
      internal/gameServer/messages.go
  3. 123
      internal/gameServer/player.go
  4. 24
      internal/player/player.go
  5. 27
      internal/room/room.go
  6. 2
      internal/room/room_test.go
  7. 39
      internal/server/server.go
  8. 53
      main.go

@ -1,11 +1,8 @@
package gameServer
import (
"fmt"
"log"
"sync"
"daydev.org/shipsgs/internal/config"
"daydev.org/shipsgs/internal/player"
"daydev.org/shipsgs/internal/utils"
)
@ -19,26 +16,15 @@ type GameServer struct {
maxPlayers int
currentPlayers int
// Storing connected Players
playerConns map[*Player]bool
// Notify Game Server a New Player
Connection chan *Player
//Quit the loops correctly and shut down the Game Server
Shutdown chan bool
//1 Second Update planning
OneSecond chan bool
// Channel to register players and their connection
join chan *player.Player
//Created Rooms
Lobbies [5]Room
// Storing connected Players
playerConns map[*player.Player]bool
//sync threads
WG sync.WaitGroup
// Channel to un register players
}
//TODO update room creation to be dynamic and according to the config
func (m *GameServer) Init(logger *utils.Logger, config *config.S_Config) {
m.Logger = logger
m.Config = config
@ -46,40 +32,17 @@ func (m *GameServer) Init(logger *utils.Logger, config *config.S_Config) {
m.maxLobbies = m.Config.MaxLobbies
m.maxPlayers = m.Config.MaxPlayers
m.Shutdown = make(chan bool)
m.OneSecond = make(chan bool)
m.currentLobbies = 0
m.currentPlayers = 0
m.Connection = make(chan *Player)
m.playerConns = make(map[*Player]bool)
m.WG.Add(2)
}
func (m *GameServer) Update() {
for {
select {
case pl := <-m.Connection:
m.playerConns[pl] = true
//p := <-m.join
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
}
}
// If room doesnt exist, spawn it, name it
//Add a player to a room
//
}
func (m *GameServer) Scheduled1S() {
@ -89,16 +52,3 @@ func (m *GameServer) Scheduled1S() {
func (m *GameServer) Scheduled10S() {
}
func (m *GameServer) ShutdownServer() {
fmt.Println("shutting down the GameServer")
}
func (m *GameServer) CreateLobby() {
if m.currentLobbies >= m.maxLobbies {
log.Fatal("Server cannot spawn more lobbies than it already has")
return
}
}

@ -1,52 +0,0 @@
package gameServer
const (
Auth string = "Auth"
Message string = "Message"
PlayerAction string = "PlayerAction"
System string = "System"
Lobby string = "Lobby"
)
const (
OK int = 200
LobbyListRequest int = 201
LobbyListAnswer int = 202
BadRequest int = 400
Forbidden int = 403
Unauthorized = 401
InternalServerError int = 500
)
/*
Status:
200 - OK
201 - Lobby List Request
202 - Lobby List Answer
400 - Bad request
403 - Forbidden
401 - Unauthorized
500 - Internal server error
*/
type Packet struct {
Type string "json:`Type`"
Status int "json:`Status`"
Message interface{} "json:`Message`"
}
type AuthMsg struct {
Login string "json:`Login`"
Password string "json:`Password`"
}
type LobbyList struct {
Lobbies []Room "json:`Lobbies`"
}

@ -1,123 +0,0 @@
package gameServer
import (
"encoding/json"
"fmt"
"github.com/gorilla/websocket"
)
type Player struct {
Name string `json:"Name"`
Password string `json:"Password"`
//Connection
Conn *websocket.Conn
AuthString string `json:"AuthString"`
Level string `json:"Level"` // hidden from user, for balancing purposes
Kills int `json:"Kills"`
Killed int `json:"Killed"`
Won int `json:"Won"`
Lost int `json:"Lost"`
WinRate int `json:"WinRate"`
Health int `json:"Health"`
Authed bool `json:"Authed"`
GS *GameServer `json:"GS"`
}
func (pc *Player) Receiver() {
for {
_, message, err := pc.Conn.ReadMessage()
if err != nil {
fmt.Println("pc err: " + err.Error())
}
var msg Packet
err = json.Unmarshal(message, &msg)
if err != nil {
fmt.Println("pc err: " + err.Error())
}
if !pc.Authed && msg.Type != Auth {
reply := Packet{
Type: System,
Status: 401,
Message: nil,
}
authRequired, err := json.Marshal(reply)
if err != nil {
fmt.Println("pc err: " + err.Error())
}
pc.Conn.WriteMessage(websocket.TextMessage, authRequired)
//Stop processing the packet of unauthed connection
return
}
switch msg.Type {
case Auth:
pc.Auth(msg)
case Message:
case PlayerAction:
pc.PlayerAction(msg)
case System:
case Lobby:
pc.Lobby(msg)
default:
}
}
}
//TODO
func (pc *Player) Auth(p Packet) (pr Packet) {
// FOR DEV PURPOSES ONLY
// This function meant to become an authentication function!
pReply := Packet{
Type: Auth,
Status: 200,
Message: nil,
}
fmt.Println("Auth successful")
pc.Authed = true
return pReply
}
func (pc *Player) Lobby(p Packet) {
switch p.Status {
case LobbyListRequest: // Lobby list request
p.Message = pc.GS.Lobbies
p.Status = LobbyListAnswer
p.Type = Lobby
pMarshall, err := json.Marshal(p)
if err != nil {
fmt.Println("pc.Lobby: " + err.Error())
}
pc.Conn.WriteMessage(websocket.TextMessage, pMarshall)
default:
fmt.Println("player unsupported status")
}
}
func (pc *Player) ReceivedMessage(p Packet) {
}
func (pc *Player) PlayerAction(p Packet) {
}

@ -0,0 +1,24 @@
package player
import "github.com/gorilla/websocket"
type Player struct {
Name string `json:"Name"`
Password string `json:"Password"`
//Connection WS variable TODO
Conn *websocket.Conn
AuthString string `json:"AuthString"`
Level string `json:"Level"` // hidden from user, for balancing purposes
Kills int `json:"Kills"`
Killed int `json:"Killed"`
Won int `json:"Won"`
Lost int `json:"Lost"`
WinRate int `json:"WinRate"`
Health int `json:"Health"`
}

@ -1,8 +1,10 @@
package gameServer
package room
import (
"math/rand"
"time"
"daydev.org/shipsgs/internal/player"
)
const ()
@ -22,18 +24,10 @@ type Room struct {
Name string `json:"Name"`
//Players
players map[*Player]bool
players map[*player.Player]bool
//Room state
// Channel to register players and their connection
join chan *Player
// Channel to un register players
leave chan *Player
// Channel to update All in the room
updateAll chan bool
}
func (r *Room) PlayerJoin() {
@ -49,18 +43,7 @@ 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
}
*/
}
}
func RandomName() string {

@ -1,4 +1,4 @@
package gameServer
package room
import "testing"

@ -6,12 +6,10 @@ 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"`
@ -42,30 +40,23 @@ func wsEndpoint(w http.ResponseWriter, r *http.Request) {
return
}
player := &gameServer.Player{
player := player.Player{
Conn: conn,
}
player.Name = "Yale"
player.Authed = false
player.GS = GS
GS.Connection <- player
/*
log.Println(r.RemoteAddr)
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
}
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
}
}
}
@ -75,11 +66,9 @@ func setupRoutes() {
}
func SetupAndRun(port string, sighup *chan bool, gs *gameServer.GameServer) {
func SetupAndRun(port string, sighup *chan bool) {
setupRoutes()
GS = gs
srv := &http.Server{Addr: port}
go func() {

@ -4,10 +4,8 @@ import (
"fmt"
"log"
"os"
"time"
"daydev.org/shipsgs/internal/config"
"daydev.org/shipsgs/internal/gameServer"
"daydev.org/shipsgs/internal/server"
"daydev.org/shipsgs/internal/utils"
"github.com/xlab/closer"
@ -16,12 +14,6 @@ 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
func main() {
logFile, err := os.OpenFile("runlog.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
@ -33,45 +25,24 @@ func main() {
closer.Bind(cleanup)
//Can be optimised to NEW instead of MAKE
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)
config.ReadConfig()
GS = new(gameServer.GameServer)
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, GS)
GS.WG.Wait()
server.SetupAndRun(":8080", ch_sighup)
}
func cleanup() {
fmt.Println("Shutting down ")
//Shutting down oneSecUpdater
ch_oneSecUpdaterShutdown <- true
//Investigate why no messages on correct closing
GS.Shutdown <- true
// Main function has to be closed the last
*ch_sighup <- true
Logger.PrintInfo("main", map[string]string{
@ -79,25 +50,3 @@ 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
}
}
}

Loading…
Cancel
Save