diff --git a/config.ini b/config.ini index bab26c0..b37d439 100644 --- a/config.ini +++ b/config.ini @@ -20,7 +20,7 @@ dbsaveinterval=240 port=8002 ip=127.0.0.1 # distance at which other players and NPCs become visible -chunksize=40000 +chunksize=30000 # time, in milliseconds, to wait before kicking a non-responsive client # default is 1 minute timeout=60000 diff --git a/src/BuddyManager.cpp b/src/BuddyManager.cpp index b3940ec..26df559 100644 --- a/src/BuddyManager.cpp +++ b/src/BuddyManager.cpp @@ -29,6 +29,9 @@ void BuddyManager::requestBuddy(CNSocket* sock, CNPacketData* data) { Player* plrReq = PlayerManager::getPlayer(sock); + if (plrReq == nullptr) + return; + sP_CL2FE_REQ_REQUEST_MAKE_BUDDY* pkt = (sP_CL2FE_REQ_REQUEST_MAKE_BUDDY*)data->buf; INITSTRUCT(sP_FE2CL_REP_REQUEST_MAKE_BUDDY_SUCC, resp); @@ -62,6 +65,9 @@ void BuddyManager::reqBuddyByName(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_PC_FIND_NAME_MAKE_BUDDY* pkt = (sP_CL2FE_REQ_PC_FIND_NAME_MAKE_BUDDY*)data->buf; Player* plrReq = PlayerManager::getPlayer(sock); + if (plrReq == nullptr) + return; + INITSTRUCT(sP_FE2CL_REP_PC_FIND_NAME_MAKE_BUDDY_SUCC, resp); CNSocket* otherSock = sock; @@ -95,6 +101,9 @@ void BuddyManager::reqAcceptBuddy(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_ACCEPT_MAKE_BUDDY* pkt = (sP_CL2FE_REQ_ACCEPT_MAKE_BUDDY*)data->buf; Player* plrReq = PlayerManager::getPlayer(sock); + if (plrReq == nullptr) + return; + INITSTRUCT(sP_FE2CL_REP_ACCEPT_MAKE_BUDDY_SUCC, resp); CNSocket* otherSock = sock; @@ -157,6 +166,9 @@ void BuddyManager::reqFindNameBuddyAccept(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_PC_FIND_NAME_ACCEPT_BUDDY* pkt = (sP_CL2FE_REQ_PC_FIND_NAME_ACCEPT_BUDDY*)data->buf; Player* plrReq = PlayerManager::getPlayer(sock); + if (plrReq == nullptr) + return; + INITSTRUCT(sP_FE2CL_REP_ACCEPT_MAKE_BUDDY_SUCC, resp); CNSocket* otherSock = sock; @@ -227,6 +239,9 @@ void BuddyManager::reqBuddyFreechat(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_SEND_BUDDY_FREECHAT_MESSAGE* pkt = (sP_CL2FE_REQ_SEND_BUDDY_FREECHAT_MESSAGE*)data->buf; Player* plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return; + INITSTRUCT(sP_FE2CL_REP_SEND_BUDDY_FREECHAT_MESSAGE_SUCC, resp); CNSocket* otherSock = sock; @@ -255,6 +270,9 @@ void BuddyManager::reqBuddyMenuchat(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_SEND_BUDDY_MENUCHAT_MESSAGE* pkt = (sP_CL2FE_REQ_SEND_BUDDY_MENUCHAT_MESSAGE*)data->buf; Player* plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return; + INITSTRUCT(sP_FE2CL_REP_SEND_BUDDY_MENUCHAT_MESSAGE_SUCC, resp); CNSocket* otherSock = sock; diff --git a/src/CNShardServer.cpp b/src/CNShardServer.cpp index 8f99d12..28bdb47 100644 --- a/src/CNShardServer.cpp +++ b/src/CNShardServer.cpp @@ -61,7 +61,12 @@ void CNShardServer::killConnection(CNSocket* cns) { if (PlayerManager::players.find(cns) == PlayerManager::players.end()) return; - int64_t key = PlayerManager::getPlayer(cns)->SerialKey; + Player* plr = PlayerManager::getPlayer(cns); + + if (plr == nullptr) + return; + + int64_t key = plr->SerialKey; // save player to DB Database::updatePlayer(PlayerManager::players[cns].plr); diff --git a/src/ItemManager.cpp b/src/ItemManager.cpp index 2a62035..96cd8e6 100644 --- a/src/ItemManager.cpp +++ b/src/ItemManager.cpp @@ -198,6 +198,9 @@ void ItemManager::itemUseHandler(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_ITEM_USE* request = (sP_CL2FE_REQ_ITEM_USE*)data->buf; Player* player = PlayerManager::getPlayer(sock); + if (player == nullptr) + return; + //gumball can only be used from inventory, so we ignore eIL sItemBase gumball = player->Inven[request->iSlotNum]; sNano nano = player->Nanos[player->equippedNanos[request->iNanoSlot]]; @@ -769,6 +772,9 @@ void ItemManager::chestOpenHandler(CNSocket *sock, CNPacketData *data) { sP_CL2FE_REQ_ITEM_CHEST_OPEN *pkt = (sP_CL2FE_REQ_ITEM_CHEST_OPEN *)data->buf; Player *plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return; + // item giving packet const size_t resplen = sizeof(sP_FE2CL_REP_REWARD_ITEM) + sizeof(sItemReward); assert(resplen < CN_PACKET_BUFFER_SIZE - 8); diff --git a/src/MissionManager.cpp b/src/MissionManager.cpp index e94b8d3..07a7ff9 100644 --- a/src/MissionManager.cpp +++ b/src/MissionManager.cpp @@ -67,6 +67,9 @@ void MissionManager::taskStart(CNSocket* sock, CNPacketData* data) { INITSTRUCT(sP_FE2CL_REP_PC_TASK_START_SUCC, response); Player *plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return; + if (!startTask(plr, missionData->iTaskNum, false)) { // TODO: TASK_FAIL? response.iTaskNum = missionData->iTaskNum; @@ -109,6 +112,9 @@ void MissionManager::taskEnd(CNSocket* sock, CNPacketData* data) { bool MissionManager::endTask(CNSocket *sock, int32_t taskNum) { Player *plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return false; + if (Tasks.find(taskNum) == Tasks.end()) return false; @@ -178,13 +184,17 @@ void MissionManager::setMission(CNSocket* sock, CNPacketData* data) { if (data->size != sizeof(sP_CL2FE_REQ_PC_SET_CURRENT_MISSION_ID)) return; // malformed packet + Player* plr = PlayerManager::getPlayer(sock); + + if (plr == nullptr) + return; + sP_CL2FE_REQ_PC_SET_CURRENT_MISSION_ID* missionData = (sP_CL2FE_REQ_PC_SET_CURRENT_MISSION_ID*)data->buf; INITSTRUCT(sP_FE2CL_REP_PC_SET_CURRENT_MISSION_ID, response); - response.iCurrentMissionID = missionData->iCurrentMissionID; - sock->sendPacket((void*)&response, P_FE2CL_REP_PC_SET_CURRENT_MISSION_ID, sizeof(sP_FE2CL_REP_PC_SET_CURRENT_MISSION_ID)); - Player* plr = PlayerManager::getPlayer(sock); plr->CurrentMissionID = missionData->iCurrentMissionID; + + sock->sendPacket((void*)&response, P_FE2CL_REP_PC_SET_CURRENT_MISSION_ID, sizeof(sP_FE2CL_REP_PC_SET_CURRENT_MISSION_ID)); } void MissionManager::quitMission(CNSocket* sock, CNPacketData* data) { @@ -199,6 +209,9 @@ void MissionManager::quitTask(CNSocket* sock, int32_t taskNum) { INITSTRUCT(sP_FE2CL_REP_PC_TASK_STOP_SUCC, response); Player* plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return; + // update player int i; for (i = 0; i < ACTIVE_MISSION_COUNT; i++) { @@ -257,11 +270,15 @@ void MissionManager::dropQuestItem(CNSocket *sock, int task, int count, int id, const size_t resplen = sizeof(sP_FE2CL_REP_REWARD_ITEM) + sizeof(sItemReward); assert(resplen < CN_PACKET_BUFFER_SIZE); // we know it's only one trailing struct, so we can skip full validation + + Player *plr = PlayerManager::getPlayer(sock); + + if (plr == nullptr) + return; uint8_t respbuf[resplen]; // not a variable length array, don't worry sP_FE2CL_REP_REWARD_ITEM *reward = (sP_FE2CL_REP_REWARD_ITEM *)respbuf; sItemReward *item = (sItemReward *)(respbuf + sizeof(sP_FE2CL_REP_REWARD_ITEM)); - Player *plr = PlayerManager::getPlayer(sock); // don't forget to zero the buffer! memset(respbuf, 0, resplen); @@ -308,6 +325,9 @@ int MissionManager::giveMissionReward(CNSocket *sock, int task) { Reward *reward = Rewards[task]; Player *plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return -1; + int nrewards = 0; for (int i = 0; i < 4; i++) { if (reward->itemIds[i] != 0) @@ -367,6 +387,9 @@ int MissionManager::giveMissionReward(CNSocket *sock, int task) { void MissionManager::updateFusionMatter(CNSocket* sock, int fusion) { Player *plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return; + plr->fusionmatter += fusion; // there's a much lower FM cap in the Future @@ -400,6 +423,10 @@ void MissionManager::updateFusionMatter(CNSocket* sock, int fusion) { void MissionManager::mobKilled(CNSocket *sock, int mobid) { Player *plr = PlayerManager::getPlayer(sock); + + if (plr == nullptr) + return; + bool missionmob = false; for (int i = 0; i < ACTIVE_MISSION_COUNT; i++) { @@ -465,6 +492,10 @@ void MissionManager::saveMission(Player* player, int missionId) { bool MissionManager::isQuestItemFull(CNSocket* sock, int itemId, int itemCount) { Player* plr = PlayerManager::getPlayer(sock); + + if (plr == nullptr) + return true; + int slot = findQSlot(plr, itemId); if (slot == -1) { // this should never happen diff --git a/src/MobManager.cpp b/src/MobManager.cpp index 8957d10..491bff5 100644 --- a/src/MobManager.cpp +++ b/src/MobManager.cpp @@ -32,6 +32,9 @@ void MobManager::pcAttackNpcs(CNSocket *sock, CNPacketData *data) { sP_CL2FE_REQ_PC_ATTACK_NPCs* pkt = (sP_CL2FE_REQ_PC_ATTACK_NPCs*)data->buf; Player *plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return; + // sanity check if (!validInVarPacket(sizeof(sP_CL2FE_REQ_PC_ATTACK_NPCs), pkt->iNPCCnt, sizeof(int32_t), data->size)) { std::cout << "[WARN] bad sP_CL2FE_REQ_PC_ATTACK_NPCs packet size\n"; @@ -98,9 +101,11 @@ void MobManager::pcAttackNpcs(CNSocket *sock, CNPacketData *data) { } void MobManager::npcAttackPc(Mob *mob) { - // player pointer has already been validated Player *plr = PlayerManager::getPlayer(mob->target); + if (plr == nullptr) + return; + const size_t resplen = sizeof(sP_FE2CL_PC_ATTACK_NPCs_SUCC) + sizeof(sAttackResult); assert(resplen < CN_PACKET_BUFFER_SIZE - 8); uint8_t respbuf[CN_PACKET_BUFFER_SIZE]; @@ -132,6 +137,9 @@ void MobManager::npcAttackPc(Mob *mob) { void MobManager::giveReward(CNSocket *sock) { Player *plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return; + const size_t resplen = sizeof(sP_FE2CL_REP_REWARD_ITEM) + sizeof(sItemReward); assert(resplen < CN_PACKET_BUFFER_SIZE - 8); // we know it's only one trailing struct, so we can skip full validation @@ -268,6 +276,9 @@ void MobManager::combatStep(Mob *mob, time_t currTime) { } Player *plr = PlayerManager::getPlayer(mob->target); + if (plr == nullptr) + return; + // did something else kill the player in the mean time? if (plr->HP <= 0) { mob->target = nullptr; @@ -501,19 +512,24 @@ std::pair MobManager::lerp(int x1, int y1, int x2, int y2, int speed) { void MobManager::combatBegin(CNSocket *sock, CNPacketData *data) { Player *plr = PlayerManager::getPlayer(sock); - plr->inCombat = true; + + if (plr != nullptr) + plr->inCombat = true; } void MobManager::combatEnd(CNSocket *sock, CNPacketData *data) { Player *plr = PlayerManager::getPlayer(sock); - plr->inCombat = false; + + if (plr != nullptr) + plr->inCombat = false; } void MobManager::dotDamageOnOff(CNSocket *sock, CNPacketData *data) { sP_CL2FE_DOT_DAMAGE_ONOFF *pkt = (sP_CL2FE_DOT_DAMAGE_ONOFF*)data->buf; Player *plr = PlayerManager::getPlayer(sock); - plr->dotDamage = (bool)pkt->iFlag; + if (plr != nullptr) + plr->dotDamage = (bool)pkt->iFlag; } void MobManager::dealGooDamage(CNSocket *sock, int amount) { @@ -527,6 +543,9 @@ void MobManager::dealGooDamage(CNSocket *sock, int amount) { sSkillResult_DotDamage *dmg = (sSkillResult_DotDamage*)(respbuf + sizeof(sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK)); Player *plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return; + // update player plr->HP -= amount; @@ -629,6 +648,9 @@ void MobManager::pcAttackChars(CNSocket *sock, CNPacketData *data) { sP_CL2FE_REQ_PC_ATTACK_CHARs* pkt = (sP_CL2FE_REQ_PC_ATTACK_CHARs*)data->buf; Player *plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return; + // Unlike the attack mob packet, attacking players packet has an 8-byte trail (Instead of 4 bytes). if (!validInVarPacket(sizeof(sP_CL2FE_REQ_PC_ATTACK_CHARs), pkt->iTargetCnt, sizeof(int32_t) * 2, data->size)) { std::cout << "[WARN] bad sP_CL2FE_REQ_PC_ATTACK_CHARs packet size\n"; diff --git a/src/NPCManager.cpp b/src/NPCManager.cpp index 7a64517..e766f0d 100644 --- a/src/NPCManager.cpp +++ b/src/NPCManager.cpp @@ -178,6 +178,10 @@ void NPCManager::npcVendorBuy(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_PC_VENDOR_ITEM_BUY* req = (sP_CL2FE_REQ_PC_VENDOR_ITEM_BUY*)data->buf; Player *plr = PlayerManager::getPlayer(sock); + + if (plr == nullptr) + return; + Item* item = ItemManager::getItemData(req->Item.iID, req->Item.iType); if (item == nullptr) { @@ -227,6 +231,9 @@ void NPCManager::npcVendorSell(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_PC_VENDOR_ITEM_SELL* req = (sP_CL2FE_REQ_PC_VENDOR_ITEM_SELL*)data->buf; Player* plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return; + if (req->iInvenSlotNum < 0 || req->iInvenSlotNum >= AINVEN_COUNT || req->iItemCnt < 0) { std::cout << "[WARN] Client failed to sell item in slot " << req->iInvenSlotNum << std::endl; INITSTRUCT(sP_FE2CL_REP_PC_VENDOR_ITEM_SELL_FAIL, failResp); @@ -283,6 +290,10 @@ void NPCManager::npcVendorBuyback(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_PC_VENDOR_ITEM_RESTORE_BUY* req = (sP_CL2FE_REQ_PC_VENDOR_ITEM_RESTORE_BUY*)data->buf; Player* plr = PlayerManager::getPlayer(sock); + + if (plr == nullptr) + return; + Item* item = ItemManager::getItemData(req->Item.iID, req->Item.iType); if (item == nullptr) { @@ -374,6 +385,9 @@ void NPCManager::npcVendorBuyBattery(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_PC_VENDOR_BATTERY_BUY* req = (sP_CL2FE_REQ_PC_VENDOR_BATTERY_BUY*)data->buf; Player* plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return; + int cost = req->Item.iOpt * 100; if ((req->Item.iID == 3 ? (plr->batteryW >= 9999) : (plr->batteryN >= 9999)) || plr->money < cost) { // sanity check INITSTRUCT(sP_FE2CL_REP_PC_VENDOR_BATTERY_BUY_FAIL, failResp); @@ -406,6 +420,9 @@ void NPCManager::npcCombineItems(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_PC_ITEM_COMBINATION* req = (sP_CL2FE_REQ_PC_ITEM_COMBINATION*)data->buf; Player* plr = PlayerManager::getPlayer(sock); + + if (plr == nullptr) + return; if (req->iCostumeItemSlot < 0 || req->iCostumeItemSlot >= AINVEN_COUNT || req->iStatItemSlot < 0 || req->iStatItemSlot >= AINVEN_COUNT) { // sanity check 1 INITSTRUCT(sP_FE2CL_REP_PC_ITEM_COMBINATION_FAIL, failResp); @@ -495,7 +512,9 @@ void NPCManager::npcUnsummonHandler(CNSocket* sock, CNPacketData* data) { if (data->size != sizeof(sP_CL2FE_REQ_NPC_UNSUMMON)) return; // malformed packet - if (PlayerManager::getPlayer(sock)->accountLevel > 30) + Player* plr = PlayerManager::getPlayer(sock); + + if (plr == nullptr || plr->accountLevel > 30) return; sP_CL2FE_REQ_NPC_UNSUMMON* req = (sP_CL2FE_REQ_NPC_UNSUMMON*)data->buf; @@ -511,7 +530,7 @@ void NPCManager::npcSummonHandler(CNSocket* sock, CNPacketData* data) { Player* plr = PlayerManager::getPlayer(sock); // permission & sanity check - if (plr->accountLevel > 30 || req->iNPCType >= 3314) + if (plr == nullptr || plr->accountLevel > 30 || req->iNPCType >= 3314) return; int team = NPCData[req->iNPCType]["m_iTeam"]; diff --git a/src/NanoManager.cpp b/src/NanoManager.cpp index 266bbd8..c024aed 100644 --- a/src/NanoManager.cpp +++ b/src/NanoManager.cpp @@ -61,8 +61,8 @@ void NanoManager::nanoEquipHandler(CNSocket* sock, CNPacketData* data) { INITSTRUCT(sP_FE2CL_REP_NANO_EQUIP_SUCC, resp); Player *plr = PlayerManager::getPlayer(sock); - // sanity check - if (nano->iNanoSlotNum > 2 || nano->iNanoSlotNum < 0) + // sanity checks + if (plr == nullptr || nano->iNanoSlotNum > 2 || nano->iNanoSlotNum < 0) return; resp.iNanoID = nano->iNanoID; @@ -87,7 +87,7 @@ void NanoManager::nanoUnEquipHandler(CNSocket* sock, CNPacketData* data) { Player *plr = PlayerManager::getPlayer(sock); // sanity check - if (nano->iNanoSlotNum > 2 || nano->iNanoSlotNum < 0) + if (plr == nullptr || nano->iNanoSlotNum > 2 || nano->iNanoSlotNum < 0) return; resp.iNanoSlotNum = nano->iNanoSlotNum; @@ -110,6 +110,9 @@ void NanoManager::nanoGMGiveHandler(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_PC_GIVE_NANO* nano = (sP_CL2FE_REQ_PC_GIVE_NANO*)data->buf; Player *plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return; + // Add nano to player addNano(sock, nano->iNanoID, 0); @@ -125,6 +128,9 @@ void NanoManager::nanoSummonHandler(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_NANO_ACTIVE* pkt = (sP_CL2FE_REQ_NANO_ACTIVE*)data->buf; Player *plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return; + summonNano(sock, pkt->iNanoSlotNum); // Send to client @@ -135,6 +141,10 @@ void NanoManager::nanoSummonHandler(CNSocket* sock, CNPacketData* data) { void NanoManager::nanoSkillUseHandler(CNSocket* sock, CNPacketData* data) { Player *plr = PlayerManager::getPlayer(sock); + + if (plr == nullptr) + return; + int16_t nanoId = plr->activeNano; int16_t skillId = plr->Nanos[nanoId].iSkillID; @@ -178,8 +188,9 @@ void NanoManager::nanoPotionHandler(CNSocket* sock, CNPacketData* data) { return; Player* player = PlayerManager::getPlayer(sock); - //sanity check - if (player->activeNano == -1 || player->batteryN == 0) + + // sanity checks + if (player == nullptr || player->activeNano == -1 || player->batteryN == 0) return; sNano nano = player->Nanos[player->activeNano]; @@ -209,6 +220,9 @@ void NanoManager::addNano(CNSocket* sock, int16_t nanoId, int16_t slot, bool spe Player *plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return; + int level = nanoId < plr->level ? plr->level : nanoId; /* @@ -255,7 +269,7 @@ void NanoManager::summonNano(CNSocket *sock, int slot) { resp.iActiveNanoSlotNum = slot; Player *plr = PlayerManager::getPlayer(sock); - if (slot > 2 || slot < -1) + if (plr == nullptr || slot > 2 || slot < -1) return; // sanity check int16_t nanoId = slot == -1 ? -1 : plr->equippedNanos[slot]; @@ -307,6 +321,10 @@ void NanoManager::setNanoSkill(CNSocket* sock, int16_t nanoId, int16_t skillId) return; Player *plr = PlayerManager::getPlayer(sock); + + if (plr == nullptr) + return; + sNano nano = plr->Nanos[nanoId]; nano.iSkillID = skillId; @@ -331,6 +349,10 @@ void NanoManager::resetNanoSkill(CNSocket* sock, int16_t nanoId) { return; Player *plr = PlayerManager::getPlayer(sock); + + if (plr == nullptr) + return; + sNano nano = plr->Nanos[nanoId]; // 0 is reset @@ -449,6 +471,9 @@ bool doLeech(CNSocket *sock, int32_t *pktdata, sSkillResult_Heal_HP *healdata, i sSkillResult_Damage *damagedata = (sSkillResult_Damage*)(((uint8_t*)healdata) + sizeof(sSkillResult_Heal_HP)); Player *plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return false; + if (plr->HP + amount > PC_MAXHEALTH(plr->level)) plr->HP = PC_MAXHEALTH(plr->level); else @@ -518,6 +543,9 @@ void activePower(CNSocket *sock, CNPacketData *data, Player *plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return; + plr->Nanos[plr->activeNano].iStamina -= 40; resp->iPC_ID = plr->iID; @@ -556,6 +584,9 @@ std::vector ActivePowers = { void NanoManager::nanoBuff(CNSocket* sock, int16_t nanoId, int skillId, int16_t eSkillType, int32_t iCBFlag, int16_t eCharStatusTimeBuffID, int16_t iValue) { Player *plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return; + if (!validOutVarPacket(sizeof(sP_FE2CL_NANO_SKILL_USE), 1, sizeof(sSkillResult_Buff))) { std::cout << "[WARN] bad sP_FE2CL_NANO_SKILL_USE packet size\n"; return; @@ -606,6 +637,10 @@ void NanoManager::nanoUnbuff(CNSocket* sock, int32_t iCBFlag, int16_t eCharStatu INITSTRUCT(sP_FE2CL_PC_BUFF_UPDATE, resp1); Player *plr = PlayerManager::getPlayer(sock); + + if (plr == nullptr) + return; + if (iCBFlag < plr->iConditionBitFlag) // prevents integer underflow plr->iConditionBitFlag -= iCBFlag; else diff --git a/src/PlayerManager.cpp b/src/PlayerManager.cpp index e559063..6fac1a1 100644 --- a/src/PlayerManager.cpp +++ b/src/PlayerManager.cpp @@ -659,6 +659,9 @@ void PlayerManager::setSpecialPlayer(CNSocket* sock, CNPacketData* data) { sP_CL2FE_GM_REQ_PC_SET_VALUE* setData = (sP_CL2FE_GM_REQ_PC_SET_VALUE*)data->buf; Player *plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return; + INITSTRUCT(sP_FE2CL_GM_REP_PC_SET_VALUE, response); DEBUGLOG( @@ -718,6 +721,10 @@ void PlayerManager::revivePlayer(CNSocket* sock, CNPacketData* data) { return; Player *plr = PlayerManager::getPlayer(sock); + + if (plr == nullptr) + return; + WarpLocation target = PlayerManager::getRespawnPoint(plr); sP_CL2FE_REQ_PC_REGEN* reviveData = (sP_CL2FE_REQ_PC_REGEN*)data->buf; @@ -857,8 +864,10 @@ void PlayerManager::changePlayerGuide(CNSocket *sock, CNPacketData *data) { #pragma region Helper methods Player *PlayerManager::getPlayer(CNSocket* key) { - assert(key->plr != nullptr); - return key->plr; + if (players.find(key) != players.end()) + return players[key].plr; + + return nullptr; } WarpLocation PlayerManager::getRespawnPoint(Player *plr) { diff --git a/src/TransportManager.cpp b/src/TransportManager.cpp index dc8409d..91c70f8 100644 --- a/src/TransportManager.cpp +++ b/src/TransportManager.cpp @@ -26,6 +26,9 @@ void TransportManager::transportRegisterLocationHandler(CNSocket* sock, CNPacket sP_CL2FE_REQ_REGIST_TRANSPORTATION_LOCATION* transport = (sP_CL2FE_REQ_REGIST_TRANSPORTATION_LOCATION*)data->buf; Player* plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return; + bool newReg = false; // this is a new registration //std::cout << "request to register transport, eTT " << transport->eTT << ", locID " << transport->iLocationID << ", npc " << transport->iNPC_ID << std::endl; if (transport->eTT == 1) { // S.C.A.M.P.E.R. @@ -108,6 +111,9 @@ void TransportManager::transportWarpHandler(CNSocket* sock, CNPacketData* data) sP_CL2FE_REQ_PC_WARP_USE_TRANSPORTATION* req = (sP_CL2FE_REQ_PC_WARP_USE_TRANSPORTATION*)data->buf; Player* plr = PlayerManager::getPlayer(sock); + if (plr == nullptr) + return; + /* * req: * eIL -- inventory type @@ -193,9 +199,7 @@ void TransportManager::stepSkywaySystem() { std::queue* queue = &it->second; - Player* plr = nullptr; - if(PlayerManager::players.find(it->first) != PlayerManager::players.end()) // check if socket still has a player - plr = PlayerManager::getPlayer(it->first); + Player* plr = PlayerManager::getPlayer(it->first); if (plr == nullptr) { // pluck out dead socket + update iterator