⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serverany.cpp.svn-base

📁 絲路server源碼 Silk Road server source
💻 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 + -