[Commands] Nested Command Aliases (#2636)

This commit is contained in:
Chris Miles 2022-12-14 22:26:05 -06:00 committed by GitHub
parent 6ddd5db480
commit dce5f03e74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 137 additions and 90 deletions

View File

@ -200,6 +200,16 @@ bool Strings::IsNumber(const std::string &s)
}
}
bool Strings::IsFloat(const std::string &s)
{
try {
auto r = stof(s);
return true;
}
catch (std::exception &) {
return false;
}
}
std::string Strings::Join(const std::vector<std::string> &ar, const std::string &delim)
{

View File

@ -86,6 +86,7 @@ public:
static bool Contains(std::vector<std::string> container, std::string element);
static bool Contains(const std::string& subject, const std::string& search);
static bool IsNumber(const std::string &s);
static bool IsFloat(const std::string &s);
static const std::string ToLower(std::string s);
static const std::string ToUpper(std::string s);
static const std::string UcFirst(std::string s);

View File

@ -143,6 +143,7 @@ int command_init(void)
command_add("faction", "[Find (criteria | all ) | Review (criteria | all) | Reset (id)] - Resets Player's Faction", AccountStatus::QuestTroupe, command_faction) ||
command_add("factionassociation", "[factionid] [amount] - triggers a faction hits via association", AccountStatus::GMLeadAdmin, command_faction_association) ||
command_add("feature", "Change your or your target's feature's temporarily", AccountStatus::QuestTroupe, command_feature) ||
command_add("size", "Change your targets size (alias of #feature size)", AccountStatus::QuestTroupe, command_feature) ||
command_add("findaa", "[Search Criteria] - Search for an AA", AccountStatus::Guide, command_findaa) ||
command_add("findaliases", "[Search Criteria]- Searches for available command aliases, by alias or command", AccountStatus::Player, command_findaliases) ||
command_add("findclass", "[Search Criteria] - Search for a class", AccountStatus::Guide, command_findclass) ||
@ -261,6 +262,8 @@ int command_init(void)
command_add("randomfeatures", "Temporarily randomizes the Facial Features of your target", AccountStatus::QuestTroupe, command_randomfeatures) ||
command_add("refreshgroup", "Refreshes Group for you or your player target.", AccountStatus::Player, command_refreshgroup) ||
command_add("reload", "Reloads different types of server data globally, use no argument for help menu.", AccountStatus::GMMgmt, command_reload) ||
command_add("rq", "Reloads quests (alias of #reload quests).", AccountStatus::GMMgmt, command_reload) ||
command_add("rl", "Reloads logs (alias of #reload logs).", AccountStatus::GMMgmt, command_reload) ||
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", "[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) ||
@ -517,15 +520,6 @@ int command_add(std::string command_name, std::string description, uint8 admin,
return -1;
}
for (const auto& c : commandlist) {
if (c.second->function != function) {
continue;
}
LogError("command_add() - Command [{}] equates to an alias of [{}] - check command.cpp", command_name, c.first);
return -1;
}
auto c = new CommandRecord;
c->admin = admin;
c->description = description;
@ -617,7 +611,7 @@ void command_help(Client *c, const Seperator *sep)
for (const auto& cur : commandlist) {
if (!search_criteria.empty()) {
if (cur.first.find(search_criteria) == std::string::npos) {
if (!Strings::Contains(cur.first, search_criteria) && !Strings::Contains(cur.second->description, search_criteria)) {
continue;
}
}

View File

@ -2,8 +2,13 @@
void command_feature(Client *c, const Seperator *sep)
{
// nested command aliasing
std::string command = sep->arg[0] ? sep->arg[0] : "";
bool is_size_alias = sep->arg[0] && Strings::Contains(command, "#size");
bool is_nested_alias = (is_size_alias);
int arguments = sep->argnum;
if (arguments < 2 || !sep->IsNumber(2)) {
if ((arguments < 2 || !sep->IsNumber(2)) && !is_nested_alias) {
auto feature_save_link = Saylink::Silent("#npcedit featuresave");
c->Message(Chat::White, "Usage: #feature beard [Beard] - Change your or your target's Beard");
@ -43,7 +48,7 @@ void command_feature(Client *c, const Seperator *sep)
bool is_helm = !strcasecmp(sep->arg[1], "helm");
bool is_heritage = !strcasecmp(sep->arg[1], "heritage");
bool is_race = !strcasecmp(sep->arg[1], "race");
bool is_size = !strcasecmp(sep->arg[1], "size");
bool is_size = !strcasecmp(sep->arg[1], "size") || is_size_alias;
bool is_tattoo = !strcasecmp(sep->arg[1], "tattoo");
bool is_texture = !strcasecmp(sep->arg[1], "texture");
@ -165,7 +170,16 @@ void command_feature(Client *c, const Seperator *sep)
feature_changed = "Race";
value_changed = race;
} else if (is_size) {
size = std::stof(sep->arg[2]);
// handle aliased input
if (is_size_alias) {
c->Message(Chat::White, "Usage: #feature size [Size] - Change your or your target's Size temporarily (Valid values are 0 to 255, decimal increments are allowed.)");
if (sep->arg[1] && Strings::IsFloat(sep->arg[1])) {
size = std::stof(sep->arg[1]);
}
}
else {
size = std::stof(sep->arg[2]);
}
if (size < 0 || size > 255) {
c->Message(Chat::White, "Usage: #feature size [Size] - Change your or your target's Size temporarily (Valid values are 0 to 255, decimal increments are allowed.)");

View File

@ -2,37 +2,40 @@
void command_reload(Client *c, const Seperator *sep)
{
int arguments = sep->argnum;
if (!arguments) {
std::string command = sep->arg[0] ? sep->arg[0] : "";
int arguments = sep->argnum;
if (!arguments && Strings::Contains(command, "#reload")) {
c->SendReloadCommandMessages();
return;
}
bool is_aa = !strcasecmp(sep->arg[1], "aa");
bool is_rq_alias = sep->arg[0] && Strings::Contains(command, "#rq");
bool is_logs_reload_alias = sep->arg[0] && Strings::Contains(command, "#rl");
bool is_aa = !strcasecmp(sep->arg[1], "aa");
bool is_alternate_currencies = !strcasecmp(sep->arg[1], "alternate_currencies");
bool is_blocked_spells = !strcasecmp(sep->arg[1], "blocked_spells");
bool is_commands = !strcasecmp(sep->arg[1], "commands");
bool is_content_flags = !strcasecmp(sep->arg[1], "content_flags");
bool is_doors = !strcasecmp(sep->arg[1], "doors");
bool is_dztemplates = !strcasecmp(sep->arg[1], "dztemplates");
bool is_ground_spawns = !strcasecmp(sep->arg[1], "ground_spawns");
bool is_level_mods = !strcasecmp(sep->arg[1], "level_mods");
bool is_logs = !strcasecmp(sep->arg[1], "logs");
bool is_merchants = !strcasecmp(sep->arg[1], "merchants");
bool is_npc_emotes = !strcasecmp(sep->arg[1], "npc_emotes");
bool is_objects = !strcasecmp(sep->arg[1], "objects");
bool is_perl_export = !strcasecmp(sep->arg[1], "perl_export");
bool is_quest = !strcasecmp(sep->arg[1], "quest");
bool is_rules = !strcasecmp(sep->arg[1], "rules");
bool is_static = !strcasecmp(sep->arg[1], "static");
bool is_tasks = !strcasecmp(sep->arg[1], "tasks");
bool is_titles = !strcasecmp(sep->arg[1], "titles");
bool is_traps = !strcasecmp(sep->arg[1], "traps");
bool is_variables = !strcasecmp(sep->arg[1], "variables");
bool is_veteran_rewards = !strcasecmp(sep->arg[1], "veteran_rewards");
bool is_world = !strcasecmp(sep->arg[1], "world");
bool is_zone = !strcasecmp(sep->arg[1], "zone");
bool is_zone_points = !strcasecmp(sep->arg[1], "zone_points");
bool is_blocked_spells = !strcasecmp(sep->arg[1], "blocked_spells");
bool is_commands = !strcasecmp(sep->arg[1], "commands");
bool is_content_flags = !strcasecmp(sep->arg[1], "content_flags");
bool is_doors = !strcasecmp(sep->arg[1], "doors");
bool is_dztemplates = !strcasecmp(sep->arg[1], "dztemplates");
bool is_ground_spawns = !strcasecmp(sep->arg[1], "ground_spawns");
bool is_level_mods = !strcasecmp(sep->arg[1], "level_mods");
bool is_logs = !strcasecmp(sep->arg[1], "logs") || is_logs_reload_alias;
bool is_merchants = !strcasecmp(sep->arg[1], "merchants");
bool is_npc_emotes = !strcasecmp(sep->arg[1], "npc_emotes");
bool is_objects = !strcasecmp(sep->arg[1], "objects");
bool is_perl_export = !strcasecmp(sep->arg[1], "perl_export");
bool is_quest = !strcasecmp(sep->arg[1], "quest") || (is_rq_alias);
bool is_rules = !strcasecmp(sep->arg[1], "rules");
bool is_static = !strcasecmp(sep->arg[1], "static");
bool is_tasks = !strcasecmp(sep->arg[1], "tasks");
bool is_titles = !strcasecmp(sep->arg[1], "titles");
bool is_traps = !strcasecmp(sep->arg[1], "traps");
bool is_variables = !strcasecmp(sep->arg[1], "variables");
bool is_veteran_rewards = !strcasecmp(sep->arg[1], "veteran_rewards");
bool is_world = !strcasecmp(sep->arg[1], "world");
bool is_zone = !strcasecmp(sep->arg[1], "zone");
bool is_zone_points = !strcasecmp(sep->arg[1], "zone_points");
if (
!is_aa &&
@ -60,38 +63,46 @@ void command_reload(Client *c, const Seperator *sep)
!is_world &&
!is_zone &&
!is_zone_points
) {
) {
c->SendReloadCommandMessages();
return;
}
ServerPacket* pack = nullptr;
ServerPacket *pack = nullptr;
if (is_aa) {
c->Message(Chat::White, "Attempting to reload Alternate Advancement Data globally.");
pack = new ServerPacket(ServerOP_ReloadAAData, 0);
} else if (is_alternate_currencies) {
}
else if (is_alternate_currencies) {
c->Message(Chat::White, "Attempting to reload Alternate Currencies globally.");
pack = new ServerPacket(ServerOP_ReloadAlternateCurrencies, 0);
} else if (is_blocked_spells) {
}
else if (is_blocked_spells) {
c->Message(Chat::White, "Attempting to reload Blocked Spells globally.");
pack = new ServerPacket(ServerOP_ReloadBlockedSpells, 0);
} else if (is_commands) {
}
else if (is_commands) {
c->Message(Chat::White, "Attempting to reload Commands globally.");
pack = new ServerPacket(ServerOP_ReloadCommands, 0);
} else if (is_content_flags) {
}
else if (is_content_flags) {
c->Message(Chat::White, "Attempting to reload Content Flags globally.");
pack = new ServerPacket(ServerOP_ReloadContentFlags, 0);
} else if (is_doors) {
}
else if (is_doors) {
c->Message(Chat::White, "Attempting to reload Doors globally.");
pack = new ServerPacket(ServerOP_ReloadDoors, 0);
} else if (is_dztemplates) {
}
else if (is_dztemplates) {
c->Message(Chat::White, "Attempting to reload Dynamic Zone Templates globally.");
pack = new ServerPacket(ServerOP_ReloadDzTemplates, 0);
} else if (is_ground_spawns) {
}
else if (is_ground_spawns) {
c->Message(Chat::White, "Attempting to reload Ground Spawns globally.");
pack = new ServerPacket(ServerOP_ReloadGroundSpawns, 0);
} else if (is_level_mods) {
}
else if (is_level_mods) {
if (!RuleB(Zone, LevelBasedEXPMods)) {
c->Message(Chat::White, "Level Based Experience Modifiers are disabled.");
return;
@ -99,22 +110,28 @@ void command_reload(Client *c, const Seperator *sep)
c->Message(Chat::White, "Attempting to reload Level Based Experience Modifiers globally.");
pack = new ServerPacket(ServerOP_ReloadLevelEXPMods, 0);
} else if (is_logs) {
}
else if (is_logs) {
c->Message(Chat::White, "Attempting to reload Log Settings globally.");
pack = new ServerPacket(ServerOP_ReloadLogs, 0);
} else if (is_merchants) {
}
else if (is_merchants) {
c->Message(Chat::White, "Attempting to reload Merchants globally.");
pack = new ServerPacket(ServerOP_ReloadMerchants, 0);
} else if (is_npc_emotes) {
}
else if (is_npc_emotes) {
c->Message(Chat::White, "Attempting to reload NPC Emotes globally.");
pack = new ServerPacket(ServerOP_ReloadNPCEmotes, 0);
} else if (is_objects) {
}
else if (is_objects) {
c->Message(Chat::White, "Attempting to reload Objects globally.");
pack = new ServerPacket(ServerOP_ReloadObjects, 0);
} else if (is_perl_export) {
}
else if (is_perl_export) {
c->Message(Chat::White, "Attempting to reload Perl Event Export Settings globally.");
pack = new ServerPacket(ServerOP_ReloadPerlExportSettings, 0);
} else if (is_quest) {
}
else if (is_quest) {
bool stop_timers = false;
if (sep->IsNumber(2)) {
@ -134,28 +151,34 @@ void command_reload(Client *c, const Seperator *sep)
entity_list.ClearAreas();
parse->ReloadQuests(stop_timers);
} else if (is_rules) {
}
else if (is_rules) {
c->Message(Chat::White, "Attempting to reload Rules globally.");
pack = new ServerPacket(ServerOP_ReloadRules, 0);
} else if (is_static) {
}
else if (is_static) {
c->Message(Chat::White, "Attempting to reload Static Zone Data globally.");
pack = new ServerPacket(ServerOP_ReloadStaticZoneData, 0);
} else if (is_tasks) {
}
else if (is_tasks) {
uint32 task_id = 0;
if (!sep->IsNumber(2)) {
c->Message(Chat::White, "Attempting to reload Tasks globally.");
pack = new ServerPacket(ServerOP_ReloadTasks, sizeof(ReloadTasks_Struct));
} else {
}
else {
task_id = std::stoul(sep->arg[2]);
}
auto rts = (ReloadTasks_Struct*) pack->pBuffer;
auto rts = (ReloadTasks_Struct *) pack->pBuffer;
rts->reload_type = RELOADTASKS;
rts->task_id = task_id;
} else if (is_titles) {
rts->task_id = task_id;
}
else if (is_titles) {
c->Message(Chat::White, "Attempting to reload Titles globally.");
pack = new ServerPacket(ServerOP_ReloadTitles, 0);
} else if (is_traps) {
}
else if (is_traps) {
if (arguments < 2 || !sep->IsNumber(2)) {
entity_list.UpdateAllTraps(true, true);
c->Message(
@ -184,13 +207,16 @@ void command_reload(Client *c, const Seperator *sep)
c->Message(Chat::White, "Attempting to reload Traps globally.");
pack = new ServerPacket(ServerOP_ReloadTraps, 0);
} else if (is_variables) {
}
else if (is_variables) {
c->Message(Chat::White, "Attempting to reload Variables globally.");
pack = new ServerPacket(ServerOP_ReloadVariables, 0);
} else if (is_veteran_rewards) {
}
else if (is_veteran_rewards) {
c->Message(Chat::White, "Attempting to reload Veteran Rewards globally.");
pack = new ServerPacket(ServerOP_ReloadVeteranRewards, 0);
} else if (is_world) {
}
else if (is_world) {
uint8 global_repop = ReloadWorld::NoRepop;
if (sep->IsNumber(2)) {
@ -207,20 +233,21 @@ void command_reload(Client *c, const Seperator *sep)
"Attempting to reload Quests {}worldwide.",
(
global_repop ?
(
global_repop == ReloadWorld::Repop ?
"and repop NPCs " :
"and forcefully repop NPCs "
) :
""
(
global_repop == ReloadWorld::Repop ?
"and repop NPCs " :
"and forcefully repop NPCs "
) :
""
)
).c_str()
);
pack = new ServerPacket(ServerOP_ReloadWorld, sizeof(ReloadWorld_Struct));
auto RW = (ReloadWorld_Struct *) pack->pBuffer;
auto RW = (ReloadWorld_Struct *) pack->pBuffer;
RW->global_repop = global_repop;
} else if (is_zone) {
}
else if (is_zone) {
zone_store.LoadZones(content_db);
if (arguments < 2) {
@ -230,8 +257,8 @@ void command_reload(Client *c, const Seperator *sep)
"Zone Header Load {} | Zone: {}",
(
zone->LoadZoneCFG(zone->GetShortName(), zone->GetInstanceVersion()) ?
"Succeeded" :
"Failed"
"Succeeded" :
"Failed"
),
zone->GetZoneDescription()
).c_str()
@ -241,8 +268,8 @@ void command_reload(Client *c, const Seperator *sep)
auto zone_id = (
sep->IsNumber(2) ?
std::stoul(sep->arg[2]) :
ZoneID(sep->arg[2])
std::stoul(sep->arg[2]) :
ZoneID(sep->arg[2])
);
if (!zone_id) {
c->Message(
@ -256,11 +283,11 @@ void command_reload(Client *c, const Seperator *sep)
}
auto zone_short_name = ZoneName(zone_id);
auto zone_long_name = ZoneLongName(zone_id);
auto version = (
auto zone_long_name = ZoneLongName(zone_id);
auto version = (
sep->IsNumber(3) ?
std::stoul(sep->arg[3]) :
0
std::stoul(sep->arg[3]) :
0
);
auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct));
@ -274,22 +301,23 @@ void command_reload(Client *c, const Seperator *sep)
"Zone Header Load {} | Zone: {} ({}){}",
(
zone->LoadZoneCFG(zone_short_name, version) ?
"Succeeded" :
"Failed"
"Succeeded" :
"Failed"
),
zone_long_name,
zone_short_name,
(
version ?
fmt::format(
" Version: {}",
version
) :
""
fmt::format(
" Version: {}",
version
) :
""
)
).c_str()
);
} else if (is_zone_points) {
}
else if (is_zone_points) {
c->Message(Chat::White, "Attempting to reloading Zone Points globally.");
pack = new ServerPacket(ServerOP_ReloadZonePoints, 0);
}