mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-16 01:01:30 +00:00
[Telnet] Add cross zone/world wide cast and move functionality to Telnet (#3409)
* [Telnet] Add cross zone/world wide cast and move functionality to Telnet # Notes - Add `czcast`, `czmove`, `wwcast`, and `wwmove` to Telnet functionality. - Allows operators to cast spells across zone/world-wide and move players across zone/world-wide from telnet. * Update console.cpp * Update console.cpp * Validation * Update console.cpp
This commit is contained in:
parent
1100668f21
commit
57243c6799
@ -962,6 +962,352 @@ void ConsoleQuit(
|
||||
connection->Close();
|
||||
}
|
||||
|
||||
void ConsoleCrossZoneCastSpell(
|
||||
EQ::Net::ConsoleServerConnection *connection,
|
||||
const std::string &command,
|
||||
const std::vector<std::string> &args
|
||||
) {
|
||||
if (args.size() < 3) {
|
||||
connection->SendLine("czcast character [character_id] [spell_id]");
|
||||
connection->SendLine("czcast expedition [expedition_id] [spell_id]");
|
||||
connection->SendLine("czcast group [group_id] [spell_id]");
|
||||
connection->SendLine("czcast guild [guild_id] [spell_id]");
|
||||
connection->SendLine("czcast name [character_name] [spell_id]");
|
||||
connection->SendLine("czcast raid [raid_id] [spell_id]");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& type = Strings::ToLower(args[0]);
|
||||
|
||||
const auto is_character = type == "character";
|
||||
const auto is_expedition = type == "expedition";
|
||||
const auto is_group = type == "group";
|
||||
const auto is_guild = type == "guild";
|
||||
const auto is_name = type == "name";
|
||||
const auto is_raid = type == "raid";
|
||||
|
||||
if (
|
||||
!is_character &&
|
||||
!is_expedition &&
|
||||
!is_group &&
|
||||
!is_guild &&
|
||||
!is_name &
|
||||
!is_raid
|
||||
) {
|
||||
connection->SendLine("czcast character [character_id] [spell_id]");
|
||||
connection->SendLine("czcast expedition [expedition_id] [spell_id]");
|
||||
connection->SendLine("czcast group [group_id] [spell_id]");
|
||||
connection->SendLine("czcast guild [guild_id] [spell_id]");
|
||||
connection->SendLine("czcast name [character_name] [spell_id]");
|
||||
connection->SendLine("czcast raid [raid_id] [spell_id]");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string name;
|
||||
int update_identifier = 0;
|
||||
|
||||
if (!is_name) {
|
||||
if (Strings::IsNumber(args[1])) {
|
||||
update_identifier = Strings::ToInt(args[1]);
|
||||
}
|
||||
|
||||
if (!update_identifier) {
|
||||
connection->SendLine(fmt::format("Identifier is invalid for '{}'.", type));
|
||||
return;
|
||||
}
|
||||
} else if (is_name) {
|
||||
if (!Strings::IsNumber(args[1])) {
|
||||
name = Strings::UcFirst(Strings::ToLower(args[1]));
|
||||
}
|
||||
|
||||
if (name.empty()) {
|
||||
connection->SendLine("Empty name is invalid.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const auto spell_id = Strings::IsNumber(args[2]) ? Strings::ToUnsignedInt(args[2]) : 0;
|
||||
|
||||
if (!spell_id) {
|
||||
connection->SendLine("Spell ID is invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8 update_type;
|
||||
|
||||
if (is_character) {
|
||||
update_type = CZUpdateType_Character;
|
||||
} else if (is_expedition) {
|
||||
update_type = CZUpdateType_Expedition;
|
||||
} else if (is_group) {
|
||||
update_type = CZUpdateType_Group;
|
||||
} else if (is_guild) {
|
||||
update_type = CZUpdateType_Guild;
|
||||
} else if (is_name) {
|
||||
update_type = CZUpdateType_ClientName;
|
||||
} else if (is_raid) {
|
||||
update_type = CZUpdateType_Raid;
|
||||
}
|
||||
|
||||
auto pack = new ServerPacket(ServerOP_CZSpell, sizeof(CZSpell_Struct));
|
||||
auto* CZS = (CZSpell_Struct*) pack->pBuffer;
|
||||
|
||||
CZS->update_type = update_type;
|
||||
CZS->update_subtype = CZSpellUpdateSubtype_Cast;
|
||||
CZS->update_identifier = update_identifier;
|
||||
CZS->spell_id = spell_id;
|
||||
|
||||
strn0cpy(CZS->client_name, name.c_str(), sizeof(CZS->client_name));
|
||||
|
||||
zoneserver_list.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
|
||||
connection->SendLine(
|
||||
fmt::format(
|
||||
"Casting spell ID {} across zones by {} with an identifier of {}.",
|
||||
spell_id,
|
||||
type,
|
||||
!is_name ? std::to_string(update_identifier) : name
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void ConsoleWorldWideCastSpell(
|
||||
EQ::Net::ConsoleServerConnection *connection,
|
||||
const std::string &command,
|
||||
const std::vector<std::string> &args
|
||||
) {
|
||||
if (args.size() < 1) {
|
||||
connection->SendLine("wwcast [spell_id]");
|
||||
connection->SendLine("wwcast [spell_id] [min_status]");
|
||||
connection->SendLine("wwcast [spell_id] [min_status] [max_status]");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto spell_id = Strings::IsNumber(args[0]) ? Strings::ToUnsignedInt(args[0]) : 0;
|
||||
|
||||
if (!spell_id) {
|
||||
connection->SendLine("Spell ID 0 is invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8 min_status = AccountStatus::Player;
|
||||
uint8 max_status = AccountStatus::Player;
|
||||
|
||||
if (args.size() >= 2 && Strings::IsNumber(args[1])) {
|
||||
min_status = static_cast<uint8>(Strings::ToUnsignedInt(args[1]));
|
||||
}
|
||||
|
||||
if (args.size() >= 3 && Strings::IsNumber(args[2])) {
|
||||
max_status = static_cast<uint8>(Strings::ToUnsignedInt(args[2]));
|
||||
}
|
||||
|
||||
auto pack = new ServerPacket(ServerOP_WWSpell, sizeof(WWSpell_Struct));
|
||||
auto* WWS = (WWSpell_Struct*) pack->pBuffer;
|
||||
|
||||
WWS->update_type = WWSpellUpdateType_Cast;
|
||||
WWS->spell_id = spell_id;
|
||||
WWS->min_status = min_status;
|
||||
WWS->max_status = max_status;
|
||||
|
||||
zoneserver_list.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
|
||||
connection->SendLine(
|
||||
fmt::format(
|
||||
"Casting spell ID {} world wide for players with a status between {} and {}.",
|
||||
spell_id,
|
||||
min_status,
|
||||
max_status
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void ConsoleCrossZoneMove(
|
||||
EQ::Net::ConsoleServerConnection *connection,
|
||||
const std::string &command,
|
||||
const std::vector<std::string> &args
|
||||
) {
|
||||
if (args.size() < 3) {
|
||||
connection->SendLine("czmove character [character_id] [instance_id]");
|
||||
connection->SendLine("czmove character [character_id] [zone_short_name]");
|
||||
connection->SendLine("czmove expedition [expedition_id] [instance_id]");
|
||||
connection->SendLine("czmove expedition [expedition_id] [zone_short_name]");
|
||||
connection->SendLine("czmove group [group_id] [instance_id]");
|
||||
connection->SendLine("czmove group [group_id] [zone_short_name]");
|
||||
connection->SendLine("czmove guild [guild_id] [instance_id]");
|
||||
connection->SendLine("czmove guild [guild_id] [zone_short_name]");
|
||||
connection->SendLine("czmove name [character_name] [instance_id]");
|
||||
connection->SendLine("czmove name [character_name] [zone_short_name]");
|
||||
connection->SendLine("czmove raid [raid_id] [instance_id]");
|
||||
connection->SendLine("czmove raid [raid_id] [zone_short_name]");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& type = Strings::ToLower(args[0]);
|
||||
|
||||
const auto is_character = type == "character";
|
||||
const auto is_expedition = type == "expedition";
|
||||
const auto is_group = type == "group";
|
||||
const auto is_guild = type == "guild";
|
||||
const auto is_name = type == "name";
|
||||
const auto is_raid = type == "raid";
|
||||
|
||||
if (
|
||||
!is_character &&
|
||||
!is_expedition &&
|
||||
!is_group &&
|
||||
!is_guild &&
|
||||
!is_name &
|
||||
!is_raid
|
||||
) {
|
||||
connection->SendLine("czmove character [character_id] [instance_id]");
|
||||
connection->SendLine("czmove character [character_id] [zone_short_name]");
|
||||
connection->SendLine("czmove expedition [expedition_id] [instance_id]");
|
||||
connection->SendLine("czmove expedition [expedition_id] [zone_short_name]");
|
||||
connection->SendLine("czmove group [group_id] [instance_id]");
|
||||
connection->SendLine("czmove group [group_id] [zone_short_name]");
|
||||
connection->SendLine("czmove guild [guild_id] [instance_id]");
|
||||
connection->SendLine("czmove guild [guild_id] [zone_short_name]");
|
||||
connection->SendLine("czmove name [character_name] [instance_id]");
|
||||
connection->SendLine("czmove name [character_name] [zone_short_name]");
|
||||
connection->SendLine("czmove raid [raid_id] [instance_id]");
|
||||
connection->SendLine("czmove raid [raid_id] [zone_short_name]");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string name;
|
||||
int update_identifier = 0;
|
||||
|
||||
if (!is_name) {
|
||||
if (Strings::IsNumber(args[1])) {
|
||||
update_identifier = Strings::ToInt(args[1]);
|
||||
}
|
||||
|
||||
if (!update_identifier) {
|
||||
connection->SendLine(fmt::format("Identifier invalid for '{}'.", type));
|
||||
return;
|
||||
}
|
||||
} else if (is_name) {
|
||||
if (!Strings::IsNumber(args[1])) {
|
||||
name = Strings::UcFirst(Strings::ToLower(args[1]));
|
||||
}
|
||||
|
||||
if (name.empty()) {
|
||||
connection->SendLine("Empty name is invalid.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const auto& zone_short_name = !Strings::IsNumber(args[2]) ? args[2] : "";
|
||||
const uint16 instance_id = Strings::IsNumber(args[2]) ? static_cast<uint16>(Strings::ToUnsignedInt(args[2])) : 0;
|
||||
|
||||
const auto& z = !zone_short_name.empty() ? zone_store.GetZone(zone_short_name) : nullptr;
|
||||
|
||||
if (z && !z->id) {
|
||||
connection->SendLine(fmt::format("No zone with the short name '{}' exists.", zone_short_name));
|
||||
return;
|
||||
}
|
||||
|
||||
uint8 update_type;
|
||||
|
||||
if (is_character) {
|
||||
update_type = CZUpdateType_Character;
|
||||
} else if (is_expedition) {
|
||||
update_type = CZUpdateType_Expedition;
|
||||
} else if (is_group) {
|
||||
update_type = CZUpdateType_Group;
|
||||
} else if (is_guild) {
|
||||
update_type = CZUpdateType_Guild;
|
||||
} else if (is_name) {
|
||||
update_type = CZUpdateType_ClientName;
|
||||
} else if (is_raid) {
|
||||
update_type = CZUpdateType_Raid;
|
||||
}
|
||||
|
||||
auto pack = new ServerPacket(ServerOP_CZMove, sizeof(CZMove_Struct));
|
||||
auto* CZM = (CZMove_Struct*) pack->pBuffer;
|
||||
|
||||
CZM->update_type = update_type;
|
||||
CZM->update_subtype = !instance_id ? CZMoveUpdateSubtype_MoveZone : CZMoveUpdateSubtype_MoveZoneInstance;
|
||||
CZM->update_identifier = update_identifier;
|
||||
CZM->instance_id = instance_id;
|
||||
|
||||
strn0cpy(CZM->zone_short_name, zone_short_name.c_str(), sizeof(CZM->zone_short_name));
|
||||
strn0cpy(CZM->client_name, name.c_str(), sizeof(CZM->client_name));
|
||||
|
||||
zoneserver_list.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
|
||||
connection->SendLine(
|
||||
fmt::format(
|
||||
"Moving player(s) to {} by {} with an identifier of {}.",
|
||||
!instance_id ? fmt::format("{} ({})", z->long_name, z->short_name) : fmt::format("Instance ID {}", instance_id),
|
||||
type,
|
||||
!is_name ? std::to_string(update_identifier) : name
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void ConsoleWorldWideMove(
|
||||
EQ::Net::ConsoleServerConnection *connection,
|
||||
const std::string &command,
|
||||
const std::vector<std::string> &args
|
||||
) {
|
||||
if (args.size() < 1) {
|
||||
connection->SendLine("wwmove [instance_id]");
|
||||
connection->SendLine("wwmove [instance_id] [min_status]");
|
||||
connection->SendLine("wwmove [instance_id] [min_status] [max_status]");
|
||||
connection->SendLine("wwmove [zone_short_name]");
|
||||
connection->SendLine("wwmove [zone_short_name] [min_status]");
|
||||
connection->SendLine("wwmove [zone_short_name] [min_status] [max_status]");
|
||||
return;
|
||||
}
|
||||
\
|
||||
const auto& zone_short_name = !Strings::IsNumber(args[2]) ? args[2] : "";
|
||||
const uint16 instance_id = Strings::IsNumber(args[2]) ? static_cast<uint16>(Strings::ToUnsignedInt(args[2])) : 0;
|
||||
|
||||
const auto& z = !zone_short_name.empty() ? zone_store.GetZone(zone_short_name) : nullptr;
|
||||
|
||||
if (z && !z->id) {
|
||||
connection->SendLine(fmt::format("No zone with the short name '{}' exists.", zone_short_name));
|
||||
return;
|
||||
}
|
||||
|
||||
uint8 min_status = AccountStatus::Player;
|
||||
uint8 max_status = AccountStatus::Player;
|
||||
|
||||
if (args.size() >= 2 && Strings::IsNumber(args[1])) {
|
||||
min_status = static_cast<uint8>(Strings::ToUnsignedInt(args[1]));
|
||||
}
|
||||
|
||||
if (args.size() >= 3 && Strings::IsNumber(args[2])) {
|
||||
max_status = static_cast<uint8>(Strings::ToUnsignedInt(args[2]));
|
||||
}
|
||||
|
||||
auto pack = new ServerPacket(ServerOP_WWMove, sizeof(WWMove_Struct));
|
||||
auto* WWM = (WWMove_Struct*) pack->pBuffer;
|
||||
|
||||
WWM->update_type = !instance_id ? WWMoveUpdateType_MoveZone : WWMoveUpdateType_MoveZoneInstance;
|
||||
WWM->instance_id = instance_id;
|
||||
WWM->min_status = min_status;
|
||||
WWM->max_status = max_status;
|
||||
|
||||
strn0cpy(WWM->zone_short_name, zone_short_name.c_str(), sizeof(WWM->zone_short_name));
|
||||
|
||||
zoneserver_list.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
|
||||
connection->SendLine(
|
||||
fmt::format(
|
||||
"Moving player(s) to {} for players with a status between {} and {}.",
|
||||
!instance_id ? fmt::format("{} ({})", z->long_name, z->short_name) : fmt::format("Instance ID {}", instance_id),
|
||||
min_status,
|
||||
max_status
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param console
|
||||
@ -973,17 +1319,20 @@ void RegisterConsoleFunctions(std::unique_ptr<EQ::Net::ConsoleServer>& console)
|
||||
console->RegisterCall("api", 200, "api", std::bind(ConsoleApi, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("auction", 50, "auction [message]", std::bind(ConsoleAuction, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("broadcast", 50, "broadcast [message]", std::bind(ConsoleBroadcast, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("czcast", 50, "czcast [type] [identifier] [spell_id]", std::bind(ConsoleCrossZoneCastSpell, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("czmove", 50, "czmove [type] [identifier] [instance_id|zone_short_name] - instance_id and zone_short_name are interchangeable", std::bind(ConsoleCrossZoneMove, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("echo", 50, "echo [on/off]", std::bind(ConsoleNull, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("emote", 50, "emote [zonename or charname or world] [type] [message]", std::bind(ConsoleEmote, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("flag", 200, "flag [status] [accountname]", std::bind(ConsoleFlag, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("gmsay", 50, "gmsay [message]", std::bind(ConsoleGMSay, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("guildsay", 50, "guildsay [Character Name] [Guild ID] [Message]", std::bind(ConsoleGuildSay, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("iplookup", 50, "IPLookup [name]", std::bind(ConsoleIpLookup, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("iplookup", 50, "iplookup [name]", std::bind(ConsoleIpLookup, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("kick", 150, "kick [charname]", std::bind(ConsoleKick, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("lock", 150, "lock", std::bind(ConsoleLock, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("lsreconnect", 50, "LSReconnect", std::bind(ConsoleNull, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("md5", 50, "md5", std::bind(ConsoleMd5, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("ooc", 50, "ooc [message]", std::bind(ConsoleOOC, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("ping", 50, "ping", std::bind(ConsoleNull, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("reloadworld", 200, "reloadworld", std::bind(ConsoleReloadWorld, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("reloadzonequests", 200, "reloadzonequests [zone_short_name]", std::bind(ConsoleReloadZoneQuests, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("setpass", 200, "setpass [account_name] [new_password]", std::bind(ConsoleSetPass, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
@ -995,10 +1344,12 @@ void RegisterConsoleFunctions(std::unique_ptr<EQ::Net::ConsoleServer>& console)
|
||||
console->RegisterCall("who", 50, "who", std::bind(ConsoleWho, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("whoami", 50, "whoami", std::bind(ConsoleWhoami, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("worldshutdown", 200, "worldshutdown", std::bind(ConsoleWorldShutdown, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("wwcast", 50, "wwcast [spell_id] [min_status] [max_status] - min_status and max_status are optional", std::bind(ConsoleWorldWideCastSpell, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("wwmove", 50, "wwmove [instance_id|zone_short_name] [min_status] [max_status] - min_status and max_status are optional, instance_id and zone_short_name are interchangeable", std::bind(ConsoleWorldWideMove, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("zonebootup", 150, "zonebootup [zone_server_id] [zone_short_name]", std::bind(ConsoleZoneBootup, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("zonelock", 150, "zonelock [list|lock|unlock] [zone_short_name]", std::bind(ConsoleZoneLock, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("zoneshutdown", 150, "zoneshutdown [zone_short_name or zone_server_id]", std::bind(ConsoleZoneShutdown, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("zonestatus", 50, "zonestatus", std::bind(ConsoleZoneStatus, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));console->RegisterCall("ping", 50, "ping", std::bind(ConsoleNull, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("zonestatus", 50, "zonestatus", std::bind(ConsoleZoneStatus, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("quit", 50, "quit", std::bind(ConsoleQuit, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
console->RegisterCall("exit", 50, "exit", std::bind(ConsoleQuit, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user