📄 character.cpp
字号:
#include "Character.h"
#include "UserManager.h"
#include "../WorldThread.h"
#include "../Common.h"
/* We need to send these when we send an Object Update
w/ type create about ourselves (Char) */
const wxUint32 CreateReqSize_CharSelf = 4;
const wxUint32 CreateReqItems_CharSelf[CreateReqSize_CharSelf] = {
CHAR_FACE, CHAR_CURRENT_XP,
CHAR_NEXTLEVEL_XP, CHAR_FACIALHAIR
};
Character::Character(Client *client, wxString name) : Unit(TYPE_CHAR, name) { CharConstructor(client, name); }
Character::Character(Client *client, wxString name, wxLongLong id) : Unit(id) {
CharConstructor(client, name);
LOG(_T("[Character] Adding to reverse db (%s -> %.4X %.4X)"), GetName(), id.GetLo(), id.GetHi());
WorldThread::GetThread()->GetObjectManager()->ReverseObj[GetName()] = id;
}
Character::~Character (void) {
WorldThread::GetThread()->GetObjectManager()->ReverseObj.erase(GetName());
}
void Character::CharConstructor (Client *c, wxString n) {
memset(ActionButtons, 0, NumActionButtons * sizeof(wxUint32));
HomeCity = 9; Realm = 0; Online = 0; SetName(n); SetType(GetType() + BMASK_CHAR);
ControllingClient = c; ControllingClient->Characters[GetGUID()] = this;
}
wxInt32 Character::FindFriend (wxLongLong FID) {
for (GUIDNode *node = Friends.GetFirst(); node; node = node->GetNext()) {
if (*node->GetData() == FID)
return node->GetIndex();
}
return -1;
}
void Character::GetCharUpdate (wowPacket *packet, wxUint32 UpdateType, wxUint32 self) {
GetUnitUpdate(packet, UpdateType, self);
if (UpdateType == OBJUPD_CREATE) {
if (self) {
for (wxUint8 x = 0; x < CreateReqSize_CharSelf; x++) {
if (!(ISSET(UpdateMasks, CreateReqItems_CharSelf[x])))
SETMASK(UpdateMasks, CreateReqItems_CharSelf[x]);
}
}
LOG(_T("Update, %d nummasks"), NumMasks);
packet->Putu8(NumMasks);
packet->PutData(UpdateMasks, NumMasks * sizeof(wxUint32));
} else if (UpdateType == OBJUPD_UPDATE) {
packet->Putu8(NumMasks);
packet->PutData(UpdateMasks, NumMasks*4);
} else
LOG(_T("[Char] Got unsupported type %d in GetCharUpdate."), UpdateType);
}
void Character::GetCharProps (wowPacket *packet) {
GetUnitProps(packet);
for (wxUint32 x = CHAR_START; x <= CHAR_END; x++)
if (ISSET(UpdateMasks, x))
packet->Putu32(PropertyMap[x].uint32);
}
void Character::ListFriends (wowPacket *packet) {
wowPacket *FList = new wowPacket(packet->GetSocket());
FList->PutHeader(SMSG_FRIEND_LIST);
FList->Putu8((wxUint8)Friends.GetCount());
for (GUIDNode *node = Friends.GetFirst(); node; node = node->GetNext()) {
ObjectManager *objm = WorldThread::GetThread()->GetObjectManager();
if (!node->GetData())
continue;
wxLongLong id = *node->GetData();
if (objm->Objects.find(id) == objm->Objects.end()) {
wowPacket *FDeleted = new wowPacket(packet->GetSocket());
FDeleted->PutHeader(SMSG_FRIEND_STATUS);
FDeleted->Putu8(FRIEND_REMOVED);
FDeleted->Putu32(id.GetLo());
FDeleted->Putu32(id.GetHi());
FDeleted->Finalize();
WorldThread::GetThread()->PostPacket(FDeleted);
Friends.DeleteNode(node);
} else {
Character *current = (Character *)objm->Objects[id];
FList->Putu32(id.GetLo());
FList->Putu32(id.GetHi());
if (!current->Online)
FList->Putu8(FRIENDLIST_OFFLINE);
else {
FList->Putu8(FRIENDLIST_ONLINE);
FList->Putu32(1); /* area */
FList->Putu32(current->GetClass());
FList->Putu32(current->GetLevel());
}
}
FList->Finalize();
WorldThread::GetThread()->PostPacket(FList);
}
}
void Character::AddFriend (wowPacket *packet) {
packet->SkipHeader();
wxString f; packet->Getcstr(f);
ObjectManager *objm = WorldThread::GetThread()->GetObjectManager();
wowPacket *FStatus = new wowPacket(packet->GetSocket());
FStatus->PutHeader(SMSG_FRIEND_STATUS);
if (objm->ReverseObj.find(f) == objm->ReverseObj.end())
FStatus->Putu8(FRIEND_NOT_FOUND);
else {
wxLongLong *id = &(objm->ReverseObj[f]);
if (*id == GetGUID()) {
FStatus->Putu8(FRIEND_SELF);
FStatus->Putu32(id->GetLo());
FStatus->Putu32(id->GetHi());
} else if (FindFriend(*id) != wxNOT_FOUND) {
FStatus->Putu8(FRIEND_ALREADY);
FStatus->Putu32(id->GetLo());
FStatus->Putu32(id->GetHi());
} else if (Friends.GetCount() > 32) {
FStatus->Putu8(FRIEND_LIST_FULL);
FStatus->Putu32(id->GetLo());
FStatus->Putu32(id->GetHi());
} else {
Friends.Append(id);
Character *Friend = (Character *)objm->Objects[*id];
if (Friend->Online)
FStatus->Putu8(FRIEND_ADDED_ONLINE);
else
FStatus->Putu8(FRIEND_ADDED_OFFLINE);
FStatus->Putu32(id->GetLo());
FStatus->Putu32(id->GetHi());
if (Friend->Online) {
FStatus->Putu32(Friend->GetLevel());
FStatus->Putu32(Friend->GetClass());
FStatus->Putu32(1); /* area */
}
}
}
FStatus->Finalize();
WorldThread::GetThread()->PostPacket(FStatus);
}
void Character::DelFriend (wowPacket *packet) {
packet->SkipHeader();
wxUint32 lo = packet->Getu32(), hi = packet->Getu32();
wxLongLong id = wxLongLong(hi, lo);
wxUint32 index = FindFriend(id);
wowPacket *FStatus = new wowPacket(packet->GetSocket());
FStatus->PutHeader(SMSG_FRIEND_STATUS);
if (index == wxNOT_FOUND)
FStatus->Putu8(FRIEND_NOT_FOUND);
else {
GUIDNode *node = Friends.FindByIndex(index);
if (node)
Friends.DeleteNode(node);
FStatus->Putu8(FRIEND_REMOVED);
}
FStatus->Putu32(id.GetLo());
FStatus->Putu32(id.GetHi());
FStatus->Finalize();
WorldThread::GetThread()->PostPacket(FStatus);
}
void Character::MoveHeartbeat (wowPacket *packet) {
packet->SkipHeader();
wxUint32 pUnk1 = packet->Getu32();
wxUint32 pUnk2 = packet->Getu32();
wxFloat32 x1 = packet->Getf32();
wxFloat32 y1 = packet->Getf32();
wxFloat32 z1 = packet->Getf32();
wxUint32 pUnk3 = packet->Getu32();
if ( x1 == Position.PosX
&& y1 == Position.PosY
&& z1 == Position.PosZ)
return;
wxFloat32 x2 = packet->Getf32();
wxFloat32 y2 = packet->Getf32();
wxFloat32 z2 = packet->Getf32();
wxUint32 pUnk4 = packet->Getu32();
wxUint32 pUnk5 = packet->Getu32();
wxUint32 pUnk6 = packet->Getu32();
SetPosition(x1, y1, z1);
}
void Character::LogoutRequest(wowPacket *packet) {
/* TODO: add code that checks if the player is in a valid state to logout */
/*if (GetAnimState() != UNIT_SITTING) {
LOG(_T("[Character] Disallowing CMSG_LOGOUT_REQUEST for %s; not sitting"), GetName());
wowPacket *LogFailed = new wowPacket(packet->GetSocket());
LogFailed->PutHeader(SMSG_LOGOUT_RESPONSE);
LogFailed->Putu8(LOGOUT_FAILURE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -