mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-31 04:56:20 +00:00
[Commands] Consolidate #set-like commands into a singular #set command (#3486)
* First push * Final push. * Consolidate zone commands in to one. * Update command.cpp * Remove debug messages. * Test * Add support for sub command status levels. * Update command.cpp * Update client.cpp * Update database_update_manifest.cpp * Update version.h * Update item.cpp * Update version.h * Update database_update_manifest.cpp * Fix command arguments. * Help message. * Update command.cpp * Do DB injection/deletion * Indent * Update server_locked.cpp * Update set.cpp * Lock aliases * Update command_subsettings_repository.h * Update set.cpp * Fix --------- Co-authored-by: Akkadius <akkadius1@gmail.com>
This commit is contained in:
Executable
+69
@@ -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()
|
||||
);
|
||||
}
|
||||
Executable
+66
@@ -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()
|
||||
);
|
||||
}
|
||||
Executable
+66
@@ -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()
|
||||
);
|
||||
}
|
||||
Executable
+63
@@ -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()
|
||||
);
|
||||
}
|
||||
Executable
+105
@@ -0,0 +1,105 @@
|
||||
#include "../../client.h"
|
||||
#include "../../../common/repositories/character_data_repository.h"
|
||||
|
||||
void SetAnon(Client *c, const Seperator *sep)
|
||||
{
|
||||
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 == 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();
|
||||
}
|
||||
|
||||
std::string anon_setting;
|
||||
if (anon_flag == Anonymity::NotAnonymous) {
|
||||
anon_setting = "no longer Anonymous or Roleplaying";
|
||||
} else if (anon_flag == Anonymity::Anonymous) {
|
||||
anon_setting = "now Anonymous";
|
||||
} else if (anon_flag == Anonymity::Roleplaying) {
|
||||
anon_setting = "now Roleplaying";
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
c->SetAnon(anon_flag);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} {} {}.",
|
||||
c->GetTargetDescription(t, TargetDescriptionType::UCYou),
|
||||
c == t ? "are" : "is",
|
||||
anon_setting
|
||||
).c_str()
|
||||
);
|
||||
} 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) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Character ID {} does not exist or is invalid.",
|
||||
character_id
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
e.anon = anon_flag;
|
||||
|
||||
auto updated = CharacterDataRepository::UpdateOne(content_db, e);
|
||||
|
||||
if (!updated) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Failed to change Anonymous Flag for {} ({}).",
|
||||
e.name,
|
||||
character_id
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string anon_setting;
|
||||
if (anon_flag == Anonymity::NotAnonymous) {
|
||||
anon_setting = "no longer Anonymous or Roleplaying";
|
||||
} else if (anon_flag == Anonymity::Anonymous) {
|
||||
anon_setting = "now Anonymous";
|
||||
} else if (anon_flag == Anonymity::Roleplaying) {
|
||||
anon_setting = "now Roleplaying";
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} ({}) is {}.",
|
||||
e.name,
|
||||
character_id,
|
||||
anon_setting
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
Executable
+45
@@ -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()
|
||||
);
|
||||
}
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
#include "../../client.h"
|
||||
#include "../../worldserver.h"
|
||||
#include "../../../common/repositories/account_repository.h"
|
||||
|
||||
extern WorldServer worldserver;
|
||||
|
||||
void SetChecksum(Client *c, const Seperator *sep)
|
||||
{
|
||||
auto account = AccountRepository::FindOne(database, c->AccountID());
|
||||
if (!account.id) {
|
||||
c->Message(Chat::White, "Your account was not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
database.SetVariable("crc_eqgame", account.crc_eqgame);
|
||||
database.SetVariable("crc_skillcaps", account.crc_skillcaps);
|
||||
database.SetVariable("crc_basedata", account.crc_basedata);
|
||||
|
||||
c->Message(Chat::White, "Attempting to reload Rules globally.");
|
||||
auto pack = new ServerPacket(ServerOP_ReloadRules, 0);
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
|
||||
c->Message(Chat::White, "Attempting to reload Variables globally.");
|
||||
pack = new ServerPacket(ServerOP_ReloadVariables, 0);
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
Executable
+40
@@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
Executable
+48
@@ -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()
|
||||
);
|
||||
}
|
||||
Executable
+46
@@ -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)
|
||||
);
|
||||
}
|
||||
@@ -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()
|
||||
);
|
||||
}
|
||||
Executable
+29
@@ -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()
|
||||
);
|
||||
}
|
||||
|
||||
Executable
+49
@@ -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()
|
||||
);
|
||||
}
|
||||
Executable
+69
@@ -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()
|
||||
);
|
||||
}
|
||||
Executable
+34
@@ -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()
|
||||
);
|
||||
}
|
||||
Executable
+38
@@ -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()
|
||||
);
|
||||
}
|
||||
Executable
+44
@@ -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()
|
||||
);
|
||||
}
|
||||
Executable
+30
@@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
Executable
+39
@@ -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()
|
||||
);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#include "../../client.h"
|
||||
|
||||
void SetHaste(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
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;
|
||||
}
|
||||
|
||||
auto t = c;
|
||||
if (c->GetGM() && c->GetTarget() && c->GetTarget()->IsClient()) {
|
||||
t = c->GetTarget()->CastToClient();
|
||||
}
|
||||
|
||||
const int extra_haste = Strings::ToInt(sep->arg[2]);
|
||||
|
||||
t->SetExtraHaste(extra_haste);
|
||||
t->CalcBonuses();
|
||||
t->SetAttackTimer();
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"GM Haste Bonus set to {}%% for {}.",
|
||||
Strings::Commify(extra_haste),
|
||||
c->GetTargetDescription(t)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
Executable
+44
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#include "../../client.h"
|
||||
|
||||
void SetHideMe(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 2) {
|
||||
c->Message(Chat::White, "Usage: #set hide_me [on|off]");
|
||||
return;
|
||||
}
|
||||
|
||||
auto t = c;
|
||||
if (c->GetGM() && c->GetTarget() && c->GetTarget()->IsClient()) {
|
||||
t = c->GetTarget()->CastToClient();
|
||||
}
|
||||
|
||||
const bool is_hidden = Strings::ToBool(sep->arg[2]);
|
||||
|
||||
t->SetHideMe(is_hidden);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} {} now {}visible to players below a status level of {}.",
|
||||
c->GetTargetDescription(t, TargetDescriptionType::UCYou),
|
||||
c == t ? "are" : "is",
|
||||
is_hidden ? "in" : "",
|
||||
t->Admin()
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
@@ -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()
|
||||
);
|
||||
}
|
||||
Executable
+20
@@ -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()
|
||||
);
|
||||
}
|
||||
Executable
+32
@@ -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()
|
||||
);
|
||||
}
|
||||
Executable
+54
@@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
Executable
+46
@@ -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()
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#include "../../bot.h"
|
||||
#include "../../client.h"
|
||||
|
||||
void SetLevel(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 2 || !sep->IsNumber(2)) {
|
||||
c->Message(Chat::White, "Usage: #set level [Level]");
|
||||
return;
|
||||
}
|
||||
|
||||
Mob* t = c;
|
||||
if (c->GetTarget()) {
|
||||
t = c->GetTarget();
|
||||
}
|
||||
|
||||
const uint8 max_level = RuleI(Character, MaxLevel);
|
||||
const uint8 level = Strings::ToUnsignedInt(sep->arg[2]);
|
||||
|
||||
if (c != t && c->Admin() < RuleI(GM, MinStatusToLevelTarget)) {
|
||||
c->Message(Chat::White, "Your status is not high enough to change another person's level.");
|
||||
return;
|
||||
}
|
||||
|
||||
t->SetLevel(level, true);
|
||||
|
||||
if (t->IsClient()) {
|
||||
t->CastToClient()->SendLevelAppearance();
|
||||
|
||||
if (RuleB(Bots, Enabled) && RuleB(Bots, BotLevelsWithOwner)) {
|
||||
Bot::LevelBotWithClient(t->CastToClient(), level, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#include "../../client.h"
|
||||
#include "../../worldserver.h"
|
||||
|
||||
extern WorldServer worldserver;
|
||||
|
||||
void SetLoginserverInfo(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 3) {
|
||||
c->Message(Chat::White, "Usage: #set lsinfo [Email] [Password]");
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string& email = sep->arg[2];
|
||||
const std::string& password = sep->arg[3];
|
||||
|
||||
auto pack = new ServerPacket(ServerOP_LSAccountUpdate, sizeof(ServerLSAccountUpdate_Struct));
|
||||
|
||||
auto s = (ServerLSAccountUpdate_Struct *) pack->pBuffer;
|
||||
|
||||
s->useraccountid = c->LSAccountID();
|
||||
strn0cpy(s->useraccount, c->AccountName(), 30);
|
||||
strn0cpy(s->user_email, email.c_str(), 100);
|
||||
strn0cpy(s->userpassword, password.c_str(), 50);
|
||||
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
|
||||
c->Message(Chat::White, "Your email and local loginserver password have been set.");
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#include "../../client.h"
|
||||
|
||||
void SetMana(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 2 || !sep->IsNumber(2)) {
|
||||
c->Message(Chat::White, "Usage: #set mana [Amount]");
|
||||
return;
|
||||
}
|
||||
|
||||
Mob* t = c;
|
||||
if (c->GetTarget()) {
|
||||
t = c->GetTarget();
|
||||
}
|
||||
|
||||
int64 mana = Strings::ToBigInt(sep->arg[2]);
|
||||
|
||||
if (t->IsClient()) {
|
||||
if (mana >= t->CastToClient()->CalcMaxMana()) {
|
||||
mana = t->CastToClient()->CalcMaxMana();
|
||||
}
|
||||
|
||||
t->CastToClient()->SetMana(mana);
|
||||
} else {
|
||||
if (mana >= t->CalcMaxMana()) {
|
||||
mana = t->CalcMaxMana();
|
||||
}
|
||||
|
||||
t->SetMana(mana);
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Set {} to {} Mana.",
|
||||
c->GetTargetDescription(t),
|
||||
Strings::Commify(mana)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
#include "../../client.h"
|
||||
|
||||
void SetManaFull(Client *c, const Seperator *sep)
|
||||
{
|
||||
Mob* t = c;
|
||||
if (c->GetTarget()) {
|
||||
t = c->GetTarget();
|
||||
}
|
||||
|
||||
int64 mana;
|
||||
|
||||
if (t->IsClient()) {
|
||||
mana = t->CastToClient()->CalcMaxMana();
|
||||
t->CastToClient()->SetMana(mana);
|
||||
} else {
|
||||
mana = t->CalcMaxMana();
|
||||
t->SetMana(mana);
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Set {} to full Mana ({}).",
|
||||
c->GetTargetDescription(t),
|
||||
Strings::Commify(mana)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#include "../../client.h"
|
||||
#include "../../worldserver.h"
|
||||
|
||||
extern WorldServer worldserver;
|
||||
|
||||
void command_motd(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 2) {
|
||||
c->Message(Chat::White, "Usage: #set motd [Message]");
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string& message = sep->argplus[2];
|
||||
|
||||
auto pack = new ServerPacket(ServerOP_Motd, sizeof(ServerMotd_Struct));
|
||||
|
||||
auto m = (ServerMotd_Struct *) pack->pBuffer;
|
||||
strn0cpy(m->myname, c->GetName(), sizeof(m->myname));
|
||||
strn0cpy(m->motd, message.c_str(), sizeof(m->motd));
|
||||
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#include "../../client.h"
|
||||
|
||||
void SetName(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 2) {
|
||||
c->Message(Chat::White, "Usage: #set name [Name]");
|
||||
return;
|
||||
}
|
||||
|
||||
if (c->GetTarget() && c->GetTarget()->IsClient()) {
|
||||
auto t = c->GetTarget()->CastToClient();
|
||||
|
||||
std::string new_name = sep->arg[2];
|
||||
std::string old_name = t->GetCleanName();
|
||||
|
||||
if (t->ChangeFirstName(new_name.c_str(), c->GetCleanName())) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Successfully renamed {} to {}",
|
||||
old_name,
|
||||
new_name
|
||||
).c_str()
|
||||
);
|
||||
|
||||
c->Message(Chat::White, "Sending player to char select.");
|
||||
|
||||
t->Kick("Name was changed");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Unable to rename {}. Check that the new name '{}' isn't already taken.",
|
||||
old_name,
|
||||
new_name
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#include "../../client.h"
|
||||
#include "../../worldserver.h"
|
||||
|
||||
extern WorldServer worldserver;
|
||||
|
||||
void SetOOCMute(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 2) {
|
||||
c->Message(Chat::White, "Usage: #set ooc_mute [on|off]");
|
||||
return;
|
||||
}
|
||||
|
||||
const bool is_muted = Strings::ToBool(sep->arg[2]);
|
||||
|
||||
ServerPacket pack(ServerOP_OOCMute, sizeof(ServerOOCMute_Struct));
|
||||
|
||||
auto o = (ServerOOCMute_Struct*) pack.pBuffer;
|
||||
o->is_muted = is_muted;
|
||||
|
||||
worldserver.SendPacket(&pack);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Server OOC is {} muted.",
|
||||
is_muted ? "now" : "no longer"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
#include "../../client.h"
|
||||
|
||||
void SetPassword(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 3) {
|
||||
c->Message(Chat::White, "Usage: #set password [Account Name] [Password] [Loginserver]");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string account_name = sep->arg[2];
|
||||
std::string password = sep->arg[3];
|
||||
std::string loginserver = arguments >= 4 ? sep->arg[4] : "eqemu";
|
||||
|
||||
int16 status = 0;
|
||||
|
||||
const uint32 account_id = database.GetAccountIDByName(account_name, loginserver, &status);
|
||||
if (!account_id) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Account {} was not found.",
|
||||
account_name
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (status > c->Admin()) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"You cannot change the password for Account {} as its status is higher than yours.",
|
||||
account_name
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Password {} changed for Account {}.",
|
||||
(
|
||||
database.SetLocalPassword(account_id, password.c_str()) ?
|
||||
"successfully" :
|
||||
"failed"
|
||||
),
|
||||
account_name
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#include "../../client.h"
|
||||
|
||||
void SetPVP(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 2) {
|
||||
c->Message(Chat::White, "Usage: #set pvp [on|off]");
|
||||
return;
|
||||
}
|
||||
|
||||
auto t = c;
|
||||
if (c->GetTarget() && c->GetTarget()->IsClient()) {
|
||||
t = c->GetTarget()->CastToClient();
|
||||
}
|
||||
|
||||
const bool pvp_state = Strings::ToBool(sep->arg[2]);
|
||||
|
||||
t->SetPVP(pvp_state);
|
||||
|
||||
if (c != t) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} now follows the ways of {}.",
|
||||
c->GetTargetDescription(t),
|
||||
pvp_state ? "Discord" : "Order"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#include "../../client.h"
|
||||
|
||||
void SetPVPPoints(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 2 || !sep->IsNumber(2)) {
|
||||
c->Message(Chat::White, "Usage: #set pvp_points [Amount]");
|
||||
return;
|
||||
}
|
||||
|
||||
auto t = c;
|
||||
if (c->GetTarget() && c->GetTarget()->IsClient()) {
|
||||
t = c->GetTarget()->CastToClient();
|
||||
}
|
||||
|
||||
const uint32 pvp_points = Strings::ToUnsignedInt(sep->arg[2]);
|
||||
|
||||
t->SetPVPPoints(pvp_points);
|
||||
t->Save();
|
||||
t->SendPVPStats();
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} now {} {} PVP Point{}.",
|
||||
c->GetTargetDescription(t, TargetDescriptionType::UCYou),
|
||||
c == t ? "have" : "has",
|
||||
Strings::Commify(pvp_points),
|
||||
pvp_points != 1 ? "s" : ""
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
#include "../../client.h"
|
||||
|
||||
void SetRace(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 2 || !sep->IsNumber(2)) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Usage: #set race [0-{}, 2253-2259] (0 for back to normal)",
|
||||
RuleI(NPC, MaxRaceID)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Mob* t = c;
|
||||
if (c->GetTarget()) {
|
||||
t = c->GetTarget();
|
||||
}
|
||||
|
||||
const uint16 race_id = Strings::ToUnsignedInt(sep->arg[2]);
|
||||
|
||||
if (
|
||||
!EQ::ValueWithin(race_id, RACE_DOUG_0, RuleI(NPC, MaxRaceID)) &&
|
||||
!EQ::ValueWithin(race_id, 2253, 2259)
|
||||
) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Usage: #race [0-{}, 2253-2259] (0 for back to normal)",
|
||||
RuleI(NPC, MaxRaceID)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
t->SendIllusionPacket(race_id);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} {} now temporarily a(n) {} ({}).",
|
||||
c->GetTargetDescription(t, TargetDescriptionType::UCYou),
|
||||
c == t ? "are" : "is",
|
||||
GetRaceIDName(race_id),
|
||||
race_id
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
#include "../../client.h"
|
||||
|
||||
void SetRacePermanent(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 2 || !sep->IsNumber(2)) {
|
||||
c->Message(Chat::White, "Usage: #set race_permanent [Race ID]");
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"NOTE: Not all models are global. If a model is not global, it will appear as a Human on character select and in zones without the model."
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
auto t = c;
|
||||
if (c->GetTarget() && c->GetTarget()->IsClient()) {
|
||||
t = c->GetTarget()->CastToClient();
|
||||
}
|
||||
|
||||
const uint16 race_id = Strings::ToUnsignedInt(sep->arg[2]);
|
||||
const uint8 gender_id = Mob::GetDefaultGender(race_id, t->GetBaseGender());
|
||||
|
||||
LogInfo("Race changed by {} for {} to {} ({})",
|
||||
c->GetCleanName(),
|
||||
c->GetTargetDescription(t),
|
||||
GetRaceIDName(race_id),
|
||||
race_id
|
||||
);
|
||||
|
||||
t->SetBaseRace(race_id);
|
||||
t->SetBaseGender(gender_id);
|
||||
t->Save();
|
||||
t->SendIllusionPacket(race_id, gender_id);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Race changed for {} to {} ({}).",
|
||||
c->GetTargetDescription(t),
|
||||
GetRaceIDName(race_id),
|
||||
race_id
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "../../client.h"
|
||||
#include "../../worldserver.h"
|
||||
|
||||
extern WorldServer worldserver;
|
||||
|
||||
void SetServerLocked(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 2) {
|
||||
c->Message(Chat::White, "Usage: #set server_locked [on|off]");
|
||||
return;
|
||||
}
|
||||
|
||||
bool is_locked = Strings::ToBool(sep->arg[2]);
|
||||
|
||||
if (c->EntityVariableExists("old_command")) {
|
||||
const std::string& old_command = c->GetEntityVariable("old_command");
|
||||
if (old_command == "lock" || old_command == "serverlock") {
|
||||
is_locked = true;
|
||||
} else if (old_command == "unlock" || old_command == "serverunlock") {
|
||||
is_locked = false;
|
||||
}
|
||||
}
|
||||
|
||||
auto pack = new ServerPacket(ServerOP_Lock, sizeof(ServerLock_Struct));
|
||||
|
||||
auto l = (ServerLock_Struct *) pack->pBuffer;
|
||||
strn0cpy(l->character_name, c->GetCleanName(), sizeof(l->character_name));
|
||||
l->is_locked = is_locked;
|
||||
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
Executable
+44
@@ -0,0 +1,44 @@
|
||||
#include "../../client.h"
|
||||
|
||||
void SetSkill(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 skill [Skill ID] [Skill Value]");
|
||||
return;
|
||||
}
|
||||
|
||||
auto t = c;
|
||||
if (c->GetTarget() && c->GetTarget()->IsClient()) {
|
||||
t = c->GetTarget()->CastToClient();
|
||||
}
|
||||
|
||||
const uint16 skill_id = Strings::ToUnsignedInt(sep->arg[2]);
|
||||
const uint16 skill_value = Strings::ToUnsignedInt(sep->arg[3]);
|
||||
|
||||
if (!EQ::ValueWithin(skill_id, EQ::skills::Skill1HBlunt, EQ::skills::HIGHEST_SKILL)) {
|
||||
c->Message(Chat::White, "Usage: #set skill [Skill ID] [Skill Value]");
|
||||
c->Message(Chat::White, fmt::format("Skill ID: 0 to {}", EQ::skills::HIGHEST_SKILL).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
const auto skill_type = static_cast<EQ::skills::SkillType>(skill_id);
|
||||
|
||||
t->SetSkill(
|
||||
skill_type,
|
||||
skill_value > t->MaxSkill(skill_type) ? t->MaxSkill(skill_type) : skill_value
|
||||
);
|
||||
|
||||
if (c != t) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Set {} ({}) to {} for {}.",
|
||||
EQ::skills::GetSkillName(skill_type),
|
||||
skill_id,
|
||||
skill_value > t->MaxSkill(skill_type) ? t->MaxSkill(skill_type) : skill_value,
|
||||
c->GetTargetDescription(t)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
#include "../../client.h"
|
||||
|
||||
void SetSkillAll(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 2 || !sep->IsNumber(2)) {
|
||||
c->Message(Chat::White, "Usage: #set skill_all [Skill Level]");
|
||||
return;
|
||||
}
|
||||
|
||||
auto t = c;
|
||||
if (c->GetTarget() && c->GetTarget()->IsClient()) {
|
||||
t = c->GetTarget()->CastToClient();
|
||||
}
|
||||
|
||||
const uint16 skill_level = Strings::ToUnsignedInt(sep->arg[2]);
|
||||
|
||||
for (const auto& s : EQ::skills::GetSkillTypeMap()) {
|
||||
if (t->CanHaveSkill(s.first) && t->MaxSkill(s.first)) {
|
||||
if (c != t) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Setting {} ({}) to {} for {}.",
|
||||
s.second,
|
||||
s.first,
|
||||
skill_level > t->MaxSkill(s.first) ? t->MaxSkill(s.first) : skill_level,
|
||||
c->GetTargetDescription(t)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
t->SetSkill(
|
||||
s.first,
|
||||
skill_level > t->MaxSkill(s.first) ? t->MaxSkill(s.first) : skill_level
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#include "../../client.h"
|
||||
|
||||
void SetSkillAllMax(Client *c, const Seperator *sep)
|
||||
{
|
||||
auto t = c;
|
||||
if (c->GetTarget() && c->GetTarget()->IsClient()) {
|
||||
t = c->GetTarget()->CastToClient();
|
||||
}
|
||||
|
||||
t->MaxSkills();
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Maxed skills for {}.",
|
||||
c->GetTargetDescription(t)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
#include "../../client.h"
|
||||
|
||||
void SetStartZone(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 2) {
|
||||
c->Message(Chat::White, "Usage: #set start_zone [Zone ID|Zone Short Name]");
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Optional Usage: Use '#set start_zone reset' or '#set start_zone 0' to clear a starting zone. Player can select a starting zone using /setstartcity"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
auto t = c;
|
||||
if (c->GetTarget() && c->GetTarget()->IsClient()) {
|
||||
t = c->GetTarget()->CastToClient();
|
||||
}
|
||||
|
||||
const uint32 zone_id = (
|
||||
sep->IsNumber(2) ?
|
||||
Strings::ToUnsignedInt(sep->arg[2]) :
|
||||
ZoneID(sep->arg[2])
|
||||
);
|
||||
|
||||
t->SetStartZone(zone_id);
|
||||
|
||||
const bool is_reset = (
|
||||
Strings::EqualFold(sep->arg[2], "reset") ||
|
||||
zone_id == 0
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Start Zone {} for {} |{}",
|
||||
is_reset ? "Reset" : "Changed",
|
||||
c->GetTargetDescription(t, TargetDescriptionType::UCSelf),
|
||||
(
|
||||
zone_id ?
|
||||
fmt::format(
|
||||
" {} ({}) ID: {}",
|
||||
ZoneLongName(zone_id),
|
||||
ZoneName(zone_id),
|
||||
zone_id
|
||||
) :
|
||||
""
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
#include "../../client.h"
|
||||
|
||||
void SetTemporaryName(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 2) {
|
||||
c->Message(Chat::White, "Usage: #set temporary_name [New Name]");
|
||||
c->Message(Chat::White, "Note: This command requires a target, even if the target is yourself.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!c->GetTarget()) {
|
||||
c->Message(Chat::White, "Usage: #set temporary_name [New Name]");
|
||||
c->Message(Chat::White, "Note: This command requires a target, even if the target is yourself.");
|
||||
return;
|
||||
}
|
||||
|
||||
Mob* t = c->GetTarget();
|
||||
|
||||
const std::string& temporary_name = strlen(sep->arg[2]) ? sep->arg[2] : "";
|
||||
|
||||
t->TempName(temporary_name.c_str());
|
||||
|
||||
if (temporary_name.length()) {
|
||||
const std::string& current_name = t->GetName();
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Renamed {} to {} temporarily.",
|
||||
current_name,
|
||||
temporary_name
|
||||
).c_str()
|
||||
);
|
||||
} else {
|
||||
c->Message(Chat::White, "Restored your target's original name.");
|
||||
}
|
||||
}
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
#include "../../client.h"
|
||||
|
||||
void SetTexture(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 2 || !sep->IsNumber(2)) {
|
||||
c->Message(Chat::White, "Usage: #set texture [Texture] [Helmet Texture]");
|
||||
return;
|
||||
}
|
||||
|
||||
const uint16 texture = Strings::ToUnsignedInt(sep->arg[2]);
|
||||
const uint8 helmet_texture = (
|
||||
sep->IsNumber(3) ?
|
||||
Strings::ToUnsignedInt(sep->arg[3]) :
|
||||
0
|
||||
);
|
||||
|
||||
Mob* t = c;
|
||||
if (c->GetTarget()) {
|
||||
t = c->GetTarget();
|
||||
}
|
||||
|
||||
if (IsPlayerRace(t->GetModel())) { // Player Races Wear Armor, so Wearchange is sent instead
|
||||
for (
|
||||
int texture_slot = EQ::textures::textureBegin;
|
||||
texture_slot <= EQ::textures::LastTintableTexture;
|
||||
texture_slot++
|
||||
) {
|
||||
t->SendTextureWC(texture_slot, texture);
|
||||
}
|
||||
} else { // Non-Player Races only need Illusion Packets to be sent for texture
|
||||
t->SendIllusionPacket(
|
||||
t->GetModel(),
|
||||
t->GetGender(),
|
||||
texture,
|
||||
helmet_texture
|
||||
);
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Texture Changed for {} | Texture: {}{}",
|
||||
c->GetTargetDescription(t, TargetDescriptionType::UCSelf),
|
||||
texture,
|
||||
(
|
||||
IsPlayerRace(t->GetModel()) ?
|
||||
"" :
|
||||
fmt::format(
|
||||
" Helmet Texture: {}",
|
||||
helmet_texture
|
||||
)
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
Executable
+67
@@ -0,0 +1,67 @@
|
||||
#include "../../client.h"
|
||||
|
||||
void SetTime(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 2 || !sep->IsNumber(2)) {
|
||||
c->Message(Chat::White, "Usage: #set time [Hour] [Minute]");
|
||||
|
||||
TimeOfDay_Struct world_time;
|
||||
zone->zone_time.GetCurrentEQTimeOfDay(time(0), &world_time);
|
||||
|
||||
auto time_string = fmt::format(
|
||||
"{} (Timezone: {})",
|
||||
Strings::ZoneTime(world_time.hour, world_time.minute),
|
||||
Strings::ZoneTime(zone->zone_time.getEQTimeZoneHr(), zone->zone_time.getEQTimeZoneHr())
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"It is currently {}.",
|
||||
time_string
|
||||
).c_str()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
uint8 minutes = 0;
|
||||
uint8 hours = Strings::ToUnsignedInt(sep->arg[2]) + 1;
|
||||
|
||||
if (hours > 24) {
|
||||
hours = 24;
|
||||
}
|
||||
|
||||
uint8 real_hours = (
|
||||
(hours - 1) > 0 ?
|
||||
(hours - 1) :
|
||||
0
|
||||
);
|
||||
|
||||
if (sep->IsNumber(3)) {
|
||||
minutes = Strings::ToUnsignedInt(sep->arg[3]);
|
||||
|
||||
if (minutes > 59) {
|
||||
minutes = 59;
|
||||
}
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Setting world time to {} (Timezone: {}).",
|
||||
Strings::ZoneTime(hours, minutes),
|
||||
Strings::ZoneTime(zone->zone_time.getEQTimeZoneHr(), zone->zone_time.getEQTimeZoneHr())
|
||||
).c_str()
|
||||
);
|
||||
|
||||
zone->SetTime(real_hours, minutes);
|
||||
|
||||
LogInfo(
|
||||
"{} :: Setting world time to {} (Timezone: {})",
|
||||
c->GetCleanName(),
|
||||
Strings::ZoneTime(hours, minutes),
|
||||
Strings::ZoneTime(zone->zone_time.getEQTimeZoneHr(), zone->zone_time.getEQTimeZoneHr())
|
||||
);
|
||||
}
|
||||
Executable
+58
@@ -0,0 +1,58 @@
|
||||
#include "../../client.h"
|
||||
|
||||
void SetTimeZone(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 2 || sep->IsNumber(2)) {
|
||||
c->Message(Chat::White, "Usage: #set time_zone [Hour] [Minute]");
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Current time zone is {}.",
|
||||
Strings::ZoneTime(zone->zone_time.getEQTimeZoneHr(), zone->zone_time.getEQTimeZoneMin())
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8 minutes = 0;
|
||||
uint8 hours = Strings::ToUnsignedInt(sep->arg[2]);
|
||||
|
||||
if (hours > 24) {
|
||||
hours = 24;
|
||||
}
|
||||
|
||||
uint8 real_hours = (
|
||||
(hours - 1) > 0 ?
|
||||
(hours - 1) :
|
||||
0
|
||||
);
|
||||
|
||||
if (sep->IsNumber(3)) {
|
||||
minutes = Strings::ToUnsignedInt(sep->arg[3]);
|
||||
|
||||
if (minutes > 59) {
|
||||
minutes = 59;
|
||||
}
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Setting timezone to {}.",
|
||||
Strings::ZoneTime(hours, minutes)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
const int new_timezone = ((hours * 60) + minutes);
|
||||
zone->zone_time.setEQTimeZone(new_timezone);
|
||||
content_db.SetZoneTZ(zone->GetZoneID(), zone->GetInstanceVersion(), new_timezone);
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_TimeOfDay, sizeof(TimeOfDay_Struct));
|
||||
|
||||
auto t = (TimeOfDay_Struct *) outapp->pBuffer;
|
||||
zone->zone_time.GetCurrentEQTimeOfDay(time(0), t);
|
||||
|
||||
entity_list.QueueClients(c, outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
#include "../../client.h"
|
||||
#include "../../titles.h"
|
||||
|
||||
void SetTitle(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 2) {
|
||||
c->Message(Chat::White, "Usage: #set title [Title]");
|
||||
c->Message(Chat::White, "Note: Use \"-1\" to remove title.");
|
||||
return;
|
||||
}
|
||||
|
||||
const bool is_remove = Strings::EqualFold(sep->argplus[2], "-1");
|
||||
std::string title = !is_remove ? sep->argplus[2] : "";
|
||||
|
||||
auto t = c;
|
||||
if (c->GetTarget() && c->GetTarget()->IsClient()) {
|
||||
t = c->GetTarget()->CastToClient();
|
||||
}
|
||||
|
||||
if (title.size() > 31) {
|
||||
c->Message(Chat::White, "Title must be 31 characters or less.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!title.empty()) {
|
||||
Strings::FindReplace(title, "_", " ");
|
||||
}
|
||||
|
||||
if (is_remove) {
|
||||
t->SetAATitle(title);
|
||||
} else {
|
||||
title_manager.CreateNewPlayerTitle(t, title);
|
||||
}
|
||||
|
||||
t->Save();
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Title has been {}{} for {}{}",
|
||||
is_remove ? "removed" : "changed",
|
||||
!is_remove ? " and saved" : "",
|
||||
c->GetTargetDescription(t),
|
||||
(
|
||||
is_remove ?
|
||||
"." :
|
||||
fmt::format(
|
||||
" to '{}'.",
|
||||
title
|
||||
)
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
#include "../../client.h"
|
||||
#include "../../titles.h"
|
||||
|
||||
void SetTitleSuffix(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (!arguments) {
|
||||
c->Message(Chat::White, "Usage: #set title_suffix [Title Suffix]");
|
||||
c->Message(Chat::White, "Note: Use \"-1\" to remove title.");
|
||||
return;
|
||||
}
|
||||
|
||||
const bool is_remove = !strcasecmp(sep->argplus[1], "-1");
|
||||
std::string suffix = is_remove ? "" : sep->argplus[1];
|
||||
|
||||
auto t = c;
|
||||
if (c->GetTarget() && c->GetTarget()->IsClient()) {
|
||||
t = c->GetTarget()->CastToClient();
|
||||
}
|
||||
|
||||
if (suffix.size() > 31) {
|
||||
c->Message(Chat::White, "Title suffix must be 31 characters or less.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!suffix.empty()) {
|
||||
Strings::FindReplace(suffix, "_", " ");
|
||||
}
|
||||
|
||||
if (is_remove) {
|
||||
t->SetTitleSuffix(suffix);
|
||||
} else {
|
||||
title_manager.CreateNewPlayerSuffix(t, suffix);
|
||||
}
|
||||
|
||||
t->Save();
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Title suffix has been {}{} for {}{}",
|
||||
is_remove ? "removed" : "changed",
|
||||
!is_remove ? " and saved" : "",
|
||||
c->GetTargetDescription(t),
|
||||
(
|
||||
is_remove ?
|
||||
"." :
|
||||
fmt::format(
|
||||
" to '{}'.",
|
||||
suffix
|
||||
)
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
Executable
+101
@@ -0,0 +1,101 @@
|
||||
#include "../../client.h"
|
||||
|
||||
void SetWeather(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 2 || !sep->IsNumber(2)) {
|
||||
c->Message(Chat::White, "Usage: #weather [0|1|2] - [Off|Rain|Snow]");
|
||||
c->Message(Chat::White, "Usage: #weather 3 [Type] [Intensity] - Manually set weather type and intensity");
|
||||
return;
|
||||
}
|
||||
|
||||
if (arguments == 2) {
|
||||
uint8 new_weather = Strings::ToUnsignedInt(sep->arg[2]);
|
||||
uint8 new_intensity = 0;
|
||||
std::string weather_message = "The sky clears.";
|
||||
|
||||
if (new_weather == EQ::constants::WeatherTypes::Snowing) {
|
||||
weather_message = "Snowflakes begin to fall from the sky.";
|
||||
new_weather = EQ::constants::WeatherTypes::Snowing;
|
||||
new_intensity = 2;
|
||||
} else if (new_weather == EQ::constants::WeatherTypes::Raining) {
|
||||
weather_message = "Raindrops begin to fall from the sky.";
|
||||
new_weather = EQ::constants::WeatherTypes::Raining;
|
||||
new_intensity = 1; // This is how it's done in Fear, and you can see a decent distance with it at this value
|
||||
}
|
||||
|
||||
zone->zone_weather = new_weather;
|
||||
auto outapp = new EQApplicationPacket(OP_Weather, 8);
|
||||
|
||||
if (new_weather != EQ::constants::WeatherTypes::None) {
|
||||
if (new_weather == EQ::constants::WeatherTypes::Snowing) {
|
||||
outapp->pBuffer[0] = EQ::constants::WeatherTypes::Snowing;
|
||||
}
|
||||
|
||||
outapp->pBuffer[4] = new_intensity;
|
||||
}
|
||||
|
||||
c->Message(Chat::White, weather_message.c_str());
|
||||
entity_list.QueueClients(c, outapp);
|
||||
|
||||
safe_delete(outapp);
|
||||
} else if (arguments == 4) {
|
||||
const uint8 command_type = Strings::ToUnsignedInt(sep->arg[2]);
|
||||
uint8 new_weather = EQ::constants::WeatherTypes::None;
|
||||
uint8 new_intensity = 0;
|
||||
std::string weather_message;
|
||||
|
||||
if (zone->zone_weather == EQ::constants::WeatherTypes::None) {
|
||||
if (command_type > EQ::constants::WeatherTypes::Snowing) {
|
||||
new_weather = Strings::ToUnsignedInt(sep->arg[3]);
|
||||
new_intensity = Strings::ToUnsignedInt(sep->arg[4]);
|
||||
|
||||
weather_message = fmt::format(
|
||||
"Sending {} ({}) with an intensity of {}.",
|
||||
EQ::constants::GetWeatherTypeName(new_weather),
|
||||
new_weather,
|
||||
new_intensity
|
||||
);
|
||||
} else if (command_type == EQ::constants::WeatherTypes::Snowing) {
|
||||
weather_message = "Snowflakes begin to fall from the sky.";
|
||||
new_weather = EQ::constants::WeatherTypes::Snowing;
|
||||
new_intensity = 2;
|
||||
} else if (command_type == EQ::constants::WeatherTypes::Raining) {
|
||||
weather_message = "Raindrops begin to fall from the sky.";
|
||||
new_weather = EQ::constants::WeatherTypes::Raining;
|
||||
new_intensity = 1; // This is how it's done in Fear, and you can see a decent distance with it at this value
|
||||
}
|
||||
|
||||
zone->zone_weather = new_weather;
|
||||
auto outapp = new EQApplicationPacket(OP_Weather, 8);
|
||||
|
||||
if (new_weather != EQ::constants::WeatherTypes::Raining) {
|
||||
outapp->pBuffer[0] = new_weather;
|
||||
}
|
||||
|
||||
outapp->pBuffer[4] = new_intensity;
|
||||
|
||||
c->Message(Chat::White, weather_message.c_str());
|
||||
entity_list.QueueClients(c, outapp);
|
||||
|
||||
safe_delete(outapp);
|
||||
} else {
|
||||
auto outapp = new EQApplicationPacket(OP_Weather, 8);
|
||||
weather_message = "The sky clears.";
|
||||
|
||||
if (zone->zone_weather == EQ::constants::WeatherTypes::Snowing) {
|
||||
weather_message = "The sky clears as the snow stops falling.";
|
||||
outapp->pBuffer[0] = 1; // Snow has it's own shutoff packet
|
||||
} else if (zone->zone_weather == EQ::constants::WeatherTypes::Raining) {
|
||||
weather_message = "The sky clears as the rain ceases to fall.";
|
||||
}
|
||||
|
||||
zone->zone_weather = EQ::constants::WeatherTypes::None;
|
||||
|
||||
c->Message(Chat::White, weather_message.c_str());
|
||||
entity_list.QueueClients(c, outapp);
|
||||
|
||||
safe_delete(outapp);
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+455
@@ -0,0 +1,455 @@
|
||||
#include "../../client.h"
|
||||
|
||||
void SetZoneData(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 3) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #set zone clipping [Minimum Clip] [Maximum Clip] [Fog Minimum Clip] [Fog Maximum Clip] [Permanent (0 = False, 1 = True)] (Permanent is optional)"
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #set zone color [Red] [Green] [Blue] [Permanent (0 = False, 1 = True)] (Permanent is optional)"
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #set zone header [Zone ID|Zone Short Name] [Version]"
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #set zone locked [on|off] [Zone ID|Zone Short Name]"
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #set zone safe_coordinates [X] [Y] [Z] [Heading] [Permanent (0 = False, 1 = True)] (Permanent is optional)"
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #set zone sky [Sky Type] [Permanent (0 = False, 1 = True)] (Permanent is optional)"
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #set zone underworld [Z] [Permanent (0 = False, 1 = True)] (Permanent is optional)"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const bool is_clipping = Strings::EqualFold(sep->arg[2], "clipping");
|
||||
const bool is_color = Strings::EqualFold(sep->arg[2], "color");
|
||||
const bool is_header = Strings::EqualFold(sep->arg[2], "header");
|
||||
const bool is_locked = Strings::EqualFold(sep->arg[2], "locked");
|
||||
const bool is_safe_coordinates = Strings::EqualFold(sep->arg[2], "safe_coordinates");
|
||||
const bool is_sky = Strings::EqualFold(sep->arg[2], "sky");
|
||||
const bool is_underworld = Strings::EqualFold(sep->arg[2], "underworld");
|
||||
|
||||
if (
|
||||
!is_clipping &&
|
||||
!is_color &&
|
||||
!is_header &&
|
||||
!is_locked &&
|
||||
!is_safe_coordinates &&
|
||||
!is_sky &&
|
||||
!is_underworld
|
||||
) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #set zone clipping [Minimum Clip] [Maximum Clip] [Fog Minimum Clip] [Fog Maximum Clip] [Permanent (0 = False, 1 = True)] (Permanent is optional)"
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #set zone color [Red] [Green] [Blue] [Permanent (0 = False, 1 = True)] (Permanent is optional)"
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #set zone header [Zone ID|Zone Short Name] [Version]"
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #set zone locked [on|off] [Zone ID|Zone Short Name]"
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #set zone safe_coordinates [X] [Y] [Z] [Heading] [Permanent (0 = False, 1 = True)] (Permanent is optional)"
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #set zone sky [Sky Type] [Permanent (0 = False, 1 = True)] (Permanent is optional)"
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #set zone underworld [Z] [Permanent (0 = False, 1 = True)] (Permanent is optional)"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_clipping) {
|
||||
const float minimum_clip = sep->arg[3] ? Strings::ToFloat(sep->arg[3]) : 0.0f;
|
||||
const float maximum_clip = sep->arg[4] ? Strings::ToFloat(sep->arg[4]) : 0.0f;
|
||||
const float minimum_fog_clip = sep->arg[5] ? Strings::ToFloat(sep->arg[5]) : 0.0f;
|
||||
const float maximum_fog_clip = sep->arg[6] ? Strings::ToFloat(sep->arg[6]) : 0.0f;
|
||||
const bool permanent = sep->arg[7] ? Strings::ToBool(sep->arg[7]) : false;
|
||||
|
||||
if (minimum_clip < 0.0f || maximum_clip < 0.0f) {
|
||||
c->Message(Chat::White, "Minimum Clip and Maximum Clip must be greater than or equal 0.0.");
|
||||
return;
|
||||
} else if (minimum_clip > maximum_clip) {
|
||||
c->Message(Chat::White, "Minimum Clip must be less than or equal to Maximum Clip!");
|
||||
return;
|
||||
} else {
|
||||
zone->newzone_data.minclip = minimum_clip;
|
||||
zone->newzone_data.maxclip = maximum_clip;
|
||||
|
||||
if (minimum_fog_clip) {
|
||||
for (float &fog_index: zone->newzone_data.fog_minclip) {
|
||||
fog_index = minimum_fog_clip;
|
||||
}
|
||||
}
|
||||
|
||||
if (maximum_fog_clip) {
|
||||
for (float &fog_index: zone->newzone_data.fog_maxclip) {
|
||||
fog_index = maximum_fog_clip;
|
||||
}
|
||||
}
|
||||
|
||||
if (permanent) {
|
||||
std::string query = fmt::format(
|
||||
"UPDATE zone SET minclip = {:.2f}, maxclip = {:.2f} WHERE zoneidnumber = {} AND version = {}",
|
||||
minimum_clip,
|
||||
maximum_clip,
|
||||
zone->GetZoneID(),
|
||||
zone->GetInstanceVersion()
|
||||
);
|
||||
|
||||
database.QueryDatabase(query);
|
||||
|
||||
if (minimum_fog_clip) {
|
||||
query = fmt::format(
|
||||
"UPDATE zone SET fog_minclip = {:.2f} WHERE zoneidnumber = {} AND version = {}",
|
||||
minimum_fog_clip,
|
||||
zone->GetZoneID(),
|
||||
zone->GetInstanceVersion()
|
||||
);
|
||||
database.QueryDatabase(query);
|
||||
}
|
||||
|
||||
if (maximum_fog_clip) {
|
||||
query = fmt::format(
|
||||
"UPDATE zone SET fog_maxclip = {:.2f} WHERE zoneidnumber = {} AND version = {}",
|
||||
maximum_fog_clip,
|
||||
zone->GetZoneID(),
|
||||
zone->GetInstanceVersion()
|
||||
);
|
||||
database.QueryDatabase(query);
|
||||
}
|
||||
}
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct));
|
||||
memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size);
|
||||
entity_list.QueueClients(c, outapp);
|
||||
safe_delete(outapp);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Clipping Changed | Zone: {} Permanent: {}",
|
||||
zone->GetZoneDescription(),
|
||||
permanent ? "Yes" : "No"
|
||||
).c_str()
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Clipping Changed | Minimum Clip: {:.2f} Maximum Clip: {:.2f}",
|
||||
minimum_clip,
|
||||
maximum_clip
|
||||
).c_str()
|
||||
);
|
||||
|
||||
if (minimum_fog_clip || maximum_fog_clip) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Clipping Changed | Fog Minimum Clip: {:.2f} Fog Maximum Clip: {:.2f}",
|
||||
minimum_fog_clip,
|
||||
maximum_fog_clip
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if (is_color) {
|
||||
if (
|
||||
arguments < 3 ||
|
||||
!sep->IsNumber(3) ||
|
||||
!sep->IsNumber(4) ||
|
||||
!sep->IsNumber(5)
|
||||
) {
|
||||
c->Message(Chat::White, "Usage: #set zone color [Red] [Green] [Blue] [Permanent (0 = False, 1 = True)]");
|
||||
return;
|
||||
}
|
||||
|
||||
const uint8 red = Strings::ToUnsignedInt(sep->arg[3]);
|
||||
const uint8 green = Strings::ToUnsignedInt(sep->arg[4]);
|
||||
const uint8 blue = Strings::ToUnsignedInt(sep->arg[5]);
|
||||
const bool permanent = sep->arg[6] ? Strings::ToBool(sep->arg[6]) : false;
|
||||
|
||||
if (
|
||||
!EQ::ValueWithin(red, 0, UINT8_MAX) ||
|
||||
!EQ::ValueWithin(green, 0, UINT8_MAX) ||
|
||||
!EQ::ValueWithin(blue, 0, UINT8_MAX)
|
||||
) {
|
||||
c->Message(Chat::White, "Colors cannot be less than 0 or greater than 255.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (permanent) {
|
||||
const std::string& query = fmt::format(
|
||||
"UPDATE zone SET fog_red = {}, fog_green = {}, fog_blue = {} "
|
||||
"WHERE zoneidnumber = {} AND version = {}",
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
zone->GetZoneID(),
|
||||
zone->GetInstanceVersion()
|
||||
);
|
||||
database.QueryDatabase(query);
|
||||
}
|
||||
|
||||
for (uint8 fog_index = 0; fog_index < 4; fog_index++) {
|
||||
zone->newzone_data.fog_red[fog_index] = red;
|
||||
zone->newzone_data.fog_green[fog_index] = green;
|
||||
zone->newzone_data.fog_blue[fog_index] = blue;
|
||||
}
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct));
|
||||
memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size);
|
||||
entity_list.QueueClients(c, outapp);
|
||||
safe_delete(outapp);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Fog Color Changed | Zone: {} Red: {} Green: {} Blue: {} Permanent: {}",
|
||||
zone->GetZoneDescription(),
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
permanent ? "Yes" : "No"
|
||||
).c_str()
|
||||
);
|
||||
} else if (is_header) {
|
||||
if (arguments < 3) {
|
||||
c->Message(Chat::White, "Usage: #set zone header [Zone ID|Zone Short Name] [Version]");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto zone_id = (
|
||||
sep->IsNumber(3) ?
|
||||
Strings::ToUnsignedInt(sep->arg[3]) :
|
||||
ZoneID(sep->arg[3])
|
||||
);
|
||||
if (!zone_id) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Zone ID {} could not be found.",
|
||||
zone_id
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string& zone_short_name = ZoneName(zone_id);
|
||||
const std::string& zone_long_name = ZoneLongName(zone_id);
|
||||
const auto version = (
|
||||
sep->IsNumber(4) ?
|
||||
Strings::ToUnsignedInt(sep->arg[4]) :
|
||||
0
|
||||
);
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct));
|
||||
memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size);
|
||||
entity_list.QueueClients(c, outapp);
|
||||
safe_delete(outapp);
|
||||
|
||||
zone_store.LoadZones(content_db);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Zone Header Load {} | Zone: {} ({}){}",
|
||||
(
|
||||
zone->LoadZoneCFG(zone_short_name.c_str(), version) ?
|
||||
"Succeeded" :
|
||||
"Failed"
|
||||
),
|
||||
zone_long_name,
|
||||
zone_short_name,
|
||||
(
|
||||
version ?
|
||||
fmt::format(
|
||||
" Version: {}",
|
||||
version
|
||||
) :
|
||||
""
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
} else if (is_locked) {
|
||||
if (arguments < 4) {
|
||||
c->Message(Chat::White, "Usage: #set zone locked [on|off] [Zone ID|Zone Short Name]");
|
||||
return;
|
||||
}
|
||||
|
||||
const bool is_locked = Strings::ToBool(sep->arg[3]);
|
||||
|
||||
const uint32 zone_id = (
|
||||
sep->IsNumber(4) ?
|
||||
Strings::ToUnsignedInt(sep->arg[4]) :
|
||||
ZoneID(sep->arg[4])
|
||||
);
|
||||
const std::string& zone_short_name = Strings::ToLower(ZoneName(zone_id, true));
|
||||
|
||||
const bool is_unknown_zone = Strings::EqualFold(zone_short_name, "unknown");
|
||||
if (!zone_id || is_unknown_zone) {
|
||||
c->Message(Chat::White, "Usage: #set zone locked [on|off] [Zone ID|Zone Short Name]");
|
||||
return;
|
||||
}
|
||||
|
||||
auto pack = new ServerPacket(ServerOP_LockZone, sizeof(ServerLockZone_Struct));
|
||||
|
||||
auto l = (ServerLockZone_Struct *) pack->pBuffer;
|
||||
strn0cpy(l->adminname, c->GetName(), sizeof(l->adminname));
|
||||
l->op = is_locked ? ServerLockType::Lock : ServerLockType::Unlock;
|
||||
l->zoneID = zone_id;
|
||||
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
} else if (is_safe_coordinates) {
|
||||
if (
|
||||
arguments < 3 ||
|
||||
!sep->IsNumber(3) ||
|
||||
!sep->IsNumber(4) ||
|
||||
!sep->IsNumber(5)
|
||||
) {
|
||||
c->Message(Chat::White, "Usage: #set zone safe_coordinates [X] [Y] [Z] [Heading] [Permanent (0 = False, 1 = True)]");
|
||||
c->Message(Chat::White, "Not sending Heading defaults to current Heading and the change is temporary.");
|
||||
return;
|
||||
}
|
||||
|
||||
const float x = Strings::ToFloat(sep->arg[3]);
|
||||
const float y = Strings::ToFloat(sep->arg[4]);
|
||||
const float z = Strings::ToFloat(sep->arg[5]);
|
||||
const float heading = sep->arg[6] ? Strings::ToFloat(sep->arg[6]) : c->GetHeading();
|
||||
const bool permanent = sep->arg[7] ? Strings::ToBool(sep->arg[7]) : false;
|
||||
|
||||
if (permanent) {
|
||||
const std::string& query = fmt::format(
|
||||
"UPDATE zone SET safe_x = {:.2f}, safe_y = {:.2f}, safe_z = {:.2f}, safe_heading = {:.2f} WHERE zoneidnumber = {} AND version = {}",
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
heading,
|
||||
zone->GetZoneID(),
|
||||
zone->GetInstanceVersion()
|
||||
);
|
||||
database.QueryDatabase(query);
|
||||
}
|
||||
|
||||
zone->newzone_data.safe_x = x;
|
||||
zone->newzone_data.safe_y = y;
|
||||
zone->newzone_data.safe_z = z;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct));
|
||||
memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size);
|
||||
entity_list.QueueClients(c, outapp);
|
||||
safe_delete(outapp);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Safe Coordinates Changed | Zone: {} XYZ: {:.2f}, {:.2f}, {:.2f} Heading: {:.2f} Permanent: {} ",
|
||||
zone->GetZoneDescription(),
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
heading,
|
||||
permanent ? "Yes" : "No"
|
||||
).c_str()
|
||||
);
|
||||
} else if (is_sky) {
|
||||
if (arguments < 3 || !sep->IsNumber(3)) {
|
||||
c->Message(Chat::White, "Usage: #set zone sky [Sky Type] [Permanent (0 = False, 1 = True)]");
|
||||
return;
|
||||
}
|
||||
|
||||
const uint8 sky_type = Strings::ToUnsignedInt(sep->arg[3]);
|
||||
const bool permanent = sep->arg[4] ? Strings::ToBool(sep->arg[4]) : false;
|
||||
|
||||
if (!EQ::ValueWithin(sky_type, 0, UINT8_MAX)) {
|
||||
c->Message(Chat::White, "Sky Type cannot be less than 0 or greater than 255!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (permanent) {
|
||||
const std::string& query = fmt::format(
|
||||
"UPDATE zone SET sky = {} WHERE zoneidnumber = {} AND version = {}",
|
||||
sky_type,
|
||||
zone->GetZoneID(),
|
||||
zone->GetInstanceVersion()
|
||||
);
|
||||
database.QueryDatabase(query);
|
||||
}
|
||||
|
||||
zone->newzone_data.sky = sky_type;
|
||||
auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct));
|
||||
memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size);
|
||||
entity_list.QueueClients(c, outapp);
|
||||
safe_delete(outapp);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Sky Changed | Zone: {} Sky Type: {} Permanent: {}",
|
||||
zone->GetZoneDescription(),
|
||||
sky_type,
|
||||
permanent ? "Yes" : "No"
|
||||
).c_str()
|
||||
);
|
||||
} else if (is_underworld) {
|
||||
if (arguments < 3 || !sep->IsNumber(3)) {
|
||||
c->Message(Chat::White, "Usage: #set zone underworld [Z] [Permanent (0 = False, 1 = True)]");
|
||||
return;
|
||||
}
|
||||
|
||||
const float z = Strings::ToFloat(sep->arg[3]);
|
||||
const bool permanent = sep->arg[4] ? Strings::ToBool(sep->arg[4]) : false;
|
||||
|
||||
if (permanent) {
|
||||
auto query = fmt::format(
|
||||
"UPDATE zone SET underworld = {:.2f} WHERE zoneidnumber = {} AND version = {}",
|
||||
z,
|
||||
zone->GetZoneID(),
|
||||
zone->GetInstanceVersion()
|
||||
);
|
||||
database.QueryDatabase(query);
|
||||
}
|
||||
|
||||
zone->newzone_data.underworld = z;
|
||||
auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct));
|
||||
memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size);
|
||||
entity_list.QueueClients(c, outapp);
|
||||
safe_delete(outapp);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Underworld Z Changed | Zone: {} Z: {:.2f} Permanent: {}",
|
||||
zone->GetZoneDescription(),
|
||||
z,
|
||||
permanent ? "Yes" : "No"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user