Improved code quality
This commit is contained in:
parent
30c7d3d609
commit
9c3d12bb50
@ -1,6 +1,6 @@
|
|||||||
package game
|
package game
|
||||||
|
|
||||||
// Account represents a player account
|
// Account represents a player account.
|
||||||
type Account struct {
|
type Account struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
@ -28,7 +28,10 @@ func (game *Game) Chat(data []byte, address *net.UDPAddr) error {
|
|||||||
|
|
||||||
// ChatCommand executes chat commands and returns true if it was one.
|
// ChatCommand executes chat commands and returns true if it was one.
|
||||||
func (game *Game) ChatCommand(player *Player, message string) bool {
|
func (game *Game) ChatCommand(player *Player, message string) bool {
|
||||||
if strings.HasPrefix(message, "/") {
|
if !strings.HasPrefix(message, "/") {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
switch message {
|
switch message {
|
||||||
case "/logout":
|
case "/logout":
|
||||||
game.server.Send(Logout, nil, player.address)
|
game.server.Send(Logout, nil, player.address)
|
||||||
@ -37,6 +40,3 @@ func (game *Game) ChatCommand(player *Player, message string) bool {
|
|||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
@ -30,8 +30,8 @@ func NewRouter(game *Game) *Router {
|
|||||||
router := &Router{}
|
router := &Router{}
|
||||||
router.Get(Ping, game.Ping)
|
router.Get(Ping, game.Ping)
|
||||||
router.Get(Login, game.Login)
|
router.Get(Login, game.Login)
|
||||||
router.Get(Move, game.Move)
|
router.Get(PlayerMove, game.Move)
|
||||||
router.Get(Jump, game.Jump)
|
router.Get(PlayerJump, game.Jump)
|
||||||
router.Get(Chat, game.Chat)
|
router.Get(Chat, game.Chat)
|
||||||
return router
|
return router
|
||||||
}
|
}
|
||||||
@ -71,18 +71,18 @@ func (game *Game) Run() {
|
|||||||
|
|
||||||
// Broadcast sends the packet to all players.
|
// Broadcast sends the packet to all players.
|
||||||
func (game *Game) Broadcast(code byte, data []byte) {
|
func (game *Game) Broadcast(code byte, data []byte) {
|
||||||
game.players.Each(func(other *Player) {
|
game.players.Each(func(player *Player) {
|
||||||
game.server.Send(code, data, other.address)
|
game.server.Send(code, data, player.address)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// BroadcastOthers sends the packet to all other players except the original sender.
|
// BroadcastOthers sends the packet to all other players except the original sender.
|
||||||
func (game *Game) BroadcastOthers(code byte, data []byte, exclude *Player) {
|
func (game *Game) BroadcastOthers(code byte, data []byte, exclude *Player) {
|
||||||
game.players.Each(func(other *Player) {
|
game.players.Each(func(player *Player) {
|
||||||
if other == exclude {
|
if player == exclude {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
game.server.Send(code, data, other.address)
|
game.server.Send(code, data, player.address)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,6 @@ func (game *Game) Jump(data []byte, address *net.UDPAddr) error {
|
|||||||
return ErrUnknownAddress
|
return ErrUnknownAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
game.BroadcastOthers(Jump, []byte(player.ID), player)
|
game.BroadcastOthers(PlayerJump, []byte(player.ID), player)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -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.X)
|
||||||
update = AppendFloat(update, player.Position.Z)
|
update = AppendFloat(update, player.Position.Z)
|
||||||
|
|
||||||
game.BroadcastOthers(Move, update, player)
|
game.BroadcastOthers(PlayerMove, update, player)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -4,18 +4,20 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Byte prefixes to indicate the packet type.
|
||||||
const (
|
const (
|
||||||
Ping = 1
|
Ping = 1
|
||||||
Login = 2
|
Login = 2
|
||||||
Logout = 3
|
Logout = 3
|
||||||
PlayerAdd = 10
|
PlayerAdd = 10
|
||||||
PlayerRemove = 11
|
PlayerRemove = 11
|
||||||
Move = 12
|
PlayerMove = 12
|
||||||
Jump = 13
|
PlayerJump = 13
|
||||||
PlayerAttack = 14
|
PlayerAttack = 14
|
||||||
Chat = 20
|
Chat = 20
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Packet represents a single UDP datagram.
|
||||||
type Packet struct {
|
type Packet struct {
|
||||||
Data []byte
|
Data []byte
|
||||||
Address *net.UDPAddr
|
Address *net.UDPAddr
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
|
|
||||||
// Ping is used as a heartbeat and latency check.
|
// Ping is used as a heartbeat and latency check.
|
||||||
func (game *Game) Ping(data []byte, address *net.UDPAddr) error {
|
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) {
|
if game.players.Contains(address) {
|
||||||
game.players.ByAddress(address).KeepAlive()
|
game.players.ByAddress(address).KeepAlive()
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PlayerManager keeps tracks of all players.
|
// PlayerManager keeps track of all players.
|
||||||
type PlayerManager struct {
|
type PlayerManager struct {
|
||||||
players map[string]*Player
|
players map[string]*Player
|
||||||
accounts map[string]*Player
|
accounts map[string]*Player
|
||||||
@ -28,52 +28,6 @@ func (m *PlayerManager) Add(player *Player) {
|
|||||||
player.OnConnect()
|
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.
|
// ByAddress returns an existing client for the requested address.
|
||||||
func (m *PlayerManager) ByAddress(address *net.UDPAddr) *Player {
|
func (m *PlayerManager) ByAddress(address *net.UDPAddr) *Player {
|
||||||
player, exists := m.players[address.String()]
|
player, exists := m.players[address.String()]
|
||||||
@ -95,3 +49,49 @@ func (m *PlayerManager) ByAccount(id string) *Player {
|
|||||||
|
|
||||||
return 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()
|
||||||
|
}
|
||||||
|
@ -77,7 +77,7 @@ func listen(port int) *net.UDPConn {
|
|||||||
return connection
|
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() {
|
func (s *Server) read() {
|
||||||
buffer := make([]byte, UDPDataMaxLength)
|
buffer := make([]byte, UDPDataMaxLength)
|
||||||
|
|
||||||
|
@ -10,6 +10,8 @@ var (
|
|||||||
data = []byte("Hello")
|
data = []byte("Hello")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func noop([]byte) {}
|
||||||
|
|
||||||
func BenchmarkSendAppend(b *testing.B) {
|
func BenchmarkSendAppend(b *testing.B) {
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
|
|
||||||
@ -30,8 +32,6 @@ func BenchmarkSendCopy(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func noop([]byte) {}
|
|
||||||
|
|
||||||
func BenchmarkReceivePointer(b *testing.B) {
|
func BenchmarkReceivePointer(b *testing.B) {
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
incoming := make(chan *game.Packet, 1)
|
incoming := make(chan *game.Packet, 1)
|
||||||
|
@ -14,14 +14,10 @@ type Vector3 struct {
|
|||||||
|
|
||||||
// AppendVector3 appends the raw bits of the vector to the given byte slice in XYZ order.
|
// AppendVector3 appends the raw bits of the vector to the given byte slice in XYZ order.
|
||||||
func AppendVector3(data []byte, vector Vector3) []byte {
|
func AppendVector3(data []byte, vector Vector3) []byte {
|
||||||
bits := math.Float32bits(vector.X)
|
data = AppendFloat(data, vector.X)
|
||||||
data = binary.LittleEndian.AppendUint32(data, bits)
|
data = AppendFloat(data, vector.Y)
|
||||||
|
data = AppendFloat(data, vector.Z)
|
||||||
bits = math.Float32bits(vector.Y)
|
return data
|
||||||
data = binary.LittleEndian.AppendUint32(data, bits)
|
|
||||||
|
|
||||||
bits = math.Float32bits(vector.Z)
|
|
||||||
return binary.LittleEndian.AppendUint32(data, bits)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AppendFloat appends the raw bits of the float to the given byte slice in XYZ order.
|
// AppendFloat appends the raw bits of the float to the given byte slice in XYZ order.
|
||||||
|
Loading…
Reference in New Issue
Block a user