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:
CPunch 2023-03-18 16:40:20 -05:00
parent 1357de99aa
commit 735bdc5b36
6 changed files with 50 additions and 46 deletions

View File

@ -1,4 +1,4 @@
package server package protocol
import ( import (
"encoding/binary" "encoding/binary"
@ -7,7 +7,6 @@ import (
"log" "log"
"net" "net"
"github.com/CPunch/gopenfusion/protocol"
"github.com/CPunch/gopenfusion/protocol/pool" "github.com/CPunch/gopenfusion/protocol/pool"
) )
@ -17,12 +16,12 @@ const (
) )
type PeerHandler interface { type PeerHandler interface {
HandlePacket(client *Peer, typeID uint32, pkt protocol.Packet) error HandlePacket(client *CNPeer, typeID uint32, pkt Packet) error
Connect(client *Peer) Disconnect(client *CNPeer)
Disconnect(client *Peer)
} }
type Peer struct { // CNPeer is a simple wrapper for net.Conn connections to send/recv packets over the Fusionfall packet protocol.
type CNPeer struct {
conn net.Conn conn net.Conn
handler PeerHandler handler PeerHandler
SzID string SzID string
@ -33,12 +32,12 @@ type Peer struct {
alive bool alive bool
} }
func NewPeer(handler PeerHandler, conn net.Conn) *Peer { func NewCNPeer(handler PeerHandler, conn net.Conn) *CNPeer {
return &Peer{ return &CNPeer{
conn: conn, conn: conn,
handler: handler, handler: handler,
SzID: "", SzID: "",
E_key: []byte(protocol.DEFAULT_KEY), E_key: []byte(DEFAULT_KEY),
FE_key: nil, FE_key: nil,
AccountID: -1, AccountID: -1,
whichKey: USE_E, whichKey: USE_E,
@ -46,13 +45,13 @@ func NewPeer(handler PeerHandler, conn net.Conn) *Peer {
} }
} }
func (peer *Peer) Send(typeID uint32, data ...interface{}) error { func (peer *CNPeer) Send(typeID uint32, data ...interface{}) error {
// grab buffer from pool // grab buffer from pool
buf := pool.Get() buf := pool.Get()
defer pool.Put(buf) defer pool.Put(buf)
// body start // body start
pkt := protocol.NewPacket(buf) pkt := NewPacket(buf)
// encode type id // encode type id
if err := pkt.Encode(typeID); err != nil { if err := pkt.Encode(typeID); err != nil {
@ -69,9 +68,9 @@ func (peer *Peer) Send(typeID uint32, data ...interface{}) error {
// encrypt body // encrypt body
switch peer.whichKey { switch peer.whichKey {
case USE_E: case USE_E:
protocol.EncryptData(buf.Bytes(), peer.E_key) EncryptData(buf.Bytes(), peer.E_key)
case USE_FE: case USE_FE:
protocol.EncryptData(buf.Bytes(), peer.FE_key) EncryptData(buf.Bytes(), peer.FE_key)
} }
// write packet size // write packet size
@ -88,7 +87,7 @@ func (peer *Peer) Send(typeID uint32, data ...interface{}) error {
return nil return nil
} }
func (peer *Peer) Kill() { func (peer *CNPeer) Kill() {
if !peer.alive { if !peer.alive {
return return
} }
@ -98,7 +97,8 @@ func (peer *Peer) Kill() {
peer.handler.Disconnect(peer) peer.handler.Disconnect(peer)
} }
func (peer *Peer) Handler() { // meant to be invoked as a goroutine
func (peer *CNPeer) Handler() {
defer peer.Kill() defer peer.Kill()
for { for {
@ -110,7 +110,7 @@ func (peer *Peer) Handler() {
} }
// client should never send a packet size outside of this range // client should never send a packet size outside of this range
if sz > protocol.CN_PACKET_BUFFER_SIZE || sz < 4 { if sz > CN_PACKET_BUFFER_SIZE || sz < 4 {
log.Printf("[FATAL] malicious packet size received! %d", sz) log.Printf("[FATAL] malicious packet size received! %d", sz)
return return
} }
@ -124,8 +124,8 @@ func (peer *Peer) Handler() {
} }
// decrypt // decrypt
protocol.DecryptData(buf.Bytes(), peer.E_key) DecryptData(buf.Bytes(), peer.E_key)
pkt := protocol.NewPacket(buf) pkt := NewPacket(buf)
// create packet && read typeID // create packet && read typeID
var typeID uint32 var typeID uint32

View File

@ -2,7 +2,9 @@ package server
import "github.com/CPunch/gopenfusion/protocol" 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 return nil
} }

View File

@ -23,7 +23,7 @@ const (
LOGIN_UPDATED_EUALA_REQUIRED = 9 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 peer.SzID = SzID
resp := protocol.SP_LS2CL_REP_LOGIN_SUCC{ resp := protocol.SP_LS2CL_REP_LOGIN_SUCC{
@ -61,7 +61,7 @@ func (server *LoginServer) AcceptLogin(peer *Peer, SzID string, IClientVerC int3
return nil 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 var loginPkt protocol.SP_CL2LS_REQ_LOGIN
pkt.Decode(&loginPkt) 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)]) 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 var charPkt protocol.SP_CL2LS_REQ_CHECK_CHAR_NAME
pkt.Decode(&charPkt) 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 var charPkt protocol.SP_CL2LS_REQ_SAVE_CHAR_NAME
pkt.Decode(&charPkt) pkt.Decode(&charPkt)
@ -200,7 +200,7 @@ func validateCharacterCreation(character *protocol.SP_CL2LS_REQ_CHAR_CREATE) boo
return true 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{ if err := peer.Send(protocol.P_LS2CL_REP_SHARD_SELECT_FAIL, protocol.SP_LS2CL_REP_SHARD_SELECT_FAIL{
IErrorCode: 2, IErrorCode: 2,
}); err != nil { }); err != nil {
@ -210,7 +210,7 @@ func SendFail(peer *Peer) error {
return nil 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 var charPkt protocol.SP_CL2LS_REQ_CHAR_CREATE
pkt.Decode(&charPkt) 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 var charPkt protocol.SP_CL2LS_REQ_CHAR_DELETE
pkt.Decode(&charPkt) 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 var selection protocol.SP_CL2LS_REQ_CHAR_SELECT
pkt.Decode(&selection) 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) 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 var charPkt protocol.SP_CL2LS_REQ_SAVE_CHAR_TUTOR
pkt.Decode(&charPkt) pkt.Decode(&charPkt)

View File

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

View File

@ -22,7 +22,7 @@ type ShardServer struct {
port int port int
dbHndlr *db.DBHandler dbHndlr *db.DBHandler
packetHandlers map[uint32]PacketHandler 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 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), 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 return server, nil
} }
@ -58,13 +60,13 @@ func (server *ShardServer) Start() {
return return
} }
client := NewPeer(server, conn) client := protocol.NewCNPeer(server, conn)
server.Connect(client) server.Connect(client)
go client.Handler() 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 hndlr, ok := server.packetHandlers[typeID]; ok {
if err := hndlr(peer, pkt); err != nil { if err := hndlr(peer, pkt); err != nil {
return err return err
@ -76,24 +78,24 @@ func (server *ShardServer) HandlePacket(peer *Peer, typeID uint32, pkt protocol.
return nil return nil
} }
func (server *ShardServer) Disconnect(peer *Peer) { func (server *ShardServer) Disconnect(peer *protocol.CNPeer) {
log.Printf("Peer %p disconnected from SHARD\n", peer) log.Printf("Peer %p disconnected from SHARD\n", peer)
server.peers.Delete(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) log.Printf("New peer %p connected to SHARD\n", peer)
server.peers.Store(peer, nil) 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) server.peers.Store(peer, player)
} }
// Simple wrapper for server.peers.Range, if f returns false the iteration is stopped. // 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 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 if !ok { // this should never happen
panic(fmt.Errorf("ShardServer.peers has an invalid key: peers[%#v] = %#v", key, value)) 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" "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 }