#include "GMGreaterThanZeroCommands.h" // Classes #include "Character.h" #include "ChatPackets.h" #include "dServer.h" #include "PlayerManager.h" #include "User.h" // Database #include "Database.h" // Components #include "DestroyableComponent.h" #include "PropertyManagementComponent.h" // Enums #include "eChatMessageType.h" #include "eServerDisconnectIdentifiers.h" #include "eObjectBits.h" namespace GMGreaterThanZeroCommands { void Kick(Entity* entity, const SystemAddress& sysAddr, const std::string args) { const auto splitArgs = GeneralUtils::SplitString(args, ' '); if (splitArgs.size() == 1) { auto* player = PlayerManager::GetPlayer(splitArgs[0]); std::u16string username = GeneralUtils::UTF8ToUTF16(splitArgs[0]); if (player == nullptr) { ChatPackets::SendSystemMessage(sysAddr, u"Count not find player of name: " + username); return; } Game::server->Disconnect(player->GetSystemAddress(), eServerDisconnectIdentifiers::KICK); ChatPackets::SendSystemMessage(sysAddr, u"Kicked: " + username); } else { ChatPackets::SendSystemMessage(sysAddr, u"Correct usage: /kick "); } } void Ban(Entity* entity, const SystemAddress& sysAddr, const std::string args) { const auto splitArgs = GeneralUtils::SplitString(args, ' '); if (splitArgs.size() == 1) { auto* player = PlayerManager::GetPlayer(splitArgs[0]); uint32_t accountId = 0; if (player == nullptr) { auto characterInfo = Database::Get()->GetCharacterInfo(splitArgs[0]); if (characterInfo) { accountId = characterInfo->accountId; } if (accountId == 0) { ChatPackets::SendSystemMessage(sysAddr, u"Count not find player of name: " + GeneralUtils::UTF8ToUTF16(splitArgs[0])); return; } } else { auto* character = player->GetCharacter(); auto* user = character != nullptr ? character->GetParentUser() : nullptr; if (user) accountId = user->GetAccountID(); } if (accountId != 0) Database::Get()->UpdateAccountBan(accountId, true); if (player != nullptr) { Game::server->Disconnect(player->GetSystemAddress(), eServerDisconnectIdentifiers::FREE_TRIAL_EXPIRED); } ChatPackets::SendSystemMessage(sysAddr, u"Banned: " + GeneralUtils::ASCIIToUTF16(splitArgs[0])); } else { ChatPackets::SendSystemMessage(sysAddr, u"Correct usage: /ban "); } } void MailItem(Entity* entity, const SystemAddress& sysAddr, const std::string args) { const auto splitArgs = GeneralUtils::SplitString(args, ' '); if (splitArgs.size() < 2) return; const auto& playerName = splitArgs[0]; auto playerInfo = Database::Get()->GetCharacterInfo(playerName); uint32_t receiverID = 0; if (!playerInfo) { ChatPackets::SendSystemMessage(sysAddr, u"Failed to find that player"); return; } receiverID = playerInfo->id; const auto lot = GeneralUtils::TryParse(splitArgs.at(1)); if (!lot) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid item lot."); return; } IMail::MailInfo mailInsert; mailInsert.senderId = entity->GetObjectID(); mailInsert.senderUsername = "Darkflame Universe"; mailInsert.receiverId = receiverID; mailInsert.recipient = playerName; mailInsert.subject = "Lost item"; mailInsert.body = "This is a replacement item for one you lost."; mailInsert.itemID = LWOOBJID_EMPTY; mailInsert.itemLOT = lot.value(); mailInsert.itemSubkey = LWOOBJID_EMPTY; mailInsert.itemCount = 1; Database::Get()->InsertNewMail(mailInsert); ChatPackets::SendSystemMessage(sysAddr, u"Mail sent"); } void ApproveProperty(Entity* entity, const SystemAddress& sysAddr, const std::string args) { if (PropertyManagementComponent::Instance() != nullptr) { PropertyManagementComponent::Instance()->UpdateApprovedStatus(true); } } void Mute(Entity* entity, const SystemAddress& sysAddr, const std::string args) { const auto splitArgs = GeneralUtils::SplitString(args, ' '); if (splitArgs.size() >= 1) { auto* player = PlayerManager::GetPlayer(splitArgs[0]); uint32_t accountId = 0; LWOOBJID characterId = 0; if (player == nullptr) { auto characterInfo = Database::Get()->GetCharacterInfo(splitArgs[0]); if (characterInfo) { accountId = characterInfo->accountId; characterId = characterInfo->id; GeneralUtils::SetBit(characterId, eObjectBits::CHARACTER); GeneralUtils::SetBit(characterId, eObjectBits::PERSISTENT); } if (accountId == 0) { ChatPackets::SendSystemMessage(sysAddr, u"Count not find player of name: " + GeneralUtils::UTF8ToUTF16(splitArgs[0])); return; } } else { auto* character = player->GetCharacter(); auto* user = character != nullptr ? character->GetParentUser() : nullptr; if (user) accountId = user->GetAccountID(); characterId = player->GetObjectID(); } time_t expire = 1; // Default to indefinate mute if (splitArgs.size() >= 2) { const auto days = GeneralUtils::TryParse(splitArgs[1]); if (!days) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid days."); return; } std::optional hours; if (splitArgs.size() >= 3) { hours = GeneralUtils::TryParse(splitArgs[2]); if (!hours) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid hours."); return; } } expire = time(NULL); expire += 24 * 60 * 60 * days.value(); expire += 60 * 60 * hours.value_or(0); } if (accountId != 0) Database::Get()->UpdateAccountUnmuteTime(accountId, expire); char buffer[32] = "brought up for review.\0"; if (expire != 1) { std::tm* ptm = std::localtime(&expire); // 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::UTF8ToUTF16(splitArgs[0]) + u" until " + timeStr); //Notify chat about it CBITSTREAM; BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::GM_MUTE); bitStream.Write(characterId); bitStream.Write(expire); Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); } else { ChatPackets::SendSystemMessage(sysAddr, u"Correct usage: /mute "); } } void Fly(Entity* entity, const SystemAddress& sysAddr, const std::string args) { const auto splitArgs = GeneralUtils::SplitString(args, ' '); auto* character = entity->GetCharacter(); if (character) { bool isFlying = character->GetIsFlying(); if (isFlying) { GameMessages::SendSetJetPackMode(entity, false); character->SetIsFlying(false); } else { float speedScale = 1.0f; if (splitArgs.size() >= 1) { const auto tempScaleStore = GeneralUtils::TryParse(splitArgs.at(0)); if (tempScaleStore) { speedScale = tempScaleStore.value(); } else { ChatPackets::SendSystemMessage(sysAddr, u"Failed to parse speed scale argument."); } } float airSpeed = 20 * speedScale; float maxAirSpeed = 30 * speedScale; float verticalVelocity = 1.5 * speedScale; GameMessages::SendSetJetPackMode(entity, true, true, false, 167, airSpeed, maxAirSpeed, verticalVelocity); character->SetIsFlying(true); } } } void AttackImmune(Entity* entity, const SystemAddress& sysAddr, const std::string args) { const auto splitArgs = GeneralUtils::SplitString(args, ' '); if (splitArgs.empty()) return; auto* destroyableComponent = entity->GetComponent(); const auto state = GeneralUtils::TryParse(splitArgs[0]); if (!state) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid state."); return; } if (destroyableComponent) destroyableComponent->SetIsImmune(state.value()); } void GmImmune(Entity* entity, const SystemAddress& sysAddr, const std::string args) { const auto splitArgs = GeneralUtils::SplitString(args, ' '); if (splitArgs.empty()) return; auto* destroyableComponent = entity->GetComponent(); const auto state = GeneralUtils::TryParse(splitArgs[0]); if (!state) { ChatPackets::SendSystemMessage(sysAddr, u"Invalid state."); return; } if (destroyableComponent) destroyableComponent->SetIsGMImmune(state.value()); } void GmInvis(Entity* entity, const SystemAddress& sysAddr, const std::string args) { GameMessages::SendToggleGMInvis(entity->GetObjectID(), true, UNASSIGNED_SYSTEM_ADDRESS); } void SetName(Entity* entity, const SystemAddress& sysAddr, const std::string args) { GameMessages::SendSetName(entity->GetObjectID(), GeneralUtils::UTF8ToUTF16(args), UNASSIGNED_SYSTEM_ADDRESS); } void Title(Entity* entity, const SystemAddress& sysAddr, const std::string args) { std::string name = entity->GetCharacter()->GetName() + " - " + args; GameMessages::SendSetName(entity->GetObjectID(), GeneralUtils::UTF8ToUTF16(name), UNASSIGNED_SYSTEM_ADDRESS); } void ShowAll(Entity* entity, const SystemAddress& sysAddr, const std::string args) { bool displayZoneData = true; bool displayIndividualPlayers = true; const auto splitArgs = GeneralUtils::SplitString(args, ' '); if (!splitArgs.empty() && !splitArgs.at(0).empty()) displayZoneData = splitArgs.at(0) == "1"; if (splitArgs.size() > 1) displayIndividualPlayers = splitArgs.at(1) == "1"; ShowAllRequest request { .requestor = entity->GetObjectID(), .displayZoneData = displayZoneData, .displayIndividualPlayers = displayIndividualPlayers }; CBITSTREAM; request.Serialize(bitStream); Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); } void FindPlayer(Entity* entity, const SystemAddress& sysAddr, const std::string args) { if (args.empty()) { GameMessages::SendSlashCommandFeedbackText(entity, u"No player Given"); return; } FindPlayerRequest request { .requestor = entity->GetObjectID(), .playerName = LUWString(args) }; CBITSTREAM; request.Serialize(bitStream); Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); } void Spectate(Entity* entity, const SystemAddress& sysAddr, const std::string args) { if (args.empty()) { GameMessages::SendForceCameraTargetCycle(entity, false, eCameraTargetCyclingMode::DISALLOW_CYCLING, entity->GetObjectID()); return; } auto player = PlayerManager::GetPlayer(args); if (!player) { GameMessages::SendSlashCommandFeedbackText(entity, u"Player not found"); return; } GameMessages::SendSlashCommandFeedbackText(entity, u"Spectating Player"); GameMessages::SendForceCameraTargetCycle(entity, false, eCameraTargetCyclingMode::DISALLOW_CYCLING, player->GetObjectID()); } }