From efd729710f7b559ef0a318c6d37fe902759f3c10 Mon Sep 17 00:00:00 2001 From: Gent Date: Wed, 14 Oct 2020 00:26:30 -0400 Subject: [PATCH] Kick players out of instances when they leave --- src/CNShardServer.cpp | 4 +--- src/Database.cpp | 16 ++++++++++++---- src/MissionManager.cpp | 18 ++++++++++++++++++ src/MissionManager.hpp | 2 ++ src/NPCManager.cpp | 21 ++++++++------------- src/Player.hpp | 1 + src/PlayerManager.cpp | 5 +++++ 7 files changed, 47 insertions(+), 20 deletions(-) diff --git a/src/CNShardServer.cpp b/src/CNShardServer.cpp index 0a5dae7..3677f3a 100644 --- a/src/CNShardServer.cpp +++ b/src/CNShardServer.cpp @@ -82,9 +82,7 @@ void CNShardServer::_killConnection(CNSocket* cns) { int64_t key = plr->SerialKey; - // save player to DB - Database::updatePlayer(PlayerManager::players[cns].plr); - PlayerManager::removePlayer(cns); + PlayerManager::removePlayer(cns); // removes the player from the list and saves it to DB // remove from CNSharedData CNSharedData::erasePlayer(key); diff --git a/src/Database.cpp b/src/Database.cpp index c12d286..ab1698b 100644 --- a/src/Database.cpp +++ b/src/Database.cpp @@ -390,10 +390,18 @@ Database::DbPlayer Database::playerToDb(Player *player) result.slot = player->slot; result.Taros = player->money; result.TutorialFlag = player->PCStyle2.iTutorialFlag; - result.x_coordinates = player->x; - result.y_coordinates = player->y; - result.z_coordinates = player->z; - result.angle = player->angle; + if (player->instanceID == 0) { // only save coords if player isn't instanced + result.x_coordinates = player->x; + result.y_coordinates = player->y; + result.z_coordinates = player->z; + result.angle = player->angle; + } + else { + result.x_coordinates = player->lastX; + result.y_coordinates = player->lastY; + result.z_coordinates = player->lastZ; + result.angle = player->lastAngle; + } result.Nano1 = player->equippedNanos[0]; result.Nano2 = player->equippedNanos[1]; result.Nano3 = player->equippedNanos[2]; diff --git a/src/MissionManager.cpp b/src/MissionManager.cpp index a34736a..536128f 100644 --- a/src/MissionManager.cpp +++ b/src/MissionManager.cpp @@ -506,3 +506,21 @@ bool MissionManager::isQuestItemFull(CNSocket* sock, int itemId, int itemCount) return (itemCount == plr->QInven[slot].iOpt); } + +void MissionManager::failInstancedMissions(CNSocket* sock) { + // loop through all tasks; if the required instance is being left, "fail" the task + Player* plr = PlayerManager::getPlayer(sock); + for (int taskNum : plr->tasks) { + if (MissionManager::Tasks.find(taskNum) == MissionManager::Tasks.end()) + continue; // sanity check + + TaskData* task = MissionManager::Tasks[taskNum]; + if ((plr->instanceID & 0xffffffff) == (int)(task->task["m_iRequireInstanceID"])) { // map num matches + int failTaskID = task->task["m_iFOutgoingTask"]; + if (failTaskID != 0) { + MissionManager::quitTask(sock, taskNum); + MissionManager::startTask(sock, failTaskID, task->task["m_iSTNanoID"] != 0); + } + } + } +} diff --git a/src/MissionManager.hpp b/src/MissionManager.hpp index 1270961..18a73be 100644 --- a/src/MissionManager.hpp +++ b/src/MissionManager.hpp @@ -58,4 +58,6 @@ namespace MissionManager { bool endTask(CNSocket *sock, int32_t taskNum); void saveMission(Player* player, int missionId); void quitTask(CNSocket* sock, int32_t taskNum); + + void failInstancedMissions(CNSocket* sock); } diff --git a/src/NPCManager.cpp b/src/NPCManager.cpp index 9c95035..8a9f696 100644 --- a/src/NPCManager.cpp +++ b/src/NPCManager.cpp @@ -590,19 +590,14 @@ void NPCManager::handleWarp(CNSocket* sock, int32_t warpId) { if (Warps.find(warpId) == Warps.end()) return; - // loop through all tasks; if the required instance is being left, "fail" the task - for (int taskNum : plrv.plr->tasks) { - if (MissionManager::Tasks.find(taskNum) == MissionManager::Tasks.end()) - continue; // sanity check - - TaskData* task = MissionManager::Tasks[taskNum]; - if ((plrv.plr->instanceID & 0xffffffff) == (int)(task->task["m_iRequireInstanceID"])) { // instance ID matches - int failTaskID = task->task["m_iFOutgoingTask"]; - if (failTaskID != 0) { - MissionManager::quitTask(sock, taskNum); - // TODO: start fail task - } - } + MissionManager::failInstancedMissions(sock); // fail any missions that require the player's current instance + + if (plrv.plr->instanceID == 0) { + // save last uninstanced coords + plrv.plr->lastX = plrv.plr->x; + plrv.plr->lastY = plrv.plr->y; + plrv.plr->lastZ = plrv.plr->z; + plrv.plr->lastAngle = plrv.plr->angle; } // std::cerr << "Warped to Map Num:" << Warps[warpId].instanceID << " NPC ID " << Warps[warpId].npcID << std::endl; diff --git a/src/Player.hpp b/src/Player.hpp index a7805ee..e90dbef 100644 --- a/src/Player.hpp +++ b/src/Player.hpp @@ -38,6 +38,7 @@ struct Player { int8_t iSpecialState; int x, y, z, angle; + int lastX, lastY, lastZ, lastAngle; uint64_t instanceID; sItemBase Equip[AEQUIP_COUNT]; sItemBase Inven[AINVEN_COUNT]; diff --git a/src/PlayerManager.cpp b/src/PlayerManager.cpp index a99dfb2..159b9d5 100644 --- a/src/PlayerManager.cpp +++ b/src/PlayerManager.cpp @@ -8,6 +8,7 @@ #include "NanoManager.hpp" #include "GroupManager.hpp" #include "ChatManager.hpp" +#include "Database.hpp" #include "settings.hpp" @@ -64,8 +65,12 @@ void PlayerManager::addPlayer(CNSocket* key, Player plr) { void PlayerManager::removePlayer(CNSocket* key) { PlayerView& view = players[key]; + MissionManager::failInstancedMissions(key); GroupManager::groupKickPlayer(view.plr); + // save player to DB + Database::updatePlayer(view.plr); + INITSTRUCT(sP_FE2CL_PC_EXIT, exitPacket); exitPacket.iID = players[key].plr->iID;