mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-23 13:17:45 +00:00
1442 lines
44 KiB
C++
1442 lines
44 KiB
C++
#include <cinttypes>
|
|
|
|
#include <Common.h>
|
|
#include <Version.h>
|
|
#include <Network/GamePacket.h>
|
|
#include <Util/Util.h>
|
|
#include <Util/UtilMath.h>
|
|
#include <Network/PacketContainer.h>
|
|
#include <Logging/Logger.h>
|
|
#include <Exd/ExdData.h>
|
|
#include <Database/DatabaseDef.h>
|
|
#include <cmath>
|
|
#include <Network/PacketWrappers/EffectPacket.h>
|
|
#include <Service.h>
|
|
|
|
#include "DebugCommand/DebugCommand.h"
|
|
#include "DebugCommandMgr.h"
|
|
|
|
#include "Network/PacketWrappers/ServerNoticePacket.h"
|
|
#include "Network/PacketWrappers/ActorControlPacket.h"
|
|
#include "Network/PacketWrappers/ActorControlSelfPacket.h"
|
|
#include "Network/PacketWrappers/PlayerSetupPacket.h"
|
|
#include "Network/PacketWrappers/PlayerSpawnPacket.h"
|
|
#include "Network/GameConnection.h"
|
|
#include "Script/ScriptMgr.h"
|
|
#include "Script/NativeScriptMgr.h"
|
|
|
|
#include "Actor/EventObject.h"
|
|
#include "Actor/BNpc.h"
|
|
|
|
#include "Territory/Territory.h"
|
|
#include "Territory/HousingZone.h"
|
|
#include "Territory/InstanceContent.h"
|
|
#include "Territory/QuestBattle.h"
|
|
#include "Manager/TerritoryMgr.h"
|
|
#include "Manager/PlayerMgr.h"
|
|
#include "Event/EventDefs.h"
|
|
#include "ContentFinder/ContentFinder.h"
|
|
|
|
#include "Manager/LinkshellMgr.h"
|
|
#include "Linkshell/Linkshell.h"
|
|
|
|
#include "Manager/WarpMgr.h"
|
|
|
|
#include "WorldServer.h"
|
|
|
|
#include "Session.h"
|
|
|
|
using namespace Sapphire::Network;
|
|
using namespace Sapphire::Network::Packets;
|
|
using namespace Sapphire::Network::Packets::WorldPackets::Server;
|
|
using namespace Sapphire::World::Manager;
|
|
|
|
// instanciate and initialize commands
|
|
DebugCommandMgr::DebugCommandMgr()
|
|
{
|
|
// Push all commands onto the register map ( command name - function - description - required GM level )
|
|
registerCommand( "set", &DebugCommandMgr::set, "Executes SET commands.", 1 );
|
|
registerCommand( "get", &DebugCommandMgr::get, "Executes GET commands.", 1 );
|
|
registerCommand( "add", &DebugCommandMgr::add, "Executes ADD commands.", 1 );
|
|
registerCommand( "inject", &DebugCommandMgr::injectPacket, "Loads and injects a premade packet.", 1 );
|
|
registerCommand( "injectc", &DebugCommandMgr::injectChatPacket, "Loads and injects a premade chat packet.", 1 );
|
|
registerCommand( "replay", &DebugCommandMgr::replay, "Replays a saved capture folder.", 1 );
|
|
registerCommand( "nudge", &DebugCommandMgr::nudge, "Nudges you forward/up/down.", 1 );
|
|
registerCommand( "info", &DebugCommandMgr::serverInfo, "Show server info.", 0 );
|
|
registerCommand( "help", &DebugCommandMgr::help, "Shows registered commands.", 0 );
|
|
registerCommand( "script", &DebugCommandMgr::script, "Server script utilities.", 1 );
|
|
registerCommand( "instance", &DebugCommandMgr::instance, "Instance utilities", 1 );
|
|
registerCommand( "questbattle", &DebugCommandMgr::questBattle, "Quest battle utilities", 1 );
|
|
registerCommand( "qb", &DebugCommandMgr::questBattle, "Quest battle utilities", 1 );
|
|
registerCommand( "housing", &DebugCommandMgr::housing, "Housing utilities", 1 );
|
|
registerCommand( "linkshell", &DebugCommandMgr::linkshell, "Linkshell creation", 1 );
|
|
registerCommand( "cf", &DebugCommandMgr::contentFinder, "Content-Finder", 1 );
|
|
registerCommand( "ew", &DebugCommandMgr::easyWarp, "Easy warping", 1 );
|
|
}
|
|
|
|
// clear all loaded commands
|
|
DebugCommandMgr::~DebugCommandMgr()
|
|
{
|
|
for( auto it = m_commandMap.begin(); it != m_commandMap.end(); ++it )
|
|
( *it ).second.reset();
|
|
}
|
|
|
|
// add a command set to the register map
|
|
void DebugCommandMgr::registerCommand( const std::string& n, DebugCommand::pFunc functionPtr, const std::string& hText, uint8_t uLevel )
|
|
{
|
|
m_commandMap[ std::string( n ) ] = std::make_shared< DebugCommand >( n, functionPtr, hText, uLevel );
|
|
}
|
|
|
|
// try to retrieve the command in question, execute if found
|
|
void DebugCommandMgr::execCommand( char* data, Entity::Player& player )
|
|
{
|
|
|
|
// define callback pointer
|
|
void ( DebugCommandMgr::*pf )( char*, Entity::Player&, std::shared_ptr< DebugCommand > );
|
|
|
|
std::string commandString;
|
|
|
|
// check if the command has parameters
|
|
std::string tmpCommand = std::string( data );
|
|
std::size_t pos = tmpCommand.find_first_of( " " );
|
|
|
|
if( pos != std::string::npos )
|
|
// command has parameters, grab the first part
|
|
commandString = tmpCommand.substr( 0, pos );
|
|
else
|
|
// no parameters, just get the command
|
|
commandString = tmpCommand;
|
|
|
|
// try to retrieve the command
|
|
auto it = m_commandMap.find( commandString );
|
|
|
|
if( it == m_commandMap.end() )
|
|
// no command found, do something... or not
|
|
PlayerMgr::sendUrgent( player, "Command not found." );
|
|
else
|
|
{
|
|
if( player.getGmRank() < it->second->getRequiredGmLevel() )
|
|
{
|
|
PlayerMgr::sendUrgent( player, "You are not allowed to use this command." );
|
|
return;
|
|
}
|
|
|
|
// command found, call the callback function and pass parameters if present.
|
|
pf = ( *it ).second->m_pFunc;
|
|
( this->*pf )( data, player, ( *it ).second );
|
|
return;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
// Definition of the commands
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void DebugCommandMgr::help( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command )
|
|
{
|
|
PlayerMgr::sendDebug( player, "Registered debug commands:" );
|
|
for( auto cmd : m_commandMap )
|
|
{
|
|
if( player.getGmRank() >= cmd.second->m_gmLevel )
|
|
{
|
|
PlayerMgr::sendDebug( player, " - {0} - {1}", cmd.first, cmd.second->getHelpText() );
|
|
}
|
|
}
|
|
}
|
|
|
|
void DebugCommandMgr::set( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command )
|
|
{
|
|
auto& server = Sapphire::Common::Service< Sapphire::World::WorldServer >::ref();
|
|
auto pSession = server.getSession( player.getCharacterId() );
|
|
auto& terriMgr = Common::Service< TerritoryMgr >::ref();
|
|
auto pCurrentZone = terriMgr.getTerritoryByGuId( player.getTerritoryId() );
|
|
|
|
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
|
std::string subCommand = "";
|
|
std::string params = "";
|
|
|
|
// check if the command has parameters
|
|
std::string tmpCommand = std::string( data + command->getName().length() + 1 );
|
|
|
|
std::size_t pos = tmpCommand.find_first_of( " " );
|
|
|
|
if( pos != std::string::npos )
|
|
// command has parameters, grab the first part
|
|
subCommand = tmpCommand.substr( 0, pos );
|
|
else
|
|
// no subcommand given
|
|
subCommand = tmpCommand;
|
|
|
|
if( command->getName().length() + 1 + pos + 1 < strlen( data ) )
|
|
params = std::string( data + command->getName().length() + 1 + pos + 1 );
|
|
|
|
Logger::debug( "[{0}] subCommand: {1} params: {1}", player.getId(), subCommand, params );
|
|
|
|
if( ( ( subCommand == "pos" ) || ( subCommand == "posr" ) ) && ( params != "" ) )
|
|
{
|
|
int32_t posX;
|
|
int32_t posY;
|
|
int32_t posZ;
|
|
|
|
sscanf( params.c_str(), "%d %d %d", &posX, &posY, &posZ );
|
|
|
|
if( ( posX == 0xcccccccc ) || ( posY == 0xcccccccc ) || ( posZ == 0xcccccccc ) )
|
|
{
|
|
PlayerMgr::sendUrgent( player, "Syntaxerror." );
|
|
return;
|
|
}
|
|
|
|
if( subCommand == "pos" )
|
|
player.setPos( static_cast< float >( posX ),
|
|
static_cast< float >( posY ),
|
|
static_cast< float >( posZ ) );
|
|
else
|
|
player.setPos( player.getPos().x + static_cast< float >( posX ),
|
|
player.getPos().y + static_cast< float >( posY ),
|
|
player.getPos().z + static_cast< float >( posZ ) );
|
|
|
|
auto setActorPosPacket = makeZonePacket< FFXIVIpcWarp >( player.getId() );
|
|
setActorPosPacket->data().x = player.getPos().x;
|
|
setActorPosPacket->data().y = player.getPos().y;
|
|
setActorPosPacket->data().z = player.getPos().z;
|
|
pSession->getZoneConnection()->queueOutPacket( setActorPosPacket );
|
|
|
|
}
|
|
else if( ( subCommand == "tele" ) && ( params != "" ) )
|
|
{
|
|
int32_t aetheryteId;
|
|
sscanf( params.c_str(), "%i", &aetheryteId );
|
|
|
|
player.teleport( static_cast< uint16_t >( aetheryteId ) );
|
|
}
|
|
else if( ( subCommand == "discovery" ) && ( params != "" ) )
|
|
{
|
|
int32_t map_id;
|
|
int32_t discover_id;
|
|
sscanf( params.c_str(), "%i %i", &map_id, &discover_id );
|
|
|
|
auto discoveryPacket = makeZonePacket< FFXIVIpcDiscoveryReply >( player.getId() );
|
|
discoveryPacket->data().mapId = static_cast< uint32_t >( map_id );
|
|
discoveryPacket->data().mapPartId = static_cast< uint32_t >( discover_id );
|
|
pSession->getZoneConnection()->queueOutPacket( discoveryPacket );
|
|
}
|
|
else if( subCommand == "discovery_reset" )
|
|
{
|
|
player.resetDiscovery();
|
|
pSession->getZoneConnection()->queueOutPacket( std::make_shared< PlayerSetupPacket >( player ) );
|
|
}
|
|
else if( subCommand == "classjob" )
|
|
{
|
|
int32_t id;
|
|
|
|
sscanf( params.c_str(), "%d", &id );
|
|
|
|
if( player.getLevelForClass( static_cast< Common::ClassJob > ( id ) ) == 0 )
|
|
{
|
|
player.setLevelForClass( 1, static_cast< Common::ClassJob > ( id ) );
|
|
player.setClassJob( static_cast< Common::ClassJob > ( id ) );
|
|
}
|
|
else
|
|
player.setClassJob( static_cast< Common::ClassJob > ( id ) );
|
|
}
|
|
else if( subCommand == "cfpenalty" )
|
|
{
|
|
int32_t minutes;
|
|
sscanf( params.c_str(), "%d", &minutes );
|
|
|
|
player.setCFPenaltyMinutes( static_cast< uint32_t >( minutes ) );
|
|
}
|
|
else if( subCommand == "eorzeatime" )
|
|
{
|
|
uint64_t timestamp;
|
|
sscanf( params.c_str(), "%" SCNu64, ×tamp );
|
|
|
|
player.setEorzeaTimeOffset( timestamp );
|
|
PlayerMgr::sendServerNotice( player, "Eorzea time offset: {0}", timestamp );
|
|
}
|
|
else if( subCommand == "setMount" )
|
|
{
|
|
int32_t id;
|
|
sscanf( params.c_str(), "%d", &id );
|
|
|
|
player.setMount( 0 );
|
|
player.setMount( static_cast< uint32_t >( id ));
|
|
}
|
|
else if( subCommand == "weatheroverride" || subCommand == "wo" )
|
|
{
|
|
uint32_t weatherId;
|
|
|
|
sscanf( params.c_str(), "%d", &weatherId );
|
|
|
|
pCurrentZone->setWeatherOverride( static_cast< Common::Weather >( weatherId ) );
|
|
}
|
|
else if( subCommand == "festival" )
|
|
{
|
|
uint16_t festivalId;
|
|
uint16_t additionalId;
|
|
|
|
sscanf( params.c_str(), "%hu %hu", &festivalId, &additionalId );
|
|
|
|
terriMgr.setCurrentFestival( festivalId, additionalId );
|
|
}
|
|
else if( subCommand == "festivaldisable" )
|
|
{
|
|
terriMgr.disableCurrentFestival();
|
|
}
|
|
else if( subCommand == "BitFlag" )
|
|
{
|
|
uint16_t questId;
|
|
uint8_t questBit;
|
|
int8_t BitFlag;
|
|
sscanf( params.c_str(), "%hhu %hu %hhu", &BitFlag, &questId, &questBit );
|
|
|
|
|
|
if( !player.hasQuest( questId ) )
|
|
{
|
|
PlayerMgr::sendDebug( player, "Player doesn't have the quest with ID#: {0}", questId );
|
|
return;
|
|
}
|
|
if( questBit == 0 || questId == 0 )
|
|
{
|
|
PlayerMgr::sendDebug( player, "Params are not correct" );
|
|
return;
|
|
}
|
|
|
|
auto questIdx = player.getQuestIndex( questId );
|
|
auto& quest = player.getQuestByIndex( questIdx );
|
|
|
|
switch( BitFlag )
|
|
{
|
|
case 8:
|
|
{
|
|
quest.setBitFlag8( questBit, true );
|
|
break;
|
|
}
|
|
case 16:
|
|
{
|
|
quest.setBitFlag16( questBit, true );
|
|
break;
|
|
}
|
|
case 24:
|
|
{
|
|
quest.setBitFlag24( questBit, true );
|
|
break;
|
|
}
|
|
case 32:
|
|
{
|
|
quest.setBitFlag32( questBit, true );
|
|
break;
|
|
}
|
|
case 40:
|
|
{
|
|
quest.setBitFlag40( questBit, true );
|
|
break;
|
|
}
|
|
case 48:
|
|
{
|
|
quest.setBitFlag48( questBit, true );
|
|
break;
|
|
}
|
|
}
|
|
player.updateQuest( quest );
|
|
}
|
|
else if( subCommand == "mobaggro" )
|
|
{
|
|
auto inRange = player.getInRangeActors();
|
|
|
|
for( auto actor : inRange )
|
|
{
|
|
if( actor->getId() == player.getTargetId() && actor->getAsChara()->isAlive() )
|
|
{
|
|
actor->getAsBNpc()->onActionHostile( player.getAsChara() );
|
|
}
|
|
}
|
|
}
|
|
else if( subCommand == "recastreset" )
|
|
{
|
|
player.resetRecastGroups();
|
|
PlayerMgr::sendDebug( player, "All recast groups cleared." );
|
|
}
|
|
else if( subCommand == "freecompany" )
|
|
{
|
|
auto fcPacket = makeZonePacket< FFXIVIpcFreeCompany >( player.getId() );
|
|
fcPacket->data().Crest = 0x0001000100010001;
|
|
strcpy( fcPacket->data().Tag, "Wang" );
|
|
pSession->getZoneConnection()->queueOutPacket( fcPacket );
|
|
|
|
auto fcResultPacket = makeZonePacket< FFXIVIpcGetFcStatusResult >( player.getId() );
|
|
fcResultPacket->data().FreeCompanyID = 1;
|
|
fcResultPacket->data().AuthorityList = 1;
|
|
fcResultPacket->data().HierarchyType = 1;
|
|
fcResultPacket->data().GrandCompanyID = 1;
|
|
fcResultPacket->data().FcRank = 8;
|
|
fcResultPacket->data().CrestID = 0x0001000100010001;
|
|
pSession->getZoneConnection()->queueOutPacket( fcResultPacket );
|
|
}
|
|
else
|
|
{
|
|
PlayerMgr::sendUrgent( player, "{0} is not a valid SET command.", subCommand );
|
|
}
|
|
|
|
}
|
|
|
|
void DebugCommandMgr::add( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command )
|
|
{
|
|
auto& server = Common::Service< World::WorldServer >::ref();
|
|
auto pSession = server.getSession( player.getCharacterId() );
|
|
auto& terriMgr = Common::Service< TerritoryMgr >::ref();
|
|
auto pCurrentZone = terriMgr.getTerritoryByGuId( player.getTerritoryId() );
|
|
|
|
std::string subCommand;
|
|
std::string params = "";
|
|
|
|
// check if the command has parameters
|
|
std::string tmpCommand = std::string( data + command->getName().length() + 1 );
|
|
|
|
std::size_t pos = tmpCommand.find_first_of( " " );
|
|
|
|
if( pos != std::string::npos )
|
|
// command has parameters, grab the first part
|
|
subCommand = tmpCommand.substr( 0, pos );
|
|
else
|
|
// no subcommand given
|
|
subCommand = tmpCommand;
|
|
|
|
if( command->getName().length() + 1 + pos + 1 < strlen( data ) )
|
|
params = std::string( data + command->getName().length() + 1 + pos + 1 );
|
|
|
|
Logger::debug( "[" + std::to_string( player.getId() ) + "] " +
|
|
"subCommand " + subCommand + " params: " + params );
|
|
|
|
|
|
if( subCommand == "status" )
|
|
{
|
|
int32_t id;
|
|
int32_t duration;
|
|
uint16_t param;
|
|
|
|
sscanf( params.c_str(), "%d %d %hu", &id, &duration, ¶m );
|
|
|
|
auto effect = StatusEffect::make_StatusEffect( id, player.getAsPlayer(), player.getAsPlayer(), duration, 3000 );
|
|
effect->setParam( param );
|
|
|
|
player.addStatusEffect( effect );
|
|
}
|
|
else if( subCommand == "title" )
|
|
{
|
|
uint32_t titleId;
|
|
sscanf( params.c_str(), "%u", &titleId );
|
|
|
|
player.addTitle( static_cast< uint16_t >( titleId ) );
|
|
PlayerMgr::sendServerNotice( player, "Added title (id#{0})", titleId );
|
|
}
|
|
else if( subCommand == "op" )
|
|
{
|
|
// temporary research packet
|
|
int32_t opcode;
|
|
sscanf( params.c_str(), "%x", &opcode );
|
|
// TODO: fix for new setup
|
|
//auto pPe = Network::Packets::make_GamePacket( opcode, 0x30, player.getId(), player.getId() );
|
|
//player.queuePacket( pPe );
|
|
}
|
|
else if( subCommand == "actrl" )
|
|
{
|
|
|
|
// temporary research packet
|
|
|
|
uint32_t opcode;
|
|
uint32_t param1;
|
|
uint32_t param2;
|
|
uint32_t param3;
|
|
uint32_t param4;
|
|
uint32_t param5;
|
|
uint32_t param6;
|
|
uint32_t playerId;
|
|
|
|
sscanf( params.c_str(), "%x %x %x %x %x %x %x %x", &opcode, &playerId, ¶m1,
|
|
¶m2, ¶m3, ¶m4, ¶m5, ¶m6 );
|
|
|
|
PlayerMgr::sendServerNotice( player, "Injecting ACTOR_CONTROL {0}", opcode );
|
|
|
|
auto actorControl = makeZonePacket< FFXIVIpcActorControl >( playerId, playerId );
|
|
actorControl->data().category = static_cast< uint16_t >( opcode );
|
|
actorControl->data().param1 = param1;
|
|
actorControl->data().param2 = param2;
|
|
actorControl->data().param3 = param3;
|
|
actorControl->data().param4 = param4;
|
|
pSession->getZoneConnection()->queueOutPacket( actorControl );
|
|
|
|
|
|
/*sscanf(params.c_str(), "%x %x %x %x %x %x %x", &opcode, ¶m1, ¶m2, ¶m3, ¶m4, ¶m5, ¶m6, &playerId);
|
|
|
|
Network::Packets::Server::ServerNoticePacket noticePacket( player, "Injecting ACTOR_CONTROL " + std::to_string( opcode ) );
|
|
|
|
player.queuePacket( noticePacket );
|
|
|
|
Network::Packets::Server::ActorControlSelfPacket controlPacket( player, opcode,
|
|
param1, param2, param3, param4, param5, param6, playerId );
|
|
player.queuePacket( controlPacket );*/
|
|
|
|
}
|
|
else if( subCommand == "actrls" )
|
|
{
|
|
|
|
// temporary research packet
|
|
|
|
uint32_t opcode;
|
|
uint32_t param1;
|
|
uint32_t param2;
|
|
uint32_t param3;
|
|
uint32_t param4;
|
|
uint32_t param5;
|
|
uint32_t param6;
|
|
uint32_t playerId;
|
|
|
|
sscanf( params.c_str(), "%x %x %x %x %x %x %x %x", &opcode, &playerId, ¶m1,
|
|
¶m2, ¶m3, ¶m4, ¶m5, ¶m6 );
|
|
|
|
PlayerMgr::sendServerNotice( player, "Injecting ACTOR_CONTROL {0}", opcode );
|
|
|
|
auto actorControl = makeZonePacket< FFXIVIpcActorControlSelf >( playerId, playerId );
|
|
actorControl->data().category = static_cast< uint16_t >( opcode );
|
|
actorControl->data().param1 = param1;
|
|
actorControl->data().param2 = param2;
|
|
actorControl->data().param3 = param3;
|
|
actorControl->data().param4 = param4;
|
|
actorControl->data().param5 = param5;
|
|
actorControl->data().param6 = param6;
|
|
pSession->getZoneConnection()->queueOutPacket( actorControl );
|
|
|
|
|
|
/*sscanf(params.c_str(), "%x %x %x %x %x %x %x", &opcode, ¶m1, ¶m2, ¶m3, ¶m4, ¶m5, ¶m6, &playerId);
|
|
|
|
Network::Packets::Server::ServerNoticePacket noticePacket( player, "Injecting ACTOR_CONTROL " + std::to_string( opcode ) );
|
|
|
|
player.queuePacket( noticePacket );
|
|
|
|
Network::Packets::Server::ActorControlSelfPacket controlPacket( player, opcode,
|
|
param1, param2, param3, param4, param5, param6, playerId );
|
|
player.queuePacket( controlPacket );*/
|
|
|
|
}
|
|
else if( subCommand == "unlock" )
|
|
{
|
|
uint32_t id;
|
|
|
|
sscanf( params.c_str(), "%d", &id );
|
|
player.setSystemActionUnlocked( static_cast< Common::UnlockEntry >( id ) );
|
|
}
|
|
else if ( subCommand == "effect")
|
|
{
|
|
uint16_t param1;
|
|
sscanf( params.c_str(), "%hu", ¶m1 );
|
|
|
|
auto effectPacket = std::make_shared< EffectPacket >( player.getId(), param1 );
|
|
effectPacket->setRotation( Common::Util::floatToUInt16Rot( player.getRot() ) );
|
|
effectPacket->setTargetActor( static_cast< uint32_t >( player.getTargetId() ) );
|
|
|
|
Common::CalcResultParam entry{};
|
|
entry.Value = static_cast< int16_t >( param1 );
|
|
entry.Type = Common::ActionEffectType::CALC_RESULT_TYPE_DAMAGE_HP;
|
|
entry.Arg0 = static_cast< uint8_t >( Common::ActionHitSeverityType::NormalDamage );
|
|
|
|
effectPacket->addTargetEffect( entry, static_cast< uint64_t >( player.getId() ) );
|
|
|
|
auto sequence = pCurrentZone->getNextEffectSequence();
|
|
effectPacket->setSequence( sequence );
|
|
|
|
// effectPacket->setAnimationId( param1 );
|
|
// effectPacket->setEffectFlags( 0 );
|
|
|
|
pSession->getZoneConnection()->queueOutPacket( effectPacket );
|
|
}
|
|
else
|
|
{
|
|
PlayerMgr::sendUrgent( player, "{0} is not a valid ADD command.", subCommand );
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void DebugCommandMgr::get( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command )
|
|
{
|
|
auto& exdData = Common::Service< Data::ExdData >::ref();
|
|
std::string subCommand;
|
|
std::string params = "";
|
|
|
|
// check if the command has parameters
|
|
std::string tmpCommand = std::string( data + command->getName().length() + 1 );
|
|
|
|
std::size_t pos = tmpCommand.find_first_of( " " );
|
|
|
|
if( pos != std::string::npos )
|
|
// command has parameters, grab the first part
|
|
subCommand = tmpCommand.substr( 0, pos );
|
|
else
|
|
// no subcommand given
|
|
subCommand = tmpCommand;
|
|
|
|
if( command->getName().length() + 1 + pos + 1 < strlen( data ) )
|
|
params = std::string( data + command->getName().length() + 1 + pos + 1 );
|
|
|
|
Logger::debug( "[{0}] subCommand: {1} params: {2}", player.getId(), subCommand, params );
|
|
|
|
if( ( subCommand == "pos" ) )
|
|
{
|
|
|
|
int16_t map_id = exdData.getRow< Excel::TerritoryType >( player.getTerritoryTypeId() )->data().Map;
|
|
|
|
PlayerMgr::sendServerNotice( player, "Pos:\n {0}\n {1}\n {2}\n {3}\n MapId: {4}\n ZoneId:{5}",
|
|
player.getPos().x, player.getPos().y, player.getPos().z,
|
|
player.getRot(), map_id, player.getTerritoryTypeId() );
|
|
}
|
|
else
|
|
{
|
|
PlayerMgr::sendUrgent( player, "{0} is not a valid GET command.", subCommand );
|
|
}
|
|
|
|
}
|
|
|
|
void DebugCommandMgr::injectPacket( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command )
|
|
{
|
|
auto& server = Common::Service< World::WorldServer >::ref();
|
|
|
|
auto pSession = server.getSession( player.getId() );
|
|
if( pSession )
|
|
pSession->getZoneConnection()->injectPacket( data + 7, player );
|
|
}
|
|
|
|
void DebugCommandMgr::injectChatPacket( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command )
|
|
{
|
|
auto& server = Common::Service< World::WorldServer >::ref();
|
|
|
|
auto pSession = server.getSession( player.getId() );
|
|
if( pSession )
|
|
pSession->getChatConnection()->injectPacket( data + 8, player );
|
|
}
|
|
|
|
void DebugCommandMgr::replay( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command )
|
|
{
|
|
auto& server = Common::Service< World::WorldServer >::ref();
|
|
|
|
std::string subCommand;
|
|
std::string params = "";
|
|
|
|
// check if the command has parameters
|
|
std::string tmpCommand = std::string( data + command->getName().length() + 1 );
|
|
|
|
std::size_t pos = tmpCommand.find_first_of( " " );
|
|
|
|
if( pos != std::string::npos )
|
|
// command has parameters, grab the first part
|
|
subCommand = tmpCommand.substr( 0, pos );
|
|
else
|
|
// no subcommand given
|
|
subCommand = tmpCommand;
|
|
|
|
if( command->getName().length() + 1 + pos + 1 < strlen( data ) )
|
|
params = std::string( data + command->getName().length() + 1 + pos + 1 );
|
|
|
|
Logger::debug( "[" + std::to_string( player.getId() ) + "] " +
|
|
"subCommand " + subCommand + " params: " + params );
|
|
|
|
|
|
if( subCommand == "start" )
|
|
{
|
|
auto pSession = server.getSession( player.getId() );
|
|
if( pSession )
|
|
pSession->startReplay( params );
|
|
}
|
|
else if( subCommand == "stop" )
|
|
{
|
|
auto pSession = server.getSession( player.getId() );
|
|
if( pSession )
|
|
pSession->stopReplay();
|
|
}
|
|
else if( subCommand == "info" )
|
|
{
|
|
auto pSession = server.getSession( player.getId() );
|
|
if( pSession )
|
|
pSession->sendReplayInfo();
|
|
}
|
|
else
|
|
{
|
|
PlayerMgr::sendUrgent( player, "{0} is not a valid replay command.", subCommand );
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void DebugCommandMgr::nudge( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command )
|
|
{
|
|
auto& server = Sapphire::Common::Service< Sapphire::World::WorldServer >::ref();
|
|
auto pSession = server.getSession( player.getCharacterId() );
|
|
|
|
std::string subCommand;
|
|
|
|
// check if the command has parameters
|
|
std::string tmpCommand = std::string( data + command->getName().length() + 1 );
|
|
|
|
std::size_t spos = tmpCommand.find_first_of( " " );
|
|
|
|
auto& pos = player.getPos();
|
|
|
|
int32_t offset = 0;
|
|
char direction[20];
|
|
memset( direction, 0, 20 );
|
|
|
|
sscanf( tmpCommand.c_str(), "%d %s", &offset, direction );
|
|
|
|
if( direction[ 0 ] == 'u' || direction[ 0 ] == '+' )
|
|
{
|
|
pos.y += offset;
|
|
PlayerMgr::sendServerNotice( player, "nudge: Placing up {0} yalms", offset );
|
|
}
|
|
else if( direction[ 0 ] == 'd' || direction[ 0 ] == '-' )
|
|
{
|
|
pos.y -= offset;
|
|
PlayerMgr::sendServerNotice( player, "nudge: Placing down {0} yalms", offset );
|
|
|
|
}
|
|
else
|
|
{
|
|
float angle = player.getRot() + ( PI / 2 );
|
|
pos.x -= offset * cos( angle );
|
|
pos.z += offset * sin( angle );
|
|
PlayerMgr::sendServerNotice( player, "nudge: Placing forward {0} yalms", offset );
|
|
}
|
|
if( offset != 0 )
|
|
{
|
|
auto setActorPosPacket = makeZonePacket< FFXIVIpcWarp >( player.getId() );
|
|
setActorPosPacket->data().x = player.getPos().x;
|
|
setActorPosPacket->data().y = player.getPos().y;
|
|
setActorPosPacket->data().z = player.getPos().z;
|
|
setActorPosPacket->data().Dir = Common::Util::floatToUInt16Rot( player.getRot() );
|
|
pSession->getZoneConnection()->queueOutPacket( setActorPosPacket );
|
|
}
|
|
}
|
|
|
|
void DebugCommandMgr::serverInfo( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command )
|
|
{
|
|
auto& server = Common::Service< World::WorldServer >::ref();
|
|
|
|
PlayerMgr::sendDebug( player, "SapphireZone {0} \nRev: {1}", Version::VERSION, Version::GIT_HASH );
|
|
PlayerMgr::sendDebug( player, "Compiled: " __DATE__ " " __TIME__ );
|
|
PlayerMgr::sendDebug( player, "Sessions: {0}", server.getSessionCount() );
|
|
}
|
|
|
|
void DebugCommandMgr::script( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command )
|
|
{
|
|
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
|
|
std::string subCommand;
|
|
std::string params = "";
|
|
|
|
// check if the command has parameters
|
|
std::string tmpCommand = std::string( data + command->getName().length() + 1 );
|
|
|
|
std::size_t pos = tmpCommand.find_first_of( " " );
|
|
|
|
if( pos != std::string::npos )
|
|
// command has parameters, grab the first part
|
|
subCommand = tmpCommand.substr( 0, pos );
|
|
else
|
|
// no subcommand given
|
|
subCommand = tmpCommand;
|
|
|
|
// todo: fix params so it's empty if there's no params
|
|
if( command->getName().length() + 1 + pos + 1 < strlen( data ) )
|
|
params = std::string( data + command->getName().length() + 1 + pos + 1 );
|
|
|
|
Logger::debug( "[{0}] subCommand: {1} params: {2}", player.getId(), subCommand, params );
|
|
|
|
if( subCommand == "unload" )
|
|
{
|
|
if( subCommand == params )
|
|
PlayerMgr::sendDebug( player, "Command failed: requires name of script" );
|
|
else if( scriptMgr.getNativeScriptHandler().unloadScript( params ) )
|
|
PlayerMgr::sendDebug( player, "Unloaded script successfully." );
|
|
else
|
|
PlayerMgr::sendDebug( player, "Failed to unload script: {0}", params );
|
|
}
|
|
else if( subCommand == "find" || subCommand == "f" )
|
|
{
|
|
if( subCommand == params )
|
|
PlayerMgr::sendDebug( player, "Because reasons of filling chat with nonsense, please enter a search term" );
|
|
else
|
|
{
|
|
std::set< Sapphire::Scripting::ScriptInfo* > scripts;
|
|
scriptMgr.getNativeScriptHandler().findScripts( scripts, params );
|
|
|
|
if( !scripts.empty() )
|
|
{
|
|
PlayerMgr::sendDebug( player, "Found {0} scripts", scripts.size() );
|
|
|
|
for( auto it = scripts.begin(); it != scripts.end(); ++it )
|
|
{
|
|
auto script = *it;
|
|
PlayerMgr::sendDebug( player, " - '{0}', num scripts: {1}", script->library_name, script->scripts.size() );
|
|
}
|
|
}
|
|
else
|
|
PlayerMgr::sendDebug( player, "No scripts found with search term: {0}", params );
|
|
}
|
|
}
|
|
else if( subCommand == "load" || subCommand == "l" )
|
|
{
|
|
if( subCommand == params )
|
|
PlayerMgr::sendDebug( player, "Command failed: requires relative path to script" );
|
|
else
|
|
{
|
|
if( scriptMgr.getNativeScriptHandler().loadScript( params ) )
|
|
PlayerMgr::sendDebug( player, "Loaded '{0}' successfully", params );
|
|
else
|
|
PlayerMgr::sendDebug( player, "Failed to load '{0}'", params );
|
|
}
|
|
|
|
}
|
|
else if( subCommand == "queuereload" || subCommand == "qrl" )
|
|
{
|
|
if( subCommand == params )
|
|
PlayerMgr::sendDebug( player, "Command failed: requires name of script to reload" );
|
|
else
|
|
{
|
|
scriptMgr.getNativeScriptHandler().queueScriptReload( params );
|
|
PlayerMgr::sendDebug( player, "Queued script reload for script: {0}", params );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PlayerMgr::sendDebug( player, "Unknown script subcommand: {0}", subCommand );
|
|
}
|
|
}
|
|
|
|
void DebugCommandMgr::instance( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command )
|
|
{
|
|
auto& terriMgr = Common::Service< TerritoryMgr >::ref();
|
|
auto pCurrentZone = terriMgr.getTerritoryByGuId( player.getTerritoryId() );
|
|
|
|
std::string cmd( data ), params, subCommand;
|
|
auto cmdPos = cmd.find_first_of( ' ' );
|
|
|
|
if( cmdPos != std::string::npos )
|
|
{
|
|
params = cmd.substr( cmdPos + 1 );
|
|
|
|
auto p = params.find_first_of( ' ' );
|
|
|
|
if( p != std::string::npos )
|
|
{
|
|
subCommand = params.substr( 0, p );
|
|
params = params.substr( subCommand.length() + 1 );
|
|
}
|
|
else
|
|
subCommand = params;
|
|
}
|
|
|
|
if( subCommand == "create" || subCommand == "cr" )
|
|
{
|
|
uint32_t contentFinderConditionId;
|
|
sscanf( params.c_str(), "%d", &contentFinderConditionId );
|
|
|
|
auto instance = terriMgr.createInstanceContent( contentFinderConditionId );
|
|
if( instance )
|
|
PlayerMgr::sendDebug( player, "Created instance with id#{0} -> {1}", instance->getGuId(), instance->getName() );
|
|
else
|
|
PlayerMgr::sendDebug( player, "Failed to create instance with id#{0}", contentFinderConditionId );
|
|
}
|
|
else if( subCommand == "bind" )
|
|
{
|
|
uint32_t instanceId;
|
|
sscanf( params.c_str(), "%d", &instanceId );
|
|
|
|
auto terri = terriMgr.getTerritoryByGuId( instanceId );
|
|
if( terri )
|
|
{
|
|
auto pInstanceContent = terri->getAsInstanceContent();
|
|
if( !pInstanceContent )
|
|
{
|
|
PlayerMgr::sendDebug( player, "Instance id#{} is not an InstanceContent territory.", instanceId );
|
|
return;
|
|
}
|
|
|
|
pInstanceContent->bindPlayer( player.getId() );
|
|
PlayerMgr::sendDebug( player,
|
|
"Now bound to instance with id: " + std::to_string( pInstanceContent->getGuId() ) +
|
|
" -> " + pInstanceContent->getName() );
|
|
}
|
|
else
|
|
PlayerMgr::sendDebug( player, "Unknown instance with id#{0}", instanceId );
|
|
}
|
|
else if( subCommand == "unbind" )
|
|
{
|
|
uint32_t instanceId;
|
|
sscanf( params.c_str(), "%d", &instanceId );
|
|
|
|
auto instance = terriMgr.getTerritoryByGuId( instanceId );
|
|
if( !instance )
|
|
{
|
|
PlayerMgr::sendDebug( player, "Unknown instance with id#{0} ", instanceId );
|
|
return;
|
|
}
|
|
|
|
auto pInstanceContent = instance->getAsInstanceContent();
|
|
if( pInstanceContent->isPlayerBound( player.getId() ) )
|
|
{
|
|
pInstanceContent->unbindPlayer( player.getId() );
|
|
PlayerMgr::sendDebug( player, "Now unbound from instance with id#{0} -> {1}", pInstanceContent->getGuId(), pInstanceContent->getName() );
|
|
}
|
|
else
|
|
PlayerMgr::sendDebug( player, "Player not bound to instance with id#{0}", instanceId );
|
|
|
|
}
|
|
else if( subCommand == "createzone" || subCommand == "crz" )
|
|
{
|
|
uint32_t zoneId;
|
|
sscanf( params.c_str(), "%d", &zoneId );
|
|
|
|
auto instance = terriMgr.createTerritoryInstance( zoneId );
|
|
if( instance )
|
|
PlayerMgr::sendDebug( player,
|
|
"Created instance with id: " + std::to_string( instance->getGuId() ) + " -> " + instance->getName() );
|
|
else
|
|
PlayerMgr::sendDebug( player, "Failed to create instance with id#{0}", zoneId );
|
|
}
|
|
else if( subCommand == "remove" || subCommand == "rm" )
|
|
{
|
|
uint32_t terriId;
|
|
sscanf( params.c_str(), "%d", &terriId );
|
|
|
|
if( terriMgr.removeTerritoryInstance( terriId ) )
|
|
PlayerMgr::sendDebug( player, "Removed instance with id#{0}", terriId );
|
|
else
|
|
PlayerMgr::sendDebug( player, "Failed to remove instance with id#{0}", terriId );
|
|
}
|
|
else if( subCommand == "return" || subCommand == "ret" )
|
|
{
|
|
player.exitInstance();
|
|
}
|
|
else if( subCommand == "stringendomode" || subCommand == "sm" )
|
|
{
|
|
uint32_t mode;
|
|
sscanf( params.c_str(), "%d", &mode );
|
|
if( mode < 5 )
|
|
{
|
|
auto instance = std::dynamic_pointer_cast< InstanceContent >( pCurrentZone );
|
|
if( !instance )
|
|
return;
|
|
|
|
instance->sendStringendoMode( mode );
|
|
}
|
|
}
|
|
else if( subCommand == "todo" )
|
|
{
|
|
auto instance = std::dynamic_pointer_cast< InstanceContent >( pCurrentZone );
|
|
if( !instance )
|
|
return;
|
|
|
|
instance->sendInvalidateTodoList();
|
|
|
|
PlayerMgr::sendDebug( player, "sendInvalidateTodoList executed!" );
|
|
}
|
|
else if( subCommand == "time" )
|
|
{
|
|
auto instance = std::dynamic_pointer_cast< InstanceContent >( pCurrentZone );
|
|
if( !instance )
|
|
return;
|
|
|
|
uint32_t time;
|
|
sscanf( params.c_str(), "%d", &time );
|
|
|
|
instance->setExpireValue( time );
|
|
|
|
PlayerMgr::sendDebug( player, "Content timer updated!" );
|
|
}
|
|
else if( subCommand == "fail" )
|
|
{
|
|
auto instance = std::dynamic_pointer_cast< InstanceContent >( pCurrentZone );
|
|
if( !instance )
|
|
return;
|
|
|
|
uint8_t reason;
|
|
sscanf( params.c_str(), "%hhu", &reason );
|
|
|
|
instance->terminate( reason );
|
|
}
|
|
else if( subCommand == "set" )
|
|
{
|
|
uint32_t index;
|
|
uint32_t value;
|
|
sscanf( params.c_str(), "%d %d", &index, &value );
|
|
|
|
|
|
auto instance = std::dynamic_pointer_cast< InstanceContent >( pCurrentZone );
|
|
if( !instance )
|
|
return;
|
|
|
|
instance->setVar( static_cast< uint8_t >( index ), static_cast< uint8_t >( value ) );
|
|
}
|
|
else if( subCommand == "objstate" )
|
|
{
|
|
char objName[128];
|
|
uint8_t state;
|
|
|
|
sscanf( params.c_str(), "%s %hhu", objName, &state );
|
|
|
|
auto instance = std::dynamic_pointer_cast< InstanceContent >( pCurrentZone );
|
|
if( !instance )
|
|
return;
|
|
|
|
auto obj = instance->getEObjByName( objName );
|
|
if( !obj )
|
|
return;
|
|
|
|
obj->setState( state );
|
|
}
|
|
else if( subCommand == "objflag" )
|
|
{
|
|
char objName[256];
|
|
uint32_t state1;
|
|
uint32_t state2;
|
|
|
|
sscanf( params.c_str(), "%s %i %i", objName, &state1, &state2 );
|
|
|
|
auto instance = std::dynamic_pointer_cast< InstanceContent >( pCurrentZone );
|
|
if( !instance )
|
|
return;
|
|
|
|
auto obj = instance->getEObjByName( objName );
|
|
if( !obj )
|
|
{
|
|
PlayerMgr::sendDebug( player, "No eobj found." );
|
|
return;
|
|
}
|
|
|
|
obj->setAnimationFlag( state1, state2 );
|
|
}
|
|
else if( subCommand == "seq" )
|
|
{
|
|
uint8_t seq;
|
|
|
|
sscanf( params.c_str(), "%hhu", &seq );
|
|
|
|
auto instance = std::dynamic_pointer_cast< InstanceContent >( pCurrentZone );
|
|
if( !instance )
|
|
return;
|
|
|
|
instance->setSequence( seq );
|
|
}
|
|
else if( subCommand == "flags" )
|
|
{
|
|
uint8_t flags;
|
|
|
|
sscanf( params.c_str(), "%hhu", &flags );
|
|
|
|
auto instance = std::dynamic_pointer_cast< InstanceContent >( pCurrentZone );
|
|
if( !instance )
|
|
return;
|
|
|
|
instance->setFlags( flags );
|
|
}
|
|
else if( subCommand == "qte_start" )
|
|
{
|
|
auto instance = std::dynamic_pointer_cast< InstanceContent >( pCurrentZone );
|
|
if( !instance )
|
|
return;
|
|
|
|
PlayerMgr::sendDebug( player, "qte start" );
|
|
instance->startQte();
|
|
}
|
|
else if( subCommand == "event_start" )
|
|
{
|
|
auto instance = std::dynamic_pointer_cast< InstanceContent >( pCurrentZone );
|
|
if( !instance )
|
|
return;
|
|
|
|
PlayerMgr::sendDebug( player, "evt start" );
|
|
instance->startEventCutscene();
|
|
}
|
|
else if( subCommand == "event_end" )
|
|
{
|
|
auto instance = std::dynamic_pointer_cast< InstanceContent >( pCurrentZone );
|
|
if( !instance )
|
|
return;
|
|
|
|
PlayerMgr::sendDebug( player, "evt end" );
|
|
instance->endEventCutscene();
|
|
}
|
|
else if( subCommand == "bgm" )
|
|
{
|
|
uint16_t bgmId;
|
|
sscanf( params.c_str(), "%hd", &bgmId );
|
|
|
|
if( auto instance = pCurrentZone->getAsInstanceContent() )
|
|
instance->setCurrentBGM( bgmId );
|
|
}
|
|
else
|
|
{
|
|
PlayerMgr::sendDebug( player, "Unknown sub command." );
|
|
}
|
|
}
|
|
|
|
void DebugCommandMgr::questBattle( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command )
|
|
{
|
|
auto& terriMgr = Common::Service< TerritoryMgr >::ref();
|
|
auto pCurrentZone = terriMgr.getTerritoryByGuId( player.getTerritoryId() );
|
|
std::string cmd( data ), params, subCommand;
|
|
auto cmdPos = cmd.find_first_of( ' ' );
|
|
|
|
if( cmdPos != std::string::npos )
|
|
{
|
|
params = cmd.substr( cmdPos + 1 );
|
|
|
|
auto p = params.find_first_of( ' ' );
|
|
|
|
if( p != std::string::npos )
|
|
{
|
|
subCommand = params.substr( 0, p );
|
|
params = params.substr( subCommand.length() + 1 );
|
|
}
|
|
else
|
|
subCommand = params;
|
|
}
|
|
|
|
if( subCommand == "create" || subCommand == "cr" )
|
|
{
|
|
uint32_t contentFinderConditionId;
|
|
sscanf( params.c_str(), "%d", &contentFinderConditionId );
|
|
|
|
auto instance = terriMgr.createQuestBattle( contentFinderConditionId );
|
|
if( instance )
|
|
PlayerMgr::sendDebug( player, "Created instance with id#{0} -> {1}", instance->getGuId(), instance->getName() );
|
|
else
|
|
PlayerMgr::sendDebug( player, "Failed to create instance with id#{0}", contentFinderConditionId );
|
|
}
|
|
else if( subCommand == "complete" )
|
|
{
|
|
|
|
auto instance = std::dynamic_pointer_cast< QuestBattle >( pCurrentZone );
|
|
if( !instance )
|
|
return;
|
|
|
|
instance->success();
|
|
|
|
}
|
|
else if( subCommand == "fail" )
|
|
{
|
|
|
|
auto instance = std::dynamic_pointer_cast< QuestBattle >( pCurrentZone );
|
|
if( !instance )
|
|
return;
|
|
|
|
instance->fail();
|
|
|
|
}
|
|
else if( subCommand == "createzone" || subCommand == "crz" )
|
|
{
|
|
uint32_t zoneId;
|
|
sscanf( params.c_str(), "%d", &zoneId );
|
|
|
|
auto instance = terriMgr.createTerritoryInstance( zoneId );
|
|
if( instance )
|
|
PlayerMgr::sendDebug( player,
|
|
"Created instance with id: " + std::to_string( instance->getGuId() ) + " -> " + instance->getName() );
|
|
else
|
|
PlayerMgr::sendDebug( player, "Failed to create instance with id#{0}", zoneId );
|
|
}
|
|
else if( subCommand == "remove" || subCommand == "rm" )
|
|
{
|
|
uint32_t terriId;
|
|
sscanf( params.c_str(), "%d", &terriId );
|
|
|
|
if( terriMgr.removeTerritoryInstance( terriId ) )
|
|
PlayerMgr::sendDebug( player, "Removed instance with id#{0}", terriId );
|
|
else
|
|
PlayerMgr::sendDebug( player, "Failed to remove instance with id#{0}", terriId );
|
|
}
|
|
else if( subCommand == "return" || subCommand == "ret" )
|
|
{
|
|
player.exitInstance();
|
|
}
|
|
else if( subCommand == "set" )
|
|
{
|
|
uint32_t index;
|
|
uint32_t value;
|
|
sscanf( params.c_str(), "%d %d", &index, &value );
|
|
|
|
|
|
auto instance = std::dynamic_pointer_cast< QuestBattle >( pCurrentZone );
|
|
if( !instance )
|
|
return;
|
|
|
|
instance->setVar( static_cast< uint8_t >( index ), static_cast< uint8_t >( value ) );
|
|
}
|
|
else if( subCommand == "objstate" )
|
|
{
|
|
char objName[128];
|
|
uint8_t state;
|
|
|
|
sscanf( params.c_str(), "%s %hhu", objName, &state );
|
|
|
|
auto instance = std::dynamic_pointer_cast< QuestBattle >( pCurrentZone );
|
|
if( !instance )
|
|
return;
|
|
|
|
auto obj = instance->getEObjByName( objName );
|
|
if( !obj )
|
|
return;
|
|
|
|
obj->setState( state );
|
|
}
|
|
else if( subCommand == "objflag" )
|
|
{
|
|
char objName[256];
|
|
uint32_t state1;
|
|
uint32_t state2;
|
|
|
|
sscanf( params.c_str(), "%s %i %i", objName, &state1, &state2 );
|
|
|
|
auto instance = std::dynamic_pointer_cast< QuestBattle >( pCurrentZone );
|
|
if( !instance )
|
|
return;
|
|
|
|
auto obj = instance->getEObjByName( objName );
|
|
if( !obj )
|
|
{
|
|
PlayerMgr::sendDebug( player, "No eobj found." );
|
|
return;
|
|
}
|
|
|
|
obj->setAnimationFlag( state1, state2 );
|
|
}
|
|
else if( subCommand == "seq" )
|
|
{
|
|
uint8_t seq;
|
|
|
|
sscanf( params.c_str(), "%hhu", &seq );
|
|
|
|
auto instance = std::dynamic_pointer_cast< QuestBattle >( pCurrentZone );
|
|
if( !instance )
|
|
return;
|
|
|
|
instance->setSequence( seq );
|
|
}
|
|
else if( subCommand == "flags" )
|
|
{
|
|
uint8_t flags;
|
|
|
|
sscanf( params.c_str(), "%hhu", &flags );
|
|
|
|
auto instance = std::dynamic_pointer_cast< QuestBattle >( pCurrentZone );
|
|
if( !instance )
|
|
return;
|
|
|
|
instance->setFlags( flags );
|
|
}
|
|
else if( subCommand == "qte_start" )
|
|
{
|
|
auto instance = std::dynamic_pointer_cast< QuestBattle >( pCurrentZone );
|
|
if( !instance )
|
|
return;
|
|
|
|
PlayerMgr::sendDebug( player, "qte start" );
|
|
instance->startQte();
|
|
}
|
|
else if( subCommand == "event_start" )
|
|
{
|
|
auto instance = std::dynamic_pointer_cast< QuestBattle >( pCurrentZone );
|
|
if( !instance )
|
|
return;
|
|
|
|
PlayerMgr::sendDebug( player, "evt start" );
|
|
instance->startEventCutscene();
|
|
}
|
|
else if( subCommand == "event_end" )
|
|
{
|
|
auto instance = std::dynamic_pointer_cast< QuestBattle >( pCurrentZone );
|
|
if( !instance )
|
|
return;
|
|
|
|
PlayerMgr::sendDebug( player, "evt end" );
|
|
instance->endEventCutscene();
|
|
}
|
|
else if( subCommand == "bgm" )
|
|
{
|
|
uint16_t bgmId;
|
|
sscanf( params.c_str(), "%hd", &bgmId );
|
|
|
|
if( auto instance = pCurrentZone->getAsInstanceContent() )
|
|
instance->setCurrentBGM( bgmId );
|
|
}
|
|
else
|
|
{
|
|
PlayerMgr::sendDebug( player, "Unknown sub command." );
|
|
}
|
|
}
|
|
|
|
void DebugCommandMgr::housing( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command )
|
|
{
|
|
auto& terriMgr = Common::Service< TerritoryMgr >::ref();
|
|
std::string cmd( data ), params, subCommand;
|
|
auto cmdPos = cmd.find_first_of( ' ' );
|
|
|
|
if( cmdPos != std::string::npos )
|
|
{
|
|
params = cmd.substr( cmdPos + 1 );
|
|
|
|
auto p = params.find_first_of( ' ' );
|
|
|
|
if( p != std::string::npos )
|
|
{
|
|
subCommand = params.substr( 0, p );
|
|
params = params.substr( subCommand.length() + 1 );
|
|
}
|
|
else
|
|
subCommand = params;
|
|
}
|
|
|
|
// if( subCommand == "permission" || subCommand == "perm" )
|
|
// {
|
|
// uint8_t permissionSet;
|
|
// sscanf( params.c_str(), "%hhu", &permissionSet );
|
|
//
|
|
// if ( permissionSet < 5 )
|
|
// {
|
|
// auto pZone = teriMgr.getTerritoryFromGuid( player.getTerritoryId() );
|
|
// if( terriMgr.isHousingTerritory( pZone->getTerritoryTypeId() ) )
|
|
// {
|
|
// auto pHousing = std::dynamic_pointer_cast< HousingZone >( pZone );
|
|
// if( pHousing )
|
|
// {
|
|
// // todo: wat?
|
|
// Common::LandIdent ident {};
|
|
// ident.wardNum = pHousing->getWardNum();
|
|
// ident.territoryTypeId = pHousing->getTerritoryTypeId();
|
|
//
|
|
// player.setLandFlags( permissionSet, 0, pHousing->getLandSetId(), ident );
|
|
// player.sendLandFlags();
|
|
// }
|
|
// else
|
|
// PlayerMgr::sendDebug( player, "You aren't in a housing Territory." );
|
|
// }
|
|
// }
|
|
// else
|
|
// PlayerMgr::sendDebug( player, "PermissionSet out of range." );
|
|
// }
|
|
else
|
|
{
|
|
PlayerMgr::sendDebug( player, "Unknown sub command." );
|
|
}
|
|
}
|
|
|
|
void DebugCommandMgr::linkshell( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command )
|
|
{
|
|
auto& terriMgr = Common::Service< TerritoryMgr >::ref();
|
|
std::string cmd( data ), params, subCommand;
|
|
auto cmdPos = cmd.find_first_of( ' ' );
|
|
|
|
if( cmdPos != std::string::npos )
|
|
{
|
|
params = cmd.substr( cmdPos + 1 );
|
|
|
|
auto p = params.find_first_of( ' ' );
|
|
|
|
if( p != std::string::npos )
|
|
{
|
|
subCommand = params.substr( 0, p );
|
|
params = params.substr( subCommand.length() + 1 );
|
|
}
|
|
else
|
|
subCommand = params;
|
|
}
|
|
|
|
if( subCommand != "" )
|
|
{
|
|
auto lsName = subCommand;
|
|
|
|
auto& lsMgr = Common::Service< Manager::LinkshellMgr >::ref();
|
|
|
|
auto lsPtr = lsMgr.createLinkshell( lsName, player );
|
|
|
|
PlayerMgr::sendDebug( player, "Created LS name " + lsPtr->getName() + " ID: " + std::to_string( lsPtr->getId() ) );
|
|
}
|
|
}
|
|
|
|
void DebugCommandMgr::contentFinder( char *data, Sapphire::Entity::Player &player, std::shared_ptr< DebugCommand > command )
|
|
{
|
|
auto& cf = Common::Service< ContentFinder >::ref();
|
|
|
|
std::string cmd( data ), params, subCommand;
|
|
auto cmdPos = cmd.find_first_of( ' ' );
|
|
|
|
if( cmdPos != std::string::npos )
|
|
{
|
|
params = cmd.substr( cmdPos + 1 );
|
|
|
|
auto p = params.find_first_of( ' ' );
|
|
|
|
if( p != std::string::npos )
|
|
{
|
|
subCommand = params.substr( 0, p );
|
|
params = params.substr( subCommand.length() + 1 );
|
|
}
|
|
else
|
|
subCommand = params;
|
|
}
|
|
|
|
if( subCommand == "pop" )
|
|
{
|
|
uint32_t registerId;
|
|
sscanf( params.c_str(), "%d", ®isterId );
|
|
|
|
auto content = cf.findContentByRegisterId( registerId );
|
|
if( !content )
|
|
{
|
|
PlayerMgr::sendDebug( player, "Content for registerId#{0} not found!", registerId );
|
|
return;
|
|
}
|
|
content->setState( QueuedContentState::MatchingComplete );
|
|
}
|
|
|
|
}
|
|
|
|
void DebugCommandMgr::easyWarp( char* data, Sapphire::Entity::Player& player, std::shared_ptr< DebugCommand > command )
|
|
{
|
|
std::string subCommand;
|
|
std::string params = "";
|
|
|
|
// check if the command has parameters
|
|
std::string tmpCommand = std::string( data + command->getName().length() + 1 );
|
|
|
|
std::size_t pos = tmpCommand.find_first_of( " " );
|
|
|
|
if( pos != std::string::npos )
|
|
// command has parameters, grab the first part
|
|
subCommand = tmpCommand.substr( 0, pos );
|
|
else
|
|
// no subcommand given
|
|
subCommand = tmpCommand;
|
|
|
|
if( command->getName().length() + 1 + pos + 1 < strlen( data ) )
|
|
params = std::string( data + command->getName().length() + 1 + pos + 1 );
|
|
|
|
Logger::debug( "[{0}] subCommand: {1} params: {2}", player.getId(), subCommand, params );
|
|
|
|
auto& terriMgr = Common::Service< TerritoryMgr >::ref();
|
|
auto& warpMgr = Common::Service< WarpMgr >::ref();
|
|
|
|
if( ( subCommand == "waking_sands" ) )
|
|
warpMgr.requestMoveTerritory( player, Common::WarpType::WARP_TYPE_GM, terriMgr.getZoneByTerritoryTypeId( 140 )->getGuId(), { -483.257f, 17.0748f, -386.731f }, 1.61298f );
|
|
else if( subCommand == "rising_stones" )
|
|
warpMgr.requestMoveTerritory( player, Common::WarpType::WARP_TYPE_GM, terriMgr.getZoneByTerritoryTypeId( 156 )->getGuId(), { 22.2674f, 21.2527f, -634.261f }, -0.369245f );
|
|
else if( subCommand == "little_solace" )
|
|
warpMgr.requestMoveTerritory( player, Common::WarpType::WARP_TYPE_GM, terriMgr.getZoneByTerritoryTypeId( 152 )->getGuId(), { 24.557f, -3.78776f, 212.615f }, 2.59117f );
|
|
else if( subCommand == "adders_nest" )
|
|
warpMgr.requestMoveTerritory( player, Common::WarpType::WARP_TYPE_GM, terriMgr.getZoneByTerritoryTypeId( 132 )->getGuId(), {-64.7448f, -0.503434f, 2.21786f }, -2.64096f );
|
|
else if( subCommand == "hall_of_flames" )
|
|
warpMgr.requestMoveTerritory( player, Common::WarpType::WARP_TYPE_GM, terriMgr.getZoneByTerritoryTypeId( 130 )->getGuId(), { -129.24f, 4.1f, -93.5221f }, -2.30172f );
|
|
else
|
|
PlayerMgr::sendUrgent( player, "{0} is not a valid easyWarp location.", subCommand );
|
|
}
|