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

📄 character.cpp

📁 魔兽世界的私服源程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#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 + -