#include #include #include #include #include #include #include #include #include "GameConnection.h" #include "Session.h" #include "Zone.h" #include "ZonePosition.h" #include "ServerZone.h" #include "ZoneMgr.h" #include "InitUIPacket.h" #include "PingPacket.h" #include "MoveActorPacket.h" #include "ChatPacket.h" #include "ServerNoticePacket.h" #include "ActorControlPacket142.h" #include "ActorControlPacket143.h" #include "ActorControlPacket144.h" #include "EventStartPacket.h" #include "EventFinishPacket.h" #include "PlayerStateFlagsPacket.h" #include "GameCommandHandler.h" #include "Player.h" #include "Inventory.h" #include "Forwards.h" #include "EventHelper.h" #include "Action.h" #include "ActionTeleport.h" extern Core::Logger g_log; extern Core::Db::Database g_database; extern Core::ServerZone g_serverZone; extern Core::ZoneMgr g_zoneMgr; extern Core::Data::ExdData g_exdData; extern Core::GameCommandHandler g_gameCommandMgr; using namespace Core::Common; using namespace Core::Network::Packets; using namespace Core::Network::Packets::Server; enum GmCommand { Pos = 0x0000, Lv = 0x0001, Race = 0x0002, Tribe = 0x0003, Sex = 0x0004, Time = 0x0005, Weather = 0x0006, Call = 0x0007, Inspect = 0x0008, Speed = 0x0009, Invis = 0x000D, Raise = 0x0010, Kill = 0x000E, Icon = 0x0012, Hp = 0x0064, Mp = 0x0065, Tp = 0x0066, Gp = 0x0067, Item = 0x00C8, Gil = 0x00C9, Collect = 0x00CA, QuestAccept = 0x012C, QuestCancel = 0x012D, QuestComplete = 0x012E, QuestIncomplete = 0x012F, QuestSequence = 0x0130, QuestInspect = 0x0131, GC = 0x0154, GCRank = 0x0155, TeriInfo = 0x025D, Jump = 0x025E, JumpNpc = 0x025F, }; void Core::Network::GameConnection::gm1Handler( const Core::Network::Packets::GamePacket& inPacket, Core::Entity::PlayerPtr pPlayer ) { uint32_t commandId = inPacket.getValAt< uint32_t >( 0x20 ); uint32_t param1 = inPacket.getValAt< uint32_t >( 0x24 ); uint32_t param2 = inPacket.getValAt< uint32_t >( 0x28 ); uint32_t param3 = inPacket.getValAt< uint32_t >( 0x38 ); g_log.debug( pPlayer->getName() + " used GM1 commandId: " + std::to_string( commandId ) + ", params: " + std::to_string( param1 ) + ", " + std::to_string( param2 ) + ", " + std::to_string( param3 ) ); Core::Entity::ActorPtr targetActor; if( pPlayer->getId() == param3 ) { targetActor = pPlayer; } else { auto inRange = pPlayer->getInRangeActors(); for( auto actor : inRange ) { if( actor->getId() == param3 ) targetActor = actor; } } if( !targetActor ) return; auto targetPlayer = targetActor->getAsPlayer(); switch( commandId ) { case GmCommand::Kill: { targetActor->takeDamage( 9999999 ); pPlayer->sendNotice( "Killed " + std::to_string( targetActor->getId() ) ); break; } case GmCommand::QuestSequence: { targetPlayer->updateQuest( param1, param2 ); break; } case GmCommand::QuestComplete: { targetPlayer->finishQuest( param1 ); break; } case GmCommand::QuestAccept: { targetPlayer->updateQuest( param1, 1 ); break; } case GmCommand::QuestCancel: { targetPlayer->removeQuest( param1 ); break; } case GmCommand::QuestIncomplete: { targetPlayer->unfinishQuest( param1 ); break; } case GmCommand::Speed: { targetPlayer->queuePacket( ActorControlPacket143( pPlayer->getId(), Flee, param1 ) ); pPlayer->sendNotice( "Speed for " + targetPlayer->getName() + " was set to " + std::to_string( param1 ) ); break; } case GmCommand::Gil: { targetPlayer->addCurrency( 1, param1 ); pPlayer->sendNotice( "Added " + std::to_string( param1 ) + " Gil for " + targetPlayer->getName() ); break; } case GmCommand::Lv: { targetPlayer->setLevel( param1 ); pPlayer->sendNotice( "Level for " + targetPlayer->getName() + " was set to " + std::to_string( param1 ) ); break; } case GmCommand::Hp: { targetPlayer->setHp( param1 ); pPlayer->sendNotice( "Hp for " + targetPlayer->getName() + " was set to " + std::to_string( param1 ) ); break; } case GmCommand::Mp: { targetPlayer->setMp( param1 ); pPlayer->sendNotice( "Mp for " + targetPlayer->getName() + " was set to " + std::to_string( param1 ) ); break; } case GmCommand::Gp: { targetPlayer->setHp( param1 ); pPlayer->sendNotice( "Gp for " + targetPlayer->getName() + " was set to " + std::to_string( param1 ) ); break; } case GmCommand::Sex: { targetPlayer->setLookAt( CharaLook::Gender, param1 ); pPlayer->sendNotice( "Sex for " + targetPlayer->getName() + " was set to " + std::to_string( param1 ) ); targetPlayer->spawn( targetPlayer ); auto inRange = targetActor->getInRangeActors(); for( auto actor : inRange ) { targetPlayer->despawn( actor->getAsPlayer() ); targetPlayer->spawn( actor->getAsPlayer() ); } break; } case GmCommand::Race: { targetPlayer->setLookAt( CharaLook::Race, param1 ); pPlayer->sendNotice( "Race for " + targetPlayer->getName() + " was set to " + std::to_string( param1 ) ); targetPlayer->spawn( targetPlayer ); auto inRange = targetPlayer->getInRangeActors(); for( auto actor : inRange ) { targetPlayer->despawn( actor->getAsPlayer() ); targetPlayer->spawn( actor->getAsPlayer() ); } break; } case GmCommand::Tribe: { targetPlayer->setLookAt( CharaLook::Tribe, param1 ); pPlayer->sendNotice( "Tribe for " + targetPlayer->getName() + " was set to " + std::to_string( param1 ) ); targetPlayer->spawn( targetPlayer ); auto inRange = targetPlayer->getInRangeActors(); for( auto actor : inRange ) { targetPlayer->despawn( actor->getAsPlayer() ); targetPlayer->spawn( actor->getAsPlayer() ); } break; } case GmCommand::Item: { if( param2 < 1 || param2 > 99 ) { param2 = 1; } if( ( param1 == 0xcccccccc ) ) { pPlayer->sendUrgent( "Syntaxerror." ); return; } if( !targetPlayer->addItem( -1, param1, param2 ) ) pPlayer->sendUrgent( "Item " + std::to_string( param1 ) + " not found..." ); break; } case GmCommand::Weather: { targetPlayer->getCurrentZone()->setWeatherOverride( param1 ); pPlayer->sendNotice( "Weather in Zone \"" + targetPlayer->getCurrentZone()->getName() + "\" of " + targetPlayer->getName() + " set in range." ); break; } case GmCommand::TeriInfo: { pPlayer->sendNotice( "ZoneId: " + std::to_string( pPlayer->getZoneId() ) + "\nName: " + pPlayer->getCurrentZone()->getName() + "\nInternalName: " + pPlayer->getCurrentZone()->getInternalName() + "\nPopCount: " + std::to_string( pPlayer->getCurrentZone()->getPopCount() ) + "\nCurrentWeather:" + std::to_string( pPlayer->getCurrentZone()->getCurrentWeather() ) + "\nNextWeather:" + std::to_string( pPlayer->getCurrentZone()->getNextWeather() ) ); break; } case GmCommand::Jump: { auto inRange = pPlayer->getInRangeActors(); for( auto actor : inRange ) { pPlayer->changePosition( targetActor->getPos().x, targetActor->getPos().y, targetActor->getPos().z, targetActor->getRotation() ); } pPlayer->sendNotice( "Jumping to " + targetPlayer->getName() + " in range." ); break; } case GmCommand::Collect: { uint32_t gil = targetPlayer->getCurrency( 1 ); if( gil < param1 ) { pPlayer->sendUrgent( "Player does not have enough Gil(" + std::to_string( gil ) + ")" ); } else { targetPlayer->removeCurrency( 1, param1 ); pPlayer->sendNotice( "Removed " + std::to_string( param1 ) + " Gil from " + targetPlayer->getName() + "(" + std::to_string( gil ) + " before)" ); } break; } case GmCommand::Icon: { targetPlayer->setOnlineStatusMask( param1 ); GamePacketNew< FFXIVIpcSetOnlineStatus > statusPacket( targetPlayer->getId() ); statusPacket.data().onlineStatusFlags = param1; queueOutPacket( statusPacket ); GamePacketNew< FFXIVIpcSetSearchInfo > searchInfoPacket( targetPlayer->getId() ); searchInfoPacket.data().onlineStatusFlags = param1; searchInfoPacket.data().selectRegion = targetPlayer->getSearchSelectRegion(); sprintf( searchInfoPacket.data().searchMessage, targetPlayer->getSearchMessage() ); targetPlayer->queuePacket( searchInfoPacket ); targetPlayer->sendToInRangeSet( ActorControlPacket142( pPlayer->getId(), SetStatusIcon, static_cast< uint8_t >( pPlayer->getOnlineStatus() ) ), true ); pPlayer->sendNotice( "Icon for " + targetPlayer->getName() + " was set to " + std::to_string( param1 ) ); break; } case GmCommand::GC: { targetPlayer->setGc( param1 ); pPlayer->sendNotice( "GC for " + targetPlayer->getName() + " was set to " + std::to_string( targetPlayer->getGc() ) ); break; } case GmCommand::GCRank: { targetPlayer->setGcRankAt( targetPlayer->getGc() - 1, param1 ); pPlayer->sendNotice( "GC Rank for " + targetPlayer->getName() + " for GC " + std::to_string( targetPlayer->getGc()) + " was set to " + std::to_string( targetPlayer->getGcRankArray()[targetPlayer->getGc() - 1] ) ); break; } default: pPlayer->sendUrgent( "GM1 Command not implemented: " + std::to_string( commandId ) ); break; } } void Core::Network::GameConnection::gm2Handler( const Core::Network::Packets::GamePacket& inPacket, Core::Entity::PlayerPtr pPlayer ) { uint32_t commandId = inPacket.getValAt< uint32_t >( 0x20 ); std::string param1 = inPacket.getStringAt( 0x34 ); g_log.debug( pPlayer->getName() + " used GM2 commandId: " + std::to_string( commandId ) + ", params: " + param1 ); auto targetSession = g_serverZone.getSession( param1 ); Core::Entity::ActorPtr targetActor; if( targetSession != nullptr ) { targetActor = targetSession->getPlayer(); } else { if( param1 == "self" ) { targetActor = pPlayer; } else { pPlayer->sendUrgent("Player " + param1 + " not found on this server."); return; } } if( !targetActor ) return; auto targetPlayer = targetActor->getAsPlayer(); switch( commandId ) { case GmCommand::Raise: { targetPlayer->resetHp(); targetPlayer->resetMp(); targetPlayer->setStatus( Entity::Actor::ActorStatus::Idle ); targetPlayer->setSyncFlag( Status ); targetPlayer->sendToInRangeSet( ActorControlPacket143( pPlayer->getId(), ZoneIn, 0x01, 0x01, 0, 113 ), true ); targetPlayer->sendToInRangeSet( ActorControlPacket142( pPlayer->getId(), SetStatus, static_cast< uint8_t >( Entity::Actor::ActorStatus::Idle ) ), true ); pPlayer->sendNotice( "Raised " + targetPlayer->getName()); break; } case GmCommand::Jump: { if( targetPlayer->getZoneId() != pPlayer->getZoneId() ) { pPlayer->setZone( targetPlayer->getZoneId() ); } pPlayer->changePosition( targetActor->getPos().x, targetActor->getPos().y, targetActor->getPos().z, targetActor->getRotation() ); pPlayer->sendNotice( "Jumping to " + targetPlayer->getName()); break; } case GmCommand::Call: { if( targetPlayer->getZoneId() != pPlayer->getZoneId() ) targetPlayer->setZone( pPlayer->getZoneId() ); targetPlayer->changePosition( pPlayer->getPos().x, pPlayer->getPos().y, pPlayer->getPos().z, pPlayer->getRotation() ); pPlayer->sendNotice( "Calling " + targetPlayer->getName() ); break; } case GmCommand::Inspect: { pPlayer->sendNotice( "Name: " + targetPlayer->getName() + "\nGil: " + std::to_string( targetPlayer->getCurrency( 1 ) ) + "\nZone: " + targetPlayer->getCurrentZone()->getName() + "(" + std::to_string( targetPlayer->getZoneId() ) + ")" + "\nClass: " + std::to_string( targetPlayer->getClass() ) + "\nLevel: " + std::to_string( targetPlayer->getLevel() ) + "\nExp: " + std::to_string( targetPlayer->getExp() ) + "\nSearchMessage: " + targetPlayer->getSearchMessage() + "\nPlayTime: " + std::to_string( targetPlayer->getPlayTime() ) ); break; } default: pPlayer->sendUrgent( "GM2 Command not implemented: " + std::to_string( commandId ) ); break; } }