From 90bcc5f03cad615ac27df27c465c7ace55181821 Mon Sep 17 00:00:00 2001 From: Kinglykrab <89047260+Kinglykrab@users.noreply.github.com> Date: Sun, 14 Nov 2021 11:32:08 -0500 Subject: [PATCH] [Commands] Cleanup #zonelock Command. (#1711) * [Commands] Cleanup #zonelock Command. - Add support for Zone IDs. - Cleanup messages and display. - Fix dangling pointer in ZoneLongName() helper method so name is displayed properly. * Add account status enum. * Typo. * Typo. * Convert list to constants. * Cleanup. * Update command.cpp * Fix compile. --- common/emu_constants.h | 25 +++++++++++++ world/world_store.cpp | 20 +++++++++++ world/world_store.h | 10 ++++-- world/zonelist.cpp | 37 +++++++++++++++---- world/zoneserver.cpp | 52 +++++++++++++++++++-------- world/zoneserver.h | 2 +- zone/command.cpp | 80 +++++++++++++++++++++++++----------------- 7 files changed, 170 insertions(+), 56 deletions(-) diff --git a/common/emu_constants.h b/common/emu_constants.h index c64199082..806ce0a86 100644 --- a/common/emu_constants.h +++ b/common/emu_constants.h @@ -230,6 +230,31 @@ namespace EQ const int STANCE_TYPE_LAST = stanceBurnAE; const int STANCE_TYPE_COUNT = stanceBurnAE; + enum ServerLockType : int { + List, + Lock, + Unlock + }; + + enum AccountStatus : uint8 { + Player = 0, + Steward = 10, + ApprenticeGuide = 20, + Guide = 50, + QuestTroupe = 80, + SeniorGuide = 81, + GMTester = 85, + EQSupport = 90, + GMStaff = 95, + GMAdmin = 100, + GMLeadAdmin = 150, + QuestMaster = 160, + GMAreas = 170, + GMCoder = 180, + GMMgmt = 200, + GMImpossible = 250, + Max = 255 + }; } /*constants*/ namespace profile { diff --git a/world/world_store.cpp b/world/world_store.cpp index 5a8201124..62c484172 100644 --- a/world/world_store.cpp +++ b/world/world_store.cpp @@ -85,6 +85,26 @@ std::string WorldStore::GetZoneName(uint32 zone_id) return std::string(); } +/** + * @param zone_id + * @param error_unknown + * @return + */ +const char *WorldStore::GetZoneLongName(uint32 zone_id, bool error_unknown) +{ + for (auto &z: zones) { + if (z.zoneidnumber == zone_id) { + return z.long_name.c_str(); + } + } + + if (error_unknown) { + return "UNKNOWN"; + } + + return nullptr; +} + /** * @param zone_id * @return diff --git a/world/world_store.h b/world/world_store.h index 985419ff0..ecbba4b5e 100644 --- a/world/world_store.h +++ b/world/world_store.h @@ -40,7 +40,7 @@ public: std::string GetZoneName(uint32 zone_id); std::string GetZoneLongName(uint32 zone_id); const char *GetZoneName(uint32 zone_id, bool error_unknown = false); - + const char *GetZoneLongName(uint32 zone_id, bool error_unknown = false); }; extern WorldStore world_store; @@ -57,7 +57,13 @@ inline const char *ZoneName(uint32 zone_id, bool error_unknown = false) error_unknown ); } -inline const char *ZoneLongName(uint32 zone_id) { return world_store.GetZoneLongName(zone_id).c_str(); } +inline const char *ZoneLongName(uint32 zone_id, bool error_unknown = false) +{ + return world_store.GetZoneLongName( + zone_id, + error_unknown + ); +} inline ZoneRepository::Zone GetZone(uint32 zone_id, int version = 0) { return world_store.GetZone(zone_id, version); }; inline ZoneRepository::Zone GetZone(const char *in_zone_name) { return world_store.GetZone(in_zone_name); }; diff --git a/world/zonelist.cpp b/world/zonelist.cpp index 400c07854..a949a8bd5 100644 --- a/world/zonelist.cpp +++ b/world/zonelist.cpp @@ -270,14 +270,39 @@ bool ZSList::IsZoneLocked(uint16 iZoneID) { } void ZSList::ListLockedZones(const char* to, WorldTCPConnection* connection) { - int x = 0; - for (auto &zone : pLockedZones) { - if (zone) { - connection->SendEmoteMessageRaw(to, 0, 0, 0, ZoneName(zone, true)); - x++; + int zone_count = 0; + for (const auto& zone_id : pLockedZones) { + if (zone_id) { + int zone_number = (zone_count + 1); + connection->SendEmoteMessageRaw( + to, + 0, + EQ::constants::AccountStatus::Player, + Chat::White, + fmt::format( + "Zone {} | Name: {} ({}) ID: {}", + zone_number, + ZoneLongName(zone_id), + ZoneName(zone_id), + zone_id + ).c_str() + ); + zone_count++; } } - connection->SendEmoteMessage(to, 0, 0, 0, "%i zones locked.", x); + + std::string zone_message = ( + zone_count ? + fmt::format("{} Zones are locked.", zone_count) : + "There are no zones locked." + ); + connection->SendEmoteMessage( + to, + 0, + EQ::constants::AccountStatus::Player, + Chat::White, + zone_message.c_str() + ); } void ZSList::SendZoneStatus(const char* to, int16 admin, WorldTCPConnection* connection) { diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index 6403b2540..7f11dc8b3 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -1022,22 +1022,44 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { LogInfo("Wrong size on ServerOP_LockZone. Got: [{}], Expected: [{}]", pack->size, sizeof(ServerLockZone_Struct)); break; } - ServerLockZone_Struct* s = (ServerLockZone_Struct*)pack->pBuffer; - switch (s->op) { - case 0: - zoneserver_list.ListLockedZones(s->adminname, this); + + ServerLockZone_Struct* lock_zone = (ServerLockZone_Struct*) pack->pBuffer; + if (lock_zone->op == EQ::constants::ServerLockType::List) { + zoneserver_list.ListLockedZones(lock_zone->adminname, this); break; - case 1: - if (zoneserver_list.SetLockedZone(s->zoneID, true)) - zoneserver_list.SendEmoteMessage(0, 0, 80, 15, "Zone locked: %s", ZoneName(s->zoneID)); - else - this->SendEmoteMessageRaw(s->adminname, 0, 0, 0, "Failed to change lock"); - break; - case 2: - if (zoneserver_list.SetLockedZone(s->zoneID, false)) - zoneserver_list.SendEmoteMessage(0, 0, 80, 15, "Zone unlocked: %s", ZoneName(s->zoneID)); - else - this->SendEmoteMessageRaw(s->adminname, 0, 0, 0, "Failed to change lock"); + } else if ( + lock_zone->op == EQ::constants::ServerLockType::Lock || + lock_zone->op == EQ::constants::ServerLockType::Unlock + ) { + if (zoneserver_list.SetLockedZone(lock_zone->zoneID, lock_zone->op == EQ::constants::ServerLockType::Lock)) { + zoneserver_list.SendEmoteMessage( + 0, + 0, + EQ::constants::AccountStatus::QuestTroupe, + Chat::White, + fmt::format( + "Zone {} | Name: {} ({}) ID: {}", + lock_zone->op == EQ::constants::ServerLockType::Lock ? "Locked" : "Unlocked", + ZoneLongName(lock_zone->zoneID), + ZoneName(lock_zone->zoneID), + lock_zone->zoneID + ).c_str() + ); + } else { + SendEmoteMessageRaw( + lock_zone->adminname, + 0, + EQ::constants::AccountStatus::Player, + Chat::White, + fmt::format( + "Zone Failed to {} | Name: {} ({}) ID: {}", + lock_zone->op == EQ::constants::ServerLockType::Lock ? "Lock" : "Unlock", + ZoneLongName(lock_zone->zoneID), + ZoneName(lock_zone->zoneID), + lock_zone->zoneID + ).c_str() + ); + } break; } break; diff --git a/world/zoneserver.h b/world/zoneserver.h index 8bb1a6da8..98f60dcdb 100644 --- a/world/zoneserver.h +++ b/world/zoneserver.h @@ -22,6 +22,7 @@ #include "../common/net/servertalk_server.h" #include "../common/event/timer.h" #include "../common/timer.h" +#include "../common/emu_constants.h" #include "console.h" #include #include @@ -29,7 +30,6 @@ class Client; class ServerPacket; - class ZoneServer : public WorldTCPConnection { public: ZoneServer(std::shared_ptr connection, EQ::Net::ConsoleServer *console); diff --git a/zone/command.cpp b/zone/command.cpp index c7f6b3b3a..16ee02d55 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -455,7 +455,7 @@ int command_init(void) command_add("zone", "[zonename] [x] [y] [z] - Go to specified zone (coords optional)", 50, command_zone) || command_add("zonebootup", "[ZoneServerID] [shortname] - Make a zone server boot a specific zone", 150, command_zonebootup) || command_add("zoneinstance", "[instanceid] [x] [y] [z] - Go to specified instance zone (coords optional)", 50, command_zone_instance) || - command_add("zonelock", "[list/lock/unlock] - Set/query lock flag for zoneservers", 100, command_zonelock) || + command_add("zonelock", "[List|Lock|Unlock] [Zone ID|Zone Short Name] - Set or get lock status of a Zone by ID or Short Name", 100, command_zonelock) || command_add("zoneshutdown", "[shortname] - Shut down a zone server", 150, command_zoneshutdown) || command_add("zonespawn", "- Not implemented", 250, command_zonespawn) || command_add("zonestatus", "- Show connected zoneservers, synonymous with /servers", 150, command_zonestatus) || @@ -5757,40 +5757,56 @@ void command_equipitem(Client *c, const Seperator *sep) void command_zonelock(Client *c, const Seperator *sep) { + int arguments = sep->argnum; + if (!arguments) { + c->Message(Chat::White, "Usage: #zonelock list - Lists Locked Zones"); + if (c->Admin() >= commandLockZones) { + c->Message(Chat::White, "Usage: #zonelock lock [Zone ID] or #zonelock lock [Zone Short Name] - Locks a Zone by ID or Short Name"); + c->Message(Chat::White, "Usage: #zonelock unlock [Zone ID] or #zonelock unlock [Zone Short Name] - Unlocks a Zone by ID or Short Name"); + } + return; + } + + std::string lock_type = str_tolower(sep->arg[1]); + bool is_list = lock_type.find("list") != std::string::npos; + bool is_lock = lock_type.find("lock") != std::string::npos; + bool is_unlock = lock_type.find("unlock") != std::string::npos; + if (!is_list && !is_lock && !is_unlock) { + c->Message(Chat::White, "Usage: #zonelock list - Lists Locked Zones"); + if (c->Admin() >= commandLockZones) { + c->Message(Chat::White, "Usage: #zonelock lock [Zone ID] or #zonelock lock [Zone Short Name] - Locks a Zone by ID or Short Name"); + c->Message(Chat::White, "Usage: #zonelock unlock [Zone ID] or #zonelock unlock [Zone Short Name] - Unlocks a Zone by ID or Short Name"); + } + return; + } + auto pack = new ServerPacket(ServerOP_LockZone, sizeof(ServerLockZone_Struct)); - ServerLockZone_Struct* s = (ServerLockZone_Struct*) pack->pBuffer; - strn0cpy(s->adminname, c->GetName(), sizeof(s->adminname)); - if (strcasecmp(sep->arg[1], "list") == 0) { - s->op = 0; + ServerLockZone_Struct* lock_zone = (ServerLockZone_Struct*) pack->pBuffer; + strn0cpy(lock_zone->adminname, c->GetName(), sizeof(lock_zone->adminname)); + + if (is_list) { + lock_zone->op = EQ::constants::ServerLockType::List; worldserver.SendPacket(pack); - } - else if (strcasecmp(sep->arg[1], "lock") == 0 && c->Admin() >= commandLockZones) { - uint16 tmp = ZoneID(sep->arg[2]); - if (tmp) { - s->op = 1; - s->zoneID = tmp; + } else if (!is_list && c->Admin() >= commandLockZones) { + auto zone_id = ( + sep->IsNumber(2) ? + static_cast(std::stoul(sep->arg[2])) : + static_cast(ZoneID(sep->arg[2])) + ); + std::string zone_short_name = str_tolower(ZoneName(zone_id, true)); + bool is_unknown_zone = zone_short_name.find("unknown") != std::string::npos; + if (zone_id && !is_unknown_zone) { + lock_zone->op = is_lock ? EQ::constants::ServerLockType::Lock : EQ::constants::ServerLockType::Unlock; + lock_zone->zoneID = zone_id; worldserver.SendPacket(pack); - } - else - c->Message(Chat::White, "Usage: #zonelock lock [zonename]"); - } - else if (strcasecmp(sep->arg[1], "unlock") == 0 && c->Admin() >= commandLockZones) { - uint16 tmp = ZoneID(sep->arg[2]); - if (tmp) { - s->op = 2; - s->zoneID = tmp; - worldserver.SendPacket(pack); - } - else - c->Message(Chat::White, "Usage: #zonelock unlock [zonename]"); - } - else { - c->Message(Chat::White, "#zonelock sub-commands"); - c->Message(Chat::White, " list"); - if(c->Admin() >= commandLockZones) - { - c->Message(Chat::White, " lock [zonename]"); - c->Message(Chat::White, " unlock [zonename]"); + } else { + c->Message( + Chat::White, + fmt::format( + "Usage: #zonelock {} [Zone ID] or #zonelock {} [Zone Short Name]", + is_lock ? "lock" : "unlock" + ).c_str() + ); } } safe_delete(pack);