From 8c707f9fe5d7398bffd97ab75f2664d1dce75342 Mon Sep 17 00:00:00 2001 From: Alex King <89047260+Kinglykrab@users.noreply.github.com> Date: Sat, 10 Dec 2022 19:07:33 -0500 Subject: [PATCH] [Commands] Add #suspendmulti Command. (#2619) * [Commands] Add #suspendmulti Command. # Notes - Allows operators to suspend multiple people at once in case they have a player who is boxing and want to suspend them all at once. * To lower. * Update command.cpp * Update suspendmulti.cpp * Create suspendmulti.cpp --- common/servertalk.h | 2 +- zone/command.cpp | 2 + zone/command.h | 1 + zone/gm_commands/suspendmulti.cpp | 93 +++++++++++++++++++++++++++++++ zone/worldserver.cpp | 8 ++- 5 files changed, 104 insertions(+), 2 deletions(-) create mode 100755 zone/gm_commands/suspendmulti.cpp diff --git a/common/servertalk.h b/common/servertalk.h index e76d42bf0..904477e21 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -605,7 +605,7 @@ struct ServerKickPlayer_Struct { char adminname[64]; int16 adminrank; char name[64]; - uint32 AccountID; + uint32 account_id; }; struct ServerLSInfo_Struct { diff --git a/zone/command.cpp b/zone/command.cpp index fcdb48564..563090242 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -317,6 +317,7 @@ int command_init(void) command_add("summonburiedplayercorpse", "Summons the target's oldest buried corpse, if any exist.", AccountStatus::GMAdmin, command_summonburiedplayercorpse) || command_add("summonitem", "[itemid] [charges] - Summon an item onto your cursor. Charges are optional.", AccountStatus::GMMgmt, command_summonitem) || command_add("suspend", "[name] [days] [reason] - Suspend by character name and for specificed number of days", AccountStatus::GMLeadAdmin, command_suspend) || + command_add("suspendmulti", "[Character Name One|Character Name Two|etc] [Days] [Reason] - Suspend multiple characters by name for specified number of days", AccountStatus::GMLeadAdmin, command_suspendmulti) || command_add("task", "(subcommand) - Task system commands", AccountStatus::GMLeadAdmin, command_task) || command_add("tempname", "[newname] - Temporarily renames your target. Leave name blank to restore the original name.", AccountStatus::GMAdmin, command_tempname) || command_add("petname", "[newname] - Temporarily renames your pet. Leave name blank to restore the original name.", AccountStatus::GMAdmin, command_petname) || @@ -1155,6 +1156,7 @@ void command_bot(Client *c, const Seperator *sep) #include "gm_commands/summonburiedplayercorpse.cpp" #include "gm_commands/summonitem.cpp" #include "gm_commands/suspend.cpp" +#include "gm_commands/suspendmulti.cpp" #include "gm_commands/task.cpp" #include "gm_commands/tempname.cpp" #include "gm_commands/texture.cpp" diff --git a/zone/command.h b/zone/command.h index 743c1f211..224741679 100644 --- a/zone/command.h +++ b/zone/command.h @@ -266,6 +266,7 @@ void command_summon(Client *c, const Seperator *sep); void command_summonburiedplayercorpse(Client *c, const Seperator *sep); void command_summonitem(Client *c, const Seperator *sep); void command_suspend(Client *c, const Seperator *sep); +void command_suspendmulti(Client *c, const Seperator *sep); void command_task(Client *c, const Seperator *sep); void command_tempname(Client *c, const Seperator *sep); void command_petname(Client *c, const Seperator *sep); diff --git a/zone/gm_commands/suspendmulti.cpp b/zone/gm_commands/suspendmulti.cpp new file mode 100755 index 000000000..9f77aaf7c --- /dev/null +++ b/zone/gm_commands/suspendmulti.cpp @@ -0,0 +1,93 @@ +#include "../client.h" +#include "../worldserver.h" +#include "../../common/repositories/account_repository.h" + +extern WorldServer worldserver; + +void command_suspendmulti(Client *c, const Seperator *sep) +{ + auto arguments = sep->argnum; + if (arguments < 2 || !sep->IsNumber(2)) { + c->Message(Chat::White, "Usage: #suspendmulti [Character Name|Character Name Two|etc] [Days] [Reason]"); + c->Message(Chat::White, "Note: Specify 0 days to lift a suspension"); + return; + } + + const auto& n = Strings::Split(sep->arg[1], "|"); + std::vector v; + for (const auto& c : n) { + v.push_back(fmt::format("'{}'", Strings::ToLower(c))); + } + + auto days = std::stoul(sep->arg[2]); + + const std::string reason = sep->arg[3] ? sep->argplus[3] : ""; + + auto l = AccountRepository::GetWhere( + database, + fmt::format( + "LOWER(charname) IN ({})", + Strings::Implode(", ", v) + ) + ); + + if (l.empty()) { + c->Message(Chat::White, "No characters found."); + return; + } + + for (auto a : l) { + a.status = -1; + a.suspendeduntil = std::time(nullptr) + (days * 86400); + a.suspend_reason = reason; + + if (!AccountRepository::UpdateOne(database, a)) { + c->Message( + Chat::White, + fmt::format( + "Failed to suspend Account {} ({}).", + a.name, + a.id + ).c_str() + ); + return; + } + + c->Message( + Chat::White, + fmt::format( + "Account {} ({}) {}.", + a.name, + a.id, + ( + days ? + fmt::format( + "has been temporarily suspended for {} day{}.", + days, + days != 1 ? "s" : "" + ) : + "is no longer suspended" + ) + ).c_str() + ); + + auto *b = entity_list.GetClientByAccID(a.id); + + if (b) { + b->WorldKick(); + return; + } + + auto pack = new ServerPacket(ServerOP_KickPlayer, sizeof(ServerKickPlayer_Struct)); + auto *k = (ServerKickPlayer_Struct *) pack->pBuffer; + + strn0cpy(k->adminname, c->GetName(), sizeof(k->adminname)); + k->account_id = a.id; + k->adminrank = c->Admin(); + + worldserver.SendPacket(pack); + + safe_delete(pack); + } +} + diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index 36bf6ac60..94b0da11f 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -669,7 +669,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) } case ServerOP_KickPlayer: { ServerKickPlayer_Struct* skp = (ServerKickPlayer_Struct*)pack->pBuffer; - Client* client = entity_list.GetClientByName(skp->name); + Client* client; + if (strlen(skp->name)) { + client = entity_list.GetClientByName(skp->name); + } else if (skp->account_id) { + client = entity_list.GetClientByAccID(skp->account_id); + } + if (client) { if (skp->adminrank >= client->Admin()) { client->WorldKick();