mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-12-31 14:37:32 -05:00
Merge pull request #1008 from ianling/master
Networking bugfixes and cleanup
This commit is contained in:
commit
4b870de39e
@ -87,19 +87,16 @@ func (l *LocalClientConnection) Open(_, saveFilePath string) error {
|
||||
|
||||
// Close disconnects from the server and destroys it.
|
||||
func (l *LocalClientConnection) Close() error {
|
||||
sc, err := d2netpacket.CreateServerClosedPacket()
|
||||
disconnectRequest, err := d2netpacket.CreatePlayerDisconnectRequestPacket(l.uniqueID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = l.SendPacketToServer(sc)
|
||||
err = l.SendPacketToServer(disconnectRequest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
l.gameServer.OnClientDisconnected(l)
|
||||
l.gameServer.Stop()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package d2remoteclient
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
@ -131,12 +132,10 @@ func (r *RemoteClientConnection) SetClientListener(listener d2networking.ClientL
|
||||
// SendPacketToServer compresses the JSON encoding of a NetPacket and
|
||||
// sends it to the server.
|
||||
func (r *RemoteClientConnection) SendPacketToServer(packet d2netpacket.NetPacket) error {
|
||||
data, err := json.Marshal(packet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
encoder := json.NewEncoder(r.tcpConnection)
|
||||
|
||||
if _, err = r.tcpConnection.Write(data); err != nil {
|
||||
err := encoder.Encode(packet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -146,15 +145,21 @@ func (r *RemoteClientConnection) SendPacketToServer(packet d2netpacket.NetPacket
|
||||
// serverListener runs a while loop, reading from the GameServer's TCP
|
||||
// connection.
|
||||
func (r *RemoteClientConnection) serverListener() {
|
||||
var packet d2netpacket.NetPacket
|
||||
|
||||
decoder := json.NewDecoder(r.tcpConnection)
|
||||
|
||||
for {
|
||||
var packet d2netpacket.NetPacket
|
||||
|
||||
err := decoder.Decode(&packet)
|
||||
if err != nil {
|
||||
r.Errorf("failed to decode the packet, err: %v\n", err)
|
||||
return
|
||||
switch err {
|
||||
case io.EOF:
|
||||
break // the other side closed the connection
|
||||
default:
|
||||
r.Errorf("failed to decode the packet, err: %v\n", err)
|
||||
}
|
||||
|
||||
return // allow the connection to close
|
||||
}
|
||||
|
||||
p, err := r.decodeToPacket(packet.PacketType, string(packet.PacketData))
|
||||
@ -186,102 +191,29 @@ func (r *RemoteClientConnection) bytesToJSON(buffer []byte) (string, d2netpacket
|
||||
func (r *RemoteClientConnection) decodeToPacket(
|
||||
t d2netpackettype.NetPacketType,
|
||||
data string) (d2netpacket.NetPacket, error) {
|
||||
var np = d2netpacket.NetPacket{}
|
||||
|
||||
var err error
|
||||
var (
|
||||
np = d2netpacket.NetPacket{}
|
||||
err error
|
||||
p interface{}
|
||||
)
|
||||
|
||||
switch t {
|
||||
case d2netpackettype.GenerateMap:
|
||||
var p d2netpacket.GenerateMapPacket
|
||||
if err = json.Unmarshal([]byte(data), &p); err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
mp, marshalErr := d2netpacket.MarshalPacket(p)
|
||||
if marshalErr != nil {
|
||||
r.Errorf("MarshalPacket: %v", marshalErr)
|
||||
}
|
||||
|
||||
np = d2netpacket.NetPacket{PacketType: t, PacketData: mp}
|
||||
|
||||
p, err = d2netpacket.UnmarshalGenerateMap([]byte(data))
|
||||
case d2netpackettype.MovePlayer:
|
||||
var p d2netpacket.MovePlayerPacket
|
||||
if err = json.Unmarshal([]byte(data), &p); err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
mp, marshalErr := d2netpacket.MarshalPacket(p)
|
||||
if marshalErr != nil {
|
||||
r.Errorf("MarshalPacket: %v", marshalErr)
|
||||
}
|
||||
|
||||
np = d2netpacket.NetPacket{PacketType: t, PacketData: mp}
|
||||
|
||||
p, err = d2netpacket.UnmarshalMovePlayer([]byte(data))
|
||||
case d2netpackettype.UpdateServerInfo:
|
||||
var p d2netpacket.UpdateServerInfoPacket
|
||||
if err = json.Unmarshal([]byte(data), &p); err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
mp, marshalErr := d2netpacket.MarshalPacket(p)
|
||||
if marshalErr != nil {
|
||||
r.Errorf("MarshalPacket: %v", marshalErr)
|
||||
}
|
||||
|
||||
np = d2netpacket.NetPacket{PacketType: t, PacketData: mp}
|
||||
|
||||
p, err = d2netpacket.UnmarshalUpdateServerInfo([]byte(data))
|
||||
case d2netpackettype.AddPlayer:
|
||||
var p d2netpacket.AddPlayerPacket
|
||||
if err = json.Unmarshal([]byte(data), &p); err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
mp, marshalErr := d2netpacket.MarshalPacket(p)
|
||||
if marshalErr != nil {
|
||||
r.Errorf("MarshalPacket: %v", marshalErr)
|
||||
}
|
||||
|
||||
np = d2netpacket.NetPacket{PacketType: t, PacketData: mp}
|
||||
|
||||
p, err = d2netpacket.UnmarshalAddPlayer([]byte(data))
|
||||
case d2netpackettype.CastSkill:
|
||||
var p d2netpacket.CastPacket
|
||||
if err = json.Unmarshal([]byte(data), &p); err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
mp, marshalErr := d2netpacket.MarshalPacket(p)
|
||||
if marshalErr != nil {
|
||||
r.Errorf("MarshalPacket: %v", marshalErr)
|
||||
}
|
||||
|
||||
np = d2netpacket.NetPacket{PacketType: t, PacketData: mp}
|
||||
|
||||
p, err = d2netpacket.UnmarshalCast([]byte(data))
|
||||
case d2netpackettype.Ping:
|
||||
var p d2netpacket.PingPacket
|
||||
if err = json.Unmarshal([]byte(data), &p); err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
mp, marshalErr := d2netpacket.MarshalPacket(p)
|
||||
if marshalErr != nil {
|
||||
r.Errorf("MarshalPacket: %v", marshalErr)
|
||||
}
|
||||
|
||||
np = d2netpacket.NetPacket{PacketType: t, PacketData: mp}
|
||||
|
||||
p, err = d2netpacket.UnmarshalPing([]byte(data))
|
||||
case d2netpackettype.PlayerDisconnectionNotification:
|
||||
var p d2netpacket.PlayerDisconnectRequestPacket
|
||||
if err = json.Unmarshal([]byte(data), &p); err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
mp, marshalErr := d2netpacket.MarshalPacket(p)
|
||||
if marshalErr != nil {
|
||||
r.Errorf("MarshalPacket: %v", marshalErr)
|
||||
}
|
||||
|
||||
np = d2netpacket.NetPacket{PacketType: t, PacketData: mp}
|
||||
|
||||
p, err = d2netpacket.UnmarshalPlayerDisconnectionRequest([]byte(data))
|
||||
case d2netpackettype.ServerClosed:
|
||||
p, err = d2netpacket.UnmarshalServerClosed([]byte(data))
|
||||
default:
|
||||
err = fmt.Errorf("RemoteClientConnection: unrecognized packet type: %v", t)
|
||||
}
|
||||
@ -290,5 +222,12 @@ func (r *RemoteClientConnection) decodeToPacket(
|
||||
return np, err
|
||||
}
|
||||
|
||||
mp, marshalErr := d2netpacket.MarshalPacket(p)
|
||||
if marshalErr != nil {
|
||||
r.Errorf("MarshalPacket: %v", marshalErr)
|
||||
}
|
||||
|
||||
np = d2netpacket.NetPacket{PacketType: t, PacketData: mp}
|
||||
|
||||
return np, nil
|
||||
}
|
||||
|
@ -160,8 +160,9 @@ func (g *GameClient) OnPacketReceived(packet d2netpacket.NetPacket) error {
|
||||
g.Errorf("GameClient: error responding to server ping: %s", err)
|
||||
}
|
||||
case d2netpackettype.PlayerDisconnectionNotification:
|
||||
// Not implemented
|
||||
g.Infof("RemoteClientConnection: received disconnect: %s", packet.PacketData)
|
||||
if err := g.handlePlayerDisconnectionPacket(packet); err != nil {
|
||||
return err
|
||||
}
|
||||
case d2netpackettype.ServerClosed:
|
||||
// https://github.com/OpenDiablo2/OpenDiablo2/issues/802
|
||||
g.Infof("Server has been closed")
|
||||
@ -446,6 +447,19 @@ func (g *GameClient) handlePingPacket() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *GameClient) handlePlayerDisconnectionPacket(packet d2netpacket.NetPacket) error {
|
||||
disconnectPacket, err := d2netpacket.UnmarshalPlayerDisconnectionRequest(packet.PacketData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
player := g.Players[disconnectPacket.ID]
|
||||
g.MapEngine.RemoveEntity(player)
|
||||
delete(g.Players, disconnectPacket.ID)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsSinglePlayer returns a bool for whether the game is a single-player game
|
||||
func (g *GameClient) IsSinglePlayer() bool {
|
||||
return g.connectionType == d2clientconnectiontype.Local
|
||||
|
@ -1,4 +1,4 @@
|
||||
package d2netpacket
|
||||
package d2netpacket //nolint:dupl // ServerClosed and Ping just happen to be very similar packets
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@ -30,3 +30,13 @@ func CreatePingPacket() (NetPacket, error) {
|
||||
PacketData: b,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UnmarshalPing unmarshals the given data to a PingPacket struct
|
||||
func UnmarshalPing(packet []byte) (PingPacket, error) {
|
||||
var p PingPacket
|
||||
if err := json.Unmarshal(packet, &p); err != nil {
|
||||
return p, err
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package d2netpacket
|
||||
package d2netpacket //nolint:dupl // ServerClosed and Ping just happen to be very similar packets
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
@ -33,12 +33,9 @@ func (t TCPClientConnection) GetUniqueID() string {
|
||||
|
||||
// SendPacketToClient marshals and sends (writes) NetPackets
|
||||
func (t *TCPClientConnection) SendPacketToClient(p d2netpacket.NetPacket) error {
|
||||
packet, err := json.Marshal(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
encoder := json.NewEncoder(t.tcpConnection)
|
||||
|
||||
_, err = t.tcpConnection.Write(packet)
|
||||
err := encoder.Encode(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
@ -16,6 +17,7 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2hero"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapengine"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapgen"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2networking/d2client/d2clientconnectiontype"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2networking/d2netpacket"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2networking/d2netpacket/d2netpackettype"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2networking/d2server/d2tcpclientconnection"
|
||||
@ -50,12 +52,19 @@ type GameServer struct {
|
||||
scriptEngine *d2script.ScriptEngine
|
||||
seed int64
|
||||
maxConnections int
|
||||
packetManagerChan chan []byte
|
||||
packetManagerChan chan ReceivedPacket
|
||||
heroStateFactory *d2hero.HeroStateFactory
|
||||
|
||||
*d2util.Logger
|
||||
}
|
||||
|
||||
// ReceivedPacket encapsulates the data necessary for the packet manager goroutine to process data from clients.
|
||||
// The packet manager needs to know who sent the data, in addition to the data itself.
|
||||
type ReceivedPacket struct {
|
||||
Client ClientConnection
|
||||
Packet d2netpacket.NetPacket
|
||||
}
|
||||
|
||||
// NewGameServer builds a new GameServer that can be started
|
||||
//
|
||||
// ctx: required context item
|
||||
@ -84,7 +93,7 @@ func NewGameServer(asset *d2asset.AssetManager,
|
||||
connections: make(map[string]ClientConnection),
|
||||
networkServer: networkServer,
|
||||
maxConnections: maxConnections[0],
|
||||
packetManagerChan: make(chan []byte),
|
||||
packetManagerChan: make(chan ReceivedPacket),
|
||||
mapEngines: make([]*d2mapengine.MapEngine, 0),
|
||||
scriptEngine: d2script.CreateScriptEngine(),
|
||||
seed: time.Now().UnixNano(),
|
||||
@ -142,7 +151,13 @@ func (g *GameServer) Start() error {
|
||||
for {
|
||||
c, err := g.listener.Accept()
|
||||
if err != nil {
|
||||
g.Errorf("Unable to accept connection: %s", err)
|
||||
select {
|
||||
case <-g.ctx.Done():
|
||||
// this error was just a result of the server closing, don't worry about it
|
||||
default:
|
||||
g.Errorf("Unable to accept connection: %s", err)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -157,6 +172,7 @@ func (g *GameServer) Start() error {
|
||||
func (g *GameServer) Stop() {
|
||||
g.Lock()
|
||||
g.cancel()
|
||||
g.connections = make(map[string]ClientConnection)
|
||||
|
||||
if err := g.listener.Close(); err != nil {
|
||||
g.Errorf("failed to close the listener %s, err: %v\n", g.listener.Addr(), err)
|
||||
@ -173,45 +189,9 @@ func (g *GameServer) packetManager() {
|
||||
case <-g.ctx.Done():
|
||||
return
|
||||
case p := <-g.packetManagerChan:
|
||||
ipt, err := d2netpacket.InspectPacketType(p)
|
||||
err := g.OnPacketReceived(p.Client, p.Packet)
|
||||
if err != nil {
|
||||
g.Errorf("InspectPacketType: %v", err)
|
||||
}
|
||||
|
||||
switch ipt {
|
||||
case d2netpackettype.PlayerConnectionRequest:
|
||||
player, err := d2netpacket.UnmarshalNetPacket(p)
|
||||
if err != nil {
|
||||
g.Errorf("Unable to unmarshal PlayerConnectionRequestPacket: %s\n", err)
|
||||
}
|
||||
|
||||
g.sendPacketToClients(player)
|
||||
case d2netpackettype.MovePlayer:
|
||||
move, err := d2netpacket.UnmarshalNetPacket(p)
|
||||
if err != nil {
|
||||
g.Error(err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
g.sendPacketToClients(move)
|
||||
case d2netpackettype.CastSkill:
|
||||
castSkill, err := d2netpacket.UnmarshalNetPacket(p)
|
||||
if err != nil {
|
||||
g.Error(err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
g.sendPacketToClients(castSkill)
|
||||
case d2netpackettype.SpawnItem:
|
||||
item, err := d2netpacket.UnmarshalNetPacket(p)
|
||||
if err != nil {
|
||||
g.Error(err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
g.sendPacketToClients(item)
|
||||
case d2netpackettype.ServerClosed:
|
||||
g.Stop()
|
||||
g.Errorf("failed to handle packet received from client %s: %v", p.Client.GetUniqueID(), err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -228,9 +208,10 @@ func (g *GameServer) sendPacketToClients(packet d2netpacket.NetPacket) {
|
||||
// handleConnection accepts an individual connection and starts pooling for new packets. It is recommended this is called
|
||||
// via Go Routine. Context should be a property of the GameServer Struct.
|
||||
func (g *GameServer) handleConnection(conn net.Conn) {
|
||||
var connected int
|
||||
|
||||
var packet d2netpacket.NetPacket
|
||||
var (
|
||||
connected int
|
||||
client ClientConnection
|
||||
)
|
||||
|
||||
g.Infof("Accepting connection: %s\n", conn.RemoteAddr().String())
|
||||
|
||||
@ -243,10 +224,18 @@ func (g *GameServer) handleConnection(conn net.Conn) {
|
||||
decoder := json.NewDecoder(conn)
|
||||
|
||||
for {
|
||||
var packet d2netpacket.NetPacket
|
||||
|
||||
err := decoder.Decode(&packet)
|
||||
if err != nil {
|
||||
g.Error(err.Error())
|
||||
return // exit this connection as we could not read the first packet
|
||||
switch err {
|
||||
case io.EOF:
|
||||
break // the other side closed the connection
|
||||
default:
|
||||
g.Error(err.Error())
|
||||
}
|
||||
|
||||
return // allow the connection to close
|
||||
}
|
||||
|
||||
// If this is the first packet we are seeing from this specific connection we first need to see if the client
|
||||
@ -257,25 +246,7 @@ func (g *GameServer) handleConnection(conn net.Conn) {
|
||||
g.Infof("Closing connection with %s: did not receive new player connection request...", conn.RemoteAddr().String())
|
||||
}
|
||||
|
||||
if err := g.registerConnection(packet.PacketData, conn); err != nil {
|
||||
switch err {
|
||||
case errServerFull: // Server is currently full and not accepting new connections.
|
||||
sf, serverFullErr := d2netpacket.CreateServerFullPacket()
|
||||
if serverFullErr != nil {
|
||||
g.Errorf("ServerFullPacket: %v", serverFullErr)
|
||||
}
|
||||
|
||||
msf, marshalServerFullErr := d2netpacket.MarshalPacket(sf)
|
||||
if marshalServerFullErr != nil {
|
||||
g.Errorf("MarshalPacket: %v", marshalServerFullErr)
|
||||
}
|
||||
|
||||
_, errServerFullPacket := conn.Write(msf)
|
||||
g.Warningf("%v", errServerFullPacket)
|
||||
case errPlayerAlreadyExists: // Player is already registered and did not disconnection correctly.
|
||||
g.Errorf("%v", err)
|
||||
}
|
||||
|
||||
if client, err = g.registerConnection(packet.PacketData, conn); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@ -286,7 +257,10 @@ func (g *GameServer) handleConnection(conn net.Conn) {
|
||||
case <-g.ctx.Done():
|
||||
return
|
||||
default:
|
||||
g.packetManagerChan <- packet.PacketData
|
||||
g.packetManagerChan <- ReceivedPacket{
|
||||
Client: client,
|
||||
Packet: packet,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -296,12 +270,28 @@ func (g *GameServer) handleConnection(conn net.Conn) {
|
||||
// Errors:
|
||||
// - errServerFull
|
||||
// - errPlayerAlreadyExists
|
||||
func (g *GameServer) registerConnection(b []byte, conn net.Conn) error {
|
||||
func (g *GameServer) registerConnection(b []byte, conn net.Conn) (ClientConnection, error) {
|
||||
var client ClientConnection
|
||||
|
||||
g.Lock()
|
||||
defer g.Unlock()
|
||||
|
||||
// check to see if the server is full
|
||||
if len(g.connections) >= g.maxConnections {
|
||||
return errServerFull
|
||||
sf, serverFullErr := d2netpacket.CreateServerFullPacket()
|
||||
if serverFullErr != nil {
|
||||
g.Errorf("ServerFullPacket: %v", serverFullErr)
|
||||
}
|
||||
|
||||
msf, marshalServerFullErr := d2netpacket.MarshalPacket(sf)
|
||||
if marshalServerFullErr != nil {
|
||||
g.Errorf("MarshalPacket: %v", marshalServerFullErr)
|
||||
}
|
||||
|
||||
_, errServerFullPacket := conn.Write(msf)
|
||||
g.Warningf("%v", errServerFullPacket)
|
||||
|
||||
return client, errServerFull
|
||||
}
|
||||
|
||||
// if it is not full, unmarshal the playerConnectionRequest
|
||||
@ -312,29 +302,17 @@ func (g *GameServer) registerConnection(b []byte, conn net.Conn) error {
|
||||
|
||||
// check to see if the player is already registered
|
||||
if _, ok := g.connections[packet.ID]; ok {
|
||||
return errPlayerAlreadyExists
|
||||
g.Errorf("%v", errPlayerAlreadyExists)
|
||||
return client, errPlayerAlreadyExists
|
||||
}
|
||||
|
||||
// Client a new TCP Client Connection and add it to the connections map
|
||||
client := d2tcpclientconnection.CreateTCPClientConnection(conn, packet.ID)
|
||||
client = d2tcpclientconnection.CreateTCPClientConnection(conn, packet.ID)
|
||||
client.SetPlayerState(packet.PlayerState)
|
||||
g.Infof("Client connected with an id of %s", client.GetUniqueID())
|
||||
g.connections[client.GetUniqueID()] = client
|
||||
|
||||
// Temporary position hack --------------------------------------------
|
||||
// https://github.com/OpenDiablo2/OpenDiablo2/issues/829
|
||||
sx, sy := g.mapEngines[0].GetStartPosition()
|
||||
clientPlayerState := client.GetPlayerState()
|
||||
clientPlayerState.X = sx
|
||||
clientPlayerState.Y = sy
|
||||
// ---------
|
||||
g.OnClientConnected(client)
|
||||
|
||||
// This really should be deferred however to much time will be spend holding a lock when we attempt to send a packet
|
||||
g.Unlock()
|
||||
|
||||
g.handleClientConnection(client, sx, sy)
|
||||
|
||||
return nil
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// OnClientConnected initializes the given ClientConnection. It sends the
|
||||
@ -447,12 +425,27 @@ func (g *GameServer) handleClientConnection(client ClientConnection, x, y float6
|
||||
|
||||
// OnClientDisconnected removes the given client from the list
|
||||
// of client connections.
|
||||
// If this client was the host, disconnects all clients and kills GameServer.
|
||||
func (g *GameServer) OnClientDisconnected(client ClientConnection) {
|
||||
g.Infof("Client disconnected with an id of %s", client.GetUniqueID())
|
||||
delete(g.connections, client.GetUniqueID())
|
||||
|
||||
if client.GetConnectionType() == d2clientconnectiontype.Local {
|
||||
g.Info("Host disconnected, game server shuting down")
|
||||
|
||||
serverClosed, err := d2netpacket.CreateServerClosedPacket()
|
||||
if err != nil {
|
||||
g.Errorf("failed to generate ServerClosed packet after host disconnected: %s", err)
|
||||
} else {
|
||||
g.sendPacketToClients(serverClosed)
|
||||
}
|
||||
|
||||
g.Stop()
|
||||
}
|
||||
}
|
||||
|
||||
// OnPacketReceived is called by the local client to 'send' a packet to the server.
|
||||
// OnPacketReceived is called when a packet has been received from a remote client,
|
||||
// and by the local client to 'send' a packet to the server,
|
||||
// nolint:gocyclo // switch statement on packet type makes sense, no need to change
|
||||
func (g *GameServer) OnPacketReceived(client ClientConnection, packet d2netpacket.NetPacket) error {
|
||||
if g == nil {
|
||||
@ -490,8 +483,13 @@ func (g *GameServer) OnPacketReceived(client ClientConnection, packet d2netpacke
|
||||
if err != nil {
|
||||
g.Errorf("GameServer: error saving saving Player: %s", err)
|
||||
}
|
||||
case d2netpackettype.PlayerConnectionRequest:
|
||||
break // prevent log message. these are handled by handleConnection
|
||||
case d2netpackettype.PlayerDisconnectionNotification:
|
||||
g.sendPacketToClients(packet)
|
||||
g.OnClientDisconnected(client)
|
||||
default:
|
||||
g.Warningf("GameServer: received unknown packet %T", packet)
|
||||
g.Warningf("GameServer: received unknown packet %s", packet.PacketType)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
Loading…
Reference in New Issue
Block a user