Merge remote-tracking branch 'upstream/master'

This commit is contained in:
neckkola
2023-07-15 13:43:01 -03:00
181 changed files with 5397 additions and 3821 deletions
+25
View File
@@ -1,3 +1,28 @@
## [22.20.0] - 07/15/2023
### Bots
* Remove orphaned commands related to botgroup ([#3489](https://github.com/EQEmu/Server/pull/3489)) @tuday2 2023-07-09
### Commands
* Consolidate #set-like commands into a singular #set command ([#3486](https://github.com/EQEmu/Server/pull/3486)) @Kinglykrab 2023-07-15
### Feature
* Add Support for item textures higher than 65,535 ([#3494](https://github.com/EQEmu/Server/pull/3494)) @Kinglykrab 2023-07-14
* Update raid features ([#3443](https://github.com/EQEmu/Server/pull/3443)) @neckkola 2023-07-13
### Fixes
* Fix Tradeskill Combines with augmented items ([#3490](https://github.com/EQEmu/Server/pull/3490)) @Kinglykrab 2023-07-15
* Fix charmed pets to follow when charmed. ([#3488](https://github.com/EQEmu/Server/pull/3488)) @noudess 2023-07-08
* Update bot naming check and add more explanation ([#3491](https://github.com/EQEmu/Server/pull/3491)) @tuday2 2023-07-13
### Quest API
* Add Mob/Entity type check methods to Perl/Lua ([#3493](https://github.com/EQEmu/Server/pull/3493)) @Kinglykrab 2023-07-13
## [22.19.0] - 07/08/2023
### Bots
@@ -4758,6 +4758,52 @@ CREATE TABLE `chatchannel_reserved_names`
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
)"
},
ManifestEntry{
.version = 9230,
.description = "2023_06_23_raid_feature_updates",
.check = "SHOW COLUMNS FROM `raid_members` LIKE 'is_assister'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `raid_members`
ADD COLUMN `is_marker` TINYINT UNSIGNED DEFAULT(0) NOT NULL AFTER `islooter`,
ADD COLUMN `is_assister` TINYINT UNSIGNED DEFAULT(0) NOT NULL AFTER `is_marker`,
ADD COLUMN `note` VARCHAR(64) DEFAULT("") NOT NULL AFTER `is_assister`;
ALTER TABLE `raid_details`
ADD COLUMN `marked_npc_1` SMALLINT UNSIGNED DEFAULT(0) NOT NULL AFTER `motd`,
ADD COLUMN `marked_npc_2` SMALLINT UNSIGNED DEFAULT(0) NOT NULL AFTER `marked_npc_1`,
ADD COLUMN `marked_npc_3` SMALLINT UNSIGNED DEFAULT(0) NOT NULL AFTER `marked_npc_2`;
)",
},
ManifestEntry{
.version = 9231,
.description = "2023_07_14_npc_unsigned_melee_texture.sql",
.check = "SHOW COLUMNS FROM `npc_types` LIKE 'd_melee_texture1'",
.condition = "contains",
.match = "int(11) signed",
.sql = R"(ALTER TABLE `npc_types`
MODIFY COLUMN `d_melee_texture1` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `armortint_blue`,
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`)
)
)"
},
+3
View File
@@ -316,6 +316,7 @@ N(OP_LootRequest),
N(OP_ManaChange),
N(OP_ManaUpdate),
N(OP_MarkNPC),
N(OP_MarkRaidNPC),
N(OP_Marquee),
N(OP_MemorizeSpell),
N(OP_Mend),
@@ -398,6 +399,8 @@ N(OP_PVPLeaderBoardRequest),
N(OP_PVPStats),
N(OP_QueryResponseThing),
N(OP_QueryUCSServerStatus),
N(OP_RaidDelegateAbility),
N(OP_RaidClearNPCMarks),
N(OP_RaidInvite),
N(OP_RaidJoin),
N(OP_RaidUpdate),
+7 -3
View File
@@ -4105,7 +4105,9 @@ struct UpdateLeadershipAA_Struct {
enum
{
GroupLeadershipAbility_MarkNPC = 0
GroupLeadershipAbility_MarkNPC = 0,
RaidLeadershipAbility_MarkNPC = 16,
RaidLeadershipAbility_MainAssist = 19
};
struct DoGroupLeadershipAbility_Struct
@@ -4149,8 +4151,10 @@ struct InspectBuffs_Struct {
struct RaidGeneral_Struct {
/*00*/ uint32 action; //=10
/*04*/ char player_name[64]; //should both be the player's name
/*64*/ char leader_name[64];
/*132*/ uint32 parameter;
/*68*/ uint32 unknown1;
/*72*/ char leader_name[64];
/*136*/ uint32 parameter;
/*200*/ char note[64];
};
struct RaidAddMember_Struct {
+15 -29
View File
@@ -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
};
+5 -3
View File
@@ -720,12 +720,14 @@ EQ::ItemInstance* EQ::ItemInstance::RemoveAugment(uint8 index)
bool EQ::ItemInstance::IsAugmented()
{
if (!m_item || !m_item->IsClassCommon())
if (!m_item || !m_item->IsClassCommon()) {
return false;
}
for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) {
if (GetAugmentItemID(index))
for (uint8 slot_id = invaug::SOCKET_BEGIN; slot_id <= invaug::SOCKET_END; ++slot_id) {
if (GetAugmentItemID(slot_id)) {
return true;
}
}
return false;
+14 -1
View File
@@ -35,6 +35,7 @@
#include "../path_manager.h"
#include "../classes.h"
#include "../races.h"
#include "../../zone/raids.h"
#include <iostream>
#include <sstream>
@@ -2737,7 +2738,7 @@ namespace RoF2
{
RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
auto outapp =
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
outlaa->action = inlaa->action;
@@ -2746,6 +2747,18 @@ namespace RoF2
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
dest->FastQueuePacket(&outapp);
}
else if (raid_gen->action == raidSetNote)
{
auto in_note = (RaidGeneral_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidGeneral_Struct));
auto note = (RaidGeneral_Struct*)outapp->pBuffer;
note->action = raidSetNote;
strn0cpy(note->leader_name, in_note->leader_name, sizeof(note->leader_name));
strn0cpy(note->player_name, in_note->player_name, sizeof(note->leader_name));
strn0cpy(note->note, in_note->note, sizeof(note->note));
dest->QueuePacket(outapp);
safe_delete(outapp);
}
else
{
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
@@ -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 <ctime>
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<std::string> Columns()
{
return {
"id",
"parent_command",
"sub_command",
"access_level",
"top_level_aliases",
};
}
static std::vector<std::string> 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<CommandSubsettings> &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<uint32_t>(strtoul(row[0], nullptr, 10));
e.parent_command = row[1] ? row[1] : "";
e.sub_command = row[2] ? row[2] : "";
e.access_level = static_cast<uint32_t>(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<std::string> 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<std::string> 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<CommandSubsettings> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> 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<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<CommandSubsettings> All(Database& db)
{
std::vector<CommandSubsettings> 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<uint32_t>(strtoul(row[0], nullptr, 10));
e.parent_command = row[1] ? row[1] : "";
e.sub_command = row[2] ? row[2] : "";
e.access_level = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.top_level_aliases = row[4] ? row[4] : "";
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<CommandSubsettings> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<CommandSubsettings> 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<uint32_t>(strtoul(row[0], nullptr, 10));
e.parent_command = row[1] ? row[1] : "";
e.sub_command = row[2] ? row[2] : "";
e.access_level = static_cast<uint32_t>(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
@@ -66,8 +66,8 @@ public:
uint8_t armortint_red;
uint8_t armortint_green;
uint8_t armortint_blue;
int32_t d_melee_texture1;
int32_t d_melee_texture2;
uint32_t d_melee_texture1;
uint32_t d_melee_texture2;
std::string ammo_idfile;
uint8_t prim_melee_type;
uint8_t sec_melee_type;
@@ -583,7 +583,7 @@ public:
e.exp_mod = 100;
e.heroic_strikethrough = 0;
e.faction_amount = 0;
e.keeps_sold_items = 0;
e.keeps_sold_items = 1;
return e;
}
@@ -666,8 +666,8 @@ public:
e.armortint_red = static_cast<uint8_t>(strtoul(row[43], nullptr, 10));
e.armortint_green = static_cast<uint8_t>(strtoul(row[44], nullptr, 10));
e.armortint_blue = static_cast<uint8_t>(strtoul(row[45], nullptr, 10));
e.d_melee_texture1 = static_cast<int32_t>(atoi(row[46]));
e.d_melee_texture2 = static_cast<int32_t>(atoi(row[47]));
e.d_melee_texture1 = static_cast<uint32_t>(strtoul(row[46], nullptr, 10));
e.d_melee_texture2 = static_cast<uint32_t>(strtoul(row[47], nullptr, 10));
e.ammo_idfile = row[48] ? row[48] : "";
e.prim_melee_type = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
e.sec_melee_type = static_cast<uint8_t>(strtoul(row[50], nullptr, 10));
@@ -1289,8 +1289,8 @@ public:
e.armortint_red = static_cast<uint8_t>(strtoul(row[43], nullptr, 10));
e.armortint_green = static_cast<uint8_t>(strtoul(row[44], nullptr, 10));
e.armortint_blue = static_cast<uint8_t>(strtoul(row[45], nullptr, 10));
e.d_melee_texture1 = static_cast<int32_t>(atoi(row[46]));
e.d_melee_texture2 = static_cast<int32_t>(atoi(row[47]));
e.d_melee_texture1 = static_cast<uint32_t>(strtoul(row[46], nullptr, 10));
e.d_melee_texture2 = static_cast<uint32_t>(strtoul(row[47], nullptr, 10));
e.ammo_idfile = row[48] ? row[48] : "";
e.prim_melee_type = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
e.sec_melee_type = static_cast<uint8_t>(strtoul(row[50], nullptr, 10));
@@ -1440,8 +1440,8 @@ public:
e.armortint_red = static_cast<uint8_t>(strtoul(row[43], nullptr, 10));
e.armortint_green = static_cast<uint8_t>(strtoul(row[44], nullptr, 10));
e.armortint_blue = static_cast<uint8_t>(strtoul(row[45], nullptr, 10));
e.d_melee_texture1 = static_cast<int32_t>(atoi(row[46]));
e.d_melee_texture2 = static_cast<int32_t>(atoi(row[47]));
e.d_melee_texture1 = static_cast<uint32_t>(strtoul(row[46], nullptr, 10));
e.d_melee_texture2 = static_cast<uint32_t>(strtoul(row[47], nullptr, 10));
e.ammo_idfile = row[48] ? row[48] : "";
e.prim_melee_type = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
e.sec_melee_type = static_cast<uint8_t>(strtoul(row[50], nullptr, 10));
@@ -16,6 +16,7 @@
#include "../../strings.h"
#include <ctime>
class BaseRaidDetailsRepository {
public:
struct RaidDetails {
@@ -23,6 +24,9 @@ public:
int32_t loottype;
int8_t locked;
std::string motd;
uint16_t marked_npc_1;
uint16_t marked_npc_2;
uint16_t marked_npc_3;
};
static std::string PrimaryKey()
@@ -37,6 +41,9 @@ public:
"loottype",
"locked",
"motd",
"marked_npc_1",
"marked_npc_2",
"marked_npc_3",
};
}
@@ -47,6 +54,9 @@ public:
"loottype",
"locked",
"motd",
"marked_npc_1",
"marked_npc_2",
"marked_npc_3",
};
}
@@ -87,10 +97,13 @@ public:
{
RaidDetails e{};
e.raidid = 0;
e.loottype = 0;
e.locked = 0;
e.motd = "";
e.raidid = 0;
e.loottype = 0;
e.locked = 0;
e.motd = "";
e.marked_npc_1 = 0;
e.marked_npc_2 = 0;
e.marked_npc_3 = 0;
return e;
}
@@ -116,8 +129,9 @@ public:
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE id = {} LIMIT 1",
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
raid_details_id
)
);
@@ -126,10 +140,13 @@ public:
if (results.RowCount() == 1) {
RaidDetails e{};
e.raidid = static_cast<int32_t>(atoi(row[0]));
e.loottype = static_cast<int32_t>(atoi(row[1]));
e.locked = static_cast<int8_t>(atoi(row[2]));
e.motd = row[3] ? row[3] : "";
e.raidid = static_cast<int32_t>(atoi(row[0]));
e.loottype = static_cast<int32_t>(atoi(row[1]));
e.locked = static_cast<int8_t>(atoi(row[2]));
e.motd = row[3] ? row[3] : "";
e.marked_npc_1 = static_cast<uint16_t>(strtoul(row[4], nullptr, 10));
e.marked_npc_2 = static_cast<uint16_t>(strtoul(row[5], nullptr, 10));
e.marked_npc_3 = static_cast<uint16_t>(strtoul(row[6], nullptr, 10));
return e;
}
@@ -167,6 +184,9 @@ public:
v.push_back(columns[1] + " = " + std::to_string(e.loottype));
v.push_back(columns[2] + " = " + std::to_string(e.locked));
v.push_back(columns[3] + " = '" + Strings::Escape(e.motd) + "'");
v.push_back(columns[4] + " = " + std::to_string(e.marked_npc_1));
v.push_back(columns[5] + " = " + std::to_string(e.marked_npc_2));
v.push_back(columns[6] + " = " + std::to_string(e.marked_npc_3));
auto results = db.QueryDatabase(
fmt::format(
@@ -192,6 +212,9 @@ public:
v.push_back(std::to_string(e.loottype));
v.push_back(std::to_string(e.locked));
v.push_back("'" + Strings::Escape(e.motd) + "'");
v.push_back(std::to_string(e.marked_npc_1));
v.push_back(std::to_string(e.marked_npc_2));
v.push_back(std::to_string(e.marked_npc_3));
auto results = db.QueryDatabase(
fmt::format(
@@ -225,6 +248,9 @@ public:
v.push_back(std::to_string(e.loottype));
v.push_back(std::to_string(e.locked));
v.push_back("'" + Strings::Escape(e.motd) + "'");
v.push_back(std::to_string(e.marked_npc_1));
v.push_back(std::to_string(e.marked_npc_2));
v.push_back(std::to_string(e.marked_npc_3));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -258,10 +284,13 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
RaidDetails e{};
e.raidid = static_cast<int32_t>(atoi(row[0]));
e.loottype = static_cast<int32_t>(atoi(row[1]));
e.locked = static_cast<int8_t>(atoi(row[2]));
e.motd = row[3] ? row[3] : "";
e.raidid = static_cast<int32_t>(atoi(row[0]));
e.loottype = static_cast<int32_t>(atoi(row[1]));
e.locked = static_cast<int8_t>(atoi(row[2]));
e.motd = row[3] ? row[3] : "";
e.marked_npc_1 = static_cast<uint16_t>(strtoul(row[4], nullptr, 10));
e.marked_npc_2 = static_cast<uint16_t>(strtoul(row[5], nullptr, 10));
e.marked_npc_3 = static_cast<uint16_t>(strtoul(row[6], nullptr, 10));
all_entries.push_back(e);
}
@@ -286,10 +315,13 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
RaidDetails e{};
e.raidid = static_cast<int32_t>(atoi(row[0]));
e.loottype = static_cast<int32_t>(atoi(row[1]));
e.locked = static_cast<int8_t>(atoi(row[2]));
e.motd = row[3] ? row[3] : "";
e.raidid = static_cast<int32_t>(atoi(row[0]));
e.loottype = static_cast<int32_t>(atoi(row[1]));
e.locked = static_cast<int8_t>(atoi(row[2]));
e.motd = row[3] ? row[3] : "";
e.marked_npc_1 = static_cast<uint16_t>(strtoul(row[4], nullptr, 10));
e.marked_npc_2 = static_cast<uint16_t>(strtoul(row[5], nullptr, 10));
e.marked_npc_3 = static_cast<uint16_t>(strtoul(row[6], nullptr, 10));
all_entries.push_back(e);
}
@@ -31,6 +31,9 @@ public:
int8_t isgroupleader;
int8_t israidleader;
int8_t islooter;
uint8_t is_marker;
uint8_t is_assister;
std::string note;
};
static std::string PrimaryKey()
@@ -52,6 +55,9 @@ public:
"isgroupleader",
"israidleader",
"islooter",
"is_marker",
"is_assister",
"note",
};
}
@@ -69,6 +75,9 @@ public:
"isgroupleader",
"israidleader",
"islooter",
"is_marker",
"is_assister",
"note",
};
}
@@ -120,6 +129,9 @@ public:
e.isgroupleader = 0;
e.israidleader = 0;
e.islooter = 0;
e.is_marker = 0;
e.is_assister = 0;
e.note = "";
return e;
}
@@ -167,6 +179,9 @@ public:
e.isgroupleader = static_cast<int8_t>(atoi(row[8]));
e.israidleader = static_cast<int8_t>(atoi(row[9]));
e.islooter = static_cast<int8_t>(atoi(row[10]));
e.is_marker = static_cast<uint8_t>(strtoul(row[11], nullptr, 10));
e.is_assister = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
e.note = row[13] ? row[13] : "";
return e;
}
@@ -210,6 +225,9 @@ public:
v.push_back(columns[8] + " = " + std::to_string(e.isgroupleader));
v.push_back(columns[9] + " = " + std::to_string(e.israidleader));
v.push_back(columns[10] + " = " + std::to_string(e.islooter));
v.push_back(columns[11] + " = " + std::to_string(e.is_marker));
v.push_back(columns[12] + " = " + std::to_string(e.is_assister));
v.push_back(columns[13] + " = '" + Strings::Escape(e.note) + "'");
auto results = db.QueryDatabase(
fmt::format(
@@ -242,6 +260,9 @@ public:
v.push_back(std::to_string(e.isgroupleader));
v.push_back(std::to_string(e.israidleader));
v.push_back(std::to_string(e.islooter));
v.push_back(std::to_string(e.is_marker));
v.push_back(std::to_string(e.is_assister));
v.push_back("'" + Strings::Escape(e.note) + "'");
auto results = db.QueryDatabase(
fmt::format(
@@ -282,6 +303,9 @@ public:
v.push_back(std::to_string(e.isgroupleader));
v.push_back(std::to_string(e.israidleader));
v.push_back(std::to_string(e.islooter));
v.push_back(std::to_string(e.is_marker));
v.push_back(std::to_string(e.is_assister));
v.push_back("'" + Strings::Escape(e.note) + "'");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -326,6 +350,9 @@ public:
e.isgroupleader = static_cast<int8_t>(atoi(row[8]));
e.israidleader = static_cast<int8_t>(atoi(row[9]));
e.islooter = static_cast<int8_t>(atoi(row[10]));
e.is_marker = static_cast<uint8_t>(strtoul(row[11], nullptr, 10));
e.is_assister = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
e.note = row[13] ? row[13] : "";
all_entries.push_back(e);
}
@@ -361,6 +388,9 @@ public:
e.isgroupleader = static_cast<int8_t>(atoi(row[8]));
e.israidleader = static_cast<int8_t>(atoi(row[9]));
e.islooter = static_cast<int8_t>(atoi(row[10]));
e.is_marker = static_cast<uint8_t>(strtoul(row[11], nullptr, 10));
e.is_assister = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
e.note = row[13] ? row[13] : "";
all_entries.push_back(e);
}
@@ -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<CommandSubsettingsRepository::CommandSubsettings> GetAll(Database& db)
{
// these are the base definitions for command_subsettings and can be over-ridden by the database
std::vector<CommandSubsettingsRepository::CommandSubsettings> 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<CommandSubsettingsRepository::CommandSubsettings> 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
@@ -44,7 +44,24 @@ public:
*/
// Custom extended repository methods here
static int UpdateRaidMarkedNPC(
Database& db,
int32_t raid_id,
uint8_t marked_npc_number,
uint8_t value
) {
auto results = db.QueryDatabase(
fmt::format(
"UPDATE `{}` SET `marked_npc_{}` = '{}' WHERE raidid = '{}';",
TableName(),
marked_npc_number,
value,
raid_id
)
);
return results.Success() ? results.RowsAffected() : 0;
}
};
#endif //EQEMU_RAID_DETAILS_REPOSITORY_H
+53 -1
View File
@@ -44,7 +44,59 @@ public:
*/
// Custom extended repository methods here
static int UpdateRaidNote(
Database& db,
int32_t raid_id,
const std::string& note,
const std::string& character_name
) {
auto results = db.QueryDatabase(
fmt::format("UPDATE `{}` SET `note` = '{}' WHERE raidid = '{}' AND name = '{}';",
TableName(),
Strings::Escape(note),
raid_id,
Strings::Escape(character_name)
)
);
return results.Success() ? results.RowsAffected() : 0;
}
static int UpdateRaidAssister(
Database& db,
int32_t raid_id,
const std::string& character_name,
uint8_t value
) {
auto results = db.QueryDatabase(
fmt::format(
"UPDATE `{}` SET `is_assister` = '{}' WHERE raidid = '{}' AND `name` = '{}';",
TableName(),
value,
raid_id,
Strings::Escape(character_name)
)
);
return results.Success() ? results.RowsAffected() : 0;
}
static int UpdateRaidMarker(
Database& db,
int32_t raid_id,
const std::string& character_name,
uint8_t value
) {
auto results = db.QueryDatabase(
fmt::format(
"UPDATE `{}` SET `is_marker` = '{}' WHERE raidid = '{}' AND `name` = '{}';",
TableName(),
value,
raid_id,
Strings::Escape(character_name)
)
);
return results.Success() ? results.RowsAffected() : 0;
}
};
#endif //EQEMU_RAID_MEMBERS_REPOSITORY_H
+5
View File
@@ -113,6 +113,7 @@
#define ServerOP_GroupFollowAck 0x0111
#define ServerOP_GroupCancelInvite 0x0112
#define ServerOP_RaidMOTD 0x0113
#define ServerOP_RaidNote 0x0114
#define ServerOP_InstanceUpdateTime 0x014F
#define ServerOP_AdventureRequest 0x0150
@@ -1075,6 +1076,10 @@ struct ServerRaidMOTD_Struct {
char motd[0];
};
struct ServerRaidNote_Struct {
uint32 rid;
};
struct ServerLFGMatchesRequest_Struct {
uint32 FromID;
uint8 QuerierLevel;
+54 -15
View File
@@ -1635,25 +1635,29 @@ bool SharedDatabase::GetCommandSettings(std::map<std::string, std::pair<uint8, s
{
command_settings.clear();
const std::string query = "SELECT `command`, `access`, `aliases` FROM `command_settings`";
const std::string& query = "SELECT `command`, `access`, `aliases` FROM `command_settings`";
auto results = QueryDatabase(query);
if (!results.Success())
if (!results.Success() || !results.RowCount()) {
return false;
}
for (auto& row = results.begin(); row != results.end(); ++row) {
for (auto row : results) {
command_settings[row[0]].first = Strings::ToUnsignedInt(row[1]);
if (row[2][0] == 0)
if (row[2][0] == 0) {
continue;
}
std::vector<std::string> 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<std::pair<std::string, uint8>> &injected)
@@ -1668,13 +1672,15 @@ bool SharedDatabase::UpdateInjectedCommandSettings(const std::vector<std::pair<s
)
);
if (!QueryDatabase(query).Success()) {
auto results = QueryDatabase(query);
if (!results.Success()) {
return false;
}
LogInfo(
"[{0}] New Command(s) Added",
injected.size()
"[{}] New Command{} Added",
injected.size(),
injected.size() != 1 ? "s" : ""
);
}
@@ -1684,25 +1690,58 @@ bool SharedDatabase::UpdateInjectedCommandSettings(const std::vector<std::pair<s
bool SharedDatabase::UpdateOrphanedCommandSettings(const std::vector<std::string> &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<char, char>('\'', '\''), 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<char, char>('\'', '\''), 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<CommandSubsettingsRepository::CommandSubsettings> &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);
+2
View File
@@ -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 <list>
#include <map>
@@ -77,6 +78,7 @@ public:
bool GetCommandSettings(std::map<std::string, std::pair<uint8, std::vector<std::string>>> &command_settings);
bool UpdateInjectedCommandSettings(const std::vector<std::pair<std::string, uint8>> &injected);
bool UpdateOrphanedCommandSettings(const std::vector<std::string> &orphaned);
bool GetCommandSubSettings(std::vector<CommandSubsettingsRepository::CommandSubsettings> &command_subsettings);
uint32 GetTotalTimeEntitledOnAccount(uint32 AccountID);
bool SetGMInvul(uint32 account_id, bool gminvul);
bool SetGMFlymode(uint32 account_id, uint8 flymode);
+14
View File
@@ -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"
);
}
+1
View File
@@ -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<typename T>
static std::string
+2 -2
View File
@@ -25,7 +25,7 @@
// Build variables
// these get injected during the build pipeline
#define CURRENT_VERSION "22.19.0-dev" // always append -dev to the current version for custom-builds
#define CURRENT_VERSION "22.20.0-dev" // always append -dev to the current version for custom-builds
#define LOGIN_VERSION "0.8.0"
#define COMPILE_DATE __DATE__
#define COMPILE_TIME __TIME__
@@ -42,7 +42,7 @@
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/
#define CURRENT_BINARY_DATABASE_VERSION 9229
#define CURRENT_BINARY_DATABASE_VERSION 9232
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9039
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "eqemu-server",
"version": "22.19.0",
"version": "22.20.0",
"repository": {
"type": "git",
"url": "https://github.com/EQEmu/Server.git"
+3 -2
View File
@@ -301,9 +301,7 @@ OP_LeadershipExpUpdate=0x2797
OP_PurchaseLeadershipAA=0x6c55
OP_UpdateLeadershipAA=0x0026
OP_MarkNPC=0x1fb5
OP_MarkRaidNPC=0x5a58 #unimplemented
OP_ClearNPCMarks=0x2003
OP_ClearRaidNPCMarks=0x20d3 #unimplemented
OP_DelegateAbility=0x76b8
OP_SetGroupTarget=0x2814
OP_Charm=0x5d92
@@ -544,6 +542,9 @@ OP_LFGResponse=0x0000
OP_RaidInvite=0x55ac
OP_RaidUpdate=0x3973
OP_RaidJoin=0x0000
OP_RaidDelegateAbility=0x2b33
OP_MarkRaidNPC=0x5a58
OP_RaidClearNPCMarks=0x20d3
# Button-push commands
OP_Taunt=0x2703
+8
View File
@@ -397,6 +397,14 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
zoneserver_list.SendPacket(pack);
break;
}
case ServerOP_RaidNote: {
if (pack->size < sizeof(ServerRaidNote_Struct)) {
break;
}
zoneserver_list.SendPacket(pack);
break;
}
case ServerOP_SpawnCondition: {
if (pack->size != sizeof(ServerSpawnCondition_Struct)) {
break;
+5 -2
View File
@@ -1273,8 +1273,11 @@ bool Bot::IsValidName(std::string& name)
if (!isupper(name[0]))
return false;
for (int i = 1; i < name.length(); ++i) {
if ((!RuleB(Bots, AllowCamelCaseNames) && !islower(name[i])) && name[i] != '_') {
for (char c : name.substr(1)) {
if (!RuleB(Bots, AllowCamelCaseNames) && !islower(c)) {
return false;
}
if (isdigit(c) || ispunct(c)) {
return false;
}
}
+2 -7
View File
@@ -5501,11 +5501,6 @@ void bot_subcommand_bot_create(Client *c, const Seperator *sep)
std::string bot_name = sep->arg[1];
bot_name = Strings::UcFirst(bot_name);
if (Strings::Contains(bot_name, "_")) {
c->Message(Chat::White, "Bot name cannot contain underscores!");
return;
}
if (arguments < 2 || !sep->IsNumber(2)) {
c->Message(Chat::White, "Invalid class!");
return;
@@ -8858,8 +8853,8 @@ uint32 helper_bot_create(Client *bot_owner, std::string bot_name, uint8 bot_clas
bot_owner->Message(
Chat::White,
fmt::format(
"'{}' is an invalid name. You may only use characters 'A-Z', 'a-z' and '_'.",
bot_name
"'{}' is an invalid name. You may only use characters 'A-Z' or 'a-z'. Mixed case {} allowed.",
bot_name, RuleB(Bots, AllowCamelCaseNames) ? "is" : "is not"
).c_str()
);
return bot_id;
+60 -19
View File
@@ -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;
@@ -6546,24 +6590,30 @@ void Client::RemoveXTarget(Mob *m, bool OnlyAutoSlots)
XTargets[i].dirty = true;
}
}
auto r = GetRaid();
if (r) {
r->UpdateRaidXTargets();
}
}
void Client::UpdateXTargetType(XTargetType Type, Mob *m, const char *Name)
{
if(!XTargettingAvailable())
if (!XTargettingAvailable()) {
return;
}
for(int i = 0; i < GetMaxXTargets(); ++i)
{
if(XTargets[i].Type == Type)
{
if(m)
for (int i = 0; i < GetMaxXTargets(); ++i) {
if (XTargets[i].Type == Type) {
if (m) {
XTargets[i].ID = m->GetID();
else
}
else {
XTargets[i].ID = 0;
}
if(Name)
if (Name) {
strncpy(XTargets[i].Name, Name, 64);
}
SendXTargetPacket(i, m);
}
@@ -6597,10 +6647,7 @@ void Client::SendXTargetPacket(uint32 Slot, Mob *m)
if (strlen(XTargets[Slot].Name) && ((XTargets[Slot].Type == CurrentTargetPC) ||
(XTargets[Slot].Type == GroupTank) ||
(XTargets[Slot].Type == GroupAssist) ||
(XTargets[Slot].Type == Puller) ||
(XTargets[Slot].Type == RaidAssist1) ||
(XTargets[Slot].Type == RaidAssist2) ||
(XTargets[Slot].Type == RaidAssist3)))
(XTargets[Slot].Type == Puller)))
{
outapp->WriteUInt8(2);
}
@@ -6664,13 +6711,7 @@ void Client::RemoveGroupXTargets()
{
if ((XTargets[i].Type == GroupTank) ||
(XTargets[i].Type == GroupAssist) ||
(XTargets[i].Type == Puller) ||
(XTargets[i].Type == RaidAssist1) ||
(XTargets[i].Type == RaidAssist2) ||
(XTargets[i].Type == RaidAssist3) ||
(XTargets[i].Type == GroupMarkTarget1) ||
(XTargets[i].Type == GroupMarkTarget2) ||
(XTargets[i].Type == GroupMarkTarget3))
(XTargets[i].Type == Puller))
{
XTargets[i].ID = 0;
XTargets[i].Name[0] = 0;
+2 -1
View File
@@ -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);
@@ -1924,6 +1925,7 @@ private:
public:
void SetSharedTaskId(int64 shared_task_id);
int64 GetSharedTaskId() const;
struct XTarget_Struct XTargets[XTARGET_HARDCAP];
private:
bool m_exp_enabled;
@@ -1976,7 +1978,6 @@ private:
bool XTargetAutoAddHaters;
bool m_dirtyautohaters;
struct XTarget_Struct XTargets[XTARGET_HARDCAP];
XTargetAutoHaters m_autohatermgr;
XTargetAutoHaters *m_activeautohatermgr;
+212 -10
View File
@@ -328,6 +328,8 @@ void MapOpcodes()
ConnectedOpcodes[OP_PVPLeaderBoardRequest] = &Client::Handle_OP_PVPLeaderBoardRequest;
ConnectedOpcodes[OP_QueryUCSServerStatus] = &Client::Handle_OP_QueryUCSServerStatus;
ConnectedOpcodes[OP_RaidInvite] = &Client::Handle_OP_RaidCommand;
ConnectedOpcodes[OP_RaidDelegateAbility] = &Client::Handle_OP_RaidDelegateAbility;
ConnectedOpcodes[OP_RaidClearNPCMarks] = &Client::Handle_OP_RaidClearNPCMarks;
ConnectedOpcodes[OP_RandomReq] = &Client::Handle_OP_RandomReq;
ConnectedOpcodes[OP_ReadBook] = &Client::Handle_OP_ReadBook;
ConnectedOpcodes[OP_RecipeAutoCombine] = &Client::Handle_OP_RecipeAutoCombine;
@@ -607,7 +609,6 @@ void Client::CompleteConnect()
but not important for now.
*/
raid->SendRaidCreate(this);
raid->SendMakeLeaderPacketTo(raid->leadername, this);
raid->SendRaidAdd(GetName(), this);
raid->SendBulkRaid(this);
raid->SendGroupUpdate(this);
@@ -616,6 +617,7 @@ void Client::CompleteConnect()
raid->UpdateRaidAAs();
raid->SendAllRaidLeadershipAA();
}
raid->SendMakeLeaderPacketTo(raid->leadername, this);
uint32 grpID = raid->GetGroup(GetName());
if (grpID < 12) {
raid->SendRaidGroupRemove(GetName(), grpID);
@@ -636,6 +638,8 @@ void Client::CompleteConnect()
raid->SendRaidLockTo(this);
raid->SendHPManaEndPacketsTo(this);
raid->SendAssistTarget(this);
raid->SendMarkTargets(this);
}
}
else {
@@ -3043,8 +3047,22 @@ void Client::Handle_OP_AssistGroup(const EQApplicationPacket *app)
LogDebug("Size mismatch in OP_AssistGroup expected [{}] got [{}]", sizeof(EntityId_Struct), app->size);
return;
}
QueuePacket(app);
return;
EntityId_Struct* eid = (EntityId_Struct*)app->pBuffer;
Entity* entity = entity_list.GetID(eid->entity_id);
if (entity && entity->IsMob()) {
Mob* new_target = entity->CastToMob();
if (new_target && (GetGM() ||
Distance(m_Position, new_target->GetPosition()) <= TARGETING_RANGE)) {
cheat_manager.SetExemptStatus(Assist, true);
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Assist, sizeof(EntityId_Struct));
eid = (EntityId_Struct*)outapp->pBuffer;
eid->entity_id = new_target->GetID();
FastQueuePacket(&outapp);
safe_delete(outapp);
}
}
}
void Client::Handle_OP_AugmentInfo(const EQApplicationPacket *app)
@@ -5850,6 +5868,31 @@ void Client::Handle_OP_DoGroupLeadershipAbility(const EQApplicationPacket *app)
break;
}
case RaidLeadershipAbility_MainAssist:
{
//This is not needed as it executes from opcode 0x2b33 which is sent
//with this opcode.
//if (GetTarget())
//{
// Raid* r = GetRaid();
// if (r)
// {
// r->DelegateAbility(GetTarget()->CastToClient()->GetName());
// }
//}
break;
}
case RaidLeadershipAbility_MarkNPC:
{
if (GetTarget() && GetTarget()->IsMob()) {
Raid* r = GetRaid();
if (r) {
r->RaidMarkNPC(this, dglas->Parameter);
}
}
break;
}
default:
LogDebug("Got unhandled OP_DoGroupLeadershipAbility Ability: [{}] Parameter: [{}]", dglas->Ability, dglas->Parameter);
break;
@@ -11934,6 +11977,8 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
if (raid->IsLocked()) {
raid->SendRaidLockTo(c);
}
raid->SendAssistTarget(c);
raid->SendMarkTargets(c);
}
}
group->JoinRaidXTarget(raid);
@@ -11948,6 +11993,8 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
if (raid->IsLocked()) {
raid->SendRaidLockTo(this);
}
raid->SendAssistTarget(this);
raid->SendMarkTargets(this);
}
}
else
@@ -11988,6 +12035,8 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
if (raid->IsLocked()) {
raid->SendRaidLockTo(c);
}
raid->SendAssistTarget(c);
raid->SendMarkTargets(c);
}
else {
Client* c = nullptr;
@@ -12004,6 +12053,8 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
if (raid->IsLocked()) {
raid->SendRaidLockTo(c);
}
raid->SendAssistTarget(c);
raid->SendMarkTargets(c);
}
}
}
@@ -12043,6 +12094,8 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
if (raid->IsLocked()) {
raid->SendRaidLockTo(c);
}
raid->SendAssistTarget(c);
raid->SendMarkTargets(c);
}
else
{
@@ -12060,6 +12113,8 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
if (raid->IsLocked()) {
raid->SendRaidLockTo(c);
}
raid->SendAssistTarget(c);
raid->SendMarkTargets(c);
}
}
}
@@ -12100,6 +12155,8 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
if (raid->IsLocked()) {
raid->SendRaidLockTo(c);
}
raid->SendAssistTarget(c);
raid->SendMarkTargets(c);
}
else
{
@@ -12116,6 +12173,8 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
if (raid->IsLocked()) {
raid->SendRaidLockTo(c);
}
raid->SendAssistTarget(c);
raid->SendMarkTargets(c);
}
}
}
@@ -12129,6 +12188,8 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
if (raid->IsLocked()) {
raid->SendRaidLockTo(this);
}
raid->SendAssistTarget(this);
raid->SendMarkTargets(this);
}
else { // neither has a group
raid = new Raid(player_sending_invite);
@@ -12143,6 +12204,8 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
if (raid->IsLocked()) {
raid->SendRaidLockTo(this);
}
raid->SendAssistTarget(this);
raid->SendMarkTargets(this);
}
}
}
@@ -12165,6 +12228,8 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
//Does not camp the Bots, just removes from the raid
if (c_to_disband) {
uint32 i = raid->GetPlayerIndex(raid_command_packet->leader_name);
raid->RemoveRaidDelegates(raid_command_packet->leader_name);
raid->SendRemoveAllRaidXTargets(raid_command_packet->leader_name);
raid->SetNewRaidLeader(i);
raid->HandleBotGroupDisband(c_to_disband->CharacterID());
raid->HandleOfflineBots(c_to_disband->CharacterID());
@@ -12180,11 +12245,13 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
if (gid < 12 && (raid->IsGroupLeader(b_to_disband->GetName()) || raid->GroupCount(gid) < 2)) {
uint32 owner_id = b_to_disband->CastToBot()->GetOwner()->CastToClient()->CharacterID();
raid->RemoveRaidDelegates(raid_command_packet->leader_name);
raid->UpdateRaidXTargets();
raid->HandleBotGroupDisband(owner_id, gid);
} else if (b_to_disband && raid->IsRaidMember(b_to_disband->GetName())) {
raid->RemoveRaidDelegates(raid_command_packet->leader_name);
raid->UpdateRaidXTargets();
Bot::RemoveBotFromRaid(b_to_disband);
} else if (gid < 12 && raid->GetGroupLeader(gid) && raid->GetGroupLeader(gid)->IsBot()) {
c_doing_disband->Message(
Chat::Yellow,
@@ -12215,6 +12282,8 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
}
}
raid->SetNewRaidLeader(i);
raid->RemoveRaidDelegates(raid_command_packet->leader_name);
raid->UpdateRaidXTargets();
raid->RemoveMember(raid_command_packet->leader_name);
Client* c = entity_list.GetClientByName(raid_command_packet->leader_name);
if (c) {
@@ -12268,9 +12337,9 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
if (client_to_update) {
raid->SendRaidRemove(raid->members[x].member_name, client_to_update);
raid->SendRaidCreate(client_to_update);
raid->SendMakeLeaderPacketTo(raid->leadername, client_to_update);
raid->SendRaidAdd(raid->members[x].member_name, client_to_update);
raid->SendBulkRaid(client_to_update);
raid->SendMakeLeaderPacketTo(raid->leadername, client_to_update);
if (raid->IsLocked()) {
raid->SendRaidLockTo(client_to_update);
}
@@ -12318,9 +12387,9 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
raid->GroupUpdate(raid_command_packet->parameter);
/* If our old was a group send update there too */
if (old_group < 12)
if (old_group < 12) {
raid->GroupUpdate(old_group);
}
}
}
/* Move player to ungrouped bank */
@@ -12381,7 +12450,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
}
raid->GroupUpdate(oldgrp);
}
}
}
Client* client_moved = entity_list.GetClientByName(raid_command_packet->leader_name);
@@ -12479,7 +12548,18 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
raid->SendRaidMOTDToWorld();
break;
}
case RaidCommandSetNote:
{
Raid* raid = entity_list.GetRaidByClient(this);
if (!raid) {
break;
}
raid->SaveRaidNote(raid_command_packet->leader_name, raid_command_packet->note);
raid->SendRaidNotesToWorld();
break;
}
default: {
Message(Chat::Red, "Raid command (%d) NYI", raid_command_packet->action);
break;
@@ -15799,14 +15879,87 @@ void Client::Handle_OP_XTargetRequest(const EQApplicationPacket *app)
case RaidAssist1:
case RaidAssist2:
case RaidAssist3:
{
struct AssistType {
XTargetType type;
int32 assist_slot;
};
std::vector<AssistType> assist_types = {
{ RaidAssist1, MAIN_ASSIST_1_SLOT },
{ RaidAssist2, MAIN_ASSIST_2_SLOT },
{ RaidAssist3, MAIN_ASSIST_3_SLOT }
};
for (auto& t : assist_types) {
if (t.type == Type) {
Raid* r = GetRaid();
if (r) {
Client* ma = entity_list.GetClientByName(r->main_assister_pcs[t.assist_slot]);
if (ma) {
UpdateXTargetType(t.type, ma, ma->GetName());
}
}
}
}
break;
}
case RaidAssist1Target:
case RaidAssist2Target:
case RaidAssist3Target:
{
struct AssistType {
XTargetType type;
int32 assist_slot;
};
std::vector<AssistType> assist_types = {
{ RaidAssist1Target, MAIN_ASSIST_1_SLOT },
{ RaidAssist2Target, MAIN_ASSIST_2_SLOT },
{ RaidAssist3Target, MAIN_ASSIST_3_SLOT }
};
for (auto& t : assist_types) {
if (t.type == Type) {
Raid* r = GetRaid();
if (r) {
Client* ma = entity_list.GetClientByName(r->main_assister_pcs[t.assist_slot]);
if (ma && ma->GetTarget()) {
UpdateXTargetType(t.type, ma->GetTarget(), ma->GetTarget()->GetName());
}
}
}
}
break;
}
case RaidMarkTarget1:
case RaidMarkTarget2:
case RaidMarkTarget3:
{
// Not implemented yet.
struct AssistType {
XTargetType type;
int32 assist_slot;
};
std::vector<AssistType> assist_types = {
{ RaidMarkTarget1, MAIN_MARKER_1_SLOT },
{ RaidMarkTarget2, MAIN_MARKER_2_SLOT },
{ RaidMarkTarget3, MAIN_MARKER_3_SLOT }
};
for (auto& t : assist_types) {
if (t.type == Type) {
Raid* r = GetRaid();
if (r) {
auto mm = entity_list.GetNPCByID(r->marked_npcs[t.assist_slot]);
if (mm) {
UpdateXTargetType(t.type, mm->CastToMob(), mm->CastToMob()->GetName());
}
}
}
}
break;
}
@@ -16190,3 +16343,52 @@ void Client::RecordKilledNPCEvent(NPC *n)
}
}
}
void Client::Handle_OP_RaidDelegateAbility(const EQApplicationPacket *app)
{
if (app->size != sizeof(DelegateAbility_Struct)) {
LogDebug(
"Size mismatch in OP_RaidDelegateAbility expected [{}] got [{}]",
sizeof(DelegateAbility_Struct),
app->size
);
DumpPacket(app);
return;
}
DelegateAbility_Struct *das = (DelegateAbility_Struct *) app->pBuffer;
switch (das->DelegateAbility) {
case RaidDelegateMainAssist: {
auto r = GetRaid();
if (r) {
r->DelegateAbilityAssist(this, das->Name);
}
break;
}
case RaidDelegateMainMarker: {
auto r = GetRaid();
if (r) {
r->DelegateAbilityMark(this, das->Name);
}
break;
}
default:
LogDebug("RaidDelegateAbility default case");
break;
}
}
void Client::Handle_OP_RaidClearNPCMarks(const EQApplicationPacket* app)
{
if (app->size != 0) {
LogDebug("Size mismatch in OP_RaidClearNPCMark expected [{}] got [{}]", 0, app->size);
DumpPacket(app);
return;
}
auto r = GetRaid();
if (r) {
r->RaidClearNPCMarks(this);
}
}
+3 -1
View File
@@ -241,7 +241,9 @@
void Handle_OP_PVPLeaderBoardRequest(const EQApplicationPacket *app);
void Handle_OP_QueryUCSServerStatus(const EQApplicationPacket *app);
void Handle_OP_RaidCommand(const EQApplicationPacket *app);
void Handle_OP_RandomReq(const EQApplicationPacket *app);
void Handle_OP_RaidDelegateAbility(const EQApplicationPacket* app);
void Handle_OP_RaidClearNPCMarks(const EQApplicationPacket* app);
void Handle_OP_RandomReq(const EQApplicationPacket* app);
void Handle_OP_ReadBook(const EQApplicationPacket *app);
void Handle_OP_RecipeAutoCombine(const EQApplicationPacket *app);
void Handle_OP_RecipeDetails(const EQApplicationPacket *app);
+77 -335
View File
@@ -1,8 +1,8 @@
#include <string.h>
#include <algorithm>
#include <thread>
#include <fmt/format.h>
#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<std::string, CommandRecord *> commandlist;
std::map<std::string, std::string> commandaliases;
std::vector<CommandRecord *> command_delete_list;
std::map<std::string, uint8> commands_map;
std::map<std::string, CommandRecord *> commandlist;
std::map<std::string, std::string> commandaliases;
std::vector<CommandRecord *> command_delete_list;
std::map<std::string, uint8> commands_map;
std::vector<CommandSubsettingsRepository::CommandSubsettings> 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<std::string, std::pair<uint8, std::vector<std::string>>> command_settings;
database.GetCommandSettings(command_settings);
database.GetCommandSubSettings(command_subsettings);
std::vector<std::pair<std::string, uint8>> injected_command_settings;
std::vector<std::string> orphaned_command_settings;
// static aliases
struct StaticAlias {
std::string command;
std::vector<std::string> aliases;
};
std::vector<StaticAlias> 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<int16>(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<int16>(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"
+3 -65
View File
@@ -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<std::string, std::string> 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);
+6 -6
View File
@@ -2315,17 +2315,17 @@ void Perl__removetitle(int title_set)
quest_manager.removetitle(title_set);
}
void Perl__wearchange(uint8 slot, uint16 texture_id)
void Perl__wearchange(uint8 slot, uint32 texture_id)
{
quest_manager.wearchange(slot, texture_id);
}
void Perl__wearchange(uint8 slot, uint16 texture_id, uint32 hero_forge_model_id)
void Perl__wearchange(uint8 slot, uint32 texture_id, uint32 hero_forge_model_id)
{
quest_manager.wearchange(slot, texture_id, hero_forge_model_id);
}
void Perl__wearchange(uint8 slot, uint16 texture_id, uint32 hero_forge_model_id, uint32 elite_material_id)
void Perl__wearchange(uint8 slot, uint32 texture_id, uint32 hero_forge_model_id, uint32 elite_material_id)
{
quest_manager.wearchange(slot, texture_id, hero_forge_model_id, elite_material_id);
}
@@ -6214,9 +6214,9 @@ void perl_register_quest()
package.add("varlink", (std::string(*)(uint32, int16, uint32, uint32, uint32, uint32, uint32, uint32, bool))&Perl__varlink);
package.add("voicetell", &Perl__voicetell);
package.add("we", &Perl__we);
package.add("wearchange", (void(*)(uint8, uint16))&Perl__wearchange);
package.add("wearchange", (void(*)(uint8, uint16, uint32))&Perl__wearchange);
package.add("wearchange", (void(*)(uint8, uint16, uint32, uint32))&Perl__wearchange);
package.add("wearchange", (void(*)(uint8, uint32))&Perl__wearchange);
package.add("wearchange", (void(*)(uint8, uint32, uint32))&Perl__wearchange);
package.add("wearchange", (void(*)(uint8, uint32, uint32, uint32))&Perl__wearchange);
package.add("whisper", &Perl__whisper);
package.add("write", &Perl__write);
package.add("ze", &Perl__ze);
+12
View File
@@ -2244,6 +2244,18 @@ Raid* EntityList::GetRaidByBot(const Bot* bot)
return nullptr;
}
Raid* EntityList::GetRaidByName(const char* name)
{
for (const auto& r : raid_list) {
for (const auto& m : r->members) {
if (Strings::EqualFold(m.member_name, name)) {
return r;
}
}
}
return nullptr;
}
Client *EntityList::GetClientByAccID(uint32 accid)
{
auto it = client_list.begin();
+1
View File
@@ -198,6 +198,7 @@ public:
Raid *GetRaidByID(uint32 id);
Raid* GetRaidByBotName(const char* name);
Raid* GetRaidByBot(const Bot* bot);
Raid* GetRaidByName(const char* name);
Corpse *GetCorpseByOwner(Client* client);
Corpse *GetCorpseByOwnerWithinRange(Client* client, Mob* center, int range);
-44
View File
@@ -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()
);
}
-67
View File
@@ -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<uint16>(Strings::ToUnsignedInt(sep->arg[1]));
auto month = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
auto day = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[3]));
auto hour = !sep->IsNumber(4) ? eq_time.hour : static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[4]) + 1);
auto minute = !sep->IsNumber(5) ? eq_time.minute : static_cast<uint8>(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"
)
);
}
-28
View File
@@ -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()
);
}
Executable → Regular
View File
+12 -1
View File
@@ -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 <sub-command <args>
// rewrite to #find <sub-command <args>>
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;
}
}
+1 -1
View File
@@ -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]);
+8 -3
View File
@@ -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()
);
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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<uint16>(Strings::ToUnsignedInt(sep->arg[2]));
+1 -1
View File
@@ -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]);
+1 -1
View File
@@ -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]);
+3 -3
View File
@@ -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";
-87
View File
@@ -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);
}
}
}
-38
View File
@@ -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<GravityBehavior>(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()
);
}
-26
View File
@@ -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()
);
}
-23
View File
@@ -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());
}
}
-38
View File
@@ -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()
);
}
-28
View File
@@ -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()
);
}
}
-39
View File
@@ -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()
);
}
-33
View File
@@ -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]");
}
}
-21
View File
@@ -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()
);
}
-44
View File
@@ -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<uint8>(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.");
}
}
}
-18
View File
@@ -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");
}
}
-28
View File
@@ -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()
);
}
-40
View File
@@ -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()
);
}
-47
View File
@@ -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<uint8>(Strings::ToUnsignedInt(sep->arg[1]));
auto max_level = static_cast<uint8>(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);
}
}
}
-25
View File
@@ -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()
);
}
-42
View File
@@ -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()
);
}
}
}
-40
View File
@@ -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()
);
}
}
-44
View File
@@ -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()
);
}
-44
View File
@@ -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()
);
}
-29
View File
@@ -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()
);
}
}
-116
View File
@@ -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()
);
}
}
-29
View File
@@ -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());
}
}
-22
View File
@@ -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);
}
+174
View File
@@ -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<std::string> a{}; // aliases
};
std::vector<Cmd> 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<std::string> 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 <sub-command <args>>
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());
}
}
+69
View File
@@ -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()
);
}
+66
View File
@@ -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()
);
}
+66
View File
@@ -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);
}
@@ -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()
);
}
+63
View File
@@ -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<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
if (
!EQ::ValueWithin(
animation_id,
static_cast<uint8>(eaStanding),
static_cast<uint8>(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<EmuAppearance>(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()
);
}
@@ -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<uint8>(Strings::ToUnsignedInt(sep->arg[1]));
if (arguments == 2) {
const uint8 anon_flag = static_cast<uint8>(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<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
} else if (arguments == 3) {
const int character_id = Strings::ToInt(sep->arg[2]);
const uint8 anon_flag = static_cast<uint8>(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;
}
+45
View File
@@ -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()
);
}
@@ -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) {
+40
View File
@@ -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()
);
}
}
+48
View File
@@ -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()
);
}
+46
View File
@@ -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)
);
}
+40
View File
@@ -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()
);
}
+29
View File
@@ -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()
);
}
+49
View File
@@ -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()
);
}
+69
View File
@@ -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<GravityBehavior>(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()
);
}
+34
View File
@@ -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()
);
}
+38
View File
@@ -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()
);
}
+44
View File
@@ -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()
);
}
+30
View File
@@ -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()
);
}
}
+39
View File
@@ -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()
);
}
+97
View File
@@ -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);
}
}
+42
View File
@@ -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);
}
+5 -6
View File
@@ -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()
);
}
+44
View File
@@ -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);
}
}
}
@@ -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()
);
+33
View File
@@ -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()
);
}
+20
View File
@@ -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()
);
}
+32
View File
@@ -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()
);
}
+54
View File
@@ -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()
);
}
}
+46
View File
@@ -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()
);
}

Some files were not shown because too many files have changed in this diff Show More