From f25e37d0c5ad12d10d41d5c2b16c8b996e142d39 Mon Sep 17 00:00:00 2001 From: Alex King <89047260+Kinglykrab@users.noreply.github.com> Date: Sat, 15 Jul 2023 01:37:51 -0400 Subject: [PATCH] [Commands] Consolidate #set-like commands into a singular #set command (#3486) * First push * Final push. * Consolidate zone commands in to one. * Update command.cpp * Remove debug messages. * Test * Add support for sub command status levels. * Update command.cpp * Update client.cpp * Update database_update_manifest.cpp * Update version.h * Update item.cpp * Update version.h * Update database_update_manifest.cpp * Fix command arguments. * Help message. * Update command.cpp * Do DB injection/deletion * Indent * Update server_locked.cpp * Update set.cpp * Lock aliases * Update command_subsettings_repository.h * Update set.cpp * Fix --------- Co-authored-by: Akkadius --- common/database/database_update_manifest.cpp | 17 + common/features.h | 44 +- .../base_command_subsettings_repository.h | 364 ++++++++++++++ .../command_subsettings_repository.h | 221 +++++++++ common/shareddb.cpp | 69 ++- common/shareddb.h | 2 + common/strings.cpp | 14 + common/strings.h | 1 + common/version.h | 2 +- zone/client.cpp | 44 ++ zone/client.h | 1 + zone/command.cpp | 412 +++------------- zone/command.h | 68 +-- zone/gm_commands/bind.cpp | 44 -- zone/gm_commands/date.cpp | 67 --- zone/gm_commands/endurance.cpp | 28 -- zone/gm_commands/faction.cpp | 0 zone/gm_commands/find.cpp | 13 +- zone/gm_commands/find/currency.cpp | 2 +- zone/gm_commands/find/item.cpp | 11 +- zone/gm_commands/find/npctype.cpp | 2 +- zone/gm_commands/find/recipe.cpp | 2 +- zone/gm_commands/find/spell.cpp | 2 +- zone/gm_commands/find/task.cpp | 2 +- zone/gm_commands/find/zone.cpp | 6 +- zone/gm_commands/flag.cpp | 87 ---- zone/gm_commands/flymode.cpp | 38 -- zone/gm_commands/freeze.cpp | 26 - zone/gm_commands/gassign.cpp | 23 - zone/gm_commands/gender.cpp | 38 -- zone/gm_commands/gm.cpp | 28 -- zone/gm_commands/gmspeed.cpp | 39 -- zone/gm_commands/godmode.cpp | 33 -- zone/gm_commands/heal.cpp | 21 - zone/gm_commands/heromodel.cpp | 44 -- zone/gm_commands/incstat.cpp | 18 - zone/gm_commands/invul.cpp | 28 -- zone/gm_commands/lastname.cpp | 40 -- zone/gm_commands/level.cpp | 47 -- zone/gm_commands/mana.cpp | 25 - zone/gm_commands/name.cpp | 42 -- zone/gm_commands/permaclass.cpp | 40 -- zone/gm_commands/permagender.cpp | 44 -- zone/gm_commands/permarace.cpp | 44 -- zone/gm_commands/pvp.cpp | 29 -- zone/gm_commands/qglobal.cpp | 116 ----- zone/gm_commands/race.cpp | 29 -- zone/gm_commands/serverlock.cpp | 22 - zone/gm_commands/set.cpp | 174 +++++++ zone/gm_commands/set/aa_exp.cpp | 69 +++ zone/gm_commands/set/aa_points.cpp | 66 +++ zone/gm_commands/set/adventure_points.cpp | 66 +++ zone/gm_commands/set/alternate_currency.cpp | 43 ++ zone/gm_commands/set/animation.cpp | 63 +++ .../gm_commands/{setanon.cpp => set/anon.cpp} | 35 +- zone/gm_commands/set/bind_point.cpp | 45 ++ .../{updatechecksum.cpp => set/checksum.cpp} | 8 +- zone/gm_commands/set/class_permanent.cpp | 40 ++ zone/gm_commands/set/crystals.cpp | 48 ++ zone/gm_commands/set/date.cpp | 46 ++ zone/gm_commands/set/endurance.cpp | 40 ++ zone/gm_commands/set/endurance_full.cpp | 29 ++ zone/gm_commands/set/exp.cpp | 49 ++ zone/gm_commands/set/flymode.cpp | 69 +++ zone/gm_commands/set/frozen.cpp | 34 ++ zone/gm_commands/set/gender.cpp | 38 ++ zone/gm_commands/set/gender_permanent.cpp | 44 ++ zone/gm_commands/set/gm.cpp | 30 ++ zone/gm_commands/set/gm_speed.cpp | 39 ++ zone/gm_commands/set/gm_status.cpp | 97 ++++ zone/gm_commands/set/god_mode.cpp | 42 ++ zone/gm_commands/{ => set}/haste.cpp | 11 +- zone/gm_commands/set/hero_model.cpp | 44 ++ .../{hideme.cpp => set/hide_me.cpp} | 15 +- zone/gm_commands/set/hp.cpp | 33 ++ zone/gm_commands/set/hp_full.cpp | 20 + zone/gm_commands/set/invulnerable.cpp | 32 ++ zone/gm_commands/set/language.cpp | 54 +++ zone/gm_commands/set/last_name.cpp | 46 ++ zone/gm_commands/set/level.cpp | 34 ++ .../loginserver_info.cpp} | 24 +- zone/gm_commands/set/mana.cpp | 41 ++ zone/gm_commands/set/mana_full.cpp | 28 ++ zone/gm_commands/{ => set}/motd.cpp | 17 +- zone/gm_commands/set/name.cpp | 43 ++ .../{oocmute.cpp => set/ooc_mute.cpp} | 16 +- zone/gm_commands/set/password.cpp | 52 ++ zone/gm_commands/set/pvp.cpp | 30 ++ zone/gm_commands/set/pvp_points.cpp | 33 ++ zone/gm_commands/set/race.cpp | 52 ++ zone/gm_commands/set/race_permanent.cpp | 45 ++ zone/gm_commands/set/server_locked.cpp | 33 ++ .../{setskill.cpp => set/skill.cpp} | 16 +- zone/gm_commands/set/skill_all.cpp | 39 ++ .../skill_all_max.cpp} | 5 +- zone/gm_commands/set/start_zone.cpp | 51 ++ zone/gm_commands/set/temporary_name.cpp | 38 ++ zone/gm_commands/set/texture.cpp | 56 +++ zone/gm_commands/set/time.cpp | 67 +++ zone/gm_commands/set/time_zone.cpp | 58 +++ zone/gm_commands/set/title.cpp | 55 +++ .../{titlesuffix.cpp => set/title_suffix.cpp} | 28 +- zone/gm_commands/{ => set}/weather.cpp | 46 +- zone/gm_commands/set/zone.cpp | 455 ++++++++++++++++++ zone/gm_commands/set_adventure_points.cpp | 76 --- zone/gm_commands/setaapts.cpp | 63 --- zone/gm_commands/setaaxp.cpp | 67 --- zone/gm_commands/setaltcurrency.cpp | 51 -- zone/gm_commands/setanim.cpp | 72 --- zone/gm_commands/setcrystals.cpp | 52 -- zone/gm_commands/setendurance.cpp | 54 --- zone/gm_commands/setfaction.cpp | 51 -- zone/gm_commands/sethp.cpp | 47 -- zone/gm_commands/setlanguage.cpp | 57 --- zone/gm_commands/setmana.cpp | 55 --- zone/gm_commands/setpass.cpp | 51 -- zone/gm_commands/setpvppoints.cpp | 32 -- zone/gm_commands/setskillall.cpp | 43 -- zone/gm_commands/setstartzone.cpp | 52 -- zone/gm_commands/setstat.cpp | 14 - zone/gm_commands/setxp.cpp | 23 - zone/gm_commands/show.cpp | 13 +- zone/gm_commands/show/recipe.cpp | 4 +- zone/gm_commands/tempname.cpp | 22 - zone/gm_commands/texture.cpp | 57 --- zone/gm_commands/time.cpp | 128 ----- zone/gm_commands/timezone.cpp | 77 --- zone/gm_commands/title.cpp | 56 --- zone/gm_commands/unfreeze.cpp | 21 - zone/gm_commands/zclip.cpp | 110 ----- zone/gm_commands/zcolor.cpp | 67 --- zone/gm_commands/zheader.cpp | 63 --- zone/gm_commands/zonelock.cpp | 76 --- zone/gm_commands/zsafecoords.cpp | 57 --- zone/gm_commands/zsky.cpp | 43 -- zone/gm_commands/zunderworld.cpp | 38 -- 136 files changed, 3582 insertions(+), 3280 deletions(-) create mode 100644 common/repositories/base/base_command_subsettings_repository.h create mode 100644 common/repositories/command_subsettings_repository.h delete mode 100755 zone/gm_commands/bind.cpp delete mode 100755 zone/gm_commands/date.cpp delete mode 100755 zone/gm_commands/endurance.cpp mode change 100755 => 100644 zone/gm_commands/faction.cpp delete mode 100755 zone/gm_commands/flag.cpp delete mode 100755 zone/gm_commands/flymode.cpp delete mode 100755 zone/gm_commands/freeze.cpp delete mode 100755 zone/gm_commands/gassign.cpp delete mode 100755 zone/gm_commands/gender.cpp delete mode 100755 zone/gm_commands/gm.cpp delete mode 100755 zone/gm_commands/gmspeed.cpp delete mode 100644 zone/gm_commands/godmode.cpp delete mode 100755 zone/gm_commands/heal.cpp delete mode 100755 zone/gm_commands/heromodel.cpp delete mode 100755 zone/gm_commands/incstat.cpp delete mode 100755 zone/gm_commands/invul.cpp delete mode 100755 zone/gm_commands/lastname.cpp delete mode 100644 zone/gm_commands/level.cpp delete mode 100755 zone/gm_commands/mana.cpp delete mode 100755 zone/gm_commands/name.cpp delete mode 100755 zone/gm_commands/permaclass.cpp delete mode 100755 zone/gm_commands/permagender.cpp delete mode 100755 zone/gm_commands/permarace.cpp delete mode 100755 zone/gm_commands/pvp.cpp delete mode 100755 zone/gm_commands/qglobal.cpp delete mode 100755 zone/gm_commands/race.cpp delete mode 100644 zone/gm_commands/serverlock.cpp create mode 100644 zone/gm_commands/set.cpp create mode 100755 zone/gm_commands/set/aa_exp.cpp create mode 100755 zone/gm_commands/set/aa_points.cpp create mode 100755 zone/gm_commands/set/adventure_points.cpp create mode 100644 zone/gm_commands/set/alternate_currency.cpp create mode 100755 zone/gm_commands/set/animation.cpp rename zone/gm_commands/{setanon.cpp => set/anon.cpp} (70%) create mode 100755 zone/gm_commands/set/bind_point.cpp rename zone/gm_commands/{updatechecksum.cpp => set/checksum.cpp} (81%) create mode 100755 zone/gm_commands/set/class_permanent.cpp create mode 100755 zone/gm_commands/set/crystals.cpp create mode 100755 zone/gm_commands/set/date.cpp create mode 100644 zone/gm_commands/set/endurance.cpp create mode 100755 zone/gm_commands/set/endurance_full.cpp create mode 100755 zone/gm_commands/set/exp.cpp create mode 100755 zone/gm_commands/set/flymode.cpp create mode 100755 zone/gm_commands/set/frozen.cpp create mode 100755 zone/gm_commands/set/gender.cpp create mode 100755 zone/gm_commands/set/gender_permanent.cpp create mode 100755 zone/gm_commands/set/gm.cpp create mode 100755 zone/gm_commands/set/gm_speed.cpp create mode 100644 zone/gm_commands/set/gm_status.cpp create mode 100644 zone/gm_commands/set/god_mode.cpp rename zone/gm_commands/{ => set}/haste.cpp (59%) mode change 100755 => 100644 create mode 100755 zone/gm_commands/set/hero_model.cpp rename zone/gm_commands/{hideme.cpp => set/hide_me.cpp} (50%) create mode 100644 zone/gm_commands/set/hp.cpp create mode 100755 zone/gm_commands/set/hp_full.cpp create mode 100755 zone/gm_commands/set/invulnerable.cpp create mode 100755 zone/gm_commands/set/language.cpp create mode 100755 zone/gm_commands/set/last_name.cpp create mode 100644 zone/gm_commands/set/level.cpp rename zone/gm_commands/{setlsinfo.cpp => set/loginserver_info.cpp} (50%) create mode 100644 zone/gm_commands/set/mana.cpp create mode 100755 zone/gm_commands/set/mana_full.cpp rename zone/gm_commands/{ => set}/motd.cpp (52%) create mode 100755 zone/gm_commands/set/name.cpp rename zone/gm_commands/{oocmute.cpp => set/ooc_mute.cpp} (55%) create mode 100755 zone/gm_commands/set/password.cpp create mode 100755 zone/gm_commands/set/pvp.cpp create mode 100755 zone/gm_commands/set/pvp_points.cpp create mode 100755 zone/gm_commands/set/race.cpp create mode 100755 zone/gm_commands/set/race_permanent.cpp create mode 100644 zone/gm_commands/set/server_locked.cpp rename zone/gm_commands/{setskill.cpp => set/skill.cpp} (67%) create mode 100755 zone/gm_commands/set/skill_all.cpp rename zone/gm_commands/{max_all_skills.cpp => set/skill_all_max.cpp} (74%) create mode 100755 zone/gm_commands/set/start_zone.cpp create mode 100755 zone/gm_commands/set/temporary_name.cpp create mode 100755 zone/gm_commands/set/texture.cpp create mode 100755 zone/gm_commands/set/time.cpp create mode 100755 zone/gm_commands/set/time_zone.cpp create mode 100755 zone/gm_commands/set/title.cpp rename zone/gm_commands/{titlesuffix.cpp => set/title_suffix.cpp} (55%) rename zone/gm_commands/{ => set}/weather.cpp (69%) create mode 100755 zone/gm_commands/set/zone.cpp delete mode 100755 zone/gm_commands/set_adventure_points.cpp delete mode 100755 zone/gm_commands/setaapts.cpp delete mode 100755 zone/gm_commands/setaaxp.cpp delete mode 100644 zone/gm_commands/setaltcurrency.cpp delete mode 100755 zone/gm_commands/setanim.cpp delete mode 100755 zone/gm_commands/setcrystals.cpp delete mode 100644 zone/gm_commands/setendurance.cpp delete mode 100755 zone/gm_commands/setfaction.cpp delete mode 100644 zone/gm_commands/sethp.cpp delete mode 100755 zone/gm_commands/setlanguage.cpp delete mode 100644 zone/gm_commands/setmana.cpp delete mode 100755 zone/gm_commands/setpass.cpp delete mode 100755 zone/gm_commands/setpvppoints.cpp delete mode 100755 zone/gm_commands/setskillall.cpp delete mode 100755 zone/gm_commands/setstartzone.cpp delete mode 100755 zone/gm_commands/setstat.cpp delete mode 100755 zone/gm_commands/setxp.cpp delete mode 100755 zone/gm_commands/tempname.cpp delete mode 100755 zone/gm_commands/texture.cpp delete mode 100755 zone/gm_commands/time.cpp delete mode 100755 zone/gm_commands/timezone.cpp delete mode 100755 zone/gm_commands/title.cpp delete mode 100755 zone/gm_commands/unfreeze.cpp delete mode 100755 zone/gm_commands/zclip.cpp delete mode 100755 zone/gm_commands/zcolor.cpp delete mode 100755 zone/gm_commands/zheader.cpp delete mode 100755 zone/gm_commands/zonelock.cpp delete mode 100755 zone/gm_commands/zsafecoords.cpp delete mode 100755 zone/gm_commands/zsky.cpp delete mode 100755 zone/gm_commands/zunderworld.cpp diff --git a/common/database/database_update_manifest.cpp b/common/database/database_update_manifest.cpp index aa56e00f5..8d24cfef4 100644 --- a/common/database/database_update_manifest.cpp +++ b/common/database/database_update_manifest.cpp @@ -4789,6 +4789,23 @@ UNIQUE KEY `name` (`name`) MODIFY COLUMN `d_melee_texture2` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `d_melee_texture1`; )", }, + ManifestEntry{ + .version = 9232, + .description = "2023_07_11_command_subsettings.sql", + .check = "SHOW TABLES LIKE 'command_subsettings'", + .condition = "empty", + .match = "", + .sql = R"(CREATE TABLE `command_subsettings` ( +`id` int UNSIGNED NOT NULL AUTO_INCREMENT, +`parent_command` varchar(32) NOT NULL, +`sub_command` varchar(32) NOT NULL, +`access_level` int(11) UNSIGNED NOT NULL DEFAULT 0, +`top_level_aliases` varchar(255) NOT NULL, +PRIMARY KEY (`id`), +UNIQUE INDEX `command`(`parent_command`, `sub_command`) +) +)" + }, // -- template; copy/paste this when you need to create a new entry // ManifestEntry{ diff --git a/common/features.h b/common/features.h index 082f18897..d49e5f015 100644 --- a/common/features.h +++ b/common/features.h @@ -240,36 +240,22 @@ enum { //some random constants //Some hard coded statuses from commands and other places: enum { - minStatusToBeGM = 40, - minStatusToUseGMCommands = 80, - minStatusToKick = 150, - minStatusToAvoidFalling = 100, - minStatusToHaveInvalidSpells = 80, - minStatusToHaveInvalidSkills = 80, - minStatusToIgnoreZoneFlags = 80, + minStatusToBeGM = 40, + minStatusToUseGMCommands = 80, + minStatusToKick = 150, + minStatusToAvoidFalling = 100, + minStatusToIgnoreZoneFlags = 80, minStatusToSeeOthersZoneFlags = 80, - minStatusToEditOtherGuilds = 80, - commandMovecharSelfOnly = 80, //below this == only self move allowed - commandMovecharToSpecials = 200, //ability to send people to cshom/load zones - commandZoneToSpecials = 80, //zone to cshome, out of load zones - commandToggleAI = 250, //can turn NPC AI on and off - commandCastSpecials = 100, //can cast special spells - commandInstacast = 100, //insta-cast all #casted spells - commandLevelAboveCap = 100, //can #level players above level cap - commandLevelNPCAboveCap = 100, //can #level NPCs above level cap - commandSetSkillsOther = 100, //ability to setskills on others - commandRaceOthers = 100, //ability to #race on others - commandGenderOthers = 100, //ability to #gender on others - commandTextureOthers = 100, //ability to #texture on others - commandDoAnimOthers = 100, //can #doanim on others - commandLockZones = 101, //can lock or unlock zones - commandEditPlayerCorpses = 150, //can Edit Player Corpses - commandChangeFlags = 200, //ability to set/refresh flags - commandBanPlayers = 100, //can set bans on players - commandChangeDatarate = 201, //edit client's data rate - commandZoneToCoords = 0, //can #zone with coords - commandInterrogateInv = 100, //below this == only log on error state and self-only target dump - commandInvSnapshot = 150 //ability to clear/restore snapshots + minStatusToEditOtherGuilds = 80, + commandMovecharSelfOnly = 80, //below this == only self move allowed + commandMovecharToSpecials = 200, //ability to send people to cshom/load zones + commandCastSpecials = 100, //can cast special spells + commandInstacast = 100, //insta-cast all #casted spells + commandDoAnimOthers = 100, //can #doanim on others + commandLockZones = 101, //can lock or unlock zones + commandEditPlayerCorpses = 150, //can Edit Player Corpses + commandInterrogateInv = 100, //below this == only log on error state and self-only target dump + commandInvSnapshot = 150 //ability to clear/restore snapshots }; diff --git a/common/repositories/base/base_command_subsettings_repository.h b/common/repositories/base/base_command_subsettings_repository.h new file mode 100644 index 000000000..1731f5470 --- /dev/null +++ b/common/repositories/base/base_command_subsettings_repository.h @@ -0,0 +1,364 @@ +/** + * DO NOT MODIFY THIS FILE + * + * This repository was automatically generated and is NOT to be modified directly. + * Any repository modifications are meant to be made to the repository extending the base. + * Any modifications to base repositories are to be made by the generator only + * + * @generator ./utils/scripts/generators/repository-generator.pl + * @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories + */ + +#ifndef EQEMU_BASE_COMMAND_SUBSETTINGS_REPOSITORY_H +#define EQEMU_BASE_COMMAND_SUBSETTINGS_REPOSITORY_H + +#include "../../database.h" +#include "../../strings.h" +#include + + +class BaseCommandSubsettingsRepository { +public: + struct CommandSubsettings { + uint32_t id; + std::string parent_command; + std::string sub_command; + uint32_t access_level; + std::string top_level_aliases; + }; + + static std::string PrimaryKey() + { + return std::string("id"); + } + + static std::vector Columns() + { + return { + "id", + "parent_command", + "sub_command", + "access_level", + "top_level_aliases", + }; + } + + static std::vector SelectColumns() + { + return { + "id", + "parent_command", + "sub_command", + "access_level", + "top_level_aliases", + }; + } + + static std::string ColumnsRaw() + { + return std::string(Strings::Implode(", ", Columns())); + } + + static std::string SelectColumnsRaw() + { + return std::string(Strings::Implode(", ", SelectColumns())); + } + + static std::string TableName() + { + return std::string("command_subsettings"); + } + + static std::string BaseSelect() + { + return fmt::format( + "SELECT {} FROM {}", + SelectColumnsRaw(), + TableName() + ); + } + + static std::string BaseInsert() + { + return fmt::format( + "INSERT INTO {} ({}) ", + TableName(), + ColumnsRaw() + ); + } + + static CommandSubsettings NewEntity() + { + CommandSubsettings e{}; + + e.id = 0; + e.parent_command = ""; + e.sub_command = ""; + e.access_level = 0; + e.top_level_aliases = ""; + + return e; + } + + static CommandSubsettings GetCommandSubsettings( + const std::vector &command_subsettingss, + int command_subsettings_id + ) + { + for (auto &command_subsettings : command_subsettingss) { + if (command_subsettings.id == command_subsettings_id) { + return command_subsettings; + } + } + + return NewEntity(); + } + + static CommandSubsettings FindOne( + Database& db, + int command_subsettings_id + ) + { + auto results = db.QueryDatabase( + fmt::format( + "{} WHERE {} = {} LIMIT 1", + BaseSelect(), + PrimaryKey(), + command_subsettings_id + ) + ); + + auto row = results.begin(); + if (results.RowCount() == 1) { + CommandSubsettings e{}; + + e.id = static_cast(strtoul(row[0], nullptr, 10)); + e.parent_command = row[1] ? row[1] : ""; + e.sub_command = row[2] ? row[2] : ""; + e.access_level = static_cast(strtoul(row[3], nullptr, 10)); + e.top_level_aliases = row[4] ? row[4] : ""; + + return e; + } + + return NewEntity(); + } + + static int DeleteOne( + Database& db, + int command_subsettings_id + ) + { + auto results = db.QueryDatabase( + fmt::format( + "DELETE FROM {} WHERE {} = {}", + TableName(), + PrimaryKey(), + command_subsettings_id + ) + ); + + return (results.Success() ? results.RowsAffected() : 0); + } + + static int UpdateOne( + Database& db, + const CommandSubsettings &e + ) + { + std::vector v; + + auto columns = Columns(); + + v.push_back(columns[1] + " = '" + Strings::Escape(e.parent_command) + "'"); + v.push_back(columns[2] + " = '" + Strings::Escape(e.sub_command) + "'"); + v.push_back(columns[3] + " = " + std::to_string(e.access_level)); + v.push_back(columns[4] + " = '" + Strings::Escape(e.top_level_aliases) + "'"); + + auto results = db.QueryDatabase( + fmt::format( + "UPDATE {} SET {} WHERE {} = {}", + TableName(), + Strings::Implode(", ", v), + PrimaryKey(), + e.id + ) + ); + + return (results.Success() ? results.RowsAffected() : 0); + } + + static CommandSubsettings InsertOne( + Database& db, + CommandSubsettings e + ) + { + std::vector v; + + v.push_back(std::to_string(e.id)); + v.push_back("'" + Strings::Escape(e.parent_command) + "'"); + v.push_back("'" + Strings::Escape(e.sub_command) + "'"); + v.push_back(std::to_string(e.access_level)); + v.push_back("'" + Strings::Escape(e.top_level_aliases) + "'"); + + auto results = db.QueryDatabase( + fmt::format( + "{} VALUES ({})", + BaseInsert(), + Strings::Implode(",", v) + ) + ); + + if (results.Success()) { + e.id = results.LastInsertedID(); + return e; + } + + e = NewEntity(); + + return e; + } + + static int InsertMany( + Database& db, + const std::vector &entries + ) + { + std::vector insert_chunks; + + for (auto &e: entries) { + std::vector v; + + v.push_back(std::to_string(e.id)); + v.push_back("'" + Strings::Escape(e.parent_command) + "'"); + v.push_back("'" + Strings::Escape(e.sub_command) + "'"); + v.push_back(std::to_string(e.access_level)); + v.push_back("'" + Strings::Escape(e.top_level_aliases) + "'"); + + insert_chunks.push_back("(" + Strings::Implode(",", v) + ")"); + } + + std::vector v; + + auto results = db.QueryDatabase( + fmt::format( + "{} VALUES {}", + BaseInsert(), + Strings::Implode(",", insert_chunks) + ) + ); + + return (results.Success() ? results.RowsAffected() : 0); + } + + static std::vector All(Database& db) + { + std::vector all_entries; + + auto results = db.QueryDatabase( + fmt::format( + "{}", + BaseSelect() + ) + ); + + all_entries.reserve(results.RowCount()); + + for (auto row = results.begin(); row != results.end(); ++row) { + CommandSubsettings e{}; + + e.id = static_cast(strtoul(row[0], nullptr, 10)); + e.parent_command = row[1] ? row[1] : ""; + e.sub_command = row[2] ? row[2] : ""; + e.access_level = static_cast(strtoul(row[3], nullptr, 10)); + e.top_level_aliases = row[4] ? row[4] : ""; + + all_entries.push_back(e); + } + + return all_entries; + } + + static std::vector GetWhere(Database& db, const std::string &where_filter) + { + std::vector all_entries; + + auto results = db.QueryDatabase( + fmt::format( + "{} WHERE {}", + BaseSelect(), + where_filter + ) + ); + + all_entries.reserve(results.RowCount()); + + for (auto row = results.begin(); row != results.end(); ++row) { + CommandSubsettings e{}; + + e.id = static_cast(strtoul(row[0], nullptr, 10)); + e.parent_command = row[1] ? row[1] : ""; + e.sub_command = row[2] ? row[2] : ""; + e.access_level = static_cast(strtoul(row[3], nullptr, 10)); + e.top_level_aliases = row[4] ? row[4] : ""; + + all_entries.push_back(e); + } + + return all_entries; + } + + static int DeleteWhere(Database& db, const std::string &where_filter) + { + auto results = db.QueryDatabase( + fmt::format( + "DELETE FROM {} WHERE {}", + TableName(), + where_filter + ) + ); + + return (results.Success() ? results.RowsAffected() : 0); + } + + static int Truncate(Database& db) + { + auto results = db.QueryDatabase( + fmt::format( + "TRUNCATE TABLE {}", + TableName() + ) + ); + + return (results.Success() ? results.RowsAffected() : 0); + } + + static int64 GetMaxId(Database& db) + { + auto results = db.QueryDatabase( + fmt::format( + "SELECT COALESCE(MAX({}), 0) FROM {}", + PrimaryKey(), + TableName() + ) + ); + + return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0); + } + + static int64 Count(Database& db, const std::string &where_filter = "") + { + auto results = db.QueryDatabase( + fmt::format( + "SELECT COUNT(*) FROM {} {}", + TableName(), + (where_filter.empty() ? "" : "WHERE " + where_filter) + ) + ); + + return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0); + } + +}; + +#endif //EQEMU_BASE_COMMAND_SUBSETTINGS_REPOSITORY_H diff --git a/common/repositories/command_subsettings_repository.h b/common/repositories/command_subsettings_repository.h new file mode 100644 index 000000000..f7e65a2b6 --- /dev/null +++ b/common/repositories/command_subsettings_repository.h @@ -0,0 +1,221 @@ +#ifndef EQEMU_COMMAND_SUBSETTINGS_REPOSITORY_H +#define EQEMU_COMMAND_SUBSETTINGS_REPOSITORY_H + +#include "../database.h" +#include "../strings.h" +#include "base/base_command_subsettings_repository.h" + +class CommandSubsettingsRepository: public BaseCommandSubsettingsRepository { +public: + + /** + * This file was auto generated and can be modified and extended upon + * + * Base repository methods are automatically + * generated in the "base" version of this repository. The base repository + * is immutable and to be left untouched, while methods in this class + * are used as extension methods for more specific persistence-layer + * accessors or mutators. + * + * Base Methods (Subject to be expanded upon in time) + * + * Note: Not all tables are designed appropriately to fit functionality with all base methods + * + * InsertOne + * UpdateOne + * DeleteOne + * FindOne + * GetWhere(std::string where_filter) + * DeleteWhere(std::string where_filter) + * InsertMany + * All + * + * Example custom methods in a repository + * + * CommandSubsettingsRepository::GetByZoneAndVersion(int zone_id, int zone_version) + * CommandSubsettingsRepository::GetWhereNeverExpires() + * CommandSubsettingsRepository::GetWhereXAndY() + * CommandSubsettingsRepository::DeleteWhereXAndY() + * + * Most of the above could be covered by base methods, but if you as a developer + * find yourself re-using logic for other parts of the code, its best to just make a + * method that can be re-used easily elsewhere especially if it can use a base repository + * method and encapsulate filters there + */ + + // Custom extended repository methods here + static std::vector GetAll(Database& db) + { + // these are the base definitions for command_subsettings and can be over-ridden by the database + std::vector static_records = { + {.parent_command = "find", .sub_command = "aa", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findaa"}, + {.parent_command = "find", .sub_command = "character", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findcharacter"}, + {.parent_command = "find", .sub_command = "class", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findclass"}, + {.parent_command = "find", .sub_command = "currency", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findcurrency"}, + {.parent_command = "find", .sub_command = "deity", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "finddeity"}, + {.parent_command = "find", .sub_command = "emote", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findemote"}, + {.parent_command = "find", .sub_command = "faction", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findfaction"}, + {.parent_command = "find", .sub_command = "item", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "fi|finditem|itemsearch"}, + {.parent_command = "find", .sub_command = "language", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findlanguage"}, + {.parent_command = "find", .sub_command = "npc_type", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "fn|findnpc|findnpctype"}, + {.parent_command = "find", .sub_command = "race", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findrace"}, + {.parent_command = "find", .sub_command = "recipe", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findrecipe"}, + {.parent_command = "find", .sub_command = "skill", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findskill"}, + {.parent_command = "find", .sub_command = "spell", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "fs|findspell"}, + {.parent_command = "find", .sub_command = "task", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findtask"}, + {.parent_command = "find", .sub_command = "zone", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "fz|findzone"}, + {.parent_command = "set", .sub_command = "aa_exp", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setaaxp|setaaexp"}, + {.parent_command = "set", .sub_command = "aa_points", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setaapts|setaapoints"}, + {.parent_command = "set", .sub_command = "adventure_points", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setadventurepoints"}, + {.parent_command = "set", .sub_command = "alternate_currency", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setaltcurrency"}, + {.parent_command = "set", .sub_command = "animation", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setanim"}, + {.parent_command = "set", .sub_command = "anon", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setanon"}, + {.parent_command = "set", .sub_command = "bind", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "bind"}, + {.parent_command = "set", .sub_command = "checksum", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "updatechecksum"}, + {.parent_command = "set", .sub_command = "class_permanent", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "permaclass"}, + {.parent_command = "set", .sub_command = "crystals", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setcrystals"}, + {.parent_command = "set", .sub_command = "date", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "date"}, + {.parent_command = "set", .sub_command = "endurance", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setendurance"}, + {.parent_command = "set", .sub_command = "endurance_full", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "endurance"}, + {.parent_command = "set", .sub_command = "exp", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setxp|setexp"}, + {.parent_command = "set", .sub_command = "faction", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setfaction"}, + {.parent_command = "set", .sub_command = "flymode", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "flymode"}, + {.parent_command = "set", .sub_command = "freeze", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "freeze|unfreeze"}, + {.parent_command = "set", .sub_command = "gender", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "gender"}, + {.parent_command = "set", .sub_command = "gender_permanent", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "permagender"}, + {.parent_command = "set", .sub_command = "gm", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "gm"}, + {.parent_command = "set", .sub_command = "gm_speed", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "gmspeed"}, + {.parent_command = "set", .sub_command = "gm_status", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "flag"}, + {.parent_command = "set", .sub_command = "god_mode", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "godmode"}, + {.parent_command = "set", .sub_command = "haste", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "haste"}, + {.parent_command = "set", .sub_command = "hero_model", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "heromodel"}, + {.parent_command = "set", .sub_command = "hide_me", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "hideme"}, + {.parent_command = "set", .sub_command = "hp", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "sethp"}, + {.parent_command = "set", .sub_command = "hp_full", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "heal"}, + {.parent_command = "set", .sub_command = "invulnerable", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "invul|invulnerable"}, + {.parent_command = "set", .sub_command = "language", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setlanguage"}, + {.parent_command = "set", .sub_command = "last_name", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "lastname"}, + {.parent_command = "set", .sub_command = "level", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "level"}, + {.parent_command = "set", .sub_command = "loginserver_info", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setlsinfo"}, + {.parent_command = "set", .sub_command = "mana", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setmana"}, + {.parent_command = "set", .sub_command = "mana_full", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "mana"}, + {.parent_command = "set", .sub_command = "motd", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "motd"}, + {.parent_command = "set", .sub_command = "name", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "name"}, + {.parent_command = "set", .sub_command = "ooc_mute", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "oocmute"}, + {.parent_command = "set", .sub_command = "password", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setpass"}, + {.parent_command = "set", .sub_command = "pvp", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "pvp"}, + {.parent_command = "set", .sub_command = "pvp_points", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setpvppoints"}, + {.parent_command = "set", .sub_command = "race", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "race"}, + {.parent_command = "set", .sub_command = "race_permanent", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "permarace"}, + {.parent_command = "set", .sub_command = "server_locked", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "lock|serverlock|serverunlock|unlock"}, + {.parent_command = "set", .sub_command = "skill", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setskill"}, + {.parent_command = "set", .sub_command = "skill_all", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setallskill|setallskills|setskillall"}, + {.parent_command = "set", .sub_command = "skill_all_max", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "maxskills"}, + {.parent_command = "set", .sub_command = "start_zone", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "setstartzone"}, + {.parent_command = "set", .sub_command = "temporary_name", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "tempname"}, + {.parent_command = "set", .sub_command = "texture", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "texture"}, + {.parent_command = "set", .sub_command = "time", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "time"}, + {.parent_command = "set", .sub_command = "time_zone", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "timezone"}, + {.parent_command = "set", .sub_command = "title", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "title"}, + {.parent_command = "set", .sub_command = "title_suffix", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "titlesuffix"}, + {.parent_command = "set", .sub_command = "weather", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "weather"}, + {.parent_command = "set", .sub_command = "zone", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "zclip|zcolor|zheader|zonelock|zsafecoords|zsky|zunderworld"}, + {.parent_command = "show", .sub_command = "aggro", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "aggro"}, + {.parent_command = "show", .sub_command = "buffs", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showbuffs"}, + {.parent_command = "show", .sub_command = "buried_corpse_count", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "getplayerburiedcorpsecount"}, + {.parent_command = "show", .sub_command = "client_version_summary", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "cvs"}, + {.parent_command = "show", .sub_command = "currencies", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "viewcurrencies"}, + {.parent_command = "show", .sub_command = "distance", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "distance"}, + {.parent_command = "show", .sub_command = "emote", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "emoteview"}, + {.parent_command = "show", .sub_command = "field_of_view", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "fov"}, + {.parent_command = "show", .sub_command = "flags", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "flags"}, + {.parent_command = "show", .sub_command = "group_info", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "ginfo"}, + {.parent_command = "show", .sub_command = "hatelist", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "hatelist"}, + {.parent_command = "show", .sub_command = "inventory", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "peekinv"}, + {.parent_command = "show", .sub_command = "ip_lookup", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "iplookup"}, + {.parent_command = "show", .sub_command = "line_of_sight", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "checklos"}, + {.parent_command = "show", .sub_command = "network", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "network"}, + {.parent_command = "show", .sub_command = "network_stats", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "netstats"}, + {.parent_command = "show", .sub_command = "npc_global_loot", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "shownpcgloballoot"}, + {.parent_command = "show", .sub_command = "npc_stats", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "npcstats"}, + {.parent_command = "show", .sub_command = "npc_type", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "viewnpctype"}, + {.parent_command = "show", .sub_command = "peqzone_flags", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "peqzone_flags"}, + {.parent_command = "show", .sub_command = "petition", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "listpetition|viewpetition"}, + {.parent_command = "show", .sub_command = "petition_info", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "petitioninfo"}, + {.parent_command = "show", .sub_command = "proximity", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "proximity"}, + {.parent_command = "show", .sub_command = "quest_errors", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "questerrors"}, + {.parent_command = "show", .sub_command = "quest_globals", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "globalview"}, + {.parent_command = "show", .sub_command = "recipe", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "viewrecipe"}, + {.parent_command = "show", .sub_command = "server_info", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "serverinfo"}, + {.parent_command = "show", .sub_command = "skills", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showskills"}, + {.parent_command = "show", .sub_command = "spawn_status", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "spawnstatus"}, + {.parent_command = "show", .sub_command = "spells", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showspells"}, + {.parent_command = "show", .sub_command = "spells_list", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showspellslist"}, + {.parent_command = "show", .sub_command = "stats", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showstats"}, + {.parent_command = "show", .sub_command = "timers", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "timers"}, + {.parent_command = "show", .sub_command = "traps", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "trapinfo"}, + {.parent_command = "show", .sub_command = "uptime", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "uptime"}, + {.parent_command = "show", .sub_command = "variable", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "getvariable"}, + {.parent_command = "show", .sub_command = "version", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "version"}, + {.parent_command = "show", .sub_command = "waypoints", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "wpinfo"}, + {.parent_command = "show", .sub_command = "who", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "who"}, + {.parent_command = "show", .sub_command = "xtargets", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "xtargets"}, + {.parent_command = "show", .sub_command = "zone_global_loot", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showzonegloballoot"}, + {.parent_command = "show", .sub_command = "zone_loot", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "viewzoneloot"}, + {.parent_command = "show", .sub_command = "zone_points", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showzonepoints"}, + {.parent_command = "show", .sub_command = "zone_stats", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "zstats"}, + {.parent_command = "show", .sub_command = "zone_status", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "zonestatus"}, + }; + + auto db_sub_settings = All(db); + + // inject commands in the database that are not already there + std::vector new_records = {}; + for (const auto &r: static_records) { + bool found = false; + for (const auto &db_r: db_sub_settings) { + if (r.parent_command == db_r.parent_command && r.sub_command == db_r.sub_command) { + found = true; + } + } + + if (!found) { + LogInfo("New command [{}] sub-command [{}] added to database table [{}] !", r.parent_command, r.sub_command, TableName()); + new_records.emplace_back(r); + } + } + + if (!new_records.empty()) { + InsertMany(db, new_records); + // if any were added, we need to reload the list + db_sub_settings = All(db); + } + + // remove commands from the database that are not in the static list + bool any_deleted = false; + for (const auto &db_r: db_sub_settings) { + bool found = false; + for (const auto &r: static_records) { + if (r.parent_command == db_r.parent_command && r.sub_command == db_r.sub_command) { + found = true; + } + } + + if (!found) { + LogInfo("Command [{}] sub-command [{}] removed from database table [{}] !", db_r.parent_command, db_r.sub_command, TableName()); + DeleteWhere(db, fmt::format("parent_command = '{}' AND sub_command = '{}'", db_r.parent_command, db_r.sub_command)); + any_deleted = true; + } + } + + // if any were deleted, re-read the database + if (any_deleted) { + db_sub_settings = All(db); + } + + // return the final list of what's in the database + return db_sub_settings; + } +}; + +#endif //EQEMU_COMMAND_SUBSETTINGS_REPOSITORY_H diff --git a/common/shareddb.cpp b/common/shareddb.cpp index d22de7056..44992f456 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -1635,25 +1635,29 @@ bool SharedDatabase::GetCommandSettings(std::map aliases = Strings::Split(row[2], '|'); - for (auto iter = aliases.begin(); iter != aliases.end(); ++iter) { - if (iter->empty()) + for (const auto& e : aliases) { + if (e.empty()) { continue; - command_settings[row[0]].second.push_back(*iter); + } + + command_settings[row[0]].second.push_back(e); } } - return true; + return true; } bool SharedDatabase::UpdateInjectedCommandSettings(const std::vector> &injected) @@ -1668,13 +1672,15 @@ bool SharedDatabase::UpdateInjectedCommandSettings(const std::vector &orphaned) { if (orphaned.size()) { - const std::string query = fmt::format( + std::string query = fmt::format( "DELETE FROM `command_settings` WHERE `command` IN ({})", Strings::ImplodePair(",", std::pair('\'', '\''), orphaned) ); - if (!QueryDatabase(query).Success()) { + auto results = QueryDatabase(query); + if (!results.Success()) { + return false; + } + + query = fmt::format( + "DELETE FROM `command_subsettings` WHERE `parent_command` IN ({})", + Strings::ImplodePair(",", std::pair('\'', '\''), orphaned) + ); + + auto results_two = QueryDatabase(query); + if (!results_two.Success()) { return false; } LogInfo( - "{} Orphaned Command{} Deleted", + "{} Orphaned Command{} Deleted | {} Orphaned Subcommand{} Deleted", orphaned.size(), - (orphaned.size() == 1 ? "" : "s") + orphaned.size() != 1 ? "s" : "", + results_two.RowsAffected(), + results_two.RowsAffected() != 1 ? "s" : "" ); } return true; } +bool SharedDatabase::GetCommandSubSettings(std::vector &command_subsettings) +{ + command_subsettings.clear(); + + const auto& l = CommandSubsettingsRepository::GetAll(*this); + + if (l.empty()) { + return false; + } + + command_subsettings.reserve(l.size()); + + for (const auto& e : l) { + command_subsettings.emplace_back(e); + } + + return true; +} + + bool SharedDatabase::LoadSkillCaps(const std::string &prefix) { skill_caps_mmf.reset(nullptr); diff --git a/common/shareddb.h b/common/shareddb.h index 2956fe9b2..55bc6b32f 100644 --- a/common/shareddb.h +++ b/common/shareddb.h @@ -28,6 +28,7 @@ #include "fixed_memory_hash_set.h" #include "fixed_memory_variable_hash_set.h" #include "say_link.h" +#include "repositories/command_subsettings_repository.h" #include #include @@ -77,6 +78,7 @@ public: bool GetCommandSettings(std::map>> &command_settings); bool UpdateInjectedCommandSettings(const std::vector> &injected); bool UpdateOrphanedCommandSettings(const std::vector &orphaned); + bool GetCommandSubSettings(std::vector &command_subsettings); uint32 GetTotalTimeEntitledOnAccount(uint32 AccountID); bool SetGMInvul(uint32 account_id, bool gminvul); bool SetGMFlymode(uint32 account_id, uint8 flymode); diff --git a/common/strings.cpp b/common/strings.cpp index b4cf5d011..5a806689e 100644 --- a/common/strings.cpp +++ b/common/strings.cpp @@ -882,3 +882,17 @@ std::string Strings::RemoveNumbers(std::string s) return s.substr(0, current); } + +std::string Strings::ZoneTime(const uint8 hours, const uint8 minutes) +{ + return fmt::format( + "{:02}:{:02} {}", + ( + (hours % 12) == 0 ? + 12 : + (hours % 12) + ), + minutes, + hours >= 13 ? "PM" : "AM" + ); +} diff --git a/common/strings.h b/common/strings.h index 0ef35f93f..818be96ef 100644 --- a/common/strings.h +++ b/common/strings.h @@ -130,6 +130,7 @@ public: static std::string Random(size_t length); static bool BeginsWith(const std::string& subject, const std::string& search); static bool EndsWith(const std::string& subject, const std::string& search); + static std::string ZoneTime(const uint8 hours, const uint8 minutes); template static std::string diff --git a/common/version.h b/common/version.h index 9a8f73a08..cc441022d 100644 --- a/common/version.h +++ b/common/version.h @@ -42,7 +42,7 @@ * Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt */ -#define CURRENT_BINARY_DATABASE_VERSION 9231 +#define CURRENT_BINARY_DATABASE_VERSION 9232 #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9039 diff --git a/zone/client.cpp b/zone/client.cpp index 3e4b3790e..2b6682c88 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -1533,6 +1533,50 @@ bool Client::UpdateLDoNPoints(uint32 theme_id, int points) { return true; } +void Client::SetLDoNPoints(uint32 theme_id, uint32 points) +{ + switch (theme_id) { + case LDoNThemes::GUK: { + m_pp.ldon_points_guk = points; + break; + } + case LDoNThemes::MIR: { + m_pp.ldon_points_mir = points; + break; + } + case LDoNThemes::MMC: { + m_pp.ldon_points_mmc = points; + break; + } + case LDoNThemes::RUJ: { + m_pp.ldon_points_ruj = points; + break; + } + case LDoNThemes::TAK: { + m_pp.ldon_points_tak = points; + break; + } + } + + m_pp.ldon_points_available += points; + + auto outapp = new EQApplicationPacket(OP_AdventurePointsUpdate, sizeof(AdventurePoints_Update_Struct)); + + auto a = (AdventurePoints_Update_Struct*) outapp->pBuffer; + + a->ldon_available_points = m_pp.ldon_points_available; + a->ldon_guk_points = m_pp.ldon_points_guk; + a->ldon_mirugal_points = m_pp.ldon_points_mir; + a->ldon_mistmoore_points = m_pp.ldon_points_mmc; + a->ldon_rujarkian_points = m_pp.ldon_points_ruj; + a->ldon_takish_points = m_pp.ldon_points_tak; + + outapp->priority = 6; + + QueuePacket(outapp); + safe_delete(outapp); +} + void Client::SetSkill(EQ::skills::SkillType skillid, uint16 value) { if (skillid > EQ::skills::HIGHEST_SKILL) return; diff --git a/zone/client.h b/zone/client.h index 22f5f1f17..9581bd97a 100644 --- a/zone/client.h +++ b/zone/client.h @@ -602,6 +602,7 @@ public: inline void SetEXPModifier(uint32 zone_id, double exp_modifier, int16 instance_version = -1) { database.SetEXPModifier(CharacterID(), zone_id, exp_modifier, instance_version); }; bool UpdateLDoNPoints(uint32 theme_id, int points); + void SetLDoNPoints(uint32 theme_id, uint32 points); void SetPVPPoints(uint32 Points) { m_pp.PVPCurrentPoints = Points; } uint32 GetPVPPoints() { return m_pp.PVPCurrentPoints; } void AddPVPPoints(uint32 Points); diff --git a/zone/command.cpp b/zone/command.cpp index 266e57fe9..96a7a9613 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -1,8 +1,8 @@ - #include #include #include #include +#include "../common/repositories/command_subsettings_repository.h" #ifdef _WINDOWS #define strcasecmp _stricmp @@ -40,16 +40,17 @@ extern FastMath g_Math; void CatchSignal(int sig_num); -int command_count; // how many commands we have +int command_count; // how many commands we have // this is the pointer to the dispatch function, updated once // init has been performed to point at the real function int (*command_dispatch)(Client *, std::string, bool) = command_notavail; -std::map commandlist; -std::map commandaliases; -std::vector command_delete_list; -std::map commands_map; +std::map commandlist; +std::map commandaliases; +std::vector command_delete_list; +std::map commands_map; +std::vector command_subsettings; /* * command_notavail @@ -94,7 +95,6 @@ int command_init(void) command_add("attack", "[Entity Name] - Make your NPC target attack an entity by name", AccountStatus::GMLeadAdmin, command_attack) || command_add("augmentitem", "Force augments an item. Must have the augment item window open.", AccountStatus::GMImpossible, command_augmentitem) || command_add("ban", "[Character Name] [Reason] - Ban by character name", AccountStatus::GMLeadAdmin, command_ban) || - command_add("bind", "Sets your targets bind spot to their current location", AccountStatus::GMMgmt, command_bind) || command_add("bugs", "[Close|Delete|Review|Search|View] - Handles player bug reports", AccountStatus::QuestTroupe, command_bugs) || command_add("bot", "Type \"#bot help\" or \"^help\" to the see the list of available commands for bots.", AccountStatus::Player, command_bot) || command_add("camerashake", "[Duration (Milliseconds)] [Intensity (1-10)] - Shakes the camera on everyone's screen globally.", AccountStatus::QuestTroupe, command_camerashake) || @@ -106,7 +106,6 @@ int command_init(void) command_add("countitem", "[Item ID] - Counts the specified Item ID in your or your target's inventory", AccountStatus::GMLeadAdmin, command_countitem) || command_add("damage", "[Amount] - Damage yourself or your target", AccountStatus::GMAdmin, command_damage) || command_add("databuckets", "View|Delete [key] [limit]- View data buckets, limit 50 default or Delete databucket by key", AccountStatus::QuestTroupe, command_databuckets) || - command_add("date", "[Year] [Month] [Day] [Hour] [Minute] - Set EQ time (Hour and Minute are optional)", AccountStatus::EQSupport, command_date) || command_add("dbspawn2", "[Spawngroup ID] [Respawn] [Variance] [Condition ID] [Condition Minimum] - Spawn an NPC from a predefined row in the spawn2 table, Respawn and Variance are in Seconds (condition is optional)", AccountStatus::GMAdmin, command_dbspawn2) || command_add("delacct", "[Account ID|Account Name] - Delete an account by ID or Name", AccountStatus::GMLeadAdmin, command_delacct) || command_add("delpetition", "[petition number] - Delete a petition", AccountStatus::ApprenticeGuide, command_delpetition) || @@ -124,7 +123,6 @@ int command_init(void) command_add("emote", "[Name|World|Zone] [type] [message] - Send an emote message by name, to the world, or to your zone (^ separator allows multiple messages to be sent at once)", AccountStatus::QuestTroupe, command_emote) || command_add("emptyinventory", "Clears your or your target's entire inventory (Equipment, General, Bank, and Shared Bank)", AccountStatus::GMImpossible, command_emptyinventory) || command_add("enablerecipe", "[Recipe ID] - Enables a Recipe", AccountStatus::QuestTroupe, command_enablerecipe) || - command_add("endurance", "Restores your or your target's endurance.", AccountStatus::Guide, command_endurance) || command_add("entityvariable", "[clear|delete|set|view] - Modify entity variables for yourself or your target", AccountStatus::GMAdmin, command_entityvariable) || command_add("exptoggle", "[Toggle] - Toggle your or your target's experience gain.", AccountStatus::QuestTroupe, command_exptoggle) || command_add("faction", "[Find (criteria | all ) | Review (criteria | all) | Reset (id)] - Resets Player's Faction", AccountStatus::QuestTroupe, command_faction) || @@ -133,59 +131,39 @@ int command_init(void) command_add("size", "Change your targets size (alias of #feature size)", AccountStatus::QuestTroupe, command_feature) || command_add("find", "Search command used to find various things", AccountStatus::Guide, command_find) || command_add("fixmob", "[race|gender|texture|helm|face|hair|haircolor|beard|beardcolor|heritage|tattoo|detail] [next|prev] - Manipulate appearance of your target", AccountStatus::QuestTroupe, command_fixmob) || - command_add("flag", "[Status] [Account Name] - Refresh your admin status, or set an account's Admin status if arguments provided", AccountStatus::Player, command_flag) || command_add("flagedit", "Edit zone flags on your target. Use #flagedit help for more info.", AccountStatus::GMAdmin, command_flagedit) || - command_add("flymode", "[0/1/2/3/4/5] - Set your or your player target's flymode to ground/flying/levitate/water/floating/levitate_running", AccountStatus::Guide, command_flymode) || - command_add("freeze", "Freeze your target", AccountStatus::QuestTroupe, command_freeze) || - command_add("gassign", "[Grid ID] - Assign targetted NPC to predefined wandering grid id", AccountStatus::GMAdmin, command_gassign) || command_add("gearup", "Developer tool to quickly equip yourself or your target", AccountStatus::GMMgmt, command_gearup) || - command_add("gender", "[0/1/2] - Change your or your target's gender to male/female/neuter", AccountStatus::Guide, command_gender) || command_add("giveitem", "[itemid] [charges] - Summon an item onto your target's cursor. Charges are optional.", AccountStatus::GMMgmt, command_giveitem) || command_add("givemoney", "[Platinum] [Gold] [Silver] [Copper] - Gives specified amount of money to you or your player target", AccountStatus::GMMgmt, command_givemoney) || - command_add("gm", "[On|Off] - Modify your or your target's GM Flag", AccountStatus::QuestTroupe, command_gm) || - command_add("gmspeed", "[On|Off] - Turn GM Speed On or Off for you or your player target", AccountStatus::GMAdmin, command_gmspeed) || command_add("gmzone", "[Zone ID|Zone Short Name] [Version] [Instance Identifier] - Zones to a private GM instance (Version defaults to 0 and Instance Identifier defaults to 'gmzone' if not used)", AccountStatus::GMAdmin, command_gmzone) || - command_add("godmode", "[on/off] - Turns on/off hideme, gmspeed, invul, and flymode.", AccountStatus::GMMgmt, command_godmode) || command_add("goto", "[playername] or [x y z] [h] - Teleport to the provided coordinates or to your target", AccountStatus::Steward, command_goto) || command_add("grid", "[add/delete] [grid_num] [wandertype] [pausetype] - Create/delete a wandering grid", AccountStatus::GMAreas, command_grid) || command_add("guild", "Guild manipulation commands. Use argument help for more info.", AccountStatus::Steward, command_guild) || - command_add("haste", "[Percentage] - Set your or your target's GM Bonus Haste (100 is 100% more Attack Speed)", AccountStatus::GMAdmin, command_haste) || - command_add("heal", "Completely heal your target", AccountStatus::Steward, command_heal) || command_add("help", "[Search Criteria] - List available commands and their description, specify partial command as argument to search", AccountStatus::Player, command_help) || - command_add("heromodel", "[Hero Model] [Slot] - Set your or your target's appearance to a full set of Hero's Forge Armor, if slot is set, sends exact model just to slot.", AccountStatus::GMMgmt, command_heromodel) || - command_add("hideme", "[On|Off] or [0|1] - Hide yourself from players below your status level.", AccountStatus::QuestTroupe, command_hideme) || command_add("hotfix", "[hotfix_name] - Reloads shared memory into a hotfix, equiv to load_shared_memory followed by apply_shared_memory", AccountStatus::GMImpossible, command_hotfix) || command_add("hp", "Refresh your HP bar from the server.", AccountStatus::Player, command_hp) || - command_add("incstat", "Increases or Decreases a client's stats permanently.", AccountStatus::GMMgmt, command_incstat) || command_add("instance", "Modify Instances", AccountStatus::GMMgmt, command_instance) || command_add("interrogateinv", "use [help] argument for available options", AccountStatus::Player, command_interrogateinv) || command_add("interrupt", "[Message ID] [Color] - Interrupt your casting. Arguments are optional.", AccountStatus::Guide, command_interrupt) || command_add("invsnapshot", "Manipulates inventory snapshots for your current target", AccountStatus::QuestTroupe, command_invsnapshot) || - command_add("invul", "[On|Off]] - Turn player target's or your invulnerable flag on or off", AccountStatus::QuestTroupe, command_invul) || command_add("ipban", "[IP] - Ban IP", AccountStatus::GMMgmt, command_ipban) || command_add("kick", "[Character Name] - Disconnect a player by name", AccountStatus::GMLeadAdmin, command_kick) || command_add("kill", "Kill your target", AccountStatus::GMAdmin, command_kill) || command_add("killallnpcs", "[npc_name] - Kills all npcs by search name, leave blank for all attackable NPC's", AccountStatus::GMMgmt, command_killallnpcs) || - command_add("lastname", "[Last Name] - Set your or your player target's last name (use \"-1\" to remove last name)", AccountStatus::Guide, command_lastname) || - command_add("level", "[Level] - Set your or your target's level", AccountStatus::Steward, command_level) || command_add("list", "[npcs|players|corpses|doors|objects] [search] - Search entities", AccountStatus::ApprenticeGuide, command_list) || command_add("lootsim", "[npc_type_id] [loottable_id] [iterations] - Runs benchmark simulations using real loot logic to report numbers and data", AccountStatus::GMImpossible, command_lootsim) || command_add("load_shared_memory", "[shared_memory_name] - Reloads shared memory and uses the input as output", AccountStatus::GMImpossible, command_load_shared_memory) || command_add("loc", "Print out your or your target's current location and heading", AccountStatus::Player, command_loc) || command_add("logs", "Manage anything to do with logs", AccountStatus::GMImpossible, command_logs) || command_add("makepet", "[Pet Name] - Make a pet", AccountStatus::Guide, command_makepet) || - command_add("mana", "Fill your or your target's mana", AccountStatus::Guide, command_mana) || - command_add("maxskills", "Maxes skills for you or your player target.", AccountStatus::GMMgmt, command_max_all_skills) || command_add("memspell", "[Spell ID] [Spell Gem] - Memorize a Spell by ID to the specified Spell Gem for you or your target", AccountStatus::Guide, command_memspell) || command_add("merchantshop", "Closes or opens your target merchant's shop", AccountStatus::GMAdmin, command_merchantshop) || command_add("modifynpcstat", "[Stat] [Value] - Modifies an NPC's stats temporarily.", AccountStatus::GMLeadAdmin, command_modifynpcstat) || - command_add("motd", "[Message of the Day] - Set Message of the Day (leave empty to have no Message of the Day)", AccountStatus::GMLeadAdmin, command_motd) || command_add("movechar", "[Character ID|Character Name] [Zone ID|Zone Short Name] - Move an offline character to the specified zone", AccountStatus::Guide, command_movechar) || command_add("movement", "Various movement commands", AccountStatus::GMMgmt, command_movement) || command_add("myskills", "Show details about your current skill levels", AccountStatus::Player, command_myskills) || command_add("mysql", "[Help|Query] [SQL Query] - Mysql CLI, see 'Help' for options.", AccountStatus::GMImpossible, command_mysql) || command_add("mystats", "Show details about you or your pet", AccountStatus::Guide, command_mystats) || - command_add("name", "[New Name] - Rename your player target", AccountStatus::GMLeadAdmin, command_name) || command_add("npccast", "[targetname/entityid] [spellid] - Causes NPC target to cast spellid on targetname/entityid", AccountStatus::QuestTroupe, command_npccast) || command_add("npcedit", "[column] [value] - Mega NPC editing command", AccountStatus::GMAdmin, command_npcedit) || command_add("npceditmass", "[name-search] [column] [value] - Mass (Zone wide) NPC data editing command", AccountStatus::GMAdmin, command_npceditmass) || @@ -199,20 +177,13 @@ int command_init(void) command_add("nukebuffs", "[Beneficial|Detrimental|Help] - Strip all buffs by type on you or your target (no argument to remove all buffs)", AccountStatus::Guide, command_nukebuffs) || command_add("nukeitem", "[Item ID] - Removes the specified Item ID from you or your player target's inventory", AccountStatus::GMLeadAdmin, command_nukeitem) || command_add("object", "List|Add|Edit|Move|Rotate|Copy|Save|Undo|Delete - Manipulate static and tradeskill objects within the zone", AccountStatus::GMAdmin, command_object) || - command_add("oocmute", "[0|1] - Enable or Disable Server OOC", AccountStatus::GMMgmt, command_oocmute) || command_add("opcode", "Reloads all opcodes from server patch files", AccountStatus::GMMgmt, command_reload) || command_add("path", "view and edit pathing", AccountStatus::GMMgmt, command_path) || command_add("peqzone", "[Zone ID|Zone Short Name] - Teleports you to the specified zone if you meet the requirements.", AccountStatus::Player, command_peqzone) || - command_add("permaclass", "[Class ID] - Change your or your player target's class, changed client is disconnected", AccountStatus::QuestTroupe, command_permaclass) || - command_add("permagender", "[Gender ID] - Change your or your player target's gender", AccountStatus::QuestTroupe, command_permagender) || - command_add("permarace", "[Race ID] - Change your or your player target's race", AccountStatus::QuestTroupe, command_permarace) || command_add("petitems", "View your pet's items if you have one", AccountStatus::ApprenticeGuide, command_petitems) || command_add("picklock", "Analog for ldon pick lock for the newer clients since we still don't have it working.", AccountStatus::Player, command_picklock) || command_add("profanity", "Manage censored language.", AccountStatus::GMLeadAdmin, command_profanity) || command_add("push", "[Back Push] [Up Push] - Lets you do spell push on an NPC", AccountStatus::GMLeadAdmin, command_push) || - command_add("pvp", "[On|Off] - Set you or your player target's PVP status", AccountStatus::GMAdmin, command_pvp) || - command_add("qglobal", "[On|Off|View] - Toggles quest global functionality for your NPC target", AccountStatus::GMAdmin, command_qglobal) || - command_add("race", "[racenum] - Change your or your target's race. Use racenum 0 to return to normal", AccountStatus::Guide, command_race) || command_add("raidloot", "[All|GroupLeader|RaidLeader|Selected] - Sets your Raid Loot Type if you have permission to do so.", AccountStatus::Player, command_raidloot) || 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) || @@ -233,29 +204,8 @@ int command_init(void) command_add("scribespells", "[Max level] [Min level] - Scribe all spells for you or your player target that are usable by them, up to level specified. (may freeze client for a few seconds)", AccountStatus::GMLeadAdmin, command_scribespells) || command_add("sendzonespawns", "Refresh spawn list for all clients in zone", AccountStatus::GMLeadAdmin, command_sendzonespawns) || command_add("sensetrap", "Analog for ldon sense trap for the newer clients since we still don't have it working.", AccountStatus::Player, command_sensetrap) || - command_add("serverlock", "[0|1] - Lock or Unlock the World Server (0 = Unlocked, 1 = Locked)", AccountStatus::GMLeadAdmin, command_serverlock) || - command_add("serverrules", "Read this server's rules", AccountStatus::Player, command_serverrules) || - command_add("setaapts", "[AA|Group|Raid] [AA Amount] - Set your or your player target's Available AA Points by Type", AccountStatus::GMAdmin, command_setaapts) || - command_add("setaaxp", "[AA|Group|Raid] [AA Experience] - Set your or your player target's AA Experience by Type", AccountStatus::GMAdmin, command_setaaxp) || - command_add("setadventurepoints", "[Theme] [Points] - Set your or your player target's available Adventure Points by Theme", AccountStatus::GMLeadAdmin, command_set_adventure_points) || - command_add("setaltcurrency", "[Currency ID] [Amount] - Set your or your target's available Alternate Currency by Currency ID", AccountStatus::GMAdmin, command_setaltcurrency) || - command_add("setanim", "[Animation ID (IDs are 0 to 4)] - Set target's appearance to Animation ID", AccountStatus::GMMgmt, command_setanim) || - command_add("setanon", "[Anonymous Flag] - Set you or your target's Anonymous Flag (0 = Not Anonymous, 1 = Anonymous, 2 = Roleplaying)", AccountStatus::QuestTroupe, command_setanon) || - command_add("setcrystals", "[value] - Set your or your player target's available radiant or ebon crystals", AccountStatus::GMAdmin, command_setcrystals) || - command_add("setendurance", "[Endurance] - Set your or your target's Endurance", AccountStatus::GMAdmin, command_setendurance) || - command_add("setfaction", "[Faction ID] - Sets targeted NPC's faction in the database", AccountStatus::GMAreas, command_setfaction) || - command_add("sethp", "[Health] - Set your or your target's Health", AccountStatus::GMAdmin, command_sethp) || - command_add("setlanguage", "[Language ID] [Value] - Set your or your target's Language by ID to Value", AccountStatus::Guide, command_setlanguage) || - command_add("setlsinfo", "[Email] [Password] - Set loginserver email address and password (if supported by loginserver)", AccountStatus::Steward, command_setlsinfo) || - command_add("setmana", "[Mana] - Set your or your target's Mana", AccountStatus::GMAdmin, command_setmana) || - command_add("setpass", "[Account Name] [Password] - Set local password by account name", AccountStatus::GMLeadAdmin, command_setpass) || - command_add("setpvppoints", "[Amount] - Set your or your player target's PVP points", AccountStatus::GMAdmin, command_setpvppoints) || - command_add("setskill", "[skillnum] [value] - Set your target's skill skillnum to value", AccountStatus::Guide, command_setskill) || - command_add("setskillall", "[Skill Level] - Set all of your or your target's skills to the specified skill level", AccountStatus::Guide, command_setskillall) || - command_add("setstartzone", "[Zone ID|Zone Short Name] - Sets your or your target's starting zone (Use '0' or 'Reset' to allow the player use of /setstartcity)", AccountStatus::QuestTroupe, command_setstartzone) || - command_add("setstat", "Sets the stats to a specific value.", AccountStatus::Max, command_setstat) || - command_add("setxp", "[value] - Set your or your player target's experience", AccountStatus::GMAdmin, command_setxp) || - command_add("show", "List command used to show various things", AccountStatus::Guide, command_show) || + command_add("set", "Set command used to set various things", AccountStatus::Guide, command_set) || + command_add("show", "Show command used to show various things", AccountStatus::Guide, command_show) || command_add("shutdown", "Shut this zone process down", AccountStatus::GMLeadAdmin, command_shutdown) || command_add("spawn", "[name] [race] [level] [material] [hp] [gender] [class] [priweapon] [secweapon] [merchantid] - Spawn an NPC", AccountStatus::Steward, command_spawn) || command_add("spawneditmass", "[Search Criteria] [Edit Option] [Edit Value] [Apply] Mass editing spawn command (Apply is optional, 0 = False, 1 = True, default is False)", AccountStatus::GMLeadAdmin, command_spawneditmass) || @@ -267,43 +217,27 @@ int command_init(void) 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) || - command_add("texture", "[Texture] [Helmet Texture] - Change your or your target's texture (Helmet Texture defaults to 0 if not used)", AccountStatus::Steward, command_texture) || - command_add("time", "[Hour] [Minute] - Set world time to specified time", AccountStatus::EQSupport, command_time) || - command_add("timezone", "[Hour] [Minutes] - Set timezone (Minutes are optional)", AccountStatus::EQSupport, command_timezone) || - command_add("title", "[Title] - Set your or your player target's title (use \"-1\" to remove title)", AccountStatus::Guide, command_title) || - command_add("titlesuffix", "[Title Suffix] - Set your or your player target's title suffix (use \"-1\" to remove title suffix)", AccountStatus::Guide, command_titlesuffix) || command_add("traindisc", "[level] - Trains all the disciplines usable by the target, up to level specified. (may freeze client for a few seconds)", AccountStatus::GMLeadAdmin, command_traindisc) || command_add("tune", "Calculate statistical values related to combat.", AccountStatus::GMAdmin, command_tune) || command_add("undye", "Remove dye from all of your or your target's armor slots", AccountStatus::GMAdmin, command_undye) || - command_add("unfreeze", "Unfreeze your target", AccountStatus::QuestTroupe, command_unfreeze) || command_add("unmemspell", "[Spell ID] - Unmemorize a Spell by ID for you or your target", AccountStatus::Guide, command_unmemspell) || command_add("unmemspells", " Unmemorize all spells for you or your target", AccountStatus::Guide, command_unmemspells) || command_add("unscribespell", "[Spell ID] - Unscribe a spell from your or your target's spell book by Spell ID", AccountStatus::GMCoder, command_unscribespell) || command_add("unscribespells", "Clear out your or your player target's spell book.", AccountStatus::GMCoder, command_unscribespells) || command_add("untraindisc", "[Spell ID] - Untrain your or your target's discipline by Spell ID", AccountStatus::GMCoder, command_untraindisc) || command_add("untraindiscs", "Untrains all disciplines from your target.", AccountStatus::GMCoder, command_untraindiscs) || - command_add("updatechecksum", "update client checksum", AccountStatus::GMImpossible, command_updatechecksum) || command_add("wc", "[Slot ID] [Material] [Hero Forge Model] [Elite Material] - Sets the specified slot for you or your target to a material, Hero Forge Model and Elite Material are optional", AccountStatus::GMMgmt, command_wc) || - command_add("weather", "[0/1/2/3] (Off/Rain/Snow/Manual) - Change the weather", AccountStatus::QuestTroupe, command_weather) || command_add("worldshutdown", "Shut down world and all zones", AccountStatus::GMMgmt, command_worldshutdown) || command_add("wp", "[add|delete] [grid_id] [pause] [waypoint_id] [-h] - Add or delete a waypoint by grid ID. (-h to use current heading)", AccountStatus::GMAreas, command_wp) || command_add("wpadd", "[pause] [-h] - Add your current location as a waypoint to your NPC target's AI path. (-h to use current heading)", AccountStatus::GMAreas, command_wpadd) || command_add("worldwide", "Performs world-wide GM functions such as cast (can be extended for other commands). Use caution", AccountStatus::GMImpossible, command_worldwide) || - command_add("zclip", "[Minimum Clip] [Maximum Clip] [Fog Minimum Clip] [Fog Maximum Clip] [Permanent (0 = False, 1 = True)] - Change zone clipping", AccountStatus::QuestTroupe, command_zclip) || - command_add("zcolor", "[Red] [Green] [Blue] [Permanent (0 = False, 1 = True)] - Change sky color", AccountStatus::QuestTroupe, command_zcolor) || - command_add("zheader", "[Zone ID|Zone Short Name] [Version] - Load a zone header from the database", AccountStatus::QuestTroupe, command_zheader) || command_add("zone", "[Zone ID|Zone Short Name] [X] [Y] [Z] - Teleport to specified Zone by ID or Short Name (coordinates are optional)", AccountStatus::Guide, command_zone) || command_add("zonebootup", "[ZoneServerID] [shortname] - Make a zone server boot a specific zone", AccountStatus::GMLeadAdmin, command_zonebootup) || command_add("zoneinstance", "[Instance ID] [X] [Y] [Z] - Teleport to specified Instance by ID (coordinates are optional)", AccountStatus::Guide, command_zone_instance) || - command_add("zonelock", "[List|Lock|Unlock] [Zone ID|Zone Short Name] - Set or get lock status of a Zone by ID or Short Name", AccountStatus::GMAdmin, command_zonelock) || command_add("zoneshutdown", "[shortname] - Shut down a zone server", AccountStatus::GMLeadAdmin, command_zoneshutdown) || command_add("zopp", "Troubleshooting command - Sends a fake item packet to you. No server reference is created.", AccountStatus::GMImpossible, command_zopp) || - command_add("zsafecoords", "[X] [Y] [Z] [Heading] [Permanent (0 = False, 1 = True)] - Set the current zone's safe coordinates", AccountStatus::QuestTroupe, command_zsafecoords) || - command_add("zsave", " Saves zheader to the database", AccountStatus::QuestTroupe, command_zsave) || - command_add("zsky", "[Sky Type] [Permanent (0 = False, 1 = True)] - Change zone sky type", AccountStatus::QuestTroupe, command_zsky) || - command_add("zunderworld", "[Z] [Permanent (0 = False, 1 = True)] - Change zone underworld Z", AccountStatus::QuestTroupe, command_zunderworld) + command_add("zsave", " Saves zheader to the database", AccountStatus::QuestTroupe, command_zsave) ) { command_deinit(); return -1; @@ -311,102 +245,17 @@ int command_init(void) std::map>> command_settings; database.GetCommandSettings(command_settings); + database.GetCommandSubSettings(command_subsettings); std::vector> injected_command_settings; std::vector orphaned_command_settings; - // static aliases - struct StaticAlias { - std::string command; - std::vector aliases; - }; - - std::vector static_aliases = { - { - .command = "find", - .aliases = { - "fi", - "fn", - "fs", - "fz", - "findaa", - "findcharacter", - "findclass", - "findcurrency", - "finddeity", - "findemote", - "findfaction", - "finditem", - "findlanguage", - "findnpc", - "findnpctype", - "findrace", - "findrecipe", - "findskill", - "findspell", - "findtask", - "findzone", - "itemsearch" - } - }, - { - .command = "show", - .aliases = { - "aggro", - "checklos", - "cvs", - "distance", - "emoteview", - "flags", - "fov", - "getplayerburiedcorpsecount", - "getvariable", - "ginfo", - "globalview", - "hatelist", - "iplookup", - "listpetition", - "network", - "netstats", - "npcstats", - "peekinv", - "petitioninfo", - "peqzone_flags", - "proximity", - "questerrors", - "serverinfo", - "showbuffs", - "shownpcgloballoot", - "showskills", - "showspells", - "showspellslist", - "showstats", - "showzonegloballoot", - "showzonepoints", - "spawnstatus", - "timers", - "trapinfo", - "uptime", - "version", - "viewcurrencies", - "viewnpctype", - "viewpetition", - "viewrecipe", - "viewzoneloot", - "who", - "wpinfo", - "xtargets", - "zonestatus", - "zstats" - } - }, - }; - - // inject static aliases + // inject static sub command aliases + // .e.g old #fi routes to #find item or #itemsearch routes to #find item for (auto& cs : command_settings) { - for (const auto& sa : static_aliases) { - if (cs.first == sa.command) { - for (const auto& alias : sa.aliases) { + for (const auto& e : command_subsettings) { + if (cs.first == e.parent_command) { + for (const auto& alias : Strings::Split(e.top_level_aliases, "|")) { cs.second.second.emplace_back(alias); } } @@ -418,7 +267,7 @@ int command_init(void) if (cl == commandlist.end()) { orphaned_command_settings.push_back(cs.first); LogInfo( - "Command [{}] no longer exists... Deleting orphaned entry from `command_settings` table...", + "Command [{}] no longer exists. Deleting orphaned entry from `command_settings` table.", cs.first ); } @@ -436,7 +285,7 @@ int command_init(void) if (cs == command_settings.end()) { injected_command_settings.emplace_back(w.first, w.second->admin); LogInfo( - "New Command [{}] found. Adding to `command_settings` table with admin [{}]...", + "New Command [{}] found. Adding to `command_settings` table with admin status [{}]", w.first, w.second->admin ); @@ -452,6 +301,7 @@ int command_init(void) } w.second->admin = cs->second.first; + LogCommands( "Command [{}] set to admin level [{}]", w.first, @@ -476,7 +326,7 @@ int command_init(void) continue; } - commandlist[a] = w.second; + commandlist[a] = w.second; commandaliases[a] = w.first; LogCommands( @@ -498,6 +348,7 @@ int command_init(void) return command_count; } + /* * command_deinit * clears the command list, freeing resources @@ -549,23 +400,24 @@ int command_add(std::string command_name, std::string description, uint8 admin, } auto c = new CommandRecord; - c->admin = admin; + + c->admin = admin; c->description = description; - c->function = function; + c->function = function; - commands_map[command_name] = admin; - - commandlist[command_name] = c; + commands_map[command_name] = admin; + commandlist[command_name] = c; commandaliases[command_name] = command_name; + command_delete_list.push_back(c); command_count++; return 0; } -uint8 GetCommandStatus(Client *c, std::string command_name) { - auto command_status = commands_map[command_name]; - return command_status; +uint8 GetCommandStatus(std::string command_name) +{ + return commands_map[command_name]; } /* @@ -591,9 +443,46 @@ int command_realdispatch(Client *c, std::string message, bool ignore_status) } auto cur = commandlist[cstr]; - if (!ignore_status && c->Admin() < cur->admin) { - c->Message(Chat::White, "Your status is not high enough to use this command."); - return -1; + + bool is_subcommand = false; + bool can_use_subcommand = false; + bool found_subcommand_setting = false; + + const auto arguments = sep.argnum; + + if (arguments >= 2) { + const std::string& sub_command = sep.arg[1]; + + for (const auto &e : command_subsettings) { + if (e.sub_command == sub_command) { + can_use_subcommand = c->Admin() >= static_cast(e.access_level); + is_subcommand = true; + found_subcommand_setting = true; + break; + } + } + + if (!found_subcommand_setting) { + for (const auto &e: command_subsettings) { + if (e.sub_command == sub_command) { + can_use_subcommand = c->Admin() >= static_cast(e.access_level); + is_subcommand = true; + break; + } + } + } + } + + if (!ignore_status) { + if (!is_subcommand && c->Admin() < cur->admin) { + c->Message(Chat::White, "Your status is not high enough to use this command."); + return -1; + } + + if (is_subcommand && !can_use_subcommand) { + c->Message(Chat::White, "Your status is not high enough to use this subcommand."); + return -1; + } } /* QS: Player_Log_Issued_Commands */ @@ -648,7 +537,10 @@ void command_help(Client *c, const Seperator *sep) for (const auto& cur : commandlist) { if (!search_criteria.empty()) { - if (!Strings::Contains(cur.first, search_criteria) && !Strings::Contains(cur.second->description, search_criteria)) { + if ( + !Strings::Contains(cur.first, search_criteria) && + !Strings::Contains(cur.second->description, search_criteria) + ) { continue; } } @@ -668,10 +560,9 @@ void command_help(Client *c, const Seperator *sep) c->Message( Chat::White, fmt::format( - "{} | Status: {} | {}", + "{} | {}", command_link, - cur.second->admin, - !cur.second->description.empty() ? cur.second->description : "" + cur.second->description ).c_str() ); @@ -703,88 +594,6 @@ void command_help(Client *c, const Seperator *sep) ); } -void command_findaliases(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments) { - c->Message(Chat::White, "Usage: #findaliases [Search Critera]"); - return; - } - - std::string search_criteria = Strings::ToLower(sep->argplus[1]); - - auto find_iter = commandaliases.find(search_criteria); - if (find_iter == commandaliases.end()) { - c->Message( - Chat::White, - fmt::format( - "No commands or aliases found matching '{}'.", - search_criteria - ).c_str() - ); - return; - } - - auto command_iter = commandlist.find(find_iter->second); - if ( - find_iter->second.empty() || - command_iter == commandlist.end() - ) { - c->Message(Chat::White, "An unknown condition occurred."); - return; - } - - auto current_commmand_link = Saylink::Silent( - fmt::format( - "{}{}", - COMMAND_CHAR, - command_iter->first - ) - ); - - int alias_count = 0; - int alias_number = 1; - std::string alias_link; - for (const auto& a : commandaliases) { - if ( - find_iter->second != a.second || - c->Admin() < command_iter->second->admin - ) { - continue; - } - - alias_link = Saylink::Silent( - fmt::format( - "{}{}", - COMMAND_CHAR, - a.first - ) - ); - - c->Message( - Chat::White, - fmt::format( - "Alias {} | {}", - alias_number, - alias_link - ).c_str() - ); - - alias_count++; - alias_number++; - } - - c->Message( - Chat::White, - fmt::format( - "{} Alias{} listed for {}.", - alias_count, - alias_count != 1 ? "es" : "", - current_commmand_link - ).c_str() - ); -} - void command_hotfix(Client *c, const Seperator *sep) { auto items_count = database.GetItemsCount(); @@ -977,7 +786,6 @@ void command_bot(Client *c, const Seperator *sep) #include "gm_commands/attack.cpp" #include "gm_commands/augmentitem.cpp" #include "gm_commands/ban.cpp" -#include "gm_commands/bind.cpp" #include "gm_commands/bugs.cpp" #include "gm_commands/camerashake.cpp" #include "gm_commands/castspell.cpp" @@ -988,7 +796,6 @@ void command_bot(Client *c, const Seperator *sep) #include "gm_commands/countitem.cpp" #include "gm_commands/damage.cpp" #include "gm_commands/databuckets.cpp" -#include "gm_commands/date.cpp" #include "gm_commands/dbspawn2.cpp" #include "gm_commands/delacct.cpp" #include "gm_commands/delpetition.cpp" @@ -1007,63 +814,42 @@ void command_bot(Client *c, const Seperator *sep) #include "gm_commands/emote.cpp" #include "gm_commands/emptyinventory.cpp" #include "gm_commands/enablerecipe.cpp" -#include "gm_commands/endurance.cpp" #include "gm_commands/entityvariable.cpp" #include "gm_commands/exptoggle.cpp" #include "gm_commands/faction.cpp" #include "gm_commands/feature.cpp" #include "gm_commands/find.cpp" #include "gm_commands/fixmob.cpp" -#include "gm_commands/flag.cpp" #include "gm_commands/flagedit.cpp" -#include "gm_commands/flymode.cpp" -#include "gm_commands/freeze.cpp" -#include "gm_commands/gassign.cpp" #include "gm_commands/gearup.cpp" -#include "gm_commands/gender.cpp" #include "gm_commands/giveitem.cpp" #include "gm_commands/givemoney.cpp" -#include "gm_commands/gm.cpp" -#include "gm_commands/gmspeed.cpp" #include "gm_commands/gmzone.cpp" -#include "gm_commands/godmode.cpp" #include "gm_commands/goto.cpp" #include "gm_commands/grid.cpp" #include "gm_commands/guild.cpp" -#include "gm_commands/haste.cpp" -#include "gm_commands/heal.cpp" -#include "gm_commands/heromodel.cpp" -#include "gm_commands/hideme.cpp" #include "gm_commands/hp.cpp" -#include "gm_commands/incstat.cpp" #include "gm_commands/instance.cpp" #include "gm_commands/interrogateinv.cpp" #include "gm_commands/interrupt.cpp" #include "gm_commands/invsnapshot.cpp" -#include "gm_commands/invul.cpp" #include "gm_commands/ipban.cpp" #include "gm_commands/kick.cpp" #include "gm_commands/kill.cpp" #include "gm_commands/killallnpcs.cpp" -#include "gm_commands/lastname.cpp" -#include "gm_commands/level.cpp" #include "gm_commands/list.cpp" #include "gm_commands/lootsim.cpp" #include "gm_commands/loc.cpp" #include "gm_commands/logs.cpp" #include "gm_commands/makepet.cpp" -#include "gm_commands/mana.cpp" -#include "gm_commands/max_all_skills.cpp" #include "gm_commands/memspell.cpp" #include "gm_commands/merchantshop.cpp" #include "gm_commands/modifynpcstat.cpp" -#include "gm_commands/motd.cpp" #include "gm_commands/movechar.cpp" #include "gm_commands/movement.cpp" #include "gm_commands/myskills.cpp" #include "gm_commands/mysql.cpp" #include "gm_commands/mystats.cpp" -#include "gm_commands/name.cpp" #include "gm_commands/npccast.cpp" #include "gm_commands/npcedit.cpp" #include "gm_commands/npceditmass.cpp" @@ -1077,20 +863,13 @@ void command_bot(Client *c, const Seperator *sep) #include "gm_commands/nukebuffs.cpp" #include "gm_commands/nukeitem.cpp" #include "gm_commands/object.cpp" -#include "gm_commands/oocmute.cpp" #include "gm_commands/path.cpp" #include "gm_commands/peqzone.cpp" -#include "gm_commands/permaclass.cpp" -#include "gm_commands/permagender.cpp" -#include "gm_commands/permarace.cpp" #include "gm_commands/petitems.cpp" #include "gm_commands/petname.cpp" #include "gm_commands/picklock.cpp" #include "gm_commands/profanity.cpp" #include "gm_commands/push.cpp" -#include "gm_commands/pvp.cpp" -#include "gm_commands/qglobal.cpp" -#include "gm_commands/race.cpp" #include "gm_commands/raidloot.cpp" #include "gm_commands/randomfeatures.cpp" #include "gm_commands/refreshgroup.cpp" @@ -1109,28 +888,7 @@ void command_bot(Client *c, const Seperator *sep) #include "gm_commands/scribespells.cpp" #include "gm_commands/sendzonespawns.cpp" #include "gm_commands/sensetrap.cpp" -#include "gm_commands/serverlock.cpp" -#include "gm_commands/serverrules.cpp" -#include "gm_commands/set_adventure_points.cpp" -#include "gm_commands/setaapts.cpp" -#include "gm_commands/setaaxp.cpp" -#include "gm_commands/setaltcurrency.cpp" -#include "gm_commands/setanim.cpp" -#include "gm_commands/setanon.cpp" -#include "gm_commands/setcrystals.cpp" -#include "gm_commands/setendurance.cpp" -#include "gm_commands/setfaction.cpp" -#include "gm_commands/sethp.cpp" -#include "gm_commands/setlanguage.cpp" -#include "gm_commands/setlsinfo.cpp" -#include "gm_commands/setmana.cpp" -#include "gm_commands/setpass.cpp" -#include "gm_commands/setpvppoints.cpp" -#include "gm_commands/setskill.cpp" -#include "gm_commands/setskillall.cpp" -#include "gm_commands/setstartzone.cpp" -#include "gm_commands/setstat.cpp" -#include "gm_commands/setxp.cpp" +#include "gm_commands/set.cpp" #include "gm_commands/show.cpp" #include "gm_commands/shutdown.cpp" #include "gm_commands/spawn.cpp" @@ -1144,39 +902,23 @@ void command_bot(Client *c, const Seperator *sep) #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" -#include "gm_commands/time.cpp" -#include "gm_commands/timezone.cpp" -#include "gm_commands/title.cpp" -#include "gm_commands/titlesuffix.cpp" #include "gm_commands/traindisc.cpp" #include "gm_commands/tune.cpp" #include "gm_commands/undye.cpp" -#include "gm_commands/unfreeze.cpp" #include "gm_commands/unmemspell.cpp" #include "gm_commands/unmemspells.cpp" #include "gm_commands/unscribespell.cpp" #include "gm_commands/unscribespells.cpp" -#include "gm_commands/updatechecksum.cpp" #include "gm_commands/untraindisc.cpp" #include "gm_commands/untraindiscs.cpp" #include "gm_commands/wc.cpp" -#include "gm_commands/weather.cpp" #include "gm_commands/worldshutdown.cpp" #include "gm_commands/worldwide.cpp" #include "gm_commands/wp.cpp" #include "gm_commands/wpadd.cpp" -#include "gm_commands/zclip.cpp" -#include "gm_commands/zcolor.cpp" -#include "gm_commands/zheader.cpp" #include "gm_commands/zone.cpp" #include "gm_commands/zonebootup.cpp" -#include "gm_commands/zonelock.cpp" #include "gm_commands/zoneshutdown.cpp" #include "gm_commands/zone_instance.cpp" #include "gm_commands/zopp.cpp" -#include "gm_commands/zsafecoords.cpp" #include "gm_commands/zsave.cpp" -#include "gm_commands/zsky.cpp" -#include "gm_commands/zunderworld.cpp" diff --git a/zone/command.h b/zone/command.h index 34cad6fad..f54265656 100644 --- a/zone/command.h +++ b/zone/command.h @@ -26,7 +26,7 @@ void command_deinit(void); int command_add(std::string command_name, std::string description, uint8 admin, CmdFuncPtr function); int command_notavail(Client *c, std::string message, bool ignore_status); int command_realdispatch(Client *c, std::string message, bool ignore_status); -uint8 GetCommandStatus(Client *c, std::string command_name); +uint8 GetCommandStatus(std::string command_name); void ListModifyNPCStatMap(Client *c); std::map GetModifyNPCStatMap(); std::string GetModifyNPCStatDescription(std::string stat); @@ -46,7 +46,6 @@ void command_apply_shared_memory(Client *c, const Seperator *sep); void command_attack(Client *c, const Seperator *sep); void command_augmentitem(Client *c, const Seperator *sep); void command_ban(Client *c, const Seperator *sep); -void command_bind(Client *c, const Seperator *sep); void command_bugs(Client *c, const Seperator *sep); void command_camerashake(Client *c, const Seperator *sep); void command_castspell(Client *c, const Seperator *sep); @@ -57,7 +56,6 @@ void command_corpsefix(Client *c, const Seperator *sep); void command_countitem(Client *c, const Seperator *sep); void command_damage(Client *c, const Seperator *sep); void command_databuckets(Client *c, const Seperator *sep); -void command_date(Client *c, const Seperator *sep); void command_dbspawn2(Client *c, const Seperator *sep); void command_delacct(Client *c, const Seperator *sep); void command_delpetition(Client *c, const Seperator *sep); @@ -75,7 +73,6 @@ void command_editmassrespawn(Client *c, const Seperator *sep); void command_emote(Client *c, const Seperator *sep); void command_emptyinventory(Client *c, const Seperator *sep); void command_enablerecipe(Client *c, const Seperator *sep); -void command_endurance(Client *c, const Seperator *sep); void command_entityvariable(Client *c, const Seperator *sep); void command_exptoggle(Client *c, const Seperator *sep); void command_faction(Client *c, const Seperator *sep); @@ -83,40 +80,25 @@ void command_faction_association(Client *c, const Seperator *sep); void command_feature(Client *c, const Seperator *sep); void command_find(Client *c, const Seperator *sep); void command_fixmob(Client *c, const Seperator *sep); -void command_flag(Client *c, const Seperator *sep); void command_flagedit(Client *c, const Seperator *sep); -void command_flymode(Client *c, const Seperator *sep); -void command_freeze(Client *c, const Seperator *sep); -void command_gassign(Client *c, const Seperator *sep); void command_gearup(Client *c, const Seperator *sep); -void command_gender(Client *c, const Seperator *sep); void command_giveitem(Client *c, const Seperator *sep); void command_givemoney(Client *c, const Seperator *sep); -void command_gm(Client *c, const Seperator *sep); -void command_gmspeed(Client *c, const Seperator *sep); void command_gmzone(Client *c, const Seperator *sep); -void command_godmode(Client* c, const Seperator *sep); void command_goto(Client *c, const Seperator *sep); void command_grid(Client *c, const Seperator *sep); void command_guild(Client *c, const Seperator *sep); -void command_haste(Client *c, const Seperator *sep); -void command_heal(Client *c, const Seperator *sep); void command_help(Client *c, const Seperator *sep); -void command_heromodel(Client *c, const Seperator *sep); -void command_hideme(Client *c, const Seperator *sep); void command_hotfix(Client *c, const Seperator *sep); void command_hp(Client *c, const Seperator *sep); -void command_incstat(Client *c, const Seperator *sep); void command_instance(Client *c, const Seperator *sep); void command_interrogateinv(Client *c, const Seperator *sep); void command_interrupt(Client *c, const Seperator *sep); void command_invsnapshot(Client *c, const Seperator *sep); -void command_invul(Client *c, const Seperator *sep); void command_ipban(Client *c, const Seperator *sep); void command_kick(Client *c, const Seperator *sep); void command_killallnpcs(Client *c, const Seperator *sep); void command_kill(Client *c, const Seperator *sep); -void command_lastname(Client *c, const Seperator *sep); void command_level(Client *c, const Seperator *sep); void command_list(Client *c, const Seperator *sep); void command_lootsim(Client *c, const Seperator *sep); @@ -124,18 +106,14 @@ void command_load_shared_memory(Client *c, const Seperator *sep); void command_loc(Client *c, const Seperator *sep); void command_logs(Client *c, const Seperator *sep); void command_makepet(Client *c, const Seperator *sep); -void command_mana(Client *c, const Seperator *sep); -void command_max_all_skills(Client *c, const Seperator *sep); void command_memspell(Client *c, const Seperator *sep); void command_merchantshop(Client *c, const Seperator *sep); void command_modifynpcstat(Client *c, const Seperator *sep); -void command_motd(Client *c, const Seperator *sep); void command_movechar(Client *c, const Seperator *sep); void command_movement(Client *c, const Seperator *sep); void command_myskills(Client *c, const Seperator *sep); void command_mysql(Client *c, const Seperator *sep); void command_mystats(Client *c, const Seperator *sep); -void command_name(Client *c, const Seperator *sep); void command_npccast(Client *c, const Seperator *sep); void command_npcedit(Client *c, const Seperator *sep); void command_npceditmass(Client *c, const Seperator *sep); @@ -152,16 +130,11 @@ void command_object(Client *c, const Seperator *sep); void command_oocmute(Client *c, const Seperator *sep); void command_path(Client *c, const Seperator *sep); void command_peqzone(Client *c, const Seperator *sep); -void command_permaclass(Client *c, const Seperator *sep); -void command_permagender(Client *c, const Seperator *sep); -void command_permarace(Client *c, const Seperator *sep); void command_petitems(Client *c, const Seperator *sep); void command_picklock(Client *c, const Seperator *sep); void command_profanity(Client *c, const Seperator *sep); void command_push(Client *c, const Seperator *sep); -void command_pvp(Client *c, const Seperator *sep); -void command_qglobal(Client *c, const Seperator *sep); -void command_race(Client *c, const Seperator *sep); +void command_pvp(Client *c, const Seperator *sep);; void command_raidloot(Client* c, const Seperator* sep); void command_randomfeatures(Client *c, const Seperator *sep); void command_refreshgroup(Client *c, const Seperator *sep); @@ -175,33 +148,13 @@ void command_revoke(Client *c, const Seperator *sep); void command_roambox(Client *c, const Seperator *sep); void command_rules(Client *c, const Seperator *sep); void command_save(Client *c, const Seperator *sep); -void command_serverlock(Client *c, const Seperator *sep); void command_scale(Client *c, const Seperator *sep); void command_scribespell(Client *c, const Seperator *sep); void command_scribespells(Client *c, const Seperator *sep); void command_sendzonespawns(Client *c, const Seperator *sep); void command_sensetrap(Client *c, const Seperator *sep); void command_serverrules(Client *c, const Seperator *sep); -void command_set_adventure_points(Client *c, const Seperator *sep); -void command_setaapts(Client *c, const Seperator *sep); -void command_setaaxp(Client *c, const Seperator *sep); -void command_setaltcurrency(Client *c, const Seperator *sep); -void command_setanim(Client *c, const Seperator *sep); -void command_setanon(Client *c, const Seperator *sep); -void command_setcrystals(Client *c, const Seperator *sep); -void command_setendurance(Client *c, const Seperator *sep); -void command_setfaction(Client *c, const Seperator *sep); -void command_sethp(Client *c, const Seperator *sep); -void command_setlanguage(Client *c, const Seperator *sep); -void command_setlsinfo(Client *c, const Seperator *sep); -void command_setmana(Client *c, const Seperator *sep); -void command_setpass(Client *c, const Seperator *sep); -void command_setpvppoints(Client *c, const Seperator *sep); -void command_setskill(Client *c, const Seperator *sep); -void command_setskillall(Client *c, const Seperator *sep); -void command_setstartzone(Client *c, const Seperator *sep); -void command_setstat(Client *c, const Seperator *sep); -void command_setxp(Client *c, const Seperator *sep); +void command_set(Client *c, const Seperator *sep); void command_show(Client *c, const Seperator *sep); void command_shutdown(Client *c, const Seperator *sep); void command_spawn(Client *c, const Seperator *sep); @@ -214,43 +167,28 @@ 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); -void command_texture(Client *c, const Seperator *sep); -void command_time(Client *c, const Seperator *sep); -void command_timezone(Client *c, const Seperator *sep); -void command_title(Client *c, const Seperator *sep); -void command_titlesuffix(Client *c, const Seperator *sep); void command_traindisc(Client *c, const Seperator *sep); void command_tune(Client *c, const Seperator *sep); void command_undye(Client *c, const Seperator *sep); -void command_unfreeze(Client *c, const Seperator *sep); void command_unmemspell(Client *c, const Seperator *sep); void command_unmemspells(Client *c, const Seperator *sep); void command_unscribespell(Client *c, const Seperator *sep); void command_unscribespells(Client *c, const Seperator *sep); void command_untraindisc(Client *c, const Seperator *sep); void command_untraindiscs(Client *c, const Seperator *sep); -void command_updatechecksum(Client* c, const Seperator* sep); void command_wc(Client *c, const Seperator *sep); -void command_weather(Client *c, const Seperator *sep); void command_worldshutdown(Client *c, const Seperator *sep); void command_wp(Client *c, const Seperator *sep); void command_wpadd(Client *c, const Seperator *sep); void command_worldwide(Client *c, const Seperator *sep); -void command_zclip(Client *c, const Seperator *sep); -void command_zcolor(Client *c, const Seperator *sep); -void command_zheader(Client *c, const Seperator *sep); void command_zone(Client *c, const Seperator *sep); void command_zone_instance(Client *c, const Seperator *sep); void command_zonebootup(Client *c, const Seperator *sep); -void command_zonelock(Client *c, const Seperator *sep); void command_zoneshutdown(Client *c, const Seperator *sep); void command_zopp(Client *c, const Seperator *sep); void command_zsafecoords(Client *c, const Seperator *sep); void command_zsave(Client *c, const Seperator *sep); -void command_zsky(Client *c, const Seperator *sep); -void command_zunderworld(Client *c, const Seperator *sep); #include "bot.h" void command_bot(Client*c, const Seperator *sep); diff --git a/zone/gm_commands/bind.cpp b/zone/gm_commands/bind.cpp deleted file mode 100755 index f90e131af..000000000 --- a/zone/gm_commands/bind.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "../client.h" - -void command_bind(Client *c, const Seperator *sep) -{ - Client *target = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); - } - - bool bind_allowed = ( - !zone->GetInstanceID() || - ( - zone->GetInstanceID() != 0 && - zone->IsInstancePersistent() - ) - ); - - if (!bind_allowed) { - c->Message(Chat::White, "You cannot bind here."); - return; - } - - target->SetBindPoint(); - - c->Message( - Chat::White, - fmt::format( - "Set Bind Point for {} | Zone: {}", - c->GetTargetDescription(target), - zone->GetZoneDescription() - ).c_str() - ); - - c->Message( - Chat::White, - fmt::format( - "Set Bind Point for {} | XYZ: {:.2f}, {:.2f}, {:.2f}", - c->GetTargetDescription(target), - target->GetX(), - target->GetY(), - target->GetZ() - ).c_str() - ); -} diff --git a/zone/gm_commands/date.cpp b/zone/gm_commands/date.cpp deleted file mode 100755 index 08cde4e60..000000000 --- a/zone/gm_commands/date.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "../client.h" - -void command_date(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if ( - !arguments || - !sep->IsNumber(1) || - !sep->IsNumber(2) || - !sep->IsNumber(3) - ) { - c->Message(Chat::White, "Usage: #date [Year] [Month] [Day] [Hour] [Minute]"); - return; - } - - TimeOfDay_Struct eq_time; - zone->zone_time.GetCurrentEQTimeOfDay(time(0), &eq_time); - - auto year = static_cast(Strings::ToUnsignedInt(sep->arg[1])); - auto month = static_cast(Strings::ToUnsignedInt(sep->arg[2])); - auto day = static_cast(Strings::ToUnsignedInt(sep->arg[3])); - - auto hour = !sep->IsNumber(4) ? eq_time.hour : static_cast(Strings::ToUnsignedInt(sep->arg[4]) + 1); - auto minute = !sep->IsNumber(5) ? eq_time.minute : static_cast(Strings::ToUnsignedInt(sep->arg[5])); - - c->Message( - Chat::White, - fmt::format("Setting world time to {}/{}/{} {:02}:{:02} {}.", - year, - month, - day, - ( - (hour % 12) == 0 ? - 12 : - (hour % 12) - ), - minute, - ( - hour >= 13 ? - "PM" : - "AM" - ) - ).c_str() - ); - - zone->SetDate(year, month, day, hour, minute); - - LogInfo( - "{} :: Setting world time to {}/{}/{} {:02}:{:02} {}.", - c->GetCleanName(), - year, - month, - day, - ( - (hour % 12) == 0 ? - 12 : - (hour % 12) - ), - minute, - ( - hour >= 13 ? - "PM" : - "AM" - ) - ); -} - diff --git a/zone/gm_commands/endurance.cpp b/zone/gm_commands/endurance.cpp deleted file mode 100755 index 7f113a949..000000000 --- a/zone/gm_commands/endurance.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "../client.h" - -void command_endurance(Client *c, const Seperator *sep) -{ - Mob* target = c; - if (c->GetTarget()) { - target = c->GetTarget(); - } - - int endurance = 0; - if (target->IsClient()) { - endurance = target->CastToClient()->GetMaxEndurance(); - target->CastToClient()->SetEndurance(endurance); - } else { - endurance = target->GetMaxEndurance(); - target->SetEndurance(endurance); - } - - c->Message( - Chat::White, - fmt::format( - "Set {} to full Endurance ({}).", - c->GetTargetDescription(target), - endurance - ).c_str() - ); -} - diff --git a/zone/gm_commands/faction.cpp b/zone/gm_commands/faction.cpp old mode 100755 new mode 100644 diff --git a/zone/gm_commands/find.cpp b/zone/gm_commands/find.cpp index 910c0a677..126de26b5 100644 --- a/zone/gm_commands/find.cpp +++ b/zone/gm_commands/find.cpp @@ -78,8 +78,19 @@ void command_find(Client *c, const Seperator *sep) // build the rewrite string std::string rewrite = fmt::format("#find {} {}", cmd.cmd, Strings::Join(args, " ")); - // rewrite to #find + // rewrite to #find > c->SendGMCommand(rewrite); + + c->Message( + Chat::Gray, + fmt::format( + "{} is now located under {}, using {}.", + sep->arg[0], + Saylink::Silent("#find"), + Saylink::Silent(rewrite) + ).c_str() + ); + return; } } diff --git a/zone/gm_commands/find/currency.cpp b/zone/gm_commands/find/currency.cpp index dde937824..c7b2f6b6a 100644 --- a/zone/gm_commands/find/currency.cpp +++ b/zone/gm_commands/find/currency.cpp @@ -2,7 +2,7 @@ void FindCurrency(Client *c, const Seperator *sep) { - const auto can_summon_items = c->Admin() >= GetCommandStatus(c, "summonitem"); + const auto can_summon_items = c->Admin() >= GetCommandStatus("summonitem"); if (sep->IsNumber(2)) { const auto item_id = Strings::ToUnsignedInt(sep->arg[2]); diff --git a/zone/gm_commands/find/item.cpp b/zone/gm_commands/find/item.cpp index a0400f521..aaea2638e 100644 --- a/zone/gm_commands/find/item.cpp +++ b/zone/gm_commands/find/item.cpp @@ -71,7 +71,11 @@ void FindItem(Client *c, const Seperator *sep) auto found_count = 0; for (const auto& e : l) { - const auto* item = database.GetItem(e); + const auto item = database.GetItem(e); + if (!item) { + continue; + } + std::string summon_links = Saylink::Silent( fmt::format( "#si {}", @@ -97,9 +101,10 @@ void FindItem(Client *c, const Seperator *sep) c->Message( Chat::White, fmt::format( - "{} | {}", + "{} | {} ({})", summon_links, - database.CreateItemLink(e) + database.CreateItemLink(e), + Strings::Commify(item->ID) ).c_str() ); diff --git a/zone/gm_commands/find/npctype.cpp b/zone/gm_commands/find/npctype.cpp index bf8fc95d6..a25bce0f0 100644 --- a/zone/gm_commands/find/npctype.cpp +++ b/zone/gm_commands/find/npctype.cpp @@ -33,7 +33,7 @@ void FindNPCType(Client *c, const Seperator *sep) return; } - const auto can_spawn_npcs = c->Admin() >= GetCommandStatus(c, "#npctypespawn"); + const auto can_spawn_npcs = c->Admin() >= GetCommandStatus("#npctypespawn"); auto found_count = 0; diff --git a/zone/gm_commands/find/recipe.cpp b/zone/gm_commands/find/recipe.cpp index 2a675dc26..0d8b18951 100644 --- a/zone/gm_commands/find/recipe.cpp +++ b/zone/gm_commands/find/recipe.cpp @@ -4,7 +4,7 @@ void FindRecipe(Client *c, const Seperator *sep) { - const auto can_view_recipes = c->Admin() >= GetCommandStatus(c, "viewrecipe"); + const auto can_view_recipes = c->Admin() >= GetCommandStatus("viewrecipe"); if (sep->IsNumber(2)) { const auto recipe_id = static_cast(Strings::ToUnsignedInt(sep->arg[2])); diff --git a/zone/gm_commands/find/spell.cpp b/zone/gm_commands/find/spell.cpp index 5aa157cbc..58887f67a 100644 --- a/zone/gm_commands/find/spell.cpp +++ b/zone/gm_commands/find/spell.cpp @@ -7,7 +7,7 @@ void FindSpell(Client *c, const Seperator *sep) return; } - const auto can_cast_spells = c->Admin() >= GetCommandStatus(c, "castspell"); + const auto can_cast_spells = c->Admin() >= GetCommandStatus("castspell"); if (sep->IsNumber(2)) { const auto spell_id = Strings::ToUnsignedInt(sep->arg[2]); diff --git a/zone/gm_commands/find/task.cpp b/zone/gm_commands/find/task.cpp index dd38433ca..3fea5a591 100644 --- a/zone/gm_commands/find/task.cpp +++ b/zone/gm_commands/find/task.cpp @@ -7,7 +7,7 @@ void FindTask(Client *c, const Seperator *sep) return; } - const auto can_assign_tasks = c->Admin() >= GetCommandStatus(c, "task"); + const auto can_assign_tasks = c->Admin() >= GetCommandStatus("task"); if (sep->IsNumber(2)) { const auto task_id = Strings::ToUnsignedInt(sep->arg[2]); diff --git a/zone/gm_commands/find/zone.cpp b/zone/gm_commands/find/zone.cpp index 92cb55968..74e6e35de 100644 --- a/zone/gm_commands/find/zone.cpp +++ b/zone/gm_commands/find/zone.cpp @@ -19,7 +19,7 @@ void FindZone(Client *c, const Seperator *sep) ); search_string = Expansion::ExpansionName[Strings::ToInt(sep->arg[3])]; - search_type = "Expansion"; + search_type = "expansion"; } else if (is_id_search) { query += fmt::format( "zoneidnumber = {}", @@ -27,7 +27,7 @@ void FindZone(Client *c, const Seperator *sep) ); search_string = sep->arg[2]; - search_type = "Expansion"; + search_type = "ID"; } else if (is_short_name_search) { query += fmt::format( "LOWER(`long_name`) LIKE '%%{}%%' OR LOWER(`short_name`) LIKE '%%{}%%'", @@ -36,7 +36,7 @@ void FindZone(Client *c, const Seperator *sep) ); search_string = sep->argplus[2]; - search_type = "Expansion"; + search_type = "name"; } query += " ORDER BY `zoneidnumber` ASC LIMIT 50"; diff --git a/zone/gm_commands/flag.cpp b/zone/gm_commands/flag.cpp deleted file mode 100755 index 12135fbe3..000000000 --- a/zone/gm_commands/flag.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include "../client.h" -#include "../worldserver.h" - -extern WorldServer worldserver; - -void command_flag(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments) { - auto target = c->GetTarget() && c->GetTarget()->IsClient() ? c->GetTarget()->CastToClient() : c; - if (target != c) { - c->Message( - Chat::White, - fmt::format( - "Status level has been refreshed for {}.", - target->GetCleanName() - ).c_str() - ); - - target->Message( - Chat::White, - fmt::format( - "Your status level has been refreshed by {}.", - c->GetCleanName() - ).c_str() - ); - } else { - c->Message(Chat::White, "Your status level has been refreshed."); - } - target->UpdateAdmin(); - return; - } - - - if ( - !sep->IsNumber(1) || - strlen(sep->arg[2]) == 0 - ) { - c->Message(Chat::White, "Usage: #flag [Status] [Account Name]"); - return; - } - - auto status = Strings::ToInt(sep->arg[1]); - if (status < -2 || status > 255) { - c->Message(Chat::White, "The lowest a status level can go is -2 and the highest a status level can go is 255."); - return; - } - - std::string account_name = sep->argplus[2]; - auto account_id = database.GetAccountIDByChar(account_name.c_str()); - - if (c->Admin() < commandChangeFlags) { //this check makes banning players by less than this level impossible, but i'll leave it in anyways - c->Message(Chat::White, "You may only refresh your own flag, doing so now."); - c->UpdateAdmin(); - } else { - if (status > c->Admin()) { - c->Message( - Chat::White, - fmt::format( - "You cannot set someone's status level to {} because your status level is only {}.", - status, - c->Admin() - ).c_str() - ); - } else if (status < 0 && c->Admin() < commandBanPlayers) { - c->Message(Chat::White, "Your status level is not high enough to ban or suspend."); - } else if (!database.SetAccountStatus(account_name, status)) { - c->Message(Chat::White, "Failed to set status level."); - } - else { - c->Message(Chat::White, "Set GM Flag on account."); - - std::string user; - std::string loginserver; - ParseAccountString(account_name, user, loginserver); - - account_id = database.GetAccountIDByName(account_name, loginserver); - - ServerPacket pack(ServerOP_FlagUpdate, sizeof(ServerFlagUpdate_Struct)); - ServerFlagUpdate_Struct *sfus = (ServerFlagUpdate_Struct *) pack.pBuffer; - sfus->account_id = account_id; - sfus->admin = status; - worldserver.SendPacket(&pack); - } - } -} - diff --git a/zone/gm_commands/flymode.cpp b/zone/gm_commands/flymode.cpp deleted file mode 100755 index 46ebc40b9..000000000 --- a/zone/gm_commands/flymode.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "../client.h" -#include "../../common/data_verification.h" - -void command_flymode(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1)) { - return; - } - - Mob *target = c; - if (c->GetTarget()) { - target = c->GetTarget(); - } - - auto flymode_id = Strings::ToUnsignedInt(sep->arg[1]); - if (!EQ::ValueWithin(flymode_id, EQ::constants::GravityBehavior::Ground, EQ::constants::GravityBehavior::LevitateWhileRunning)) { - c->Message(Chat::White, "Usage:: #flymode [Flymode ID]"); - c->Message(Chat::White, "0 = Ground, 1 = Flying, 2 = Levitating, 3 = Water, 4 = Floating, 5 = Levitating While Running"); - return; - } - - target->SetFlyMode(static_cast(flymode_id)); - target->SendAppearancePacket(AT_Levitate, flymode_id); - uint32 account = c->AccountID(); - database.SetGMFlymode(account, flymode_id); - c->Message( - Chat::White, - fmt::format( - "Fly Mode for {} is now {} ({}).", - c->GetTargetDescription(target), - EQ::constants::GetFlyModeName(flymode_id), - flymode_id - ).c_str() - ); -} - - diff --git a/zone/gm_commands/freeze.cpp b/zone/gm_commands/freeze.cpp deleted file mode 100755 index 0b002b124..000000000 --- a/zone/gm_commands/freeze.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "../client.h" - -void command_freeze(Client *c, const Seperator *sep) -{ - if (!c->GetTarget()) { - c->Message(Chat::White, "You must have a target to use this command."); - return; - } - - auto target = c->GetTarget(); - if (c == target) { - c->Message(Chat::White, "You cannot freeze yourself."); - return; - } - - target->SendAppearancePacket(AT_Anim, ANIM_FREEZE); - - c->Message( - Chat::White, - fmt::format( - "You have frozen {}.", - c->GetTargetDescription(target) - ).c_str() - ); -} - diff --git a/zone/gm_commands/gassign.cpp b/zone/gm_commands/gassign.cpp deleted file mode 100755 index 4c4b61aa9..000000000 --- a/zone/gm_commands/gassign.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "../client.h" - -void command_gassign(Client *c, const Seperator *sep) -{ - if (!c->GetTarget() || !c->GetTarget()->IsNPC()) { - c->Message(Chat::White, "You must target an NPC to use this command."); - return; - } - - int arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1)) { - c->Message(Chat::White, "Usage: #gassign [Grid ID]"); - return; - } - - auto grid_id = Strings::ToUnsignedInt(sep->arg[1]); - - auto target = c->GetTarget()->CastToNPC(); - if (target->GetSpawnPointID() > 0) { - database.AssignGrid(c, grid_id, target->GetID()); - } -} - diff --git a/zone/gm_commands/gender.cpp b/zone/gm_commands/gender.cpp deleted file mode 100755 index 42e7396c4..000000000 --- a/zone/gm_commands/gender.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "../client.h" - -void command_gender(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1)) { - c->Message(Chat::White, "Usage: #gender [Gender ID]"); - c->Message(Chat::White, "Genders: 0 = Male, 1 = Female, 2 = Neuter"); - return; - } - - Mob *target = c; - if (c->GetTarget() && c->Admin() >= commandGenderOthers) { - target = c->GetTarget(); - } - - auto gender_id = Strings::ToInt(sep->arg[1]); - if (gender_id < 0 || gender_id > 2) { - c->Message(Chat::White, "Usage: #gender [Gender ID]"); - c->Message(Chat::White, "Genders: 0 = Male, 1 = Female, 2 = Neuter"); - return; - } - - target->SendIllusionPacket( - target->GetRace(), - gender_id - ); - - c->Message( - Chat::White, - fmt::format( - "Gender changed for {} to {} ({}).", - c->GetTargetDescription(target), - GetGenderName(gender_id), - gender_id - ).c_str() - ); -} diff --git a/zone/gm_commands/gm.cpp b/zone/gm_commands/gm.cpp deleted file mode 100755 index fb5560b74..000000000 --- a/zone/gm_commands/gm.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "../client.h" - -void command_gm(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments) { - c->Message(Chat::White, "Usage: #gm [On|Off]"); - return; - } - - bool gm_flag = atobool(sep->arg[1]); - Client *target = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); - } - - target->SetGM(gm_flag); - if (c != target) { - c->Message( - Chat::White, - fmt::format( - "{} is {} flagged as a GM.", - c->GetTargetDescription(target), - gm_flag ? "now" : "no longer" - ).c_str() - ); - } -} diff --git a/zone/gm_commands/gmspeed.cpp b/zone/gm_commands/gmspeed.cpp deleted file mode 100755 index 627082c74..000000000 --- a/zone/gm_commands/gmspeed.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "../client.h" - -void command_gmspeed(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments) { - c->Message(Chat::White, "Usage: #gmspeed [On|Off]"); - return; - } - - bool gm_speed_flag = atobool(sep->arg[1]); - Client *target = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); - } - - database.SetGMSpeed( - target->AccountID(), - gm_speed_flag ? 1 : 0 - ); - - c->Message( - Chat::White, - fmt::format( - "Turning GM Speed {} for {}.", - gm_speed_flag ? "on" : "off", - c->GetTargetDescription(target) - ).c_str() - ); - - c->Message( - Chat::White, - fmt::format( - "Note: {} must zone for it to take effect.", - c->GetTargetDescription(target, TargetDescriptionType::UCYou) - ).c_str() - ); -} - diff --git a/zone/gm_commands/godmode.cpp b/zone/gm_commands/godmode.cpp deleted file mode 100644 index 81ecbe93d..000000000 --- a/zone/gm_commands/godmode.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "../client.h" -#include "../../common/repositories/account_repository.h" - -void command_godmode(Client *c, const Seperator *sep) -{ - bool state = atobool(sep->arg[1]); - uint32 account_id = c->AccountID(); - - if (sep->arg[1][0] != 0) { - auto a = AccountRepository::FindOne(database, c->AccountID()); - if (a.id > 0) { - a.flymode = state ? 1 : 0; - a.gmspeed = state ? 1 : 0; - a.invulnerable = state ? 1 : 0; - a.hideme = state ? 1 : 0; - } - - c->SetInvul(state); - c->SendAppearancePacket(AT_Levitate, state); - c->SetHideMe(state); - c->Message( - Chat::White, - "Turning GodMode %s for %s (zone for gmspeed to take effect)", - state ? "On" : "Off", - c->GetName() - ); - - AccountRepository::UpdateOne(database, a); - } - else { - c->Message(Chat::White, "Usage: #godmode [on/off]"); - } -} diff --git a/zone/gm_commands/heal.cpp b/zone/gm_commands/heal.cpp deleted file mode 100755 index 904cf4baf..000000000 --- a/zone/gm_commands/heal.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "../client.h" - -void command_heal(Client *c, const Seperator *sep) -{ - Mob* target = c; - if (c->GetTarget()) { - target = c->GetTarget(); - } - - target->Heal(); - - c->Message( - Chat::White, - fmt::format( - "Set {} to full Health ({}).", - c->GetTargetDescription(target), - target->GetMaxHP() - ).c_str() - ); -} - diff --git a/zone/gm_commands/heromodel.cpp b/zone/gm_commands/heromodel.cpp deleted file mode 100755 index f6c35b142..000000000 --- a/zone/gm_commands/heromodel.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "../client.h" - -void command_heromodel(Client *c, const Seperator *sep) -{ - auto arguments = sep->argnum; - if (!arguments) { - c->Message(Chat::White, "Usage: #heromodel [Hero Model]"); - c->Message(Chat::White, "Usage: #heromodel [Hero Model] [Slot]"); - c->Message( - Chat::White, - fmt::format( - "Example: {}", - Saylink::Silent("#heromodel 63") - ).c_str() - ); - return; - } - - Mob* t = c; - if (c->GetTarget()) { - t = c->GetTarget(); - } - - auto hero_forge_model = Strings::IsNumber(sep->arg[1]) ? Strings::ToUnsignedInt(sep->arg[1]) : 0; - - if (arguments > 1) { - auto slot = static_cast(Strings::ToUnsignedInt(sep->arg[2])); - c->GetTarget()->SendTextureWC(slot, 0, hero_forge_model, 0, 0, 0); - } else { - if (hero_forge_model) { - // Conversion to simplify the command arguments - // Hero's Forge model is actually model * 1000 + texture * 100 + wearslot - // Hero's Forge Model slot 7 is actually for Robes, but it still needs to use wearslot 1 in the packet - hero_forge_model *= 100; - - for (uint8 slot = 0; slot < 7; slot++) { - c->GetTarget()->SendTextureWC(slot, 0, (hero_forge_model + slot), 0, 0, 0); - } - } else { - c->Message(Chat::White, "Hero's Forge Model must be greater than 0."); - } - } -} - diff --git a/zone/gm_commands/incstat.cpp b/zone/gm_commands/incstat.cpp deleted file mode 100755 index 14ad4a235..000000000 --- a/zone/gm_commands/incstat.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "../client.h" - -void command_incstat(Client *c, const Seperator *sep) -{ - if (sep->arg[1][0] && sep->arg[2][0] && c->GetTarget() != 0 && c->GetTarget()->IsClient()) { - c->GetTarget()->CastToClient()->IncStats(Strings::ToInt(sep->arg[1]), Strings::ToInt(sep->arg[2])); - } - else { - c->Message(Chat::White, "This command is used to permanently increase or decrease a players stats."); - c->Message(Chat::White, "Usage: #setstat {type} {value by which to increase or decrease}"); - c->Message( - Chat::White, - "Note: The value is in increments of 2, so a value of 3 will actually increase the stat by 6" - ); - c->Message(Chat::White, "Types: Str: 0, Sta: 1, Agi: 2, Dex: 3, Int: 4, Wis: 5, Cha: 6"); - } -} - diff --git a/zone/gm_commands/invul.cpp b/zone/gm_commands/invul.cpp deleted file mode 100755 index 398cd5174..000000000 --- a/zone/gm_commands/invul.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "../client.h" - -void command_invul(Client *c, const Seperator *sep) { - int arguments = sep->argnum; - if (!arguments) { - c->Message(Chat::White, "Usage: #invul [On|Off]"); - return; - } - - bool invul_flag = atobool(sep->arg[1]); - Client *target = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); - } - - target->SetInvul(invul_flag); - uint32 account = target->AccountID(); - database.SetGMInvul(account, invul_flag); - c->Message( - Chat::White, - fmt::format( - "{} {} now {}.", - c->GetTargetDescription(target, TargetDescriptionType::UCYou), - c == target ? "are" : "is", - invul_flag ? "invulnerable" : "vulnerable" - ).c_str() - ); -} diff --git a/zone/gm_commands/lastname.cpp b/zone/gm_commands/lastname.cpp deleted file mode 100755 index 070f5023a..000000000 --- a/zone/gm_commands/lastname.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "../client.h" - -void command_lastname(Client *c, const Seperator *sep) -{ - Client *target = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); - } - - LogInfo("#lastname request from [{}] for [{}]", c->GetCleanName(), target->GetCleanName()); - - bool is_remove = !strcasecmp(sep->argplus[1], "-1"); - std::string last_name = is_remove ? "" : sep->argplus[1]; - - if (last_name.size() > 64) { - c->Message(Chat::White, "Last name must be 64 characters or less."); - return; - } - - target->ChangeLastName(last_name); - - c->Message( - Chat::White, - fmt::format( - "Last name has been {}{} for {}{}", - is_remove ? "removed" : "changed", - !is_remove ? " and saved" : "", - c->GetTargetDescription(target), - ( - is_remove ? - "." : - fmt::format( - " to '{}'.", - last_name - ) - ) - ).c_str() - ); -} - diff --git a/zone/gm_commands/level.cpp b/zone/gm_commands/level.cpp deleted file mode 100644 index 37f6a4bb2..000000000 --- a/zone/gm_commands/level.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "../client.h" - -void command_level(Client *c, const Seperator *sep) -{ - const auto arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1)) { - c->Message(Chat::White, "Usage: #level [Level]"); - return; - } - - Mob* t = c; - if (c->GetTarget()) { - t = c->GetTarget(); - } - - auto level = static_cast(Strings::ToUnsignedInt(sep->arg[1])); - auto max_level = static_cast(RuleI(Character, MaxLevel)); - - if (c != t && c->Admin() < RuleI(GM, MinStatusToLevelTarget)) { - c->Message(Chat::White, "Your status is not high enough to change another person's level."); - return; - } - - if ( - level > max_level && - c->Admin() < commandLevelAboveCap - ) { - c->Message( - Chat::White, - fmt::format( - "Level {} is above the Maximum Level of {} and your status is not high enough to go beyond the cap.", - level, - max_level - ).c_str() - ); - return; - } - - t->SetLevel(level, true); - if (t->IsClient()) { - t->CastToClient()->SendLevelAppearance(); - - if (RuleB(Bots, Enabled) && RuleB(Bots, BotLevelsWithOwner)) { - Bot::LevelBotWithClient(t->CastToClient(), level, true); - } - } -} diff --git a/zone/gm_commands/mana.cpp b/zone/gm_commands/mana.cpp deleted file mode 100755 index 8808a568e..000000000 --- a/zone/gm_commands/mana.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "../client.h" - -void command_mana(Client *c, const Seperator *sep) -{ - auto target = c->GetTarget() ? c->GetTarget() : c; - int mana = 0; - if (target->IsClient()) { - mana = target->CastToClient()->CalcMaxMana(); - target->CastToClient()->SetMana(mana); - } - else { - mana = target->CalcMaxMana(); - target->SetMana(mana); - } - - c->Message( - Chat::White, - fmt::format( - "Set {} to full Mana ({}).", - c->GetTargetDescription(target), - mana - ).c_str() - ); -} - diff --git a/zone/gm_commands/name.cpp b/zone/gm_commands/name.cpp deleted file mode 100755 index 58dda8e75..000000000 --- a/zone/gm_commands/name.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include "../client.h" - -void command_name(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments) { - c->Message(Chat::White, "Usage: #name [New Name] - Rename your player target"); - return; - } - - if (c->GetTarget() && c->GetTarget()->IsClient()) { - auto target = c->GetTarget()->CastToClient(); - - std::string new_name = sep->arg[1]; - std::string old_name = target->GetCleanName(); - - if (target->ChangeFirstName(new_name.c_str(), c->GetCleanName())) { - c->Message( - Chat::White, - fmt::format( - "Successfully renamed {} to {}", - old_name, - new_name - ).c_str() - ); - - c->Message(Chat::White, "Sending player to char select."); - - target->Kick("Name was changed"); - } else { - c->Message( - Chat::White, - fmt::format( - "Unable to rename {}. Check that the new name '{}' isn't already taken.", - old_name, - new_name - ).c_str() - ); - } - } -} - diff --git a/zone/gm_commands/permaclass.cpp b/zone/gm_commands/permaclass.cpp deleted file mode 100755 index 1c8d9924f..000000000 --- a/zone/gm_commands/permaclass.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "../client.h" - -void command_permaclass(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1)) { - c->Message(Chat::White, "Usage: #permaclass [Class ID]"); - return; - } - - Client *target = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); - } - - auto class_id = Strings::ToInt(sep->arg[1]); - - LogInfo("Class changed by {} for {} to {} ({})", - c->GetCleanName(), - c->GetTargetDescription(target), - GetClassIDName(class_id), - class_id - ); - - target->SetBaseClass(class_id); - target->Save(); - target->Kick("Class was changed."); - - if (c != target) { - c->Message( - Chat::White, - fmt::format( - "Class changed for {} to {} ({}).", - c->GetTargetDescription(target), - GetClassIDName(class_id), - class_id - ).c_str() - ); - } -} diff --git a/zone/gm_commands/permagender.cpp b/zone/gm_commands/permagender.cpp deleted file mode 100755 index a23cbce95..000000000 --- a/zone/gm_commands/permagender.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "../client.h" - -void command_permagender(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1)) { - c->Message(Chat::White, "Usage: #permagender [Gender ID]"); - c->Message(Chat::White, "Genders: 0 = Male, 1 = Female, 2 = Neuter"); - return; - } - - Client *target = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); - } - - auto gender_id = Strings::ToInt(sep->arg[1]); - if (gender_id < 0 || gender_id > 2) { - c->Message(Chat::White, "Usage: #permagender [Gender ID]"); - c->Message(Chat::White, "Genders: 0 = Male, 1 = Female, 2 = Neuter"); - return; - } - - LogInfo("Gender changed by {} for {} to {} ({})", - c->GetCleanName(), - c->GetTargetDescription(target), - GetGenderName(gender_id), - gender_id - ); - - target->SetBaseGender(gender_id); - target->Save(); - target->SendIllusionPacket(target->GetRace(), gender_id); - - c->Message( - Chat::White, - fmt::format( - "Gender changed for {} to {} ({}).", - c->GetTargetDescription(target), - GetGenderName(gender_id), - gender_id - ).c_str() - ); -} diff --git a/zone/gm_commands/permarace.cpp b/zone/gm_commands/permarace.cpp deleted file mode 100755 index 2595e1838..000000000 --- a/zone/gm_commands/permarace.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "../client.h" - -void command_permarace(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1)) { - c->Message(Chat::White, "Usage: #permarace [Race ID]"); - c->Message( - Chat::White, - "NOTE: Not all models are global. If a model is not global, it will appear as a human on character select and in zones without the model." - ); - return; - } - - Client *target = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); - } - - auto race_id = Strings::ToInt(sep->arg[1]); - auto gender_id = Mob::GetDefaultGender(race_id, target->GetBaseGender()); - - LogInfo("Race changed by {} for {} to {} ({})", - c->GetCleanName(), - c->GetTargetDescription(target), - GetRaceIDName(race_id), - race_id - ); - - target->SetBaseRace(race_id); - target->SetBaseGender(gender_id); - target->Save(); - target->SendIllusionPacket(race_id, gender_id); - - c->Message( - Chat::White, - fmt::format( - "Race changed for {} to {} ({}).", - c->GetTargetDescription(target), - GetRaceIDName(race_id), - race_id - ).c_str() - ); -} diff --git a/zone/gm_commands/pvp.cpp b/zone/gm_commands/pvp.cpp deleted file mode 100755 index ed9992b10..000000000 --- a/zone/gm_commands/pvp.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "../client.h" - -void command_pvp(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments) { - c->Message(Chat::White, "Usage: #pvp [On|Off]"); - return; - } - - bool pvp_state = atobool(sep->arg[1]); - Client* target = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); - } - - target->SetPVP(pvp_state); - if (c != target) { - c->Message( - Chat::White, - fmt::format( - "{} now follow{} the ways of {}.", - c->GetTargetDescription(target, TargetDescriptionType::UCYou), - c != target ? "s" : "", - pvp_state ? "Discord" : "Order" - ).c_str() - ); - } -} diff --git a/zone/gm_commands/qglobal.cpp b/zone/gm_commands/qglobal.cpp deleted file mode 100755 index e065b23ff..000000000 --- a/zone/gm_commands/qglobal.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include "../client.h" - -void command_qglobal(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments) { - c->Message(Chat::White, "Usage: #qglobal on - Enables target NPC's ability to view quest globals"); - c->Message(Chat::White, "Usage: #qglobal off - Disables target NPC's ability to view quest globals"); - c->Message(Chat::White, "Usage: #qglobal view - View target NPC's ability to view quest globals"); - return; - } - - - if (!c->GetTarget() || !c->GetTarget()->IsNPC()) { - c->Message(Chat::White, "You must target an NPC to use this command."); - return; - } - - auto target = c->GetTarget()->CastToNPC(); - - bool is_off = !strcasecmp(sep->arg[1], "off"); - bool is_on = !strcasecmp(sep->arg[1], "on"); - bool is_view = !strcasecmp(sep->arg[1], "view"); - if ( - !is_off && - !is_on && - !is_view - ) { - c->Message(Chat::White, "Usage: #qglobal on - Enables target NPC's ability to view quest globals"); - c->Message(Chat::White, "Usage: #qglobal off - Disables target NPC's ability to view quest globals"); - c->Message(Chat::White, "Usage: #qglobal view - View target NPC's ability to view quest globals"); - return; - } - - if (is_off) { - auto query = fmt::format( - "UPDATE npc_types SET qglobal = 0 WHERE id = {}", - target->GetNPCTypeID() - ); - auto results = content_db.QueryDatabase(query); - - if (!results.Success()) { - c->Message( - Chat::White, - fmt::format( - "Failed to disable quest global flag for {}.", - c->GetTargetDescription(target) - ).c_str() - ); - return; - } - - auto repop_link = Saylink::Silent("#repop", "repop"); - - c->Message( - Chat::White, - fmt::format( - "{} will no longer be able to view quest globals, {} them to apply this change.", - c->GetTargetDescription(target), - repop_link - ).c_str() - ); - return; - } else if (is_on) { - auto query = fmt::format( - "UPDATE npc_types SET qglobal = 1 WHERE id = {}", - target->GetNPCTypeID() - ); - auto results = content_db.QueryDatabase(query); - - if (!results.Success()) { - c->Message( - Chat::White, - fmt::format( - "Failed to enable quest global flag for {}.", - c->GetTargetDescription(target) - ).c_str() - ); - return; - } - - auto repop_link = Saylink::Silent("#repop", "repop"); - - c->Message( - Chat::White, - fmt::format( - "{} will now be able to view quest globals, {} them to apply this change.", - c->GetTargetDescription(target), - repop_link - ).c_str() - ); - return; - } else if (!strcasecmp(sep->arg[1], "view")) { - const NPCType *npc_type = content_db.LoadNPCTypesData(target->GetNPCTypeID()); - if (!npc_type) { - c->Message( - Chat::White, - fmt::format( - "NPC ID {} was not found.", - target->GetNPCTypeID() - ).c_str() - ); - return; - } - - c->Message( - Chat::White, - fmt::format( - "{} {} view quest globals.", - c->GetTargetDescription(target), - npc_type->qglobal ? "can" : "cannot" - ).c_str() - ); - } -} - diff --git a/zone/gm_commands/race.cpp b/zone/gm_commands/race.cpp deleted file mode 100755 index cc3b51888..000000000 --- a/zone/gm_commands/race.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "../client.h" - -void command_race(Client *c, const Seperator *sep) -{ - Mob *target = c->CastToMob(); - - if (sep->IsNumber(1)) { - auto race = Strings::ToInt(sep->arg[1]); - if ((race >= 0 && race <= RuleI(NPC, MaxRaceID)) || (race >= 2253 && race <= 2259)) { - if ((c->GetTarget()) && c->Admin() >= commandRaceOthers) { - target = c->GetTarget(); - } - target->SendIllusionPacket(race); - } - else { - c->Message( - Chat::White, - fmt::format( - "Usage: #race [0-{}, 2253-2259] (0 for back to normal)", - RuleI(NPC, MaxRaceID)).c_str()); - } - } - else { - c->Message( - Chat::White, - fmt::format("Usage: #race [0-{}, 2253-2259] (0 for back to normal)", RuleI(NPC, MaxRaceID)).c_str()); - } -} - diff --git a/zone/gm_commands/serverlock.cpp b/zone/gm_commands/serverlock.cpp deleted file mode 100644 index cd2c38ff9..000000000 --- a/zone/gm_commands/serverlock.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "../client.h" -#include "../worldserver.h" - -extern WorldServer worldserver; - -void command_serverlock(Client *c, const Seperator *sep) -{ - if (!sep->IsNumber(1)) { - c->Message(Chat::White, "Usage: #serverlock [0|1] - Lock or Unlock the World Server (0 = Unlocked, 1 = Locked)"); - return; - } - - auto is_locked = Strings::ToInt(sep->arg[1]) ? true : false; - - auto pack = new ServerPacket(ServerOP_Lock, sizeof(ServerLock_Struct)); - auto l = (ServerLock_Struct *) pack->pBuffer; - strn0cpy(l->character_name, c->GetCleanName(), sizeof(l->character_name)); - l->is_locked = is_locked; - worldserver.SendPacket(pack); - safe_delete(pack); -} - diff --git a/zone/gm_commands/set.cpp b/zone/gm_commands/set.cpp new file mode 100644 index 000000000..6a345a0d4 --- /dev/null +++ b/zone/gm_commands/set.cpp @@ -0,0 +1,174 @@ +#include "../client.h" +#include "set/aa_exp.cpp" +#include "set/aa_points.cpp" +#include "set/adventure_points.cpp" +#include "set/alternate_currency.cpp" +#include "set/animation.cpp" +#include "set/anon.cpp" +#include "set/bind_point.cpp" +#include "set/checksum.cpp" +#include "set/class_permanent.cpp" +#include "set/crystals.cpp" +#include "set/date.cpp" +#include "set/endurance.cpp" +#include "set/endurance_full.cpp" +#include "set/exp.cpp" +#include "set/flymode.cpp" +#include "set/frozen.cpp" +#include "set/gender.cpp" +#include "set/gender_permanent.cpp" +#include "set/gm.cpp" +#include "set/gm_speed.cpp" +#include "set/gm_status.cpp" +#include "set/god_mode.cpp" +#include "set/haste.cpp" +#include "set/hero_model.cpp" +#include "set/hide_me.cpp" +#include "set/hp.cpp" +#include "set/hp_full.cpp" +#include "set/invulnerable.cpp" +#include "set/language.cpp" +#include "set/last_name.cpp" +#include "set/level.cpp" +#include "set/loginserver_info.cpp" +#include "set/mana.cpp" +#include "set/mana_full.cpp" +#include "set/name.cpp" +#include "set/ooc_mute.cpp" +#include "set/password.cpp" +#include "set/pvp.cpp" +#include "set/pvp_points.cpp" +#include "set/race.cpp" +#include "set/race_permanent.cpp" +#include "set/server_locked.cpp" +#include "set/skill.cpp" +#include "set/skill_all.cpp" +#include "set/skill_all_max.cpp" +#include "set/start_zone.cpp" +#include "set/temporary_name.cpp" +#include "set/texture.cpp" +#include "set/time.cpp" +#include "set/time_zone.cpp" +#include "set/title.cpp" +#include "set/title_suffix.cpp" +#include "set/weather.cpp" +#include "set/zone.cpp" + +void command_set(Client *c, const Seperator *sep) +{ + struct Cmd { + std::string cmd{}; // command + std::string u{}; // usage + void (*fn)(Client *c, const Seperator *sep) = nullptr; // function + std::vector a{}; // aliases + }; + + std::vector commands = { + Cmd{.cmd = "aa_exp", .u = "aa_exp [aa|group|raid] [Amount]", .fn = SetAAEXP, .a = {"#setaaxp"}}, + Cmd{.cmd = "aa_points", .u = "aa_points [aa|group|raid] [Amount]", .fn = SetAAPoints, .a = {"#setaapts"}}, + Cmd{.cmd = "adventure_points", .u = "adventure_points [Theme ID] [Amount]", .fn = SetAdventurePoints, .a = {"#set_adventure_points"}}, + Cmd{.cmd = "alternate_currency", .u = "alternate_currency [Currency ID] [Amount]", .fn = SetAlternateCurrency, .a = {"#setaltcurrency"}}, + Cmd{.cmd = "animation", .u = "animation [Animation ID]", .fn = SetAnimation, .a = {"#setanim"}}, + Cmd{.cmd = "anon", .u = "anon [Character ID] [Anonymous Flag] or #set anon [Anonymous Flag]", .fn = SetAnon, .a = {"#setanon"}}, + Cmd{.cmd = "bind_point", .u = "bind_point", .fn = SetBindPoint, .a = {"#setbind"}}, + Cmd{.cmd = "checksum", .u = "checksum", .fn = SetChecksum, .a = {"#updatechecksum"}}, + Cmd{.cmd = "class_permanent", .u = "class_permanent [Class ID]", .fn = SetClassPermanent, .a = {"#permaclass"}}, + Cmd{.cmd = "crystals", .u = "crystals [ebon|radiant] [Amount]", .fn = SetCrystals, .a = {"#setcrystals"}}, + Cmd{.cmd = "date", .u = "date [Year] [Month] [Day] [Hour] [Minute] (Hour and Minute are optional)", .fn = SetDate, .a = {"#date"}}, + Cmd{.cmd = "endurance", .u = "endurance [Amount]", .fn = SetEndurance, .a = {"#setendurance"}}, + Cmd{.cmd = "endurance_full", .u = "endurance_full", .fn = SetEnduranceFull, .a = {"#endurance"}}, + Cmd{.cmd = "exp", .u = "exp [aa|exp] [Amount]", .fn = SetEXP, .a = {"#setxp"}}, + Cmd{.cmd = "flymode", .u = "flymode [Flymode ID]", .fn = SetFlymode, .a = {"#flymode"}}, + Cmd{.cmd = "frozen", .u = "frozen [on|off]", .fn = SetFrozen, .a = {"#freeze", "#unfreeze"}}, + Cmd{.cmd = "gender", .u = "gender [Gender ID]", .fn = SetGender, .a = {"#gender"}}, + Cmd{.cmd = "gender_permanent", .u = "gender_permanent [Gender ID]", .fn = SetGenderPermanent, .a = {"#permagender"}}, + Cmd{.cmd = "gm", .u = "gm [on|off]", .fn = SetGM, .a = {"#flymode"}}, + Cmd{.cmd = "gm_speed", .u = "gm_speed [on|off]", .fn = SetGMSpeed, .a = {"#gmspeed"}}, + Cmd{.cmd = "gm_status", .u = "gm_status [GM Status] [Account]", .fn = SetGMStatus, .a = {"#flag"}}, + Cmd{.cmd = "god_mode", .u = "god_mode [on|off]", .fn = SetGodMode, .a = {"#godmode"}}, + Cmd{.cmd = "haste", .u = "haste [Percentage]", .fn = SetHaste, .a = {"#haste"}}, + Cmd{.cmd = "hide_me", .u = "hide_me [on|off]", .fn = SetHideMe, .a = {"#hideme"}}, + Cmd{.cmd = "hero_model", .u = "hero_model [Hero Model] [Slot] (Slot is optional)", .fn = SetHeroModel, .a = {"#heromodel"}}, + Cmd{.cmd = "hp", .u = "hp [Amount]", .fn = SetHP, .a = {"#sethp"}}, + Cmd{.cmd = "hp_full", .u = "hp_full", .fn = SetHPFull, .a = {"#heal"}}, + Cmd{.cmd = "invulnerable", .u = "invulnerable", .fn = SetInvulnerable, .a = {"#invul"}}, + Cmd{.cmd = "language", .u = "language [Language ID] [Language Level]", .fn = SetLanguage, .a = {"#setlanguage"}}, + Cmd{.cmd = "last_name", .u = "last_name [Last Name]", .fn = SetLastName, .a = {"#lastname"}}, + Cmd{.cmd = "level", .u = "level [Level]", .fn = SetLevel, .a = {"#level"}}, + Cmd{.cmd = "loginserver_info", .u = "loginserver_info [Email] [Password]", .fn = SetLoginserverInfo, .a = {"#setlsinfo"}}, + Cmd{.cmd = "mana", .u = "mana [Amount]", .fn = SetMana, .a = {"#setmana"}}, + Cmd{.cmd = "mana_full", .u = "mana_full", .fn = SetManaFull, .a = {"#mana"}}, + Cmd{.cmd = "name", .u = "name", .fn = SetName, .a = {"#name"}}, + Cmd{.cmd = "ooc_mute", .u = "ooc_mute", .fn = SetOOCMute, .a = {"#oocmute"}}, + Cmd{.cmd = "password", .u = "password [Account Name] [Password] (account table password)", .fn = SetPassword, .a = {"#setpass"}}, + Cmd{.cmd = "pvp", .u = "pvp [on|off]", .fn = SetPVP, .a = {"#pvp"}}, + Cmd{.cmd = "pvp_points", .u = "pvp_points [Amount]", .fn = SetPVPPoints, .a = {"#setpvppoints"}}, + Cmd{.cmd = "race", .u = "race [Race ID]", .fn = SetRace, .a = {"#race"}}, + Cmd{.cmd = "race_permanent", .u = "race_permanent [Race ID]", .fn = SetRacePermanent, .a = {"#permarace"}}, + Cmd{.cmd = "server_locked", .u = "server_locked [on|off]", .fn = SetServerLocked, .a = {"#lock", "#serverlock", "#serverunlock", "#unlock"}}, + Cmd{.cmd = "skill", .u = "skill [Skill ID] [Skill Level]", .fn = SetSkill, .a = {"#setskill"}}, + Cmd{.cmd = "skill_all", .u = "skill_all [Skill Level]", .fn = SetSkillAll, .a = {"#setskillall"}}, + Cmd{.cmd = "skill_all_max", .u = "skill_all_max", .fn = SetSkillAllMax, .a = {"#maxskills"}}, + Cmd{.cmd = "start_zone", .u = "endurance [Amount]", .fn = SetStartZone, .a = {"#setstartzone"}}, + Cmd{.cmd = "temporary_name", .u = "temporary_name [Name]", .fn = SetTemporaryName, .a = {"#tempname"}}, + Cmd{.cmd = "texture", .u = "texture [Texture ID]", .fn = SetTexture, .a = {"#texture"}}, + Cmd{.cmd = "time", .u = "time [Hour] [Minute]", .fn = SetTime, .a = {"#time"}}, + Cmd{.cmd = "time_zone", .u = "time_zone [Hour] [Minute]", .fn = SetTimeZone, .a = {"#timezone"}}, + Cmd{.cmd = "title", .u = "title [Title]", .fn = SetTitle, .a = {"#title"}}, + Cmd{.cmd = "title_suffix", .u = "title_suffix [Title Suffix]", .fn = SetTitleSuffix, .a = {"#titlesuffix"}}, + Cmd{.cmd = "temporary_name", .u = "temporary_name [Name]", .fn = SetTemporaryName, .a = {"#tempname"}}, + Cmd{.cmd = "weather", .u = "weather [0|1|2|3]", .fn = SetWeather, .a = {"#weather"}}, + Cmd{.cmd = "zone", .u = "zone [option]", .fn = SetZoneData, .a = {"#zclip", "#zcolor", "#zheader", "#zonelock", "#zsafecoords", "#zsky", "#zunderworld"}}, + }; + + // Check for arguments + const auto arguments = sep->argnum; + + // look for alias or command + for (const auto &cmd: commands) { + // Check for alias first + for (const auto &alias: cmd.a) { + if (!alias.empty() && Strings::EqualFold(alias, sep->arg[0])) { + // build string from sep args + std::vector args = {}; + + // skip the first arg + for (auto i = 1; i <= arguments; i++) { + args.emplace_back(sep->arg[i]); + } + + // build the rewrite string + const std::string& rewrite = fmt::format("#set {} {}", cmd.cmd, Strings::Join(args, " ")); + + // rewrite to #set > + c->SetEntityVariable("old_command", Strings::Replace(alias, "#", "")); + c->SendGMCommand(rewrite); + c->DeleteEntityVariable("old_command"); + + c->Message( + Chat::Gray, + fmt::format( + "{} is now located under {}, using {}.", + sep->arg[0], + Saylink::Silent("#set"), + Saylink::Silent(rewrite) + ).c_str() + ); + + return; + } + } + + // Check for command + if (cmd.cmd == Strings::ToLower(sep->arg[1])) { + cmd.fn(c, sep); + return; + } + } + + // Command not found + c->Message(Chat::White, "Command not found. Usage: #set [command]"); + for (const auto &cmd: commands) { + c->Message(Chat::White, fmt::format("Usage: #set {}", cmd.u).c_str()); + } +} diff --git a/zone/gm_commands/set/aa_exp.cpp b/zone/gm_commands/set/aa_exp.cpp new file mode 100755 index 000000000..9ca995357 --- /dev/null +++ b/zone/gm_commands/set/aa_exp.cpp @@ -0,0 +1,69 @@ +#include "../../client.h" +#include "../../groups.h" +#include "../../raids.h" +#include "../../raids.h" + +void SetAAEXP(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 3 || !sep->IsNumber(3)) { + c->Message(Chat::White, "Usage: #set aa_exp [aa|group|raid] [Amount]"); + return; + } + + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + const std::string& aa_type = Strings::ToLower(sep->arg[2]); + const uint32 aa_experience = Strings::ToUnsignedInt(sep->arg[3]); + + std::string group_raid_string; + + const bool is_aa = Strings::EqualFold(aa_type, "aa"); + const bool is_group = Strings::EqualFold(aa_type, "group"); + const bool is_raid = Strings::EqualFold(aa_type, "raid"); + + if ( + !is_aa && + !is_group && + !is_raid + ) { + c->Message(Chat::White, "Usage: #set aa_exp [aa|group|raid] [Amount]"); + return; + } + + if (is_aa) { + t->SetEXP( + t->GetEXP(), + aa_experience, + false + ); + } else if (is_group) { + group_raid_string = "Group "; + + t->SetLeadershipEXP( + aa_experience, + t->GetRaidEXP() + ); + } else if (is_raid) { + group_raid_string = "Raid "; + + t->SetLeadershipEXP( + t->GetGroupEXP(), + aa_experience + ); + } + + c->Message( + Chat::White, + fmt::format( + "{} now {} {} {}AA Experience.", + c->GetTargetDescription(t, TargetDescriptionType::UCYou), + c == t ? "have" : "has", + Strings::Commify(aa_experience), + group_raid_string + ).c_str() + ); +} diff --git a/zone/gm_commands/set/aa_points.cpp b/zone/gm_commands/set/aa_points.cpp new file mode 100755 index 000000000..ab1bb8bfd --- /dev/null +++ b/zone/gm_commands/set/aa_points.cpp @@ -0,0 +1,66 @@ +#include "../../client.h" +#include "../../groups.h" +#include "../../raids.h" +#include "../../raids.h" + +void SetAAPoints(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 3 || !sep->IsNumber(3)) { + c->Message(Chat::White, "Usage: #set aa_points [aa|group|raid] [Amount]"); + return; + } + + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + const std::string& aa_type = Strings::ToLower(sep->arg[2]); + const uint32 aa_points = Strings::ToUnsignedInt(sep->arg[3]); + + std::string group_raid_string; + + const bool is_aa = Strings::EqualFold(aa_type, "aa"); + const bool is_group = Strings::EqualFold(aa_type, "group"); + const bool is_raid = Strings::EqualFold(aa_type, "raid"); + + if ( + !is_aa && + !is_group && + !is_raid + ) { + c->Message(Chat::White, "Usage: #set aa_points [aa|group|raid] [Amount]"); + return; + } + + if (is_aa) { + t->GetPP().aapoints = aa_points; + t->GetPP().expAA = 0; + t->SendAlternateAdvancementStats(); + } else if (is_group || is_raid) { + if (is_group) { + group_raid_string = "Group "; + t->GetPP().group_leadership_points = aa_points; + t->GetPP().group_leadership_exp = 0; + } else if (is_raid) { + group_raid_string = "Raid "; + t->GetPP().raid_leadership_points = aa_points; + t->GetPP().raid_leadership_exp = 0; + } + + t->SendLeadershipEXPUpdate(); + } + + c->Message( + Chat::White, + fmt::format( + "{} now {} {} {}AA Point{}.", + c->GetTargetDescription(t, TargetDescriptionType::UCYou), + c == t ? "have" : "has", + Strings::Commify(aa_points), + group_raid_string, + aa_points != 1 ? "s" : "" + ).c_str() + ); +} diff --git a/zone/gm_commands/set/adventure_points.cpp b/zone/gm_commands/set/adventure_points.cpp new file mode 100755 index 000000000..3b49d06ec --- /dev/null +++ b/zone/gm_commands/set/adventure_points.cpp @@ -0,0 +1,66 @@ +#include "../../client.h" +#include "../../../common/data_verification.h" + +void SetAdventurePoints(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 3 || !sep->IsNumber(2) || !sep->IsNumber(3)) { + c->Message(Chat::White, "Usage: #set adventure_points [Theme] [Points]"); + + c->Message(Chat::White, "Valid themes are as follows:"); + + for (const auto& e : EQ::constants::GetLDoNThemeMap()) { + if (e.first != LDoNThemes::Unused) { + c->Message( + Chat::White, + fmt::format( + "Theme {} | {}", + e.first, + e.second + ).c_str() + ); + } + } + + return; + } + + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + const uint32 theme_id = Strings::ToUnsignedInt(sep->arg[2]); + const uint32 points = Strings::ToUnsignedInt(sep->arg[3]); + + if (!EQ::ValueWithin(theme_id, LDoNThemes::GUK, LDoNThemes::TAK)) { + c->Message(Chat::White, "Valid themes are as follows:"); + + for (const auto& e : EQ::constants::GetLDoNThemeMap()) { + if (e.first != LDoNThemes::Unused) { + c->Message( + Chat::White, + fmt::format( + "Theme {} | {}", + e.first, + e.second + ).c_str() + ); + } + } + + return; + } + + c->Message( + Chat::White, + fmt::format( + "Set {} Points to {} for {}.", + EQ::constants::GetLDoNThemeName(theme_id), + Strings::Commify(points), + c->GetTargetDescription(t) + ).c_str() + ); + + t->SetLDoNPoints(theme_id, points); +} diff --git a/zone/gm_commands/set/alternate_currency.cpp b/zone/gm_commands/set/alternate_currency.cpp new file mode 100644 index 000000000..3718076fe --- /dev/null +++ b/zone/gm_commands/set/alternate_currency.cpp @@ -0,0 +1,43 @@ +#include "../../client.h" + +void SetAlternateCurrency(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 3 || !sep->IsNumber(2) || !sep->IsNumber(3)) { + c->Message(Chat::White, "Usage: #set alternate_currency [Currency ID] [Amount]"); + return; + } + + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + const uint32 currency_id = Strings::ToUnsignedInt(sep->arg[2]); + const uint32 currency_item_id = zone->GetCurrencyItemID(currency_id); + const uint32 currency_amount = Strings::ToUnsignedInt(sep->arg[3]); + + if (!currency_item_id) { + c->Message( + Chat::White, + fmt::format( + "Currency ID {} could not be found.", + currency_id + ).c_str() + ); + return; + } + + t->SetAlternateCurrencyValue(currency_id, currency_amount); + + c->Message( + Chat::White, + fmt::format( + "{} now {} {} {}.", + c->GetTargetDescription(t, TargetDescriptionType::UCYou), + c == t ? "have" : "has", + Strings::Commify(currency_amount), + database.CreateItemLink(currency_item_id) + ).c_str() + ); +} diff --git a/zone/gm_commands/set/animation.cpp b/zone/gm_commands/set/animation.cpp new file mode 100755 index 000000000..416235067 --- /dev/null +++ b/zone/gm_commands/set/animation.cpp @@ -0,0 +1,63 @@ +#include "../../client.h" + +void SetAnimation(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2 || !sep->IsNumber(2)) { + c->Message(Chat::White, "Usage: #set animation [Animation ID]"); + + for (const auto& a : EQ::constants::GetSpawnAnimationMap()) { + c->Message( + Chat::White, + fmt::format( + "Animation {} | {}", + a.first, + a.second + ).c_str() + ); + } + + return; + } + + Mob* t = c; + if (c->GetTarget()) { + t = c->GetTarget(); + } + + const auto animation_id = static_cast(Strings::ToUnsignedInt(sep->arg[2])); + if ( + !EQ::ValueWithin( + animation_id, + static_cast(eaStanding), + static_cast(eaLooting) + ) + ) { + c->Message(Chat::White, "Usage: #set animation [Animation ID]"); + + for (const auto& a : EQ::constants::GetSpawnAnimationMap()) { + c->Message( + Chat::White, + fmt::format( + "Animation {} | {}", + a.first, + a.second + ).c_str() + ); + } + + return; + } + + t->SetAppearance(static_cast(animation_id), false); + + c->Message( + Chat::White, + fmt::format( + "Set animation to {} ({}) for {}.", + EQ::constants::GetSpawnAnimationName(animation_id), + animation_id, + c->GetTargetDescription(t) + ).c_str() + ); +} diff --git a/zone/gm_commands/setanon.cpp b/zone/gm_commands/set/anon.cpp similarity index 70% rename from zone/gm_commands/setanon.cpp rename to zone/gm_commands/set/anon.cpp index 2b50c3def..e0b84f7fb 100755 --- a/zone/gm_commands/setanon.cpp +++ b/zone/gm_commands/set/anon.cpp @@ -1,18 +1,19 @@ -#include "../client.h" -#include "../../common/repositories/character_data_repository.h" +#include "../../client.h" +#include "../../../common/repositories/character_data_repository.h" -void command_setanon(Client *c, const Seperator *sep) +void SetAnon(Client *c, const Seperator *sep) { - auto arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1) || arguments > 2) { - c->Message(Chat::White, "Usage: #setanon [Anonymous Flag]"); - c->Message(Chat::White, "Usage: #setanon [Character ID] [Anonymous Flag]"); + const auto arguments = sep->argnum; + if (arguments < 2 || !sep->IsNumber(2)) { + c->Message(Chat::White, "Usage: #set anon [Anonymous Flag]"); + c->Message(Chat::White, "Usage: #set anon [Character ID] [Anonymous Flag]"); c->Message(Chat::White, "Note: 0 = Not Anonymous, 1 = Anonymous, 2 = Roleplaying"); return; } - if (arguments == 1) { - const uint8 anon_flag = static_cast(Strings::ToUnsignedInt(sep->arg[1])); + if (arguments == 2) { + const uint8 anon_flag = static_cast(Strings::ToUnsignedInt(sep->arg[2])); + auto t = c; if (c->GetTarget() && c->GetTarget()->IsClient() && c->GetGM()) { t = c->GetTarget()->CastToClient(); @@ -26,8 +27,8 @@ void command_setanon(Client *c, const Seperator *sep) } else if (anon_flag == Anonymity::Roleplaying) { anon_setting = "now Roleplaying"; } else { - c->Message(Chat::White, "Usage: #setanon [Anonymous Flag]"); - c->Message(Chat::White, "Usage: #setanon [Character ID] [Anonymous Flag]"); + c->Message(Chat::White, "Usage: #set anon [Anonymous Flag]"); + c->Message(Chat::White, "Usage: #set anon [Character ID] [Anonymous Flag]"); c->Message(Chat::White, "Note: 0 = Not Anonymous, 1 = Anonymous, 2 = Roleplaying"); return; } @@ -43,9 +44,9 @@ void command_setanon(Client *c, const Seperator *sep) anon_setting ).c_str() ); - } else if (arguments == 2) { - const auto character_id = Strings::ToInt(sep->arg[1]); - const uint8 anon_flag = static_cast(Strings::ToUnsignedInt(sep->arg[2])); + } else if (arguments == 3) { + const int character_id = Strings::ToInt(sep->arg[2]); + const uint8 anon_flag = static_cast(Strings::ToUnsignedInt(sep->arg[3])); auto e = CharacterDataRepository::FindOne(content_db, character_id); if (!e.id) { @@ -56,6 +57,7 @@ void command_setanon(Client *c, const Seperator *sep) character_id ).c_str() ); + return; } @@ -72,6 +74,7 @@ void command_setanon(Client *c, const Seperator *sep) character_id ).c_str() ); + return; } @@ -83,8 +86,8 @@ void command_setanon(Client *c, const Seperator *sep) } else if (anon_flag == Anonymity::Roleplaying) { anon_setting = "now Roleplaying"; } else { - c->Message(Chat::White, "Usage: #setanon [Anonymous Flag]"); - c->Message(Chat::White, "Usage: #setanon [Character ID] [Anonymous Flag]"); + c->Message(Chat::White, "Usage: #set anon [Anonymous Flag]"); + c->Message(Chat::White, "Usage: #set anon [Character ID] [Anonymous Flag]"); c->Message(Chat::White, "Note: 0 = Not Anonymous, 1 = Anonymous, 2 = Roleplaying"); return; } diff --git a/zone/gm_commands/set/bind_point.cpp b/zone/gm_commands/set/bind_point.cpp new file mode 100755 index 000000000..8d5bbb626 --- /dev/null +++ b/zone/gm_commands/set/bind_point.cpp @@ -0,0 +1,45 @@ +#include "../../client.h" + +void SetBindPoint(Client *c, const Seperator *sep) +{ + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + const bool bind_allowed = ( + !zone->GetInstanceID() || + ( + zone->GetInstanceID() && + zone->IsInstancePersistent() + ) + ); + + if (!bind_allowed) { + c->Message(Chat::White, "You cannot bind here."); + return; + } + + t->SetBindPoint(); + + c->Message( + Chat::White, + fmt::format( + "Set Bind Point for {} | Zone: {}", + c->GetTargetDescription(t, TargetDescriptionType::UCSelf), + zone->GetZoneDescription() + ).c_str() + ); + + c->Message( + Chat::White, + fmt::format( + "Set Bind Point for {} | XYZH: {:.2f}, {:.2f}, {:.2f}, {:.2f}", + c->GetTargetDescription(t, TargetDescriptionType::UCSelf), + t->GetX(), + t->GetY(), + t->GetZ(), + t->GetHeading() + ).c_str() + ); +} diff --git a/zone/gm_commands/updatechecksum.cpp b/zone/gm_commands/set/checksum.cpp similarity index 81% rename from zone/gm_commands/updatechecksum.cpp rename to zone/gm_commands/set/checksum.cpp index f84fafb28..76df72d29 100755 --- a/zone/gm_commands/updatechecksum.cpp +++ b/zone/gm_commands/set/checksum.cpp @@ -1,10 +1,10 @@ -#include "../client.h" -#include "../worldserver.h" -#include "../../common/repositories/account_repository.h" +#include "../../client.h" +#include "../../worldserver.h" +#include "../../../common/repositories/account_repository.h" extern WorldServer worldserver; -void command_updatechecksum(Client *c, const Seperator *sep) +void SetChecksum(Client *c, const Seperator *sep) { auto account = AccountRepository::FindOne(database, c->AccountID()); if (!account.id) { diff --git a/zone/gm_commands/set/class_permanent.cpp b/zone/gm_commands/set/class_permanent.cpp new file mode 100755 index 000000000..abce4979f --- /dev/null +++ b/zone/gm_commands/set/class_permanent.cpp @@ -0,0 +1,40 @@ +#include "../../client.h" + +void SetClassPermanent(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2 || !sep->IsNumber(2)) { + c->Message(Chat::White, "Usage: #set class_permanent [Class ID]"); + return; + } + + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + const uint32 class_id = Strings::ToUnsignedInt(sep->arg[2]); + + LogInfo("Class changed by {} for {} to {} ({}).", + c->GetCleanName(), + c->GetTargetDescription(t), + GetClassIDName(class_id), + class_id + ); + + t->SetBaseClass(class_id); + t->Save(); + t->Kick("Class was changed."); + + if (c != t) { + c->Message( + Chat::White, + fmt::format( + "Class changed for {} to {} ({}).", + c->GetTargetDescription(t), + GetClassIDName(class_id), + class_id + ).c_str() + ); + } +} diff --git a/zone/gm_commands/set/crystals.cpp b/zone/gm_commands/set/crystals.cpp new file mode 100755 index 000000000..84bfc3525 --- /dev/null +++ b/zone/gm_commands/set/crystals.cpp @@ -0,0 +1,48 @@ +#include "../../client.h" + +void SetCrystals(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2 || !sep->IsNumber(3)) { + c->Message(Chat::White, "Usage: #setcrystals [ebon|radiant] [Amount]"); + return; + } + + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + const std::string& crystal_type = Strings::ToLower(sep->arg[2]); + const uint32 crystal_amount = Strings::ToUnsignedInt(sep->arg[3]); + + const bool is_ebon = Strings::EqualFold(crystal_type, "ebon"); + const bool is_radiant = Strings::EqualFold(crystal_type, "radiant"); + if (!is_ebon && !is_radiant) { + c->Message(Chat::White, "Usage: #setcrystals [ebon|radiant] [Amount]"); + return; + } + + const uint32 crystal_item_id = ( + is_ebon ? + RuleI(Zone, EbonCrystalItemID) : + RuleI(Zone, RadiantCrystalItemID) + ); + + if (is_radiant) { + t->SetRadiantCrystals(crystal_amount); + } else { + t->SetEbonCrystals(crystal_amount); + } + + c->Message( + Chat::White, + fmt::format( + "{} now {} {} {}.", + c->GetTargetDescription(t, TargetDescriptionType::UCYou), + c == t ? "have" : "has", + Strings::Commify(crystal_amount), + database.CreateItemLink(crystal_item_id) + ).c_str() + ); +} diff --git a/zone/gm_commands/set/date.cpp b/zone/gm_commands/set/date.cpp new file mode 100755 index 000000000..cac21e061 --- /dev/null +++ b/zone/gm_commands/set/date.cpp @@ -0,0 +1,46 @@ +#include "../../client.h" + +void SetDate(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if ( + arguments < 2 || + !sep->IsNumber(2) || + !sep->IsNumber(3) || + !sep->IsNumber(4) + ) { + c->Message(Chat::White, "Usage: #date [Year] [Month] [Day] [Hour] [Minute]"); + c->Message(Chat::White, "Hour and Minute are optional"); + return; + } + + TimeOfDay_Struct eq_time; + zone->zone_time.GetCurrentEQTimeOfDay(time(0), &eq_time); + + const uint16 year = Strings::ToUnsignedInt(sep->arg[2]); + const uint8 month = Strings::ToUnsignedInt(sep->arg[3]); + const uint8 day = Strings::ToUnsignedInt(sep->arg[4]); + const uint8 hour = !sep->IsNumber(5) ? eq_time.hour : Strings::ToUnsignedInt(sep->arg[5]) + 1; + const uint8 minute = !sep->IsNumber(6) ? eq_time.minute : Strings::ToUnsignedInt(sep->arg[6]); + + c->Message( + Chat::White, + fmt::format("Setting world time to {}/{}/{} {}.", + year, + month, + day, + Strings::ZoneTime(hour, minute) + ).c_str() + ); + + zone->SetDate(year, month, day, hour, minute); + + LogInfo( + "{} :: Setting world time to {}/{}/{} {}.", + c->GetCleanName(), + year, + month, + day, + Strings::ZoneTime(hour, minute) + ); +} diff --git a/zone/gm_commands/set/endurance.cpp b/zone/gm_commands/set/endurance.cpp new file mode 100644 index 000000000..f4a8c375b --- /dev/null +++ b/zone/gm_commands/set/endurance.cpp @@ -0,0 +1,40 @@ +#include "../../client.h" + +void SetEndurance(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2 || !sep->IsNumber(2)) { + c->Message(Chat::White, "Usage: #set endurance [Endurance]"); + return; + } + + int endurance = Strings::ToInt(sep->arg[2]); + + Mob* t = c; + if (c->GetTarget()) { + t = c->GetTarget(); + } + + if (t->IsClient()) { + if (endurance >= t->CastToClient()->GetMaxEndurance()) { + endurance = t->CastToClient()->GetMaxEndurance(); + } + + t->CastToClient()->SetEndurance(endurance); + } else { + if (endurance >= t->GetMaxEndurance()) { + endurance = t->GetMaxEndurance(); + } + + t->SetEndurance(endurance); + } + + c->Message( + Chat::White, + fmt::format( + "Set {} to {} Endurance.", + c->GetTargetDescription(t), + Strings::Commify(endurance) + ).c_str() + ); +} diff --git a/zone/gm_commands/set/endurance_full.cpp b/zone/gm_commands/set/endurance_full.cpp new file mode 100755 index 000000000..8b493e41e --- /dev/null +++ b/zone/gm_commands/set/endurance_full.cpp @@ -0,0 +1,29 @@ +#include "../../client.h" + +void SetEnduranceFull(Client *c, const Seperator *sep) +{ + Mob* t = c; + if (c->GetTarget()) { + t = c->GetTarget(); + } + + int endurance; + + if (t->IsClient()) { + endurance = t->CastToClient()->GetMaxEndurance(); + t->CastToClient()->SetEndurance(endurance); + } else { + endurance = t->GetMaxEndurance(); + t->SetEndurance(endurance); + } + + c->Message( + Chat::White, + fmt::format( + "Set {} to full Endurance ({}).", + c->GetTargetDescription(t), + Strings::Commify(endurance) + ).c_str() + ); +} + diff --git a/zone/gm_commands/set/exp.cpp b/zone/gm_commands/set/exp.cpp new file mode 100755 index 000000000..20274d878 --- /dev/null +++ b/zone/gm_commands/set/exp.cpp @@ -0,0 +1,49 @@ +#include "../../client.h" + +void SetEXP(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 3 || !sep->IsNumber(3)) { + c->Message(Chat::White, "Usage: #set exp [aa|exp] [Amount]"); + return; + } + + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + const std::string& type = Strings::ToLower(sep->arg[2]); + + const bool is_aa = Strings::EqualFold(type, "aa"); + const bool is_exp = Strings::EqualFold(type, "exp"); + if (!is_aa && !is_exp) { + c->Message(Chat::White, "Usage: #set exp [aa|exp] [Amount]"); + return; + } + + const uint32 amount = Strings::ToUnsignedInt(sep->arg[3]); + + if (is_aa) { + t->SetEXP( + t->GetEXP(), + amount + ); + } else if (is_exp) { + t->SetEXP( + amount, + t->GetAAXP() + ); + } + + c->Message( + Chat::White, + fmt::format( + "{} now {} {} {}experience.", + c->GetTargetDescription(t, TargetDescriptionType::UCYou), + c == t ? "have" : "has", + Strings::Commify(amount), + is_aa ? "AA " : "" + ).c_str() + ); +} diff --git a/zone/gm_commands/set/flymode.cpp b/zone/gm_commands/set/flymode.cpp new file mode 100755 index 000000000..864c4a938 --- /dev/null +++ b/zone/gm_commands/set/flymode.cpp @@ -0,0 +1,69 @@ +#include "../../client.h" +#include "../../../common/data_verification.h" + +void SetFlymode(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2 || !sep->IsNumber(2)) { + c->Message(Chat::White, "Usage: #set flymode [Flymode ID]"); + + for (const auto& e : EQ::constants::GetFlyModeMap()) { + c->Message( + Chat::White, + fmt::format( + "Flymode {} | {}", + e.first, + e.second + ).c_str() + ); + } + + return; + } + + Mob* t = c; + if (c->GetTarget()) { + t = c->GetTarget(); + } + + const int8 flymode_id = Strings::ToInt(sep->arg[2]); + if ( + !EQ::ValueWithin( + flymode_id, + EQ::constants::GravityBehavior::Ground, + EQ::constants::GravityBehavior::LevitateWhileRunning + ) + ) { + c->Message(Chat::White, "Usage: #set flymode [Flymode ID]"); + + for (const auto& e : EQ::constants::GetFlyModeMap()) { + c->Message( + Chat::White, + fmt::format( + "Flymode {} | {}", + e.first, + e.second + ).c_str() + ); + } + + return; + } + + t->SetFlyMode(static_cast(flymode_id)); + t->SendAppearancePacket(AT_Levitate, flymode_id); + + const uint32 account = c->AccountID(); + + database.SetGMFlymode(account, flymode_id); + + c->Message( + Chat::White, + fmt::format( + "Fly Mode for {} is now {} ({}).", + c->GetTargetDescription(t), + EQ::constants::GetFlyModeName(flymode_id), + flymode_id + ).c_str() + ); +} diff --git a/zone/gm_commands/set/frozen.cpp b/zone/gm_commands/set/frozen.cpp new file mode 100755 index 000000000..b46de5cce --- /dev/null +++ b/zone/gm_commands/set/frozen.cpp @@ -0,0 +1,34 @@ +#include "../../client.h" + +void SetFrozen(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2) { + c->Message(Chat::White, "Usage: #set frozen [on|off]"); + return; + } + + if (!c->GetTarget()) { + c->Message(Chat::White, "You must have a target to use this command."); + return; + } + + const bool is_frozen = Strings::ToBool(sep->arg[2]); + + auto t = c->GetTarget(); + if (c == t) { + c->Message(Chat::White, "You cannot use this command on yourself."); + return; + } + + t->SendAppearancePacket(AT_Anim, is_frozen ? ANIM_FREEZE : ANIM_STAND); + + c->Message( + Chat::White, + fmt::format( + "You have {}frozen {}.", + !is_frozen ? "un" : "", + c->GetTargetDescription(t) + ).c_str() + ); +} diff --git a/zone/gm_commands/set/gender.cpp b/zone/gm_commands/set/gender.cpp new file mode 100755 index 000000000..5ad6fdf9f --- /dev/null +++ b/zone/gm_commands/set/gender.cpp @@ -0,0 +1,38 @@ +#include "../../client.h" + +void SetGender(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2 || !sep->IsNumber(2)) { + c->Message(Chat::White, "Usage: #set gender [Gender ID]"); + c->Message(Chat::White, "Genders: 0 = Male, 1 = Female, 2 = Neuter"); + return; + } + + Mob *t = c; + if (c->GetTarget()) { + t = c->GetTarget(); + } + + const uint8 gender_id = Strings::ToUnsignedInt(sep->arg[2]); + if (!EQ::ValueWithin(gender_id, MALE, NEUTER)) { + c->Message(Chat::White, "Usage: #set gender [Gender ID]"); + c->Message(Chat::White, "Genders: 0 = Male, 1 = Female, 2 = Neuter"); + return; + } + + t->SendIllusionPacket( + t->GetRace(), + gender_id + ); + + c->Message( + Chat::White, + fmt::format( + "Gender changed for {} to {} ({}).", + c->GetTargetDescription(t), + GetGenderName(gender_id), + gender_id + ).c_str() + ); +} diff --git a/zone/gm_commands/set/gender_permanent.cpp b/zone/gm_commands/set/gender_permanent.cpp new file mode 100755 index 000000000..6d05e0690 --- /dev/null +++ b/zone/gm_commands/set/gender_permanent.cpp @@ -0,0 +1,44 @@ +#include "../../client.h" + +void SetGenderPermanent(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2 || !sep->IsNumber(2)) { + c->Message(Chat::White, "Usage: #set gender_permanent [Gender ID]"); + c->Message(Chat::White, "Genders: 0 = Male, 1 = Female, 2 = Neuter"); + return; + } + + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + const uint8 gender_id = Strings::ToInt(sep->arg[2]); + if (!EQ::ValueWithin(gender_id, MALE, NEUTER)) { + c->Message(Chat::White, "Usage: #set gender_permanent [Gender ID]"); + c->Message(Chat::White, "Genders: 0 = Male, 1 = Female, 2 = Neuter"); + return; + } + + LogInfo("Gender changed by {} for {} to {} ({})", + c->GetCleanName(), + c->GetTargetDescription(t), + GetGenderName(gender_id), + gender_id + ); + + t->SetBaseGender(gender_id); + t->Save(); + t->SendIllusionPacket(t->GetRace(), gender_id); + + c->Message( + Chat::White, + fmt::format( + "Gender changed for {} to {} ({}).", + c->GetTargetDescription(t), + GetGenderName(gender_id), + gender_id + ).c_str() + ); +} diff --git a/zone/gm_commands/set/gm.cpp b/zone/gm_commands/set/gm.cpp new file mode 100755 index 000000000..19aca7826 --- /dev/null +++ b/zone/gm_commands/set/gm.cpp @@ -0,0 +1,30 @@ +#include "../../client.h" + +void SetGM(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2) { + c->Message(Chat::White, "Usage: #set gm [on|off]"); + return; + } + + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + const bool gm_flag = Strings::ToBool(sep->arg[2]); + + t->SetGM(gm_flag); + + if (c != t) { + c->Message( + Chat::White, + fmt::format( + "{} is {} flagged as a GM.", + c->GetTargetDescription(t), + gm_flag ? "now" : "no longer" + ).c_str() + ); + } +} diff --git a/zone/gm_commands/set/gm_speed.cpp b/zone/gm_commands/set/gm_speed.cpp new file mode 100755 index 000000000..ffcef33b3 --- /dev/null +++ b/zone/gm_commands/set/gm_speed.cpp @@ -0,0 +1,39 @@ +#include "../../client.h" + +void SetGMSpeed(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2) { + c->Message(Chat::White, "Usage: #set gmspeed [on|off]"); + return; + } + + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + const bool gm_speed = Strings::ToBool(sep->arg[2]); + + database.SetGMSpeed( + t->AccountID(), + gm_speed ? 1 : 0 + ); + + c->Message( + Chat::White, + fmt::format( + "Turning GM Speed {} for {}.", + gm_speed ? "on" : "off", + c->GetTargetDescription(t) + ).c_str() + ); + + c->Message( + Chat::White, + fmt::format( + "Note: {} must zone for it to take effect.", + c->GetTargetDescription(t, TargetDescriptionType::UCYou) + ).c_str() + ); +} diff --git a/zone/gm_commands/set/gm_status.cpp b/zone/gm_commands/set/gm_status.cpp new file mode 100644 index 000000000..aae8dcff3 --- /dev/null +++ b/zone/gm_commands/set/gm_status.cpp @@ -0,0 +1,97 @@ +#include "../../client.h" +#include "../../worldserver.h" + +extern WorldServer worldserver; + +void SetGMStatus(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2) { + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + c->Message( + Chat::White, + fmt::format( + "Status level has been refreshed for {}.", + c->GetTargetDescription(t) + ).c_str() + ); + + if (t != c) { + t->Message( + Chat::White, + fmt::format( + "Your status level has been refreshed by {}.", + c->GetCleanName() + ).c_str() + ); + } + + t->UpdateAdmin(); + return; + } + + + if ( + !sep->IsNumber(2) || + !strlen(sep->arg[3]) + ) { + c->Message(Chat::White, "Usage: #set gm_status [Status] [Account Name]"); + return; + } + + const int gm_status = Strings::ToInt(sep->arg[2]); + if (!EQ::ValueWithin(gm_status, -2, UINT8_MAX)) { + c->Message(Chat::White, "The lowest a status level can go is -2 and the highest a status level can go is 255."); + return; + } + + const std::string& account_name = sep->argplus[3]; + + if (gm_status > c->Admin()) { + c->Message( + Chat::White, + fmt::format( + "You cannot set someone's status level to {} because your status level is only {}.", + gm_status, + c->Admin() + ).c_str() + ); + } else if (!database.SetAccountStatus(account_name, gm_status)) { + c->Message( + Chat::White, + fmt::format( + "Failed to set status level to {} for account {}.", + gm_status, + account_name + ).c_str() + ); + } else { + c->Message( + Chat::White, + fmt::format( + "Set GM status to {} on account {}.", + gm_status, + account_name + ).c_str() + ); + + std::string user; + std::string loginserver; + ParseAccountString(account_name, user, loginserver); + + const uint32 account_id = database.GetAccountIDByName(account_name, loginserver); + + ServerPacket pack(ServerOP_FlagUpdate, sizeof(ServerFlagUpdate_Struct)); + + auto s = (ServerFlagUpdate_Struct *) pack.pBuffer; + s->account_id = account_id; + s->admin = gm_status; + + worldserver.SendPacket(&pack); + } +} + diff --git a/zone/gm_commands/set/god_mode.cpp b/zone/gm_commands/set/god_mode.cpp new file mode 100644 index 000000000..1075d0091 --- /dev/null +++ b/zone/gm_commands/set/god_mode.cpp @@ -0,0 +1,42 @@ +#include "../../client.h" +#include "../../../common/repositories/account_repository.h" + +void SetGodMode(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2) { + c->Message(Chat::White, "Usage: #set god_mode [on|off]"); + return; + } + + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + const bool god_mode = Strings::ToBool(sep->arg[2]); + const uint32 account_id = c->AccountID(); + + auto a = AccountRepository::FindOne(database, c->AccountID()); + if (a.id) { + a.flymode = god_mode ? 1 : 0; + a.gmspeed = god_mode ? 1 : 0; + a.invulnerable = god_mode ? 1 : 0; + a.hideme = god_mode ? 1 : 0; + } + + c->SetInvul(god_mode); + c->SendAppearancePacket(AT_Levitate, god_mode); + c->SetHideMe(god_mode); + + c->Message( + Chat::White, + fmt::format( + "Turning God Mode {} for {}, zone for GM Speed to take effect.", + god_mode ? "on" : "off", + c->GetTargetDescription(t) + ).c_str() + ); + + AccountRepository::UpdateOne(database, a); +} diff --git a/zone/gm_commands/haste.cpp b/zone/gm_commands/set/haste.cpp old mode 100755 new mode 100644 similarity index 59% rename from zone/gm_commands/haste.cpp rename to zone/gm_commands/set/haste.cpp index d5e19f569..ea4712745 --- a/zone/gm_commands/haste.cpp +++ b/zone/gm_commands/set/haste.cpp @@ -1,10 +1,10 @@ -#include "../client.h" +#include "../../client.h" -void command_haste(Client *c, const Seperator *sep) +void SetHaste(Client *c, const Seperator *sep) { const auto arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1)) { - c->Message(Chat::White, "Usage: #haste [Percentage] - Set GM Bonus Haste (100 is 100% more Attack Speed)"); + if (arguments < 2 || !sep->IsNumber(2)) { + c->Message(Chat::White, "Usage: #set haste [Percentage] - Set GM Bonus Haste (100 is 100% more Attack Speed)"); return; } @@ -13,7 +13,7 @@ void command_haste(Client *c, const Seperator *sep) t = c->GetTarget()->CastToClient(); } - const auto extra_haste = Strings::ToInt(sep->arg[1]); + const int extra_haste = Strings::ToInt(sep->arg[2]); t->SetExtraHaste(extra_haste); t->CalcBonuses(); @@ -28,4 +28,3 @@ void command_haste(Client *c, const Seperator *sep) ).c_str() ); } - diff --git a/zone/gm_commands/set/hero_model.cpp b/zone/gm_commands/set/hero_model.cpp new file mode 100755 index 000000000..f98b5d5e2 --- /dev/null +++ b/zone/gm_commands/set/hero_model.cpp @@ -0,0 +1,44 @@ +#include "../../client.h" + +void SetHeroModel(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2 || !sep->IsNumber(2)) { + c->Message(Chat::White, "Usage: #set hero_model [Hero Model]"); + c->Message(Chat::White, "Usage: #set hero_model [Hero Model] [Slot]"); + c->Message( + Chat::White, + fmt::format( + "Example: {}", + Saylink::Silent("#heromodel 63") + ).c_str() + ); + return; + } + + Mob* t = c; + if (c->GetTarget()) { + t = c->GetTarget(); + } + + uint32 hero_forge_model = Strings::ToUnsignedInt(sep->arg[2]); + + if (arguments > 2) { + const uint8 slot = Strings::ToUnsignedInt(sep->arg[3]); + c->GetTarget()->SendTextureWC(slot, 0, hero_forge_model, 0, 0, 0); + } else { + if (!hero_forge_model) { + c->Message(Chat::White, "Hero's Forge Model must be greater than 0."); + return; + } + + // Conversion to simplify the command arguments + // Hero's Forge model is actually model * 1000 + texture * 100 + wearslot + // Hero's Forge Model slot 7 is actually for Robes, but it still needs to use wearslot 1 in the packet + hero_forge_model *= 100; + + for (uint8 slot = 0; slot < 7; slot++) { + c->GetTarget()->SendTextureWC(slot, 0, (hero_forge_model + slot), 0, 0, 0); + } + } +} diff --git a/zone/gm_commands/hideme.cpp b/zone/gm_commands/set/hide_me.cpp similarity index 50% rename from zone/gm_commands/hideme.cpp rename to zone/gm_commands/set/hide_me.cpp index 108807d8d..8b2e580f1 100755 --- a/zone/gm_commands/hideme.cpp +++ b/zone/gm_commands/set/hide_me.cpp @@ -1,11 +1,10 @@ -#include "../client.h" +#include "../../client.h" -void command_hideme(Client *c, const Seperator *sep) +void SetHideMe(Client *c, const Seperator *sep) { const auto arguments = sep->argnum; - if (!arguments) { - c->Message(Chat::White, "Usage: #hideme [On|Off]"); - c->Message(Chat::White, "Usage: #hideme [0|1]"); + if (arguments < 2) { + c->Message(Chat::White, "Usage: #set hide_me [on|off]"); return; } @@ -14,17 +13,17 @@ void command_hideme(Client *c, const Seperator *sep) t = c->GetTarget()->CastToClient(); } - const auto is_hidden = Strings::ToBool(sep->arg[1]); + const bool is_hidden = Strings::ToBool(sep->arg[2]); t->SetHideMe(is_hidden); c->Message( Chat::White, fmt::format( - "{} {} now {} to players below a status level of {}.", + "{} {} now {}visible to players below a status level of {}.", c->GetTargetDescription(t, TargetDescriptionType::UCYou), c == t ? "are" : "is", - is_hidden ? "invisible" : "visible", + is_hidden ? "in" : "", t->Admin() ).c_str() ); diff --git a/zone/gm_commands/set/hp.cpp b/zone/gm_commands/set/hp.cpp new file mode 100644 index 000000000..3078cc98c --- /dev/null +++ b/zone/gm_commands/set/hp.cpp @@ -0,0 +1,33 @@ +#include "../../client.h" + +void SetHP(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2 || !sep->IsNumber(2)) { + c->Message(Chat::White, "Usage: #set hp [Amount]"); + return; + } + + Mob* t = c; + if (c->GetTarget()) { + t = c->GetTarget(); + } + + int64 health = Strings::ToBigInt(sep->arg[2]); + + if (health >= t->GetMaxHP()) { + health = t->GetMaxHP(); + } + + t->SetHP(health); + t->SendHPUpdate(); + + c->Message( + Chat::White, + fmt::format( + "Set {} to {} Health.", + c->GetTargetDescription(t), + Strings::Commify(health) + ).c_str() + ); +} diff --git a/zone/gm_commands/set/hp_full.cpp b/zone/gm_commands/set/hp_full.cpp new file mode 100755 index 000000000..b823b7fc5 --- /dev/null +++ b/zone/gm_commands/set/hp_full.cpp @@ -0,0 +1,20 @@ +#include "../../client.h" + +void SetHPFull(Client *c, const Seperator *sep) +{ + Mob* t = c; + if (c->GetTarget()) { + t = c->GetTarget(); + } + + t->Heal(); + + c->Message( + Chat::White, + fmt::format( + "Set {} to full Health ({}).", + c->GetTargetDescription(t), + Strings::Commify(t->GetMaxHP()) + ).c_str() + ); +} diff --git a/zone/gm_commands/set/invulnerable.cpp b/zone/gm_commands/set/invulnerable.cpp new file mode 100755 index 000000000..f8efcb2d7 --- /dev/null +++ b/zone/gm_commands/set/invulnerable.cpp @@ -0,0 +1,32 @@ +#include "../../client.h" + +void SetInvulnerable(Client *c, const Seperator *sep) { + const auto arguments = sep->argnum; + if (arguments < 2) { + c->Message(Chat::White, "Usage: #set invulnerable [on|off]"); + return; + } + + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + const bool invulnerable = Strings::ToBool(sep->arg[2]); + + t->SetInvul(invulnerable); + + const uint32 account_id = t->AccountID(); + + database.SetGMInvul(account_id, invulnerable); + + c->Message( + Chat::White, + fmt::format( + "{} {} now {}vulnerable.", + c->GetTargetDescription(t, TargetDescriptionType::UCYou), + c == t ? "are" : "is", + invulnerable ? "in" : "" + ).c_str() + ); +} diff --git a/zone/gm_commands/set/language.cpp b/zone/gm_commands/set/language.cpp new file mode 100755 index 000000000..f16c01850 --- /dev/null +++ b/zone/gm_commands/set/language.cpp @@ -0,0 +1,54 @@ +#include "../../client.h" +#include "../../../common/languages.h" +#include "../../../common/data_verification.h" + +void SetLanguage(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 3 || !sep->IsNumber(2) || !sep->IsNumber(3)) { + c->Message(Chat::White, "Usage: #set language [Language ID] [Language Value]"); + c->Message(Chat::White, "Language ID = 0 to 27"); + c->Message(Chat::White, "Language Value = 0 to 100"); + return; + } + + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + const int language_id = Strings::ToInt(sep->arg[2]); + const int language_value = Strings::ToInt(sep->arg[3]); + if ( + !EQ::ValueWithin(language_id, LANG_COMMON_TONGUE, LANG_UNKNOWN) || + !EQ::ValueWithin(language_value, 0, MAX_LANGUAGE_SKILL) + ) { + c->Message(Chat::White, "Usage: #set language [Language ID] [Language Value]"); + c->Message(Chat::White, "Language ID = 0 to 27"); + c->Message(Chat::White, "Language Value = 0 to 100"); + return; + } + + LogInfo( + "Set language request from [{}], Target: [{}] Language ID: [{}] Language Value: [{}]", + c->GetCleanName(), + c->GetTargetDescription(t), + language_id, + language_value + ); + + t->SetLanguageSkill(language_id, language_value); + + if (c != t) { + c->Message( + Chat::White, + fmt::format( + "Set {} ({}) to {} for {}.", + EQ::constants::GetLanguageName(language_id), + language_id, + language_value, + c->GetTargetDescription(t) + ).c_str() + ); + } +} diff --git a/zone/gm_commands/set/last_name.cpp b/zone/gm_commands/set/last_name.cpp new file mode 100755 index 000000000..8fd23789e --- /dev/null +++ b/zone/gm_commands/set/last_name.cpp @@ -0,0 +1,46 @@ +#include "../../client.h" + +void SetLastName(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2) { + c->Message(Chat::White, "Usage: #set lastname [Last Name]"); + c->Message(Chat::White, "Note: Use \"-1\" to remove last name."); + return; + } + + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + LogInfo("#lastname request from [{}] for [{}]", c->GetCleanName(), t->GetCleanName()); + + const bool is_remove = Strings::EqualFold(sep->argplus[2], "-1"); + const std::string& last_name = !is_remove ? sep->argplus[2] : ""; + + if (last_name.size() > 64) { + c->Message(Chat::White, "Last name must be 64 characters or less."); + return; + } + + t->ChangeLastName(last_name); + + c->Message( + Chat::White, + fmt::format( + "Last name has been {}{} for {}{}", + is_remove ? "removed" : "changed", + !is_remove ? " and saved" : "", + c->GetTargetDescription(t), + ( + is_remove ? + "." : + fmt::format( + " to '{}'.", + last_name + ) + ) + ).c_str() + ); +} diff --git a/zone/gm_commands/set/level.cpp b/zone/gm_commands/set/level.cpp new file mode 100644 index 000000000..549de0b8b --- /dev/null +++ b/zone/gm_commands/set/level.cpp @@ -0,0 +1,34 @@ +#include "../../bot.h" +#include "../../client.h" + +void SetLevel(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2 || !sep->IsNumber(2)) { + c->Message(Chat::White, "Usage: #set level [Level]"); + return; + } + + Mob* t = c; + if (c->GetTarget()) { + t = c->GetTarget(); + } + + const uint8 max_level = RuleI(Character, MaxLevel); + const uint8 level = Strings::ToUnsignedInt(sep->arg[2]); + + if (c != t && c->Admin() < RuleI(GM, MinStatusToLevelTarget)) { + c->Message(Chat::White, "Your status is not high enough to change another person's level."); + return; + } + + t->SetLevel(level, true); + + if (t->IsClient()) { + t->CastToClient()->SendLevelAppearance(); + + if (RuleB(Bots, Enabled) && RuleB(Bots, BotLevelsWithOwner)) { + Bot::LevelBotWithClient(t->CastToClient(), level, true); + } + } +} diff --git a/zone/gm_commands/setlsinfo.cpp b/zone/gm_commands/set/loginserver_info.cpp similarity index 50% rename from zone/gm_commands/setlsinfo.cpp rename to zone/gm_commands/set/loginserver_info.cpp index 280c3e6f1..3e42216de 100755 --- a/zone/gm_commands/setlsinfo.cpp +++ b/zone/gm_commands/set/loginserver_info.cpp @@ -1,24 +1,30 @@ -#include "../client.h" -#include "../worldserver.h" +#include "../../client.h" +#include "../../worldserver.h" extern WorldServer worldserver; -void command_setlsinfo(Client *c, const Seperator *sep) +void SetLoginserverInfo(Client *c, const Seperator *sep) { - int arguments = sep->argnum; - if (arguments < 2) { - c->Message(Chat::White, "Usage: #setlsinfo [Email] [Password]"); + const auto arguments = sep->argnum; + if (arguments < 3) { + c->Message(Chat::White, "Usage: #set lsinfo [Email] [Password]"); return; } + const std::string& email = sep->arg[2]; + const std::string& password = sep->arg[3]; + auto pack = new ServerPacket(ServerOP_LSAccountUpdate, sizeof(ServerLSAccountUpdate_Struct)); + auto s = (ServerLSAccountUpdate_Struct *) pack->pBuffer; + s->useraccountid = c->LSAccountID(); strn0cpy(s->useraccount, c->AccountName(), 30); - strn0cpy(s->user_email, sep->arg[1], 100); - strn0cpy(s->userpassword, sep->arg[2], 50); + strn0cpy(s->user_email, email.c_str(), 100); + strn0cpy(s->userpassword, password.c_str(), 50); + worldserver.SendPacket(pack); safe_delete(pack); + c->Message(Chat::White, "Your email and local loginserver password have been set."); } - diff --git a/zone/gm_commands/set/mana.cpp b/zone/gm_commands/set/mana.cpp new file mode 100644 index 000000000..68779dc47 --- /dev/null +++ b/zone/gm_commands/set/mana.cpp @@ -0,0 +1,41 @@ +#include "../../client.h" + +void SetMana(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2 || !sep->IsNumber(2)) { + c->Message(Chat::White, "Usage: #set mana [Amount]"); + return; + } + + Mob* t = c; + if (c->GetTarget()) { + t = c->GetTarget(); + } + + int64 mana = Strings::ToBigInt(sep->arg[2]); + + if (t->IsClient()) { + if (mana >= t->CastToClient()->CalcMaxMana()) { + mana = t->CastToClient()->CalcMaxMana(); + } + + t->CastToClient()->SetMana(mana); + } else { + if (mana >= t->CalcMaxMana()) { + mana = t->CalcMaxMana(); + } + + t->SetMana(mana); + } + + c->Message( + Chat::White, + fmt::format( + "Set {} to {} Mana.", + c->GetTargetDescription(t), + Strings::Commify(mana) + ).c_str() + ); +} + diff --git a/zone/gm_commands/set/mana_full.cpp b/zone/gm_commands/set/mana_full.cpp new file mode 100755 index 000000000..5b9ad77bb --- /dev/null +++ b/zone/gm_commands/set/mana_full.cpp @@ -0,0 +1,28 @@ +#include "../../client.h" + +void SetManaFull(Client *c, const Seperator *sep) +{ + Mob* t = c; + if (c->GetTarget()) { + t = c->GetTarget(); + } + + int64 mana; + + if (t->IsClient()) { + mana = t->CastToClient()->CalcMaxMana(); + t->CastToClient()->SetMana(mana); + } else { + mana = t->CalcMaxMana(); + t->SetMana(mana); + } + + c->Message( + Chat::White, + fmt::format( + "Set {} to full Mana ({}).", + c->GetTargetDescription(t), + Strings::Commify(mana) + ).c_str() + ); +} diff --git a/zone/gm_commands/motd.cpp b/zone/gm_commands/set/motd.cpp similarity index 52% rename from zone/gm_commands/motd.cpp rename to zone/gm_commands/set/motd.cpp index 55a6d8ccc..f22cad89b 100755 --- a/zone/gm_commands/motd.cpp +++ b/zone/gm_commands/set/motd.cpp @@ -1,15 +1,24 @@ -#include "../client.h" -#include "../worldserver.h" +#include "../../client.h" +#include "../../worldserver.h" extern WorldServer worldserver; void command_motd(Client *c, const Seperator *sep) { + const auto arguments = sep->argnum; + if (arguments < 2) { + c->Message(Chat::White, "Usage: #set motd [Message]"); + return; + } + + const std::string& message = sep->argplus[2]; + auto pack = new ServerPacket(ServerOP_Motd, sizeof(ServerMotd_Struct)); + auto m = (ServerMotd_Struct *) pack->pBuffer; strn0cpy(m->myname, c->GetName(), sizeof(m->myname)); - strn0cpy(m->motd, sep->argplus[1], sizeof(m->motd)); + strn0cpy(m->motd, message.c_str(), sizeof(m->motd)); + worldserver.SendPacket(pack); safe_delete(pack); } - diff --git a/zone/gm_commands/set/name.cpp b/zone/gm_commands/set/name.cpp new file mode 100755 index 000000000..0e3ca531a --- /dev/null +++ b/zone/gm_commands/set/name.cpp @@ -0,0 +1,43 @@ +#include "../../client.h" + +void SetName(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2) { + c->Message(Chat::White, "Usage: #set name [Name]"); + return; + } + + if (c->GetTarget() && c->GetTarget()->IsClient()) { + auto t = c->GetTarget()->CastToClient(); + + std::string new_name = sep->arg[2]; + std::string old_name = t->GetCleanName(); + + if (t->ChangeFirstName(new_name.c_str(), c->GetCleanName())) { + c->Message( + Chat::White, + fmt::format( + "Successfully renamed {} to {}", + old_name, + new_name + ).c_str() + ); + + c->Message(Chat::White, "Sending player to char select."); + + t->Kick("Name was changed"); + + return; + } + + c->Message( + Chat::White, + fmt::format( + "Unable to rename {}. Check that the new name '{}' isn't already taken.", + old_name, + new_name + ).c_str() + ); + } +} diff --git a/zone/gm_commands/oocmute.cpp b/zone/gm_commands/set/ooc_mute.cpp similarity index 55% rename from zone/gm_commands/oocmute.cpp rename to zone/gm_commands/set/ooc_mute.cpp index d8711eccf..4f2db4e87 100755 --- a/zone/gm_commands/oocmute.cpp +++ b/zone/gm_commands/set/ooc_mute.cpp @@ -1,20 +1,23 @@ -#include "../client.h" -#include "../worldserver.h" +#include "../../client.h" +#include "../../worldserver.h" extern WorldServer worldserver; -void command_oocmute(Client *c, const Seperator *sep) +void SetOOCMute(Client *c, const Seperator *sep) { - if (!sep->IsNumber(1)) { - c->Message(Chat::White, "Usage: #oocmute [0|1] - Enable or Disable Server OOC"); + const auto arguments = sep->argnum; + if (arguments < 2) { + c->Message(Chat::White, "Usage: #set ooc_mute [on|off]"); return; } - bool is_muted = Strings::ToInt(sep->arg[1]) ? true : false; + const bool is_muted = Strings::ToBool(sep->arg[2]); ServerPacket pack(ServerOP_OOCMute, sizeof(ServerOOCMute_Struct)); + auto o = (ServerOOCMute_Struct*) pack.pBuffer; o->is_muted = is_muted; + worldserver.SendPacket(&pack); c->Message( @@ -25,4 +28,3 @@ void command_oocmute(Client *c, const Seperator *sep) ).c_str() ); } - diff --git a/zone/gm_commands/set/password.cpp b/zone/gm_commands/set/password.cpp new file mode 100755 index 000000000..d057daa4b --- /dev/null +++ b/zone/gm_commands/set/password.cpp @@ -0,0 +1,52 @@ +#include "../../client.h" + +void SetPassword(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 3) { + c->Message(Chat::White, "Usage: #set password [Account Name] [Password] [Loginserver]"); + return; + } + + std::string account_name = sep->arg[2]; + std::string password = sep->arg[3]; + std::string loginserver = arguments >= 4 ? sep->arg[4] : "eqemu"; + + int16 status = 0; + + const uint32 account_id = database.GetAccountIDByName(account_name, loginserver, &status); + if (!account_id) { + c->Message( + Chat::White, + fmt::format( + "Account {} was not found.", + account_name + ).c_str() + ); + return; + } + + if (status > c->Admin()) { + c->Message( + Chat::White, + fmt::format( + "You cannot change the password for Account {} as its status is higher than yours.", + account_name + ).c_str() + ); + return; + } + + c->Message( + Chat::White, + fmt::format( + "Password {} changed for Account {}.", + ( + database.SetLocalPassword(account_id, password.c_str()) ? + "successfully" : + "failed" + ), + account_name + ).c_str() + ); +} diff --git a/zone/gm_commands/set/pvp.cpp b/zone/gm_commands/set/pvp.cpp new file mode 100755 index 000000000..f851ddea1 --- /dev/null +++ b/zone/gm_commands/set/pvp.cpp @@ -0,0 +1,30 @@ +#include "../../client.h" + +void SetPVP(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2) { + c->Message(Chat::White, "Usage: #set pvp [on|off]"); + return; + } + + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + const bool pvp_state = Strings::ToBool(sep->arg[2]); + + t->SetPVP(pvp_state); + + if (c != t) { + c->Message( + Chat::White, + fmt::format( + "{} now follows the ways of {}.", + c->GetTargetDescription(t), + pvp_state ? "Discord" : "Order" + ).c_str() + ); + } +} diff --git a/zone/gm_commands/set/pvp_points.cpp b/zone/gm_commands/set/pvp_points.cpp new file mode 100755 index 000000000..1562eaf12 --- /dev/null +++ b/zone/gm_commands/set/pvp_points.cpp @@ -0,0 +1,33 @@ +#include "../../client.h" + +void SetPVPPoints(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2 || !sep->IsNumber(2)) { + c->Message(Chat::White, "Usage: #set pvp_points [Amount]"); + return; + } + + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + const uint32 pvp_points = Strings::ToUnsignedInt(sep->arg[2]); + + t->SetPVPPoints(pvp_points); + t->Save(); + t->SendPVPStats(); + + c->Message( + Chat::White, + fmt::format( + "{} now {} {} PVP Point{}.", + c->GetTargetDescription(t, TargetDescriptionType::UCYou), + c == t ? "have" : "has", + Strings::Commify(pvp_points), + pvp_points != 1 ? "s" : "" + ).c_str() + ); +} + diff --git a/zone/gm_commands/set/race.cpp b/zone/gm_commands/set/race.cpp new file mode 100755 index 000000000..5f9eb37ac --- /dev/null +++ b/zone/gm_commands/set/race.cpp @@ -0,0 +1,52 @@ +#include "../../client.h" + +void SetRace(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2 || !sep->IsNumber(2)) { + c->Message( + Chat::White, + fmt::format( + "Usage: #set race [0-{}, 2253-2259] (0 for back to normal)", + RuleI(NPC, MaxRaceID) + ).c_str() + ); + + return; + } + + Mob* t = c; + if (c->GetTarget()) { + t = c->GetTarget(); + } + + const uint16 race_id = Strings::ToUnsignedInt(sep->arg[2]); + + if ( + !EQ::ValueWithin(race_id, RACE_DOUG_0, RuleI(NPC, MaxRaceID)) && + !EQ::ValueWithin(race_id, 2253, 2259) + ) { + c->Message( + Chat::White, + fmt::format( + "Usage: #race [0-{}, 2253-2259] (0 for back to normal)", + RuleI(NPC, MaxRaceID) + ).c_str() + ); + + return; + } + + t->SendIllusionPacket(race_id); + + c->Message( + Chat::White, + fmt::format( + "{} {} now temporarily a(n) {} ({}).", + c->GetTargetDescription(t, TargetDescriptionType::UCYou), + c == t ? "are" : "is", + GetRaceIDName(race_id), + race_id + ).c_str() + ); +} diff --git a/zone/gm_commands/set/race_permanent.cpp b/zone/gm_commands/set/race_permanent.cpp new file mode 100755 index 000000000..bc6a094ee --- /dev/null +++ b/zone/gm_commands/set/race_permanent.cpp @@ -0,0 +1,45 @@ +#include "../../client.h" + +void SetRacePermanent(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2 || !sep->IsNumber(2)) { + c->Message(Chat::White, "Usage: #set race_permanent [Race ID]"); + c->Message( + Chat::White, + "NOTE: Not all models are global. If a model is not global, it will appear as a Human on character select and in zones without the model." + ); + + return; + } + + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + const uint16 race_id = Strings::ToUnsignedInt(sep->arg[2]); + const uint8 gender_id = Mob::GetDefaultGender(race_id, t->GetBaseGender()); + + LogInfo("Race changed by {} for {} to {} ({})", + c->GetCleanName(), + c->GetTargetDescription(t), + GetRaceIDName(race_id), + race_id + ); + + t->SetBaseRace(race_id); + t->SetBaseGender(gender_id); + t->Save(); + t->SendIllusionPacket(race_id, gender_id); + + c->Message( + Chat::White, + fmt::format( + "Race changed for {} to {} ({}).", + c->GetTargetDescription(t), + GetRaceIDName(race_id), + race_id + ).c_str() + ); +} diff --git a/zone/gm_commands/set/server_locked.cpp b/zone/gm_commands/set/server_locked.cpp new file mode 100644 index 000000000..73e92dad3 --- /dev/null +++ b/zone/gm_commands/set/server_locked.cpp @@ -0,0 +1,33 @@ +#include "../../client.h" +#include "../../worldserver.h" + +extern WorldServer worldserver; + +void SetServerLocked(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2) { + c->Message(Chat::White, "Usage: #set server_locked [on|off]"); + return; + } + + bool is_locked = Strings::ToBool(sep->arg[2]); + + if (c->EntityVariableExists("old_command")) { + const std::string& old_command = c->GetEntityVariable("old_command"); + if (old_command == "lock" || old_command == "serverlock") { + is_locked = true; + } else if (old_command == "unlock" || old_command == "serverunlock") { + is_locked = false; + } + } + + auto pack = new ServerPacket(ServerOP_Lock, sizeof(ServerLock_Struct)); + + auto l = (ServerLock_Struct *) pack->pBuffer; + strn0cpy(l->character_name, c->GetCleanName(), sizeof(l->character_name)); + l->is_locked = is_locked; + + worldserver.SendPacket(pack); + safe_delete(pack); +} diff --git a/zone/gm_commands/setskill.cpp b/zone/gm_commands/set/skill.cpp similarity index 67% rename from zone/gm_commands/setskill.cpp rename to zone/gm_commands/set/skill.cpp index 428a9cc48..b6071a9f6 100755 --- a/zone/gm_commands/setskill.cpp +++ b/zone/gm_commands/set/skill.cpp @@ -1,11 +1,10 @@ -#include "../client.h" +#include "../../client.h" -void command_setskill(Client *c, const Seperator *sep) +void SetSkill(Client *c, const Seperator *sep) { const auto arguments = sep->argnum; - - if (arguments < 2 || !sep->IsNumber(1) || !sep->IsNumber(2)) { - c->Message(Chat::White, "Usage: #setskill [Skill ID] [Skill Value]"); + if (arguments < 3 || !sep->IsNumber(2) || !sep->IsNumber(3)) { + c->Message(Chat::White, "Usage: #set skill [Skill ID] [Skill Value]"); return; } @@ -14,11 +13,11 @@ void command_setskill(Client *c, const Seperator *sep) t = c->GetTarget()->CastToClient(); } - const auto skill_id = Strings::ToInt(sep->arg[1]); - const auto skill_value = Strings::ToInt(sep->arg[2]); + const uint16 skill_id = Strings::ToUnsignedInt(sep->arg[2]); + const uint16 skill_value = Strings::ToUnsignedInt(sep->arg[3]); if (!EQ::ValueWithin(skill_id, EQ::skills::Skill1HBlunt, EQ::skills::HIGHEST_SKILL)) { - c->Message(Chat::White, "Usage: #setskill [Skill ID] [Skill Value]"); + c->Message(Chat::White, "Usage: #set skill [Skill ID] [Skill Value]"); c->Message(Chat::White, fmt::format("Skill ID: 0 to {}", EQ::skills::HIGHEST_SKILL).c_str()); return; } @@ -43,4 +42,3 @@ void command_setskill(Client *c, const Seperator *sep) ); } } - diff --git a/zone/gm_commands/set/skill_all.cpp b/zone/gm_commands/set/skill_all.cpp new file mode 100755 index 000000000..1094b4bea --- /dev/null +++ b/zone/gm_commands/set/skill_all.cpp @@ -0,0 +1,39 @@ +#include "../../client.h" + +void SetSkillAll(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2 || !sep->IsNumber(2)) { + c->Message(Chat::White, "Usage: #set skill_all [Skill Level]"); + return; + } + + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + const uint16 skill_level = Strings::ToUnsignedInt(sep->arg[2]); + + for (const auto& s : EQ::skills::GetSkillTypeMap()) { + if (t->CanHaveSkill(s.first) && t->MaxSkill(s.first)) { + if (c != t) { + c->Message( + Chat::White, + fmt::format( + "Setting {} ({}) to {} for {}.", + s.second, + s.first, + skill_level > t->MaxSkill(s.first) ? t->MaxSkill(s.first) : skill_level, + c->GetTargetDescription(t) + ).c_str() + ); + } + + t->SetSkill( + s.first, + skill_level > t->MaxSkill(s.first) ? t->MaxSkill(s.first) : skill_level + ); + } + } +} diff --git a/zone/gm_commands/max_all_skills.cpp b/zone/gm_commands/set/skill_all_max.cpp similarity index 74% rename from zone/gm_commands/max_all_skills.cpp rename to zone/gm_commands/set/skill_all_max.cpp index d032265ec..0565721f8 100755 --- a/zone/gm_commands/max_all_skills.cpp +++ b/zone/gm_commands/set/skill_all_max.cpp @@ -1,6 +1,6 @@ -#include "../client.h" +#include "../../client.h" -void command_max_all_skills(Client *c, const Seperator *sep) +void SetSkillAllMax(Client *c, const Seperator *sep) { auto t = c; if (c->GetTarget() && c->GetTarget()->IsClient()) { @@ -17,4 +17,3 @@ void command_max_all_skills(Client *c, const Seperator *sep) ).c_str() ); } - diff --git a/zone/gm_commands/set/start_zone.cpp b/zone/gm_commands/set/start_zone.cpp new file mode 100755 index 000000000..71748ccb9 --- /dev/null +++ b/zone/gm_commands/set/start_zone.cpp @@ -0,0 +1,51 @@ +#include "../../client.h" + +void SetStartZone(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2) { + c->Message(Chat::White, "Usage: #set start_zone [Zone ID|Zone Short Name]"); + c->Message( + Chat::White, + "Optional Usage: Use '#set start_zone reset' or '#set start_zone 0' to clear a starting zone. Player can select a starting zone using /setstartcity" + ); + return; + } + + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + const uint32 zone_id = ( + sep->IsNumber(2) ? + Strings::ToUnsignedInt(sep->arg[2]) : + ZoneID(sep->arg[2]) + ); + + t->SetStartZone(zone_id); + + const bool is_reset = ( + Strings::EqualFold(sep->arg[2], "reset") || + zone_id == 0 + ); + + c->Message( + Chat::White, + fmt::format( + "Start Zone {} for {} |{}", + is_reset ? "Reset" : "Changed", + c->GetTargetDescription(t, TargetDescriptionType::UCSelf), + ( + zone_id ? + fmt::format( + " {} ({}) ID: {}", + ZoneLongName(zone_id), + ZoneName(zone_id), + zone_id + ) : + "" + ) + ).c_str() + ); +} diff --git a/zone/gm_commands/set/temporary_name.cpp b/zone/gm_commands/set/temporary_name.cpp new file mode 100755 index 000000000..f04577c5b --- /dev/null +++ b/zone/gm_commands/set/temporary_name.cpp @@ -0,0 +1,38 @@ +#include "../../client.h" + +void SetTemporaryName(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2) { + c->Message(Chat::White, "Usage: #set temporary_name [New Name]"); + c->Message(Chat::White, "Note: This command requires a target, even if the target is yourself."); + return; + } + + if (!c->GetTarget()) { + c->Message(Chat::White, "Usage: #set temporary_name [New Name]"); + c->Message(Chat::White, "Note: This command requires a target, even if the target is yourself."); + return; + } + + Mob* t = c->GetTarget(); + + const std::string& temporary_name = strlen(sep->arg[2]) ? sep->arg[2] : ""; + + t->TempName(temporary_name.c_str()); + + if (temporary_name.length()) { + const std::string& current_name = t->GetName(); + + c->Message( + Chat::White, + fmt::format( + "Renamed {} to {} temporarily.", + current_name, + temporary_name + ).c_str() + ); + } else { + c->Message(Chat::White, "Restored your target's original name."); + } +} diff --git a/zone/gm_commands/set/texture.cpp b/zone/gm_commands/set/texture.cpp new file mode 100755 index 000000000..e08cc530d --- /dev/null +++ b/zone/gm_commands/set/texture.cpp @@ -0,0 +1,56 @@ +#include "../../client.h" + +void SetTexture(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2 || !sep->IsNumber(2)) { + c->Message(Chat::White, "Usage: #set texture [Texture] [Helmet Texture]"); + return; + } + + const uint16 texture = Strings::ToUnsignedInt(sep->arg[2]); + const uint8 helmet_texture = ( + sep->IsNumber(3) ? + Strings::ToUnsignedInt(sep->arg[3]) : + 0 + ); + + Mob* t = c; + if (c->GetTarget()) { + t = c->GetTarget(); + } + + if (IsPlayerRace(t->GetModel())) { // Player Races Wear Armor, so Wearchange is sent instead + for ( + int texture_slot = EQ::textures::textureBegin; + texture_slot <= EQ::textures::LastTintableTexture; + texture_slot++ + ) { + t->SendTextureWC(texture_slot, texture); + } + } else { // Non-Player Races only need Illusion Packets to be sent for texture + t->SendIllusionPacket( + t->GetModel(), + t->GetGender(), + texture, + helmet_texture + ); + } + + c->Message( + Chat::White, + fmt::format( + "Texture Changed for {} | Texture: {}{}", + c->GetTargetDescription(t, TargetDescriptionType::UCSelf), + texture, + ( + IsPlayerRace(t->GetModel()) ? + "" : + fmt::format( + " Helmet Texture: {}", + helmet_texture + ) + ) + ).c_str() + ); +} diff --git a/zone/gm_commands/set/time.cpp b/zone/gm_commands/set/time.cpp new file mode 100755 index 000000000..6cd3ab57b --- /dev/null +++ b/zone/gm_commands/set/time.cpp @@ -0,0 +1,67 @@ +#include "../../client.h" + +void SetTime(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2 || !sep->IsNumber(2)) { + c->Message(Chat::White, "Usage: #set time [Hour] [Minute]"); + + TimeOfDay_Struct world_time; + zone->zone_time.GetCurrentEQTimeOfDay(time(0), &world_time); + + auto time_string = fmt::format( + "{} (Timezone: {})", + Strings::ZoneTime(world_time.hour, world_time.minute), + Strings::ZoneTime(zone->zone_time.getEQTimeZoneHr(), zone->zone_time.getEQTimeZoneHr()) + ); + + c->Message( + Chat::White, + fmt::format( + "It is currently {}.", + time_string + ).c_str() + ); + + return; + } + + uint8 minutes = 0; + uint8 hours = Strings::ToUnsignedInt(sep->arg[2]) + 1; + + if (hours > 24) { + hours = 24; + } + + uint8 real_hours = ( + (hours - 1) > 0 ? + (hours - 1) : + 0 + ); + + if (sep->IsNumber(3)) { + minutes = Strings::ToUnsignedInt(sep->arg[3]); + + if (minutes > 59) { + minutes = 59; + } + } + + c->Message( + Chat::White, + fmt::format( + "Setting world time to {} (Timezone: {}).", + Strings::ZoneTime(hours, minutes), + Strings::ZoneTime(zone->zone_time.getEQTimeZoneHr(), zone->zone_time.getEQTimeZoneHr()) + ).c_str() + ); + + zone->SetTime(real_hours, minutes); + + LogInfo( + "{} :: Setting world time to {} (Timezone: {})", + c->GetCleanName(), + Strings::ZoneTime(hours, minutes), + Strings::ZoneTime(zone->zone_time.getEQTimeZoneHr(), zone->zone_time.getEQTimeZoneHr()) + ); +} diff --git a/zone/gm_commands/set/time_zone.cpp b/zone/gm_commands/set/time_zone.cpp new file mode 100755 index 000000000..cb96700c6 --- /dev/null +++ b/zone/gm_commands/set/time_zone.cpp @@ -0,0 +1,58 @@ +#include "../../client.h" + +void SetTimeZone(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2 || sep->IsNumber(2)) { + c->Message(Chat::White, "Usage: #set time_zone [Hour] [Minute]"); + c->Message( + Chat::White, + fmt::format( + "Current time zone is {}.", + Strings::ZoneTime(zone->zone_time.getEQTimeZoneHr(), zone->zone_time.getEQTimeZoneMin()) + ).c_str() + ); + return; + } + + uint8 minutes = 0; + uint8 hours = Strings::ToUnsignedInt(sep->arg[2]); + + if (hours > 24) { + hours = 24; + } + + uint8 real_hours = ( + (hours - 1) > 0 ? + (hours - 1) : + 0 + ); + + if (sep->IsNumber(3)) { + minutes = Strings::ToUnsignedInt(sep->arg[3]); + + if (minutes > 59) { + minutes = 59; + } + } + + c->Message( + Chat::White, + fmt::format( + "Setting timezone to {}.", + Strings::ZoneTime(hours, minutes) + ).c_str() + ); + + const int new_timezone = ((hours * 60) + minutes); + zone->zone_time.setEQTimeZone(new_timezone); + content_db.SetZoneTZ(zone->GetZoneID(), zone->GetInstanceVersion(), new_timezone); + + auto outapp = new EQApplicationPacket(OP_TimeOfDay, sizeof(TimeOfDay_Struct)); + + auto t = (TimeOfDay_Struct *) outapp->pBuffer; + zone->zone_time.GetCurrentEQTimeOfDay(time(0), t); + + entity_list.QueueClients(c, outapp); + safe_delete(outapp); +} diff --git a/zone/gm_commands/set/title.cpp b/zone/gm_commands/set/title.cpp new file mode 100755 index 000000000..a6fc8a6e2 --- /dev/null +++ b/zone/gm_commands/set/title.cpp @@ -0,0 +1,55 @@ +#include "../../client.h" +#include "../../titles.h" + +void SetTitle(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 2) { + c->Message(Chat::White, "Usage: #set title [Title]"); + c->Message(Chat::White, "Note: Use \"-1\" to remove title."); + return; + } + + const bool is_remove = Strings::EqualFold(sep->argplus[2], "-1"); + std::string title = !is_remove ? sep->argplus[2] : ""; + + auto t = c; + if (c->GetTarget() && c->GetTarget()->IsClient()) { + t = c->GetTarget()->CastToClient(); + } + + if (title.size() > 31) { + c->Message(Chat::White, "Title must be 31 characters or less."); + return; + } + + if (!title.empty()) { + Strings::FindReplace(title, "_", " "); + } + + if (is_remove) { + t->SetAATitle(title); + } else { + title_manager.CreateNewPlayerTitle(t, title); + } + + t->Save(); + + c->Message( + Chat::White, + fmt::format( + "Title has been {}{} for {}{}", + is_remove ? "removed" : "changed", + !is_remove ? " and saved" : "", + c->GetTargetDescription(t), + ( + is_remove ? + "." : + fmt::format( + " to '{}'.", + title + ) + ) + ).c_str() + ); +} diff --git a/zone/gm_commands/titlesuffix.cpp b/zone/gm_commands/set/title_suffix.cpp similarity index 55% rename from zone/gm_commands/titlesuffix.cpp rename to zone/gm_commands/set/title_suffix.cpp index cc5581d96..1b4619dc4 100755 --- a/zone/gm_commands/titlesuffix.cpp +++ b/zone/gm_commands/set/title_suffix.cpp @@ -1,23 +1,21 @@ -#include "../client.h" -#include "../titles.h" +#include "../../client.h" +#include "../../titles.h" -void command_titlesuffix(Client *c, const Seperator *sep) +void SetTitleSuffix(Client *c, const Seperator *sep) { - int arguments = sep->argnum; + const auto arguments = sep->argnum; if (!arguments) { - c->Message( - Chat::White, - "Usage: #titlesuffix [Title Suffix] (use \"-1\" to remove title suffix)" - ); + c->Message(Chat::White, "Usage: #set title_suffix [Title Suffix]"); + c->Message(Chat::White, "Note: Use \"-1\" to remove title."); return; } - bool is_remove = !strcasecmp(sep->argplus[1], "-1"); + const bool is_remove = !strcasecmp(sep->argplus[1], "-1"); std::string suffix = is_remove ? "" : sep->argplus[1]; - auto target = c; + auto t = c; if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); + t = c->GetTarget()->CastToClient(); } if (suffix.size() > 31) { @@ -30,12 +28,12 @@ void command_titlesuffix(Client *c, const Seperator *sep) } if (is_remove) { - target->SetTitleSuffix(suffix); + t->SetTitleSuffix(suffix); } else { - title_manager.CreateNewPlayerSuffix(target, suffix); + title_manager.CreateNewPlayerSuffix(t, suffix); } - target->Save(); + t->Save(); c->Message( Chat::White, @@ -43,7 +41,7 @@ void command_titlesuffix(Client *c, const Seperator *sep) "Title suffix has been {}{} for {}{}", is_remove ? "removed" : "changed", !is_remove ? " and saved" : "", - c->GetTargetDescription(target), + c->GetTargetDescription(t), ( is_remove ? "." : diff --git a/zone/gm_commands/weather.cpp b/zone/gm_commands/set/weather.cpp similarity index 69% rename from zone/gm_commands/weather.cpp rename to zone/gm_commands/set/weather.cpp index 6289275f1..028ba2387 100755 --- a/zone/gm_commands/weather.cpp +++ b/zone/gm_commands/set/weather.cpp @@ -1,27 +1,27 @@ -#include "../client.h" +#include "../../client.h" -void command_weather(Client *c, const Seperator *sep) +void SetWeather(Client *c, const Seperator *sep) { - if (!sep->IsNumber(1)) { + const auto arguments = sep->argnum; + if (arguments < 2 || !sep->IsNumber(2)) { c->Message(Chat::White, "Usage: #weather [0|1|2] - [Off|Rain|Snow]"); c->Message(Chat::White, "Usage: #weather 3 [Type] [Intensity] - Manually set weather type and intensity"); return; } - int arguments = sep->argnum; - if (arguments == 1) { - auto new_weather = static_cast(Strings::ToUnsignedInt(sep->arg[1])); - uint8 new_intensity = 0; + if (arguments == 2) { + uint8 new_weather = Strings::ToUnsignedInt(sep->arg[2]); + uint8 new_intensity = 0; std::string weather_message = "The sky clears."; if (new_weather == EQ::constants::WeatherTypes::Snowing) { weather_message = "Snowflakes begin to fall from the sky."; - new_weather = EQ::constants::WeatherTypes::Snowing; - new_intensity = 0x02; + new_weather = EQ::constants::WeatherTypes::Snowing; + new_intensity = 2; } else if (new_weather == EQ::constants::WeatherTypes::Raining) { weather_message = "Raindrops begin to fall from the sky."; - new_weather = EQ::constants::WeatherTypes::Raining; - new_intensity = 0x01; // This is how it's done in Fear, and you can see a decent distance with it at this value + new_weather = EQ::constants::WeatherTypes::Raining; + new_intensity = 1; // This is how it's done in Fear, and you can see a decent distance with it at this value } zone->zone_weather = new_weather; @@ -35,21 +35,20 @@ void command_weather(Client *c, const Seperator *sep) outapp->pBuffer[4] = new_intensity; } - c->Message(Chat::White, weather_message.c_str()); entity_list.QueueClients(c, outapp); safe_delete(outapp); - } else if (arguments == 3) { - auto command_type = static_cast(Strings::ToUnsignedInt(sep->arg[1])); - uint8 new_weather = EQ::constants::WeatherTypes::None; - uint8 new_intensity = 0; + } else if (arguments == 4) { + const uint8 command_type = Strings::ToUnsignedInt(sep->arg[2]); + uint8 new_weather = EQ::constants::WeatherTypes::None; + uint8 new_intensity = 0; std::string weather_message; if (zone->zone_weather == EQ::constants::WeatherTypes::None) { if (command_type > EQ::constants::WeatherTypes::Snowing) { - new_weather = static_cast(Strings::ToUnsignedInt(sep->arg[2])); - new_intensity = static_cast(Strings::ToUnsignedInt(sep->arg[3])); + new_weather = Strings::ToUnsignedInt(sep->arg[3]); + new_intensity = Strings::ToUnsignedInt(sep->arg[4]); weather_message = fmt::format( "Sending {} ({}) with an intensity of {}.", @@ -59,12 +58,12 @@ void command_weather(Client *c, const Seperator *sep) ); } else if (command_type == EQ::constants::WeatherTypes::Snowing) { weather_message = "Snowflakes begin to fall from the sky."; - new_weather = EQ::constants::WeatherTypes::Snowing; - new_intensity = 0x02; + new_weather = EQ::constants::WeatherTypes::Snowing; + new_intensity = 2; } else if (command_type == EQ::constants::WeatherTypes::Raining) { weather_message = "Raindrops begin to fall from the sky."; - new_weather = EQ::constants::WeatherTypes::Raining; - new_intensity = 0x01; // This is how it's done in Fear, and you can see a decent distance with it at this value + new_weather = EQ::constants::WeatherTypes::Raining; + new_intensity = 1; // This is how it's done in Fear, and you can see a decent distance with it at this value } zone->zone_weather = new_weather; @@ -86,7 +85,7 @@ void command_weather(Client *c, const Seperator *sep) if (zone->zone_weather == EQ::constants::WeatherTypes::Snowing) { weather_message = "The sky clears as the snow stops falling."; - outapp->pBuffer[0] = 0x01; // Snow has it's own shutoff packet + outapp->pBuffer[0] = 1; // Snow has it's own shutoff packet } else if (zone->zone_weather == EQ::constants::WeatherTypes::Raining) { weather_message = "The sky clears as the rain ceases to fall."; } @@ -100,4 +99,3 @@ void command_weather(Client *c, const Seperator *sep) } } } - diff --git a/zone/gm_commands/set/zone.cpp b/zone/gm_commands/set/zone.cpp new file mode 100755 index 000000000..a79acf6bf --- /dev/null +++ b/zone/gm_commands/set/zone.cpp @@ -0,0 +1,455 @@ +#include "../../client.h" + +void SetZoneData(Client *c, const Seperator *sep) +{ + const auto arguments = sep->argnum; + if (arguments < 3) { + c->Message( + Chat::White, + "Usage: #set zone clipping [Minimum Clip] [Maximum Clip] [Fog Minimum Clip] [Fog Maximum Clip] [Permanent (0 = False, 1 = True)] (Permanent is optional)" + ); + c->Message( + Chat::White, + "Usage: #set zone color [Red] [Green] [Blue] [Permanent (0 = False, 1 = True)] (Permanent is optional)" + ); + c->Message( + Chat::White, + "Usage: #set zone header [Zone ID|Zone Short Name] [Version]" + ); + c->Message( + Chat::White, + "Usage: #set zone locked [on|off] [Zone ID|Zone Short Name]" + ); + c->Message( + Chat::White, + "Usage: #set zone safe_coordinates [X] [Y] [Z] [Heading] [Permanent (0 = False, 1 = True)] (Permanent is optional)" + ); + c->Message( + Chat::White, + "Usage: #set zone sky [Sky Type] [Permanent (0 = False, 1 = True)] (Permanent is optional)" + ); + c->Message( + Chat::White, + "Usage: #set zone underworld [Z] [Permanent (0 = False, 1 = True)] (Permanent is optional)" + ); + return; + } + + const bool is_clipping = Strings::EqualFold(sep->arg[2], "clipping"); + const bool is_color = Strings::EqualFold(sep->arg[2], "color"); + const bool is_header = Strings::EqualFold(sep->arg[2], "header"); + const bool is_locked = Strings::EqualFold(sep->arg[2], "locked"); + const bool is_safe_coordinates = Strings::EqualFold(sep->arg[2], "safe_coordinates"); + const bool is_sky = Strings::EqualFold(sep->arg[2], "sky"); + const bool is_underworld = Strings::EqualFold(sep->arg[2], "underworld"); + + if ( + !is_clipping && + !is_color && + !is_header && + !is_locked && + !is_safe_coordinates && + !is_sky && + !is_underworld + ) { + c->Message( + Chat::White, + "Usage: #set zone clipping [Minimum Clip] [Maximum Clip] [Fog Minimum Clip] [Fog Maximum Clip] [Permanent (0 = False, 1 = True)] (Permanent is optional)" + ); + c->Message( + Chat::White, + "Usage: #set zone color [Red] [Green] [Blue] [Permanent (0 = False, 1 = True)] (Permanent is optional)" + ); + c->Message( + Chat::White, + "Usage: #set zone header [Zone ID|Zone Short Name] [Version]" + ); + c->Message( + Chat::White, + "Usage: #set zone locked [on|off] [Zone ID|Zone Short Name]" + ); + c->Message( + Chat::White, + "Usage: #set zone safe_coordinates [X] [Y] [Z] [Heading] [Permanent (0 = False, 1 = True)] (Permanent is optional)" + ); + c->Message( + Chat::White, + "Usage: #set zone sky [Sky Type] [Permanent (0 = False, 1 = True)] (Permanent is optional)" + ); + c->Message( + Chat::White, + "Usage: #set zone underworld [Z] [Permanent (0 = False, 1 = True)] (Permanent is optional)" + ); + return; + } + + if (is_clipping) { + const float minimum_clip = sep->arg[3] ? Strings::ToFloat(sep->arg[3]) : 0.0f; + const float maximum_clip = sep->arg[4] ? Strings::ToFloat(sep->arg[4]) : 0.0f; + const float minimum_fog_clip = sep->arg[5] ? Strings::ToFloat(sep->arg[5]) : 0.0f; + const float maximum_fog_clip = sep->arg[6] ? Strings::ToFloat(sep->arg[6]) : 0.0f; + const bool permanent = sep->arg[7] ? Strings::ToBool(sep->arg[7]) : false; + + if (minimum_clip < 0.0f || maximum_clip < 0.0f) { + c->Message(Chat::White, "Minimum Clip and Maximum Clip must be greater than or equal 0.0."); + return; + } else if (minimum_clip > maximum_clip) { + c->Message(Chat::White, "Minimum Clip must be less than or equal to Maximum Clip!"); + return; + } else { + zone->newzone_data.minclip = minimum_clip; + zone->newzone_data.maxclip = maximum_clip; + + if (minimum_fog_clip) { + for (float &fog_index: zone->newzone_data.fog_minclip) { + fog_index = minimum_fog_clip; + } + } + + if (maximum_fog_clip) { + for (float &fog_index: zone->newzone_data.fog_maxclip) { + fog_index = maximum_fog_clip; + } + } + + if (permanent) { + std::string query = fmt::format( + "UPDATE zone SET minclip = {:.2f}, maxclip = {:.2f} WHERE zoneidnumber = {} AND version = {}", + minimum_clip, + maximum_clip, + zone->GetZoneID(), + zone->GetInstanceVersion() + ); + + database.QueryDatabase(query); + + if (minimum_fog_clip) { + query = fmt::format( + "UPDATE zone SET fog_minclip = {:.2f} WHERE zoneidnumber = {} AND version = {}", + minimum_fog_clip, + zone->GetZoneID(), + zone->GetInstanceVersion() + ); + database.QueryDatabase(query); + } + + if (maximum_fog_clip) { + query = fmt::format( + "UPDATE zone SET fog_maxclip = {:.2f} WHERE zoneidnumber = {} AND version = {}", + maximum_fog_clip, + zone->GetZoneID(), + zone->GetInstanceVersion() + ); + database.QueryDatabase(query); + } + } + + auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct)); + memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size); + entity_list.QueueClients(c, outapp); + safe_delete(outapp); + + c->Message( + Chat::White, + fmt::format( + "Clipping Changed | Zone: {} Permanent: {}", + zone->GetZoneDescription(), + permanent ? "Yes" : "No" + ).c_str() + ); + + c->Message( + Chat::White, + fmt::format( + "Clipping Changed | Minimum Clip: {:.2f} Maximum Clip: {:.2f}", + minimum_clip, + maximum_clip + ).c_str() + ); + + if (minimum_fog_clip || maximum_fog_clip) { + c->Message( + Chat::White, + fmt::format( + "Clipping Changed | Fog Minimum Clip: {:.2f} Fog Maximum Clip: {:.2f}", + minimum_fog_clip, + maximum_fog_clip + ).c_str() + ); + } + } + } else if (is_color) { + if ( + arguments < 3 || + !sep->IsNumber(3) || + !sep->IsNumber(4) || + !sep->IsNumber(5) + ) { + c->Message(Chat::White, "Usage: #set zone color [Red] [Green] [Blue] [Permanent (0 = False, 1 = True)]"); + return; + } + + const uint8 red = Strings::ToUnsignedInt(sep->arg[3]); + const uint8 green = Strings::ToUnsignedInt(sep->arg[4]); + const uint8 blue = Strings::ToUnsignedInt(sep->arg[5]); + const bool permanent = sep->arg[6] ? Strings::ToBool(sep->arg[6]) : false; + + if ( + !EQ::ValueWithin(red, 0, UINT8_MAX) || + !EQ::ValueWithin(green, 0, UINT8_MAX) || + !EQ::ValueWithin(blue, 0, UINT8_MAX) + ) { + c->Message(Chat::White, "Colors cannot be less than 0 or greater than 255."); + return; + } + + if (permanent) { + const std::string& query = fmt::format( + "UPDATE zone SET fog_red = {}, fog_green = {}, fog_blue = {} " + "WHERE zoneidnumber = {} AND version = {}", + red, + green, + blue, + zone->GetZoneID(), + zone->GetInstanceVersion() + ); + database.QueryDatabase(query); + } + + for (uint8 fog_index = 0; fog_index < 4; fog_index++) { + zone->newzone_data.fog_red[fog_index] = red; + zone->newzone_data.fog_green[fog_index] = green; + zone->newzone_data.fog_blue[fog_index] = blue; + } + + auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct)); + memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size); + entity_list.QueueClients(c, outapp); + safe_delete(outapp); + + c->Message( + Chat::White, + fmt::format( + "Fog Color Changed | Zone: {} Red: {} Green: {} Blue: {} Permanent: {}", + zone->GetZoneDescription(), + red, + green, + blue, + permanent ? "Yes" : "No" + ).c_str() + ); + } else if (is_header) { + if (arguments < 3) { + c->Message(Chat::White, "Usage: #set zone header [Zone ID|Zone Short Name] [Version]"); + return; + } + + const auto zone_id = ( + sep->IsNumber(3) ? + Strings::ToUnsignedInt(sep->arg[3]) : + ZoneID(sep->arg[3]) + ); + if (!zone_id) { + c->Message( + Chat::White, + fmt::format( + "Zone ID {} could not be found.", + zone_id + ).c_str() + ); + return; + } + + const std::string& zone_short_name = ZoneName(zone_id); + const std::string& zone_long_name = ZoneLongName(zone_id); + const auto version = ( + sep->IsNumber(4) ? + Strings::ToUnsignedInt(sep->arg[4]) : + 0 + ); + + auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct)); + memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size); + entity_list.QueueClients(c, outapp); + safe_delete(outapp); + + zone_store.LoadZones(content_db); + + c->Message( + Chat::White, + fmt::format( + "Zone Header Load {} | Zone: {} ({}){}", + ( + zone->LoadZoneCFG(zone_short_name.c_str(), version) ? + "Succeeded" : + "Failed" + ), + zone_long_name, + zone_short_name, + ( + version ? + fmt::format( + " Version: {}", + version + ) : + "" + ) + ).c_str() + ); + } else if (is_locked) { + if (arguments < 4) { + c->Message(Chat::White, "Usage: #set zone locked [on|off] [Zone ID|Zone Short Name]"); + return; + } + + const bool is_locked = Strings::ToBool(sep->arg[3]); + + const uint32 zone_id = ( + sep->IsNumber(4) ? + Strings::ToUnsignedInt(sep->arg[4]) : + ZoneID(sep->arg[4]) + ); + const std::string& zone_short_name = Strings::ToLower(ZoneName(zone_id, true)); + + const bool is_unknown_zone = Strings::EqualFold(zone_short_name, "unknown"); + if (!zone_id || is_unknown_zone) { + c->Message(Chat::White, "Usage: #set zone locked [on|off] [Zone ID|Zone Short Name]"); + return; + } + + auto pack = new ServerPacket(ServerOP_LockZone, sizeof(ServerLockZone_Struct)); + + auto l = (ServerLockZone_Struct *) pack->pBuffer; + strn0cpy(l->adminname, c->GetName(), sizeof(l->adminname)); + l->op = is_locked ? ServerLockType::Lock : ServerLockType::Unlock; + l->zoneID = zone_id; + + worldserver.SendPacket(pack); + safe_delete(pack); + } else if (is_safe_coordinates) { + if ( + arguments < 3 || + !sep->IsNumber(3) || + !sep->IsNumber(4) || + !sep->IsNumber(5) + ) { + c->Message(Chat::White, "Usage: #set zone safe_coordinates [X] [Y] [Z] [Heading] [Permanent (0 = False, 1 = True)]"); + c->Message(Chat::White, "Not sending Heading defaults to current Heading and the change is temporary."); + return; + } + + const float x = Strings::ToFloat(sep->arg[3]); + const float y = Strings::ToFloat(sep->arg[4]); + const float z = Strings::ToFloat(sep->arg[5]); + const float heading = sep->arg[6] ? Strings::ToFloat(sep->arg[6]) : c->GetHeading(); + const bool permanent = sep->arg[7] ? Strings::ToBool(sep->arg[7]) : false; + + if (permanent) { + const std::string& query = fmt::format( + "UPDATE zone SET safe_x = {:.2f}, safe_y = {:.2f}, safe_z = {:.2f}, safe_heading = {:.2f} WHERE zoneidnumber = {} AND version = {}", + x, + y, + z, + heading, + zone->GetZoneID(), + zone->GetInstanceVersion() + ); + database.QueryDatabase(query); + } + + zone->newzone_data.safe_x = x; + zone->newzone_data.safe_y = y; + zone->newzone_data.safe_z = z; + + auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct)); + memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size); + entity_list.QueueClients(c, outapp); + safe_delete(outapp); + + c->Message( + Chat::White, + fmt::format( + "Safe Coordinates Changed | Zone: {} XYZ: {:.2f}, {:.2f}, {:.2f} Heading: {:.2f} Permanent: {} ", + zone->GetZoneDescription(), + x, + y, + z, + heading, + permanent ? "Yes" : "No" + ).c_str() + ); + } else if (is_sky) { + if (arguments < 3 || !sep->IsNumber(3)) { + c->Message(Chat::White, "Usage: #set zone sky [Sky Type] [Permanent (0 = False, 1 = True)]"); + return; + } + + const uint8 sky_type = Strings::ToUnsignedInt(sep->arg[3]); + const bool permanent = sep->arg[4] ? Strings::ToBool(sep->arg[4]) : false; + + if (!EQ::ValueWithin(sky_type, 0, UINT8_MAX)) { + c->Message(Chat::White, "Sky Type cannot be less than 0 or greater than 255!"); + return; + } + + if (permanent) { + const std::string& query = fmt::format( + "UPDATE zone SET sky = {} WHERE zoneidnumber = {} AND version = {}", + sky_type, + zone->GetZoneID(), + zone->GetInstanceVersion() + ); + database.QueryDatabase(query); + } + + zone->newzone_data.sky = sky_type; + auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct)); + memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size); + entity_list.QueueClients(c, outapp); + safe_delete(outapp); + + c->Message( + Chat::White, + fmt::format( + "Sky Changed | Zone: {} Sky Type: {} Permanent: {}", + zone->GetZoneDescription(), + sky_type, + permanent ? "Yes" : "No" + ).c_str() + ); + } else if (is_underworld) { + if (arguments < 3 || !sep->IsNumber(3)) { + c->Message(Chat::White, "Usage: #set zone underworld [Z] [Permanent (0 = False, 1 = True)]"); + return; + } + + const float z = Strings::ToFloat(sep->arg[3]); + const bool permanent = sep->arg[4] ? Strings::ToBool(sep->arg[4]) : false; + + if (permanent) { + auto query = fmt::format( + "UPDATE zone SET underworld = {:.2f} WHERE zoneidnumber = {} AND version = {}", + z, + zone->GetZoneID(), + zone->GetInstanceVersion() + ); + database.QueryDatabase(query); + } + + zone->newzone_data.underworld = z; + auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct)); + memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size); + entity_list.QueueClients(c, outapp); + safe_delete(outapp); + + c->Message( + Chat::White, + fmt::format( + "Underworld Z Changed | Zone: {} Z: {:.2f} Permanent: {}", + zone->GetZoneDescription(), + z, + permanent ? "Yes" : "No" + ).c_str() + ); + } +} diff --git a/zone/gm_commands/set_adventure_points.cpp b/zone/gm_commands/set_adventure_points.cpp deleted file mode 100755 index 89a309b94..000000000 --- a/zone/gm_commands/set_adventure_points.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include "../client.h" -#include "../../common/data_verification.h" - -void command_set_adventure_points(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - - if ( - !arguments || - !sep->IsNumber(1) || - !sep->IsNumber(2) - ) { - c->Message(Chat::White, "Usage: #setadventurepoints [Theme] [Points]"); - c->Message(Chat::White, "Valid themes are as follows."); - auto theme_map = EQ::constants::GetLDoNThemeMap(); - for (const auto& theme : theme_map) { - c->Message( - Chat::White, - fmt::format( - "Theme {} | {}", - theme.first, - theme.second - ).c_str() - ); - } - c->Message(Chat::White, "Note: Theme 0 splits the points evenly across all Themes."); - return; - } - - auto target = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); - } - - auto theme_id = Strings::ToUnsignedInt(sep->arg[1]); - if (!EQ::ValueWithin(theme_id, LDoNThemes::Unused, LDoNThemes::TAK)) { - c->Message(Chat::White, "Valid themes are as follows."); - auto& theme_map = EQ::constants::GetLDoNThemeMap(); - for (const auto& theme : theme_map) { - c->Message( - Chat::White, - fmt::format( - "Theme {} | {}", - theme.first, - theme.second - ).c_str() - ); - } - c->Message(Chat::White, "Note: Theme 0 splits the points evenly across all Themes."); - return; - } - - auto points = Strings::ToInt(sep->arg[2]); - - c->Message( - Chat::White, - fmt::format( - "{} for {}.", - ( - theme_id == LDoNThemes::Unused ? - fmt::format( - "Splitting {} Points Evenly", - points - ) : - fmt::format( - "Adding {} {} Points", - points, - EQ::constants::GetLDoNThemeName(theme_id) - ) - ), - c->GetTargetDescription(target) - ).c_str() - ); - - target->UpdateLDoNPoints(theme_id, points); -} diff --git a/zone/gm_commands/setaapts.cpp b/zone/gm_commands/setaapts.cpp deleted file mode 100755 index 86b8c2994..000000000 --- a/zone/gm_commands/setaapts.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "../client.h" -#include "../groups.h" -#include "../raids.h" -#include "../raids.h" - -void command_setaapts(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (arguments <= 1 || !sep->IsNumber(2)) { - c->Message(Chat::White, "Usage: #setaapts [AA|Group|Raid] [AA Amount]"); - return; - } - - Client *target = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); - } - - std::string aa_type = Strings::ToLower(sep->arg[1]); - std::string group_raid_string; - uint32 aa_points = static_cast(std::min(Strings::ToUnsignedBigInt(sep->arg[2]), (uint64) 2000000000)); - bool is_aa = aa_type.find("aa") != std::string::npos; - bool is_group = aa_type.find("group") != std::string::npos; - bool is_raid = aa_type.find("raid") != std::string::npos; - if (!is_aa && !is_group && !is_raid) { - c->Message(Chat::White, "Usage: #setaapts [AA|Group|Raid] [AA Amount]"); - return; - } - - if (is_aa) { - target->GetPP().aapoints = aa_points; - target->GetPP().expAA = 0; - target->SendAlternateAdvancementStats(); - } - else if (is_group || is_raid) { - if (is_group) { - group_raid_string = "Group "; - target->GetPP().group_leadership_points = aa_points; - target->GetPP().group_leadership_exp = 0; - } - else if (is_raid) { - group_raid_string = "Raid "; - target->GetPP().raid_leadership_points = aa_points; - target->GetPP().raid_leadership_exp = 0; - } - target->SendLeadershipEXPUpdate(); - } - - std::string aa_message = fmt::format( - "{} now {} {} {}AA Point{}.", - c->GetTargetDescription(target, TargetDescriptionType::UCYou), - c == target ? "have" : "has", - aa_points, - group_raid_string, - aa_points != 1 ? "s" : "" - - ); - c->Message( - Chat::White, - aa_message.c_str() - ); -} - diff --git a/zone/gm_commands/setaaxp.cpp b/zone/gm_commands/setaaxp.cpp deleted file mode 100755 index dbf81320f..000000000 --- a/zone/gm_commands/setaaxp.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "../client.h" -#include "../groups.h" -#include "../raids.h" -#include "../raids.h" - -void command_setaaxp(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (arguments <= 1 || !sep->IsNumber(2)) { - c->Message(Chat::White, "Usage: #setaaxp [AA|Group|Raid] [AA Experience]"); - return; - } - - Client *target = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); - } - - std::string aa_type = Strings::ToLower(sep->arg[1]); - std::string group_raid_string; - uint32 aa_experience = static_cast(std::min( - Strings::ToUnsignedBigInt(sep->arg[2]), - (uint64) 2000000000 - )); - bool is_aa = aa_type.find("aa") != std::string::npos; - bool is_group = aa_type.find("group") != std::string::npos; - bool is_raid = aa_type.find("raid") != std::string::npos; - if (!is_aa && !is_group && !is_raid) { - c->Message(Chat::White, "Usage: #setaaxp [AA|Group|Raid] [AA Experience]"); - return; - } - - if (is_aa) { - target->SetEXP( - target->GetEXP(), - aa_experience, - false - ); - } - else if (is_group) { - group_raid_string = "Group "; - target->SetLeadershipEXP( - aa_experience, - target->GetRaidEXP() - ); - } - else if (is_raid) { - group_raid_string = "Raid "; - target->SetLeadershipEXP( - target->GetGroupEXP(), - aa_experience - ); - } - - std::string aa_exp_message = fmt::format( - "{} now {} {} {}AA Experience.", - c->GetTargetDescription(target, TargetDescriptionType::UCYou), - c == target ? "have" : "has", - aa_experience, - group_raid_string - ); - c->Message( - Chat::White, - aa_exp_message.c_str() - ); -} - diff --git a/zone/gm_commands/setaltcurrency.cpp b/zone/gm_commands/setaltcurrency.cpp deleted file mode 100644 index d3208cc0c..000000000 --- a/zone/gm_commands/setaltcurrency.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "../client.h" - -void command_setaltcurrency(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if ( - arguments < 2 || - !sep->IsNumber(1) || - !sep->IsNumber(2) - ) { - c->Message(Chat::White, "Command Syntax: #setaltcurrency [Currency ID] [Amount]"); - return; - } - - auto target = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); - } - - auto currency_id = Strings::ToUnsignedInt(sep->arg[1]); - auto amount = static_cast(std::min(Strings::ToBigInt(sep->arg[2]), (int64) 2000000000)); - uint32 currency_item_id = zone->GetCurrencyItemID(currency_id); - if (!currency_item_id) { - c->Message( - Chat::White, - fmt::format( - "Currency ID {} could not be found.", - currency_id - ).c_str() - ); - return; - } - - target->SetAlternateCurrencyValue(currency_id, amount); - - c->Message( - Chat::White, - fmt::format( - "{} now {} {} {}.", - c->GetTargetDescription(target, TargetDescriptionType::UCYou), - c == target ? "have" : "has", - ( - amount ? - std::to_string(amount) : - "no" - ), - database.CreateItemLink(currency_item_id) - ).c_str() - ); -} - diff --git a/zone/gm_commands/setanim.cpp b/zone/gm_commands/setanim.cpp deleted file mode 100755 index 72f16edc9..000000000 --- a/zone/gm_commands/setanim.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "../client.h" - -void command_setanim(Client *c, const Seperator *sep) -{ - const auto arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1)) { - c->Message(Chat::White, "Usage: #setanim [Animation ID]"); - - uint32 animation_number = 1; - for (const auto& a : EQ::constants::GetSpawnAnimationMap()) { - c->Message( - Chat::White, - fmt::format( - "Animation {} | ID: {} Name: {}", - animation_number, - a.first, - a.second - ).c_str() - ); - - animation_number++; - } - return; - } - - Mob* target = c; - if (c->GetTarget()) { - target = c->GetTarget(); - } - - const auto animation_id = static_cast(Strings::ToUnsignedInt(sep->arg[1])); - if ( - !EQ::ValueWithin( - animation_id, - static_cast(eaStanding), - static_cast(eaLooting) - ) - ) { - c->Message(Chat::White, "Usage: #setanim [Animation ID]"); - - uint32 animation_number = 1; - for (const auto& a : EQ::constants::GetSpawnAnimationMap()) { - c->Message( - Chat::White, - fmt::format( - "Animation {} | ID: {} Name: {}", - animation_number, - a.first, - a.second - ).c_str() - ); - - animation_number++; - } - return; - } - - target->SetAppearance(static_cast(animation_id), false); - - const auto animation_name = EQ::constants::GetSpawnAnimationName(animation_id); - - c->Message( - Chat::White, - fmt::format( - "Set animation to {} ({}) for {}.", - animation_name, - animation_id, - c->GetTargetDescription(target) - ).c_str() - ); -} - diff --git a/zone/gm_commands/setcrystals.cpp b/zone/gm_commands/setcrystals.cpp deleted file mode 100755 index b2befc92a..000000000 --- a/zone/gm_commands/setcrystals.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "../client.h" - -void command_setcrystals(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (arguments <= 1 || !sep->IsNumber(2)) { - c->Message(Chat::White, "Usage: #setcrystals [Ebon|Radiant] [Crystal Amount]"); - return; - } - - Client *target = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); - } - - std::string crystal_type = Strings::ToLower(sep->arg[1]); - uint32 crystal_amount = static_cast(std::min( - Strings::ToUnsignedBigInt(sep->arg[2]), - (uint64) 2000000000 - )); - bool is_ebon = crystal_type.find("ebon") != std::string::npos; - bool is_radiant = crystal_type.find("radiant") != std::string::npos; - if (!is_ebon && !is_radiant) { - c->Message(Chat::White, "Usage: #setcrystals [Ebon|Radiant] [Crystal Amount]"); - return; - } - - uint32 crystal_item_id = ( - is_ebon ? - RuleI(Zone, EbonCrystalItemID) : - RuleI(Zone, RadiantCrystalItemID) - ); - - auto crystal_link = database.CreateItemLink(crystal_item_id); - if (is_radiant) { - target->SetRadiantCrystals(crystal_amount); - } else { - target->SetEbonCrystals(crystal_amount); - } - - c->Message( - Chat::White, - fmt::format( - "{} now {} {} {}.", - c->GetTargetDescription(target, TargetDescriptionType::UCYou), - c == target ? "have" : "has", - crystal_amount, - crystal_link - ).c_str() - ); -} - diff --git a/zone/gm_commands/setendurance.cpp b/zone/gm_commands/setendurance.cpp deleted file mode 100644 index 86da26008..000000000 --- a/zone/gm_commands/setendurance.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "../client.h" - -void command_setendurance(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1)) { - c->Message(Chat::White, "Usage: #setendurance [Endurance]"); - return; - } - - auto endurance = static_cast(std::min(Strings::ToBigInt(sep->arg[1]), (int64) 2000000000)); - bool set_to_max = false; - Mob* target = c; - if (c->GetTarget()) { - target = c->GetTarget(); - } - - if (target->IsClient()) { - if (endurance >= target->CastToClient()->GetMaxEndurance()) { - endurance = target->CastToClient()->GetMaxEndurance(); - set_to_max = true; - } - - target->CastToClient()->SetEndurance(endurance); - } else { - if (endurance >= target->GetMaxEndurance()) { - endurance = target->GetMaxEndurance(); - set_to_max = true; - } - - target->SetEndurance(endurance); - } - - c->Message( - Chat::White, - fmt::format( - "Set {} to {} Endurance{}.", - c->GetTargetDescription(target), - ( - set_to_max ? - "full" : - std::to_string(endurance) - ), - ( - set_to_max ? - fmt::format( - " ({})", - endurance - ) : - "" - ) - ).c_str() - ); -} diff --git a/zone/gm_commands/setfaction.cpp b/zone/gm_commands/setfaction.cpp deleted file mode 100755 index a3d8a82a3..000000000 --- a/zone/gm_commands/setfaction.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "../client.h" - -void command_setfaction(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1)) { - c->Message(Chat::White, "Usage: #setfaction [Faction ID]"); - return; - } - - if ( - !c->GetTarget() || - ( - c->GetTarget() && - c->GetTarget()->IsClient() - ) - ) { - c->Message(Chat::White, "You must target an NPC to use this command."); - return; - } - - NPC* target = c->GetTarget()->CastToNPC(); - auto npc_id = target->GetNPCTypeID(); - auto faction_id = Strings::ToInt(sep->arg[1]); - auto faction_name = content_db.GetFactionName(faction_id); - if (!faction_name.empty()) { - c->Message( - Chat::White, - fmt::format( - "Faction Changed | Name: {} ({}) Faction: {} ({}).", - target->GetCleanName(), - npc_id, - content_db.GetFactionName(faction_id), - faction_id - ).c_str() - ); - - std::string query = fmt::format( - "UPDATE npc_types SET npc_faction_id = {} WHERE id = {}", - faction_id, - npc_id - ); - content_db.QueryDatabase(query); - } else { - c->Message( - Chat::White, - "Invalid Faction ID, please specify a valid Faction ID." - ); - } -} - diff --git a/zone/gm_commands/sethp.cpp b/zone/gm_commands/sethp.cpp deleted file mode 100644 index 9c1463e13..000000000 --- a/zone/gm_commands/sethp.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "../client.h" - -void command_sethp(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1)) { - c->Message(Chat::White, "Usage: #sethp [Health]"); - return; - } - - auto health = static_cast(std::min(Strings::ToBigInt(sep->arg[1]), (int64) 2000000000)); - bool set_to_max = false; - Mob* target = c; - if (c->GetTarget()) { - target = c->GetTarget(); - } - - if (health >= target->GetMaxHP()) { - health = target->GetMaxHP(); - set_to_max = true; - } - - target->SetHP(health); - target->SendHPUpdate(); - - c->Message( - Chat::White, - fmt::format( - "Set {} to {} Health{}.", - c->GetTargetDescription(target), - ( - set_to_max ? - "full" : - std::to_string(health) - ), - ( - set_to_max ? - fmt::format( - " ({})", - health - ) : - "" - ) - ).c_str() - ); -} - diff --git a/zone/gm_commands/setlanguage.cpp b/zone/gm_commands/setlanguage.cpp deleted file mode 100755 index ad9b400ef..000000000 --- a/zone/gm_commands/setlanguage.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include "../client.h" -#include "../../common/languages.h" -#include "../../common/data_verification.h" - -void command_setlanguage(Client *c, const Seperator *sep) -{ - auto target = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); - } - - auto language_id = sep->IsNumber(1) ? Strings::ToInt(sep->arg[1]) : -1; - auto language_value = sep->IsNumber(2) ? Strings::ToInt(sep->arg[2]) : -1; - if (!strcasecmp(sep->arg[1], "list")) { - for (const auto& language : EQ::constants::GetLanguageMap()) { - c->Message( - Chat::White, - fmt::format( - "Language {}: {}", - language.first, - language.second - ).c_str() - ); - } - } else if ( - !EQ::ValueWithin(language_id, LANG_COMMON_TONGUE, LANG_UNKNOWN) || - !EQ::ValueWithin(language_value, 0, 100) - ) { - c->Message(Chat::White, "Usage: #setlanguage [Language ID] [Language Value]"); - c->Message(Chat::White, "Usage: #setlanguage [List]"); - c->Message(Chat::White, "Language ID = 0 to 27"); - c->Message(Chat::White, "Language Value = 0 to 100"); - } else { - LogInfo( - "Set language request from [{}], Target: [{}] Language ID: [{}] Language Value: [{}]", - c->GetCleanName(), - c->GetTargetDescription(target), - language_id, - language_value - ); - - target->SetLanguageSkill(language_id, language_value); - - if (c != target) { - c->Message( - Chat::White, - fmt::format( - "Set {} ({}) to {} for {}.", - EQ::constants::GetLanguageName(language_id), - language_id, - language_value, - c->GetTargetDescription(target) - ).c_str() - ); - } - } -} diff --git a/zone/gm_commands/setmana.cpp b/zone/gm_commands/setmana.cpp deleted file mode 100644 index 57e2e6ece..000000000 --- a/zone/gm_commands/setmana.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "../client.h" - -void command_setmana(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1)) { - c->Message(Chat::White, "Usage: #setmana [Mana]"); - return; - } - - auto mana = static_cast(std::min(Strings::ToBigInt(sep->arg[1]), (int64) 2000000000)); - bool set_to_max = false; - Mob* target = c; - if (c->GetTarget()) { - target = c->GetTarget(); - } - - if (target->IsClient()) { - if (mana >= target->CastToClient()->CalcMaxMana()) { - mana = target->CastToClient()->CalcMaxMana(); - set_to_max = true; - } - - target->CastToClient()->SetMana(mana); - } else { - if (mana >= target->CalcMaxMana()) { - mana = target->CalcMaxMana(); - set_to_max = true; - } - - target->SetMana(mana); - } - - c->Message( - Chat::White, - fmt::format( - "Set {} to {} Mana{}.", - c->GetTargetDescription(target), - ( - set_to_max ? - "full" : - std::to_string(mana) - ), - ( - set_to_max ? - fmt::format( - " ({})", - mana - ) : - "" - ) - ).c_str() - ); -} - diff --git a/zone/gm_commands/setpass.cpp b/zone/gm_commands/setpass.cpp deleted file mode 100755 index 88b02fdf0..000000000 --- a/zone/gm_commands/setpass.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "../client.h" - -void command_setpass(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (arguments < 2) { - c->Message(Chat::White, "Usage: #setpass [Account Name] [Password]"); - return; - } - - std::string account_name; - std::string loginserver; - ParseAccountString(sep->arg[1], account_name, loginserver); - int16 status = 0; - auto account_id = database.GetAccountIDByName(account_name, loginserver, &status); - if (!account_id) { - c->Message( - Chat::White, - fmt::format( - "Account {} not found.", - account_name - ).c_str() - ); - return; - } - - if (status > c->Admin()) { - c->Message( - Chat::White, - fmt::format( - "You cannot change the password for Account {} as its status is higher than yours.", - account_name - ).c_str() - ); - return; - } - - c->Message( - Chat::White, - fmt::format( - "Password {} changed for Account {}.", - ( - database.SetLocalPassword(account_id, sep->arg[2]) ? - "successfully" : - "failed" - ), - account_name - ).c_str() - ); -} - diff --git a/zone/gm_commands/setpvppoints.cpp b/zone/gm_commands/setpvppoints.cpp deleted file mode 100755 index 15b24a01a..000000000 --- a/zone/gm_commands/setpvppoints.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "../client.h" - -void command_setpvppoints(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1)) { - c->Message(Chat::White, "Command Syntax: #setpvppoints [Amount]"); - return; - } - - Client *target = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); - } - - uint32 pvp_points = static_cast(std::min(Strings::ToUnsignedBigInt(sep->arg[1]), (uint64) 2000000000)); - target->SetPVPPoints(pvp_points); - target->Save(); - target->SendPVPStats(); - std::string pvp_message = fmt::format( - "{} now {} {} PVP Point{}.", - c->GetTargetDescription(target, TargetDescriptionType::UCYou), - c == target ? "have" : "has", - pvp_points, - pvp_points != 1 ? "s" : "" - ); - c->Message( - Chat::White, - pvp_message.c_str() - ); -} - diff --git a/zone/gm_commands/setskillall.cpp b/zone/gm_commands/setskillall.cpp deleted file mode 100755 index 16f38a5ef..000000000 --- a/zone/gm_commands/setskillall.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "../client.h" - -void command_setskillall(Client *c, const Seperator *sep) -{ - const auto arguments = sep->argnum; - - if (!arguments || !sep->IsNumber(1)) { - c->Message(Chat::White, "Usage: #setskillall [Skill Level] - Set all of your or your target's skills to the specified skill level"); - return; - } - - auto t = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - t = c->GetTarget()->CastToClient(); - } - - if (c->Admin() < commandSetSkillsOther && t != c) { - c->Message(Chat::White, "Your status is not high enough to set another player's skills."); - return; - } - - auto skill_level = static_cast(Strings::ToUnsignedInt(sep->arg[1])); - - for (const auto& s : EQ::skills::GetSkillTypeMap()) { - if (c != t) { - c->Message( - Chat::White, - fmt::format( - "Setting {} ({}) to {} for {}.", - s.second, - s.first, - skill_level > t->MaxSkill(s.first) ? t->MaxSkill(s.first) : skill_level, - c->GetTargetDescription(t) - ).c_str() - ); - } - - t->SetSkill( - s.first, - skill_level > t->MaxSkill(s.first) ? t->MaxSkill(s.first) : skill_level - ); - } -} diff --git a/zone/gm_commands/setstartzone.cpp b/zone/gm_commands/setstartzone.cpp deleted file mode 100755 index 7accda12e..000000000 --- a/zone/gm_commands/setstartzone.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "../client.h" - -void command_setstartzone(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments) { - c->Message(Chat::White, "Usage: #setstartzone [Zone ID|Zone Short Name]"); - c->Message( - Chat::White, - "Optional Usage: Use '#setstartzone Reset' or '#setstartzone 0' to clear a starting zone. Player can select a starting zone using /setstartcity" - ); - return; - } - - auto target = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); - } - - auto zone_id = ( - sep->IsNumber(1) ? - Strings::ToUnsignedInt(sep->arg[1]) : - ZoneID(sep->arg[1]) - ); - - target->SetStartZone(zone_id); - - bool is_reset = ( - !strcasecmp(sep->arg[1], "reset") || - zone_id == 0 - ); - - c->Message( - Chat::White, - fmt::format( - "Start Zone {} for {} |{}", - is_reset ? "Reset" : "Changed", - c->GetTargetDescription(target, TargetDescriptionType::UCSelf), - ( - zone_id ? - fmt::format( - " {} ({}) ID: {}", - ZoneLongName(zone_id), - ZoneName(zone_id), - zone_id - ) : - "" - ) - ).c_str() - ); -} - diff --git a/zone/gm_commands/setstat.cpp b/zone/gm_commands/setstat.cpp deleted file mode 100755 index 7e4c42cd3..000000000 --- a/zone/gm_commands/setstat.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "../client.h" - -void command_setstat(Client *c, const Seperator *sep) -{ - if (sep->arg[1][0] && sep->arg[2][0] && c->GetTarget() != 0 && c->GetTarget()->IsClient()) { - c->GetTarget()->CastToClient()->SetStats(Strings::ToInt(sep->arg[1]), Strings::ToInt(sep->arg[2])); - } - else { - c->Message(Chat::White, "This command is used to permanently increase or decrease a players stats."); - c->Message(Chat::White, "Usage: #setstat {type} {value the stat should be}"); - c->Message(Chat::White, "Types: Str: 0, Sta: 1, Agi: 2, Dex: 3, Int: 4, Wis: 5, Cha: 6"); - } -} - diff --git a/zone/gm_commands/setxp.cpp b/zone/gm_commands/setxp.cpp deleted file mode 100755 index 8aa810b0b..000000000 --- a/zone/gm_commands/setxp.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "../client.h" - -void command_setxp(Client *c, const Seperator *sep) -{ - Client *t = c; - - if (c->GetTarget() && c->GetTarget()->IsClient()) { - t = c->GetTarget()->CastToClient(); - } - - if (sep->IsNumber(1)) { - if (Strings::ToInt(sep->arg[1]) > 9999999) { - c->Message(Chat::White, "Error: Value too high."); - } - else { - t->AddEXP(Strings::ToInt(sep->arg[1])); - } - } - else { - c->Message(Chat::White, "Usage: #setxp number"); - } -} - diff --git a/zone/gm_commands/show.cpp b/zone/gm_commands/show.cpp index d88410984..2bea01355 100755 --- a/zone/gm_commands/show.cpp +++ b/zone/gm_commands/show.cpp @@ -121,8 +121,19 @@ void command_show(Client *c, const Seperator *sep) // build the rewrite string const std::string& rewrite = fmt::format("#show {} {}", cmd.cmd, Strings::Join(args, " ")); - // rewrite to #show + // rewrite to #show > c->SendGMCommand(rewrite); + + c->Message( + Chat::Gray, + fmt::format( + "{} is now located under {}, using {}.", + sep->arg[0], + Saylink::Silent("#show"), + Saylink::Silent(rewrite) + ).c_str() + ); + return; } } diff --git a/zone/gm_commands/show/recipe.cpp b/zone/gm_commands/show/recipe.cpp index 0bc980316..95cae95cc 100644 --- a/zone/gm_commands/show/recipe.cpp +++ b/zone/gm_commands/show/recipe.cpp @@ -6,7 +6,7 @@ void ShowRecipe(Client *c, const Seperator *sep) { if (!sep->IsNumber(2)) { - c->Message(Chat::White, "Command Syntax: #show recipe [Recipe ID]"); + c->Message(Chat::White, "Usage: #show recipe [Recipe ID]"); return; } @@ -43,7 +43,7 @@ void ShowRecipe(Client *c, const Seperator *sep) ); uint32 entry_number = 1; - const bool can_summon_items = c->Admin() >= GetCommandStatus(c, "summonitem"); + const bool can_summon_items = c->Admin() >= GetCommandStatus("summonitem"); for (const auto& e : re) { c->Message( diff --git a/zone/gm_commands/tempname.cpp b/zone/gm_commands/tempname.cpp deleted file mode 100755 index 849549472..000000000 --- a/zone/gm_commands/tempname.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "../client.h" - -void command_tempname(Client *c, const Seperator *sep) -{ - Mob *target; - target = c->GetTarget(); - - if (!target) { - c->Message(Chat::White, "Usage: #tempname newname (requires a target)"); - } - else if (strlen(sep->arg[1]) > 0) { - char *oldname = strdup(target->GetName()); - target->TempName(sep->arg[1]); - c->Message(Chat::White, "Renamed %s to %s", oldname, sep->arg[1]); - free(oldname); - } - else { - target->TempName(); - c->Message(Chat::White, "Restored the original name"); - } -} - diff --git a/zone/gm_commands/texture.cpp b/zone/gm_commands/texture.cpp deleted file mode 100755 index 518b91549..000000000 --- a/zone/gm_commands/texture.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include "../client.h" - -void command_texture(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1)) { - c->Message(Chat::White, "Usage: #texture [Texture] [Helmet Texture]"); - return; - } - - auto texture = static_cast(std::min(Strings::ToUnsignedInt(sep->arg[1]), (uint32) 65535)); - auto helmet_texture = static_cast( - sep->IsNumber(2) ? - std::min(Strings::ToUnsignedInt(sep->arg[2]), (uint32) 255) : - 0 - ); - - Mob* target = c; - if (c->GetTarget() && c->Admin() >= commandTextureOthers) { - target = c->GetTarget(); - } - - if (IsPlayerRace(target->GetModel())) { // Player Races Wear Armor, so Wearchange is sent instead - for ( - int texture_slot = EQ::textures::textureBegin; - texture_slot <= EQ::textures::LastTintableTexture; - texture_slot++ - ) { - target->SendTextureWC(texture_slot, texture); - } - } else { // Non-Player Races only need Illusion Packets to be sent for texture - target->SendIllusionPacket( - target->GetModel(), - target->GetGender(), - texture, - helmet_texture - ); - } - - c->Message( - Chat::White, - fmt::format( - "Texture Changed for {} | Texture: {}{}", - c->GetTargetDescription(target, TargetDescriptionType::UCSelf), - texture, - ( - IsPlayerRace(target->GetModel()) ? - "" : - fmt::format( - " Helmet Texture: {}", - helmet_texture - ) - ) - ).c_str() - ); -} - diff --git a/zone/gm_commands/time.cpp b/zone/gm_commands/time.cpp deleted file mode 100755 index 7df178eca..000000000 --- a/zone/gm_commands/time.cpp +++ /dev/null @@ -1,128 +0,0 @@ -#include "../client.h" - -void command_time(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1)) { - c->Message(Chat::White, "Usage: #time [Hour] [Minute]"); - - TimeOfDay_Struct world_time; - zone->zone_time.GetCurrentEQTimeOfDay(time(0), &world_time); - - auto time_string = fmt::format( - "{:02}:{:02} {} (Timezone: {:02}:{:02} {})", - ( - ((world_time.hour - 1) % 12) == 0 ? - 12 : - ((world_time.hour - 1) % 12) - ), - world_time.minute, - ( - world_time.hour >= 13 ? - "PM" : - "AM" - ), - ( - ((zone->zone_time.getEQTimeZoneHr() - 1) % 12) == 0 ? - 12 : - ((zone->zone_time.getEQTimeZoneHr() - 1) % 12) - ), - zone->zone_time.getEQTimeZoneMin(), - ( - zone->zone_time.getEQTimeZoneHr() >= 13 ? - "PM" : - "AM" - ) - ); - - c->Message( - Chat::White, - fmt::format( - "It is currently {}.", - time_string - ).c_str() - ); - - return; - } - - uint8 minutes = 0; - auto hours = static_cast(Strings::ToUnsignedInt(sep->arg[1]) + 1); - - if (hours > 24) { - hours = 24; - } - - uint8 real_hours = ( - (hours - 1) > 0 ? - (hours - 1) : - 0 - ); - - if (sep->IsNumber(2)) { - minutes = static_cast(Strings::ToUnsignedInt(sep->arg[2])); - - if (minutes > 59) { - minutes = 59; - } - } - - c->Message( - Chat::White, - fmt::format( - "Setting world time to {:02}:{:02} {} (Timezone: {:02}:{:02} {}).", - ( - (hours % 12) == 0 ? - 12 : - (hours % 12) - ), - minutes, - ( - hours >= 13 ? - "PM" : - "AM" - ), - ( - ((zone->zone_time.getEQTimeZoneHr() - 1) % 12) == 0 ? - 12 : - ((zone->zone_time.getEQTimeZoneHr() - 1) % 12) - ), - zone->zone_time.getEQTimeZoneMin(), - ( - zone->zone_time.getEQTimeZoneHr() >= 13 ? - "PM" : - "AM" - ) - ).c_str() - ); - - zone->SetTime(real_hours, minutes); - - LogInfo( - "{} :: Setting world time to {:02}:{:02} {} (Timezone: {:02}:{:02} {})", - c->GetCleanName(), - ( - (hours % 12) == 0 ? - 12 : - (hours % 12) - ), - minutes, - ( - hours >= 13 ? - "PM" : - "AM" - ), - ( - ((zone->zone_time.getEQTimeZoneHr() - 1) % 12) == 0 ? - 12 : - ((zone->zone_time.getEQTimeZoneHr() - 1) % 12) - ), - zone->zone_time.getEQTimeZoneMin(), - ( - zone->zone_time.getEQTimeZoneHr() >= 13 ? - "PM" : - "AM" - ) - ); -} - diff --git a/zone/gm_commands/timezone.cpp b/zone/gm_commands/timezone.cpp deleted file mode 100755 index 9270f1445..000000000 --- a/zone/gm_commands/timezone.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include "../client.h" - -void command_timezone(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1)) { - c->Message(Chat::White, "Usage: #timezone [Hour] [Minute]"); - c->Message( - Chat::White, - fmt::format( - "Current timezone is {:02}:{:02} {}.", - ( - ((zone->zone_time.getEQTimeZoneHr() - 1) % 12) == 0 ? - 12 : - ((zone->zone_time.getEQTimeZoneHr() - 1) % 12) - ), - zone->zone_time.getEQTimeZoneMin(), - ( - zone->zone_time.getEQTimeZoneHr() >= 13 ? - "PM" : - "AM" - ) - ).c_str() - ); - return; - } - - uint8 minutes = 0; - auto hours = static_cast(Strings::ToUnsignedInt(sep->arg[1])); - - if (hours > 24) { - hours = 24; - } - - uint8 real_hours = ( - (hours - 1) > 0 ? - (hours - 1) : - 0 - ); - - if (sep->IsNumber(2)) { - minutes = static_cast(Strings::ToUnsignedInt(sep->arg[2])); - - if (minutes > 59) { - minutes = 59; - } - } - - c->Message( - Chat::White, - fmt::format( - "Setting timezone to {:02}:{:02} {}.", - ( - (real_hours % 12) == 0 ? - 12 : - (real_hours % 12) - ), - minutes, - ( - hours >= 13 ? - "PM" : - "AM" - ) - ).c_str() - ); - - uint32 new_timezone = ((hours * 60) + minutes); - zone->zone_time.setEQTimeZone(new_timezone); - content_db.SetZoneTZ(zone->GetZoneID(), zone->GetInstanceVersion(), new_timezone); - - auto outapp = new EQApplicationPacket(OP_TimeOfDay, sizeof(TimeOfDay_Struct)); - TimeOfDay_Struct *tod = (TimeOfDay_Struct *) outapp->pBuffer; - zone->zone_time.GetCurrentEQTimeOfDay(time(0), tod); - entity_list.QueueClients(c, outapp); - safe_delete(outapp); -} - diff --git a/zone/gm_commands/title.cpp b/zone/gm_commands/title.cpp deleted file mode 100755 index 653355608..000000000 --- a/zone/gm_commands/title.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "../client.h" -#include "../titles.h" - -void command_title(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments) { - c->Message(Chat::White, "Usage: #title [Title] (use \"-1\" to remove title)"); - return; - } - - bool is_remove = !strcasecmp(sep->argplus[1], "-1"); - std::string title = is_remove ? "" : sep->argplus[1]; - - auto target = c; - if (c->GetTarget() && c->GetTarget()->IsClient()) { - target = c->GetTarget()->CastToClient(); - } - - if (title.size() > 31) { - c->Message(Chat::White, "Title must be 31 characters or less."); - return; - } - - if (!title.empty()) { - Strings::FindReplace(title, "_", " "); - } - - if (is_remove) { - target->SetAATitle(title); - } else { - title_manager.CreateNewPlayerTitle(target, title); - } - - target->Save(); - - c->Message( - Chat::White, - fmt::format( - "Title has been {}{} for {}{}", - is_remove ? "removed" : "changed", - !is_remove ? " and saved" : "", - c->GetTargetDescription(target), - ( - is_remove ? - "." : - fmt::format( - " to '{}'.", - title - ) - ) - ).c_str() - ); -} - - diff --git a/zone/gm_commands/unfreeze.cpp b/zone/gm_commands/unfreeze.cpp deleted file mode 100755 index c9658fb7b..000000000 --- a/zone/gm_commands/unfreeze.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "../client.h" - -void command_unfreeze(Client *c, const Seperator *sep) -{ - if (!c->GetTarget()) { - c->Message(Chat::White, "You must have a target to use this command."); - return; - } - - auto target = c->GetTarget(); - target->SendAppearancePacket(AT_Anim, ANIM_STAND); - - c->Message( - Chat::White, - fmt::format( - "You have unfrozen {}.", - c->GetTargetDescription(target) - ).c_str() - ); -} - diff --git a/zone/gm_commands/zclip.cpp b/zone/gm_commands/zclip.cpp deleted file mode 100755 index 09c7e0e64..000000000 --- a/zone/gm_commands/zclip.cpp +++ /dev/null @@ -1,110 +0,0 @@ -#include "../client.h" - -void command_zclip(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (arguments <= 3) { - c->Message( - Chat::White, - "Usage: #zclip [Minimum Clip] [Maximum Clip] [Fog Minimum Clip] [Fog Maximum Clip] [Permanent (0 = False, 1 = True)]" - ); - return; - } - - auto minimum_clip = sep->arg[1] ? Strings::ToFloat(sep->arg[1]) : 0; - auto maximum_clip = sep->arg[2] ? Strings::ToFloat(sep->arg[2]) : 0; - auto minimum_fog_clip = sep->arg[3] ? Strings::ToFloat(sep->arg[3]) : 0; - auto maximum_fog_clip = sep->arg[4] ? Strings::ToFloat(sep->arg[4]) : 0; - - auto permanent = sep->arg[5] ? atobool(sep->arg[5]) : false; - if (minimum_clip <= 0 || maximum_clip <= 0) { - c->Message(Chat::White, "Minimum Clip and Maximum Clip must be greater than 0."); - return; - } - else if (minimum_clip > maximum_clip) { - c->Message(Chat::White, "Minimum Clip must be less than or equal to Maximum Clip!"); - return; - } - else { - zone->newzone_data.minclip = minimum_clip; - zone->newzone_data.maxclip = maximum_clip; - - if (minimum_fog_clip) { - for (float &fog_index: zone->newzone_data.fog_minclip) { - fog_index = minimum_fog_clip; - } - } - - if (maximum_fog_clip) { - for (float &fog_index: zone->newzone_data.fog_maxclip) { - fog_index = maximum_fog_clip; - } - } - - if (permanent) { - auto query = fmt::format( - "UPDATE zone SET minclip = {:.2f}, maxclip = {:.2f} WHERE zoneidnumber = {} AND version = {}", - minimum_clip, - maximum_clip, - zone->GetZoneID(), - zone->GetInstanceVersion() - ); - database.QueryDatabase(query); - - if (minimum_fog_clip) { - query = fmt::format( - "UPDATE zone SET fog_minclip = {:.2f} WHERE zoneidnumber = {} AND version = {}", - minimum_fog_clip, - zone->GetZoneID(), - zone->GetInstanceVersion() - ); - database.QueryDatabase(query); - } - - if (maximum_fog_clip) { - query = fmt::format( - "UPDATE zone SET fog_maxclip = {:.2f} WHERE zoneidnumber = {} AND version = {}", - maximum_fog_clip, - zone->GetZoneID(), - zone->GetInstanceVersion() - ); - database.QueryDatabase(query); - } - } - - auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct)); - memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size); - entity_list.QueueClients(c, outapp); - safe_delete(outapp); - - c->Message( - Chat::White, - fmt::format( - "Clipping Changed | Zone: {} Permanent: {}", - zone->GetZoneDescription(), - permanent ? "Yes" : "No" - ).c_str() - ); - - c->Message( - Chat::White, - fmt::format( - "Clipping Changed | Minimum Clip: {:.2f} Maximum Clip: {:.2f}", - minimum_clip, - maximum_clip - ).c_str() - ); - - if (minimum_fog_clip || maximum_fog_clip) { - c->Message( - Chat::White, - fmt::format( - "Clipping Changed | Fog Minimum Clip: {:.2f} Fog Maximum Clip: {:.2f}", - minimum_fog_clip, - maximum_fog_clip - ).c_str() - ); - } - } -} - diff --git a/zone/gm_commands/zcolor.cpp b/zone/gm_commands/zcolor.cpp deleted file mode 100755 index 9e107d1f6..000000000 --- a/zone/gm_commands/zcolor.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "../client.h" - -void command_zcolor(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if ( - !arguments || - !sep->IsNumber(1) || - !sep->IsNumber(2) || - !sep->IsNumber(3) - ) { - c->Message(Chat::White, "Usage: #zcolor [Red] [Green] [Blue] [Permanent (0 = False, 1 = True)]"); - return; - } - - auto red = Strings::ToUnsignedInt(sep->arg[1]); - auto green = Strings::ToUnsignedInt(sep->arg[2]); - auto blue = Strings::ToUnsignedInt(sep->arg[3]); - auto permanent = sep->arg[4] ? atobool(sep->arg[4]) : false; - if ( - red < 0 || - red > 255 || - green < 0 || - green > 255 || - blue < 0 || - blue > 255 - ) { - c->Message(Chat::White, "Colors cannot be less than 0 or greater than 255."); - return; - } - - if (permanent) { - auto query = fmt::format( - "UPDATE zone SET fog_red = {}, fog_green = {}, fog_blue = {} " - "WHERE zoneidnumber = {} AND version = {}", - red, - green, - blue, - zone->GetZoneID(), - zone->GetInstanceVersion() - ); - database.QueryDatabase(query); - } - - for (int fog_index = 0; fog_index < 4; fog_index++) { - zone->newzone_data.fog_red[fog_index] = static_cast(red); - zone->newzone_data.fog_green[fog_index] = static_cast(green); - zone->newzone_data.fog_blue[fog_index] = static_cast(blue); - } - - auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct)); - memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size); - entity_list.QueueClients(c, outapp); - safe_delete(outapp); - - c->Message( - Chat::White, - fmt::format( - "Fog Color Changed | Zone: {} Red: {} Green: {} Blue: {} Permanent: {}", - zone->GetZoneDescription(), - red, - green, - blue, - permanent ? "Yes" : "No" - ).c_str() - ); -} diff --git a/zone/gm_commands/zheader.cpp b/zone/gm_commands/zheader.cpp deleted file mode 100755 index 2b486fb10..000000000 --- a/zone/gm_commands/zheader.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "../client.h" - -void command_zheader(Client *c, const Seperator *sep) -{ - const auto arguments = sep->argnum; - if (!arguments) { - c->Message(Chat::White, "Usage: #zheader [Zone ID|Zone Short Name] [Version]"); - return; - } - - const auto zone_id = ( - sep->IsNumber(1) ? - Strings::ToUnsignedInt(sep->arg[1]) : - ZoneID(sep->arg[1]) - ); - if (!zone_id) { - c->Message( - Chat::White, - fmt::format( - "Zone ID {} could not be found.", - zone_id - ).c_str() - ); - return; - } - - auto zone_short_name = ZoneName(zone_id); - auto zone_long_name = ZoneLongName(zone_id); - const auto version = ( - sep->IsNumber(2) ? - Strings::ToUnsignedInt(sep->arg[2]) : - 0 - ); - - auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct)); - memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size); - entity_list.QueueClients(c, outapp); - safe_delete(outapp); - - zone_store.LoadZones(content_db); - - c->Message( - Chat::White, - fmt::format( - "Zone Header Load {} | Zone: {} ({}){}", - ( - zone->LoadZoneCFG(zone_short_name, version) ? - "Succeeded" : - "Failed" - ), - zone_long_name, - zone_short_name, - ( - version ? - fmt::format( - " Version: {}", - version - ) : - "" - ) - ).c_str() - ); -} diff --git a/zone/gm_commands/zonelock.cpp b/zone/gm_commands/zonelock.cpp deleted file mode 100755 index 1f0de1f0a..000000000 --- a/zone/gm_commands/zonelock.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include "../client.h" -#include "../worldserver.h" - -extern WorldServer worldserver; - -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 = Strings::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 *lock_zone = (ServerLockZone_Struct *) pack->pBuffer; - strn0cpy(lock_zone->adminname, c->GetName(), sizeof(lock_zone->adminname)); - - if (is_list) { - lock_zone->op = ServerLockType::List; - worldserver.SendPacket(pack); - } - else if (!is_list && c->Admin() >= commandLockZones) { - auto zone_id = ( - sep->IsNumber(2) ? - static_cast(Strings::ToUnsignedInt(sep->arg[2])) : - static_cast(ZoneID(sep->arg[2])) - ); - std::string zone_short_name = Strings::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 ? ServerLockType::Lock : ServerLockType::Unlock; - lock_zone->zoneID = zone_id; - worldserver.SendPacket(pack); - } - else { - c->Message( - Chat::White, - fmt::format( - "Usage: #zonelock {0} [Zone ID] or #zonelock {0} [Zone Short Name]", - is_lock ? "lock" : "unlock" - ).c_str() - ); - } - } - safe_delete(pack); -} - diff --git a/zone/gm_commands/zsafecoords.cpp b/zone/gm_commands/zsafecoords.cpp deleted file mode 100755 index 4f3e5be4b..000000000 --- a/zone/gm_commands/zsafecoords.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include "../client.h" - -void command_zsafecoords(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if ( - !arguments || - !sep->IsNumber(1) || - !sep->IsNumber(2) || - !sep->IsNumber(3) - ) { - c->Message(Chat::White, "Usage: #zsafecoords [X] [Y] [Z] [Heading] [Permanent (0 = False, 1 = True)]"); - c->Message(Chat::White, "Not sending Heading defaults to current Heading and the change is temporary."); - return; - } - - auto x = Strings::ToFloat(sep->arg[1]); - auto y = Strings::ToFloat(sep->arg[2]); - auto z = Strings::ToFloat(sep->arg[3]); - auto heading = sep->arg[3] ? Strings::ToFloat(sep->arg[3]) : c->GetHeading(); - auto permanent = sep->arg[4] ? atobool(sep->arg[4]) : false; - if (permanent) { - auto query = fmt::format( - "UPDATE zone SET safe_x = {:.2f}, safe_y = {:.2f}, safe_z = {:.2f}, safe_heading = {:.2f} WHERE zoneidnumber = {} AND version = {}", - x, - y, - z, - heading, - zone->GetZoneID(), - zone->GetInstanceVersion() - ); - database.QueryDatabase(query); - } - - zone->newzone_data.safe_x = x; - zone->newzone_data.safe_y = y; - zone->newzone_data.safe_z = z; - - auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct)); - memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size); - entity_list.QueueClients(c, outapp); - safe_delete(outapp); - - c->Message( - Chat::White, - fmt::format( - "Safe Coordinates Changed | Zone: {} XYZ: {:.2f}, {:.2f}, {:.2f} Heading: {:.2f} Permanent: {} ", - zone->GetZoneDescription(), - x, - y, - z, - heading, - permanent ? "Yes" : "No" - ).c_str() - ); -} - diff --git a/zone/gm_commands/zsky.cpp b/zone/gm_commands/zsky.cpp deleted file mode 100755 index 5802b7011..000000000 --- a/zone/gm_commands/zsky.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "../client.h" - -void command_zsky(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1)) { - c->Message(Chat::White, "Usage: #zsky [Sky Type] [Permanent (0 = False, 1 = True)]"); - return; - } - - auto sky_type = Strings::ToUnsignedInt(sep->arg[1]); - auto permanent = sep->arg[2] ? atobool(sep->arg[2]) : false; - if (sky_type < 0 || sky_type > 255) { - c->Message(Chat::White, "Sky Type cannot be less than 0 or greater than 255!"); - return; - } - - if (permanent) { - auto query = fmt::format( - "UPDATE zone SET sky = {} WHERE zoneidnumber = {} AND version = {}", - sky_type, - zone->GetZoneID(), - zone->GetInstanceVersion() - ); - database.QueryDatabase(query); - } - - zone->newzone_data.sky = static_cast(sky_type); - auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct)); - memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size); - entity_list.QueueClients(c, outapp); - safe_delete(outapp); - - c->Message( - Chat::White, - fmt::format( - "Sky Changed | Zone: {} Sky Type: {} Permanent: {}", - zone->GetZoneDescription(), - sky_type, - permanent ? "Yes" : "No" - ).c_str() - ); -} diff --git a/zone/gm_commands/zunderworld.cpp b/zone/gm_commands/zunderworld.cpp deleted file mode 100755 index 8f7c8832d..000000000 --- a/zone/gm_commands/zunderworld.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "../client.h" - -void command_zunderworld(Client *c, const Seperator *sep) -{ - int arguments = sep->argnum; - if (!arguments || !sep->IsNumber(1)) { - c->Message(Chat::White, "Usage: #zunderworld [Z] [Permanent (0 = False, 1 = True)]"); - return; - } - - auto z = Strings::ToFloat(sep->arg[1]); - auto permanent = sep->arg[2] ? atobool(sep->arg[2]) : false; - if (permanent) { - auto query = fmt::format( - "UPDATE zone SET underworld = {:.2f} WHERE zoneidnumber = {} AND version = {}", - z, - zone->GetZoneID(), - zone->GetInstanceVersion() - ); - database.QueryDatabase(query); - } - - zone->newzone_data.underworld = z; - auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct)); - memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size); - entity_list.QueueClients(c, outapp); - safe_delete(outapp); - - c->Message( - Chat::White, - fmt::format( - "Underworld Z Changed | Zone: {} Z: {:.2f} Permanent: {}", - zone->GetZoneDescription(), - z, - permanent ? "Yes" : "No" - ).c_str() - ); -}