diff --git a/src/CNShardServer.hpp b/src/CNShardServer.hpp index fb3b65a..608fa7e 100644 --- a/src/CNShardServer.hpp +++ b/src/CNShardServer.hpp @@ -6,15 +6,17 @@ #include enum SHARDPACKETID { - // client 2 shard P_CL2FE_REQ_PC_ENTER = 318767105, P_CL2FE_REQ_PC_LOADING_COMPLETE = 318767245, P_CL2FE_REP_LIVE_CHECK = 318767221, P_CL2FE_REQ_NANO_ACTIVE = 318767119, P_CL2FE_REQ_NANO_EQUIP = 318767117, + P_CL2FE_REQ_NANO_UNEQUIP = 318767118, P_CL2FE_REQ_NANO_SKILL_USE = 318767121, P_CL2FE_REQ_NANO_TUNE = 318767120, + P_CL2FE_REQ_PC_FIRST_USE_FLAG_SET = 318767238, + P_CL2FE_REQ_PC_GIVE_NANO = 318767172, P_CL2FE_REQ_PC_MOVE = 318767107, P_CL2FE_REQ_PC_STOP = 318767108, P_CL2FE_REQ_PC_JUMP = 318767109, @@ -27,18 +29,22 @@ enum SHARDPACKETID { P_CL2FE_GM_REQ_PC_SET_VALUE = 318767211, P_CL2FE_REQ_SEND_FREECHAT_MESSAGE = 318767111, P_CL2FE_REQ_PC_AVATAR_EMOTES_CHAT = 318767184, + P_CL2FE_REQ_ITEM_MOVE = 318767114, + P_CL2FE_REQ_PC_ITEM_DELETE = 318767129, + P_CL2FE_REQ_PC_GIVE_ITEM = 318767130, P_CL2FE_REQ_PC_EXIT = 318767106, - P_CL2FE_REQ_PC_FIRST_USE_FLAG_SET = 318767238, // shard 2 client P_FE2CL_REP_NANO_ACTIVE_SUCC = 822083624, P_FE2CL_REP_PC_NANO_CREATE_SUCC = 822083667, P_FE2CL_REP_NANO_EQUIP_SUCC = 822083622, + P_FE2CL_REP_NANO_UNEQUIP_SUCC = 822083623, P_FE2CL_NANO_SKILL_USE_SUCC = 822083627, P_FE2CL_NANO_SKILL_USE = 822083628, P_FE2CL_REP_NANO_TUNE_SUCC = 822083625, P_FE2CL_REP_PC_ENTER_SUCC = 822083586, P_FE2CL_REP_PC_LOADING_COMPLETE_SUCC = 822083833, + P_FE2CL_REP_PC_GOTO_SUCC = 822083633, P_FE2CL_REQ_LIVE_CHECK = 822083792, P_FE2CL_PC_NEW = 822083587, P_FE2CL_PC_MOVE = 822083592, @@ -50,11 +56,18 @@ enum SHARDPACKETID { P_FE2CL_PC_ZIPLINE = 822083703, P_FE2CL_PC_MOVEPLATFORM = 822083704, P_FE2CL_PC_SLOPE = 822083705, - P_FE2CL_REP_PC_GOTO_SUCC = 822083633, + P_FE2CL_NPC_ENTER = 822083595, + P_FE2CL_NPC_EXIT = 822083596, + P_FE2CL_ANNOUNCE_MSG = 822083778, P_FE2CL_GM_REP_PC_SET_VALUE = 822083781, P_FE2CL_REP_SEND_FREECHAT_MESSAGE_SUCC = 822083602, P_FE2CL_REP_PC_AVATAR_EMOTES_CHAT = 822083730, + P_FE2CL_PC_ITEM_MOVE_SUCC = 822083610, + P_FE2CL_PC_EQUIP_CHANGE = 822083611, + P_FE2CL_REP_PC_ITEM_DELETE_SUCC = 822083641, + P_FE2CL_REP_PC_GIVE_ITEM_SUCC = 822083681, P_FE2CL_REP_PC_EXIT_SUCC = 822083589, + P_FE2CL_REP_PC_CHANGE_LEVEL = 822083786, P_FE2CL_PC_MOTD_LOGIN = 822083793 }; diff --git a/src/NanoManager.cpp b/src/NanoManager.cpp index 6ed526a..70cf4c5 100644 --- a/src/NanoManager.cpp +++ b/src/NanoManager.cpp @@ -6,11 +6,16 @@ void NanoManager::init() { REGISTER_SHARD_PACKET(P_CL2FE_REQ_NANO_ACTIVE, nanoSummonHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_NANO_EQUIP, nanoEquipHandler); + REGISTER_SHARD_PACKET(P_CL2FE_REQ_NANO_UNEQUIP, nanoUnEquipHandler); + REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_GIVE_NANO, nanoGMGiveHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_NANO_TUNE, nanoSkillSetHandler); REGISTER_SHARD_PACKET(P_CL2FE_REQ_NANO_SKILL_USE, nanoSkillUseHandler); } void NanoManager::nanoEquipHandler(CNSocket* sock, CNPacketData* data) { + if (data->size != sizeof(sP_CL2FE_REQ_NANO_EQUIP)) + return; // malformed packet + sP_CL2FE_REQ_NANO_EQUIP* nano = (sP_CL2FE_REQ_NANO_EQUIP*)data->buf; sP_FE2CL_REP_NANO_EQUIP_SUCC* resp = (sP_FE2CL_REP_NANO_EQUIP_SUCC*)xmalloc(sizeof(sP_FE2CL_REP_NANO_EQUIP_SUCC)); resp->iNanoID = nano->iNanoID; @@ -19,7 +24,34 @@ void NanoManager::nanoEquipHandler(CNSocket* sock, CNPacketData* data) { sock->sendPacket(new CNPacketData((void*)resp, P_FE2CL_REP_NANO_EQUIP_SUCC, sizeof(sP_FE2CL_REP_NANO_EQUIP_SUCC), sock->getFEKey())); } +void NanoManager::nanoUnEquipHandler(CNSocket* sock, CNPacketData* data) { + if (data->size != sizeof(sP_CL2FE_REQ_NANO_UNEQUIP)) + return; // malformed packet + + sP_CL2FE_REQ_NANO_UNEQUIP* nano = (sP_CL2FE_REQ_NANO_UNEQUIP*)data->buf; + sP_FE2CL_REP_NANO_UNEQUIP_SUCC* resp = (sP_FE2CL_REP_NANO_UNEQUIP_SUCC*)xmalloc(sizeof(sP_FE2CL_REP_NANO_UNEQUIP_SUCC)); + resp->iNanoSlotNum = nano->iNanoSlotNum; + + sock->sendPacket(new CNPacketData((void*)resp, P_FE2CL_REP_NANO_UNEQUIP_SUCC, sizeof(sP_FE2CL_REP_NANO_UNEQUIP_SUCC), sock->getFEKey())); +} + +void NanoManager::nanoGMGiveHandler(CNSocket* sock, CNPacketData* data) { + if (data->size != sizeof(sP_CL2FE_REQ_PC_GIVE_NANO)) + return; // ignore the malformed packet + + // Cmd: /nano + sP_CL2FE_REQ_PC_GIVE_NANO* nano = (sP_CL2FE_REQ_PC_GIVE_NANO*)data->buf; + Player plr = PlayerManager::getPlayer(sock); + + // Add nano to player + addNano(sock, nano->iNanoID, 0); + std::cout << U16toU8(plr.PCStyle.szFirstName) << U16toU8(plr.PCStyle.szLastName) << " requested to add nano id: " << nano->iNanoID << std::endl; +} + void NanoManager::nanoSummonHandler(CNSocket* sock, CNPacketData* data) { + if (data->size != sizeof(sP_CL2FE_REQ_NANO_ACTIVE)) + return; // malformed packet + sP_CL2FE_REQ_NANO_ACTIVE* nano = (sP_CL2FE_REQ_NANO_ACTIVE*)data->buf; PlayerView plr = PlayerManager::players[sock]; @@ -32,6 +64,9 @@ void NanoManager::nanoSummonHandler(CNSocket* sock, CNPacketData* data) { } void NanoManager::nanoSkillUseHandler(CNSocket* sock, CNPacketData* data) { + if (data->size != sizeof(sP_CL2FE_REQ_NANO_SKILL_USE)) + return; // malformed packet + sP_CL2FE_REQ_NANO_SKILL_USE* skill = (sP_CL2FE_REQ_NANO_SKILL_USE*)data->buf; PlayerView plr = PlayerManager::players[sock]; @@ -51,10 +86,14 @@ void NanoManager::nanoSkillUseHandler(CNSocket* sock, CNPacketData* data) { } void NanoManager::nanoSkillSetHandler(CNSocket* sock, CNPacketData* data) { + if (data->size != sizeof(sP_CL2FE_REQ_NANO_TUNE)) + return; // malformed packet + sP_CL2FE_REQ_NANO_TUNE* skill = (sP_CL2FE_REQ_NANO_TUNE*)data->buf; setNanoSkill(sock, skill->iNanoID, skill->iTuneID); } +#pragma region Helper methods void NanoManager::addNano(CNSocket* sock, int16_t nanoId, int16_t slot) { Player plr = PlayerManager::getPlayer(sock); @@ -100,4 +139,5 @@ void NanoManager::resetNanoSkill(CNSocket* sock, int16_t nanoId) { // Update the player PlayerManager::updatePlayer(sock, plr); -} \ No newline at end of file +} +#pragma endregion \ No newline at end of file diff --git a/src/NanoManager.hpp b/src/NanoManager.hpp index bdadc81..748851f 100644 --- a/src/NanoManager.hpp +++ b/src/NanoManager.hpp @@ -7,6 +7,8 @@ namespace NanoManager { void init(); void nanoSummonHandler(CNSocket* sock, CNPacketData* data); void nanoEquipHandler(CNSocket* sock, CNPacketData* data); + void nanoUnEquipHandler(CNSocket* sock, CNPacketData* data); + void nanoGMGiveHandler(CNSocket* sock, CNPacketData* data); void nanoSkillUseHandler(CNSocket* sock, CNPacketData* data); void nanoSkillSetHandler(CNSocket* sock, CNPacketData* data); diff --git a/src/PlayerManager.cpp b/src/PlayerManager.cpp index 86a01c3..8a5f2a2 100644 --- a/src/PlayerManager.cpp +++ b/src/PlayerManager.cpp @@ -1,6 +1,6 @@ #include "CNProtocol.hpp" -#include "NanoManager.hpp" #include "PlayerManager.hpp" +#include "NPCManager.hpp" #include "CNShardServer.hpp" #include "CNShared.hpp" @@ -28,7 +28,6 @@ void PlayerManager::init() { REGISTER_SHARD_PACKET(P_CL2FE_GM_REQ_PC_SET_VALUE, PlayerManager::setSpecialPlayer); REGISTER_SHARD_PACKET(P_CL2FE_REP_LIVE_CHECK, PlayerManager::heartbeatPlayer); REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_EXIT, PlayerManager::exitGame); - REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_FIRST_USE_FLAG_SET, PlayerManager::onPlayerSpawn); } void PlayerManager::addPlayer(CNSocket* key, Player plr) { @@ -37,7 +36,7 @@ void PlayerManager::addPlayer(CNSocket* key, Player plr) { players[key].plr = plr; players[key].lastHeartbeat = 0; - std::cout << U16toU8(plr.PCStyle.szFirstName) << U16toU8(plr.PCStyle.szLastName) << " has joined!" << std::endl; + std::cout << U16toU8(plr.PCStyle.szFirstName) << " " << U16toU8(plr.PCStyle.szLastName) << " has joined!" << std::endl; std::cout << players.size() << " players" << std::endl; } @@ -89,9 +88,9 @@ void PlayerManager::updatePlayerPosition(CNSocket* sock, int X, int Y, int Z) { } } - std::list cachedview(players[sock].viewable); // copies the viewable - - for (CNSocket* otherSock : cachedview) { + std::list::iterator i = players[sock].viewable.begin(); + while (i != players[sock].viewable.end()) { + CNSocket* otherSock = *i; if (std::find(noView.begin(), noView.end(), otherSock) != noView.end()) { // sock shouldn't be visible, send PC_EXIT packet & remove them @@ -104,15 +103,16 @@ void PlayerManager::updatePlayerPosition(CNSocket* sock, int X, int Y, int Z) { otherSock->sendPacket(new CNPacketData((void*)exitPacket, P_FE2CL_PC_EXIT, sizeof(sP_FE2CL_PC_EXIT), otherSock->getFEKey())); sock->sendPacket(new CNPacketData((void*)exitPacketOther, P_FE2CL_PC_EXIT, sizeof(sP_FE2CL_PC_EXIT), sock->getFEKey())); - players[sock].viewable.remove(otherSock); + players[sock].viewable.erase(i++); players[otherSock].viewable.remove(sock); + continue; } + + ++i; } - cachedview = players[sock].viewable; - for (CNSocket* otherSock : yesView) { - if (std::find(cachedview.begin(), cachedview.end(), otherSock) == cachedview.end()) { + if (std::find(players[sock].viewable.begin(), players[sock].viewable.end(), otherSock) == players[sock].viewable.end()) { // this needs to be added to the viewable players, send PC_ENTER sP_FE2CL_PC_NEW* newPlayer = (sP_FE2CL_PC_NEW*)xmalloc(sizeof(sP_FE2CL_PC_NEW)); // current connection to other player @@ -148,6 +148,8 @@ void PlayerManager::updatePlayerPosition(CNSocket* sock, int X, int Y, int Z) { players[otherSock].viewable.push_back(sock); } } + + NPCManager::updatePlayerNPCS(sock, players[sock]); } void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) { @@ -156,6 +158,7 @@ void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_PC_ENTER* enter = (sP_CL2FE_REQ_PC_ENTER*)data->buf; sP_FE2CL_REP_PC_ENTER_SUCC* response = (sP_FE2CL_REP_PC_ENTER_SUCC*)xmalloc(sizeof(sP_FE2CL_REP_PC_ENTER_SUCC)); + sP_FE2CL_PC_MOTD_LOGIN* motd = (sP_FE2CL_PC_MOTD_LOGIN*)xmalloc(sizeof(sP_FE2CL_PC_MOTD_LOGIN)); // TODO: check if serialkey exists, if it doesn't send sP_FE2CL_REP_PC_ENTER_FAIL Player plr = CNSharedData::getPlayer(enter->iEnterSerialKey); @@ -187,19 +190,33 @@ void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) { for (int i = 0; i < AEQUIP_COUNT; i++) response->PCLoadData2CL.aEquip[i] = plr.Equip[i]; - //assign 37 nanos with something.hardcoded for now... + // protocol-agnostic sItemBase usage + sItemBase item; + memset(&item, 0, sizeof(sItemBase)); + item.iID = 495; + + for (int i = 0; i < AINVEN_COUNT; i++) { + switch (i) { + case 6: case 8: case 11: case 13: case 20: + case 24: case 26: case 27: case 28: + plr.Inven[i] = item; + break; + default: + memset(&plr.Inven[i], 0, sizeof(sItemBase)); + } + response->PCLoadData2CL.aInven[i] = plr.Inven[i]; + } + + // don't ask.. for (int i = 1; i < 37; i++) { response->PCLoadData2CL.aNanoBank[i].iID = i; - response->PCLoadData2CL.aNanoBank[i].iSkillID = 2; + response->PCLoadData2CL.aNanoBank[i].iSkillID = 1; response->PCLoadData2CL.aNanoBank[i].iStamina = 150; } - response->PCLoadData2CL.aNanoBank[1].iSkillID = 0; - response->PCLoadData2CL.aNanoBank[2].iSkillID = 0; - response->PCLoadData2CL.aNanoBank[3].iSkillID = 0; - response->PCLoadData2CL.aNanoSlots[0] = 1; - response->PCLoadData2CL.aNanoSlots[1] = 2; - response->PCLoadData2CL.aNanoSlots[2] = 3; + //response->PCLoadData2CL.aNanoSlots[0] = 1; + //response->PCLoadData2CL.aNanoSlots[1] = 2; + //response->PCLoadData2CL.aNanoSlots[2] = 3; response->PCLoadData2CL.aQuestFlag[0] = -1; @@ -207,10 +224,15 @@ void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) { plr.SerialKey = enter->iEnterSerialKey; plr.HP = response->PCLoadData2CL.iHP; + motd->iType = 1; + U8toU16(settings::MOTDSTRING, (char16_t*)motd->szSystemMsg); + sock->setEKey(CNSocketEncryption::createNewKey(response->uiSvrTime, response->iID + 1, response->PCLoadData2CL.iFusionMatter + 1)); sock->setFEKey(plr.FEKey); sock->sendPacket(new CNPacketData((void*)response, P_FE2CL_REP_PC_ENTER_SUCC, sizeof(sP_FE2CL_REP_PC_ENTER_SUCC), sock->getFEKey())); + // transmit MOTD after entering the game, so the client hopefully changes modes on time + sock->sendPacket(new CNPacketData((void*)motd, P_FE2CL_PC_MOTD_LOGIN, sizeof(sP_FE2CL_PC_MOTD_LOGIN), sock->getFEKey())); addPlayer(sock, plr); } @@ -221,7 +243,6 @@ void PlayerManager::loadPlayer(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_PC_LOADING_COMPLETE* complete = (sP_CL2FE_REQ_PC_LOADING_COMPLETE*)data->buf; sP_FE2CL_REP_PC_LOADING_COMPLETE_SUCC* response = (sP_FE2CL_REP_PC_LOADING_COMPLETE_SUCC*)xmalloc(sizeof(sP_FE2CL_REP_PC_LOADING_COMPLETE_SUCC)); - sP_FE2CL_PC_MOTD_LOGIN* motd = (sP_FE2CL_PC_MOTD_LOGIN*)xmalloc(sizeof(sP_FE2CL_PC_MOTD_LOGIN)); DEBUGLOG( std::cout << "P_CL2FE_REQ_PC_LOADING_COMPLETE:" << std::endl; @@ -230,11 +251,7 @@ void PlayerManager::loadPlayer(CNSocket* sock, CNPacketData* data) { response->iPC_ID = complete->iPC_ID; - motd->iType = 1; - U8toU16(settings::MOTDSTRING, (char16_t*)motd->szSystemMsg); - sock->sendPacket(new CNPacketData((void*)response, P_FE2CL_REP_PC_LOADING_COMPLETE_SUCC, sizeof(sP_FE2CL_REP_PC_LOADING_COMPLETE_SUCC), sock->getFEKey())); - sock->sendPacket(new CNPacketData((void*)motd, P_FE2CL_PC_MOTD_LOGIN, sizeof(sP_FE2CL_PC_MOTD_LOGIN), sock->getFEKey())); } void PlayerManager::movePlayer(CNSocket* sock, CNPacketData* data) {