diff --git a/src/CombatManager.cpp b/src/CombatManager.cpp index 16bbeb3..2836dab 100644 --- a/src/CombatManager.cpp +++ b/src/CombatManager.cpp @@ -26,7 +26,8 @@ void CombatManager::pcAttackNpcs(CNSocket *sock, CNPacketData *data) { /* * Due to the possibility of multiplication overflow (and regular buffer overflow), - * both incoming and outgoing variable-length packets must be validated. + * both incoming and outgoing variable-length packets must be validated, at least if + * the number of trailing structs isn't well known (ie. it's from the client). */ if (!validOutVarPacket(sizeof(sP_FE2CL_PC_ATTACK_NPCs_SUCC), pkt->iNPCCnt, sizeof(sAttackResult))) { std::cout << "[WARN] bad sP_FE2CL_PC_ATTACK_NPCs_SUCC packet size\n"; @@ -56,6 +57,7 @@ void CombatManager::pcAttackNpcs(CNSocket *sock, CNPacketData *data) { if (mob.appearanceData.iHP <= 0) giveReward(sock); + // TODO: despawn mobs when they die respdata[i].iID = mob.appearanceData.iNPC_ID; respdata[i].iDamage = 100; diff --git a/src/PlayerManager.cpp b/src/PlayerManager.cpp index 2b1ad85..7f87515 100644 --- a/src/PlayerManager.cpp +++ b/src/PlayerManager.cpp @@ -32,6 +32,7 @@ void PlayerManager::init() { REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_SPECIAL_STATE_SWITCH, PlayerManager::setSpecialSwitchPlayer); REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_VEHICLE_ON, PlayerManager::enterPlayerVehicle); REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_VEHICLE_OFF, PlayerManager::exitPlayerVehicle); + REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_CHANGE_MENTOR, PlayerManager::changePlayerGuide); } void PlayerManager::addPlayer(CNSocket* key, Player plr) { @@ -651,6 +652,21 @@ void PlayerManager::setSpecialSwitchPlayer(CNSocket* sock, CNPacketData* data) { sock->sendPacket((void*)&response, P_FE2CL_REP_PC_SPECIAL_STATE_SWITCH_SUCC, sizeof(sP_FE2CL_REP_PC_SPECIAL_STATE_SWITCH_SUCC)); } +void PlayerManager::changePlayerGuide(CNSocket *sock, CNPacketData *data) { + if (data->size != sizeof(sP_CL2FE_REQ_PC_CHANGE_MENTOR)) + return; + + sP_CL2FE_REQ_PC_CHANGE_MENTOR *pkt = (sP_CL2FE_REQ_PC_CHANGE_MENTOR*)data->buf; + INITSTRUCT(sP_FE2CL_REP_PC_CHANGE_MENTOR_SUCC, resp); + Player *plr = getPlayer(sock); + + resp.iMentor = pkt->iMentor; + resp.iMentorCnt = 1; + resp.iFusionMatter = plr->fusionmatter; // no cost + + sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_CHANGE_MENTOR_SUCC, sizeof(sP_FE2CL_REP_PC_CHANGE_MENTOR_SUCC)); +} + #pragma region Helper methods Player *PlayerManager::getPlayer(CNSocket* key) { return players[key].plr; diff --git a/src/PlayerManager.hpp b/src/PlayerManager.hpp index 78f904b..52eb95a 100644 --- a/src/PlayerManager.hpp +++ b/src/PlayerManager.hpp @@ -45,6 +45,7 @@ namespace PlayerManager { void exitGame(CNSocket* sock, CNPacketData* data); void setSpecialSwitchPlayer(CNSocket* sock, CNPacketData* data); + void changePlayerGuide(CNSocket *sock, CNPacketData *data); void enterPlayerVehicle(CNSocket* sock, CNPacketData* data); void exitPlayerVehicle(CNSocket* sock, CNPacketData* data);