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

📄 usermanager.cpp

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