protocol: added CNPeer

- moved Peer from the server package to the protocol package, it was also renamed to CNPeer as most fusionfall specific constants in the client use the 'CN' prefix.
This commit is contained in:
2023-03-18 16:40:20 -05:00
parent 1357de99aa
commit 735bdc5b36
6 changed files with 50 additions and 46 deletions

View File

@@ -2,7 +2,9 @@ package server
import "github.com/CPunch/gopenfusion/protocol"
func (server *ShardServer) RequestEnter(peer *Peer, pkt protocol.Packet) error {
func (server *ShardServer) RequestEnter(peer *protocol.CNPeer, pkt protocol.Packet) error {
var enter protocol.SP_CL2FE_REQ_PC_ENTER
pkt.Decode(&enter)
return nil
}

View File

@@ -23,7 +23,7 @@ const (
LOGIN_UPDATED_EUALA_REQUIRED = 9
)
func (server *LoginServer) AcceptLogin(peer *Peer, SzID string, IClientVerC int32, ISlotNum int8, data []protocol.SP_LS2CL_REP_CHAR_INFO) error {
func (server *LoginServer) AcceptLogin(peer *protocol.CNPeer, SzID string, IClientVerC int32, ISlotNum int8, data []protocol.SP_LS2CL_REP_CHAR_INFO) error {
peer.SzID = SzID
resp := protocol.SP_LS2CL_REP_LOGIN_SUCC{
@@ -61,7 +61,7 @@ func (server *LoginServer) AcceptLogin(peer *Peer, SzID string, IClientVerC int3
return nil
}
func (server *LoginServer) Login(peer *Peer, pkt protocol.Packet) error {
func (server *LoginServer) Login(peer *protocol.CNPeer, pkt protocol.Packet) error {
var loginPkt protocol.SP_CL2LS_REQ_LOGIN
pkt.Decode(&loginPkt)
@@ -137,7 +137,7 @@ func (server *LoginServer) Login(peer *Peer, pkt protocol.Packet) error {
return server.AcceptLogin(peer, loginPkt.SzID, loginPkt.IClientVerC, 1, charInfo[:len(plrs)])
}
func (server *LoginServer) CheckCharacterName(peer *Peer, pkt protocol.Packet) error {
func (server *LoginServer) CheckCharacterName(peer *protocol.CNPeer, pkt protocol.Packet) error {
var charPkt protocol.SP_CL2LS_REQ_CHECK_CHAR_NAME
pkt.Decode(&charPkt)
@@ -148,7 +148,7 @@ func (server *LoginServer) CheckCharacterName(peer *Peer, pkt protocol.Packet) e
})
}
func (server *LoginServer) SaveCharacterName(peer *Peer, pkt protocol.Packet) error {
func (server *LoginServer) SaveCharacterName(peer *protocol.CNPeer, pkt protocol.Packet) error {
var charPkt protocol.SP_CL2LS_REQ_SAVE_CHAR_NAME
pkt.Decode(&charPkt)
@@ -200,7 +200,7 @@ func validateCharacterCreation(character *protocol.SP_CL2LS_REQ_CHAR_CREATE) boo
return true
}
func SendFail(peer *Peer) error {
func SendFail(peer *protocol.CNPeer) error {
if err := peer.Send(protocol.P_LS2CL_REP_SHARD_SELECT_FAIL, protocol.SP_LS2CL_REP_SHARD_SELECT_FAIL{
IErrorCode: 2,
}); err != nil {
@@ -210,7 +210,7 @@ func SendFail(peer *Peer) error {
return nil
}
func (server *LoginServer) CharacterCreate(peer *Peer, pkt protocol.Packet) error {
func (server *LoginServer) CharacterCreate(peer *protocol.CNPeer, pkt protocol.Packet) error {
var charPkt protocol.SP_CL2LS_REQ_CHAR_CREATE
pkt.Decode(&charPkt)
@@ -236,7 +236,7 @@ func (server *LoginServer) CharacterCreate(peer *Peer, pkt protocol.Packet) erro
})
}
func (server *LoginServer) CharacterDelete(peer *Peer, pkt protocol.Packet) error {
func (server *LoginServer) CharacterDelete(peer *protocol.CNPeer, pkt protocol.Packet) error {
var charPkt protocol.SP_CL2LS_REQ_CHAR_DELETE
pkt.Decode(&charPkt)
@@ -250,7 +250,7 @@ func (server *LoginServer) CharacterDelete(peer *Peer, pkt protocol.Packet) erro
})
}
func (server *LoginServer) ShardSelect(peer *Peer, pkt protocol.Packet) error {
func (server *LoginServer) ShardSelect(peer *protocol.CNPeer, pkt protocol.Packet) error {
var selection protocol.SP_CL2LS_REQ_CHAR_SELECT
pkt.Decode(&selection)
@@ -282,7 +282,7 @@ func (server *LoginServer) ShardSelect(peer *Peer, pkt protocol.Packet) error {
return peer.Send(protocol.P_LS2CL_REP_SHARD_SELECT_SUCC, resp)
}
func (server *LoginServer) FinishTutorial(peer *Peer, pkt protocol.Packet) error {
func (server *LoginServer) FinishTutorial(peer *protocol.CNPeer, pkt protocol.Packet) error {
var charPkt protocol.SP_CL2LS_REQ_SAVE_CHAR_TUTOR
pkt.Decode(&charPkt)

View File

@@ -15,7 +15,7 @@ type LoginServer struct {
port int
dbHndlr *db.DBHandler
packetHandlers map[uint32]PacketHandler
peers map[*Peer]bool
peers map[*protocol.CNPeer]bool
peersLock sync.Mutex
shard *ShardServer
}
@@ -30,7 +30,7 @@ func NewLoginServer(dbHndlr *db.DBHandler, port int) (*LoginServer, error) {
listener: listener,
port: port,
dbHndlr: dbHndlr,
peers: make(map[*Peer]bool),
peers: make(map[*protocol.CNPeer]bool),
}
server.packetHandlers = map[uint32]PacketHandler{
@@ -63,13 +63,13 @@ func (server *LoginServer) Start() {
return
}
client := NewPeer(server, conn)
client := protocol.NewCNPeer(server, conn)
server.Connect(client)
go client.Handler()
}
}
func (server *LoginServer) HandlePacket(peer *Peer, typeID uint32, pkt protocol.Packet) error {
func (server *LoginServer) HandlePacket(peer *protocol.CNPeer, typeID uint32, pkt protocol.Packet) error {
if hndlr, ok := server.packetHandlers[typeID]; ok {
if err := hndlr(peer, pkt); err != nil {
return err
@@ -81,14 +81,14 @@ func (server *LoginServer) HandlePacket(peer *Peer, typeID uint32, pkt protocol.
return nil
}
func (server *LoginServer) Disconnect(peer *Peer) {
func (server *LoginServer) Disconnect(peer *protocol.CNPeer) {
server.peersLock.Lock()
log.Printf("Peer %p disconnected from LOGIN\n", peer)
delete(server.peers, peer)
server.peersLock.Unlock()
}
func (server *LoginServer) Connect(peer *Peer) {
func (server *LoginServer) Connect(peer *protocol.CNPeer) {
server.peersLock.Lock()
log.Printf("New peer %p connected to LOGIN\n", peer)
server.peers[peer] = true

View File

@@ -1,148 +0,0 @@
package server
import (
"encoding/binary"
"fmt"
"io"
"log"
"net"
"github.com/CPunch/gopenfusion/protocol"
"github.com/CPunch/gopenfusion/protocol/pool"
)
const (
USE_E = iota
USE_FE
)
type PeerHandler interface {
HandlePacket(client *Peer, typeID uint32, pkt protocol.Packet) error
Connect(client *Peer)
Disconnect(client *Peer)
}
type Peer struct {
conn net.Conn
handler PeerHandler
SzID string
E_key []byte
FE_key []byte
AccountID int
whichKey int
alive bool
}
func NewPeer(handler PeerHandler, conn net.Conn) *Peer {
return &Peer{
conn: conn,
handler: handler,
SzID: "",
E_key: []byte(protocol.DEFAULT_KEY),
FE_key: nil,
AccountID: -1,
whichKey: USE_E,
alive: true,
}
}
func (peer *Peer) Send(typeID uint32, data ...interface{}) error {
// grab buffer from pool
buf := pool.Get()
defer pool.Put(buf)
// body start
pkt := protocol.NewPacket(buf)
// encode type id
if err := pkt.Encode(typeID); err != nil {
return err
}
// encode data
for _, trailer := range data {
if err := pkt.Encode(trailer); err != nil {
return err
}
}
// encrypt body
switch peer.whichKey {
case USE_E:
protocol.EncryptData(buf.Bytes(), peer.E_key)
case USE_FE:
protocol.EncryptData(buf.Bytes(), peer.FE_key)
}
// write packet size
if err := binary.Write(peer.conn, binary.LittleEndian, uint32(buf.Len())); err != nil {
return err
}
// write packet body
log.Printf("Sending %#v, sizeof: %d", data, buf.Len())
if _, err := peer.conn.Write(buf.Bytes()); err != nil {
return fmt.Errorf("[FATAL] failed to write packet body! %v", err)
}
return nil
}
func (peer *Peer) Kill() {
if !peer.alive {
return
}
peer.alive = false
peer.conn.Close()
peer.handler.Disconnect(peer)
}
func (peer *Peer) Handler() {
defer peer.Kill()
for {
// read packet size, the goroutine spends most of it's time parked here
var sz uint32
if err := binary.Read(peer.conn, binary.LittleEndian, &sz); err != nil {
log.Printf("[FATAL] failed to read packet size! %v\n", err)
return
}
// client should never send a packet size outside of this range
if sz > protocol.CN_PACKET_BUFFER_SIZE || sz < 4 {
log.Printf("[FATAL] malicious packet size received! %d", sz)
return
}
// grab buffer && read packet body
if err := func() error { // we wrap this in a closure so we can easily defer the buffer return to pool
buf := pool.Get()
defer pool.Put(buf)
if _, err := buf.ReadFrom(io.LimitReader(peer.conn, int64(sz))); err != nil {
return fmt.Errorf("failed to read packet body! %v", err)
}
// decrypt
protocol.DecryptData(buf.Bytes(), peer.E_key)
pkt := protocol.NewPacket(buf)
// create packet && read typeID
var typeID uint32
if err := pkt.Decode(&typeID); err != nil {
return fmt.Errorf("failed to read packet type! %v", err)
}
// dispatch packet
log.Printf("Got packet ID: %x, with a sizeof: %d\n", typeID, sz)
if err := peer.handler.HandlePacket(peer, typeID, pkt); err != nil {
return err
}
return nil
}(); err != nil {
log.Printf("[FATAL] %v", err)
return
}
}
}

View File

@@ -22,7 +22,7 @@ type ShardServer struct {
port int
dbHndlr *db.DBHandler
packetHandlers map[uint32]PacketHandler
peers sync.Map // [*Peer]*db.Player
peers sync.Map // [*protocol.CNPeer]*db.Player
loginMetadataQueue sync.Map // [int64]*LoginMetadata w/ int64 = serialKey
}
@@ -39,7 +39,9 @@ func NewShardServer(dbHndlr *db.DBHandler, port int) (*ShardServer, error) {
packetHandlers: make(map[uint32]PacketHandler),
}
server.packetHandlers = map[uint32]PacketHandler{}
server.packetHandlers = map[uint32]PacketHandler{
protocol.P_CL2FE_REQ_PC_ENTER: server.RequestEnter,
}
return server, nil
}
@@ -58,13 +60,13 @@ func (server *ShardServer) Start() {
return
}
client := NewPeer(server, conn)
client := protocol.NewCNPeer(server, conn)
server.Connect(client)
go client.Handler()
}
}
func (server *ShardServer) HandlePacket(peer *Peer, typeID uint32, pkt protocol.Packet) error {
func (server *ShardServer) HandlePacket(peer *protocol.CNPeer, typeID uint32, pkt protocol.Packet) error {
if hndlr, ok := server.packetHandlers[typeID]; ok {
if err := hndlr(peer, pkt); err != nil {
return err
@@ -76,24 +78,24 @@ func (server *ShardServer) HandlePacket(peer *Peer, typeID uint32, pkt protocol.
return nil
}
func (server *ShardServer) Disconnect(peer *Peer) {
func (server *ShardServer) Disconnect(peer *protocol.CNPeer) {
log.Printf("Peer %p disconnected from SHARD\n", peer)
server.peers.Delete(peer)
}
func (server *ShardServer) Connect(peer *Peer) {
func (server *ShardServer) Connect(peer *protocol.CNPeer) {
log.Printf("New peer %p connected to SHARD\n", peer)
server.peers.Store(peer, nil)
}
func (server *ShardServer) JoinPlayer(peer *Peer, player *db.Player) {
func (server *ShardServer) JoinPlayer(peer *protocol.CNPeer, player *db.Player) {
server.peers.Store(peer, player)
}
// Simple wrapper for server.peers.Range, if f returns false the iteration is stopped.
func (server *ShardServer) RangePeers(f func(peer *Peer, player *db.Player) bool) {
func (server *ShardServer) RangePeers(f func(peer *protocol.CNPeer, player *db.Player) bool) {
server.peers.Range(func(key, value any) bool { // simple wrapper to cast the datatypes
peer, ok := key.(*Peer)
peer, ok := key.(*protocol.CNPeer)
if !ok { // this should never happen
panic(fmt.Errorf("ShardServer.peers has an invalid key: peers[%#v] = %#v", key, value))
}

View File

@@ -4,6 +4,6 @@ import (
"github.com/CPunch/gopenfusion/protocol"
)
type PacketHandler func(peer *Peer, pkt protocol.Packet) error
type PacketHandler func(peer *protocol.CNPeer, pkt protocol.Packet) error
func stubbedPacket(_ *Peer, _ protocol.Packet) error { /* stubbed */ return nil }
func stubbedPacket(_ *protocol.CNPeer, _ protocol.Packet) error { /* stubbed */ return nil }