Improved code quality

This commit is contained in:
Eduard Urbach 2024-01-30 11:33:32 +01:00
parent 30c7d3d609
commit 9c3d12bb50
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
11 changed files with 78 additions and 80 deletions

View File

@ -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"`

View File

@ -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
}

View File

@ -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)
})
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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()

View File

@ -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()
}

View File

@ -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)

View File

@ -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)

View File

@ -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.