From 938348ce260f1b92b994c9fde5debabc7364e109 Mon Sep 17 00:00:00 2001 From: Jordan Orelli Date: Mon, 3 Jun 2019 02:26:09 +0000 Subject: [PATCH] run multiple games at once --- commands.go | 4 +-- connection.go | 70 +++++++++++++++++++++++++++++++++++++++++++++---- game.go | 10 ++----- game_manager.go | 34 ++++++++++++++++++++++++ idle.go | 4 +-- main.go | 14 ++-------- system.go | 2 +- 7 files changed, 108 insertions(+), 30 deletions(-) create mode 100644 game_manager.go diff --git a/commands.go b/commands.go index a02cd00..da6909a 100644 --- a/commands.go +++ b/commands.go @@ -120,7 +120,7 @@ func BroadcastCommand(sys *System) Command { msg := strings.Join(args, " ") b := NewBroadcast(sys, msg) log_info("player %s send broadcast from system %v: %v\n", c.Name(), sys, msg) - currentGame.Register(b) + c.game.Register(b) }, } } @@ -162,7 +162,7 @@ var playersCommand = Command{ name: "players", help: "lists the connected players", handler: func(conn *Connection, args ...string) { - for other, _ := range currentGame.connections { + for other, _ := range conn.game.connections { conn.Printf("%v\n", other.Name()) } }, diff --git a/connection.go b/connection.go index 67f428d..b07895d 100644 --- a/connection.go +++ b/connection.go @@ -12,6 +12,7 @@ import ( type Connection struct { *bufio.Reader + game *Game net.Conn ConnectionState bombs int @@ -30,8 +31,7 @@ func NewConnection(conn net.Conn) *Connection { bombs: options.startBombs, money: options.startMoney, } - c.SetState(SpawnRandomly()) - currentGame.Join(c) + c.SetState(new(LobbyState)) return c } @@ -45,6 +45,7 @@ func (c *Connection) Login() { log_error("player failed to connect: %v", err) return } + if !ValidName(name) { c.Printf("that name is illegal.\n") continue @@ -66,7 +67,6 @@ func (c *Connection) Login() { } break } - currentGame.Register(c) } func (c *Connection) Dead() bool { @@ -162,7 +162,7 @@ func (c *Connection) Printf(template string, args ...interface{}) (int, error) { func (c *Connection) Close() error { log_info("player disconnecting: %s", c.Name()) - currentGame.Quit(c) + c.game.Quit(c) if c.Conn != nil { return c.Conn.Close() } @@ -226,7 +226,7 @@ func (c *Connection) Deposit(n int) { } func (c *Connection) Win(method string) { - currentGame.Win(c, method) + c.game.Win(c, method) } func (c *Connection) Die(frame int64) { @@ -260,3 +260,63 @@ func SpawnRandomly() ConnectionState { } return Idle(sys) } + +type LobbyState struct { + NopExit +} + +func (st *LobbyState) String() string { return "Lobby" } + +func (st *LobbyState) Enter(c *Connection) { + c.Login() +} + +func (st *LobbyState) Tick(c *Connection, frame int64) ConnectionState { return st } + +func (st *LobbyState) Commands() []Command { + return []Command{newGameCommand, joinGameCommand} +} + +func (st *LobbyState) GetCommand(name string) *Command { + switch name { + case "new": + return &newGameCommand + case "join": + return &joinGameCommand + default: + return nil + } +} + +var newGameCommand = Command{ + name: "new", + help: "starts a new game", + arity: 0, + variadic: false, + handler: func(c *Connection, args ...string) { + c.Printf("Starting a new game...\n") + game := gm.NewGame() + log_info("Created game: %s", game.id) + go game.Run() + c.game = game + c.Printf("Now playing in game: %s\n\n", game.id) + c.Line() + c.game.Join(c) + c.SetState(SpawnRandomly()) + }, + debug: false, +} + +var joinGameCommand = Command{ + name: "join", + help: "joins an existing game", + arity: 1, + variadic: false, + handler: func(c *Connection, args ...string) { + id := args[0] + c.game = gm.Get(id) + c.SetState(SpawnRandomly()) + c.game.Join(c) + }, + debug: false, +} diff --git a/game.go b/game.go index 09e9491..72de927 100644 --- a/game.go +++ b/game.go @@ -56,14 +56,6 @@ func NewGame() *Game { for _, system := range index { game.Register(system) } - if currentGame != nil { - log_info("passing %d connections...", len(currentGame.connections)) - for conn, _ := range currentGame.connections { - log_info("moving player %s to new game", conn.Name()) - currentGame.Quit(conn) - game.Join(conn) - } - } return game } @@ -90,7 +82,9 @@ func (g *Game) Store() error { } func (g *Game) Join(conn *Connection) { + log_info("Player %s has joined game %s", conn.Name(), g.id) g.connections[conn] = true + g.Register(conn) } func (g *Game) Quit(conn *Connection) { diff --git a/game_manager.go b/game_manager.go new file mode 100644 index 0000000..513dedd --- /dev/null +++ b/game_manager.go @@ -0,0 +1,34 @@ +package main + +import ( + "sync" +) + +var gm *GameManager + +func init() { + gm = &GameManager{ + games: make(map[string]*Game, 32), + } +} + +type GameManager struct { + games map[string]*Game + sync.Mutex +} + +func (g *GameManager) NewGame() *Game { + g.Lock() + defer g.Unlock() + + game := NewGame() + g.games[game.id] = game + return game +} + +func (g *GameManager) Get(id string) *Game { + g.Lock() + defer g.Unlock() + + return g.games[id] +} diff --git a/idle.go b/idle.go index e14c1b6..91eac69 100644 --- a/idle.go +++ b/idle.go @@ -98,7 +98,7 @@ func (i *IdleState) bomb(c *Connection, args ...string) { c.bombs -= 1 c.lastBomb = time.Now() bomb := NewBomb(c, i.System, target) - currentGame.Register(bomb) + c.game.Register(bomb) } func (i *IdleState) mine(c *Connection, args ...string) { @@ -115,7 +115,7 @@ func (i *IdleState) scan(c *Connection, args ...string) { return } c.Printf("Scanning the galaxy for signs of life...\n") - currentGame.Register(NewScan(i.System)) + c.game.Register(NewScan(i.System)) } // "make" is already a keyword diff --git a/main.go b/main.go index c9b6c6c..0b4bb88 100644 --- a/main.go +++ b/main.go @@ -34,9 +34,8 @@ var options struct { } var ( - info_log *log.Logger - error_log *log.Logger - currentGame *Game + info_log *log.Logger + error_log *log.Logger ) func log_error(template string, args ...interface{}) { @@ -58,7 +57,6 @@ func bail(status int, template string, args ...interface{}) { func handleConnection(conn *Connection) { defer conn.Close() - conn.Login() c := make(chan []string) go conn.ReadLines(c) @@ -95,14 +93,6 @@ func main() { } log_info("listening on %s", addr) - go func() { - for { - log_info("starting new game") - currentGame = NewGame() - currentGame.Run() - } - }() - for { conn, err := listener.Accept() if err != nil { diff --git a/system.go b/system.go index 0072a3e..1757f2f 100644 --- a/system.go +++ b/system.go @@ -279,7 +279,7 @@ func indexSystems() map[int]*System { index[p.id] = &p nameIndex[p.name] = &p p.money = int64(rand.NormFloat64()*options.moneySigma + options.moneyMean) - log_info("seeded system %v with %v monies", p, p.money) + // log_info("seeded system %v with %v monies", p, p.money) } return index }