📄 usermanager.cpp
字号:
#include "../Common.h"
#include "../CallbackHandler.h"
#include "../NetCode/OpCodes.h"
#include "../NetCode/Packet.h"
#include "UserManager.h"
#include "ObjectManager.h"
#include "Object.h"
UserManager::UserManager(void) {
objman = WorldThread::GetThread()->GetObjectManager();
PacketHandler *p = WorldThread::GetThread()->GetPacketHandler();
/* Establish / kill connection */
p->RegisterHandler(ClientConnected, this, &UserManager::Connect);
p->RegisterHandler(KillClient, this, &UserManager::Kill);
/* Ping/pong */
p->RegisterHandler(CMSG_PING, this, &UserManager::Ping);
/* Start a new authenticated session */
p->RegisterHandler(CMSG_AUTH_SESSION, this, &UserManager::AuthSession);
/* Character handling */
p->RegisterRoutedHandler(CMSG_CHAR_ENUM, this, &UserManager::GetClientByPacket, &Client::CharacterEnum);
p->RegisterRoutedHandler(CMSG_CHAR_CREATE, this, &UserManager::GetClientByPacket, &Client::CreateChar);
p->RegisterRoutedHandler(CMSG_CHAR_DELETE, this, &UserManager::GetClientByPacket, &Client::DeleteChar);
/* Character enters world */
p->RegisterRoutedHandler(CMSG_PLAYER_LOGIN, this, &UserManager::GetClientByPacket, &Client::PlayerLogin);
/* What is the name of GUID? */
p->RegisterRoutedHandler(CMSG_NAME_QUERY, this, &UserManager::GetObjectManagerByPacket, &ObjectManager::NameQuery);
/* Cancel any running trades */
p->RegisterRoutedHandler(CMSG_CANCEL_TRADE, this, &UserManager::GetCharByPacket, &Character::CancelTrade);
/* Clients wants to / doesnt want to log out */
p->RegisterRoutedHandler(CMSG_LOGOUT_REQUEST, this, &UserManager::GetCharByPacket, &Character::LogoutRequest);
//p->RegisterHandler(CMSG_LOGOUT_CANCEL, this, &UserManager::LogoutCancel);
/* Movement start + stop - redirected to other clients */
p->RegisterHandler(MSG_MOVE_START_FORWARD, this, &UserManager::MoveHandler);
p->RegisterHandler(MSG_MOVE_START_BACKWARD, this, &UserManager::MoveHandler);
p->RegisterHandler(MSG_MOVE_STOP, this, &UserManager::MoveHandler);
p->RegisterHandler(MSG_MOVE_START_STRAFE_LEFT, this, &UserManager::MoveHandler);
p->RegisterHandler(MSG_MOVE_START_STRAFE_RIGHT, this, &UserManager::MoveHandler);
p->RegisterHandler(MSG_MOVE_STOP_STRAFE, this, &UserManager::MoveHandler);
p->RegisterHandler(MSG_MOVE_JUMP, this, &UserManager::MoveHandler);
p->RegisterHandler(MSG_MOVE_START_TURN_LEFT, this, &UserManager::MoveHandler);
p->RegisterHandler(MSG_MOVE_START_TURN_RIGHT, this, &UserManager::MoveHandler);
p->RegisterHandler(MSG_MOVE_STOP_TURN, this, &UserManager::MoveHandler);
p->RegisterHandler(MSG_MOVE_START_PITCH_UP, this, &UserManager::MoveHandler);
p->RegisterHandler(MSG_MOVE_START_PITCH_DOWN, this, &UserManager::MoveHandler);
p->RegisterHandler(MSG_MOVE_STOP_PITCH, this, &UserManager::MoveHandler);
p->RegisterHandler(MSG_MOVE_SET_FACING, this, &UserManager::MoveHandler);
p->RegisterHandler(MSG_MOVE_SET_PITCH, this, &UserManager::MoveHandler);
p->RegisterHandler(MSG_MOVE_COLLIDE_REDIRECT, this, &UserManager::MoveHandler);
p->RegisterHandler(MSG_MOVE_COLLIDE_STUCK, this, &UserManager::MoveHandler);
/* Movement - update internal coordinates */
p->RegisterRoutedHandler(MSG_MOVE_HEARTBEAT, this, &UserManager::GetCharByPacket, &Character::MoveHeartbeat);
/* Chat / emotes */
p->RegisterHandler(CMSG_MESSAGECHAT, this, &UserManager::ChatMessage);
p->RegisterHandler(CMSG_TEXT_EMOTE, this, &UserManager::TextEmote);
/* Changing stand state */
p->RegisterRoutedHandler(CMSG_STANDSTATECHANGE, this, &UserManager::GetCharByPacket, &Character::StandStateChange);
/* Setting target */
p->RegisterRoutedHandler(CMSG_SET_SELECTION, this, &UserManager::GetCharByPacket, &Character::SelectionChange);
/* Friends / ignores */
p->RegisterRoutedHandler(CMSG_FRIEND_LIST, this, &UserManager::GetCharByPacket, &Character::ListFriends);
p->RegisterRoutedHandler(CMSG_ADD_FRIEND, this, &UserManager::GetCharByPacket, &Character::AddFriend);
p->RegisterRoutedHandler(CMSG_DEL_FRIEND, this, &UserManager::GetCharByPacket, &Character::DelFriend);
}
UserManager::~UserManager(void) {
ClientHashMap::iterator it;
for (it = Clients.begin(); it != Clients.end(); ++it)
if (it->second) delete it->second;
}
Client *UserManager::GetClientByPacket(wowPacket *packet) {
wxUint32 handle = (wxUint32)packet->GetSocket();
if (Clients.find(handle) == Clients.end())
return (Client *)0;
else
return Clients[handle];
}
Character *UserManager::GetCharByPacket(wowPacket *packet) {
wxUint32 Handle = (wxUint32)packet->GetSocket();
if (Clients.find(Handle) == Clients.end())
return (Character *)0;
else {
Character *CClient = Clients[Handle]->CurrentChar;
if (!CClient)
return (Character *)0;
else
return CClient;
}
}
/* Huhu - 'by packet' *snicker* */
ObjectManager *UserManager::GetObjectManagerByPacket (wowPacket *packet) { return WorldThread::GetThread()->GetObjectManager(); }
void UserManager::StatusMsg(wxSocketBase *sock, wxString msg) {
msg.Prepend(_T("(server) "));
wowPacket *smsg = new wowPacket(sock);
smsg->PutHeader(SMSG_MESSAGECHAT);
smsg->Putu32(9); smsg->Putu8(CHAT_MSG_SYSTEM);
smsg->Putu32(0); smsg->Putu32(0); /* GUID */
smsg->Putcstr0(msg);
smsg->Putu8(0);
smsg->Finalize();
WorldThread::GetThread()->PostPacket(smsg);
}
void UserManager::VicinityBroadcast(ObjPosition *SelfPosition, wowPacket *packet) {
ClientHashMap::iterator it;
for (it = Clients.begin(); it != Clients.end(); ++it) {
wxSocketBase *CSocket = it->second->CurrentSocket;
Character *CChar = it->second->CurrentChar;
if (!CChar)
continue;
if (abs(int(SelfPosition->PosX - CChar->Position.PosX)) > 20
|| abs(int(SelfPosition->PosY - CChar->Position.PosY)) > 20
|| abs(int(SelfPosition->PosZ - CChar->Position.PosZ)) > 20)
continue;
wowPacket *copy = new wowPacket(*packet);
copy->SetSocket(CSocket);
WorldThread::GetThread()->PostPacket(copy);
}
delete packet;
}
void UserManager::VicinityBroadcast(ObjPosition *SelfPosition, wowPacket *packet, wxLongLong exclude) {
ClientHashMap::iterator it;
for (it = Clients.begin(); it != Clients.end(); ++it) {
if (it->first == exclude) continue;
wxSocketBase *CSocket = it->second->CurrentSocket;
Character *CChar = it->second->CurrentChar;
if (!CChar)
continue;
if (abs(int(SelfPosition->PosX - CChar->Position.PosX)) > 20
|| abs(int(SelfPosition->PosY - CChar->Position.PosY)) > 20
|| abs(int(SelfPosition->PosZ - CChar->Position.PosZ)) > 20)
continue;
wowPacket *copy = new wowPacket(*packet);
copy->SetSocket(CSocket);
WorldThread::GetThread()->PostPacket(copy);
}
delete packet;
}
void UserManager::Connect(wowPacket *packet) {
Clients[(wxUint32)packet->GetSocket()] = new Client(packet->GetSocket());
LOG(_T("[UserManager] ClientConnected: sending auth challenge."));
wowPacket *AuthChallenge = new wowPacket(packet->GetSocket());
AuthChallenge->PutHeader(SMSG_AUTH_CHALLENGE);
AuthChallenge->Putu32(0); /* unk1 */
AuthChallenge->Finalize();
WorldThread::GetThread()->PostPacket(AuthChallenge);
}
void UserManager::Kill(wowPacket *packet) {
LOG(_T("[UserManager] KillClient: dropping client."));
Client *c = GetClientByPacket(packet);
if (c) {
/*if (c->CurrentChar) {
wowPacket *Kill = new wowPacket;
Kill->PutHeader(SMSG_DESTROY_OBJECT);
Kill->Putu32(c->CurrentChar->GetGUID().GetLo());
Kill->Putu32(c->CurrentChar->GetGUID().GetHi());
Kill->Finalize();
VicinityBroadcast(&c->CurrentChar->Position, Kill);
c->CurrentChar->Online = 0;
c->CurrentChar = 0;
}*/
Clients.erase((wxUint32)packet->GetSocket());
delete c;
}
}
void UserManager::NewPlayer (Character *Self, wxUint8 TellSelf) {
if (TellSelf) {
LOG(_T("[UserManager] Telling %s about self."), Self->GetName());
wowPacket *TellPacket = new wowPacket(Self->ControllingClient->CurrentSocket);
TellPacket->PutHeader(SMSG_UPDATE_OBJECT);
TellPacket->Putu32(1);
Self->GetCharUpdate(TellPacket, OBJUPD_CREATE, 1);
Self->GetCharProps(TellPacket);
TellPacket->Finalize();
WorldThread::GetThread()->PostPacket(TellPacket);
} else {
wowPacket *EnviromentUpdate = new wowPacket(Self->ControllingClient->CurrentSocket);
EnviromentUpdate->PutHeader(SMSG_UPDATE_OBJECT);
wxUint32 Position = EnviromentUpdate->GetPosition();
EnviromentUpdate->Putu32(0); /* Temporary, we set real value later on */
wxUint32 UpdateCount = 0;
ClientHashMap::iterator it;
for (it = Clients.begin(); it != Clients.end(); ++it) {
Client *CClient = it->second;
Character *CChar = CClient->CurrentChar;
if (!CChar || !CClient)
continue;
if (CClient == Self->ControllingClient)
continue;
LOG(_T("[UserManager] Enviroment update (for %s), adding %s to packet."), Self->GetName(), CChar->GetName());
CChar->GetCharUpdate(EnviromentUpdate, OBJUPD_CREATE, 0);
CChar->GetCharProps(EnviromentUpdate); UpdateCount++;
LOG(_T("[UserManager] Telling %s about %s."), Self->GetName(), CChar->GetName());
wowPacket *NewPlayer = new wowPacket(CClient->CurrentSocket);
NewPlayer->PutHeader(SMSG_UPDATE_OBJECT);
NewPlayer->Putu32(1); /* Number of objects */
Self->GetCharUpdate(NewPlayer, OBJUPD_CREATE, 0);
Self->GetCharProps(NewPlayer);
NewPlayer->Finalize();
WorldThread::GetThread()->PostPacket(NewPlayer);
}
/* Might not need to jump back to where we were. :-) (better safe than sorry) */
if (UpdateCount > 0) {
wxUint32 Temp = EnviromentUpdate->GetPosition();
EnviromentUpdate->SetPosition(Position);
LOG(_T("[UserManager] Setting updatecount to %d (old pos: %d updatepos: %d)"), UpdateCount, Temp, Position);
EnviromentUpdate->Putu32(UpdateCount);
EnviromentUpdate->SetPosition(Temp);
EnviromentUpdate->Finalize();
WorldThread::GetThread()->PostPacket(EnviromentUpdate);
} else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -