From 3091a845405f25eeca0cfe9bc863682b30a80f45 Mon Sep 17 00:00:00 2001 From: Kinglykrab <89047260+Kinglykrab@users.noreply.github.com> Date: Fri, 6 May 2022 20:06:51 -0400 Subject: [PATCH] [Commands] Cleanup #reloadworld and #repop Command. (#2127) * [Commands] Cleanup #reloadworld Command. - Cleanup messages and logic. * [Commands] Cleanup #reloadworld and #repop Command. - Cleanup messages and logic. - Add #reloadworld 2 option to forcefully repop all mobs globally as well as reset quest timers and reload quests. - Remove delay argument from #repop as it isn't used for anything. * Typos. --- common/emu_constants.h | 6 +++ common/servertalk.h | 2 +- world/console.cpp | 2 +- world/console.old.cpp | 2 +- world/world_event_scheduler.cpp | 2 +- zone/command.cpp | 4 +- zone/gm_commands/reloadworld.cpp | 34 +++++++++++---- zone/gm_commands/repop.cpp | 41 ++++++------------ zone/questmgr.cpp | 15 ++----- zone/spawn2.cpp | 2 +- zone/worldserver.cpp | 2 +- zone/zone.cpp | 71 +++++++++++++++++++++++++++----- zone/zone.h | 5 ++- zone/zone_reload.cpp | 2 +- zone/zonedb.h | 2 +- 15 files changed, 121 insertions(+), 71 deletions(-) diff --git a/common/emu_constants.h b/common/emu_constants.h index f6272274e..178fcbcf4 100644 --- a/common/emu_constants.h +++ b/common/emu_constants.h @@ -416,4 +416,10 @@ enum ConsiderLevel : uint8 { Scowls }; +enum ReloadWorld : uint8 { + NoRepop = 0, + Repop, + ForceRepop +}; + #endif /*COMMON_EMU_CONSTANTS_H*/ diff --git a/common/servertalk.h b/common/servertalk.h index 181344184..8da15b3f9 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -1601,7 +1601,7 @@ struct WWTaskUpdate_Struct { }; struct ReloadWorld_Struct { - uint32 Option; + uint8 global_repop; }; struct HotReloadQuestsStruct { diff --git a/world/console.cpp b/world/console.cpp index 2fa162b98..55a08cabb 100644 --- a/world/console.cpp +++ b/world/console.cpp @@ -889,7 +889,7 @@ void ConsoleReloadWorld( connection->SendLine("Reloading World..."); auto pack = new ServerPacket(ServerOP_ReloadWorld, sizeof(ReloadWorld_Struct)); ReloadWorld_Struct *RW = (ReloadWorld_Struct *) pack->pBuffer; - RW->Option = 1; + RW->global_repop = ReloadWorld::Repop; zoneserver_list.SendPacket(pack); safe_delete(pack); } diff --git a/world/console.old.cpp b/world/console.old.cpp index 49e14f68e..f2e848e57 100644 --- a/world/console.old.cpp +++ b/world/console.old.cpp @@ -875,7 +875,7 @@ void Console::ProcessCommand(const char* command) { SendEmoteMessage(0,0,0,15,"Reloading World..."); auto pack = new ServerPacket(ServerOP_ReloadWorld, sizeof(ReloadWorld_Struct)); ReloadWorld_Struct* RW = (ReloadWorld_Struct*) pack->pBuffer; - RW->Option = 1; + RW->global_repop = ReloadWorld::Repop; zoneserver_list.SendPacket(pack); safe_delete(pack); } diff --git a/world/world_event_scheduler.cpp b/world/world_event_scheduler.cpp index 9b71a4bbd..a38c4684f 100644 --- a/world/world_event_scheduler.cpp +++ b/world/world_event_scheduler.cpp @@ -59,7 +59,7 @@ void WorldEventScheduler::Process(ZSList *zs_list) auto pack = new ServerPacket(ServerOP_ReloadWorld, sizeof(ReloadWorld_Struct)); auto *reload_world = (ReloadWorld_Struct *) pack->pBuffer; - reload_world->Option = 1; + reload_world->global_repop = ReloadWorld::Repop; zs_list->SendPacket(pack); safe_delete(pack); } diff --git a/zone/command.cpp b/zone/command.cpp index 3b14113ea..50e765885 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -299,10 +299,10 @@ int command_init(void) command_add("reloadstatic", "- Reload Static Zone Data globally", AccountStatus::GMLeadAdmin, command_reloadstatic) || command_add("reloadtraps", "- Repops all traps in the current zone.", AccountStatus::QuestTroupe, command_reloadtraps) || command_add("reloadtitles", "- Reload player titles from the database", AccountStatus::GMLeadAdmin, command_reloadtitles) || - command_add("reloadworld", "[0|1] - Clear quest cache (0 - no repop, 1 - repop)", AccountStatus::Max, command_reloadworld) || + command_add("reloadworld", "[0|1|2] - Reload quests global and repop NPCs if specified (0 = No Repop, 1 = Repop, 2 = Force Repop)", AccountStatus::Max, command_reloadworld) || command_add("reloadzps", "- Reload zone points from database", AccountStatus::GMLeadAdmin, command_reloadzps) || command_add("removeitem", "[Item ID] [Amount] - Removes the specified Item ID by Amount from you or your player target's inventory (Amount defaults to 1 if not used)", AccountStatus::GMAdmin, command_removeitem) || - command_add("repop", "[delay] - Repop the zone with optional delay", AccountStatus::GMAdmin, command_repop) || + command_add("repop", "[Force] - Repop the zone with optional force repop", AccountStatus::GMAdmin, command_repop) || command_add("resetaa", "- Resets a Player's AA in their profile and refunds spent AA's to unspent, may disconnect player.", AccountStatus::GMMgmt, command_resetaa) || command_add("resetaa_timer", "Command to reset AA cooldown timers.", AccountStatus::GMMgmt, command_resetaa_timer) || command_add("resetdisc_timer", "[All|Timer ID] - Command to reset discipline timers.", AccountStatus::GMMgmt, command_resetdisc_timer) || diff --git a/zone/gm_commands/reloadworld.cpp b/zone/gm_commands/reloadworld.cpp index f87574d79..4cc67ec56 100755 --- a/zone/gm_commands/reloadworld.cpp +++ b/zone/gm_commands/reloadworld.cpp @@ -5,17 +5,35 @@ extern WorldServer worldserver; void command_reloadworld(Client *c, const Seperator *sep) { - int world_repop = atoi(sep->arg[1]); - if (world_repop == 0) { - c->Message(Chat::White, "Reloading quest cache worldwide."); - } - else { - c->Message(Chat::White, "Reloading quest cache and repopping zones worldwide."); + uint8 global_repop = ReloadWorld::NoRepop; + + if (sep->IsNumber(1)) { + global_repop = static_cast(std::stoul(sep->arg[1])); + + if (global_repop > ReloadWorld::ForceRepop) { + global_repop = ReloadWorld::ForceRepop; + } } - auto pack = new ServerPacket(ServerOP_ReloadWorld, sizeof(ReloadWorld_Struct)); + c->Message( + Chat::White, + fmt::format( + "Attempting to reload quests {}worldwide.", + ( + global_repop ? + ( + global_repop == ReloadWorld::Repop ? + "and repop NPCs " : + "and forcefully repop NPCs " + ) : + "" + ) + ).c_str() + ); + + auto pack = new ServerPacket(ServerOP_ReloadWorld, sizeof(ReloadWorld_Struct)); ReloadWorld_Struct *RW = (ReloadWorld_Struct *) pack->pBuffer; - RW->Option = world_repop; + RW->global_repop = global_repop; worldserver.SendPacket(pack); safe_delete(pack); } diff --git a/zone/gm_commands/repop.cpp b/zone/gm_commands/repop.cpp index 114ef6fa5..7a4f1dbcd 100755 --- a/zone/gm_commands/repop.cpp +++ b/zone/gm_commands/repop.cpp @@ -2,39 +2,22 @@ void command_repop(Client *c, const Seperator *sep) { - int timearg = 1; - int delay = 0; - - if (sep->arg[1] && strcasecmp(sep->arg[1], "force") == 0) { - timearg++; - - LinkedListIterator iterator(zone->spawn2_list); - iterator.Reset(); - while (iterator.MoreElements()) { - std::string query = StringFormat( - "DELETE FROM respawn_times WHERE id = %lu AND instance_id = %lu", - (unsigned long) iterator.GetData()->GetID(), - (unsigned long) zone->GetInstanceID() - ); - auto results = database.QueryDatabase(query); - iterator.Advance(); - } - c->Message(Chat::White, "Zone depop: Force resetting spawn timers."); - } - - if (!sep->IsNumber(timearg)) { - c->Message(Chat::White, "Zone depopped - repopping now."); - - zone->Repop(); - - /* Force a spawn2 timer trigger so we don't delay actually spawning the NPC's */ - zone->spawn2_timer.Trigger(); + int arguments = sep->argnum; + if (!arguments) { + c->Message(Chat::White, "Zone depopped, repopping now."); return; } - c->Message(Chat::White, "Zone depoped. Repop in %i seconds", atoi(sep->arg[timearg])); - zone->Repop(atoi(sep->arg[timearg]) * 1000); + bool is_force = !strcasecmp(sep->arg[1], "force"); + if (is_force) { + zone->ClearSpawnTimers(); + c->Message(Chat::White, "Zone depopped, forcefully repopping now."); + } else { + c->Message(Chat::White, "Zone depopped, repopping now."); + } + + zone->Repop(); zone->spawn2_timer.Trigger(); } diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 59a7d20d0..d90e90a71 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -2520,20 +2520,11 @@ std::string QuestManager::gettaskname(uint32 task_id) { } void QuestManager::clearspawntimers() { - if(!zone) + if (!zone) { return; - - //TODO: Dec 19, 2008, replace with code updated for current spawn timers. - LinkedListIterator iterator(zone->spawn2_list); - iterator.Reset(); - while (iterator.MoreElements()) { - std::string query = StringFormat("DELETE FROM respawn_times " - "WHERE id = %lu AND instance_id = %lu", - (unsigned long)iterator.GetData()->GetID(), - (unsigned long)zone->GetInstanceID()); - auto results = database.QueryDatabase(query); - iterator.Advance(); } + + zone->ClearSpawnTimers(); } void QuestManager::ze(int type, const char *str) { diff --git a/zone/spawn2.cpp b/zone/spawn2.cpp index f15ff12c3..d314137bd 100644 --- a/zone/spawn2.cpp +++ b/zone/spawn2.cpp @@ -535,7 +535,7 @@ bool ZoneDatabase::PopulateZoneSpawnListClose(uint32 zoneid, LinkedList return true; } -bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList &spawn2_list, int16 version, uint32 repopdelay) { +bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList &spawn2_list, int16 version) { std::unordered_map spawn_times; diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index 3b41e71bf..25abd8ab7 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -3133,7 +3133,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { auto* reload_world = (ReloadWorld_Struct*)pack->pBuffer; if (zone) { - zone->ReloadWorld(reload_world->Option); + zone->ReloadWorld(reload_world->global_repop); } break; } diff --git a/zone/zone.cpp b/zone/zone.cpp index d20be4022..b0a027dd1 100755 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -1773,7 +1773,7 @@ void Zone::ClearNPCTypeCache(int id) { } } -void Zone::Repop(uint32 delay) +void Zone::Repop() { if (!Depop()) { return; @@ -1802,7 +1802,7 @@ void Zone::Repop(uint32 delay) LogError("Loading spawn conditions failed, continuing without them"); } - if (!content_db.PopulateZoneSpawnList(zoneid, spawn2_list, GetInstanceVersion(), delay)) { + if (!content_db.PopulateZoneSpawnList(zoneid, spawn2_list, GetInstanceVersion())) { LogDebug("Error in Zone::Repop: database.PopulateZoneSpawnList failed"); } @@ -2458,14 +2458,65 @@ void Zone::LoadNPCEmotes(LinkedList* NPCEmoteList) } -void Zone::ReloadWorld(uint32 Option){ - if (Option == 0) { - entity_list.ClearAreas(); - parse->ReloadQuests(); - } else if(Option == 1) { - entity_list.ClearAreas(); - parse->ReloadQuests(); - zone->Repop(0); +void Zone::ReloadWorld(uint8 global_repop) +{ + entity_list.ClearAreas(); + parse->ReloadQuests(); + + if (global_repop) { + if (global_repop == ReloadWorld::ForceRepop) { + zone->ClearSpawnTimers(); + } + + zone->Repop(); + } + + worldserver.SendEmoteMessage( + 0, + 0, + AccountStatus::GMAdmin, + Chat::Yellow, + fmt::format( + "Quests reloaded {}for {}{}.", + ( + global_repop ? + ( + global_repop == ReloadWorld::Repop ? + "and repopped NPCs " : + "and forcefully repopped NPCs " + ) : + "" + ), + fmt::format( + "{} ({})", + GetLongName(), + GetZoneID() + ), + ( + GetInstanceID() ? + fmt::format( + " (Instance ID {})", + GetInstanceID() + ) : + "" + ) + ).c_str() + ); +} + +void Zone::ClearSpawnTimers() +{ + LinkedListIterator iterator(spawn2_list); + iterator.Reset(); + while (iterator.MoreElements()) { + auto query = fmt::format( + "DELETE FROM respawn_times WHERE id = {} AND instance_id = {}", + iterator.GetData()->GetID(), + GetInstanceID() + ); + auto results = database.QueryDatabase(query); + + iterator.Advance(); } } diff --git a/zone/zone.h b/zone/zone.h index 3304aa30d..3437eb6a6 100755 --- a/zone/zone.h +++ b/zone/zone.h @@ -275,10 +275,10 @@ public: void LoadVeteranRewards(); void LoadZoneDoors(const char *zone, int16 version); void ReloadStaticData(); - void ReloadWorld(uint32 Option); + void ReloadWorld(uint8 global_repop); void RemoveAuth(const char *iCharName, const char *iLSKey); void RemoveAuth(uint32 lsid); - void Repop(uint32 delay = 0); + void Repop(); void RequestUCSServerStatus(); void ResetAuth(); void SetDate(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute); @@ -291,6 +291,7 @@ public: void StartShutdownTimer(uint32 set_time = (RuleI(Zone, AutoShutdownDelay))); void UpdateQGlobal(uint32 qid, QGlobal newGlobal); void weatherSend(Client *client = nullptr); + void ClearSpawnTimers(); bool IsQuestHotReloadQueued() const; void SetQuestHotReloadQueued(bool in_quest_hot_reload_queued); diff --git a/zone/zone_reload.cpp b/zone/zone_reload.cpp index 3dca89d71..f39b35fc7 100644 --- a/zone/zone_reload.cpp +++ b/zone/zone_reload.cpp @@ -30,7 +30,7 @@ void ZoneReload::HotReloadQuests() parse->ReloadQuests(RuleB(HotReload, QuestsResetTimersWithReload)); if (RuleB(HotReload, QuestsRepopWithReload)) { - zone->Repop(0); + zone->Repop(); } zone->SetQuestHotReloadQueued(false); diff --git a/zone/zonedb.h b/zone/zonedb.h index 355a6d632..ad276c73e 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -460,7 +460,7 @@ public: /* Spawns and Spawn Points */ bool LoadSpawnGroups(const char* zone_name, uint16 version, SpawnGroupList* spawn_group_list); bool LoadSpawnGroupsByID(int spawn_group_id, SpawnGroupList* spawn_group_list); - bool PopulateZoneSpawnList(uint32 zoneid, LinkedList &spawn2_list, int16 version, uint32 repopdelay = 0); + bool PopulateZoneSpawnList(uint32 zoneid, LinkedList &spawn2_list, int16 version); bool PopulateZoneSpawnListClose(uint32 zoneid, LinkedList &spawn2_list, int16 version, const glm::vec4& client_position, uint32 repop_distance); Spawn2* LoadSpawn2(LinkedList &spawn2_list, uint32 spawn2id, uint32 timeleft); bool CreateSpawn2(Client *c, uint32 spawngroup, const char* zone, const glm::vec4& position, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value);