Add proper sanitizing for input to SQLite database.

Adds function `ExecuteQueryWithArgs(query, ...)` to allow for queries 
with user input.

There is a known issue, that the funciton does not work with 
std::string. All strings must be converted to c strings.
This commit is contained in:
TheMatt2 2022-01-05 21:52:33 -05:00
parent f7b3a1ef10
commit 590ccc78aa
3 changed files with 137 additions and 119 deletions

View File

@ -40,4 +40,18 @@ namespace CDClientDatabase {
*/
CppSQLite3Query ExecuteQuery(const std::string& query);
//! Queries the CDClient and parses arguments
/*!
\param query The query with formatted arguments
\return the results of the query
*/
// Due to the template, implementation must be in the header.
template <typename... Args>
CppSQLite3Query ExecuteQueryWithArgs(const std::string& query, Args... args) {
CppSQLite3Buffer sqlBuf;
sqlBuf.format(query.c_str(), args...);
std::string safe_query = (const char *) sqlBuf;
return ExecuteQuery(safe_query);
}
};

View File

@ -89,21 +89,21 @@ Behavior* Behavior::GetBehavior(const uint32_t behaviorId)
Behavior* Behavior::CreateBehavior(const uint32_t behaviorId)
{
auto* cached = GetBehavior(behaviorId);
if (cached != nullptr)
{
return cached;
}
if (behaviorId == 0)
{
return new EmptyBehavior(0);
}
const auto templateId = GetBehaviorTemplate(behaviorId);
Behavior* behavior = nullptr;
switch (templateId)
{
case BehaviorTemplates::BEHAVIOR_EMPTY: break;
@ -266,7 +266,7 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId)
if (behavior == nullptr)
{
//Game::logger->Log("Behavior", "Failed to load unimplemented template id (%i)!\n", templateId);
behavior = new EmptyBehavior(behaviorId);
}
@ -293,7 +293,7 @@ BehaviorTemplates Behavior::GetBehaviorTemplate(const uint32_t behaviorId)
return BehaviorTemplates::BEHAVIOR_EMPTY;
}
const auto id = static_cast<BehaviorTemplates>(result.getIntField(0));
result.finalize();
@ -319,7 +319,7 @@ void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID
return;
}
auto* renderComponent = targetEntity->GetComponent<RenderComponent>();
const auto typeString = GeneralUtils::UTF16ToWTF8(type);
@ -342,29 +342,30 @@ void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID
if (renderComponent == nullptr)
{
GameMessages::SendPlayFXEffect(targetEntity, effectId, type, pair->second, secondary, 1, 1, true);
return;
}
renderComponent->PlayEffect(effectId, type, pair->second, secondary);
return;
}
}
std::stringstream query;
CppSQLite3Query result;
if (!type.empty())
{
query << "SELECT effectName FROM BehaviorEffect WHERE effectType = '" << typeString << "' AND effectID = " << std::to_string(effectId) << ";";
result = CDClientDatabase::ExecuteQueryWithArgs(
"SELECT effectName FROM BehaviorEffect WHERE effectType = %Q AND effectID = %u;",
typeString.c_str(), effectId);
}
else
{
query << "SELECT effectName, effectType FROM BehaviorEffect WHERE effectID = " << std::to_string(effectId) << ";";
result = CDClientDatabase::ExecuteQueryWithArgs(
"SELECT effectName, effectType FROM BehaviorEffect WHERE effectID = %u;",
effectId);
}
auto result = CDClientDatabase::ExecuteQuery(query.str());
if (result.eof() || result.fieldIsNull(0))
{
return;
@ -375,7 +376,7 @@ void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID
if (type.empty())
{
const auto typeResult = result.getStringField(1);
type = GeneralUtils::ASCIIToUTF16(typeResult);
m_effectType = new std::string(typeResult);
@ -388,7 +389,7 @@ void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID
if (renderComponent == nullptr)
{
GameMessages::SendPlayFXEffect(targetEntity, effectId, type, name, secondary, 1, 1, true);
return;
}
@ -431,7 +432,7 @@ Behavior::Behavior(const uint32_t behaviorId)
}
this->m_templateId = static_cast<BehaviorTemplates>(result.getIntField(0));
this->m_effectId = result.getIntField(1);
if (!result.fieldIsNull(2))

View File

@ -66,22 +66,22 @@
void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entity* entity, const SystemAddress& sysAddr) {
std::string chatCommand;
std::vector<std::string> args;
uint32_t breakIndex = 0;
for (uint32_t i = 1; i < command.size(); ++i) {
if (command[i] == L' ') {
breakIndex = i;
break;
}
chatCommand.push_back(static_cast<unsigned char>(command[i]));
breakIndex++;
}
uint32_t index = ++breakIndex;
while (true) {
std::string arg;
while (index < command.size()) {
if (command[index] == L' ') {
args.push_back(arg);
@ -89,24 +89,24 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
index++;
continue;
}
arg.push_back(static_cast<char>(command[index]));
index++;
}
if (arg != "") {
args.push_back(arg);
}
break;
}
//Game::logger->Log("SlashCommandHandler", "Received chat command \"%s\"\n", GeneralUtils::UTF16ToWTF8(command).c_str());
User* user = UserManager::Instance()->GetUser(sysAddr);
if ((chatCommand == "setgmlevel" || chatCommand == "makegm" || chatCommand == "gmlevel") && user->GetMaxGMLevel() > GAME_MASTER_LEVEL_CIVILIAN) {
if (args.size() != 1) return;
uint32_t level;
if (!GeneralUtils::TryParse(args[0], level))
@ -129,7 +129,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
if (level == entity->GetGMLevel()) return;
bool success = user->GetMaxGMLevel() >= level;
if (success) {
if (entity->GetGMLevel() > GAME_MASTER_LEVEL_CIVILIAN && level == GAME_MASTER_LEVEL_CIVILIAN)
{
@ -174,10 +174,10 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
character->SetPvpEnabled(!character->GetPvpEnabled());
EntityManager::Instance()->SerializeEntity(entity);
std::stringstream message;
message << character->GetName() << " changed their PVP flag to " << std::to_string(character->GetPvpEnabled()) << "!";
ChatPackets::SendSystemMessage(UNASSIGNED_SYSTEM_ADDRESS, GeneralUtils::ASCIIToUTF16(message.str()), true);
return;
@ -206,14 +206,14 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
{
std::stringstream message;
message << "Your latest ping: " << std::to_string(Game::server->GetLatestPing(sysAddr)) << "ms";
ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(message.str()));
}
else
{
std::stringstream message;
message << "Your average ping: " << std::to_string(Game::server->GetPing(sysAddr)) << "ms";
ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(message.str()));
}
return;
@ -293,7 +293,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
Game::logger->Log("SlashCommandHandler", "Sending \n%s\n", customText.c_str());
GameMessages::SendUIMessageServerToSingleClient(entity, entity->GetSystemAddress(), "ToggleStoryBox", &args);
delete visiable;
delete text;
});
@ -301,7 +301,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return;
}
if ((chatCommand == "leave-zone")) {
if (chatCommand == "leave-zone") {
const auto currentZone = dZoneManager::Instance()->GetZone()->GetZoneID().GetMapID();
auto newZone = 1100;
@ -322,10 +322,10 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
if (currentZone == newZone)
{
ChatPackets::SendSystemMessage(sysAddr, u"You are not in an instanced zone.");
return;
}
ChatPackets::SendSystemMessage(sysAddr, u"Leaving zone...");
const auto objid = entity->GetObjectID();
@ -354,10 +354,10 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
});
}
if ((chatCommand == "join" && !args.empty())) {
if (chatCommand == "join" && !args.empty()) {
ChatPackets::SendSystemMessage(sysAddr, u"Requesting private map...");
const auto& password = args[0];
ZoneInstanceManager::Instance()->RequestPrivateZone(Game::server, false, password, [=](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort)
{
Game::logger->Log("UserManager", "Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i\n", sysAddr.ToString(), zoneID, zoneInstance, zoneClone, mythranShift == true ? "true" : "false", serverIP.c_str(), serverPort);
@ -386,12 +386,12 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
if (chatCommand == "resurrect") {
ScriptedActivityComponent* scriptedActivityComponent = dZoneManager::Instance()->GetZoneControlObject()->GetComponent<ScriptedActivityComponent>();
if (scriptedActivityComponent) { // check if user is in activity world and if so, they can't resurrect
ChatPackets::SendSystemMessage(sysAddr, u"You cannot resurrect in an activity world.");
return;
}
GameMessages::SendResurrect(entity);
}
@ -414,7 +414,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
stmt->setString(2, GeneralUtils::UTF16ToWTF8(command).c_str());
stmt->execute();
delete stmt;
if (chatCommand == "setminifig" && args.size() == 2 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_FORUM_MODERATOR) { // could break characters so only allow if GM > 0
int32_t minifigItemId;
if (!GeneralUtils::TryParse(args[1], minifigItemId)) {
@ -452,7 +452,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
ChatPackets::SendSystemMessage(sysAddr, u"Invalid Minifig item to change, try one of the following: Eyebrows, Eyes, HairColor, HairStyle, Pants, LeftHand, Mouth, RightHand, Shirt, Hands");
return;
}
EntityManager::Instance()->ConstructEntity(entity);
ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(lowerName) + u" set to " + (GeneralUtils::to_u16string(minifigItemId)));
@ -463,15 +463,15 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
for (const auto& pair : EntityManager::Instance()->GetSpawnPointEntities()) {
ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(pair.first));
}
ChatPackets::SendSystemMessage(sysAddr, u"Current: " + GeneralUtils::ASCIIToUTF16(entity->GetCharacter()->GetTargetScene()));
return;
}
if (chatCommand == "unlock-emote" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) {
int32_t emoteID;
if (!GeneralUtils::TryParse(args[0], emoteID))
{
ChatPackets::SendSystemMessage(sysAddr, u"Invalid emote ID.");
@ -503,7 +503,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
if (chatCommand == "speedboost" && args.size() == 1 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER)
{
float boost;
if (!GeneralUtils::TryParse(args[0], boost))
{
ChatPackets::SendSystemMessage(sysAddr, u"Invalid boost.");
@ -527,7 +527,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
entity->SetVar<bool>(u"freecam", state);
GameMessages::SendSetPlayerControlScheme(entity, static_cast<eControlSceme>(state ? 9 : 1));
ChatPackets::SendSystemMessage(sysAddr, u"Toggled freecam.");
return;
}
@ -540,9 +540,9 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
ChatPackets::SendSystemMessage(sysAddr, u"Invalid control scheme.");
return;
}
GameMessages::SendSetPlayerControlScheme(entity, static_cast<eControlSceme>(scheme));
ChatPackets::SendSystemMessage(sysAddr, u"Switched control scheme.");
return;
}
@ -564,7 +564,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
AMFArrayValue args;
args.InsertValue("state", value);
GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, "pushGameState", &args);
ChatPackets::SendSystemMessage(sysAddr, u"Switched UI state.");
delete value;
@ -578,7 +578,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
AMFArrayValue amfArgs;
amfArgs.InsertValue("visible", value);
GameMessages::SendUIMessageServerToSingleClient(entity, sysAddr, args[0], &amfArgs);
ChatPackets::SendSystemMessage(sysAddr, u"Toggled UI state.");
delete value;
@ -596,12 +596,12 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
ChatPackets::SendSystemMessage(sysAddr, u"Invalid size.");
return;
}
InventoryComponent* inventory = static_cast<InventoryComponent*>(entity->GetComponent(COMPONENT_TYPE_INVENTORY));
if (inventory)
{
auto* items = inventory->GetInventory(ITEMS);
items->SetSize(size);
}
@ -626,7 +626,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
else {
ChatPackets::SendSystemMessage(sysAddr, u"Unknown macro! Is the filename right?");
}
return;
}
@ -640,7 +640,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
ChatPackets::SendSystemMessage(sysAddr, u"Invalid mission id.");
return;
}
auto comp = static_cast<MissionComponent*>(entity->GetComponent(COMPONENT_TYPE_MISSION));
if (comp) comp->AcceptMission(missionID, true);
return;
@ -656,7 +656,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
ChatPackets::SendSystemMessage(sysAddr, u"Invalid mission id.");
return;
}
auto comp = static_cast<MissionComponent*>(entity->GetComponent(COMPONENT_TYPE_MISSION));
if (comp) comp->CompleteMission(missionID, true);
return;
@ -698,7 +698,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
ChatPackets::SendSystemMessage(sysAddr, u"Invalid mission id.");
return;
}
auto* comp = static_cast<MissionComponent*>(entity->GetComponent(COMPONENT_TYPE_MISSION));
if (comp == nullptr) {
@ -710,7 +710,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
if (mission == nullptr) {
return;
}
mission->SetMissionState(MissionState::MISSION_STATE_ACTIVE);
return;
@ -792,7 +792,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
ChatPackets::SendSystemMessage(sysAddr, u"Invalid item LOT.");
return;
}
InventoryComponent * inventory = static_cast<InventoryComponent*>(entity->GetComponent(COMPONENT_TYPE_INVENTORY));
inventory->AddItem(itemLOT, 1);
@ -840,7 +840,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
if (receiverID == 0)
{
ChatPackets::SendSystemMessage(sysAddr, u"Failed to find that player");
return;
}
@ -867,7 +867,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
ins->setInt(11, 1);
ins->execute();
delete ins;
ChatPackets::SendSystemMessage(sysAddr, u"Mail sent");
return;
@ -884,7 +884,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
GameMessages::SendSetName(entity->GetObjectID(), GeneralUtils::ASCIIToUTF16(name), UNASSIGNED_SYSTEM_ADDRESS);
}
if (chatCommand == "title" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER)
{
std::string name = entity->GetCharacter()->GetName() + " - ";
@ -902,19 +902,19 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
if (args.size() == 3) {
float x, y, z;
if (!GeneralUtils::TryParse(args[0], x))
{
ChatPackets::SendSystemMessage(sysAddr, u"Invalid x.");
return;
}
if (!GeneralUtils::TryParse(args[1], y))
{
ChatPackets::SendSystemMessage(sysAddr, u"Invalid y.");
return;
}
if (!GeneralUtils::TryParse(args[2], z))
{
ChatPackets::SendSystemMessage(sysAddr, u"Invalid z.");
@ -924,7 +924,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
pos.SetX(x);
pos.SetY(y);
pos.SetZ(z);
Game::logger->Log("SlashCommandHandler", "Teleporting objectID: %llu to %f, %f, %f\n", entity->GetObjectID(), pos.x, pos.y, pos.z);
GameMessages::SendTeleport(entity->GetObjectID(), pos, NiQuaternion(), sysAddr);
} else if (args.size() == 2) {
@ -946,7 +946,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
pos.SetY(0.0f);
pos.SetZ(z);
Game::logger->Log("SlashCommandHandler", "Teleporting objectID: %llu to X: %f, Z: %f\n", entity->GetObjectID(), pos.x, pos.z);
GameMessages::SendTeleport(entity->GetObjectID(), pos, NiQuaternion(), sysAddr);
} else {
@ -1019,7 +1019,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
if (player == nullptr)
{
auto* accountQuery = Database::CreatePreppedStmt("SELECT account_id, id FROM charinfo WHERE name=? LIMIT 1;");
accountQuery->setString(1, args[0]);
auto result = accountQuery->executeQuery();
@ -1029,7 +1029,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
while (result->next()) {
accountId = result->getUInt(1);
characterId = result->getUInt64(2);
characterId = GeneralUtils::SetBit(characterId, OBJECT_BIT_CHARACTER);
characterId = GeneralUtils::SetBit(characterId, OBJECT_BIT_PERSISTENT);
}
@ -1087,7 +1087,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
userUpdate->executeUpdate();
delete userUpdate;
char buffer[32] = "brought up for review.\0";
if (expire != 1)
@ -1096,12 +1096,12 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
// Format: Mo, 15.06.2009 20:20:00
std::strftime(buffer, 32, "%a, %d.%m.%Y %H:%M:%S", ptm);
}
const auto timeStr = GeneralUtils::ASCIIToUTF16(std::string(buffer));
ChatPackets::SendSystemMessage(sysAddr, u"Muted: " + GeneralUtils::ASCIIToUTF16(args[0]) + u" until " + timeStr);
//Notify chat about it
//Notify chat about it
CBITSTREAM;
PacketUtils::WriteHeader(bitStream, CHAT_INTERNAL, MSG_CHAT_INTERNAL_MUTE_UPDATE);
@ -1144,7 +1144,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
if (player == nullptr)
{
auto* accountQuery = Database::CreatePreppedStmt("SELECT account_id FROM charinfo WHERE name=? LIMIT 1;");
accountQuery->setString(1, args[0]);
auto result = accountQuery->executeQuery();
@ -1190,7 +1190,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
}
//-------------------------------------------------
if (chatCommand == "buffme" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) {
auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE));
if (dest) {
@ -1201,13 +1201,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
dest->SetImagination(999);
dest->SetMaxImagination(999.0f);
}
EntityManager::Instance()->SerializeEntity(entity);
}
if (chatCommand == "startcelebration" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 1) {
int32_t celebration;
if (!GeneralUtils::TryParse(args[0], celebration))
{
ChatPackets::SendSystemMessage(sysAddr, u"Invalid celebration.");
@ -1216,7 +1216,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
GameMessages::SendStartCelebrationEffect(entity, entity->GetSystemAddress(), celebration);
}
if (chatCommand == "buffmed" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) {
auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE));
if (dest) {
@ -1230,7 +1230,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
EntityManager::Instance()->SerializeEntity(entity);
}
if (chatCommand == "refillstats" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) {
auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE));
if (dest) {
@ -1241,23 +1241,27 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
EntityManager::Instance()->SerializeEntity(entity);
}
if (chatCommand == "lookup" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 1) {
std::string query = "SELECT `id`, `name` FROM `Objects` WHERE `displayName` LIKE '%" + args[0] + "%' OR `name` LIKE '%" + args[0] + "%' OR `description` LIKE '%" + args[0] + "%'";
auto tables = CDClientDatabase::ExecuteQuery(query.c_str());
std::string query = "%" + args[0] + "%";
const char* query_cstr = query.c_str();
auto tables = CDClientDatabase::ExecuteQueryWithArgs(
"SELECT `id`, `name` FROM `Objects` WHERE `displayName` LIKE %Q OR `name` LIKE %Q OR `description` LIKE %Q LIMIT 50",
query_cstr, query_cstr, query_cstr);
while (!tables.eof()) {
std::string message = std::to_string(tables.getIntField(0)) + " - " + tables.getStringField(1);
ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(message, message.size()));
tables.nextRow();
}
}
if (chatCommand == "spawn" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) {
ControllablePhysicsComponent* comp = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(COMPONENT_TYPE_CONTROLLABLE_PHYSICS));
if (!comp) return;
uint32_t lot;
if (!GeneralUtils::TryParse(args[0], lot))
{
ChatPackets::SendSystemMessage(sysAddr, u"Invalid lot.");
@ -1301,7 +1305,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
const auto position = entity->GetPosition();
ChatPackets::SendSystemMessage(sysAddr, u"<" + (GeneralUtils::to_u16string(position.x)) + u", " + (GeneralUtils::to_u16string(position.y)) + u", " + (GeneralUtils::to_u16string(position.z)) + u">");
std::cout << position.x << ", " << position.y << ", " << position.z << std::endl;
}
@ -1358,7 +1362,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
if (chatCommand == "gminvis" && entity->GetParentUser()->GetMaxGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER)
{
GameMessages::SendToggleGMInvis(entity->GetObjectID(), true, UNASSIGNED_SYSTEM_ADDRESS);
return;
}
@ -1378,7 +1382,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
{
destroyableComponent->SetIsGMImmune(state);
}
return;
}
@ -1405,7 +1409,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
{
buffComponent->ApplyBuff(id, duration, entity->GetObjectID());
}
return;
}
@ -1440,10 +1444,10 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
}
const auto objid = entity->GetObjectID();
if (force || CheckIfAccessibleZone(reqZone)) { // to prevent tomfoolery
bool darwin = true; //Putting this on true, as I'm sick of having to wait 3-4 seconds on a transfer while trying to quickly moderate properties
Character* character = entity->GetCharacter();
if (character) {
std::string lowerName = character->GetName();
@ -1488,7 +1492,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
WorldPackets::SendTransferToWorld(sysAddr, serverIP, serverPort, mythranShift);
});
return;
});
} else {
@ -1519,7 +1523,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
const auto& password = args[2];
ZoneInstanceManager::Instance()->CreatePrivateZone(Game::server, zone, clone, password);
ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16("Sent request for private zone with password: " + password));
return;
@ -1594,7 +1598,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
}
}
}
if (chatCommand == "triggerspawner" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1)
{
auto spawners = dZoneManager::Instance()->GetSpawnersByName(args[0]);
@ -1676,13 +1680,13 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
ChatPackets::SendSystemMessage(
sysAddr,
GeneralUtils::ASCIIToUTF16(Metrics::MetricVariableToString(variable)) +
u": " +
GeneralUtils::to_u16string(Metrics::ToMiliseconds(metric->average)) +
GeneralUtils::ASCIIToUTF16(Metrics::MetricVariableToString(variable)) +
u": " +
GeneralUtils::to_u16string(Metrics::ToMiliseconds(metric->average)) +
u"ms"
);
}
ChatPackets::SendSystemMessage(
sysAddr,
u"Peak RSS: " + GeneralUtils::to_u16string((float) ((double) Metrics::GetPeakRSS() / 1.024e6)) +
@ -1729,11 +1733,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
}
std::u16string message = u"Ran loot drops looking for "
+ GeneralUtils::to_u16string(targetLot)
+ u", "
+ GeneralUtils::to_u16string(loops)
+ u" times. It ran "
+ GeneralUtils::to_u16string(totalRuns)
+ GeneralUtils::to_u16string(targetLot)
+ u", "
+ GeneralUtils::to_u16string(loops)
+ u" times. It ran "
+ GeneralUtils::to_u16string(totalRuns)
+ u" times. Averaging out at "
+ GeneralUtils::to_u16string((float) totalRuns / loops);
@ -1764,7 +1768,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
auto closestDistance = 0.0f;
const auto candidates = EntityManager::Instance()->GetEntitiesByComponent(component);
for (auto* candidate : candidates)
{
if (candidate->GetLOT() == 1 || candidate->GetLOT() == 8092)
@ -1776,16 +1780,16 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
{
continue;
}
if (closest == nullptr)
{
closest = candidate;
closestDistance = NiPoint3::Distance(candidate->GetPosition(), reference);
continue;
}
const auto distance = NiPoint3::Distance(candidate->GetPosition(), reference);
if (distance < closestDistance)
@ -1812,7 +1816,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
header << info.name << " [" << std::to_string(info.id) << "]" << " " << std::to_string(closestDistance) << " " << std::to_string(closest->IsSleeping());
ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(header.str()));
for (const auto& pair : closest->GetComponents())
{
auto id = pair.first;
@ -1825,7 +1829,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
}
if (args.size() >= 2)
{
{
if (args[1] == "-m" && args.size() >= 3)
{
auto* movingPlatformComponent = closest->GetComponent<MovingPlatformComponent>();
@ -1869,7 +1873,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
const auto postion = closest->GetPosition();
ChatPackets::SendSystemMessage(
sysAddr,
sysAddr,
GeneralUtils::ASCIIToUTF16("< " + std::to_string(postion.x) + ", " + std::to_string(postion.y) + ", " + std::to_string(postion.z) + " >")
);
}
@ -1936,35 +1940,35 @@ bool SlashCommandHandler::CheckIfAccessibleZone(const unsigned int zoneID) {
case 98:
case 1000:
case 1001:
case 1100:
case 1101:
case 1150:
case 1151:
case 1152:
case 1200:
case 1201:
case 1250:
case 1251:
case 1260:
case 1300:
case 1350:
case 1351:
case 1400:
case 1401:
case 1450:
case 1451:
case 1600:
case 1601:
case 1602:
case 1603:
case 1604:
case 1800:
case 1900:
case 2000:
@ -1973,11 +1977,11 @@ bool SlashCommandHandler::CheckIfAccessibleZone(const unsigned int zoneID) {
case 58005:
case 58006:
return true;
default:
return false;
}
return false;
}
@ -1998,7 +2002,7 @@ void SlashCommandHandler::SendAnnouncement(const std::string& title, const std::
titleValue = nullptr;
messageValue = nullptr;
//Notify chat about it
//Notify chat about it
CBITSTREAM;
PacketUtils::WriteHeader(bitStream, CHAT_INTERNAL, MSG_CHAT_INTERNAL_ANNOUNCEMENT);
@ -2010,4 +2014,3 @@ void SlashCommandHandler::SendAnnouncement(const std::string& title, const std::
Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false);
}