From 9c3d12bb503636401b2a926f17cdc8f8ea310d6c Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Tue, 30 Jan 2024 11:33:32 +0100 Subject: [PATCH] Improved code quality --- server/game/Account.go | 2 +- server/game/Chat.go | 18 +++---- server/game/Game.go | 14 +++--- server/game/Jump.go | 2 +- server/game/Move.go | 2 +- server/game/Packet.go | 6 ++- server/game/Ping.go | 2 +- server/game/PlayerManager.go | 94 ++++++++++++++++++------------------ server/game/Server.go | 2 +- server/game/Server_test.go | 4 +- server/game/Vector3.go | 12 ++--- 11 files changed, 78 insertions(+), 80 deletions(-) diff --git a/server/game/Account.go b/server/game/Account.go index 1d9cff9..668646f 100644 --- a/server/game/Account.go +++ b/server/game/Account.go @@ -1,6 +1,6 @@ package game -// Account represents a player account +// Account represents a player account. type Account struct { ID string `json:"id"` Name string `json:"name"` diff --git a/server/game/Chat.go b/server/game/Chat.go index f739a48..2e61339 100644 --- a/server/game/Chat.go +++ b/server/game/Chat.go @@ -28,15 +28,15 @@ func (game *Game) Chat(data []byte, address *net.UDPAddr) error { // ChatCommand executes chat commands and returns true if it was one. func (game *Game) ChatCommand(player *Player, message string) bool { - if strings.HasPrefix(message, "/") { - switch message { - case "/logout": - game.server.Send(Logout, nil, player.address) - game.players.Remove(player) - } - - return true + if !strings.HasPrefix(message, "/") { + return false } - return false + switch message { + case "/logout": + game.server.Send(Logout, nil, player.address) + game.players.Remove(player) + } + + return true } diff --git a/server/game/Game.go b/server/game/Game.go index a683fa1..f1b3447 100644 --- a/server/game/Game.go +++ b/server/game/Game.go @@ -30,8 +30,8 @@ func NewRouter(game *Game) *Router { router := &Router{} router.Get(Ping, game.Ping) router.Get(Login, game.Login) - router.Get(Move, game.Move) - router.Get(Jump, game.Jump) + router.Get(PlayerMove, game.Move) + router.Get(PlayerJump, game.Jump) router.Get(Chat, game.Chat) return router } @@ -71,18 +71,18 @@ func (game *Game) Run() { // Broadcast sends the packet to all players. func (game *Game) Broadcast(code byte, data []byte) { - game.players.Each(func(other *Player) { - game.server.Send(code, data, other.address) + 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(other *Player) { - if other == exclude { + game.players.Each(func(player *Player) { + if player == exclude { return } - game.server.Send(code, data, other.address) + game.server.Send(code, data, player.address) }) } diff --git a/server/game/Jump.go b/server/game/Jump.go index c195bf0..5c683b8 100644 --- a/server/game/Jump.go +++ b/server/game/Jump.go @@ -12,6 +12,6 @@ func (game *Game) Jump(data []byte, address *net.UDPAddr) error { return ErrUnknownAddress } - game.BroadcastOthers(Jump, []byte(player.ID), player) + game.BroadcastOthers(PlayerJump, []byte(player.ID), player) return nil } diff --git a/server/game/Move.go b/server/game/Move.go index 55edfe0..0b829a9 100644 --- a/server/game/Move.go +++ b/server/game/Move.go @@ -26,6 +26,6 @@ func (game *Game) Move(data []byte, address *net.UDPAddr) error { update = AppendFloat(update, player.Position.X) update = AppendFloat(update, player.Position.Z) - game.BroadcastOthers(Move, update, player) + game.BroadcastOthers(PlayerMove, update, player) return nil } diff --git a/server/game/Packet.go b/server/game/Packet.go index 69527b0..d87e523 100644 --- a/server/game/Packet.go +++ b/server/game/Packet.go @@ -4,18 +4,20 @@ import ( "net" ) +// Byte prefixes to indicate the packet type. const ( Ping = 1 Login = 2 Logout = 3 PlayerAdd = 10 PlayerRemove = 11 - Move = 12 - Jump = 13 + PlayerMove = 12 + PlayerJump = 13 PlayerAttack = 14 Chat = 20 ) +// Packet represents a single UDP datagram. type Packet struct { Data []byte Address *net.UDPAddr diff --git a/server/game/Ping.go b/server/game/Ping.go index 80f67a5..1700abf 100644 --- a/server/game/Ping.go +++ b/server/game/Ping.go @@ -6,7 +6,7 @@ import ( // Ping is used as a heartbeat and latency check. func (game *Game) Ping(data []byte, address *net.UDPAddr) error { - game.server.Send(Ping, data, address) + game.server.Send(Ping, data[:1], address) if game.players.Contains(address) { game.players.ByAddress(address).KeepAlive() diff --git a/server/game/PlayerManager.go b/server/game/PlayerManager.go index f5bc436..a46d590 100644 --- a/server/game/PlayerManager.go +++ b/server/game/PlayerManager.go @@ -5,7 +5,7 @@ import ( "time" ) -// PlayerManager keeps tracks of all players. +// PlayerManager keeps track of all players. type PlayerManager struct { players map[string]*Player accounts map[string]*Player @@ -28,52 +28,6 @@ func (m *PlayerManager) Add(player *Player) { player.OnConnect() } -// ChangeAddress changes the address of a player. -func (m *PlayerManager) ChangeAddress(player *Player, address *net.UDPAddr) { - delete(m.players, player.address.String()) - player.address = address - m.players[player.address.String()] = player -} - -// Clean checks for players who haven't responded in the timeout duration and disconnects them. -func (m *PlayerManager) Clean(timeout time.Duration) { - now := time.Now() - - for _, player := range m.players { - if player.lastPacket.IsZero() || now.Before(player.lastPacket.Add(timeout)) { - continue - } - - m.Remove(player) - } -} - -// Remove removes a player. -func (m *PlayerManager) Remove(player *Player) { - delete(m.players, player.address.String()) - delete(m.accounts, player.ID) - m.count-- - player.OnDisconnect() -} - -// Contains tells you whether the address is already a registered client. -func (m *PlayerManager) Contains(address *net.UDPAddr) bool { - _, exists := m.players[address.String()] - return exists -} - -// Count returns the number of clients. -func (m *PlayerManager) Count() int { - return m.count -} - -// Each calls the callback function for each client. -func (m *PlayerManager) Each(callback func(*Player)) { - for _, player := range m.players { - callback(player) - } -} - // ByAddress returns an existing client for the requested address. func (m *PlayerManager) ByAddress(address *net.UDPAddr) *Player { player, exists := m.players[address.String()] @@ -95,3 +49,49 @@ func (m *PlayerManager) ByAccount(id string) *Player { return player } + +// ChangeAddress changes the address of a player. +func (m *PlayerManager) ChangeAddress(player *Player, address *net.UDPAddr) { + delete(m.players, player.address.String()) + player.address = address + m.players[player.address.String()] = player +} + +// Clean checks for players who haven't responded in the timeout duration and disconnects them. +func (m *PlayerManager) Clean(timeout time.Duration) { + now := time.Now() + + for _, player := range m.players { + if player.lastPacket.IsZero() || now.Before(player.lastPacket.Add(timeout)) { + continue + } + + m.Remove(player) + } +} + +// Contains tells you whether the address is already a registered client. +func (m *PlayerManager) Contains(address *net.UDPAddr) bool { + _, exists := m.players[address.String()] + return exists +} + +// Count returns the number of clients. +func (m *PlayerManager) Count() int { + return m.count +} + +// Each calls the callback function for each client. +func (m *PlayerManager) Each(callback func(*Player)) { + for _, player := range m.players { + callback(player) + } +} + +// Remove removes a player. +func (m *PlayerManager) Remove(player *Player) { + delete(m.players, player.address.String()) + delete(m.accounts, player.ID) + m.count-- + player.OnDisconnect() +} diff --git a/server/game/Server.go b/server/game/Server.go index cfc893c..e41fea8 100644 --- a/server/game/Server.go +++ b/server/game/Server.go @@ -77,7 +77,7 @@ func listen(port int) *net.UDPConn { return connection } -// read is a blocking call which will read incoming packets and handle them. +// read is a blocking call which will read incoming packets and send them to a channel. func (s *Server) read() { buffer := make([]byte, UDPDataMaxLength) diff --git a/server/game/Server_test.go b/server/game/Server_test.go index bc698c1..b308e7c 100644 --- a/server/game/Server_test.go +++ b/server/game/Server_test.go @@ -10,6 +10,8 @@ var ( data = []byte("Hello") ) +func noop([]byte) {} + func BenchmarkSendAppend(b *testing.B) { b.ReportAllocs() @@ -30,8 +32,6 @@ func BenchmarkSendCopy(b *testing.B) { } } -func noop([]byte) {} - func BenchmarkReceivePointer(b *testing.B) { b.ReportAllocs() incoming := make(chan *game.Packet, 1) diff --git a/server/game/Vector3.go b/server/game/Vector3.go index a93e965..ed82055 100644 --- a/server/game/Vector3.go +++ b/server/game/Vector3.go @@ -14,14 +14,10 @@ type Vector3 struct { // AppendVector3 appends the raw bits of the vector to the given byte slice in XYZ order. func AppendVector3(data []byte, vector Vector3) []byte { - bits := math.Float32bits(vector.X) - data = binary.LittleEndian.AppendUint32(data, bits) - - bits = math.Float32bits(vector.Y) - data = binary.LittleEndian.AppendUint32(data, bits) - - bits = math.Float32bits(vector.Z) - return binary.LittleEndian.AppendUint32(data, bits) + data = AppendFloat(data, vector.X) + data = AppendFloat(data, vector.Y) + data = AppendFloat(data, vector.Z) + return data } // AppendFloat appends the raw bits of the float to the given byte slice in XYZ order.