89 lines
1.8 KiB
Go
89 lines
1.8 KiB
Go
package game
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/signal"
|
|
"time"
|
|
)
|
|
|
|
// Game represents the entire state of the game server.
|
|
type Game struct {
|
|
server *Server
|
|
router *Router
|
|
players *PlayerManager
|
|
}
|
|
|
|
// New creates a new game.
|
|
func New() *Game {
|
|
game := &Game{
|
|
server: NewServer(),
|
|
players: NewPlayerManager(),
|
|
}
|
|
|
|
game.router = NewRouter(game)
|
|
return game
|
|
}
|
|
|
|
// NewRouter creates a new router.
|
|
func NewRouter(game *Game) *Router {
|
|
router := &Router{}
|
|
router.Get(Ping, game.Ping)
|
|
router.Get(Login, game.Login)
|
|
router.Get(PlayerMove, game.Move)
|
|
router.Get(PlayerJump, game.Jump)
|
|
router.Get(Chat, game.Chat)
|
|
return router
|
|
}
|
|
|
|
// Run starts all game systems.
|
|
func (game *Game) Run() {
|
|
physics := time.NewTicker(20 * time.Millisecond).C
|
|
statistics := time.NewTicker(time.Second).C
|
|
clean := time.NewTicker(time.Second).C
|
|
close := make(chan os.Signal, 1)
|
|
signal.Notify(close, os.Interrupt)
|
|
|
|
go game.server.Run(4242)
|
|
|
|
for {
|
|
select {
|
|
case p := <-game.server.incoming:
|
|
game.router.handle(p)
|
|
|
|
case <-physics:
|
|
game.players.Each(func(c *Player) {
|
|
c.Tick()
|
|
})
|
|
|
|
case <-statistics:
|
|
fmt.Printf("%d players | %d packets\n", game.players.Count(), game.server.PacketCount())
|
|
game.server.ResetPacketCount()
|
|
|
|
case <-clean:
|
|
game.players.Clean(5 * time.Second)
|
|
|
|
case <-close:
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
// Broadcast sends the packet to all players.
|
|
func (game *Game) Broadcast(code byte, data []byte) {
|
|
game.players.Each(func(player *Player) {
|
|
game.server.Send(code, data, player.address)
|
|
})
|
|
}
|
|
|
|
// BroadcastOthers sends the packet to all other players except the original sender.
|
|
func (game *Game) BroadcastOthers(code byte, data []byte, exclude *Player) {
|
|
game.players.Each(func(player *Player) {
|
|
if player == exclude {
|
|
return
|
|
}
|
|
|
|
game.server.Send(code, data, player.address)
|
|
})
|
|
}
|