From d2a8e5dc165e07a7bb95e8dd98b7c7646cead699 Mon Sep 17 00:00:00 2001 From: JeidoUran Date: Sat, 5 Jan 2019 14:50:16 +0100 Subject: [PATCH 1/7] Several GM Commands no longer crashes world.exe if used while a bnpc or an eobj is in range --- .../Network/Handlers/GMCommandHandlers.cpp | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/world/Network/Handlers/GMCommandHandlers.cpp b/src/world/Network/Handlers/GMCommandHandlers.cpp index 2cbb3543..d2c07be3 100644 --- a/src/world/Network/Handlers/GMCommandHandlers.cpp +++ b/src/world/Network/Handlers/GMCommandHandlers.cpp @@ -143,9 +143,11 @@ void Sapphire::Network::GameConnection::gm1Handler( FrameworkPtr pFw, auto inRange = targetPlayer->getInRangeActors(); for( auto actor : inRange ) { - targetPlayer->despawn( actor->getAsPlayer() ); - targetPlayer->spawn( actor->getAsPlayer() ); - } + if( actor->isPlayer() ) + { + targetPlayer->despawn( actor->getAsPlayer() ); + targetPlayer->spawn( actor->getAsPlayer() ); + } break; } case GmCommand::Tribe: @@ -156,8 +158,11 @@ void Sapphire::Network::GameConnection::gm1Handler( FrameworkPtr pFw, auto inRange = targetPlayer->getInRangeActors(); for( auto actor : inRange ) { - targetPlayer->despawn( actor->getAsPlayer() ); - targetPlayer->spawn( actor->getAsPlayer() ); + if( actor->isPlayer() ) + { + targetPlayer->despawn( actor->getAsPlayer() ); + targetPlayer->spawn( actor->getAsPlayer() ); + } } break; } @@ -169,8 +174,11 @@ void Sapphire::Network::GameConnection::gm1Handler( FrameworkPtr pFw, auto inRange = targetActor->getInRangeActors(); for( auto actor : inRange ) { - targetPlayer->despawn( actor->getAsPlayer() ); - targetPlayer->spawn( actor->getAsPlayer() ); + if( actor->isPlayer() ) + { + targetPlayer->despawn( actor->getAsPlayer() ); + targetPlayer->spawn( actor->getAsPlayer() ); + } } break; } @@ -223,8 +231,11 @@ void Sapphire::Network::GameConnection::gm1Handler( FrameworkPtr pFw, for( auto actor : player.getInRangeActors() ) { - player.despawn( actor->getAsPlayer() ); - player.spawn( actor->getAsPlayer() ); + if( actor->isPlayer() ) + { + targetPlayer->despawn( actor->getAsPlayer() ); + targetPlayer->spawn( actor->getAsPlayer() ); + } } break; } From 808adc9f1c50d03340fe2ad23319a8ca26d165c6 Mon Sep 17 00:00:00 2001 From: JeidoUran Date: Sat, 5 Jan 2019 18:50:27 +0100 Subject: [PATCH 2/7] GM Call is now closer to retail behavior --- src/world/Network/Handlers/GMCommandHandlers.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/world/Network/Handlers/GMCommandHandlers.cpp b/src/world/Network/Handlers/GMCommandHandlers.cpp index d2c07be3..3e135eb5 100644 --- a/src/world/Network/Handlers/GMCommandHandlers.cpp +++ b/src/world/Network/Handlers/GMCommandHandlers.cpp @@ -148,6 +148,7 @@ void Sapphire::Network::GameConnection::gm1Handler( FrameworkPtr pFw, targetPlayer->despawn( actor->getAsPlayer() ); targetPlayer->spawn( actor->getAsPlayer() ); } + } break; } case GmCommand::Tribe: @@ -640,9 +641,16 @@ void Sapphire::Network::GameConnection::gm2Handler( FrameworkPtr pFw, player.sendUrgent( "You are unable to call a player while bound to a battle instance." ); return; } - - targetPlayer->setInstance( player.getCurrentZone() ); - + targetPlayer->prepareZoning( player.getZoneId(), true, 1, 0 ); + if( targetPlayer->getCurrentInstance() ) + { + targetPlayer->exitInstance(); + } + if ( targetPlayer->getZoneId() != player.getZoneId() ) + { + targetPlayer->setZone( player.getZoneId() ); + } + targetPlayer->sendToInRangeSet( makeActorControl143( player.getId(), ZoneIn, 0, 0, 0, 0 ) ); targetPlayer->changePosition( player.getPos().x, player.getPos().y, player.getPos().z, player.getRot() ); player.sendNotice( "Calling " + targetPlayer->getName() ); break; From 5d9084c279db2e9c1969c6a1cacfe714dc3016ac Mon Sep 17 00:00:00 2001 From: JeidoUran Date: Sun, 6 Jan 2019 01:47:07 +0100 Subject: [PATCH 3/7] GM Jumping no longer crashes the server if used across instances, and works like GM Call --- src/world/Network/Handlers/GMCommandHandlers.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/world/Network/Handlers/GMCommandHandlers.cpp b/src/world/Network/Handlers/GMCommandHandlers.cpp index 3e135eb5..4e6e7f8e 100644 --- a/src/world/Network/Handlers/GMCommandHandlers.cpp +++ b/src/world/Network/Handlers/GMCommandHandlers.cpp @@ -624,12 +624,26 @@ void Sapphire::Network::GameConnection::gm2Handler( FrameworkPtr pFw, } case GmCommand::Jump: { + player.prepareZoning( targetPlayer->getZoneId(), true, 1, 0 ); + if( player.getCurrentInstance() ) + { + player.exitInstance(); + } + if( targetPlayer->getCurrentInstance() && player.getCurrentInstance() != targetPlayer->getCurrentInstance() ) + { + auto instance = targetPlayer->getCurrentInstance(); + auto pInstanceContent = instance->getAsInstanceContent(); + // Not sure if GMs actually get bound to an instance they jump to on retail. It's mostly here to avoid a crash for now. + pInstanceContent->bindPlayer( player.getId() ); + player.setInstance( targetPlayer->getCurrentInstance() ); + } if( targetPlayer->getZoneId() != player.getZoneId() ) { player.setZone( targetPlayer->getZoneId() ); } player.changePosition( targetActor->getPos().x, targetActor->getPos().y, targetActor->getPos().z, targetActor->getRot() ); + player.sendZoneInPackets( 0x00, 0x00, 0, 0, false ); player.sendNotice( "Jumping to " + targetPlayer->getName() ); break; } @@ -650,8 +664,8 @@ void Sapphire::Network::GameConnection::gm2Handler( FrameworkPtr pFw, { targetPlayer->setZone( player.getZoneId() ); } - targetPlayer->sendToInRangeSet( makeActorControl143( player.getId(), ZoneIn, 0, 0, 0, 0 ) ); targetPlayer->changePosition( player.getPos().x, player.getPos().y, player.getPos().z, player.getRot() ); + targetPlayer->sendZoneInPackets( 0x00, 0x00, 0, 0, false ); player.sendNotice( "Calling " + targetPlayer->getName() ); break; } From 193288929d38de32c90d95c13e6ca1c1456f09d9 Mon Sep 17 00:00:00 2001 From: JeidoUran Date: Sun, 6 Jan 2019 02:03:33 +0100 Subject: [PATCH 4/7] Sending a /tell while acting as a GM will send a GM Tell GM Call was also fixed 3 commits ago, now works on players within instances --- src/common/Network/PacketDef/Chat/ServerChatDef.h | 2 +- src/world/Network/Handlers/PacketHandlers.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/common/Network/PacketDef/Chat/ServerChatDef.h b/src/common/Network/PacketDef/Chat/ServerChatDef.h index e2ebe0ba..955c9bf6 100644 --- a/src/common/Network/PacketDef/Chat/ServerChatDef.h +++ b/src/common/Network/PacketDef/Chat/ServerChatDef.h @@ -21,7 +21,7 @@ struct FFXIVIpcTell : uint16_t u2b; uint8_t preName; uint8_t u3a; - uint8_t u3b; //Setting this to 1 seems to mark the tell as a GM tell (More research needed) + uint8_t u3b; //Setting this to 1 marks the tell as a GM tell char receipientName[32]; char msg[1031]; }; diff --git a/src/world/Network/Handlers/PacketHandlers.cpp b/src/world/Network/Handlers/PacketHandlers.cpp index d737bf8a..91933295 100644 --- a/src/world/Network/Handlers/PacketHandlers.cpp +++ b/src/world/Network/Handlers/PacketHandlers.cpp @@ -656,6 +656,10 @@ void Sapphire::Network::GameConnection::tellHandler( FrameworkPtr pFw, //tellPacket.data().u1 = 0x92CD7337; //tellPacket.data().u2a = 0x2E; //tellPacket.data().u2b = 0x40; + if( player.isActingAsGm() ) + { + tellPacket->data().u3b = 0x01; + } pTargetPlayer->queueChatPacket( tellPacket ); } From a5e6ca82abbfe8fc902e7a1c93db2a4197889671 Mon Sep 17 00:00:00 2001 From: JeidoUran Date: Sun, 6 Jan 2019 04:48:24 +0100 Subject: [PATCH 5/7] Changed 'u3b' to 'isGm' and made it a bool --- src/common/Network/PacketDef/Chat/ServerChatDef.h | 2 +- src/world/Network/Handlers/PacketHandlers.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/Network/PacketDef/Chat/ServerChatDef.h b/src/common/Network/PacketDef/Chat/ServerChatDef.h index 955c9bf6..bbec5794 100644 --- a/src/common/Network/PacketDef/Chat/ServerChatDef.h +++ b/src/common/Network/PacketDef/Chat/ServerChatDef.h @@ -21,7 +21,7 @@ struct FFXIVIpcTell : uint16_t u2b; uint8_t preName; uint8_t u3a; - uint8_t u3b; //Setting this to 1 marks the tell as a GM tell + bool isGm; char receipientName[32]; char msg[1031]; }; diff --git a/src/world/Network/Handlers/PacketHandlers.cpp b/src/world/Network/Handlers/PacketHandlers.cpp index 7034d89a..7e79b963 100644 --- a/src/world/Network/Handlers/PacketHandlers.cpp +++ b/src/world/Network/Handlers/PacketHandlers.cpp @@ -658,7 +658,7 @@ void Sapphire::Network::GameConnection::tellHandler( FrameworkPtr pFw, //tellPacket.data().u2b = 0x40; if( player.isActingAsGm() ) { - tellPacket->data().u3b = 0x01; + tellPacket->data().isGm = true; } pTargetPlayer->queueChatPacket( tellPacket ); From ca3851d7d4b664ede70a213e5644f78c7e604042 Mon Sep 17 00:00:00 2001 From: JeidoUran Date: Sun, 6 Jan 2019 16:25:51 +0100 Subject: [PATCH 6/7] More GM Call/Jump fixes --- .../Network/Handlers/GMCommandHandlers.cpp | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/world/Network/Handlers/GMCommandHandlers.cpp b/src/world/Network/Handlers/GMCommandHandlers.cpp index 3c5e8965..8291d24d 100644 --- a/src/world/Network/Handlers/GMCommandHandlers.cpp +++ b/src/world/Network/Handlers/GMCommandHandlers.cpp @@ -627,17 +627,16 @@ void Sapphire::Network::GameConnection::gm2Handler( FrameworkPtr pFw, { player.exitInstance(); } - if( targetPlayer->getCurrentInstance() && player.getCurrentInstance() != targetPlayer->getCurrentInstance() ) + if( targetPlayer->getCurrentZone()->getGuId() != player.getCurrentZone()->getGuId() ) { - auto instance = targetPlayer->getCurrentInstance(); - auto pInstanceContent = instance->getAsInstanceContent(); - // Not sure if GMs actually get bound to an instance they jump to on retail. It's mostly here to avoid a crash for now. - pInstanceContent->bindPlayer( player.getId() ); - player.setInstance( targetPlayer->getCurrentInstance() ); - } - if( targetPlayer->getZoneId() != player.getZoneId() ) - { - player.setZone( targetPlayer->getZoneId() ); + // Checks if the target player is in an InstanceContent to avoid binding to a Zone or PublicContent + if( targetPlayer->getCurrentInstance() ) + { + auto pInstanceContent = targetPlayer->getCurrentInstance()->getAsInstanceContent(); + // Not sure if GMs actually get bound to an instance they jump to on retail. It's mostly here to avoid a crash for now + pInstanceContent->bindPlayer( player.getId() ); + } + player.setInstance( targetPlayer->getCurrentZone()->getGuId() ); } player.changePosition( targetActor->getPos().x, targetActor->getPos().y, targetActor->getPos().z, targetActor->getRot() ); @@ -658,9 +657,9 @@ void Sapphire::Network::GameConnection::gm2Handler( FrameworkPtr pFw, { targetPlayer->exitInstance(); } - if ( targetPlayer->getZoneId() != player.getZoneId() ) + if( targetPlayer->getCurrentZone()->getGuId() != player.getCurrentZone()->getGuId() ) { - targetPlayer->setZone( player.getZoneId() ); + targetPlayer->setInstance( player.getCurrentZone()->getGuId() ); } targetPlayer->changePosition( player.getPos().x, player.getPos().y, player.getPos().z, player.getRot() ); targetPlayer->sendZoneInPackets( 0x00, 0x00, 0, 0, false ); From 9c90b34c2bd050c9717f597cfef14ab8b55a65e4 Mon Sep 17 00:00:00 2001 From: JeidoUran Date: Sun, 6 Jan 2019 16:32:06 +0100 Subject: [PATCH 7/7] Added prepareZoning research + fixed typo --- src/common/Network/PacketDef/Zone/ServerZoneDef.h | 2 +- src/world/Actor/Player.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index e1f3980e..84ce832d 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -1439,7 +1439,7 @@ struct FFXIVIpcPrepareZoning : uint8_t fadeOut; uint8_t param7; uint8_t fadeOutTime; - uint8_t unknown; + uint8_t unknown; // this changes whether or not the destination zone's name displays during the loading screen. Seems to always be 9 (=hidden) when going to an instance and certain zones, 0 otherwise. uint16_t padding; }; diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index 2009e219..bdfbadc8 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -534,7 +534,7 @@ namespace Sapphire::Entity void teleportQuery( uint16_t aetheryteId, FrameworkPtr pFw ); /*! prepares zoning / fades out the screen */ - void prepareZoning( uint16_t targetZone, bool fadeOut, uint8_t fadoutTime = 0, uint16_t animation = 0 ); + void prepareZoning( uint16_t targetZone, bool fadeOut, uint8_t fadeOutTime = 0, uint16_t animation = 0 ); /*! get player's title list (available titles) */ uint8_t* getTitleList();