Merge PR #4: Packet Handling Refactor
* more detailed logging of packets * rename handlers to be less redundant * straggler file * packet handling refactor * get config ref
This commit is contained in:
parent
e32a74c9e1
commit
f6856b3b42
|
@ -34,6 +34,8 @@ type Session interface {
|
|||
Queue(packet *packets.OutgoingPacket)
|
||||
Flush(packet *packets.OutgoingPacket)
|
||||
Database() *sql.DB
|
||||
Address() string
|
||||
GetPacketHandler(headerId int) (func(*Player, *packets.IncomingPacket), bool)
|
||||
Close()
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +1,29 @@
|
|||
package log
|
||||
|
||||
import (
|
||||
"github.com/jtieri/HabbGo/habbgo/game/player"
|
||||
"github.com/jtieri/HabbGo/habbgo/protocol/packets"
|
||||
"log"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func PrintOutgoingPacket(p *packets.OutgoingPacket) {
|
||||
|
||||
func PrintOutgoingPacket(playerAddr string, p *packets.OutgoingPacket) {
|
||||
log.Printf("[%v] [OUTGOING] [%v - %v] contents: %v ", playerAddr, p.Header, p.HeaderId, p.Payload.String())
|
||||
}
|
||||
|
||||
func PrintIncomingPacket(p *packets.IncomingPacket) {
|
||||
log.Printf("Received packet [%v - %v] with contents: %v ", p.Header, p.HeaderId, p.Payload.String())
|
||||
func PrintIncomingPacket(playerAddr string, handler func(*player.Player, *packets.IncomingPacket), p *packets.IncomingPacket) {
|
||||
hName := getHandlerName(runtime.FuncForPC(reflect.ValueOf(handler).Pointer()).Name())
|
||||
log.Printf("[%v] [INCOMING] [%v - %v|%v] contents: %v ", playerAddr, hName, p.Header, p.HeaderId, p.Payload.String())
|
||||
}
|
||||
|
||||
func PrintUnkownPacket(p *packets.IncomingPacket) {
|
||||
|
||||
func PrintUnkownPacket(playerAddr string, p *packets.IncomingPacket) {
|
||||
log.Printf("[%v] [UNK] [%v - %v] contents: %v ", playerAddr, p.Header, p.HeaderId, p.Payload.String())
|
||||
}
|
||||
|
||||
func getHandlerName(handler string) string {
|
||||
sp := strings.Split(handler, "/") // e.g. github.com/jtieri/HabbGo/habbgo/protocol/handlers.GenerateKey
|
||||
s2 := sp[len(sp)-1] // e.g. handlers.GenerateKey
|
||||
return strings.Split(s2, ".")[1] // e.g. GenerateKey
|
||||
}
|
||||
|
|
|
@ -1,24 +1,27 @@
|
|||
package handlers
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
import (
|
||||
"github.com/jtieri/HabbGo/habbgo/game/player"
|
||||
"github.com/jtieri/HabbGo/habbgo/protocol/composers"
|
||||
"github.com/jtieri/HabbGo/habbgo/protocol/packets"
|
||||
)
|
||||
|
||||
func HandleInitCrypto(player *player.Player, packet *packets.IncomingPacket) {
|
||||
func InitCrypto(player *player.Player, packet *packets.IncomingPacket) {
|
||||
player.Session.Send(composers.ComposeCryptoParams())
|
||||
}
|
||||
|
||||
func HandleGenerateKey(player *player.Player, packet *packets.IncomingPacket) {
|
||||
func GenerateKey(player *player.Player, packet *packets.IncomingPacket) {
|
||||
player.Session.Send(composers.ComposeEndCrypto())
|
||||
}
|
||||
|
||||
func HandleGetSessionParams(player *player.Player, packet *packets.IncomingPacket) {
|
||||
func GetSessionParams(player *player.Player, packet *packets.IncomingPacket) {
|
||||
player.Session.Send(composers.ComposeSessionParams())
|
||||
}
|
||||
|
||||
func HandleSSO(p *player.Player, packet *packets.IncomingPacket) {
|
||||
func SSO(p *player.Player, packet *packets.IncomingPacket) {
|
||||
token := packet.ReadString()
|
||||
|
||||
// TODO if p login with token is success login, otherwise send LOCALISED ERROR & disconnect from server
|
||||
|
@ -29,7 +32,7 @@ func HandleSSO(p *player.Player, packet *packets.IncomingPacket) {
|
|||
}
|
||||
}
|
||||
|
||||
func HandleTryLogin(p *player.Player, packet *packets.IncomingPacket) {
|
||||
func TryLogin(p *player.Player, packet *packets.IncomingPacket) {
|
||||
username := packet.ReadString()
|
||||
password := packet.ReadString()
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"github.com/jtieri/HabbGo/habbgo/protocol/packets"
|
||||
)
|
||||
|
||||
func HandleNavigate(player *player.Player, packet *packets.IncomingPacket) {
|
||||
func Navigate(player *player.Player, packet *packets.IncomingPacket) {
|
||||
roomService := room.RoomService()
|
||||
|
||||
nodeMask := packet.ReadInt() == 1
|
||||
|
|
|
@ -6,23 +6,23 @@ import (
|
|||
"github.com/jtieri/HabbGo/habbgo/protocol/packets"
|
||||
)
|
||||
|
||||
func HandleGetInfo(player *player.Player, packet *packets.IncomingPacket) {
|
||||
func GetInfo(player *player.Player, packet *packets.IncomingPacket) {
|
||||
player.Session.Send(composers.ComposeUserObj(player))
|
||||
}
|
||||
|
||||
func HandleGetCredits(player *player.Player, packet *packets.IncomingPacket) {
|
||||
func GetCredits(player *player.Player, packet *packets.IncomingPacket) {
|
||||
player.Session.Send(composers.ComposeCreditBalance(player.Details.Credits))
|
||||
}
|
||||
|
||||
func HandleGetAvailableBadges(player *player.Player, packet *packets.IncomingPacket) {
|
||||
func GetAvailableBadges(player *player.Player, packet *packets.IncomingPacket) {
|
||||
player.Session.Send(composers.ComposeAvailableBadges(player))
|
||||
}
|
||||
|
||||
func HandleGetSoundSetting(player *player.Player, packet *packets.IncomingPacket) {
|
||||
func GetSoundSetting(player *player.Player, packet *packets.IncomingPacket) {
|
||||
player.Session.Send(composers.ComposeSoundSetting(player.Details.SoundEnabled))
|
||||
}
|
||||
|
||||
func HandleTestLatency(player *player.Player, packet *packets.IncomingPacket) {
|
||||
func TestLatency(player *player.Player, packet *packets.IncomingPacket) {
|
||||
l := packet.ReadInt()
|
||||
player.Session.Send(composers.ComposeLatency(l))
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"github.com/jtieri/HabbGo/habbgo/game/player"
|
||||
"github.com/jtieri/HabbGo/habbgo/protocol/handlers"
|
||||
"github.com/jtieri/HabbGo/habbgo/protocol/packets"
|
||||
)
|
||||
|
||||
type Router struct {
|
||||
RegisteredPackets map[int]func(*player.Player, *packets.IncomingPacket)
|
||||
}
|
||||
|
||||
func (r *Router) GetHandler(headerId int) (func(*player.Player, *packets.IncomingPacket), bool) {
|
||||
h, found := r.RegisteredPackets[headerId]
|
||||
return h, found
|
||||
}
|
||||
|
||||
func RegisterHandlers() (r *Router) {
|
||||
r = &Router{RegisteredPackets: make(map[int]func(p *player.Player, packet *packets.IncomingPacket))}
|
||||
|
||||
r.RegisterHandshakeHandlers()
|
||||
r.RegisterPlayerHandlers()
|
||||
r.RegisterNavigatorHandlers()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (r *Router) RegisterHandshakeHandlers() {
|
||||
r.RegisteredPackets[206] = handlers.InitCrypto
|
||||
r.RegisteredPackets[202] = handlers.GenerateKey // older clients
|
||||
r.RegisteredPackets[2002] = handlers.GenerateKey // newer clients
|
||||
// 207 - SECRETKEY
|
||||
// 5 - VERSIONCHECK in older clients
|
||||
// 1170 - VERSIONCHECK in later clients? v26+?
|
||||
// TODO figure out exact client revisions when these packet headers change
|
||||
// 6 - UNIQUEID
|
||||
r.RegisteredPackets[181] = handlers.GetSessionParams
|
||||
r.RegisteredPackets[204] = handlers.SSO
|
||||
r.RegisteredPackets[4] = handlers.TryLogin
|
||||
}
|
||||
|
||||
func (r *Router) RegisterPlayerHandlers() {
|
||||
r.RegisteredPackets[7] = handlers.GetInfo
|
||||
r.RegisteredPackets[8] = handlers.GetCredits
|
||||
r.RegisteredPackets[157] = handlers.GetAvailableBadges
|
||||
r.RegisteredPackets[228] = handlers.GetSoundSetting
|
||||
r.RegisteredPackets[315] = handlers.TestLatency
|
||||
}
|
||||
|
||||
func (r *Router) RegisterNavigatorHandlers() {
|
||||
r.RegisteredPackets[150] = handlers.Navigate
|
||||
// 151: GETUSERFLATCATS
|
||||
// 21: GETFLATINFO
|
||||
// 23: DELETEFLAT
|
||||
// 24: UPDATEFLAT
|
||||
// 25: SETFLATINFO
|
||||
// 13: SBUSYF
|
||||
// 152: GETFLATCAT
|
||||
// 153: SETFLATCAT
|
||||
// 155: REMOVEALLRIGHTS
|
||||
// 156: GETPARENTCHAIN
|
||||
// 16: SUSERF
|
||||
// 264: GET_RECOMMENDED_ROOMS
|
||||
// 17: SRCHF
|
||||
// 154: GETSPACENODEUSERS
|
||||
// 18: GETFVRF
|
||||
// 19: ADD_FAVORITE_ROOM
|
||||
// 20: DEL_FAVORITE_ROOM
|
||||
}
|
|
@ -2,85 +2,22 @@ package server
|
|||
|
||||
import (
|
||||
"github.com/jtieri/HabbGo/habbgo/game/player"
|
||||
"github.com/jtieri/HabbGo/habbgo/protocol/handlers"
|
||||
logger "github.com/jtieri/HabbGo/habbgo/log"
|
||||
"github.com/jtieri/HabbGo/habbgo/protocol/packets"
|
||||
"log"
|
||||
)
|
||||
|
||||
func Handle(player *player.Player, packet *packets.IncomingPacket) {
|
||||
switch packet.HeaderId {
|
||||
// Handshake Packets ----------------------------------------------------------------------------------------------
|
||||
case 206: // INIT_CRYPTO
|
||||
handlers.HandleInitCrypto(player, packet)
|
||||
case 202: // GENERATEKEY
|
||||
handlers.HandleGenerateKey(player, packet)
|
||||
case 2002:
|
||||
handlers.HandleGenerateKey(player, packet)
|
||||
case 207: // SECRETKEY
|
||||
func Handle(p *player.Player, packet *packets.IncomingPacket) {
|
||||
handler, found := p.Session.GetPacketHandler(packet.HeaderId)
|
||||
|
||||
case 5: // VERSIONCHECK
|
||||
|
||||
case 6: // UNIQUEID
|
||||
|
||||
case 181: // GET_SESSION_PARAMETERS
|
||||
handlers.HandleGetSessionParams(player, packet)
|
||||
case 204: // SSO
|
||||
handlers.HandleSSO(player, packet)
|
||||
case 4: // TRY LOGIN - used when SSO is disabled
|
||||
handlers.HandleTryLogin(player, packet)
|
||||
|
||||
// Player Packets -------------------------------------------------------------------------------------------------
|
||||
case 7: // GET_INFO
|
||||
handlers.HandleGetInfo(player, packet)
|
||||
case 8: // GET_CREDITS
|
||||
handlers.HandleGetCredits(player, packet)
|
||||
case 157: // GETAVAILABLEBADGES
|
||||
handlers.HandleGetAvailableBadges(player, packet)
|
||||
case 228: // GET_SOUND_SETTING
|
||||
handlers.HandleGetSoundSetting(player, packet)
|
||||
case 315: // TEST_LATENCY ---> Init Latency Test
|
||||
handlers.HandleTestLatency(player, packet)
|
||||
|
||||
// Navigator Packets ----------------------------------------------------------------------------------------------
|
||||
case 150: // NAVIGATE
|
||||
//handlers.HandleNavigate(player, packet)
|
||||
case 151: // GETUSERFLATCATS
|
||||
|
||||
case 21: // GETFLATINFO
|
||||
|
||||
case 23: // DELETEFLAT
|
||||
|
||||
case 24: // UPDATEFLAT
|
||||
|
||||
case 25: // SETFLATINFO
|
||||
|
||||
case 13: // SBUSYF
|
||||
|
||||
case 152: // GETFLATCAT
|
||||
|
||||
case 153: // SETFLATCAT
|
||||
|
||||
case 155: // REMOVEALLRIGHTS
|
||||
|
||||
case 156: // GETPARENTCHAIN
|
||||
|
||||
case 16: // SUSERF
|
||||
|
||||
case 264: // GET_RECOMMENDED_ROOMS
|
||||
|
||||
case 17: //SRCHF
|
||||
|
||||
case 154: // GETSPACENODEUSERS
|
||||
|
||||
case 18: // GETFVRF
|
||||
|
||||
case 19: // ADD_FAVORITE_ROOM
|
||||
|
||||
case 20: // DEL_FAVORITE_ROOM
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------------
|
||||
default:
|
||||
log.Printf("No registered handler for packet [%v - %v], it's payload contained %v ",
|
||||
packet.Header, packet.HeaderId, packet.Payload.String())
|
||||
if found {
|
||||
if GetConfig().Server.Debug {
|
||||
logger.PrintIncomingPacket(p.Session.Address(), handler, packet)
|
||||
}
|
||||
handler(p, packet)
|
||||
} else {
|
||||
if GetConfig().Server.Debug {
|
||||
logger.PrintUnkownPacket(p.Session.Address(), packet)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,25 +10,27 @@ import (
|
|||
"sync"
|
||||
)
|
||||
|
||||
var Config *config.Config
|
||||
|
||||
type Server struct {
|
||||
Config *config.Config
|
||||
Database *sql.DB
|
||||
activeSessions []*Session
|
||||
}
|
||||
|
||||
// New returns a pointer to a newly allocated server struct.
|
||||
func New(config *config.Config, db *sql.DB) *Server {
|
||||
Config = config
|
||||
|
||||
return &Server{
|
||||
Config: config,
|
||||
Database: db,
|
||||
}
|
||||
}
|
||||
|
||||
// Start will setup the game server, start listening for incoming connections, and handle connections appropriately.
|
||||
func (server *Server) Start() {
|
||||
listener, err := net.Listen("tcp", server.Config.Server.Host+":"+strconv.Itoa(server.Config.Server.Port))
|
||||
listener, err := net.Listen("tcp", Config.Server.Host+":"+strconv.Itoa(Config.Server.Port))
|
||||
if err != nil {
|
||||
log.Fatalf("There was an issue starting the game server on port %v.", server.Config.Server.Port) // TODO properly handle errors
|
||||
log.Fatalf("There was an issue starting the game server on port %v.", Config.Server.Port) // TODO properly handle errors
|
||||
}
|
||||
log.Printf("Successfully started the game server at %v", listener.Addr().String())
|
||||
defer listener.Close()
|
||||
|
@ -44,7 +46,7 @@ func (server *Server) Start() {
|
|||
|
||||
// Check that there aren't multiple sessions for a given IP address
|
||||
// TODO kick a session to make room for the new one
|
||||
if server.sessionsFromSameAddr(conn) < server.Config.Server.MaxConns {
|
||||
if server.sessionsFromSameAddr(conn) < Config.Server.MaxConns {
|
||||
session := NewSession(conn, server)
|
||||
|
||||
log.Printf("New session created for address: %v", conn.LocalAddr().String())
|
||||
|
@ -94,3 +96,7 @@ func (server *Server) sessionsFromSameAddr(conn net.Conn) int {
|
|||
|
||||
return count
|
||||
}
|
||||
|
||||
func GetConfig() *config.Config {
|
||||
return Config
|
||||
}
|
||||
|
|
|
@ -4,8 +4,10 @@ import (
|
|||
"bufio"
|
||||
"bytes"
|
||||
"database/sql"
|
||||
logger "github.com/jtieri/HabbGo/habbgo/log"
|
||||
"log"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/jtieri/HabbGo/habbgo/game/player"
|
||||
|
@ -20,6 +22,7 @@ type Session struct {
|
|||
buffer *buffer
|
||||
active bool
|
||||
server *Server
|
||||
router *Router
|
||||
}
|
||||
|
||||
type buffer struct {
|
||||
|
@ -35,6 +38,7 @@ func NewSession(conn net.Conn, server *Server) *Session {
|
|||
buffer: &buffer{mux: sync.Mutex{}, buff: bufio.NewWriter(conn)},
|
||||
active: true,
|
||||
server: server,
|
||||
router: RegisterHandlers(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,11 +82,6 @@ func (session *Session) Listen() {
|
|||
|
||||
packet := packets.NewIncoming(rawHeader, payload)
|
||||
|
||||
if session.server.Config.Server.Debug {
|
||||
log.Printf("Received packet [%v - %v] with contents: %v ",
|
||||
packet.Header, packet.HeaderId, packet.Payload.String())
|
||||
}
|
||||
|
||||
go Handle(p, packet) // Handle packets coming in from p's Session
|
||||
}
|
||||
}
|
||||
|
@ -95,16 +94,16 @@ func (session *Session) Send(packet *packets.OutgoingPacket) {
|
|||
|
||||
_, err := session.buffer.buff.Write(packet.Payload.Bytes())
|
||||
if err != nil {
|
||||
log.Printf("Error sending packet %v to session %v \n %v ", packet.Header, session.connection.LocalAddr(), err)
|
||||
log.Printf("Error sending packet %v to session %v \n %v ", packet.Header, session.Address(), err)
|
||||
}
|
||||
|
||||
err = session.buffer.buff.Flush()
|
||||
if err != nil {
|
||||
log.Printf("Error sending packet %v to session %v \n %v ", packet.Header, session.connection.LocalAddr(), err)
|
||||
log.Printf("Error sending packet %v to session %v \n %v ", packet.Header, session.Address(), err)
|
||||
}
|
||||
|
||||
if session.server.Config.Server.Debug {
|
||||
log.Printf("Sent packet [%v - %v] with contents: %v ", packet.Header, packet.HeaderId, packet.String())
|
||||
if Config.Server.Debug {
|
||||
logger.PrintOutgoingPacket(session.Address(), packet)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,7 +115,7 @@ func (session *Session) Queue(packet *packets.OutgoingPacket) {
|
|||
|
||||
_, err := session.buffer.buff.Write(packet.Payload.Bytes())
|
||||
if err != nil {
|
||||
log.Printf("Error sending packet %v to session %v \n %v ", packet.Header, session.connection.LocalAddr(), err)
|
||||
log.Printf("Error sending packet %v to session %v \n %v ", packet.Header, session.Address(), err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,11 +126,11 @@ func (session *Session) Flush(packet *packets.OutgoingPacket) {
|
|||
|
||||
err := session.buffer.buff.Flush()
|
||||
if err != nil {
|
||||
log.Printf("Error sending packet %v to session %v \n %v ", packet.Header, session.connection.LocalAddr(), err)
|
||||
log.Printf("Error sending packet %v to session %v \n %v ", packet.Header, session.Address(), err)
|
||||
}
|
||||
|
||||
if session.server.Config.Server.Debug {
|
||||
log.Printf("Sent packet [%v - %v] with contents: %v ", packet.Header, packet.HeaderId, packet.String())
|
||||
if Config.Server.Debug {
|
||||
logger.PrintOutgoingPacket(session.Address(), packet)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,9 +139,17 @@ func (session *Session) Database() *sql.DB {
|
|||
return session.database
|
||||
}
|
||||
|
||||
func (session *Session) GetPacketHandler(headerId int) (func(*player.Player, *packets.IncomingPacket), bool) {
|
||||
return session.router.GetHandler(headerId)
|
||||
}
|
||||
|
||||
func (session *Session) Address() string {
|
||||
return strings.Split(session.connection.RemoteAddr().String(), ":")[0] // split ip:port at : and return ip part
|
||||
}
|
||||
|
||||
// Close disconnects a Session from the server.
|
||||
func (session *Session) Close() {
|
||||
log.Printf("Closing session for address: %v ", session.connection.LocalAddr())
|
||||
log.Printf("Closing session for address: %v ", session.Address())
|
||||
session.server.RemoveSession(session)
|
||||
session.server = nil
|
||||
session.buffer = nil
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package controller
|
||||
|
||||
import "github.com/gin-gonic/gin"
|
||||
|
||||
func GetClient(c *gin.Context) {
|
||||
//fmt.Println("Inside GetIndex() .....")
|
||||
c.File("./client/client.html")
|
||||
}
|
Loading…
Reference in New Issue