mirror of
https://github.com/CPunch/gopenfusion.git
synced 2025-10-06 01:30:07 +00:00
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:
@@ -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
|
||||
}
|
||||
|
@@ -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)
|
||||
|
||||
|
@@ -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
|
||||
|
148
server/peer.go
148
server/peer.go
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
@@ -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))
|
||||
}
|
||||
|
@@ -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 }
|
||||
|
Reference in New Issue
Block a user