2021-12-05 17:54:36 +00:00
/*
* Darkflame Universe
* Copyright 2018
*/
# include "SlashCommandHandler.h"
# include <sstream>
# include <iostream>
# include <fstream>
# include <exception>
# include "dZoneManager.h"
# include <stdio.h> /* defines FILENAME_MAX */
# ifdef _WIN32
# include <direct.h>
# define GetCurrentDir _getcwd
# else
# include <unistd.h>
# define GetCurrentDir getcwd
# endif
# include "Metrics.hpp"
# include "User.h"
# include "UserManager.h"
# include "BitStream.h"
# include "dCommonVars.h"
# include "GeneralUtils.h"
# include "Entity.h"
# include "EntityManager.h"
2023-10-21 23:31:55 +00:00
# include "Logger.h"
2021-12-05 17:54:36 +00:00
# include "WorldPackets.h"
# include "GameMessages.h"
# include "CDClientDatabase.h"
# include "ZoneInstanceManager.h"
# include "ControllablePhysicsComponent.h"
# include "NiPoint3.h"
# include "NiQuaternion.h"
# include "ChatPackets.h"
# include "InventoryComponent.h"
# include "Game.h"
# include "CharacterComponent.h"
# include "Database.h"
# include "DestroyableComponent.h"
# include "dServer.h"
# include "MissionComponent.h"
# include "Mail.h"
# include "dpWorld.h"
# include "Item.h"
# include "PropertyManagementComponent.h"
2023-09-21 01:06:28 +00:00
# include "BitStreamUtils.h"
2023-01-07 05:17:05 +00:00
# include "Loot.h"
# include "EntityInfo.h"
# include "LUTriggers.h"
2021-12-05 17:54:36 +00:00
# include "PhantomPhysicsComponent.h"
# include "ProximityMonitorComponent.h"
# include "dpShapeSphere.h"
# include "PossessableComponent.h"
# include "PossessorComponent.h"
2023-12-04 15:20:41 +00:00
# include "HavokVehiclePhysicsComponent.h"
2021-12-05 17:54:36 +00:00
# include "BuffComponent.h"
# include "SkillComponent.h"
# include "VanityUtilities.h"
2022-01-01 10:10:12 +00:00
# include "ScriptedActivityComponent.h"
2022-07-24 18:04:02 +00:00
# include "LevelProgressionComponent.h"
2022-11-01 18:21:26 +00:00
# include "AssetManager.h"
2022-11-27 11:59:59 +00:00
# include "BinaryPathFinder.h"
2022-12-04 22:25:58 +00:00
# include "dConfig.h"
2023-01-07 06:14:51 +00:00
# include "eBubbleType.h"
2023-05-13 22:22:00 +00:00
# include "Amf3.h"
2023-01-07 05:17:05 +00:00
# include "MovingPlatformComponent.h"
2023-01-22 23:38:47 +00:00
# include "eMissionState.h"
2023-02-10 08:29:53 +00:00
# include "TriggerComponent.h"
2023-02-19 12:29:14 +00:00
# include "eServerDisconnectIdentifiers.h"
2023-04-25 18:17:40 +00:00
# include "eObjectBits.h"
2023-03-24 23:16:45 +00:00
# include "eGameMasterLevel.h"
2023-03-04 07:16:37 +00:00
# include "eReplicaComponentType.h"
2023-03-20 13:10:52 +00:00
# include "RenderComponent.h"
2023-05-02 22:39:21 +00:00
# include "eControlScheme.h"
2023-05-03 21:38:32 +00:00
# include "eConnectionType.h"
# include "eChatInternalMessageType.h"
# include "eMasterMessageType.h"
2024-01-13 09:40:56 +00:00
# include "PlayerManager.h"
2021-12-05 17:54:36 +00:00
2023-11-22 02:05:15 +00:00
# include "CDRewardCodesTable.h"
2023-03-17 14:36:21 +00:00
# include "CDObjectsTable.h"
# include "CDZoneTableTable.h"
2023-11-22 02:04:44 +00:00
# include "ePlayerFlag.h"
2024-01-19 21:12:05 +00:00
# include "dNavMesh.h"
2023-03-17 14:36:21 +00:00
2021-12-05 17:54:36 +00:00
void SlashCommandHandler : : HandleChatCommand ( const std : : u16string & command , Entity * entity , const SystemAddress & sysAddr ) {
2023-04-08 20:45:45 +00:00
auto commandCopy = command ;
// Sanity check that a command was given
if ( command . empty ( ) | | command . front ( ) ! = u ' / ' ) return ;
commandCopy . erase ( commandCopy . begin ( ) ) ;
// Split the command by spaces
2022-07-28 13:39:57 +00:00
std : : string chatCommand ;
std : : vector < std : : string > args ;
2023-04-08 20:45:45 +00:00
auto wideCommand = GeneralUtils : : SplitString ( commandCopy , u ' ' ) ;
if ( wideCommand . empty ( ) ) return ;
2022-01-06 02:52:33 +00:00
2023-04-08 20:45:45 +00:00
// Convert the command to lowercase
chatCommand = GeneralUtils : : UTF16ToWTF8 ( wideCommand . front ( ) ) ;
std : : transform ( chatCommand . begin ( ) , chatCommand . end ( ) , chatCommand . begin ( ) , : : tolower ) ;
wideCommand . erase ( wideCommand . begin ( ) ) ;
2022-01-06 02:52:33 +00:00
2023-04-08 20:45:45 +00:00
// Convert the arguements to not u16strings
for ( auto wideArg : wideCommand ) args . push_back ( GeneralUtils : : UTF16ToWTF8 ( wideArg ) ) ;
2022-01-06 02:52:33 +00:00
2022-07-28 13:39:57 +00:00
User * user = UserManager : : Instance ( ) - > GetUser ( sysAddr ) ;
2023-03-24 23:16:45 +00:00
if ( ( chatCommand = = " setgmlevel " | | chatCommand = = " makegm " | | chatCommand = = " gmlevel " ) & & user - > GetMaxGMLevel ( ) > eGameMasterLevel : : CIVILIAN ) {
2022-07-28 13:39:57 +00:00
if ( args . size ( ) ! = 1 ) return ;
2022-01-06 02:52:33 +00:00
2024-02-10 11:05:25 +00:00
const auto level_intermed = GeneralUtils : : TryParse < uint32_t > ( args [ 0 ] ) ;
2021-12-05 17:54:36 +00:00
2024-02-10 11:05:25 +00:00
if ( ! level_intermed ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid gm level. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
eGameMasterLevel level = static_cast < eGameMasterLevel > ( level_intermed . value ( ) ) ;
2021-12-05 17:54:36 +00:00
# ifndef DEVELOPER_SERVER
2023-03-24 23:16:45 +00:00
if ( user - > GetMaxGMLevel ( ) = = eGameMasterLevel : : JUNIOR_DEVELOPER ) {
level = eGameMasterLevel : : CIVILIAN ;
2021-12-05 17:54:36 +00:00
}
# endif
2022-07-28 13:39:57 +00:00
if ( level > user - > GetMaxGMLevel ( ) ) {
2021-12-05 17:54:36 +00:00
level = user - > GetMaxGMLevel ( ) ;
}
2022-07-28 13:39:57 +00:00
if ( level = = entity - > GetGMLevel ( ) ) return ;
bool success = user - > GetMaxGMLevel ( ) > = level ;
2022-01-06 02:52:33 +00:00
2022-07-28 13:39:57 +00:00
if ( success ) {
2022-04-12 19:06:03 +00:00
2023-03-24 23:16:45 +00:00
if ( entity - > GetGMLevel ( ) > eGameMasterLevel : : CIVILIAN & & level = = eGameMasterLevel : : CIVILIAN ) {
2021-12-05 17:54:36 +00:00
GameMessages : : SendToggleGMInvis ( entity - > GetObjectID ( ) , false , UNASSIGNED_SYSTEM_ADDRESS ) ;
2023-03-24 23:16:45 +00:00
} else if ( entity - > GetGMLevel ( ) = = eGameMasterLevel : : CIVILIAN & & level > eGameMasterLevel : : CIVILIAN ) {
2021-12-05 17:54:36 +00:00
GameMessages : : SendToggleGMInvis ( entity - > GetObjectID ( ) , true , UNASSIGNED_SYSTEM_ADDRESS ) ;
}
2022-04-12 23:30:46 +00:00
WorldPackets : : SendGMLevelChange ( sysAddr , success , user - > GetMaxGMLevel ( ) , entity - > GetGMLevel ( ) , level ) ;
GameMessages : : SendChatModeUpdate ( entity - > GetObjectID ( ) , level ) ;
entity - > SetGMLevel ( level ) ;
2024-03-08 21:44:02 +00:00
Log : : Info ( " User {:s} ({:d}) has changed their GM level to {:d} for charID {:d} " , user - > GetUsername ( ) , user - > GetAccountID ( ) , GeneralUtils : : ToUnderlying ( level ) , entity - > GetObjectID ( ) ) ;
2022-04-12 23:30:46 +00:00
}
}
2021-12-05 17:54:36 +00:00
# ifndef DEVELOPER_SERVER
2023-03-24 23:16:45 +00:00
if ( ( entity - > GetGMLevel ( ) > user - > GetMaxGMLevel ( ) ) | | ( entity - > GetGMLevel ( ) > eGameMasterLevel : : CIVILIAN & & user - > GetMaxGMLevel ( ) = = eGameMasterLevel : : JUNIOR_DEVELOPER ) ) {
WorldPackets : : SendGMLevelChange ( sysAddr , true , user - > GetMaxGMLevel ( ) , entity - > GetGMLevel ( ) , eGameMasterLevel : : CIVILIAN ) ;
GameMessages : : SendChatModeUpdate ( entity - > GetObjectID ( ) , eGameMasterLevel : : CIVILIAN ) ;
entity - > SetGMLevel ( eGameMasterLevel : : CIVILIAN ) ;
2021-12-05 17:54:36 +00:00
GameMessages : : SendToggleGMInvis ( entity - > GetObjectID ( ) , false , UNASSIGNED_SYSTEM_ADDRESS ) ;
ChatPackets : : SendSystemMessage ( sysAddr , u " Your game master level has been changed, you may not be able to use all commands. " ) ;
}
# endif
2023-04-02 01:30:08 +00:00
if ( chatCommand = = " togglenameplate " & & ( Game : : config - > GetValue ( " allow_nameplate_off " ) = = " 1 " | | entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) ) {
2023-03-23 14:49:31 +00:00
auto * character = entity - > GetCharacter ( ) ;
if ( character & & character - > GetBillboardVisible ( ) ) {
character - > SetBillboardVisible ( false ) ;
ChatPackets : : SendSystemMessage ( sysAddr , u " Your nameplate has been turned off and is not visible to players currently in this zone. " ) ;
} else {
character - > SetBillboardVisible ( true ) ;
ChatPackets : : SendSystemMessage ( sysAddr , u " Your nameplate is now on and visible to all players. " ) ;
}
return ;
}
2023-11-22 02:04:44 +00:00
if ( chatCommand = = " toggleskipcinematics " & & ( Game : : config - > GetValue ( " allow_players_to_skip_cinematics " ) = = " 1 " | | entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) ) {
auto * character = entity - > GetCharacter ( ) ;
if ( ! character ) return ;
bool current = character - > GetPlayerFlag ( ePlayerFlag : : DLU_SKIP_CINEMATICS ) ;
character - > SetPlayerFlag ( ePlayerFlag : : DLU_SKIP_CINEMATICS , ! current ) ;
if ( ! current ) {
ChatPackets : : SendSystemMessage ( sysAddr , u " You have elected to skip cinematics. Note that not all cinematics can be skipped, but most will be skipped now. " ) ;
} else {
ChatPackets : : SendSystemMessage ( sysAddr , u " Cinematics will no longer be skipped. " ) ;
}
return ;
}
2021-12-05 17:54:36 +00:00
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//HANDLE ALL NON GM SLASH COMMANDS RIGHT HERE!
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if ( chatCommand = = " pvp " ) {
auto * character = entity - > GetComponent < CharacterComponent > ( ) ;
if ( character = = nullptr ) {
2023-10-21 23:31:55 +00:00
LOG ( " Failed to find character component! " ) ;
2021-12-05 17:54:36 +00:00
return ;
}
character - > SetPvpEnabled ( ! character - > GetPvpEnabled ( ) ) ;
2023-07-15 20:56:33 +00:00
Game : : entityManager - > SerializeEntity ( entity ) ;
2022-01-06 02:52:33 +00:00
2021-12-05 17:54:36 +00:00
std : : stringstream message ;
message < < character - > GetName ( ) < < " changed their PVP flag to " < < std : : to_string ( character - > GetPvpEnabled ( ) ) < < " ! " ;
2022-01-06 02:52:33 +00:00
2022-08-02 13:56:20 +00:00
ChatPackets : : SendSystemMessage ( UNASSIGNED_SYSTEM_ADDRESS , GeneralUtils : : UTF8ToUTF16 ( message . str ( ) ) , true ) ;
2021-12-05 17:54:36 +00:00
return ;
}
2022-07-28 13:39:57 +00:00
if ( chatCommand = = " who " ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage (
sysAddr ,
2024-01-13 09:40:56 +00:00
u " Players in this instance: ( " + GeneralUtils : : to_u16string ( PlayerManager : : GetAllPlayers ( ) . size ( ) ) + u " ) "
2021-12-05 17:54:36 +00:00
) ;
2024-01-13 09:40:56 +00:00
for ( auto * player : PlayerManager : : GetAllPlayers ( ) ) {
2021-12-05 17:54:36 +00:00
const auto & name = player - > GetCharacter ( ) - > GetName ( ) ;
ChatPackets : : SendSystemMessage (
sysAddr ,
2022-08-02 13:56:20 +00:00
GeneralUtils : : UTF8ToUTF16 ( player = = entity ? name + " (you) " : name )
2021-12-05 17:54:36 +00:00
) ;
}
}
if ( chatCommand = = " ping " ) {
2022-07-28 13:39:57 +00:00
if ( ! args . empty ( ) & & args [ 0 ] = = " -l " ) {
2021-12-05 17:54:36 +00:00
std : : stringstream message ;
message < < " Your latest ping: " < < std : : to_string ( Game : : server - > GetLatestPing ( sysAddr ) ) < < " ms " ;
2022-01-06 02:52:33 +00:00
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , GeneralUtils : : ASCIIToUTF16 ( message . str ( ) ) ) ;
2022-07-28 13:39:57 +00:00
} else {
2021-12-05 17:54:36 +00:00
std : : stringstream message ;
message < < " Your average ping: " < < std : : to_string ( Game : : server - > GetPing ( sysAddr ) ) < < " ms " ;
2022-01-06 02:52:33 +00:00
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , GeneralUtils : : ASCIIToUTF16 ( message . str ( ) ) ) ;
}
return ;
}
2022-07-28 13:39:57 +00:00
if ( chatCommand = = " fix-stats " ) {
2021-12-05 17:54:36 +00:00
// Reset skill component and buff component
auto * skillComponent = entity - > GetComponent < SkillComponent > ( ) ;
auto * buffComponent = entity - > GetComponent < BuffComponent > ( ) ;
auto * destroyableComponent = entity - > GetComponent < DestroyableComponent > ( ) ;
// If any of the components are nullptr, return
2022-07-28 13:39:57 +00:00
if ( skillComponent = = nullptr | | buffComponent = = nullptr | | destroyableComponent = = nullptr ) {
2021-12-05 17:54:36 +00:00
return ;
}
// Reset skill component
skillComponent - > Reset ( ) ;
// Reset buff component
buffComponent - > Reset ( ) ;
// Fix the destroyable component
destroyableComponent - > FixStats ( ) ;
}
2022-07-28 13:39:57 +00:00
if ( chatCommand = = " credits " | | chatCommand = = " info " ) {
2023-11-12 11:53:03 +00:00
const auto & customText = chatCommand = = " credits " ? VanityUtilities : : ParseMarkdown ( ( BinaryPathFinder : : GetBinaryDir ( ) / " vanity/CREDITS.md " ) . string ( ) ) : VanityUtilities : : ParseMarkdown ( ( BinaryPathFinder : : GetBinaryDir ( ) / " vanity/INFO.md " ) . string ( ) ) ;
2021-12-05 17:54:36 +00:00
{
AMFArrayValue args ;
2023-05-13 22:22:00 +00:00
args . Insert ( " state " , " Story " ) ;
2021-12-05 17:54:36 +00:00
2023-05-13 22:22:00 +00:00
GameMessages : : SendUIMessageServerToSingleClient ( entity , entity - > GetSystemAddress ( ) , " pushGameState " , args ) ;
2021-12-05 17:54:36 +00:00
}
2022-07-28 13:39:57 +00:00
entity - > AddCallbackTimer ( 0.5f , [ customText , entity ] ( ) {
2021-12-05 17:54:36 +00:00
AMFArrayValue args ;
2023-05-13 22:22:00 +00:00
args . Insert ( " visible " , true ) ;
args . Insert ( " text " , customText ) ;
2021-12-05 17:54:36 +00:00
2023-10-21 23:31:55 +00:00
LOG ( " Sending %s " , customText . c_str ( ) ) ;
2021-12-05 17:54:36 +00:00
2023-05-13 22:22:00 +00:00
GameMessages : : SendUIMessageServerToSingleClient ( entity , entity - > GetSystemAddress ( ) , " ToggleStoryBox " , args ) ;
2022-07-28 13:39:57 +00:00
} ) ;
2021-12-05 17:54:36 +00:00
return ;
}
2023-12-20 21:12:01 +00:00
if ( chatCommand = = " leave-zone " | | chatCommand = = " leavezone " ) {
2023-07-17 22:55:33 +00:00
const auto currentZone = Game : : zoneManager - > GetZone ( ) - > GetZoneID ( ) . GetMapID ( ) ;
2023-05-08 09:38:08 +00:00
LWOMAPID newZone = 0 ;
2023-12-20 21:12:01 +00:00
2023-12-23 17:28:32 +00:00
if ( currentZone = = 1001 | | currentZone % 100 = = 0 ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " You are not in an instanced zone. " ) ;
return ;
2022-02-04 06:32:45 +00:00
} else {
newZone = ( currentZone / 100 ) * 100 ;
2021-12-05 17:54:36 +00:00
}
2022-02-04 06:32:45 +00:00
// If new zone would be inaccessible, then default to Avant Gardens.
2023-07-17 22:55:33 +00:00
if ( ! Game : : zoneManager - > CheckIfAccessibleZone ( newZone ) ) newZone = 1100 ;
2022-01-06 02:52:33 +00:00
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Leaving zone... " ) ;
const auto objid = entity - > GetObjectID ( ) ;
2022-07-28 13:39:57 +00:00
ZoneInstanceManager : : Instance ( ) - > RequestZoneTransfer ( Game : : server , newZone , 0 , false , [ objid ] ( bool mythranShift , uint32_t zoneID , uint32_t zoneInstance , uint32_t zoneClone , std : : string serverIP , uint16_t serverPort ) {
2023-07-15 20:56:33 +00:00
auto * entity = Game : : entityManager - > GetEntity ( objid ) ;
2021-12-05 17:54:36 +00:00
2022-07-28 13:39:57 +00:00
if ( entity = = nullptr ) {
return ;
}
2021-12-05 17:54:36 +00:00
2022-07-28 13:39:57 +00:00
const auto sysAddr = entity - > GetSystemAddress ( ) ;
2021-12-05 17:54:36 +00:00
2023-10-21 23:31:55 +00:00
LOG ( " Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i " , entity - > GetCharacter ( ) - > GetName ( ) . c_str ( ) , zoneID , zoneInstance , zoneClone , mythranShift = = true ? " true " : " false " , serverIP . c_str ( ) , serverPort ) ;
2021-12-05 17:54:36 +00:00
2022-07-28 13:39:57 +00:00
if ( entity - > GetCharacter ( ) ) {
entity - > GetCharacter ( ) - > SetZoneID ( zoneID ) ;
entity - > GetCharacter ( ) - > SetZoneInstance ( zoneInstance ) ;
entity - > GetCharacter ( ) - > SetZoneClone ( zoneClone ) ;
}
2021-12-05 17:54:36 +00:00
2022-07-28 13:39:57 +00:00
entity - > GetCharacter ( ) - > SaveXMLToDatabase ( ) ;
2021-12-05 17:54:36 +00:00
2022-07-28 13:39:57 +00:00
WorldPackets : : SendTransferToWorld ( sysAddr , serverIP , serverPort , mythranShift ) ;
2021-12-05 17:54:36 +00:00
} ) ;
}
2022-01-06 02:52:33 +00:00
if ( chatCommand = = " join " & & ! args . empty ( ) ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Requesting private map... " ) ;
const auto & password = args [ 0 ] ;
2022-01-06 02:52:33 +00:00
2022-07-28 13:39:57 +00:00
ZoneInstanceManager : : Instance ( ) - > RequestPrivateZone ( Game : : server , false , password , [ = ] ( bool mythranShift , uint32_t zoneID , uint32_t zoneInstance , uint32_t zoneClone , std : : string serverIP , uint16_t serverPort ) {
2023-10-21 23:31:55 +00:00
LOG ( " Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i " , sysAddr . ToString ( ) , zoneID , zoneInstance , zoneClone , mythranShift = = true ? " true " : " false " , serverIP . c_str ( ) , serverPort ) ;
2021-12-05 17:54:36 +00:00
2022-07-28 13:39:57 +00:00
if ( entity - > GetCharacter ( ) ) {
entity - > GetCharacter ( ) - > SetZoneID ( zoneID ) ;
entity - > GetCharacter ( ) - > SetZoneInstance ( zoneInstance ) ;
entity - > GetCharacter ( ) - > SetZoneClone ( zoneClone ) ;
}
2021-12-05 17:54:36 +00:00
2022-07-28 13:39:57 +00:00
entity - > GetCharacter ( ) - > SaveXMLToDatabase ( ) ;
2021-12-05 17:54:36 +00:00
2022-07-28 13:39:57 +00:00
WorldPackets : : SendTransferToWorld ( sysAddr , serverIP , serverPort , mythranShift ) ;
2021-12-05 17:54:36 +00:00
} ) ;
}
2023-03-24 23:16:45 +00:00
if ( user - > GetMaxGMLevel ( ) = = eGameMasterLevel : : CIVILIAN | | entity - > GetGMLevel ( ) > = eGameMasterLevel : : CIVILIAN ) {
2021-12-05 17:54:36 +00:00
if ( chatCommand = = " die " ) {
entity - > Smash ( entity - > GetObjectID ( ) ) ;
}
if ( chatCommand = = " resurrect " ) {
2023-07-17 22:55:33 +00:00
ScriptedActivityComponent * scriptedActivityComponent = Game : : zoneManager - > GetZoneControlObject ( ) - > GetComponent < ScriptedActivityComponent > ( ) ;
2022-01-06 02:52:33 +00:00
2022-01-01 10:10:12 +00:00
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 ;
}
2022-01-06 02:52:33 +00:00
2021-12-05 17:54:36 +00:00
GameMessages : : SendResurrect ( entity ) ;
}
if ( chatCommand = = " requestmailcount " ) {
Mail : : HandleNotificationRequest ( entity - > GetSystemAddress ( ) , entity - > GetObjectID ( ) ) ;
}
if ( chatCommand = = " instanceinfo " ) {
2023-07-17 22:55:33 +00:00
const auto zoneId = Game : : zoneManager - > GetZone ( ) - > GetZoneID ( ) ;
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Map: " + ( GeneralUtils : : to_u16string ( zoneId . GetMapID ( ) ) ) + u " \n Clone: " + ( GeneralUtils : : to_u16string ( zoneId . GetCloneID ( ) ) ) + u " \n Instance: " + ( GeneralUtils : : to_u16string ( zoneId . GetInstanceID ( ) ) ) ) ;
}
2023-03-24 23:16:45 +00:00
if ( entity - > GetGMLevel ( ) = = eGameMasterLevel : : CIVILIAN ) return ;
2022-04-12 23:30:46 +00:00
}
2021-12-05 17:54:36 +00:00
2024-01-06 00:49:21 +00:00
if ( chatCommand = = " resetmission " & & args . size ( ) > = 1 & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2024-02-10 11:05:25 +00:00
const auto missionId = GeneralUtils : : TryParse < uint32_t > ( args [ 0 ] ) ;
if ( ! missionId ) {
2024-01-06 00:49:21 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid mission ID. " ) ;
return ;
}
auto * missionComponent = entity - > GetComponent < MissionComponent > ( ) ;
if ( ! missionComponent ) return ;
2024-02-10 11:05:25 +00:00
missionComponent - > ResetMission ( missionId . value ( ) ) ;
2024-01-06 00:49:21 +00:00
}
2021-12-05 17:54:36 +00:00
// Log command to database
2023-11-18 00:47:18 +00:00
Database : : Get ( ) - > InsertSlashCommandUsage ( entity - > GetObjectID ( ) , chatCommand ) ;
2022-01-06 02:52:33 +00:00
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " setminifig " & & args . size ( ) = = 2 & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : FORUM_MODERATOR ) { // could break characters so only allow if GM > 0
2024-02-10 11:05:25 +00:00
const auto minifigItemIdExists = GeneralUtils : : TryParse < int32_t > ( args [ 1 ] ) ;
if ( ! minifigItemIdExists ) {
2021-12-11 02:02:02 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid Minifig Item Id ID. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
const int32_t minifigItemId = minifigItemIdExists . value ( ) ;
2023-07-15 20:56:33 +00:00
Game : : entityManager - > DestructEntity ( entity , sysAddr ) ;
2021-12-11 02:02:02 +00:00
auto * charComp = entity - > GetComponent < CharacterComponent > ( ) ;
std : : string lowerName = args [ 0 ] ;
if ( lowerName . empty ( ) ) return ;
std : : transform ( lowerName . begin ( ) , lowerName . end ( ) , lowerName . begin ( ) , : : tolower ) ;
if ( lowerName = = " eyebrows " ) {
charComp - > m_Character - > SetEyebrows ( minifigItemId ) ;
} else if ( lowerName = = " eyes " ) {
charComp - > m_Character - > SetEyes ( minifigItemId ) ;
} else if ( lowerName = = " haircolor " ) {
charComp - > m_Character - > SetHairColor ( minifigItemId ) ;
} else if ( lowerName = = " hairstyle " ) {
charComp - > m_Character - > SetHairStyle ( minifigItemId ) ;
} else if ( lowerName = = " pants " ) {
charComp - > m_Character - > SetPantsColor ( minifigItemId ) ;
} else if ( lowerName = = " lefthand " ) {
charComp - > m_Character - > SetLeftHand ( minifigItemId ) ;
} else if ( lowerName = = " mouth " ) {
charComp - > m_Character - > SetMouth ( minifigItemId ) ;
} else if ( lowerName = = " righthand " ) {
charComp - > m_Character - > SetRightHand ( minifigItemId ) ;
2021-12-15 02:55:05 +00:00
} else if ( lowerName = = " shirtcolor " ) {
2021-12-11 02:02:02 +00:00
charComp - > m_Character - > SetShirtColor ( minifigItemId ) ;
} else if ( lowerName = = " hands " ) {
charComp - > m_Character - > SetLeftHand ( minifigItemId ) ;
charComp - > m_Character - > SetRightHand ( minifigItemId ) ;
} else {
2023-07-15 20:56:33 +00:00
Game : : entityManager - > ConstructEntity ( entity ) ;
2021-12-11 02:02:02 +00:00
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 ;
}
2022-01-06 02:52:33 +00:00
2023-07-15 20:56:33 +00:00
Game : : entityManager - > ConstructEntity ( entity ) ;
2021-12-11 02:02:02 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , GeneralUtils : : ASCIIToUTF16 ( lowerName ) + u " set to " + ( GeneralUtils : : to_u16string ( minifigItemId ) ) ) ;
GameMessages : : SendToggleGMInvis ( entity - > GetObjectID ( ) , false , UNASSIGNED_SYSTEM_ADDRESS ) ; // need to retoggle because it gets reenabled on creation of new character
}
2023-03-24 23:16:45 +00:00
if ( ( chatCommand = = " playanimation " | | chatCommand = = " playanim " ) & & args . size ( ) = = 1 & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2022-03-29 20:06:28 +00:00
std : : u16string anim = GeneralUtils : : ASCIIToUTF16 ( args [ 0 ] , args [ 0 ] . size ( ) ) ;
2023-03-20 13:10:52 +00:00
RenderComponent : : PlayAnimation ( entity , anim ) ;
2022-09-02 18:49:19 +00:00
auto * possessorComponent = entity - > GetComponent < PossessorComponent > ( ) ;
if ( possessorComponent ) {
2023-07-15 20:56:33 +00:00
auto * possessedComponent = Game : : entityManager - > GetEntity ( possessorComponent - > GetPossessable ( ) ) ;
2023-03-20 13:10:52 +00:00
if ( possessedComponent ) RenderComponent : : PlayAnimation ( possessedComponent , anim ) ;
2022-09-02 18:49:19 +00:00
}
2022-03-29 20:06:28 +00:00
}
2021-12-11 02:02:02 +00:00
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " list-spawns " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2023-07-15 20:56:33 +00:00
for ( const auto & pair : Game : : entityManager - > GetSpawnPointEntities ( ) ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , GeneralUtils : : ASCIIToUTF16 ( pair . first ) ) ;
}
2022-01-06 02:52:33 +00:00
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Current: " + GeneralUtils : : ASCIIToUTF16 ( entity - > GetCharacter ( ) - > GetTargetScene ( ) ) ) ;
return ;
}
2022-01-06 02:52:33 +00:00
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " unlock-emote " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2024-02-10 11:05:25 +00:00
const auto emoteID = GeneralUtils : : TryParse < int32_t > ( args . at ( 0 ) ) ;
2022-01-06 02:52:33 +00:00
2024-02-10 11:05:25 +00:00
if ( ! emoteID ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid emote ID. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
entity - > GetCharacter ( ) - > UnlockEmote ( emoteID . value ( ) ) ;
2021-12-05 17:54:36 +00:00
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " force-save " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2021-12-11 02:02:02 +00:00
entity - > GetCharacter ( ) - > SaveXMLToDatabase ( ) ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " kill " & & args . size ( ) = = 1 & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Brutally murdering that player, if online on this server. " ) ;
2024-01-13 09:40:56 +00:00
auto * player = PlayerManager : : GetPlayer ( args [ 0 ] ) ;
2023-11-16 01:29:00 +00:00
if ( player ) {
2021-12-05 17:54:36 +00:00
player - > Smash ( entity - > GetObjectID ( ) ) ;
ChatPackets : : SendSystemMessage ( sysAddr , u " It has been done, do you feel good about yourself now? " ) ;
return ;
}
ChatPackets : : SendSystemMessage ( sysAddr , u " They were saved from your carnage. " ) ;
return ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " speedboost " & & args . size ( ) = = 1 & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2024-02-10 11:05:25 +00:00
const auto boostOptional = GeneralUtils : : TryParse < float > ( args [ 0 ] ) ;
if ( ! boostOptional ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid boost. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
const float boost = boostOptional . value ( ) ;
2021-12-05 17:54:36 +00:00
auto * controllablePhysicsComponent = entity - > GetComponent < ControllablePhysicsComponent > ( ) ;
2022-09-02 18:49:19 +00:00
if ( ! controllablePhysicsComponent ) return ;
2021-12-05 17:54:36 +00:00
controllablePhysicsComponent - > SetSpeedMultiplier ( boost ) ;
2024-02-10 11:05:25 +00:00
// speedboost possessables
2022-09-02 18:49:19 +00:00
auto possessor = entity - > GetComponent < PossessorComponent > ( ) ;
if ( possessor ) {
auto possessedID = possessor - > GetPossessable ( ) ;
if ( possessedID ! = LWOOBJID_EMPTY ) {
2023-07-15 20:56:33 +00:00
auto possessable = Game : : entityManager - > GetEntity ( possessedID ) ;
2022-09-02 18:49:19 +00:00
if ( possessable ) {
auto * possessControllablePhysicsComponent = possessable - > GetComponent < ControllablePhysicsComponent > ( ) ;
if ( possessControllablePhysicsComponent ) {
possessControllablePhysicsComponent - > SetSpeedMultiplier ( boost ) ;
}
}
}
}
2023-07-15 20:56:33 +00:00
Game : : entityManager - > SerializeEntity ( entity ) ;
2021-12-05 17:54:36 +00:00
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " freecam " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2021-12-05 17:54:36 +00:00
const auto state = ! entity - > GetVar < bool > ( u " freecam " ) ;
entity - > SetVar < bool > ( u " freecam " , state ) ;
2023-05-02 22:39:21 +00:00
GameMessages : : SendSetPlayerControlScheme ( entity , static_cast < eControlScheme > ( state ? 9 : 1 ) ) ;
2022-01-06 02:52:33 +00:00
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Toggled freecam. " ) ;
return ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " setcontrolscheme " & & args . size ( ) = = 1 & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2024-02-10 11:05:25 +00:00
const auto scheme = GeneralUtils : : TryParse < uint32_t > ( args [ 0 ] ) ;
2021-12-05 17:54:36 +00:00
2024-02-10 11:05:25 +00:00
if ( ! scheme ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid control scheme. " ) ;
return ;
}
2022-01-06 02:52:33 +00:00
2024-02-10 11:05:25 +00:00
GameMessages : : SendSetPlayerControlScheme ( entity , static_cast < eControlScheme > ( scheme . value ( ) ) ) ;
2022-01-06 02:52:33 +00:00
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Switched control scheme. " ) ;
return ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " approveproperty " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : LEAD_MODERATOR ) {
2021-12-05 17:54:36 +00:00
2022-07-28 13:39:57 +00:00
if ( PropertyManagementComponent : : Instance ( ) ! = nullptr ) {
2021-12-05 17:54:36 +00:00
PropertyManagementComponent : : Instance ( ) - > UpdateApprovedStatus ( true ) ;
}
return ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " setuistate " & & args . size ( ) = = 1 & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2023-05-13 22:22:00 +00:00
AMFArrayValue uiState ;
2021-12-05 17:54:36 +00:00
2023-05-13 22:22:00 +00:00
uiState . Insert ( " state " , args . at ( 0 ) ) ;
GameMessages : : SendUIMessageServerToSingleClient ( entity , sysAddr , " pushGameState " , uiState ) ;
2022-01-06 02:52:33 +00:00
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Switched UI state. " ) ;
return ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " toggle " & & args . size ( ) = = 1 & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2021-12-05 17:54:36 +00:00
AMFArrayValue amfArgs ;
2023-05-13 22:22:00 +00:00
amfArgs . Insert ( " visible " , true ) ;
GameMessages : : SendUIMessageServerToSingleClient ( entity , sysAddr , args [ 0 ] , amfArgs ) ;
2022-01-06 02:52:33 +00:00
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Toggled UI state. " ) ;
return ;
}
2023-03-24 23:16:45 +00:00
if ( ( chatCommand = = " setinventorysize " | | chatCommand = = " setinvsize " ) & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER & & args . size ( ) > = 1 ) {
2024-02-10 11:05:25 +00:00
const auto sizeOptional = GeneralUtils : : TryParse < uint32_t > ( args [ 0 ] ) ;
if ( ! sizeOptional ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid size. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
const uint32_t size = sizeOptional . value ( ) ;
2022-01-06 02:52:33 +00:00
2023-03-14 12:50:12 +00:00
eInventoryType selectedInventory = eInventoryType : : ITEMS ;
2022-01-06 02:52:33 +00:00
2023-03-14 12:50:12 +00:00
// a possible inventory was provided if we got more than 1 argument
if ( args . size ( ) > = 2 ) {
2024-02-10 11:05:25 +00:00
selectedInventory = GeneralUtils : : TryParse < eInventoryType > ( args . at ( 1 ) ) . value_or ( eInventoryType : : INVALID ) ;
if ( selectedInventory = = eInventoryType : : INVALID ) {
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid inventory. " ) ;
return ;
} else {
2023-03-14 12:50:12 +00:00
// In this case, we treat the input as a string and try to find it in the reflection list
std : : transform ( args . at ( 1 ) . begin ( ) , args . at ( 1 ) . end ( ) , args . at ( 1 ) . begin ( ) , : : toupper ) ;
for ( uint32_t index = 0 ; index < NUMBER_OF_INVENTORIES ; index + + ) {
if ( std : : string_view ( args . at ( 1 ) ) = = std : : string_view ( InventoryType : : InventoryTypeToString ( static_cast < eInventoryType > ( index ) ) ) ) selectedInventory = static_cast < eInventoryType > ( index ) ;
}
}
ChatPackets : : SendSystemMessage ( sysAddr , u " Setting inventory " +
GeneralUtils : : ASCIIToUTF16 ( args . at ( 1 ) ) +
u " to size " +
GeneralUtils : : to_u16string ( size ) ) ;
} else ChatPackets : : SendSystemMessage ( sysAddr , u " Setting inventory ITEMS to size " + GeneralUtils : : to_u16string ( size ) ) ;
auto * inventoryComponent = entity - > GetComponent < InventoryComponent > ( ) ;
if ( inventoryComponent ) {
auto * inventory = inventoryComponent - > GetInventory ( selectedInventory ) ;
inventory - > SetSize ( size ) ;
2021-12-05 17:54:36 +00:00
}
return ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " runmacro " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2021-12-05 17:54:36 +00:00
if ( args . size ( ) ! = 1 ) return ;
2022-01-04 05:40:07 +00:00
// Only process if input does not contain separator charaters
if ( args [ 0 ] . find ( " / " ) ! = std : : string : : npos ) return ;
if ( args [ 0 ] . find ( " \\ " ) ! = std : : string : : npos ) return ;
2023-12-23 17:24:16 +00:00
auto infile = Game : : assetManager - > GetFile ( ( " macros/ " + args [ 0 ] + " .scm " ) . c_str ( ) ) ;
2022-11-10 18:59:31 +00:00
2023-12-23 17:24:16 +00:00
if ( ! infile ) {
2022-11-10 18:59:31 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Unknown macro! Is the filename right? " ) ;
return ;
2023-03-14 12:50:12 +00:00
}
2022-11-10 18:59:31 +00:00
2021-12-05 17:54:36 +00:00
if ( infile . good ( ) ) {
std : : string line ;
while ( std : : getline ( infile , line ) ) {
2024-02-11 06:38:21 +00:00
// Do this in two separate calls to catch both \n and \r\n
line . erase ( std : : remove ( line . begin ( ) , line . end ( ) , ' \n ' ) , line . end ( ) ) ;
line . erase ( std : : remove ( line . begin ( ) , line . end ( ) , ' \r ' ) , line . end ( ) ) ;
2021-12-05 17:54:36 +00:00
SlashCommandHandler : : HandleChatCommand ( GeneralUtils : : ASCIIToUTF16 ( line ) , entity , sysAddr ) ;
}
2022-07-28 13:39:57 +00:00
} else {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Unknown macro! Is the filename right? " ) ;
}
2022-01-06 02:52:33 +00:00
2021-12-05 17:54:36 +00:00
return ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " addmission " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2021-12-05 17:54:36 +00:00
if ( args . size ( ) = = 0 ) return ;
2024-02-10 11:05:25 +00:00
const auto missionID = GeneralUtils : : TryParse < uint32_t > ( args . at ( 0 ) ) ;
2021-12-05 17:54:36 +00:00
2024-02-10 11:05:25 +00:00
if ( ! missionID ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid mission id. " ) ;
return ;
}
2022-01-06 02:52:33 +00:00
2023-03-04 07:16:37 +00:00
auto comp = static_cast < MissionComponent * > ( entity - > GetComponent ( eReplicaComponentType : : MISSION ) ) ;
2024-02-10 11:05:25 +00:00
if ( comp ) comp - > AcceptMission ( missionID . value ( ) , true ) ;
2021-12-05 17:54:36 +00:00
return ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " completemission " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2021-12-05 17:54:36 +00:00
if ( args . size ( ) = = 0 ) return ;
2024-02-10 11:05:25 +00:00
const auto missionID = GeneralUtils : : TryParse < uint32_t > ( args . at ( 0 ) ) ;
2021-12-05 17:54:36 +00:00
2024-02-10 11:05:25 +00:00
if ( ! missionID ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid mission id. " ) ;
return ;
}
2022-01-06 02:52:33 +00:00
2023-03-04 07:16:37 +00:00
auto comp = static_cast < MissionComponent * > ( entity - > GetComponent ( eReplicaComponentType : : MISSION ) ) ;
2024-02-10 11:05:25 +00:00
if ( comp ) comp - > CompleteMission ( missionID . value ( ) , true ) ;
2021-12-05 17:54:36 +00:00
return ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " setflag " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER & & args . size ( ) = = 1 ) {
2024-02-10 11:05:25 +00:00
const auto flagId = GeneralUtils : : TryParse < int32_t > ( args . at ( 0 ) ) ;
2021-12-05 17:54:36 +00:00
2024-02-10 11:05:25 +00:00
if ( ! flagId ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid flag id. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
entity - > GetCharacter ( ) - > SetPlayerFlag ( flagId . value ( ) , true ) ;
2021-12-05 17:54:36 +00:00
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " setflag " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER & & args . size ( ) = = 2 ) {
2024-02-10 11:05:25 +00:00
const auto flagId = GeneralUtils : : TryParse < int32_t > ( args . at ( 1 ) ) ;
std : : string onOffFlag = args . at ( 0 ) ;
if ( ! flagId ) {
2022-01-24 13:57:50 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid flag id. " ) ;
return ;
}
if ( onOffFlag ! = " off " & & onOffFlag ! = " on " ) {
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid flag type. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
entity - > GetCharacter ( ) - > SetPlayerFlag ( flagId . value ( ) , onOffFlag = = " on " ) ;
2022-01-24 13:57:50 +00:00
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " clearflag " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER & & args . size ( ) = = 1 ) {
2024-02-10 11:05:25 +00:00
const auto flagId = GeneralUtils : : TryParse < int32_t > ( args . at ( 0 ) ) ;
2021-12-05 17:54:36 +00:00
2024-02-10 11:05:25 +00:00
if ( ! flagId ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid flag id. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
entity - > GetCharacter ( ) - > SetPlayerFlag ( flagId . value ( ) , false ) ;
2021-12-05 17:54:36 +00:00
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " playeffect " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER & & args . size ( ) > = 3 ) {
2024-02-10 11:05:25 +00:00
const auto effectID = GeneralUtils : : TryParse < int32_t > ( args . at ( 0 ) ) ;
2021-12-05 17:54:36 +00:00
2024-02-10 11:05:25 +00:00
if ( ! effectID ) return ;
2021-12-05 17:54:36 +00:00
2022-08-02 13:56:20 +00:00
// FIXME: use fallible ASCIIToUTF16 conversion, because non-ascii isn't valid anyway
2024-02-10 11:05:25 +00:00
GameMessages : : SendPlayFXEffect ( entity - > GetObjectID ( ) , effectID . value ( ) , GeneralUtils : : ASCIIToUTF16 ( args . at ( 1 ) ) , args . at ( 2 ) ) ;
2021-12-05 17:54:36 +00:00
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " stopeffect " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER & & args . size ( ) > = 1 ) {
2021-12-05 17:54:36 +00:00
GameMessages : : SendStopFXEffect ( entity , true , args [ 0 ] ) ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " setanntitle " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2021-12-05 17:54:36 +00:00
if ( args . size ( ) < 0 ) return ;
std : : stringstream ss ;
for ( auto string : args )
ss < < string < < " " ;
entity - > GetCharacter ( ) - > SetAnnouncementTitle ( ss . str ( ) ) ;
return ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " setannmsg " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2021-12-05 17:54:36 +00:00
if ( args . size ( ) < 0 ) return ;
std : : stringstream ss ;
for ( auto string : args )
ss < < string < < " " ;
entity - > GetCharacter ( ) - > SetAnnouncementMessage ( ss . str ( ) ) ;
return ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " announce " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2021-12-05 17:54:36 +00:00
if ( entity - > GetCharacter ( ) - > GetAnnouncementTitle ( ) . size ( ) = = 0 | | entity - > GetCharacter ( ) - > GetAnnouncementMessage ( ) . size ( ) = = 0 ) {
ChatPackets : : SendSystemMessage ( sysAddr , u " Use /setanntitle <title> & /setannmsg <msg> first! " ) ;
return ;
}
SendAnnouncement ( entity - > GetCharacter ( ) - > GetAnnouncementTitle ( ) , entity - > GetCharacter ( ) - > GetAnnouncementMessage ( ) ) ;
return ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " shutdownuniverse " & & entity - > GetGMLevel ( ) = = eGameMasterLevel : : OPERATOR ) {
2021-12-05 17:54:36 +00:00
//Tell the master server that we're going to be shutting down whole "universe":
CBITSTREAM ;
2023-09-21 01:06:28 +00:00
BitStreamUtils : : WriteHeader ( bitStream , eConnectionType : : MASTER , eMasterMessageType : : SHUTDOWN_UNIVERSE ) ;
2024-02-27 05:43:33 +00:00
Game : : server - > SendToMaster ( bitStream ) ;
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Sent universe shutdown notification to master. " ) ;
//Tell chat to send an announcement to all servers
SendAnnouncement ( " Servers Closing Soon! " , " DLU servers will close for maintenance in 10 minutes from now. " ) ;
return ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " getnavmeshheight " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2023-03-04 07:16:37 +00:00
auto control = static_cast < ControllablePhysicsComponent * > ( entity - > GetComponent ( eReplicaComponentType : : CONTROLLABLE_PHYSICS ) ) ;
2021-12-05 17:54:36 +00:00
if ( ! control ) return ;
2024-01-19 21:12:05 +00:00
float y = dpWorld : : GetNavMesh ( ) - > GetHeightAtPoint ( control - > GetPosition ( ) ) ;
2021-12-05 17:54:36 +00:00
std : : u16string msg = u " Navmesh height: " + ( GeneralUtils : : to_u16string ( y ) ) ;
ChatPackets : : SendSystemMessage ( sysAddr , msg ) ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " gmadditem " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2022-04-12 23:30:46 +00:00
if ( args . size ( ) = = 1 ) {
2024-02-10 11:05:25 +00:00
const auto itemLOT = GeneralUtils : : TryParse < uint32_t > ( args . at ( 0 ) ) ;
2021-12-05 17:54:36 +00:00
2024-02-10 11:05:25 +00:00
if ( ! itemLOT ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid item LOT. " ) ;
return ;
}
2022-01-06 02:52:33 +00:00
2023-03-04 07:16:37 +00:00
InventoryComponent * inventory = static_cast < InventoryComponent * > ( entity - > GetComponent ( eReplicaComponentType : : INVENTORY ) ) ;
2021-12-05 17:54:36 +00:00
2024-02-10 11:05:25 +00:00
inventory - > AddItem ( itemLOT . value ( ) , 1 , eLootSourceType : : MODERATION ) ;
2022-07-28 13:39:57 +00:00
} else if ( args . size ( ) = = 2 ) {
2024-02-10 11:05:25 +00:00
const auto itemLOT = GeneralUtils : : TryParse < uint32_t > ( args . at ( 0 ) ) ;
if ( ! itemLOT ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid item LOT. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
const auto count = GeneralUtils : : TryParse < uint32_t > ( args . at ( 1 ) ) ;
if ( ! count ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid item count. " ) ;
return ;
}
2023-03-04 07:16:37 +00:00
InventoryComponent * inventory = static_cast < InventoryComponent * > ( entity - > GetComponent ( eReplicaComponentType : : INVENTORY ) ) ;
2021-12-05 17:54:36 +00:00
2024-02-10 11:05:25 +00:00
inventory - > AddItem ( itemLOT . value ( ) , count . value ( ) , eLootSourceType : : MODERATION ) ;
2022-07-28 13:39:57 +00:00
} else {
2022-04-12 23:30:46 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Correct usage: /gmadditem <lot> " ) ;
}
}
2021-12-05 17:54:36 +00:00
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " mailitem " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : MODERATOR & & args . size ( ) > = 2 ) {
2021-12-05 17:54:36 +00:00
const auto & playerName = args [ 0 ] ;
2023-11-18 00:47:18 +00:00
auto playerInfo = Database : : Get ( ) - > GetCharacterInfo ( playerName ) ;
2021-12-05 17:54:36 +00:00
2023-11-18 00:47:18 +00:00
uint32_t receiverID = 0 ;
if ( ! playerInfo ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Failed to find that player " ) ;
2022-01-06 02:52:33 +00:00
2021-12-05 17:54:36 +00:00
return ;
}
2023-11-18 00:47:18 +00:00
receiverID = playerInfo - > id ;
2024-02-10 11:05:25 +00:00
const auto lot = GeneralUtils : : TryParse < LOT > ( args . at ( 1 ) ) ;
2021-12-05 17:54:36 +00:00
2024-02-10 11:05:25 +00:00
if ( ! lot ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid item lot. " ) ;
return ;
}
2023-11-18 00:47:18 +00:00
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 ;
2024-02-10 11:05:25 +00:00
mailInsert . itemLOT = lot . value ( ) ;
2023-11-18 00:47:18 +00:00
mailInsert . itemSubkey = LWOOBJID_EMPTY ;
mailInsert . itemCount = 1 ;
Database : : Get ( ) - > InsertNewMail ( mailInsert ) ;
2022-01-06 02:52:33 +00:00
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Mail sent " ) ;
return ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " setname " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2021-12-05 17:54:36 +00:00
std : : string name = " " ;
2022-07-28 13:39:57 +00:00
for ( const auto & arg : args ) {
2021-12-05 17:54:36 +00:00
name + = arg + " " ;
}
2022-08-02 13:56:20 +00:00
GameMessages : : SendSetName ( entity - > GetObjectID ( ) , GeneralUtils : : UTF8ToUTF16 ( name ) , UNASSIGNED_SYSTEM_ADDRESS ) ;
2021-12-05 17:54:36 +00:00
}
2022-01-06 02:52:33 +00:00
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " title " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2021-12-05 17:54:36 +00:00
std : : string name = entity - > GetCharacter ( ) - > GetName ( ) + " - " ;
2022-07-28 13:39:57 +00:00
for ( const auto & arg : args ) {
2021-12-05 17:54:36 +00:00
name + = arg + " " ;
}
2022-08-02 13:56:20 +00:00
GameMessages : : SendSetName ( entity - > GetObjectID ( ) , GeneralUtils : : UTF8ToUTF16 ( name ) , UNASSIGNED_SYSTEM_ADDRESS ) ;
2021-12-05 17:54:36 +00:00
}
2023-03-24 23:16:45 +00:00
if ( ( chatCommand = = " teleport " | | chatCommand = = " tele " ) & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : JUNIOR_MODERATOR ) {
2022-07-28 13:39:57 +00:00
NiPoint3 pos { } ;
2022-04-12 23:30:46 +00:00
if ( args . size ( ) = = 3 ) {
2021-12-05 17:54:36 +00:00
2024-02-10 11:05:25 +00:00
const auto x = GeneralUtils : : TryParse < float > ( args . at ( 0 ) ) ;
if ( ! x ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid x. " ) ;
return ;
}
2022-01-06 02:52:33 +00:00
2024-02-10 11:05:25 +00:00
const auto y = GeneralUtils : : TryParse < float > ( args . at ( 1 ) ) ;
if ( ! y ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid y. " ) ;
return ;
}
2022-01-06 02:52:33 +00:00
2024-02-10 11:05:25 +00:00
const auto z = GeneralUtils : : TryParse < float > ( args . at ( 2 ) ) ;
if ( ! z ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid z. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
pos . SetX ( x . value ( ) ) ;
pos . SetY ( y . value ( ) ) ;
pos . SetZ ( z . value ( ) ) ;
2022-01-06 02:52:33 +00:00
2023-10-21 23:31:55 +00:00
LOG ( " Teleporting objectID: %llu to %f, %f, %f " , entity - > GetObjectID ( ) , pos . x , pos . y , pos . z ) ;
2022-07-28 13:39:57 +00:00
GameMessages : : SendTeleport ( entity - > GetObjectID ( ) , pos , NiQuaternion ( ) , sysAddr ) ;
} else if ( args . size ( ) = = 2 ) {
2022-04-12 19:06:03 +00:00
2024-02-10 11:05:25 +00:00
const auto x = GeneralUtils : : TryParse < float > ( args . at ( 0 ) ) ;
if ( ! x ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid x. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
const auto z = GeneralUtils : : TryParse < float > ( args . at ( 1 ) ) ;
if ( ! z ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid z. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
pos . SetX ( x . value ( ) ) ;
2021-12-05 17:54:36 +00:00
pos . SetY ( 0.0f ) ;
2024-02-10 11:05:25 +00:00
pos . SetZ ( z . value ( ) ) ;
2021-12-05 17:54:36 +00:00
2023-10-21 23:31:55 +00:00
LOG ( " Teleporting objectID: %llu to X: %f, Z: %f " , entity - > GetObjectID ( ) , pos . x , pos . z ) ;
2022-07-28 13:39:57 +00:00
GameMessages : : SendTeleport ( entity - > GetObjectID ( ) , pos , NiQuaternion ( ) , sysAddr ) ;
} else {
ChatPackets : : SendSystemMessage ( sysAddr , u " Correct usage: /teleport <x> (<y>) <z> - if no Y given, will teleport to the height of the terrain (or any physics object). " ) ;
}
2021-12-05 17:54:36 +00:00
2022-09-02 18:49:19 +00:00
auto * possessorComponent = entity - > GetComponent < PossessorComponent > ( ) ;
if ( possessorComponent ) {
2023-07-15 20:56:33 +00:00
auto * possassableEntity = Game : : entityManager - > GetEntity ( possessorComponent - > GetPossessable ( ) ) ;
2021-12-05 17:54:36 +00:00
2022-07-28 13:39:57 +00:00
if ( possassableEntity ! = nullptr ) {
2023-12-04 15:20:41 +00:00
auto * havokVehiclePhysicsComponent = possassableEntity - > GetComponent < HavokVehiclePhysicsComponent > ( ) ;
if ( havokVehiclePhysicsComponent ) {
havokVehiclePhysicsComponent - > SetPosition ( pos ) ;
2023-07-15 20:56:33 +00:00
Game : : entityManager - > SerializeEntity ( possassableEntity ) ;
2022-09-02 18:49:19 +00:00
} else GameMessages : : SendTeleport ( possassableEntity - > GetObjectID ( ) , pos , NiQuaternion ( ) , sysAddr ) ;
2021-12-05 17:54:36 +00:00
}
}
2022-04-12 23:30:46 +00:00
}
2021-12-05 17:54:36 +00:00
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " tpall " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2021-12-05 17:54:36 +00:00
const auto pos = entity - > GetPosition ( ) ;
2023-07-15 20:56:33 +00:00
const auto characters = Game : : entityManager - > GetEntitiesByComponent ( eReplicaComponentType : : CHARACTER ) ;
2021-12-05 17:54:36 +00:00
2022-07-28 13:39:57 +00:00
for ( auto * character : characters ) {
2021-12-05 17:54:36 +00:00
GameMessages : : SendTeleport ( character - > GetObjectID ( ) , pos , NiQuaternion ( ) , character - > GetSystemAddress ( ) ) ;
}
return ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " dismount " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2022-09-02 18:49:19 +00:00
auto * possessorComponent = entity - > GetComponent < PossessorComponent > ( ) ;
if ( possessorComponent ) {
auto possessableId = possessorComponent - > GetPossessable ( ) ;
if ( possessableId ! = LWOOBJID_EMPTY ) {
2023-07-15 20:56:33 +00:00
auto * possessableEntity = Game : : entityManager - > GetEntity ( possessableId ) ;
2022-09-02 18:49:19 +00:00
if ( possessableEntity ) possessorComponent - > Dismount ( possessableEntity , true ) ;
2021-12-05 17:54:36 +00:00
}
}
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " fly " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : JUNIOR_DEVELOPER ) {
2022-08-06 08:19:34 +00:00
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 ( args . size ( ) > = 1 ) {
2024-02-10 11:05:25 +00:00
const auto tempScaleStore = GeneralUtils : : TryParse < float > ( args . at ( 0 ) ) ;
2022-08-06 08:19:34 +00:00
2024-02-10 11:05:25 +00:00
if ( tempScaleStore ) {
speedScale = tempScaleStore . value ( ) ;
2022-08-06 08:19:34 +00:00
} 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 ) ;
}
}
}
2021-12-05 17:54:36 +00:00
//------- GM COMMANDS TO ACTUALLY MODERATE --------
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " mute " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : JUNIOR_DEVELOPER ) {
2021-12-05 17:54:36 +00:00
if ( args . size ( ) > = 1 ) {
2024-01-13 09:40:56 +00:00
auto * player = PlayerManager : : GetPlayer ( args [ 0 ] ) ;
2021-12-05 17:54:36 +00:00
uint32_t accountId = 0 ;
LWOOBJID characterId = 0 ;
2022-07-28 13:39:57 +00:00
if ( player = = nullptr ) {
2023-11-18 00:47:18 +00:00
auto characterInfo = Database : : Get ( ) - > GetCharacterInfo ( args [ 0 ] ) ;
2021-12-05 17:54:36 +00:00
2023-11-18 00:47:18 +00:00
if ( characterInfo ) {
accountId = characterInfo - > accountId ;
characterId = characterInfo - > id ;
2022-01-06 02:52:33 +00:00
2023-11-18 00:47:18 +00:00
GeneralUtils : : SetBit ( characterId , eObjectBits : : CHARACTER ) ;
GeneralUtils : : SetBit ( characterId , eObjectBits : : PERSISTENT ) ;
2021-12-05 17:54:36 +00:00
}
2022-07-28 13:39:57 +00:00
if ( accountId = = 0 ) {
2022-08-02 13:56:20 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Count not find player of name: " + GeneralUtils : : UTF8ToUTF16 ( args [ 0 ] ) ) ;
2021-12-05 17:54:36 +00:00
return ;
}
2022-07-28 13:39:57 +00:00
} else {
2024-02-04 14:29:05 +00:00
auto * character = player - > GetCharacter ( ) ;
auto * user = character ! = nullptr ? character - > GetParentUser ( ) : nullptr ;
if ( user ) accountId = user - > GetAccountID ( ) ;
2023-11-16 01:29:00 +00:00
characterId = player - > GetObjectID ( ) ;
2021-12-05 17:54:36 +00:00
}
time_t expire = 1 ; // Default to indefinate mute
2022-07-28 13:39:57 +00:00
if ( args . size ( ) > = 2 ) {
2024-02-10 11:05:25 +00:00
const auto days = GeneralUtils : : TryParse < uint32_t > ( args [ 1 ] ) ;
if ( ! days ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid days. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
std : : optional < uint32_t > hours ;
2022-07-28 13:39:57 +00:00
if ( args . size ( ) > = 3 ) {
2024-02-10 11:05:25 +00:00
hours = GeneralUtils : : TryParse < uint32_t > ( args [ 2 ] ) ;
if ( ! hours ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid hours. " ) ;
return ;
}
}
expire = time ( NULL ) ;
2024-02-10 11:05:25 +00:00
expire + = 24 * 60 * 60 * days . value ( ) ;
expire + = 60 * 60 * hours . value_or ( 0 ) ;
2021-12-05 17:54:36 +00:00
}
2024-02-04 14:29:05 +00:00
if ( accountId ! = 0 ) Database : : Get ( ) - > UpdateAccountUnmuteTime ( accountId , expire ) ;
2022-01-06 02:52:33 +00:00
2021-12-05 17:54:36 +00:00
char buffer [ 32 ] = " brought up for review. \0 " ;
2022-07-28 13:39:57 +00:00
if ( expire ! = 1 ) {
std : : tm * ptm = std : : localtime ( & expire ) ;
2021-12-05 17:54:36 +00:00
// Format: Mo, 15.06.2009 20:20:00
std : : strftime ( buffer , 32 , " %a, %d.%m.%Y %H:%M:%S " , ptm ) ;
}
2022-01-06 02:52:33 +00:00
2021-12-05 17:54:36 +00:00
const auto timeStr = GeneralUtils : : ASCIIToUTF16 ( std : : string ( buffer ) ) ;
2022-08-02 13:56:20 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Muted: " + GeneralUtils : : UTF8ToUTF16 ( args [ 0 ] ) + u " until " + timeStr ) ;
2021-12-05 17:54:36 +00:00
2022-01-06 02:52:33 +00:00
//Notify chat about it
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
2023-09-21 01:06:28 +00:00
BitStreamUtils : : WriteHeader ( bitStream , eConnectionType : : CHAT_INTERNAL , eChatInternalMessageType : : MUTE_UPDATE ) ;
2021-12-05 17:54:36 +00:00
bitStream . Write ( characterId ) ;
bitStream . Write ( expire ) ;
Game : : chatServer - > Send ( & bitStream , SYSTEM_PRIORITY , RELIABLE , 0 , Game : : chatSysAddr , false ) ;
2022-07-28 13:39:57 +00:00
} else {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Correct usage: /mute <username> <days (optional)> <hours (optional)> " ) ;
}
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " kick " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : JUNIOR_MODERATOR ) {
2021-12-05 17:54:36 +00:00
if ( args . size ( ) = = 1 ) {
2024-01-13 09:40:56 +00:00
auto * player = PlayerManager : : GetPlayer ( args [ 0 ] ) ;
2021-12-05 17:54:36 +00:00
2022-08-02 13:56:20 +00:00
std : : u16string username = GeneralUtils : : UTF8ToUTF16 ( args [ 0 ] ) ;
2022-07-28 13:39:57 +00:00
if ( player = = nullptr ) {
2022-08-02 13:56:20 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Count not find player of name: " + username ) ;
2021-12-05 17:54:36 +00:00
return ;
}
2023-02-19 12:29:14 +00:00
Game : : server - > Disconnect ( player - > GetSystemAddress ( ) , eServerDisconnectIdentifiers : : KICK ) ;
2021-12-05 17:54:36 +00:00
2022-08-02 13:56:20 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Kicked: " + username ) ;
2022-07-28 13:39:57 +00:00
} else {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Correct usage: /kick <username> " ) ;
}
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " ban " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : SENIOR_MODERATOR ) {
2021-12-05 17:54:36 +00:00
if ( args . size ( ) = = 1 ) {
2024-01-13 09:40:56 +00:00
auto * player = PlayerManager : : GetPlayer ( args [ 0 ] ) ;
2021-12-05 17:54:36 +00:00
uint32_t accountId = 0 ;
2022-07-28 13:39:57 +00:00
if ( player = = nullptr ) {
2023-11-18 00:47:18 +00:00
auto characterInfo = Database : : Get ( ) - > GetCharacterInfo ( args [ 0 ] ) ;
2021-12-05 17:54:36 +00:00
2023-11-18 00:47:18 +00:00
if ( characterInfo ) {
accountId = characterInfo - > accountId ;
2021-12-05 17:54:36 +00:00
}
2022-07-28 13:39:57 +00:00
if ( accountId = = 0 ) {
2022-08-02 13:56:20 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Count not find player of name: " + GeneralUtils : : UTF8ToUTF16 ( args [ 0 ] ) ) ;
2021-12-05 17:54:36 +00:00
return ;
}
2022-07-28 13:39:57 +00:00
} else {
2024-02-04 14:29:05 +00:00
auto * character = player - > GetCharacter ( ) ;
auto * user = character ! = nullptr ? character - > GetParentUser ( ) : nullptr ;
if ( user ) accountId = user - > GetAccountID ( ) ;
2021-12-05 17:54:36 +00:00
}
2024-02-04 14:29:05 +00:00
if ( accountId ! = 0 ) Database : : Get ( ) - > UpdateAccountBan ( accountId , true ) ;
2021-12-05 17:54:36 +00:00
2022-07-28 13:39:57 +00:00
if ( player ! = nullptr ) {
2023-02-19 12:29:14 +00:00
Game : : server - > Disconnect ( player - > GetSystemAddress ( ) , eServerDisconnectIdentifiers : : FREE_TRIAL_EXPIRED ) ;
2021-12-05 17:54:36 +00:00
}
ChatPackets : : SendSystemMessage ( sysAddr , u " Banned: " + GeneralUtils : : ASCIIToUTF16 ( args [ 0 ] ) ) ;
2022-07-28 13:39:57 +00:00
} else {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Correct usage: /ban <username> " ) ;
}
}
//-------------------------------------------------
2022-01-06 02:52:33 +00:00
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " buffme " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2023-03-04 07:16:37 +00:00
auto dest = static_cast < DestroyableComponent * > ( entity - > GetComponent ( eReplicaComponentType : : DESTROYABLE ) ) ;
2021-12-05 17:54:36 +00:00
if ( dest ) {
dest - > SetHealth ( 999 ) ;
dest - > SetMaxHealth ( 999.0f ) ;
dest - > SetArmor ( 999 ) ;
dest - > SetMaxArmor ( 999.0f ) ;
dest - > SetImagination ( 999 ) ;
dest - > SetMaxImagination ( 999.0f ) ;
}
2023-07-15 20:56:33 +00:00
Game : : entityManager - > SerializeEntity ( entity ) ;
2022-07-28 13:39:57 +00:00
}
2021-12-05 17:54:36 +00:00
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " startcelebration " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER & & args . size ( ) = = 1 ) {
2024-02-10 11:05:25 +00:00
const auto celebration = GeneralUtils : : TryParse < int32_t > ( args . at ( 0 ) ) ;
2022-01-06 02:52:33 +00:00
2024-02-10 11:05:25 +00:00
if ( ! celebration ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid celebration. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
GameMessages : : SendStartCelebrationEffect ( entity , entity - > GetSystemAddress ( ) , celebration . value ( ) ) ;
2021-12-05 17:54:36 +00:00
}
2022-01-06 02:52:33 +00:00
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " buffmed " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2023-03-04 07:16:37 +00:00
auto dest = static_cast < DestroyableComponent * > ( entity - > GetComponent ( eReplicaComponentType : : DESTROYABLE ) ) ;
2021-12-05 17:54:36 +00:00
if ( dest ) {
dest - > SetHealth ( 9 ) ;
dest - > SetMaxHealth ( 9.0f ) ;
dest - > SetArmor ( 9 ) ;
dest - > SetMaxArmor ( 9.0f ) ;
dest - > SetImagination ( 9 ) ;
dest - > SetMaxImagination ( 9.0f ) ;
}
2023-07-15 20:56:33 +00:00
Game : : entityManager - > SerializeEntity ( entity ) ;
2022-07-28 13:39:57 +00:00
}
2022-01-06 02:52:33 +00:00
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " refillstats " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2022-04-12 19:06:03 +00:00
2023-03-04 07:16:37 +00:00
auto dest = static_cast < DestroyableComponent * > ( entity - > GetComponent ( eReplicaComponentType : : DESTROYABLE ) ) ;
2021-12-05 17:54:36 +00:00
if ( dest ) {
2023-12-28 04:18:20 +00:00
dest - > SetHealth ( static_cast < int32_t > ( dest - > GetMaxHealth ( ) ) ) ;
dest - > SetArmor ( static_cast < int32_t > ( dest - > GetMaxArmor ( ) ) ) ;
dest - > SetImagination ( static_cast < int32_t > ( dest - > GetMaxImagination ( ) ) ) ;
2021-12-05 17:54:36 +00:00
}
2023-07-15 20:56:33 +00:00
Game : : entityManager - > SerializeEntity ( entity ) ;
2022-07-28 13:39:57 +00:00
}
2022-01-06 02:52:33 +00:00
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " lookup " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER & & args . size ( ) > = 1 ) {
2022-01-13 03:48:27 +00:00
auto query = CDClientDatabase : : CreatePreppedStmt (
2022-01-15 19:02:14 +00:00
" SELECT `id`, `name` FROM `Objects` WHERE `displayName` LIKE ?1 OR `name` LIKE ?1 OR `description` LIKE ?1 LIMIT 50 " ) ;
2023-01-07 06:17:09 +00:00
// Concatenate all of the arguments into a single query so a multi word query can be used properly.
std : : string conditional = args [ 0 ] ;
args . erase ( args . begin ( ) ) ;
for ( auto & argument : args ) {
conditional + = ' ' + argument ;
}
2022-01-13 03:48:27 +00:00
2023-01-07 06:17:09 +00:00
const std : : string query_text = " % " + conditional + " % " ;
2022-01-15 19:02:14 +00:00
query . bind ( 1 , query_text . c_str ( ) ) ;
2022-01-13 03:48:27 +00:00
auto tables = query . execQuery ( ) ;
2022-01-06 02:52:33 +00:00
2022-07-28 13:39:57 +00:00
while ( ! tables . eof ( ) ) {
std : : string message = std : : to_string ( tables . getIntField ( 0 ) ) + " - " + tables . getStringField ( 1 ) ;
2022-08-02 13:56:20 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , GeneralUtils : : UTF8ToUTF16 ( message , message . size ( ) ) ) ;
2022-07-28 13:39:57 +00:00
tables . nextRow ( ) ;
}
}
2022-01-06 02:52:33 +00:00
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " spawn " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER & & args . size ( ) > = 1 ) {
2023-03-04 07:16:37 +00:00
ControllablePhysicsComponent * comp = static_cast < ControllablePhysicsComponent * > ( entity - > GetComponent ( eReplicaComponentType : : CONTROLLABLE_PHYSICS ) ) ;
2022-07-28 13:39:57 +00:00
if ( ! comp ) return ;
2021-12-05 17:54:36 +00:00
2024-02-10 11:05:25 +00:00
const auto lot = GeneralUtils : : TryParse < uint32_t > ( args [ 0 ] ) ;
2022-01-06 02:52:33 +00:00
2024-02-10 11:05:25 +00:00
if ( ! lot ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid lot. " ) ;
return ;
}
2022-04-12 23:30:46 +00:00
EntityInfo info ;
2024-02-10 11:05:25 +00:00
info . lot = lot . value ( ) ;
2022-04-12 23:30:46 +00:00
info . pos = comp - > GetPosition ( ) ;
info . rot = comp - > GetRotation ( ) ;
2021-12-05 17:54:36 +00:00
info . spawner = nullptr ;
info . spawnerID = entity - > GetObjectID ( ) ;
info . spawnerNodeID = 0 ;
2023-07-15 20:56:33 +00:00
Entity * newEntity = Game : : entityManager - > CreateEntity ( info , nullptr ) ;
2021-12-05 17:54:36 +00:00
2022-04-12 23:30:46 +00:00
if ( newEntity = = nullptr ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Failed to spawn entity. " ) ;
return ;
2022-04-12 23:30:46 +00:00
}
2021-12-05 17:54:36 +00:00
2023-07-15 20:56:33 +00:00
Game : : entityManager - > ConstructEntity ( newEntity ) ;
2022-04-12 23:30:46 +00:00
}
2021-12-05 17:54:36 +00:00
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " spawngroup " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER & & args . size ( ) > = 3 ) {
2022-12-02 11:47:27 +00:00
auto controllablePhysicsComponent = entity - > GetComponent < ControllablePhysicsComponent > ( ) ;
if ( ! controllablePhysicsComponent ) return ;
2024-02-10 11:05:25 +00:00
const auto lot = GeneralUtils : : TryParse < LOT > ( args [ 0 ] ) ;
if ( ! lot ) {
2022-12-02 11:47:27 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid lot. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
const auto numberToSpawnOptional = GeneralUtils : : TryParse < uint32_t > ( args [ 1 ] ) ;
if ( ! numberToSpawnOptional & & numberToSpawnOptional . value ( ) > 0 ) {
2022-12-02 11:47:27 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid number of enemies to spawn. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
uint32_t numberToSpawn = numberToSpawnOptional . value ( ) ;
2022-12-02 11:47:27 +00:00
// Must spawn within a radius of at least 0.0f
2024-02-10 11:05:25 +00:00
const auto radiusToSpawnWithinOptional = GeneralUtils : : TryParse < float > ( args [ 2 ] ) ;
if ( ! radiusToSpawnWithinOptional & & radiusToSpawnWithinOptional . value ( ) < 0.0f ) {
2022-12-02 11:47:27 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid radius to spawn within. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
const float radiusToSpawnWithin = radiusToSpawnWithinOptional . value ( ) ;
2022-12-02 11:47:27 +00:00
EntityInfo info ;
2024-02-10 11:05:25 +00:00
info . lot = lot . value ( ) ;
2022-12-02 11:47:27 +00:00
info . spawner = nullptr ;
info . spawnerID = entity - > GetObjectID ( ) ;
info . spawnerNodeID = 0 ;
auto playerPosition = controllablePhysicsComponent - > GetPosition ( ) ;
while ( numberToSpawn > 0 ) {
auto randomAngle = GeneralUtils : : GenerateRandomNumber < float > ( 0.0f , 2 * PI ) ;
auto randomRadius = GeneralUtils : : GenerateRandomNumber < float > ( 0.0f , radiusToSpawnWithin ) ;
// Set the position to the generated random position plus the player position. This will
// spawn the entity in a circle around the player. As you get further from the player, the angle chosen will get less accurate.
info . pos = playerPosition + NiPoint3 ( cos ( randomAngle ) * randomRadius , 0.0f , sin ( randomAngle ) * randomRadius ) ;
info . rot = NiQuaternion ( ) ;
2023-07-15 20:56:33 +00:00
auto newEntity = Game : : entityManager - > CreateEntity ( info ) ;
2022-12-02 11:47:27 +00:00
if ( newEntity = = nullptr ) {
ChatPackets : : SendSystemMessage ( sysAddr , u " Failed to spawn entity. " ) ;
return ;
}
2023-07-15 20:56:33 +00:00
Game : : entityManager - > ConstructEntity ( newEntity ) ;
2022-12-02 11:47:27 +00:00
numberToSpawn - - ;
}
}
2023-03-24 23:16:45 +00:00
if ( ( chatCommand = = " giveuscore " ) & & args . size ( ) > = 1 & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2024-02-10 11:05:25 +00:00
const auto uscoreOptional = GeneralUtils : : TryParse < int32_t > ( args [ 0 ] ) ;
if ( ! uscoreOptional ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid uscore. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
const int32_t uscore = uscoreOptional . value ( ) ;
2021-12-05 17:54:36 +00:00
CharacterComponent * character = entity - > GetComponent < CharacterComponent > ( ) ;
if ( character ) character - > SetUScore ( character - > GetUScore ( ) + uscore ) ;
2023-05-02 22:39:21 +00:00
// MODERATION should work but it doesn't. Relog to see uscore changes
2023-01-11 20:50:21 +00:00
2023-05-02 22:39:21 +00:00
eLootSourceType lootType = eLootSourceType : : MODERATION ;
2023-01-11 20:50:21 +00:00
2024-02-10 11:05:25 +00:00
if ( args . size ( ) > = 2 ) {
const auto type = GeneralUtils : : TryParse < eLootSourceType > ( args [ 1 ] ) ;
lootType = type . value_or ( lootType ) ;
2023-01-11 20:50:21 +00:00
}
GameMessages : : SendModifyLEGOScore ( entity , entity - > GetSystemAddress ( ) , uscore , lootType ) ;
2021-12-05 17:54:36 +00:00
}
2023-03-24 23:16:45 +00:00
if ( ( chatCommand = = " setlevel " ) & & args . size ( ) > = 1 & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2022-06-13 07:45:17 +00:00
// We may be trying to set a specific players level to a level. If so override the entity with the requested players.
std : : string requestedPlayerToSetLevelOf = " " ;
if ( args . size ( ) > 1 ) {
requestedPlayerToSetLevelOf = args [ 1 ] ;
2024-01-13 09:40:56 +00:00
auto requestedPlayer = PlayerManager : : GetPlayer ( requestedPlayerToSetLevelOf ) ;
2022-06-13 07:45:17 +00:00
if ( ! requestedPlayer ) {
2022-08-02 13:56:20 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " No player found with username: ( " + GeneralUtils : : UTF8ToUTF16 ( requestedPlayerToSetLevelOf ) + u " ). " ) ;
2022-06-13 07:45:17 +00:00
return ;
}
if ( ! requestedPlayer - > GetOwner ( ) ) {
2022-08-02 13:56:20 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " No entity found with username: ( " + GeneralUtils : : UTF8ToUTF16 ( requestedPlayerToSetLevelOf ) + u " ). " ) ;
2022-06-13 07:45:17 +00:00
return ;
}
entity = requestedPlayer - > GetOwner ( ) ;
}
2024-02-10 11:05:25 +00:00
const auto requestedLevelOptional = GeneralUtils : : TryParse < uint32_t > ( args [ 0 ] ) ;
2022-06-13 07:45:17 +00:00
uint32_t oldLevel ;
2024-02-10 11:05:25 +00:00
// first check the level is valid
if ( ! requestedLevelOptional ) {
2022-06-13 07:45:17 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid level. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
uint32_t requestedLevel = requestedLevelOptional . value ( ) ;
2022-06-13 07:45:17 +00:00
// query to set our uscore to the correct value for this level
auto characterComponent = entity - > GetComponent < CharacterComponent > ( ) ;
2022-07-24 18:04:02 +00:00
if ( ! characterComponent ) return ;
auto levelComponent = entity - > GetComponent < LevelProgressionComponent > ( ) ;
2022-06-13 07:45:17 +00:00
auto query = CDClientDatabase : : CreatePreppedStmt ( " SELECT requiredUScore from LevelProgressionLookup WHERE id = ?; " ) ;
2023-12-28 04:18:20 +00:00
query . bind ( 1 , static_cast < int > ( requestedLevel ) ) ;
2022-06-13 07:45:17 +00:00
auto result = query . execQuery ( ) ;
if ( result . eof ( ) ) return ;
// Set the UScore first
2022-07-24 18:04:02 +00:00
oldLevel = levelComponent - > GetLevel ( ) ;
2022-06-13 07:45:17 +00:00
characterComponent - > SetUScore ( result . getIntField ( 0 , characterComponent - > GetUScore ( ) ) ) ;
// handle level up for each level we have passed if we set our level to be higher than the current one.
if ( oldLevel < requestedLevel ) {
while ( oldLevel < requestedLevel ) {
2022-07-28 13:39:57 +00:00
oldLevel + = 1 ;
2022-07-24 18:04:02 +00:00
levelComponent - > SetLevel ( oldLevel ) ;
levelComponent - > HandleLevelUp ( ) ;
2022-06-13 07:45:17 +00:00
}
} else {
2022-07-24 18:04:02 +00:00
levelComponent - > SetLevel ( requestedLevel ) ;
2022-06-13 07:45:17 +00:00
}
if ( requestedPlayerToSetLevelOf ! = " " ) {
2022-07-28 13:39:57 +00:00
ChatPackets : : SendSystemMessage (
2022-08-02 13:56:20 +00:00
sysAddr , u " Set " + GeneralUtils : : UTF8ToUTF16 ( requestedPlayerToSetLevelOf ) + u " 's level to " + GeneralUtils : : to_u16string ( requestedLevel ) +
2022-07-28 13:39:57 +00:00
u " and UScore to " + GeneralUtils : : to_u16string ( characterComponent - > GetUScore ( ) ) +
u " . Relog to see changes. " ) ;
2022-06-13 07:45:17 +00:00
} else {
2022-07-28 13:39:57 +00:00
ChatPackets : : SendSystemMessage (
sysAddr , u " Set your level to " + GeneralUtils : : to_u16string ( requestedLevel ) +
u " and UScore to " + GeneralUtils : : to_u16string ( characterComponent - > GetUScore ( ) ) +
u " . Relog to see changes. " ) ;
2022-06-13 07:45:17 +00:00
}
return ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " pos " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2021-12-05 17:54:36 +00:00
const auto position = entity - > GetPosition ( ) ;
2022-07-28 13:39:57 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " < " + ( GeneralUtils : : to_u16string ( position . x ) ) + u " , " + ( GeneralUtils : : to_u16string ( position . y ) ) + u " , " + ( GeneralUtils : : to_u16string ( position . z ) ) + u " > " ) ;
2022-01-06 02:52:33 +00:00
2023-11-22 02:04:23 +00:00
LOG ( " Position: %f, %f, %f " , position . x , position . y , position . z ) ;
2021-12-05 17:54:36 +00:00
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " rot " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2021-12-05 17:54:36 +00:00
const auto rotation = entity - > GetRotation ( ) ;
2022-07-28 13:39:57 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " < " + ( GeneralUtils : : to_u16string ( rotation . w ) ) + u " , " + ( GeneralUtils : : to_u16string ( rotation . x ) ) + u " , " + ( GeneralUtils : : to_u16string ( rotation . y ) ) + u " , " + ( GeneralUtils : : to_u16string ( rotation . z ) ) + u " > " ) ;
2021-12-05 17:54:36 +00:00
2023-11-22 02:04:23 +00:00
LOG ( " Rotation: %f, %f, %f, %f " , rotation . w , rotation . x , rotation . y , rotation . z ) ;
2021-12-05 17:54:36 +00:00
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " locrow " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2021-12-05 17:54:36 +00:00
const auto position = entity - > GetPosition ( ) ;
const auto rotation = entity - > GetRotation ( ) ;
2023-11-22 02:04:23 +00:00
LOG ( " <location x= \" %f \" y= \" %f \" z= \" %f \" rw= \" %f \" rx= \" %f \" ry= \" %f \" rz= \" %f \" /> " , position . x , position . y , position . z , rotation . w , rotation . x , rotation . y , rotation . z ) ;
2021-12-05 17:54:36 +00:00
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " playlvlfx " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2021-12-05 17:54:36 +00:00
GameMessages : : SendPlayFXEffect ( entity , 7074 , u " create " , " 7074 " , LWOOBJID_EMPTY , 1.0f , 1.0f , true ) ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " playrebuildfx " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2022-04-12 23:30:46 +00:00
GameMessages : : SendPlayFXEffect ( entity , 230 , u " rebuild " , " 230 " , LWOOBJID_EMPTY , 1.0f , 1.0f , true ) ;
}
2021-12-05 17:54:36 +00:00
2023-03-24 23:16:45 +00:00
if ( ( chatCommand = = " freemoney " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) & & args . size ( ) = = 1 ) {
2024-02-10 11:05:25 +00:00
const auto money = GeneralUtils : : TryParse < int64_t > ( args [ 0 ] ) ;
2021-12-05 17:54:36 +00:00
2024-02-10 11:05:25 +00:00
if ( ! money ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid money. " ) ;
return ;
}
auto * ch = entity - > GetCharacter ( ) ;
2024-02-10 11:05:25 +00:00
ch - > SetCoins ( ch - > GetCoins ( ) + money . value ( ) , eLootSourceType : : MODERATION ) ;
2021-12-05 17:54:36 +00:00
}
2023-03-24 23:16:45 +00:00
if ( ( chatCommand = = " setcurrency " ) & & args . size ( ) = = 1 & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2024-02-10 11:05:25 +00:00
const auto money = GeneralUtils : : TryParse < int64_t > ( args [ 0 ] ) ;
2021-12-05 17:54:36 +00:00
2024-02-10 11:05:25 +00:00
if ( ! money ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid money. " ) ;
return ;
}
auto * ch = entity - > GetCharacter ( ) ;
2024-02-10 11:05:25 +00:00
ch - > SetCoins ( money . value ( ) , eLootSourceType : : MODERATION ) ;
2021-12-05 17:54:36 +00:00
}
// Allow for this on even while not a GM, as it sometimes toggles incorrrectly.
2024-02-04 14:29:05 +00:00
if ( chatCommand = = " gminvis " & & entity - > GetCharacter ( ) - > GetParentUser ( ) - > GetMaxGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2021-12-05 17:54:36 +00:00
GameMessages : : SendToggleGMInvis ( entity - > GetObjectID ( ) , true , UNASSIGNED_SYSTEM_ADDRESS ) ;
2022-01-06 02:52:33 +00:00
2021-12-05 17:54:36 +00:00
return ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " gmimmune " & & args . size ( ) > = 1 & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2021-12-05 17:54:36 +00:00
auto * destroyableComponent = entity - > GetComponent < DestroyableComponent > ( ) ;
2024-02-10 11:05:25 +00:00
const auto state = GeneralUtils : : TryParse < int32_t > ( args [ 0 ] ) ;
2021-12-05 17:54:36 +00:00
2024-02-10 11:05:25 +00:00
if ( ! state ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid state. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
if ( destroyableComponent ) destroyableComponent - > SetIsGMImmune ( state . value ( ) ) ;
2021-12-05 17:54:36 +00:00
return ;
}
2023-11-12 11:53:03 +00:00
//Testing basic attack immunity
if ( chatCommand = = " attackimmune " & & args . size ( ) > = 1 & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
auto * destroyableComponent = entity - > GetComponent < DestroyableComponent > ( ) ;
2024-02-10 11:05:25 +00:00
const auto state = GeneralUtils : : TryParse < int32_t > ( args [ 0 ] ) ;
2023-11-12 11:53:03 +00:00
2024-02-10 11:05:25 +00:00
if ( ! state ) {
2023-11-12 11:53:03 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid state. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
if ( destroyableComponent ) destroyableComponent - > SetIsImmune ( state . value ( ) ) ;
2023-11-12 11:53:03 +00:00
return ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " buff " & & args . size ( ) > = 2 & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2021-12-05 17:54:36 +00:00
auto * buffComponent = entity - > GetComponent < BuffComponent > ( ) ;
2024-02-10 11:05:25 +00:00
const auto id = GeneralUtils : : TryParse < int32_t > ( args [ 0 ] ) ;
if ( ! id ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid buff id. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
const auto duration = GeneralUtils : : TryParse < int32_t > ( args [ 1 ] ) ;
if ( ! duration ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid buff duration. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
if ( buffComponent ) buffComponent - > ApplyBuff ( id . value ( ) , duration . value ( ) , entity - > GetObjectID ( ) ) ;
2021-12-05 17:54:36 +00:00
return ;
}
2023-03-24 23:16:45 +00:00
if ( ( chatCommand = = " testmap " & & args . size ( ) > = 1 ) & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : FORUM_MODERATOR ) {
2022-04-12 23:30:46 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Requesting map change... " ) ;
2021-12-05 17:54:36 +00:00
LWOCLONEID cloneId = 0 ;
bool force = false ;
2024-02-10 11:05:25 +00:00
const auto reqZoneOptional = GeneralUtils : : TryParse < LWOMAPID > ( args [ 0 ] ) ;
if ( ! reqZoneOptional ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid zone. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
const LWOMAPID reqZone = reqZoneOptional . value ( ) ;
2021-12-05 17:54:36 +00:00
2022-07-28 13:39:57 +00:00
if ( args . size ( ) > 1 ) {
2021-12-05 17:54:36 +00:00
auto index = 1 ;
2022-07-28 13:39:57 +00:00
if ( args [ index ] = = " force " ) {
2021-12-05 17:54:36 +00:00
index + + ;
force = true ;
}
2024-02-10 11:05:25 +00:00
if ( args . size ( ) > index ) {
const auto cloneIdOptional = GeneralUtils : : TryParse < LWOCLONEID > ( args [ index ] ) ;
if ( ! cloneIdOptional ) {
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid clone id. " ) ;
return ;
}
cloneId = cloneIdOptional . value ( ) ;
2021-12-05 17:54:36 +00:00
}
}
const auto objid = entity - > GetObjectID ( ) ;
2022-01-06 02:52:33 +00:00
2023-07-17 22:55:33 +00:00
if ( force | | Game : : zoneManager - > CheckIfAccessibleZone ( reqZone ) ) { // to prevent tomfoolery
2022-01-06 02:52:33 +00:00
2022-07-09 03:25:44 +00:00
ZoneInstanceManager : : Instance ( ) - > RequestZoneTransfer ( Game : : server , reqZone , cloneId , false , [ objid ] ( bool mythranShift , uint32_t zoneID , uint32_t zoneInstance , uint32_t zoneClone , std : : string serverIP , uint16_t serverPort ) {
2021-12-05 17:54:36 +00:00
2023-07-15 20:56:33 +00:00
auto * entity = Game : : entityManager - > GetEntity ( objid ) ;
2022-07-09 03:25:44 +00:00
if ( ! entity ) return ;
2021-12-05 17:54:36 +00:00
2022-07-09 03:25:44 +00:00
const auto sysAddr = entity - > GetSystemAddress ( ) ;
2021-12-05 17:54:36 +00:00
2022-07-09 03:25:44 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Transfering map... " ) ;
2021-12-05 17:54:36 +00:00
2023-10-21 23:31:55 +00:00
LOG ( " Transferring %s to Zone %i (Instance %i | Clone %i | Mythran Shift: %s) with IP %s and Port %i " , sysAddr . ToString ( ) , zoneID , zoneInstance , zoneClone , mythranShift = = true ? " true " : " false " , serverIP . c_str ( ) , serverPort ) ;
2022-07-09 03:25:44 +00:00
if ( entity - > GetCharacter ( ) ) {
entity - > GetCharacter ( ) - > SetZoneID ( zoneID ) ;
entity - > GetCharacter ( ) - > SetZoneInstance ( zoneInstance ) ;
entity - > GetCharacter ( ) - > SetZoneClone ( zoneClone ) ;
entity - > GetComponent < CharacterComponent > ( ) - > SetLastRocketConfig ( u " " ) ;
}
2021-12-05 17:54:36 +00:00
2022-07-09 03:25:44 +00:00
entity - > GetCharacter ( ) - > SaveXMLToDatabase ( ) ;
2021-12-05 17:54:36 +00:00
2022-07-09 03:25:44 +00:00
WorldPackets : : SendTransferToWorld ( sysAddr , serverIP , serverPort , mythranShift ) ;
return ;
2022-07-28 13:39:57 +00:00
} ) ;
2022-07-09 03:25:44 +00:00
} else {
std : : string msg = " ZoneID not found or allowed: " ;
2022-08-02 13:56:20 +00:00
msg . append ( args [ 0 ] ) ; // FIXME: unnecessary utf16 re-encoding just for error
ChatPackets : : SendSystemMessage ( sysAddr , GeneralUtils : : UTF8ToUTF16 ( msg , msg . size ( ) ) ) ;
2022-07-09 03:25:44 +00:00
}
}
2021-12-05 17:54:36 +00:00
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " createprivate " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER & & args . size ( ) > = 3 ) {
2024-02-10 11:05:25 +00:00
const auto zone = GeneralUtils : : TryParse < uint32_t > ( args [ 0 ] ) ;
if ( ! zone ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid zone. " ) ;
return ;
}
2024-02-10 11:05:25 +00:00
const auto clone = GeneralUtils : : TryParse < uint32_t > ( args [ 1 ] ) ;
if ( ! clone ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid clone. " ) ;
return ;
}
const auto & password = args [ 2 ] ;
2024-02-10 11:05:25 +00:00
ZoneInstanceManager : : Instance ( ) - > CreatePrivateZone ( Game : : server , zone . value ( ) , clone . value ( ) , password ) ;
2022-01-06 02:52:33 +00:00
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , GeneralUtils : : ASCIIToUTF16 ( " Sent request for private zone with password: " + password ) ) ;
return ;
}
2023-03-24 23:16:45 +00:00
if ( ( chatCommand = = " debugui " ) & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Opening UIDebugger... " ) ;
AMFArrayValue args ;
2023-05-13 22:22:00 +00:00
GameMessages : : SendUIMessageServerToSingleClient ( entity , sysAddr , " ToggleUIDebugger; " , args ) ;
2021-12-05 17:54:36 +00:00
}
2023-03-24 23:16:45 +00:00
if ( ( chatCommand = = " boost " ) & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2021-12-05 17:54:36 +00:00
auto * possessorComponent = entity - > GetComponent < PossessorComponent > ( ) ;
2022-07-28 13:39:57 +00:00
if ( possessorComponent = = nullptr ) {
2021-12-05 17:54:36 +00:00
return ;
}
2023-07-15 20:56:33 +00:00
auto * vehicle = Game : : entityManager - > GetEntity ( possessorComponent - > GetPossessable ( ) ) ;
2021-12-05 17:54:36 +00:00
2022-07-28 13:39:57 +00:00
if ( vehicle = = nullptr ) {
2021-12-05 17:54:36 +00:00
return ;
}
2022-09-02 18:49:19 +00:00
if ( args . size ( ) > = 1 ) {
2024-02-10 11:05:25 +00:00
const auto time = GeneralUtils : : TryParse < float > ( args [ 0 ] ) ;
2022-09-02 18:49:19 +00:00
2024-02-10 11:05:25 +00:00
if ( ! time ) {
2022-09-02 18:49:19 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid boost time. " ) ;
return ;
} else {
GameMessages : : SendVehicleAddPassiveBoostAction ( vehicle - > GetObjectID ( ) , UNASSIGNED_SYSTEM_ADDRESS ) ;
2024-02-10 11:05:25 +00:00
entity - > AddCallbackTimer ( time . value ( ) , [ vehicle ] ( ) {
2022-09-02 18:49:19 +00:00
if ( ! vehicle ) return ;
GameMessages : : SendVehicleRemovePassiveBoostAction ( vehicle - > GetObjectID ( ) , UNASSIGNED_SYSTEM_ADDRESS ) ;
} ) ;
}
} else {
GameMessages : : SendVehicleAddPassiveBoostAction ( vehicle - > GetObjectID ( ) , UNASSIGNED_SYSTEM_ADDRESS ) ;
}
}
2023-03-24 23:16:45 +00:00
if ( ( chatCommand = = " unboost " ) & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2022-09-02 18:49:19 +00:00
auto * possessorComponent = entity - > GetComponent < PossessorComponent > ( ) ;
if ( possessorComponent = = nullptr ) return ;
2023-07-15 20:56:33 +00:00
auto * vehicle = Game : : entityManager - > GetEntity ( possessorComponent - > GetPossessable ( ) ) ;
2022-09-02 18:49:19 +00:00
if ( vehicle = = nullptr ) return ;
GameMessages : : SendVehicleRemovePassiveBoostAction ( vehicle - > GetObjectID ( ) , UNASSIGNED_SYSTEM_ADDRESS ) ;
2021-12-05 17:54:36 +00:00
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " activatespawner " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER & & args . size ( ) > = 1 ) {
2023-07-17 22:55:33 +00:00
auto spawners = Game : : zoneManager - > GetSpawnersByName ( args [ 0 ] ) ;
2021-12-05 17:54:36 +00:00
2022-07-28 13:39:57 +00:00
for ( auto * spawner : spawners ) {
2021-12-05 17:54:36 +00:00
spawner - > Activate ( ) ;
}
2023-07-17 22:55:33 +00:00
spawners = Game : : zoneManager - > GetSpawnersInGroup ( args [ 0 ] ) ;
2021-12-05 17:54:36 +00:00
2022-07-28 13:39:57 +00:00
for ( auto * spawner : spawners ) {
2021-12-05 17:54:36 +00:00
spawner - > Activate ( ) ;
}
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " spawnphysicsverts " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : JUNIOR_DEVELOPER ) {
2021-12-05 17:54:36 +00:00
//Go tell physics to spawn all the vertices:
2023-07-15 20:56:33 +00:00
auto entities = Game : : entityManager - > GetEntitiesByComponent ( eReplicaComponentType : : PHANTOM_PHYSICS ) ;
2021-12-05 17:54:36 +00:00
for ( auto en : entities ) {
2023-03-04 07:16:37 +00:00
auto phys = static_cast < PhantomPhysicsComponent * > ( en - > GetComponent ( eReplicaComponentType : : PHANTOM_PHYSICS ) ) ;
2021-12-05 17:54:36 +00:00
if ( phys )
phys - > SpawnVertices ( ) ;
}
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " reportproxphys " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : JUNIOR_DEVELOPER ) {
2023-07-15 20:56:33 +00:00
auto entities = Game : : entityManager - > GetEntitiesByComponent ( eReplicaComponentType : : PROXIMITY_MONITOR ) ;
2021-12-05 17:54:36 +00:00
for ( auto en : entities ) {
2023-03-04 07:16:37 +00:00
auto phys = static_cast < ProximityMonitorComponent * > ( en - > GetComponent ( eReplicaComponentType : : PROXIMITY_MONITOR ) ) ;
2021-12-05 17:54:36 +00:00
if ( phys ) {
for ( auto prox : phys - > GetProximitiesData ( ) ) {
if ( ! prox . second ) continue ;
auto sphere = static_cast < dpShapeSphere * > ( prox . second - > GetShape ( ) ) ;
auto pos = prox . second - > GetPosition ( ) ;
2023-11-22 02:04:23 +00:00
LOG ( " Proximity: %s, r: %f, pos: %f, %f, %f " , prox . first . c_str ( ) , sphere - > GetRadius ( ) , pos . x , pos . y , pos . z ) ;
2021-12-05 17:54:36 +00:00
}
}
}
}
2022-01-06 02:52:33 +00:00
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " triggerspawner " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER & & args . size ( ) > = 1 ) {
2023-07-17 22:55:33 +00:00
auto spawners = Game : : zoneManager - > GetSpawnersByName ( args [ 0 ] ) ;
2021-12-05 17:54:36 +00:00
2022-07-28 13:39:57 +00:00
for ( auto * spawner : spawners ) {
2021-12-05 17:54:36 +00:00
spawner - > Spawn ( ) ;
}
2023-07-17 22:55:33 +00:00
spawners = Game : : zoneManager - > GetSpawnersInGroup ( args [ 0 ] ) ;
2021-12-05 17:54:36 +00:00
2022-07-28 13:39:57 +00:00
for ( auto * spawner : spawners ) {
2021-12-05 17:54:36 +00:00
spawner - > Spawn ( ) ;
}
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " reforge " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER & & args . size ( ) > = 2 ) {
2024-02-10 11:05:25 +00:00
const auto baseItem = GeneralUtils : : TryParse < LOT > ( args [ 0 ] ) ;
if ( ! baseItem ) return ;
2021-12-05 17:54:36 +00:00
2024-02-10 11:05:25 +00:00
const auto reforgedItem = GeneralUtils : : TryParse < LOT > ( args [ 1 ] ) ;
if ( ! reforgedItem ) return ;
2021-12-05 17:54:36 +00:00
auto * inventoryComponent = entity - > GetComponent < InventoryComponent > ( ) ;
2024-02-10 11:05:25 +00:00
if ( ! inventoryComponent ) return ;
2021-12-05 17:54:36 +00:00
2022-07-28 13:39:57 +00:00
std : : vector < LDFBaseData * > data { } ;
2024-02-10 11:05:25 +00:00
data . push_back ( new LDFData < int32_t > ( u " reforgedLOT " , reforgedItem . value ( ) ) ) ;
2021-12-05 17:54:36 +00:00
2024-02-10 11:05:25 +00:00
inventoryComponent - > AddItem ( baseItem . value ( ) , 1 , eLootSourceType : : MODERATION , eInventoryType : : INVALID , data ) ;
2021-12-05 17:54:36 +00:00
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " crash " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : OPERATOR ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Crashing... " ) ;
int * badPtr = nullptr ;
* badPtr = 0 ;
return ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " metrics " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2022-07-28 13:39:57 +00:00
for ( const auto variable : Metrics : : GetAllMetrics ( ) ) {
2021-12-05 17:54:36 +00:00
auto * metric = Metrics : : GetMetric ( variable ) ;
2022-07-28 13:39:57 +00:00
if ( metric = = nullptr ) {
2021-12-05 17:54:36 +00:00
continue ;
}
ChatPackets : : SendSystemMessage (
sysAddr ,
2022-01-06 02:52:33 +00:00
GeneralUtils : : ASCIIToUTF16 ( Metrics : : MetricVariableToString ( variable ) ) +
u " : " +
GeneralUtils : : to_u16string ( Metrics : : ToMiliseconds ( metric - > average ) ) +
2021-12-05 17:54:36 +00:00
u " ms "
) ;
}
2022-01-06 02:52:33 +00:00
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage (
sysAddr ,
2023-12-28 04:18:20 +00:00
u " Peak RSS: " + GeneralUtils : : to_u16string ( static_cast < float > ( static_cast < double > ( Metrics : : GetPeakRSS ( ) ) / 1.024e6 ) ) +
2021-12-05 17:54:36 +00:00
u " MB "
) ;
ChatPackets : : SendSystemMessage (
sysAddr ,
2023-12-28 04:18:20 +00:00
u " Current RSS: " + GeneralUtils : : to_u16string ( static_cast < float > ( static_cast < double > ( Metrics : : GetCurrentRSS ( ) ) / 1.024e6 ) ) +
2021-12-05 17:54:36 +00:00
u " MB "
) ;
ChatPackets : : SendSystemMessage (
sysAddr ,
u " Process ID: " + GeneralUtils : : to_u16string ( Metrics : : GetProcessID ( ) )
) ;
return ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " reloadconfig " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
2022-12-04 22:25:58 +00:00
Game : : config - > ReloadConfig ( ) ;
VanityUtilities : : SpawnVanity ( ) ;
2024-01-19 21:12:05 +00:00
dpWorld : : Reload ( ) ;
2023-07-15 20:56:33 +00:00
auto entities = Game : : entityManager - > GetEntitiesByComponent ( eReplicaComponentType : : SCRIPTED_ACTIVITY ) ;
2024-02-10 11:05:25 +00:00
for ( const auto * const entity : entities ) {
auto * const scriptedActivityComponent = entity - > GetComponent < ScriptedActivityComponent > ( ) ;
2022-12-04 22:25:58 +00:00
if ( ! scriptedActivityComponent ) continue ;
scriptedActivityComponent - > ReloadConfig ( ) ;
}
2022-12-21 16:51:27 +00:00
Game : : server - > UpdateMaximumMtuSize ( ) ;
2022-12-06 00:08:47 +00:00
Game : : server - > UpdateBandwidthLimit ( ) ;
2022-12-04 22:25:58 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Successfully reloaded config for world! " ) ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " rollloot " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : OPERATOR & & args . size ( ) > = 3 ) {
2024-02-10 11:05:25 +00:00
const auto lootMatrixIndex = GeneralUtils : : TryParse < uint32_t > ( args [ 0 ] ) ;
if ( ! lootMatrixIndex ) return ;
2021-12-20 10:25:45 +00:00
2024-02-10 11:05:25 +00:00
const auto targetLot = GeneralUtils : : TryParse < uint32_t > ( args [ 1 ] ) ;
if ( ! targetLot ) return ;
const auto loops = GeneralUtils : : TryParse < uint32_t > ( args [ 2 ] ) ;
if ( ! loops ) return ;
2021-12-20 10:25:45 +00:00
uint64_t totalRuns = 0 ;
for ( uint32_t i = 0 ; i < loops ; i + + ) {
while ( true ) {
2024-02-10 11:05:25 +00:00
auto lootRoll = Loot : : RollLootMatrix ( lootMatrixIndex . value ( ) ) ;
2021-12-20 10:25:45 +00:00
totalRuns + = 1 ;
bool doBreak = false ;
for ( const auto & kv : lootRoll ) {
2023-12-28 04:18:20 +00:00
if ( static_cast < uint32_t > ( kv . first ) = = targetLot ) {
2021-12-20 10:25:45 +00:00
doBreak = true ;
}
}
if ( doBreak ) break ;
}
}
std : : u16string message = u " Ran loot drops looking for "
2024-02-10 11:05:25 +00:00
+ GeneralUtils : : to_u16string ( targetLot . value ( ) )
2022-01-06 02:52:33 +00:00
+ u " , "
2024-02-10 11:05:25 +00:00
+ GeneralUtils : : to_u16string ( loops . value ( ) )
2022-01-06 02:52:33 +00:00
+ u " times. It ran "
+ GeneralUtils : : to_u16string ( totalRuns )
2021-12-20 10:25:45 +00:00
+ u " times. Averaging out at "
2024-02-10 11:05:25 +00:00
+ GeneralUtils : : to_u16string ( static_cast < float > ( totalRuns ) / loops . value ( ) ) ;
2021-12-20 10:25:45 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , message ) ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " deleteinven " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER & & args . size ( ) > = 1 ) {
2022-12-18 15:46:04 +00:00
eInventoryType inventoryType = eInventoryType : : INVALID ;
2024-02-10 11:05:25 +00:00
const auto inventoryTypeOptional = GeneralUtils : : TryParse < eInventoryType > ( args [ 0 ] ) ;
if ( ! inventoryTypeOptional ) {
2022-12-18 15:46:04 +00:00
// In this case, we treat the input as a string and try to find it in the reflection list
2023-03-14 12:50:12 +00:00
std : : transform ( args [ 0 ] . begin ( ) , args [ 0 ] . end ( ) , args [ 0 ] . begin ( ) , : : toupper ) ;
2023-10-21 23:31:55 +00:00
LOG ( " looking for inventory %s " , args [ 0 ] . c_str ( ) ) ;
2022-12-18 15:46:04 +00:00
for ( uint32_t index = 0 ; index < NUMBER_OF_INVENTORIES ; index + + ) {
if ( std : : string_view ( args [ 0 ] ) = = std : : string_view ( InventoryType : : InventoryTypeToString ( static_cast < eInventoryType > ( index ) ) ) ) inventoryType = static_cast < eInventoryType > ( index ) ;
}
2024-02-10 11:05:25 +00:00
} else {
inventoryType = inventoryTypeOptional . value ( ) ;
2022-12-18 15:46:04 +00:00
}
if ( inventoryType = = eInventoryType : : INVALID | | inventoryType > = NUMBER_OF_INVENTORIES ) {
ChatPackets : : SendSystemMessage ( sysAddr , u " Invalid inventory provided. " ) ;
return ;
}
auto * inventoryComponent = entity - > GetComponent < InventoryComponent > ( ) ;
if ( ! inventoryComponent ) return ;
auto * inventoryToDelete = inventoryComponent - > GetInventory ( inventoryType ) ;
if ( ! inventoryToDelete ) return ;
inventoryToDelete - > DeleteAllItems ( ) ;
2023-10-21 23:31:55 +00:00
LOG ( " Deleted inventory %s for user %llu " , args [ 0 ] . c_str ( ) , entity - > GetObjectID ( ) ) ;
2022-12-18 15:46:04 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Deleted inventory " + GeneralUtils : : UTF8ToUTF16 ( args [ 0 ] ) ) ;
}
2023-10-09 20:18:51 +00:00
if ( chatCommand = = " castskill " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER & & args . size ( ) > = 1 ) {
auto * skillComponent = entity - > GetComponent < SkillComponent > ( ) ;
2023-11-12 11:53:03 +00:00
if ( skillComponent ) {
2024-02-10 11:05:25 +00:00
const auto skillId = GeneralUtils : : TryParse < uint32_t > ( args [ 0 ] ) ;
2023-10-09 20:18:51 +00:00
2024-02-10 11:05:25 +00:00
if ( ! skillId ) {
2023-10-09 20:18:51 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Error getting skill ID. " ) ;
return ;
} else {
2024-02-10 11:05:25 +00:00
skillComponent - > CastSkill ( skillId . value ( ) , entity - > GetObjectID ( ) , entity - > GetObjectID ( ) ) ;
2023-10-09 20:18:51 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Cast skill " ) ;
}
}
}
if ( chatCommand = = " setskillslot " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER & & args . size ( ) > = 2 ) {
2024-02-10 11:05:25 +00:00
auto * const inventoryComponent = entity - > GetComponent < InventoryComponent > ( ) ;
2023-11-12 11:53:03 +00:00
if ( inventoryComponent ) {
2024-02-10 11:05:25 +00:00
const auto slot = GeneralUtils : : TryParse < BehaviorSlot > ( args [ 0 ] ) ;
if ( ! slot ) {
2023-10-09 20:18:51 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Error getting slot. " ) ;
return ;
} else {
2024-02-10 11:05:25 +00:00
const auto skillId = GeneralUtils : : TryParse < uint32_t > ( args [ 1 ] ) ;
if ( ! skillId ) {
2023-10-09 20:18:51 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Error getting skill. " ) ;
return ;
} else {
2024-02-10 11:05:25 +00:00
if ( inventoryComponent - > SetSkill ( slot . value ( ) , skillId . value ( ) ) ) ChatPackets : : SendSystemMessage ( sysAddr , u " Set skill to slot successfully " ) ;
2023-10-09 20:18:51 +00:00
else ChatPackets : : SendSystemMessage ( sysAddr , u " Set skill to slot failed " ) ;
}
}
}
}
if ( chatCommand = = " setfaction " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER & & args . size ( ) > = 1 ) {
auto * destroyableComponent = entity - > GetComponent < DestroyableComponent > ( ) ;
2023-11-12 11:53:03 +00:00
if ( destroyableComponent ) {
2024-02-10 11:05:25 +00:00
const auto faction = GeneralUtils : : TryParse < int32_t > ( args [ 0 ] ) ;
2023-10-09 20:18:51 +00:00
2024-02-10 11:05:25 +00:00
if ( ! faction ) {
2023-10-09 20:18:51 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Error getting faction. " ) ;
return ;
} else {
2024-02-10 11:05:25 +00:00
destroyableComponent - > SetFaction ( faction . value ( ) ) ;
2023-10-09 20:18:51 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Set faction and updated enemies list " ) ;
}
}
}
if ( chatCommand = = " addfaction " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER & & args . size ( ) > = 1 ) {
auto * destroyableComponent = entity - > GetComponent < DestroyableComponent > ( ) ;
2023-11-12 11:53:03 +00:00
if ( destroyableComponent ) {
2024-02-10 11:05:25 +00:00
const auto faction = GeneralUtils : : TryParse < int32_t > ( args [ 0 ] ) ;
2023-10-09 20:18:51 +00:00
2024-02-10 11:05:25 +00:00
if ( ! faction ) {
2023-10-09 20:18:51 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Error getting faction. " ) ;
return ;
} else {
2024-02-10 11:05:25 +00:00
destroyableComponent - > AddFaction ( faction . value ( ) ) ;
2023-10-09 20:18:51 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Added faction and updated enemies list " ) ;
}
}
}
if ( chatCommand = = " getfactions " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER ) {
auto * destroyableComponent = entity - > GetComponent < DestroyableComponent > ( ) ;
2023-11-12 11:53:03 +00:00
if ( destroyableComponent ) {
2023-10-09 20:18:51 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Friendly factions: " ) ;
for ( const auto entry : destroyableComponent - > GetFactionIDs ( ) ) {
ChatPackets : : SendSystemMessage ( sysAddr , ( GeneralUtils : : to_u16string ( entry ) ) ) ;
}
ChatPackets : : SendSystemMessage ( sysAddr , u " Enemy factions: " ) ;
for ( const auto entry : destroyableComponent - > GetEnemyFactionsIDs ( ) ) {
ChatPackets : : SendSystemMessage ( sysAddr , ( GeneralUtils : : to_u16string ( entry ) ) ) ;
}
}
}
2023-11-22 02:05:15 +00:00
if ( chatCommand = = " setrewardcode " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER & & args . size ( ) = = 1 ) {
2024-02-09 05:40:43 +00:00
auto * cdrewardCodes = CDClientManager : : GetTable < CDRewardCodesTable > ( ) ;
2023-11-22 02:05:15 +00:00
auto id = cdrewardCodes - > GetCodeID ( args [ 0 ] ) ;
if ( id ! = - 1 ) Database : : Get ( ) - > InsertRewardCode ( user - > GetAccountID ( ) , id ) ;
}
2023-03-24 23:16:45 +00:00
if ( chatCommand = = " inspect " & & entity - > GetGMLevel ( ) > = eGameMasterLevel : : DEVELOPER & & args . size ( ) > = 1 ) {
2021-12-05 17:54:36 +00:00
Entity * closest = nullptr ;
std : : u16string ldf ;
bool isLDF = false ;
2024-02-10 11:05:25 +00:00
auto component = GeneralUtils : : TryParse < eReplicaComponentType > ( args [ 0 ] ) ;
if ( ! component ) {
2023-03-04 07:16:37 +00:00
component = eReplicaComponentType : : INVALID ;
2021-12-05 17:54:36 +00:00
2022-08-02 13:56:20 +00:00
ldf = GeneralUtils : : UTF8ToUTF16 ( args [ 0 ] ) ;
2021-12-05 17:54:36 +00:00
isLDF = true ;
}
auto reference = entity - > GetPosition ( ) ;
auto closestDistance = 0.0f ;
2024-02-10 11:05:25 +00:00
const auto candidates = Game : : entityManager - > GetEntitiesByComponent ( component . value ( ) ) ;
2022-01-06 02:52:33 +00:00
2022-07-28 13:39:57 +00:00
for ( auto * candidate : candidates ) {
if ( candidate - > GetLOT ( ) = = 1 | | candidate - > GetLOT ( ) = = 8092 ) {
2021-12-05 17:54:36 +00:00
continue ;
}
2022-07-28 13:39:57 +00:00
if ( isLDF & & ! candidate - > HasVar ( ldf ) ) {
2021-12-05 17:54:36 +00:00
continue ;
}
2022-01-06 02:52:33 +00:00
2024-02-10 11:05:25 +00:00
if ( ! closest ) {
2021-12-05 17:54:36 +00:00
closest = candidate ;
closestDistance = NiPoint3 : : Distance ( candidate - > GetPosition ( ) , reference ) ;
2022-01-06 02:52:33 +00:00
2021-12-05 17:54:36 +00:00
continue ;
}
2022-01-06 02:52:33 +00:00
2021-12-05 17:54:36 +00:00
const auto distance = NiPoint3 : : Distance ( candidate - > GetPosition ( ) , reference ) ;
2022-07-28 13:39:57 +00:00
if ( distance < closestDistance ) {
2021-12-05 17:54:36 +00:00
closest = candidate ;
closestDistance = distance ;
}
}
2024-02-10 11:05:25 +00:00
if ( ! closest ) return ;
2021-12-05 17:54:36 +00:00
2023-07-15 20:56:33 +00:00
Game : : entityManager - > SerializeEntity ( closest ) ;
2021-12-05 17:54:36 +00:00
2024-02-09 05:40:43 +00:00
auto * table = CDClientManager : : GetTable < CDObjectsTable > ( ) ;
2021-12-05 17:54:36 +00:00
const auto & info = table - > GetByID ( closest - > GetLOT ( ) ) ;
std : : stringstream header ;
header < < info . name < < " [ " < < std : : to_string ( info . id ) < < " ] " < < " " < < std : : to_string ( closestDistance ) < < " " < < std : : to_string ( closest - > IsSleeping ( ) ) ;
ChatPackets : : SendSystemMessage ( sysAddr , GeneralUtils : : ASCIIToUTF16 ( header . str ( ) ) ) ;
2022-01-06 02:52:33 +00:00
2022-07-28 13:39:57 +00:00
for ( const auto & pair : closest - > GetComponents ( ) ) {
2021-12-05 17:54:36 +00:00
auto id = pair . first ;
std : : stringstream stream ;
2023-03-04 07:16:37 +00:00
stream < < " Component [ " < < std : : to_string ( static_cast < uint32_t > ( id ) ) < < " ] " ;
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , GeneralUtils : : ASCIIToUTF16 ( stream . str ( ) ) ) ;
}
2022-07-28 13:39:57 +00:00
if ( args . size ( ) > = 2 ) {
if ( args [ 1 ] = = " -m " & & args . size ( ) > = 3 ) {
2024-02-10 11:05:25 +00:00
auto * const movingPlatformComponent = closest - > GetComponent < MovingPlatformComponent > ( ) ;
2021-12-05 17:54:36 +00:00
2024-02-10 11:05:25 +00:00
const auto mValue = GeneralUtils : : TryParse < int32_t > ( args [ 2 ] ) ;
2021-12-05 17:54:36 +00:00
2024-02-10 11:05:25 +00:00
if ( ! movingPlatformComponent | | ! mValue ) return ;
2021-12-05 17:54:36 +00:00
movingPlatformComponent - > SetSerialized ( true ) ;
2024-02-10 11:05:25 +00:00
if ( mValue = = - 1 ) {
2021-12-05 17:54:36 +00:00
movingPlatformComponent - > StopPathing ( ) ;
2022-07-28 13:39:57 +00:00
} else {
2024-02-10 11:05:25 +00:00
movingPlatformComponent - > GotoWaypoint ( mValue . value ( ) ) ;
2021-12-05 17:54:36 +00:00
}
2023-07-15 20:56:33 +00:00
Game : : entityManager - > SerializeEntity ( closest ) ;
2022-07-28 13:39:57 +00:00
} else if ( args [ 1 ] = = " -a " & & args . size ( ) > = 3 ) {
2023-03-20 13:10:52 +00:00
RenderComponent : : PlayAnimation ( closest , args . at ( 2 ) ) ;
2022-07-28 13:39:57 +00:00
} else if ( args [ 1 ] = = " -s " ) {
for ( auto * entry : closest - > GetSettings ( ) ) {
2022-08-02 13:56:20 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , GeneralUtils : : UTF8ToUTF16 ( entry - > GetString ( ) ) ) ;
2021-12-05 17:54:36 +00:00
}
ChatPackets : : SendSystemMessage ( sysAddr , u " ------ " ) ;
ChatPackets : : SendSystemMessage ( sysAddr , u " Spawner ID: " + GeneralUtils : : to_u16string ( closest - > GetSpawnerID ( ) ) ) ;
2022-07-28 13:39:57 +00:00
} else if ( args [ 1 ] = = " -p " ) {
2021-12-05 17:54:36 +00:00
const auto postion = closest - > GetPosition ( ) ;
ChatPackets : : SendSystemMessage (
2022-01-06 02:52:33 +00:00
sysAddr ,
2021-12-05 17:54:36 +00:00
GeneralUtils : : ASCIIToUTF16 ( " < " + std : : to_string ( postion . x ) + " , " + std : : to_string ( postion . y ) + " , " + std : : to_string ( postion . z ) + " > " )
) ;
2022-07-28 13:39:57 +00:00
} else if ( args [ 1 ] = = " -f " ) {
2021-12-05 17:54:36 +00:00
auto * destuctable = closest - > GetComponent < DestroyableComponent > ( ) ;
2022-07-28 13:39:57 +00:00
if ( destuctable = = nullptr ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " No destroyable component on this entity! " ) ;
return ;
}
ChatPackets : : SendSystemMessage ( sysAddr , u " Smashable: " + ( GeneralUtils : : to_u16string ( destuctable - > GetIsSmashable ( ) ) ) ) ;
ChatPackets : : SendSystemMessage ( sysAddr , u " Friendly factions: " ) ;
2022-07-28 13:39:57 +00:00
for ( const auto entry : destuctable - > GetFactionIDs ( ) ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , ( GeneralUtils : : to_u16string ( entry ) ) ) ;
}
ChatPackets : : SendSystemMessage ( sysAddr , u " Enemy factions: " ) ;
2022-07-28 13:39:57 +00:00
for ( const auto entry : destuctable - > GetEnemyFactionsIDs ( ) ) {
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , ( GeneralUtils : : to_u16string ( entry ) ) ) ;
}
2022-07-28 13:39:57 +00:00
if ( args . size ( ) > = 3 ) {
2024-02-10 11:05:25 +00:00
const auto faction = GeneralUtils : : TryParse < int32_t > ( args [ 2 ] ) ;
if ( ! faction ) return ;
2021-12-05 17:54:36 +00:00
destuctable - > SetFaction ( - 1 ) ;
2024-02-10 11:05:25 +00:00
destuctable - > AddFaction ( faction . value ( ) , true ) ;
2021-12-05 17:54:36 +00:00
}
2023-10-09 20:18:51 +00:00
} else if ( args [ 1 ] = = " -cf " ) {
auto * destuctable = entity - > GetComponent < DestroyableComponent > ( ) ;
if ( ! destuctable ) {
ChatPackets : : SendSystemMessage ( sysAddr , u " No destroyable component on this entity! " ) ;
return ;
}
if ( destuctable - > IsEnemy ( closest ) ) ChatPackets : : SendSystemMessage ( sysAddr , u " They are our enemy " ) ;
else ChatPackets : : SendSystemMessage ( sysAddr , u " They are NOT our enemy " ) ;
2022-07-28 13:39:57 +00:00
} else if ( args [ 1 ] = = " -t " ) {
2021-12-05 17:54:36 +00:00
auto * phantomPhysicsComponent = closest - > GetComponent < PhantomPhysicsComponent > ( ) ;
2022-07-28 13:39:57 +00:00
if ( phantomPhysicsComponent ! = nullptr ) {
2023-03-25 10:26:39 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Type: " + ( GeneralUtils : : to_u16string ( static_cast < uint32_t > ( phantomPhysicsComponent - > GetEffectType ( ) ) ) ) ) ;
2021-12-05 17:54:36 +00:00
const auto dir = phantomPhysicsComponent - > GetDirection ( ) ;
2022-07-28 13:39:57 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Direction: < " + ( GeneralUtils : : to_u16string ( dir . x ) ) + u " , " + ( GeneralUtils : : to_u16string ( dir . y ) ) + u " , " + ( GeneralUtils : : to_u16string ( dir . z ) ) + u " > " ) ;
2021-12-05 17:54:36 +00:00
ChatPackets : : SendSystemMessage ( sysAddr , u " Multiplier: " + ( GeneralUtils : : to_u16string ( phantomPhysicsComponent - > GetDirectionalMultiplier ( ) ) ) ) ;
ChatPackets : : SendSystemMessage ( sysAddr , u " Active: " + ( GeneralUtils : : to_u16string ( phantomPhysicsComponent - > GetPhysicsEffectActive ( ) ) ) ) ;
}
2023-02-10 08:29:53 +00:00
auto * triggerComponent = closest - > GetComponent < TriggerComponent > ( ) ;
2023-03-14 12:50:12 +00:00
if ( triggerComponent ) {
2023-02-10 08:29:53 +00:00
auto trigger = triggerComponent - > GetTrigger ( ) ;
if ( trigger ) {
ChatPackets : : SendSystemMessage ( sysAddr , u " Trigger: " + ( GeneralUtils : : to_u16string ( trigger - > id ) ) ) ;
}
2021-12-05 17:54:36 +00:00
}
}
}
}
}
void SlashCommandHandler : : SendAnnouncement ( const std : : string & title , const std : : string & message ) {
AMFArrayValue args ;
2023-05-13 22:22:00 +00:00
args . Insert ( " title " , title ) ;
args . Insert ( " message " , message ) ;
2021-12-05 17:54:36 +00:00
2023-05-13 22:22:00 +00:00
GameMessages : : SendUIMessageServerToAllClients ( " ToggleAnnounce " , args ) ;
2021-12-05 17:54:36 +00:00
2022-01-06 02:52:33 +00:00
//Notify chat about it
2021-12-05 17:54:36 +00:00
CBITSTREAM ;
2023-09-21 01:06:28 +00:00
BitStreamUtils : : WriteHeader ( bitStream , eConnectionType : : CHAT_INTERNAL , eChatInternalMessageType : : ANNOUNCEMENT ) ;
2021-12-05 17:54:36 +00:00
2022-07-17 03:40:46 +00:00
bitStream . Write < uint32_t > ( title . size ( ) ) ;
for ( auto character : title ) {
bitStream . Write < char > ( character ) ;
}
2021-12-05 17:54:36 +00:00
2022-07-17 03:40:46 +00:00
bitStream . Write < uint32_t > ( message . size ( ) ) ;
for ( auto character : message ) {
bitStream . Write < char > ( character ) ;
}
2021-12-05 17:54:36 +00:00
Game : : chatServer - > Send ( & bitStream , SYSTEM_PRIORITY , RELIABLE , 0 , Game : : chatSysAddr , false ) ;
}