📄 serverany.cpp.svn-base
字号:
#include "RStdAfx.h"
WServerHandler WServer::PHandlers[IMSG_NUM_TYPES];
void WServer::InitHandlers()
{
memset(PHandlers, 0, sizeof(void*) * IMSG_NUM_TYPES);
PHandlers[ICMSG_REGISTER_WORKER] = &WServer::HandleRegisterWorker;
PHandlers[ICMSG_WOW_PACKET] = &WServer::HandleWoWPacket;
PHandlers[ICMSG_PLAYER_LOGIN_RESULT] = &WServer::HandlePlayerLoginResult;
PHandlers[ICMSG_PLAYER_LOGOUT] = &WServer::HandlePlayerLogout;
PHandlers[ICMSG_TELEPORT_REQUEST] = &WServer::HandleTeleportRequest;
}
WServer::WServer(uint32 id, WSSocket * s) : m_id(id), m_socket(s)
{
}
void WServer::HandleRegisterWorker(WorldPacket & pck)
{
vector<uint32> preferred;
uint32 build;
pck >> build >> preferred;
/* send a packed packet of all online players to this server */
sClientMgr.SendPackedClientInfo(this);
/* allocate initial PVPs for this worker */
sClusterMgr.AllocateInitialPVPs(this, preferred);
}
void WServer::HandleWoWPacket(WorldPacket & pck)
{
uint32 sessionid, size;
uint16 opcode;
/* get session */
pck >> sessionid >> opcode >> size;
Session * session = sClientMgr.GetSession(sessionid);
if(!session) return;
/* write it to that session's output buffer */
WorldSocket * s = session->GetSocket();
if(s) s->OutPacket(opcode, size, size ? ((const void*)(pck.contents() + 10)) : 0);
}
void WServer::HandlePlayerLogout(WorldPacket & pck)
{
uint32 sessionid, guid;
pck >> sessionid >> guid;
RPlayerInfo * pi = sClientMgr.GetRPlayer(guid);
Session * s = sClientMgr.GetSession(sessionid);
if(pi && s)
{
/* tell all other servers this player has gone offline */
WorldPacket data(ISMSG_DESTROY_PLAYER_INFO, 4);
data << guid;
sClusterMgr.DistributePacketToAll(&data, this);
/* clear the player from the session */
s->ClearCurrentPlayer();
s->ClearServers();
/* destroy the playerinfo struct here */
sClientMgr.DestroyRPlayerInfo(guid);
}
}
void WServer::HandleTeleportRequest(WorldPacket & pck)
{
WorldPacket data(ISMSG_TELEPORT_RESULT, 100);
RPlayerInfo * pi;
Session * s;
PVP * dest;
uint32 mapid, sessionid, PVPid;
/* this packet is only used upon changing main maps! */
pck >> sessionid >> mapid >> PVPid;
s = sClientMgr.GetSession(sessionid);
if(s)
{
pi = s->GetPlayer();
ASSERT(pi);
/* find the destination server */
if(PVPid == 0)
dest = sClusterMgr.GetPVPByMapId(mapid);
else
dest = sClusterMgr.GetPVPByPVPId(PVPid);
/* server up? */
if(!dest)
{
data.Initialize(SMSG_TRANSFER_ABORTED);
data << uint32(0x02); // PVP_ABORT_NOT_FOUND
s->SendPacket(&data);
}
else
{
/* server found! */
LocationVector vec;
pck >> vec >> vec.o;
pi->MapId = mapid;
pi->PVPId = dest->PVPId;
pi->PositionX = vec.x;
pi->PositionY = vec.y;
if(dest->Server == s->GetServer())
{
/* we're not changing servers, the new PVP is on the same server */
data << sessionid << uint8(1) << mapid << PVPid << vec << vec.o;
SendPacket(&data);
}
else
{
/* notify the old server to pack the player info together to send to the new server, and delete the player */
data << sessionid << uint8(0) << mapid << PVPid << vec << vec.o;
SendPacket(&data);
}
data.Initialize(ISMSG_PLAYER_INFO);
pi->Pack(data);
sClusterMgr.DistributePacketToAll(&data, this);
data.Initialize(SMSG_Venice_WORLD);
data << mapid << vec << vec.o;
s->SendPacket(&data);
}
}
}
void WServer::HandlePlayerLoginResult(WorldPacket & pck)
{
uint32 guid, sessionid;
uint8 result;
pck >> guid >> sessionid >> result;
if(result)
{
Log.Success("WServer", "Worldserver %u reports successful login of player %u", m_id, guid);
Session * s = sClientMgr.GetSession(sessionid);
if(s)
{
/* update server */
s->SetNextServer();
/* pack together a player info packet and distribute it to all the other servers */
ASSERT(s->GetPlayer());
WorldPacket data(ISMSG_PLAYER_INFO, 100);
s->GetPlayer()->Pack(data);
sClusterMgr.DistributePacketToAll(&data, this);
}
}
else
{
Log.Error("WServer", "Worldserver %u reports failed login of player %u", m_id, guid);
Session * s = sClientMgr.GetSession(sessionid);
if(s)
{
s->ClearCurrentPlayer();
s->ClearServers();
}
sClientMgr.DestroyRPlayerInfo(guid);
}
}
void WServer::Update()
{
WorldPacket * pck;
uint16 opcode;
while((pck = m_recvQueue.Pop()))
{
opcode = pck->GetOpcode();
if(opcode < IMSG_NUM_TYPES && WServer::PHandlers[opcode] != 0)
(this->*WServer::PHandlers[opcode])(*pck);
else
Log.Error("WServer", "Unhandled packet %u\n", opcode);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -