Merge branch 'master' into master

This commit is contained in:
Gray
2024-03-15 07:57:29 -04:00
committed by GitHub
39 changed files with 1348 additions and 240 deletions

View File

@@ -4,11 +4,6 @@
#include "GameplayAbilitySpec.h"
#include "AttributeSet.h"
struct PadHex10 { char Pad[0x10]; };
struct PadHex18 { char Pad[0x18]; };
struct PadHexA8 { char Pad[0xA8]; };
struct PadHexB0 { char Pad[0xB0]; };
// using FPredictionKey = PadHex18;
// using FGameplayEventData = PadHexA8;

View File

@@ -205,6 +205,28 @@ bool AActor::IsPendingKillPending()
return IsActorBeingDestroyed() || !IsValidChecked(this);
}
UObject* AActor::AddComponentByClass(UClass* Class)
{
struct
{
UClass* Class;
bool bManualAttachment;
FTransform RelativeTransform;
bool bDeferredFinish;
UObject* ReturnValue;
} params;
params.Class = Class;
params.bManualAttachment = false;
params.RelativeTransform = FTransform();
params.bDeferredFinish = true;
static UFunction* AddComp = FindObject<UFunction>("/Script/Engine.Actor:AddComponentByClass");
this->ProcessEvent(AddComp, &params);
return params.ReturnValue;
}
float& AActor::GetNetUpdateFrequency()
{
static auto NetUpdateFrequencyOffset = GetOffset("NetUpdateFrequency");

View File

@@ -48,6 +48,7 @@ public:
void ForceNetUpdate();
bool IsNetStartupActor();
bool IsPendingKillPending();
UObject* AddComponentByClass(UClass* Class);
float& GetNetUpdateFrequency();
float& GetMinNetUpdateFrequency();
const AActor* GetNetOwner() const;

View File

@@ -26,9 +26,17 @@ public:
return this->ReadBitfieldValue(bAlreadySearchedOffset, bAlreadySearchedFieldMask);
}
FVector& GetLootSpawnLocation_Athena()
FVector/*&*/ GetLootSpawnLocation_Athena()
{
static auto LootSpawnLocation_AthenaOffset = this->GetOffset("LootSpawnLocation_Athena");
static auto LootSpawnLocation_AthenaOffset = this->GetOffset("LootSpawnLocation_Athena", false);
if (LootSpawnLocation_AthenaOffset == -1)
{
static auto LootSpawnLocationOffset = this->GetOffset("LootSpawnLocation", false);
// return this->Get<FVector>(LootSpawnLocationOffset);
return FVector();
}
return this->Get<FVector>(LootSpawnLocation_AthenaOffset);
}

View File

@@ -55,7 +55,7 @@ public:
)
{
SetNetDormancy((ENetDormancy)(2 - (NewEditingPlayer != 0)));
// they do something here
this->ForceNetUpdate();
GetEditingPlayer() = NewEditingPlayer;
}
}

View File

@@ -4,7 +4,7 @@
void AFortWeap_EditingTool::OnRep_EditActor()
{
static auto OnRep_EditActorFn = FindObject<UFunction>("/Script/FortniteGame.FortWeap_EditingTool.OnRep_EditActor");
static auto OnRep_EditActorFn = FindObject<UFunction>(L"/Script/FortniteGame.FortWeap_EditingTool.OnRep_EditActor");
this->ProcessEvent(OnRep_EditActorFn);
}

View File

@@ -22,5 +22,14 @@ public:
void OnRep_EditActor();
void SetEditActor(ABuildingSMActor* EditActor)
{
// if (HasAuthority())
{
GetEditActor() = EditActor;
OnRep_EditActor();
}
}
static UClass* StaticClass();
};

View File

@@ -23,5 +23,11 @@ public:
return ((PlaceholderBitfield*)(__int64(this) + BitfieldOffset))->Third;
}
class UNetConnection*& GetConnection()
{
static auto ConnectionOffset = GetOffset("Connection");
return *(UNetConnection**)(__int64(this) + ConnectionOffset);
}
int32 IsNetReady(bool Saturate);
};

View File

@@ -14,4 +14,10 @@ void AController::Possess(class APawn* Pawn)
{
auto PossessFn = FindFunction("Possess");
this->ProcessEvent(PossessFn, &Pawn);
}
void AController::UnPossess()
{
auto UnPossessFn = FindFunction("UnPossess");
this->ProcessEvent(UnPossessFn);
}

View File

@@ -7,6 +7,7 @@ class AController : public AActor
public:
AActor* GetViewTarget();
void Possess(class APawn* Pawn);
void UnPossess();
FName& GetStateName()
{

View File

@@ -27,6 +27,8 @@ UFortWeaponItemDefinition* AFortAthenaVehicle::GetVehicleWeaponForSeat(int SeatI
static auto WeaponSeatDefinitionsOffset = WeaponComponent->GetOffset("WeaponSeatDefinitions");
auto& WeaponSeatDefinitions = WeaponComponent->Get<TArray<__int64>>(WeaponSeatDefinitionsOffset);
// VehicleWeaponDefinition = *(UFortWeaponItemDefinition**)(__int64(WeaponSeatDefinitions.at(SeatIdx)) + VehicleWeaponOffset);
for (int i = 0; i < WeaponSeatDefinitions.Num(); i++)
{
auto WeaponSeat = WeaponSeatDefinitions.AtPtr(i, WeaponSeatDefinitionStructSize);

View File

@@ -67,6 +67,8 @@ static UFortPlaylistAthena* GetPlaylistToUse()
if (Globals::bCreative)
Playlist = FindObject<UFortPlaylistAthena>(L"/Game/Athena/Playlists/Creative/Playlist_PlaygroundV2.Playlist_PlaygroundV2");
// Playlist = FindObject<UFortPlaylistAthena>(L"/Game/Athena/Playlists/Respawn/Variants/Respawn_Vamp/Playlist_Respawn_Vamp_Solo.Playlist_Respawn_Vamp_Solo");
return Playlist;
}
@@ -468,6 +470,12 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
// SpawnIsland->RepData->Soemthing = FoundationSetup->LobbyLocation;
}
if (Fortnite_Version == 14.60 && Globals::bGoingToPlayEvent)
{
// Auto with SetDynamicFoundationEnabled
// ShowFoundation(FindObject<AActor>(L"/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.Lobby_Foundation3")); // Aircraft Carrier
}
if (Fortnite_Version == 12.41)
{
ShowFoundation(FindObject<AActor>("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.LF_Athena_POI_19x19_2"));
@@ -596,12 +604,16 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
}
}
if (Fortnite_Version == 14.60 && Globals::bGoingToPlayEvent)
{
ShowFoundation(FindObject<AActor>(L"/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.Lobby_Foundation3")); // Aircraft Carrier
}
AActor* TheBlock = nullptr;
auto TheBlock = FindObject<AActor>(L"/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.SLAB_2"); // SLAB_3 is blank
if (Fortnite_Version > 10) // todo only checked on 10.40
{
TheBlock = FindObject<AActor>(L"/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.SLAB_4");
}
else
{
TheBlock = FindObject<AActor>(L"/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.SLAB_2"); // SLAB_3 is blank
}
if (TheBlock)
ShowFoundation(TheBlock);
@@ -933,6 +945,10 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
WorldNamesToStreamAllFoundationsIn.push_back("/Temp/Game/Athena/Maps/POI/Athena_POI_CommunityPark_003_M_5c711338");
}
static auto PawnClass = FindObject<UClass>(L"/Game/Athena/PlayerPawn_Athena.PlayerPawn_Athena_C");
static auto DefaultPawnClassOffset = GameMode->GetOffset("DefaultPawnClass");
GameMode->Get<UClass*>(DefaultPawnClassOffset) = PawnClass; // I think it would be better if we didn't talk about this.
if (WorldNamesToStreamAllFoundationsIn.size() > 0)
{
auto ObjectNum = ChunkedObjects ? ChunkedObjects->Num() : UnchunkedObjects ? UnchunkedObjects->Num() : 0;
@@ -963,6 +979,13 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
}
}
static auto ReplicationDriverOffset = GetWorld()->GetNetDriver()->GetOffset("ReplicationDriver", false); // If netdriver is null the world blows up
Globals::bShouldUseReplicationGraph = (!(ReplicationDriverOffset == -1 || Fortnite_Version >= 20))
&& Fortnite_Version != 3.3; // RepGraph is half implemented
LOG_INFO(LogDev, "bShouldUseReplicationGraph: {}", Globals::bShouldUseReplicationGraph);
Globals::bStartedListening = true;
}
@@ -1133,7 +1156,7 @@ int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint
}
}
LOG_INFO(LogTeams, "Spreading Teams {} [{}] Player is going on team {} with {} members.", bShouldSpreadTeams, TeamsNum, NextTeamIndex, CurrentTeamMembers);
LOG_INFO(LogTeams, "Spreading Teams {} Player is going on team {}/{} with {} members.", bShouldSpreadTeams, NextTeamIndex, TeamsNum, CurrentTeamMembers);
CurrentTeamMembers++;
@@ -1429,7 +1452,8 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
}
}
NewPlayer->GetMatchReport() = (UAthenaPlayerMatchReport*)UGameplayStatics::SpawnObject(UAthenaPlayerMatchReport::StaticClass(), NewPlayer); // idk when to do this
if (auto MatchReportPtr = NewPlayer->GetMatchReport())
*MatchReportPtr = (UAthenaPlayerMatchReport*)UGameplayStatics::SpawnObject(UAthenaPlayerMatchReport::StaticClass(), NewPlayer); // idk when to do this
static auto SquadIdOffset = PlayerStateAthena->GetOffset("SquadId", false);

View File

@@ -26,7 +26,15 @@ void AFortPickup::SpawnMovementComponent()
static auto ProjectileMovementComponentClass = FindObject<UClass>("/Script/Engine.ProjectileMovementComponent"); // UFortProjectileMovementComponent
static auto MovementComponentOffset = this->GetOffset("MovementComponent");
this->Get(MovementComponentOffset) = UGameplayStatics::SpawnObject(ProjectileMovementComponentClass, this);
if (auto NewComponent = UGameplayStatics::SpawnObject(ProjectileMovementComponentClass, this))
{
this->Get(MovementComponentOffset) = NewComponent;
}
else
{
}
}
AFortPickup* AFortPickup::SpawnPickup(PickupCreateData& PickupData)

View File

@@ -429,9 +429,6 @@ void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame*
static auto ReceivingActorOffset = FindOffsetStruct(StructName, "ReceivingActor");
auto ReceivingActor = *(AActor**)(__int64(Params) + ReceivingActorOffset);
static auto InteractionBeingAttemptedOffset = FindOffsetStruct(StructName, "InteractionBeingAttempted");
auto InteractionBeingAttempted = *(EInteractionBeingAttempted*)(__int64(Params) + InteractionBeingAttemptedOffset);
// LOG_INFO(LogInteraction, "ReceivingActor: {}", __int64(ReceivingActor));
if (!ReceivingActor)
@@ -499,54 +496,30 @@ void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame*
if (!WorldInventory)
return;
auto NewAndModifiedInstances = WorldInventory->AddItem(VehicleWeaponDefinition, nullptr);
auto NewAndModifiedInstances = WorldInventory->AddItem(VehicleWeaponDefinition, nullptr, 1, 9999);
auto NewVehicleInstance = NewAndModifiedInstances.first[0];
if (!NewVehicleInstance)
return;
WorldInventory->Update();
static auto FortItemEntrySize = FFortItemEntry::GetStructSize();
auto VehicleWeapon = Pawn->EquipWeaponDefinition(VehicleWeaponDefinition, NewVehicleInstance->GetItemEntry()->GetItemGuid());
// PlayerController->ServerExecuteInventoryItemHook(PlayerController, newitem->GetItemEntry()->GetItemGuid());
auto& ReplicatedEntries = WorldInventory->GetItemList().GetReplicatedEntries();
/* static auto GetSeatWeaponComponentFn = FindObject<UFunction>("/Script/FortniteGame.FortAthenaVehicle.GetSeatWeaponComponent");
if (GetSeatWeaponComponentFn)
for (int i = 0; i < ReplicatedEntries.Num(); i++)
{
struct { int SeatIndex; UObject* ReturnValue; } AFortAthenaVehicle_GetSeatWeaponComponent_Params{};
auto ReplicatedEntry = ReplicatedEntries.AtPtr(i, FortItemEntrySize);
Vehicle->ProcessEvent(GetSeatWeaponComponentFn, &AFortAthenaVehicle_GetSeatWeaponComponent_Params);
UObject* WeaponComponent = AFortAthenaVehicle_GetSeatWeaponComponent_Params.ReturnValue;
if (!WeaponComponent)
return;
static auto WeaponSeatDefinitionStructSize = FindObject<UClass>("/Script/FortniteGame.WeaponSeatDefinition")->GetPropertiesSize();
static auto VehicleWeaponOffset = FindOffsetStruct("/Script/FortniteGame.WeaponSeatDefinition", "VehicleWeapon");
static auto SeatIndexOffset = FindOffsetStruct("/Script/FortniteGame.WeaponSeatDefinition", "SeatIndex");
static auto WeaponSeatDefinitionsOffset = WeaponComponent->GetOffset("WeaponSeatDefinitions");
auto& WeaponSeatDefinitions = WeaponComponent->Get<TArray<__int64>>(WeaponSeatDefinitionsOffset);
for (int i = 0; i < WeaponSeatDefinitions.Num(); ++i)
if (ReplicatedEntry->GetItemGuid() == NewVehicleInstance->GetItemEntry()->GetItemGuid())
{
auto WeaponSeat = WeaponSeatDefinitions.AtPtr(i, WeaponSeatDefinitionStructSize);
WorldInventory->GetItemList().MarkItemDirty(ReplicatedEntry);
WorldInventory->GetItemList().MarkItemDirty(NewVehicleInstance->GetItemEntry());
WorldInventory->HandleInventoryLocalUpdate();
if (*(int*)(__int64(WeaponSeat) + SeatIndexOffset) != Vehicle->FindSeatIndex(Pawn))
continue;
auto VehicleGrantedWeaponItem = (TWeakObjectPtr<UFortItem>*)(__int64(WeaponSeat) + 0x20);
VehicleGrantedWeaponItem->ObjectIndex = NewVehicleInstance->InternalIndex;
VehicleGrantedWeaponItem->ObjectSerialNumber = GetItemByIndex(NewVehicleInstance->InternalIndex)->SerialNumber;
static auto bWeaponEquippedOffset = WeaponComponent->GetOffset("bWeaponEquipped");
WeaponComponent->Get<bool>(bWeaponEquippedOffset) = true;
break;
PlayerController->ServerExecuteInventoryItemHook(PlayerController, NewVehicleInstance->GetItemEntry()->GetItemGuid());
}
} */
}
return;
}
@@ -554,6 +527,9 @@ void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame*
{
if (Engine_Version >= 424 && Fortnite_Version < 15 && ReceivingActor->GetFullName().contains("Wumba"))
{
static auto InteractionBeingAttemptedOffset = FindOffsetStruct(StructName, "InteractionBeingAttempted");
auto InteractionBeingAttempted = *(EInteractionBeingAttempted*)(__int64(Params) + InteractionBeingAttemptedOffset);
bool bIsSidegrading = InteractionBeingAttempted == EInteractionBeingAttempted::SecondInteraction ? true : false;
LOG_INFO(LogDev, "bIsSidegrading: {}", (bool)bIsSidegrading);
@@ -776,7 +752,7 @@ void AFortPlayerController::ServerAttemptAircraftJumpHook(AFortPlayerController*
{
if (false)
{
// honestly idk why this doesnt work
// honestly idk why this doesnt work ( ithink its suppsoed to be spectator)
auto NAME_Inactive = UKismetStringLibrary::Conv_StringToName(L"NAME_Inactive");
@@ -858,8 +834,8 @@ void AFortPlayerController::ServerCreateBuildingActorHook(UObject* Context, FFra
{
auto PlayerController = (AFortPlayerController*)Context;
if (!PlayerController) // ??
return ServerCreateBuildingActorOriginal(Context, Stack, Ret);
// if (!PlayerController) // ??
// return ServerCreateBuildingActorOriginal(Context, Stack, Ret);
auto WorldInventory = PlayerController->GetWorldInventory();
@@ -886,7 +862,7 @@ void AFortPlayerController::ServerCreateBuildingActorHook(UObject* Context, FFra
bMirrored = CreateBuildingData->bMirrored;
static auto BroadcastRemoteClientInfoOffset = PlayerController->GetOffset("BroadcastRemoteClientInfo");
auto BroadcastRemoteClientInfo = PlayerController->Get(BroadcastRemoteClientInfoOffset);
UObject* BroadcastRemoteClientInfo = PlayerController->Get(BroadcastRemoteClientInfoOffset);
static auto RemoteBuildableClassOffset = BroadcastRemoteClientInfo->GetOffset("RemoteBuildableClass");
BuildingClass = BroadcastRemoteClientInfo->Get<UClass*>(RemoteBuildableClassOffset);
@@ -909,7 +885,7 @@ void AFortPlayerController::ServerCreateBuildingActorHook(UObject* Context, FFra
if (!BuildingClass)
return ServerCreateBuildingActorOriginal(Context, Stack, Ret);
auto GameState = Cast<AFortGameStateAthena>(((AFortGameMode*)GetWorld()->GetGameMode())->GetGameState());
auto GameState = Cast<AFortGameStateAthena>(Cast<AFortGameMode>(GetWorld()->GetGameMode(), false)->GetGameState(), false);
auto StructuralSupportSystem = GameState->GetStructuralSupportSystem();
@@ -954,20 +930,28 @@ void AFortPlayerController::ServerCreateBuildingActorHook(UObject* Context, FFra
auto MatDefinition = UFortKismetLibrary::K2_GetResourceItemDefinition(BuildingActor->GetResourceType());
auto MatInstance = WorldInventory->FindItemInstance(MatDefinition);
bool bBuildFree = PlayerController->DoesBuildFree();
// LOG_INFO(LogDev, "MatInstance->GetItemEntry()->GetCount(): {}", MatInstance->GetItemEntry()->GetCount());
int MinimumMaterial = 10;
bool bShouldDestroy = MatInstance && MatInstance->GetItemEntry() ? MatInstance->GetItemEntry()->GetCount() < MinimumMaterial : true;
if (bShouldDestroy && !bBuildFree)
if (!bBuildFree)
{
ExistingBuildings.Free();
BuildingActor->SilentDie();
return ServerCreateBuildingActorOriginal(Context, Stack, Ret);
int MaterialCost = 10;
UFortItem* MatInstance = WorldInventory->FindItemInstance(MatDefinition);
if (!MatInstance || MatInstance->GetItemEntry()->GetCount() < MaterialCost)
{
ExistingBuildings.Free();
BuildingActor->SilentDie();
return ServerCreateBuildingActorOriginal(Context, Stack, Ret);
}
bool bShouldUpdate = false;
WorldInventory->RemoveItem(MatInstance->GetItemEntry()->GetItemGuid(), &bShouldUpdate, MaterialCost);
if (bShouldUpdate)
WorldInventory->Update();
}
for (int i = 0; i < ExistingBuildings.Num(); ++i)
@@ -983,15 +967,6 @@ void AFortPlayerController::ServerCreateBuildingActorHook(UObject* Context, FFra
BuildingActor->InitializeBuildingActor(PlayerController, BuildingActor, true);
BuildingActor->SetTeam(PlayerStateAthena->GetTeamIndex()); // required?
if (!bBuildFree)
{
bool bShouldUpdate = false;
WorldInventory->RemoveItem(MatInstance->GetItemEntry()->GetItemGuid(), &bShouldUpdate, 10);
if (bShouldUpdate)
WorldInventory->Update();
}
/*
GET_PLAYLIST(GameState);
@@ -1290,7 +1265,7 @@ DWORD WINAPI SpectateThread(LPVOID PC)
Sleep(3000);
LOG_INFO(LogDev, "bugha!");
LOG_INFO(LogDev, "Spectate!");
SpectatingPC->SpectateOnDeath();
@@ -1346,6 +1321,18 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
DeathCause = ToDeathCause(Tags, false, DeadPawn); // DeadPawn->IsDBNO() ??
FGameplayTagContainer CopyTags;
for (int i = 0; i < Tags.GameplayTags.Num(); ++i)
{
CopyTags.GameplayTags.Add(Tags.GameplayTags.at(i));
}
for (int i = 0; i < Tags.ParentTags.Num(); ++i)
{
CopyTags.ParentTags.Add(Tags.ParentTags.at(i));
}
LOG_INFO(LogDev, "DeathCause: {}", (int)DeathCause);
LOG_INFO(LogDev, "DeadPawn->IsDBNO(): {}", DeadPawn->IsDBNO());
LOG_INFO(LogDev, "KillerPlayerState: {}", __int64(KillerPlayerState));
@@ -1358,7 +1345,7 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
*(FVector*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::DeathLocation) = DeathLocation;
if (MemberOffsets::DeathInfo::DeathTags != -1)
*(FGameplayTagContainer*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::DeathTags) = Tags;
*(FGameplayTagContainer*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::DeathTags) = CopyTags;
if (MemberOffsets::DeathInfo::bInitialized != -1)
*(bool*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::bInitialized) = true;
@@ -1630,7 +1617,7 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
if (IsRestartingSupported() && Globals::bAutoRestart && !bIsInAutoRestart)
{
// wtf
// wht
if (GameState->GetGamePhase() > EAthenaGamePhase::Warmup)
{
@@ -1670,6 +1657,22 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
return ClientOnPawnDiedOriginal(PlayerController, DeathReport);
}
bool Idk(ABuildingSMActor* BuildingActor)
{
return true; // bIsPlayerBuildable && EditModeSupport && EditModePatternData && GameState->StructuralSupportSystem && ?? && ??
}
bool IsOkForEditing(ABuildingSMActor* BuildingActor, AFortPlayerController* Controller)
{
if (BuildingActor->GetEditingPlayer() &&
BuildingActor->GetEditingPlayer() != Controller->GetPlayerState())
return false;
return !BuildingActor->IsDestroyed() &&
// BuildingActor->GetWorld() &&
Idk(BuildingActor);
}
void AFortPlayerController::ServerBeginEditingBuildingActorHook(AFortPlayerController* PlayerController, ABuildingSMActor* BuildingActorToEdit)
{
if (!BuildingActorToEdit || !BuildingActorToEdit->IsPlayerPlaced()) // We need more checks.
@@ -1680,6 +1683,9 @@ void AFortPlayerController::ServerBeginEditingBuildingActorHook(AFortPlayerContr
if (!Pawn)
return;
if (!IsOkForEditing(BuildingActorToEdit, PlayerController))
return;
auto PlayerState = PlayerController->GetPlayerState();
if (!PlayerState)
@@ -1699,15 +1705,18 @@ void AFortPlayerController::ServerBeginEditingBuildingActorHook(AFortPlayerContr
if (!EditToolInstance)
return;
Pawn->EquipWeaponDefinition(EditToolDef, EditToolInstance->GetItemEntry()->GetItemGuid());
AFortWeap_EditingTool* EditTool = nullptr;
auto EditTool = Cast<AFortWeap_EditingTool>(Pawn->GetCurrentWeapon());
#if 1
EditTool = Cast<AFortWeap_EditingTool>(Pawn->EquipWeaponDefinition(EditToolDef, EditToolInstance->GetItemEntry()->GetItemGuid()));
#else
EditTool = Cast<AFortWeap_EditingTool>(Pawn->GetCurrentWeapon());
#endif
if (!EditTool)
return;
EditTool->GetEditActor() = BuildingActorToEdit;
EditTool->OnRep_EditActor();
EditTool->SetEditActor(BuildingActorToEdit);
}
void AFortPlayerController::ServerEditBuildingActorHook(UObject* Context, FFrame& Stack, void* Ret)
@@ -1740,7 +1749,7 @@ void AFortPlayerController::ServerEditBuildingActorHook(UObject* Context, FFrame
// if (!PlayerState || PlayerState->GetTeamIndex() != BuildingActorToEdit->GetTeamIndex())
//return ServerEditBuildingActorOriginal(Context, Frame, Ret);
BuildingActorToEdit->SetEditingPlayer(nullptr);
// BuildingActorToEdit->SetEditingPlayer(nullptr); // uh?
static ABuildingSMActor* (*BuildingSMActorReplaceBuildingActor)(ABuildingSMActor*, __int64, UClass*, int, int, uint8_t, AFortPlayerController*) =
decltype(BuildingSMActorReplaceBuildingActor)(Addresses::ReplaceBuildingActor);
@@ -1774,21 +1783,33 @@ void AFortPlayerController::ServerEndEditingBuildingActorHook(AFortPlayerControl
if (!WorldInventory)
return;
AFortWeap_EditingTool* EditTool = nullptr;
#if 1
auto EditToolInstance = WorldInventory->FindItemInstance(EditToolDef);
if (!EditToolInstance)
return;
Pawn->EquipWeaponDefinition(EditToolDef, EditToolInstance->GetItemEntry()->GetItemGuid());
FGuid EditToolGuid = EditToolInstance->GetItemEntry()->GetItemGuid(); // Should we ref?
auto EditTool = Cast<AFortWeap_EditingTool>(Pawn->GetCurrentWeapon());
BuildingActorToStopEditing->GetEditingPlayer() = nullptr;
// BuildingActorToStopEditing->OnRep_EditingPlayer();
#if 1
EditTool = Cast<AFortWeap_EditingTool>(Pawn->EquipWeaponDefinition(EditToolDef, EditToolGuid)); // ERM
#else
Cast<AFortWeap_EditingTool>(Pawn->EquipWeaponDefinition(EditToolDef, EditToolGuid)); // ERM
EditTool = Cast<AFortWeap_EditingTool>(Pawn->GetCurrentWeapon());
#endif
#else
EditTool = Cast<AFortWeap_EditingTool>(Pawn->GetCurrentWeapon());
#endif
if (EditTool)
{
EditTool->GetEditActor() = nullptr;
EditTool->OnRep_EditActor();
static auto bEditConfirmedOffset = EditTool->GetOffset("bEditConfirmed");
if (bEditConfirmedOffset != -1)
EditTool->Get<bool>(bEditConfirmedOffset) = true; // this probably does nothing on server
EditTool->SetEditActor(nullptr);
}
}

View File

@@ -131,6 +131,10 @@ public:
FFortAthenaLoadout* GetCosmeticLoadout()
{
static auto CosmeticLoadoutPCOffset = GetCosmeticLoadoutOffset();
if (CosmeticLoadoutPCOffset == -1)
return nullptr;
auto CosmeticLoadout = this->GetPtr<FFortAthenaLoadout>(CosmeticLoadoutPCOffset);
return CosmeticLoadout;
@@ -143,7 +147,7 @@ public:
static auto WeaponDefinitionOffset = FindOffsetStruct("/Script/FortniteGame.AthenaPickaxeItemDefinition", "WeaponDefinition");
auto PickaxeDefinition = CosmeticLoadoutPickaxe ? CosmeticLoadoutPickaxe->Get<UFortItemDefinition*>(WeaponDefinitionOffset)
auto PickaxeDefinition = /* WeaponDefinitionOffset != -1 && */ CosmeticLoadoutPickaxe ? CosmeticLoadoutPickaxe->Get<UFortItemDefinition*>(WeaponDefinitionOffset)
: FindObject<UFortItemDefinition>(L"/Game/Athena/Items/Weapons/WID_Harvest_Pickaxe_Athena_C_T01.WID_Harvest_Pickaxe_Athena_C_T01");
auto WorldInventory = GetWorldInventory();

View File

@@ -132,6 +132,27 @@ void AFortPlayerControllerAthena::EndGhostModeHook(AFortPlayerControllerAthena*
return EndGhostModeOriginal(PlayerController);
}
void AFortPlayerControllerAthena::ServerCreativeSetFlightSpeedIndexHook(UObject* Context, FFrame* Stack)
{
int Index;
Stack->StepCompiledIn(&Index);
// LOG_INFO(LogDev, "Player {} wanting to change creative flight speed at index {}", Context->GetName(), Index);
static auto WantedFlightSpeedChangedFn = FindObject<UFunction>("/Script/FortniteGame.FortPlayerControllerGameplay:OnRep_FlyingModifierIndex");
if (!WantedFlightSpeedChangedFn)
{
return;
}
static auto FlyingModifierIndexOffset = Context->GetOffset("FlyingModifierIndex");
Context->Get<int>(FlyingModifierIndexOffset) = Index;
return Context->ProcessEvent(WantedFlightSpeedChangedFn);
}
void AFortPlayerControllerAthena::EnterAircraftHook(UObject* PC, AActor* Aircraft)
{
auto PlayerController = Cast<AFortPlayerController>(Engine_Version < 424 ? PC : ((UActorComponent*)PC)->GetOwner());
@@ -334,6 +355,13 @@ void AFortPlayerControllerAthena::ServerRestartPlayerHook(AFortPlayerControllerA
static auto ZoneServerRestartPlayer = __int64(FortPlayerControllerZoneDefault->VFTable[GetFunctionIdxOrPtr(ServerRestartPlayerFn) / 8]);
static void (*ZoneServerRestartPlayerOriginal)(AFortPlayerController*) = decltype(ZoneServerRestartPlayerOriginal)(__int64(ZoneServerRestartPlayer));
// auto NAME_Spectating = UKismetStringLibrary::Conv_StringToName(L"NAME_Spectating");
// LOG_INFO(LogDev, "ISplayerwaiting: {}", Controller->IsPlayerWaiting());
// Controller->GetStateName() = NAME_Spectating;
// Controller->SetPlayerIsWaiting(true);
LOG_INFO(LogDev, "ServerRestartPlayerHook Call 0x{:x} returning with 0x{:x}!", ZoneServerRestartPlayer - __int64(_ReturnAddress()), __int64(ZoneServerRestartPlayerOriginal) - __int64(GetModuleHandleW(0)));
return ZoneServerRestartPlayerOriginal(Controller);
}

View File

@@ -201,10 +201,10 @@ public:
this->ProcessEvent(ClientClearDeathNotificationFn);
}
UAthenaPlayerMatchReport*& GetMatchReport()
UAthenaPlayerMatchReport** GetMatchReport()
{
static auto MatchReportOffset = GetOffset("MatchReport");
return Get<UAthenaPlayerMatchReport*>(MatchReportOffset);
static auto MatchReportOffset = GetOffset("MatchReport", false);
return MatchReportOffset == -1 ? nullptr : GetPtr<UAthenaPlayerMatchReport*>(MatchReportOffset);
}
void ClientSendTeamStatsForPlayer(FAthenaMatchTeamStats* TeamStats)
@@ -253,6 +253,7 @@ public:
static void StartGhostModeHook(UObject* Context, FFrame* Stack, void* Ret); // we could native hook this but eh
static void EndGhostModeHook(AFortPlayerControllerAthena* PlayerController);
static void ServerCreativeSetFlightSpeedIndexHook(UObject* Context, FFrame* Stack);
static void EnterAircraftHook(UObject* PC, AActor* Aircraft);
static void ServerRequestSeatChangeHook(AFortPlayerControllerAthena* PlayerController, int TargetSeatIndex); // actually in zone
static void ServerRestartPlayerHook(AFortPlayerControllerAthena* Controller);

View File

@@ -86,6 +86,22 @@ AActor* AGameModeBase::K2_FindPlayerStart(AController* Player, FString IncomingN
return AGameModeBase_K2_FindPlayerStart_Params.ReturnValue;
}
bool AGameModeBase::PlayerCanRestartHook(UObject* Context, FFrame& Stack, bool* Ret)
{
auto ret = PlayerCanRestartOriginal(Context, Stack, Ret);
LOG_INFO(LogDev, "PlayerCanRestartHook ret: {}", ret);
if (Globals::bGoingToPlayEvent && Fortnite_Version == 14.60)
{
// 1:1
ret = true;
*Ret = true;
}
return ret;
}
APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AController* NewPlayer, AActor* StartSpot)
{
LOG_INFO(LogDev, "SpawnDefaultPawnForHook!");
@@ -159,7 +175,20 @@ APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AControll
auto& StartingItems = ((AFortGameModeAthena*)GameMode)->GetStartingItems();
NewPlayerAsAthena->AddPickaxeToInventory();
if (Globals::bGoingToPlayEvent && Fortnite_Version >= 16.00)
{
auto WID = Cast<UFortWorldItemDefinition>(FindObject("WID_EventMode_Activator", nullptr, ANY_PACKAGE)); // Empty Hands
bool bShouldUpdate = false;
WorldInventory->AddItem(WID, &bShouldUpdate, 1);
if (bShouldUpdate)
WorldInventory->Update();
}
else
{
NewPlayerAsAthena->AddPickaxeToInventory();
}
for (int i = 0; i < StartingItems.Num(); ++i)
{

View File

@@ -5,10 +5,13 @@
#include "Controller.h"
#include "Pawn.h"
#include "UnrealString.h"
#include "Stack.h"
class AGameModeBase : public AActor // AInfo
{
public:
static inline bool (*PlayerCanRestartOriginal)(UObject* Context, FFrame& Stack, bool* Ret);
UClass* GetDefaultPawnClassForController(AController* InController);
void ChangeName(AController* Controller, const FString& NewName, bool bNameChange);
AActor* K2_FindPlayerStart(AController* Player, FString IncomingName);
@@ -16,5 +19,6 @@ public:
void RestartPlayerAtPlayerStart(AController* NewPlayer, AActor* StartSpot);
void RestartPlayer(AController* NewPlayer);
static bool PlayerCanRestartHook(UObject* Context, FFrame& Stack, bool* Ret);
static APawn* SpawnDefaultPawnForHook(AGameModeBase* GameMode, AController* NewPlayer, AActor* StartSpot);
};

View File

@@ -71,5 +71,11 @@ public:
return Get<TArray<AActor*>>(SentTemporariesOffset);
}
UObject*& GetPackageMap()
{
static auto PackageMapOffset = GetOffset("PackageMap");
return Get<UObject*>(PackageMapOffset);
}
bool ClientHasInitializedLevelFor(const AActor* TestActor) const;
};

View File

@@ -56,23 +56,34 @@ void UNetDriver::TickFlushHook(UNetDriver* NetDriver)
if (Globals::bStartedListening)
{
static auto ReplicationDriverOffset = NetDriver->GetOffset("ReplicationDriver", false);
// if (ReplicationDriverOffset == -1)
if (ReplicationDriverOffset == -1 || Fortnite_Version >= 20)
if (!Globals::bShouldUseReplicationGraph)
{
NetDriver->ServerReplicateActors();
}
else
{
static auto ReplicationDriverOffset = NetDriver->GetOffset("ReplicationDriver"/*, false */);
if (auto ReplicationDriver = NetDriver->Get(ReplicationDriverOffset))
{
reinterpret_cast<void(*)(UObject*)>(ReplicationDriver->VFTable[Offsets::ServerReplicateActors])(ReplicationDriver);
}
else
{
// LOG_INFO(LogDev, "ReplicationDriver is nul!!?1//33/221/4/124/123"); // 3.3 MOMENT
}
}
}
return TickFlushOriginal(NetDriver);
}
enum class EChannelCreateFlags : uint32_t
{
None = (1 << 0),
OpenedLocally = (1 << 1)
};
int32 ServerReplicateActors_PrepConnections(UNetDriver* NetDriver)
{
auto& ClientConnections = NetDriver->GetClientConnections();
@@ -448,6 +459,117 @@ bool UNetDriver::IsLevelInitializedForActor(const AActor* InActor, const UNetCon
return bCorrectWorld || bIsConnectionPC;
}
TMap<FNetworkGUID, FActorDestructionInfo>* GetDestroyedStartupOrDormantActors(UNetDriver* Driver)
{
static int off = Fortnite_Version == 1.11 ? 0x228 : 0; // 0x240
return off == 0 ? nullptr : (TMap<FNetworkGUID, FActorDestructionInfo>*)(__int64(Driver) + off);
}
TSet<FNetworkGUID>* GetDestroyedStartupOrDormantActors(UNetConnection* NetConnection)
{
static int off = Fortnite_Version == 1.11 ? 0x33678 : 0;
return off == 0 ? nullptr : (TSet<FNetworkGUID>*)(__int64(NetConnection) + off);
}
using FArchive = void;
bool IsError(FArchive* Ar)
{
return false;
}
void SerializeChecksum(FArchive* Ar, uint32 x, bool ErrorOK)
{
/*
if (Ar->IsLoading())
{
uint32 Magic = 0;
Ar << Magic;
if ((!ErrorOK || !IsError(Ar))
// && !ensure(Magic == x)
)
{
// UE_LOG(LogCoreNet, Warning, TEXT("%d == %d"), Magic, x);
}
}
else
{
uint32 Magic = x;
Ar << Magic;
}
*/
}
#define NET_CHECKSUM(Ser) \
{ \
SerializeChecksum(Ser,0xE282FA84, false); \
}
struct FPacketIdRange
{
FPacketIdRange(int32 _First, int32 _Last) : First(_First), Last(_Last) { }
FPacketIdRange(int32 PacketId) : First(PacketId), Last(PacketId) { }
FPacketIdRange() : First(INDEX_NONE), Last(INDEX_NONE) { }
int32 First;
int32 Last;
bool InRange(int32 PacketId) const
{
return (First <= PacketId && PacketId <= Last);
}
};
void SetChannelActorForDestroy(UActorChannel* Channel, FActorDestructionInfo* DestructInfo)
{
auto Connection = Channel->GetConnection();
if (
true
// && !Channel->IsClosing()
// && (Connection->State == USOCK_Open || Connection->State == USOCK_Pending)
)
{
// Send a close notify, and wait for ack.
struct FOutBunch
{
char pad[0x600]; // idk real size
};
FOutBunch CloseBunch{};
FOutBunch(*ConstructorFOutBunch)(FOutBunch*, UChannel* , bool) = decltype(ConstructorFOutBunch)(__int64(GetModuleHandleW(0)) + 0x194E800);
ConstructorFOutBunch(&CloseBunch, Channel, 1);
// check(!CloseBunch.IsError());
// check(CloseBunch.bClose);
// https://imgur.com/a/EtKFkrD
*(bool*)(__int64(&CloseBunch) + 0xE8) = 1;
*(bool*)(__int64(&CloseBunch) + 0xE6) = 0;
// Serialize DestructInfo
// NET_CHECKSUM(CloseBunch); // This is to mirror the Checksum in UPackageMapClient::SerializeNewActor
using UPackageMap = UObject;
reinterpret_cast<bool(*)(UPackageMap*, FArchive * Ar, UObject * InOuter,FNetworkGUID NetGUID, FString ObjName)>(Connection->GetPackageMap()->VFTable[0x238 / 8])(Connection->GetPackageMap(), &CloseBunch, DestructInfo->ObjOuter.Get(), DestructInfo->NetGUID, DestructInfo->PathName);
// UE_LOG(LogNetTraffic, Log, TEXT("SetChannelActorForDestroy: Channel %d. NetGUID <%s> Path: %s. Bits: %d"), ChIndex, *DestructInfo->NetGUID.ToString(), *DestructInfo->PathName, CloseBunch.GetNumBits());
// UE_LOG(LogNetDormancy, Verbose, TEXT("SetChannelActorForDestroy: Channel %d. NetGUID <%s> Path: %s. Bits: %d"), ChIndex, *DestructInfo->NetGUID.ToString(), *DestructInfo->PathName, CloseBunch.GetNumBits());
// 0x196E9C0
reinterpret_cast<FPacketIdRange(*)(UActorChannel*, FOutBunch*, bool)>(Channel->VFTable[0x288 / 8])(Channel, &CloseBunch, false);
}
}
TSet<FName>* GetClientVisibleLevelNames(UNetConnection* NetConnection)
{
return (TSet<FName>*)(__int64(NetConnection) + 0x336C8);
}
int32 UNetDriver::ServerReplicateActors()
{
int32 Updated = 0;
@@ -487,6 +609,11 @@ int32 UNetDriver::ServerReplicateActors()
// LOG_INFO(LogReplication, "Considering {} actors.", ConsiderList.size());
static UChannel* (*CreateChannel)(UNetConnection*, int, bool, int32_t) = decltype(CreateChannel)(Addresses::CreateChannel);
static __int64 (*ReplicateActor)(UActorChannel*) = decltype(ReplicateActor)(Addresses::ReplicateActor);
static UObject* (*CreateChannelByName)(UNetConnection * Connection, FName * ChName, EChannelCreateFlags CreateFlags, int32_t ChannelIndex) = decltype(CreateChannelByName)(Addresses::CreateChannel);
static __int64 (*SetChannelActor)(UActorChannel*, AActor*) = decltype(SetChannelActor)(Addresses::SetChannelActor);
for (int32 i = 0; i < this->GetClientConnections().Num(); i++)
{
UNetConnection* Connection = this->GetClientConnections().at(i);
@@ -522,6 +649,87 @@ int32 UNetDriver::ServerReplicateActors()
Connection->GetSentTemporaries().at(j)->GetNetTag() = GetNetTag();
} */
std::vector<FActorDestructionInfo*> DeletionEntries;
#if 0
auto ConnectionDestroyedStartupOrDormantActors = GetDestroyedStartupOrDormantActors(Connection);
if (ConnectionDestroyedStartupOrDormantActors)
{
auto DriverDestroyedStartupOrDormantActors = GetDestroyedStartupOrDormantActors(this);
if (DriverDestroyedStartupOrDormantActors)
{
for (FNetworkGUID& ConnectionIt : *ConnectionDestroyedStartupOrDormantActors)
{
FActorDestructionInfo* DInfo = nullptr;
for (TPair<FNetworkGUID, FActorDestructionInfo>& DriverIt : *DriverDestroyedStartupOrDormantActors)
{
if (DriverIt.First == ConnectionIt)
{
DInfo = &DriverIt.Second;
break;
}
}
if (!DInfo) continue; // should never happen
DeletionEntries.push_back(DInfo);
}
}
}
LOG_INFO(LogDev, "DeletionEntries: {}", DeletionEntries.size());
#endif
for (FActorDestructionInfo* DeletionEntry : DeletionEntries)
{
LOG_INFO(LogDev, "AA: {}", DeletionEntry->PathName.Data.Data ? DeletionEntry->PathName.ToString() : "Null");
if (DeletionEntry->StreamingLevelName != -1)
{
auto ClientVisibleLevelNames = GetClientVisibleLevelNames(Connection);
bool bFound = false;
for (FName& ClientVisibleLevelName : *ClientVisibleLevelNames)
{
if (ClientVisibleLevelName == DeletionEntry->StreamingLevelName)
{
bFound = true;
break;
}
}
if (!bFound)
continue;
}
UActorChannel* Channel = nullptr;
if (Engine_Version >= 422)
{
FString ActorStr = L"Actor";
FName ActorName = UKismetStringLibrary::Conv_StringToName(ActorStr);
int ChannelIndex = -1; // 4294967295
Channel = (UActorChannel*)CreateChannelByName(Connection, &ActorName, EChannelCreateFlags::OpenedLocally, ChannelIndex);
}
else
{
Channel = (UActorChannel*)CreateChannel(Connection, 2, true, -1);
}
if (Channel)
{
// FinalRelevantCount++;
SetChannelActorForDestroy(Channel, DeletionEntry); // Send a close bunch on the new channel
GetDestroyedStartupOrDormantActors(Connection)->Remove(DeletionEntry->NetGUID); // Remove from connections to-be-destroyed list (close bunch of reliable, so it will make it there)
}
}
for (auto& ActorInfo : ConsiderList)
{
if (!ActorInfo || !ActorInfo->Actor)
@@ -592,16 +800,6 @@ int32 UNetDriver::ServerReplicateActors()
}
}
enum class EChannelCreateFlags : uint32_t
{
None = (1 << 0),
OpenedLocally = (1 << 1)
};
static UChannel* (*CreateChannel)(UNetConnection*, int, bool, int32_t) = decltype(CreateChannel)(Addresses::CreateChannel);
static __int64 (*ReplicateActor)(UActorChannel*) = decltype(ReplicateActor)(Addresses::ReplicateActor);
static UObject* (*CreateChannelByName)(UNetConnection* Connection, FName* ChName, EChannelCreateFlags CreateFlags, int32_t ChannelIndex) = decltype(CreateChannelByName)(Addresses::CreateChannel);
static __int64 (*SetChannelActor)(UActorChannel*, AActor*) = decltype(SetChannelActor)(Addresses::SetChannelActor);
if (!Channel)
{

View File

@@ -68,7 +68,7 @@ public:
int GetOffset(const std::string& ChildName, bool bWarnIfNotFound = true) const;
template <typename T = UObject*>
T& Get(int Offset) const { return *(T*)(__int64(this) + Offset); }
inline T& Get(int Offset) const { return *(T*)(__int64(this) + Offset); }
void* GetInterfaceAddress(UClass* InterfaceClass);

View File

@@ -16,6 +16,13 @@ void APlayerController::SetPlayerIsWaiting(bool NewValue)
this->SetBitfieldValue(bPlayerIsWaitingOffset, bPlayerIsWaitingFieldMask, NewValue);
}
bool APlayerController::IsPlayerWaiting()
{
static auto bPlayerIsWaitingOffset = GetOffset("bPlayerIsWaiting");
static auto bPlayerIsWaitingFieldMask = GetFieldMask(this->GetProperty("bPlayerIsWaiting"));
return this->ReadBitfieldValue(bPlayerIsWaitingOffset, bPlayerIsWaitingFieldMask);
}
UCheatManager*& APlayerController::SpawnCheatManager(UClass* CheatManagerClass)
{
GetCheatManager() = UGameplayStatics::SpawnObject<UCheatManager>(CheatManagerClass, this, true);

View File

@@ -23,6 +23,7 @@ public:
}
void SetPlayerIsWaiting(bool NewValue);
bool IsPlayerWaiting();
void ServerChangeName(FString& S);
UCheatManager*& SpawnCheatManager(UClass* CheatManagerClass);
FRotator GetControlRotation();

View File

@@ -307,7 +307,6 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="log.h" />
<ClInclude Include="finder.h" />
<ClInclude Include="Array.h">
<Filter>Engine\Source\Runtime\Core\Public\Containers</Filter>
</ClInclude>
@@ -962,6 +961,8 @@
</ClInclude>
<ClInclude Include="TSubclassOf.h">
<Filter>Engine\Source\Runtime\Engine\Classes\Engine</Filter>
<ClInclude Include="finder.h">
<Filter>Reboot\Public</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>

View File

@@ -65,10 +65,102 @@ struct FActorSpawnParametersUE500
TFunction<void(UObject*)> CustomPreSpawnInitalization; // my favorite
};
#if 0
static inline PadHexB0 CreateSpawnParameters(ESpawnActorCollisionHandlingMethod SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::Undefined, bool bDeferConstruction = false, UObject* Owner = nullptr)
{
if (Engine_Version >= 500)
{
FActorSpawnParametersUE500 addr{};
addr.Owner = Owner;
addr.bDeferConstruction = bDeferConstruction;
addr.SpawnCollisionHandlingOverride = SpawnCollisionHandlingOverride;
return *(PadHexB0*)&addr;
}
else
{
FActorSpawnParameters addr{};
addr.Owner = Owner;
addr.bDeferConstruction = bDeferConstruction;
addr.SpawnCollisionHandlingOverride = SpawnCollisionHandlingOverride;
return *(PadHexB0*)&addr;
}
return PadHexB0();
}
class UWorld : public UObject, public FNetworkNotify
{
public:
static inline UObject* (*SpawnActorOriginal)(UWorld* World, UClass* Class, FTransform const* UserTransformPtr, void* SpawnParameters);
template <typename T = AActor>
T*& GetGameMode()
{
static auto AuthorityGameModeOffset = GetOffset("AuthorityGameMode");
return this->Get<T*>(AuthorityGameModeOffset);
}
class AGameState*& GetGameState()
{
static auto GameStateOffset = GetOffset("GameState");
return this->Get<class AGameState*>(GameStateOffset);
}
class UNetDriver*& GetNetDriver()
{
static auto NetDriverOffset = GetOffset("NetDriver");
return this->Get<class UNetDriver*>(NetDriverOffset);
}
UGameInstance* GetOwningGameInstance()
{
static auto OwningGameInstanceOffset = GetOffset("OwningGameInstance");
return this->Get<UGameInstance*>(OwningGameInstanceOffset);
}
inline FTimerManager& GetTimerManager()
{
return GetOwningGameInstance()->GetTimerManager();
// return (GetOwningGameInstance() ? GetOwningGameInstance()->GetTimerManager() : *TimerManager);
}
template <typename ActorType>
ActorType* SpawnActor(UClass* Class, FTransform UserTransformPtr = FTransform(), PadHexB0 SpawnParameters = CreateSpawnParameters())
{
auto actor = (ActorType*)SpawnActorOriginal(this, Class, &UserTransformPtr, &SpawnParameters);
return actor;
}
template <typename ActorType>
ActorType* SpawnActor(UClass* Class, FVector Location, FQuat Rotation = FQuat(), FVector Scale3D = FVector(1, 1, 1), PadHexB0 SpawnParameters = CreateSpawnParameters())
{
FTransform UserTransformPtr{};
UserTransformPtr.Translation = Location;
UserTransformPtr.Rotation = Rotation;
UserTransformPtr.Scale3D = Scale3D;
auto actor = SpawnActor<ActorType>(Class, UserTransformPtr, SpawnParameters);
return actor;
}
AWorldSettings* GetWorldSettings(bool bCheckStreamingPersistent = false, bool bChecked = true) const;
AWorldSettings* K2_GetWorldSettings(); // DONT USE WHEN POSSIBLE
void Listen();
};
#else
// #define USE_VIRTUALALLOC_SPAWNPARAMS
static inline void* CreateSpawnParameters(ESpawnActorCollisionHandlingMethod SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::Undefined, bool bDeferConstruction = false, UObject* Owner = nullptr)
{
if (Engine_Version >= 500)
{
#ifdef USE_VIRTUALALLOC_SPAWNPARAMS
auto addr = (FActorSpawnParametersUE500*)VirtualAlloc(0, sizeof(FActorSpawnParametersUE500), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!addr)
@@ -78,9 +170,18 @@ static inline void* CreateSpawnParameters(ESpawnActorCollisionHandlingMethod Spa
addr->bDeferConstruction = bDeferConstruction;
addr->SpawnCollisionHandlingOverride = SpawnCollisionHandlingOverride;
return addr;
#else
FActorSpawnParametersUE500 addr{};
addr.Owner = Owner;
addr.bDeferConstruction = bDeferConstruction;
addr.SpawnCollisionHandlingOverride = SpawnCollisionHandlingOverride;
return &addr;
#endif
}
else
{
#ifdef USE_VIRTUALALLOC_SPAWNPARAMS
auto addr = (FActorSpawnParameters*)VirtualAlloc(0, sizeof(FActorSpawnParameters), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!addr)
@@ -90,6 +191,14 @@ static inline void* CreateSpawnParameters(ESpawnActorCollisionHandlingMethod Spa
addr->bDeferConstruction = bDeferConstruction;
addr->SpawnCollisionHandlingOverride = SpawnCollisionHandlingOverride;
return addr;
#else
FActorSpawnParameters addr{};
addr.Owner = Owner;
addr.bDeferConstruction = bDeferConstruction;
addr.SpawnCollisionHandlingOverride = SpawnCollisionHandlingOverride;
return &addr;
#endif
}
return nullptr;
@@ -134,12 +243,21 @@ public:
template <typename ActorType>
ActorType* SpawnActor(UClass* Class, FTransform UserTransformPtr = FTransform(), void* SpawnParameters = nullptr)
{
if (!SpawnParameters)
const bool bCreatedSpawnParameters = !SpawnParameters;
if (bCreatedSpawnParameters)
{
SpawnParameters = CreateSpawnParameters();
}
auto actor = (ActorType*)SpawnActorOriginal(this, Class, &UserTransformPtr, SpawnParameters);
VirtualFree(SpawnParameters, 0, MEM_RELEASE);
// if (bCreatedSpawnParameters)
{
#ifdef USE_VIRTUALALLOC_SPAWNPARAMS
VirtualFree(SpawnParameters, 0, MEM_RELEASE);
#endif
}
return actor;
}
@@ -166,4 +284,5 @@ public:
AWorldSettings* K2_GetWorldSettings(); // DONT USE WHEN POSSIBLE
void Listen();
};
};
#endif

View File

@@ -471,11 +471,25 @@ void Offsets::FindAll()
Offsets::NetworkObjectList = 0x4F0;
Offsets::ReplicationFrame = 0x328;
}
if (Fortnite_Version == 3.1 || Fortnite_Version == 3.2)
if (Fortnite_Version == 3.1)
{
Offsets::NetworkObjectList = 0x4F8;
Offsets::ClientWorldPackageName = 0x1818;
}
if (Fortnite_Version == 3.2)
{
Offsets::NetworkObjectList = 0x4F8;
Offsets::ClientWorldPackageName = 0x1820;
}
if (Fortnite_Version == 3.2 || Fortnite_Version == 3.3)
{
Offsets::ReplicationFrame = 0x330;
}
if (Fortnite_Version == 3.3)
{
Offsets::NetworkObjectList = 0x508;
Offsets::ClientWorldPackageName = 0x1828;
}
if (Engine_Version == 419) // checked 2.4.2 & 2.2 & 1.11
{
Offsets::NetworkObjectList = 0x490;
@@ -583,8 +597,13 @@ std::vector<uint64> Addresses::GetFunctionsToNull()
toNull.push_back(Memcury::Scanner::FindStringRef(L"Widget Class %s - Running Initialize On Archetype, %s.").ScanFor({ 0x40, 0x55 }, false).Get()); // Widget class
}
if (Engine_Version == 422)
if (Engine_Version == 422
|| Engine_Version == 423
|| Engine_Version == 424 // guessed
)
{
// This sig is valid on 7.40, 8.51, 11.31 (3 refs), but on 12.41 it has 1 ref which isn't widget class
// Also this isn't the actual function but something the widget class thing calls
toNull.push_back(Memcury::Scanner::FindPattern("48 89 5C 24 ? 57 48 83 EC 30 48 8B 41 28 48 8B DA 48 8B F9 48 85 C0 74 34 48 8B 4B 08 48 8D").Get()); // widget class
}

View File

@@ -95,7 +95,7 @@ namespace Offsets
extern inline uint64 SuperStruct = 0;
extern inline uint64 Offset_Internal = 0;
extern inline uint64 ServerReplicateActors = 0;
extern inline uint64 ReplicationFrame = 0;
extern inline uint64 ReplicationFrame = 0; // Attempt to replicate function '%s' on Actor '%s' while it is in the middle of variable replication!
extern inline uint64 IsNetRelevantFor = 0;
extern inline uint64 NetworkObjectList = 0;
extern inline uint64 ClientWorldPackageName = 0;

View File

@@ -156,7 +156,8 @@ static inline void ProcessEventHook(UObject* Object, UFunction* Function, void*
!strstr(FunctionName.c_str(), "ServerTriggerCombatEvent") &&
!strstr(FunctionName.c_str(), "SpinCubeTimeline__UpdateFunc") &&
!strstr(ObjectName.c_str(), "FortPhysicsObjectComponent") &&
!strstr(FunctionName.c_str(), "GetTextValue"))
!strstr(FunctionName.c_str(), "GetTextValue") &&
!strstr(FunctionName.c_str(), "ExecuteUbergraph_BGA_Petrol_Pickup"))
{
LOG_INFO(LogDev, "Function called: {} with {}", FunctionFullName, ObjectName);
}

View File

@@ -79,6 +79,7 @@ static ENetMode GetNetModeHook2() { return NetMode; }
static bool ReturnTrueHook() { return true; }
static bool ReturnFalseHook() { return false; }
static int Return2Hook() { return 2; }
static void EmptyHook() { return; }
static bool NoMCPHook() { return Globals::bNoMCP; }
static void CollectGarbageHook() { return; }
@@ -211,9 +212,413 @@ void ActivatePhaseAtIndexHook(UObject* SpecialEventScript, int Index)
static auto OnRep_ReplicatedActivePhaseIndexFn = FindObject<UFunction>("/Script/SpecialEventGameplayRuntime.SpecialEventScript.OnRep_ReplicatedActivePhaseIndex");
SpecialEventScript->ProcessEvent(OnRep_ReplicatedActivePhaseIndexFn);
auto ClientConnections = GetWorld()->GetNetDriver()->GetClientConnections();
// Rift Tour
if (Fortnite_Version == 17.30)
{
auto EventPlaylist = GetEventPlaylist();
struct { UObject* GameState; UObject* Playlist; FGameplayTagContainer PlaylistContextTags; } OnReadyParams{ Cast<AFortGameStateAthena>(GetWorld()->GetGameState()), EventPlaylist };
{
if (Index == 0) // Start of Event
{
auto AllSatelliteDishes = UGameplayStatics::GetAllActorsOfClass(GetWorld(), FindObject<UClass>("/Game/Athena/Apollo/Environments/BuildingActors/Complex/Props/Apollo_Complex_Satellite_Dish_Top_01.Apollo_Complex_Satellite_Dish_Top_01_C"));
for (int i = 0; i < AllSatelliteDishes.Num(); i++)
{
AllSatelliteDishes.At(i)->K2_DestroyActor();
}
auto AllSpecialEventMutators = UGameplayStatics::GetAllActorsOfClass(GetWorld(), FindObject<UClass>("/Script/SpecialEventGameplayRuntime.FortAthenaMutator_SpecialEvent"));
for (int i = 0; i < AllSpecialEventMutators.Num(); i++)
{
auto CurrentSpecialEventMutator = AllSpecialEventMutators.At(i);
auto ScriptActor = CurrentSpecialEventMutator->Get<AActor*>(CurrentSpecialEventMutator->GetOffset("ScriptActor"));
if (!ScriptActor)
{
ScriptActor = Cast<AActor>(GetEventScripting());
LOG_INFO(LogEvent, "ScriptActor set for mutator: {}", CurrentSpecialEventMutator->GetName());
}
}
}
if (Index == 2) // Slide
{
auto Script = FindObject<UObject>("/Buffet/Levels/Buffet_Part_4.Buffet_Part_4.PersistentLevel.BP_Buffet_PhaseScripting_Paint_4");
auto SplineActor = Script->Get<AActor*>(Script->GetOffset("SplineActor"));
auto PawnLocation = Script->Get<AActor*>(Script->GetOffset("PawnLocation")) = SplineActor;
auto AllWrapsSpawners = UGameplayStatics::GetAllActorsOfClass(GetWorld(), FindObject<UClass>("/Script/SpecialEventGameplayRuntime.FortSpecialRelevancyActorSpawner"));
for (int i = 0; i < AllWrapsSpawners.Num(); i++)
{
auto CurrentWrapSpawner = AllWrapsSpawners.At(i);
if (CurrentWrapSpawner)
{
auto WrapSpawnerLocation = CurrentWrapSpawner->GetActorLocation();
auto WrapSpawnerRotation = CurrentWrapSpawner->GetActorRotation();
UClass* ClassToSpawn = nullptr;
if (CurrentWrapSpawner->GetName().contains("WrapChangePickup"))
{
ClassToSpawn = FindObject<UClass>("/Buffet/Gameplay/Blueprints/WrapWorldPrototype/BP_Buffet_Paint_WrapChangePickup.BP_Buffet_Paint_WrapChangePickup_C");
}
else if (CurrentWrapSpawner->GetName().contains("Paint_Pickup"))
{
ClassToSpawn = FindObject<UClass>("/Buffet/Gameplay/Blueprints/WrapWorldPrototype/BP_Buffet_Paint_Pickup.BP_Buffet_Paint_Pickup_C");
}
auto SpawnedWrap = GetWorld()->SpawnActor<AActor>(ClassToSpawn, WrapSpawnerLocation, WrapSpawnerRotation.Quaternion(), FVector(1, 1, 1),
CreateSpawnParameters(ESpawnActorCollisionHandlingMethod::AlwaysSpawn, true, nullptr));
if (SpawnedWrap)
{
LOG_INFO(LogDev, "Spawner Spawned a Wrap: {}", SpawnedWrap->GetName());
}
else
{
LOG_INFO(LogDev, "Spawner Failed to spawn a Wrap {}!", CurrentWrapSpawner->GetName());
}
}
else
{
LOG_INFO(LogDev, "Spawner Invalid!");
}
}
for (int i = 0; i < ClientConnections.Num(); i++)
{
auto CurrentPawn = ClientConnections.At(i)->GetPlayerController()->GetPawn();
auto CurrentController = ClientConnections.At(i)->GetPlayerController();
if (!CurrentPawn)
continue;
auto PlayerComponent = CurrentPawn->AddComponentByClass(FindObject<UClass>("/Buffet/Gameplay/Blueprints/WrapWorldPrototype/BP_Buffet_Paint_PlayerComponent.BP_Buffet_Paint_PlayerComponent_C")); // WHY DOESnT IT WORK AUTO
auto MovementComponent = CurrentPawn->AddComponentByClass(FindObject<UClass>("/Buffet/Gameplay/Blueprints/WrapWorldPrototype/BP_Buffet_Paint_MovementComponent.BP_Buffet_Paint_MovementComponent_C"));
PlayerComponent->Get<AActor*>(PlayerComponent->GetOffset("OwningPlayerController")) = CurrentController;
struct
{
AActor* Pawn;
AActor* ReturnValue;
}wrapmanagerparams{};
wrapmanagerparams.Pawn = CurrentPawn;
Script->ProcessEvent(Script->FindFunction("GetWrapManagerForPlayer"), &wrapmanagerparams);
MovementComponent->Get<bool>(MovementComponent->GetOffset("bIsMovingAlongSpline")) = true;
MovementComponent->Get<float>(MovementComponent->GetOffset("ReplicatedTotalSplineTime")) = 59.793846f; // TotalSplineTime
MovementComponent->Get<AActor*>(MovementComponent->GetOffset("TargetSplineActor")) = SplineActor;
MovementComponent->ProcessEvent(MovementComponent->FindFunction("SetSplineActor"), &SplineActor);
bool IsMoving = true;
MovementComponent->ProcessEvent(MovementComponent->FindFunction("SetIsMovingAlongSpline"), &IsMoving);
MovementComponent->Get<float>(MovementComponent->GetOffset("ReplicatedSplineInterpStrength")) = 1.3f; // SplineInterpStrength
auto GameMode = (AFortGameMode*)GetWorld()->GetGameMode();
auto GameState = Cast<AFortGameStateAthena>(GameMode->GetGameState());
MovementComponent->Get<float>(MovementComponent->GetOffset("StartServerWorldTime")) = GameState->GetServerWorldTimeSeconds();
MovementComponent->ProcessEvent(MovementComponent->FindFunction("OnRep_TargetSplineActor"));
PlayerComponent->Get<AActor*>(PlayerComponent->GetOffset("WrapManager")) = wrapmanagerparams.ReturnValue;
PlayerComponent->Get<UObject*>(PlayerComponent->GetOffset("MovementComponent")) = MovementComponent;
int StasisMode = 3;
CurrentPawn->ProcessEvent(CurrentPawn->FindFunction("SetStasisMode"), &StasisMode); // ??
}
}
if (Index == 3)
{
for (int i = 0; i < ClientConnections.Num(); i++)
{
auto CurrentPawn = ClientConnections.At(i)->GetPlayerController()->GetPawn();
auto CurrentController = ClientConnections.At(i)->GetPlayerController();
int StasisMode = 0;
CurrentPawn->ProcessEvent(CurrentPawn->FindFunction("SetStasisMode"), &StasisMode);
}
}
if (Index == 4) // Storm King
{
auto StormScript = FindObject<AActor>("/Buffet/Levels/Buffet_Part_6.Buffet_Part_6:PersistentLevel.BP_Buffet_PhaseScripting_4");
auto DefaultPlane = FindObject("/Buffet/Gameplay/Blueprints/WolfMother/BP_PlanePrototype.Default__BP_PlanePrototype_C");
auto WID = Cast<UFortWorldItemDefinition>(FindObject("WID_Buffet_BeatMatchingBoomBox", nullptr, ANY_PACKAGE)); // Storm King weapon thing
for (int i = 0; i < ClientConnections.Num(); i++)
{
auto CurrentPawn = ClientConnections.At(i)->GetPlayerController()->GetPawn();
auto CurrentController = (AFortPlayerControllerAthena*)ClientConnections.At(i)->GetPlayerController();
auto WorldInventory = CurrentController->GetWorldInventory();
bool bShouldUpdate = false;
WorldInventory->AddItem(WID, &bShouldUpdate, 1);
if (bShouldUpdate)
WorldInventory->Update();
SendMessageToConsole(CurrentController, L"Gave WID_Buffet_BeatMatchingBoomBox!");
}
auto AllWeps = UGameplayStatics::GetAllActorsOfClass(GetWorld(), FindObject<UClass>("/Buffet/Gameplay/Blueprints/WolfMother/BeatmatchingWeapon/B_Buffet_BeatMatchingWeaponPrototype.B_Buffet_BeatMatchingWeaponPrototype_C"));
for (int i = 0; i < AllWeps.Num(); i++)
{
auto CurrentWep = AllWeps.At(i);
if (CurrentWep != nullptr)
{
CurrentWep->Get<AActor*>(CurrentWep->GetOffset("Phase4ScriptingRef")) = StormScript;
}
}
}
if (Index == 6) // Ariana
{
auto ReflectScript = FindObject("/Buffet/Levels/Buffet_Reflect.Buffet_Reflect:PersistentLevel.BP_Buffet_PhaseScripting_Stars_2");
for (int i = 0; i < ClientConnections.Num(); i++)
{
auto CurrentPawn = ClientConnections.At(i)->GetPlayerController()->GetPawn();
CurrentPawn->AddComponentByClass(FindObject<UClass>("/Buffet/Gameplay/Blueprints/Stars/BP_Buffet_Stars_PlayerComponent.BP_Buffet_Stars_PlayerComponent_C"));
CurrentPawn->AddComponentByClass(FindObject<UClass>("/BuffetPlaylist/Playlist/BuffetCharacterMovementMutatorComponent.BuffetCharacterMovementMutatorComponent_C"));
}
}
if (Index == 8) // Bubbles
{
//auto BubbleScript = FindObject("/Buffet/Levels/Buffet_Bubbles.Buffet_Bubbles:PersistentLevel.BP_Buffet_PhaseScripting_Bubble_4");
//auto BubbleSpline = FindObject("/Buffet/Levels/Buffet_Bubbles.Buffet_Bubbles:PersistentLevel.BP_Buffet_SmallBubblePath_2.Spline");
for (int i = 0; i < ClientConnections.Num(); i++)
{
auto CurrentPawn = ClientConnections.At(i)->GetPlayerController()->GetPawn();
auto ComptoRemove = CurrentPawn->GetComponentByClass(FindObject<UClass>("/Buffet/Gameplay/Blueprints/Stars/BP_Buffet_Stars_PlayerComponent.BP_Buffet_Stars_PlayerComponent_C"));
auto BubbleMovementComponent = CurrentPawn->AddComponentByClass(FindObject<UClass>("/Buffet/Gameplay/Blueprints/Bubble/BP_BubblePlayerMovementComponent.BP_BubblePlayerMovementComponent_C"));
/*
struct
{
UObject* InSplineComponent;
float StartDistance;
}SetSplineComponent;
SetSplineComponent.StartDistance = 0;
SetSplineComponent.InSplineComponent = BubbleSpline;
// Works but too fast and player not in correct place on the spline.
BubbleMovementComponent->ProcessEvent(BubbleMovementComponent->FindFunction("SetSplineComponent"), &SetSplineComponent);
BubbleMovementComponent->Get<UObject*>(BubbleMovementComponent->GetOffset("SplineComponent")) = BubbleSpline;
BubbleMovementComponent->Get<bool>(BubbleMovementComponent->GetOffset("bIsMovingAlongSpline")) = true;
auto GameMode = (AFortGameMode*)GetWorld()->GetGameMode();
auto GameState = Cast<AFortGameStateAthena>(GameMode->GetGameState());
BubbleMovementComponent->Get<float>(BubbleMovementComponent->GetOffset("StartServerWorldTime")) = GameState->GetServerWorldTimeSeconds();
bool IsMoving = true;
BubbleMovementComponent->ProcessEvent(BubbleMovementComponent->FindFunction("SetIsMovingAlongSpline"), &IsMoving);
*/
CurrentPawn->ProcessEvent(CurrentPawn->FindFunction("K2_DestroyComponent"), &ComptoRemove);
}
}
if (Index == 10) // Escher
{
for (int i = 0; i < ClientConnections.Num(); i++)
{
auto CurrentPawn = ClientConnections.At(i)->GetPlayerController()->GetPawn();
CurrentPawn->TeleportTo(FVector(36.34f, 1044.07f, 504.50f), CurrentPawn->GetActorRotation());
}
}
}
}
if (Fortnite_Version == 18.40)
{
if (Index == 0)
{
for (int i = 0; i < ClientConnections.Num(); i++)
{
auto CurrentController = (AFortPlayerControllerAthena*)ClientConnections.At(i)->GetPlayerController();
static auto StormEffectClass = FindObject<UClass>(L"/Game/Athena/SafeZone/GE_OutsideSafeZoneDamage.GE_OutsideSafeZoneDamage_C");
auto PlayerState = CurrentController->GetPlayerStateAthena();
PlayerState->GetAbilitySystemComponent()->RemoveActiveGameplayEffectBySourceEffect(StormEffectClass, 1, PlayerState->GetAbilitySystemComponent());
}
auto AssultWID = Cast<UFortWorldItemDefinition>(FindObject("WID_Guava_Assault_AutoHigh_Athena_SR_Ore_T03", nullptr, ANY_PACKAGE));
auto RevolveWID = Cast<UFortWorldItemDefinition>(FindObject("WID_Guava_Pistol_SixShooter_Athena_SR_Ore_T03", nullptr, ANY_PACKAGE));
for (int i = 0; i < ClientConnections.Num(); i++)
{
auto CurrentPawn = ClientConnections.At(i)->GetPlayerController()->GetPawn();
auto CurrentController = (AFortPlayerControllerAthena*)ClientConnections.At(i)->GetPlayerController();
auto WorldInventory = CurrentController->GetWorldInventory();
bool bShouldUpdate = true;
WorldInventory->AddItem(AssultWID, &bShouldUpdate, 1);
WorldInventory->AddItem(RevolveWID, &bShouldUpdate, 1);
if (bShouldUpdate)
WorldInventory->Update();
SendMessageToConsole(CurrentController, L"Gave Event Weapons!");
}
auto AllSatelliteDishes = UGameplayStatics::GetAllActorsOfClass(GetWorld(), FindObject<UClass>("/Game/Athena/Apollo/Environments/BuildingActors/Complex/Props/Apollo_Complex_Satellite_Dish_Top_01.Apollo_Complex_Satellite_Dish_Top_01_C"));
for (int i = 0; i < AllSatelliteDishes.Num(); i++)
{
AllSatelliteDishes.At(i)->K2_DestroyActor();
}
}
}
return ActivatePhaseAtIndexOriginal(SpecialEventScript, Index);
}
static void (*AttemptFinishPhaseOriginal)(AActor* SpecialEventScript, FGameplayTag PhaseTag);
void AttemptFinishPhaseHook(AActor* SpecialEventScript, FGameplayTag PhaseTag)
{
LOG_INFO(LogDev, "SpecialEventScript::AttemptFinishPhase PhaseTag: {}", PhaseTag.TagName.ToString());
static auto ReplicatedActivePhaseIndexOffset = SpecialEventScript->GetOffset("ReplicatedActivePhaseIndex"); // Sets what Map/Phase were replicating to clients.
auto LastTag = PhaseTag.TagName.ToString();
static auto OnRep_ReplicatedActivePhaseIndexFn = FindObject<UFunction>("/Script/SpecialEventGameplayRuntime.SpecialEventScript.OnRep_ReplicatedActivePhaseIndex");
auto& Connections = GetWorld()->GetNetDriver()->GetClientConnections();
if (LastTag == "Kiwi.Phase.Islands") // PrisonBlocks (Event Start)
{
SpecialEventScript->Get<int32>(ReplicatedActivePhaseIndexOffset) = 1;
for (int i = 0; i < Connections.Num(); i++)
{
auto CurrentPawn = Cast<AFortPlayerPawn>(Connections.At(i)->GetPlayerController()->GetPawn());
CurrentPawn->TeleportTo(FVector(34640.0f, 32350.0f, 100600.0f), CurrentPawn->GetActorRotation());
CurrentPawn->ServerChoosePart(EFortCustomPartType::Backpack, FindObject("/Kiwi/Gameplay/Blueprints/Backpack/CP_Backpack_Kiwi.CP_Backpack_Kiwi"));
}
}
if (LastTag == "Kiwi.Phase.Prison") // Kevin
{
SpecialEventScript->Get<int32>(ReplicatedActivePhaseIndexOffset) = 2;
}
if (LastTag == "Kiwi.Phase.ObservationRoom") // Hangar
{
SpecialEventScript->Get<int32>(ReplicatedActivePhaseIndexOffset) = 3;
}
if (LastTag == "Kiwi.Phase.Hanger") // Ending
{
SpecialEventScript->Get<int32>(ReplicatedActivePhaseIndexOffset) = 4;
}
SpecialEventScript->ProcessEvent(OnRep_ReplicatedActivePhaseIndexFn);
return AttemptFinishPhaseOriginal(SpecialEventScript, PhaseTag);
}
// Used to teleport the pawn in some events, not used in all parts of rift tour for some reason.
static void (*TeleportPlayerPawnOriginal)(UObject* Context, FFrame& Stack, void* Ret);
void TeleportPlayerPawnHook(UObject* Context, FFrame& Stack, void* Ret)
{
LOG_INFO(LogEvent, "Teleported PlayerPawn!");
UObject* WorldContextObject;
AFortPlayerPawn* PlayerPawn; //(Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FVector DestLocation; //(Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
FRotator DestRotation; //(Parm, ZeroConstructor, IsPlainOldData, NoDestructor, NativeAccessSpecifierPublic)
bool bIgnoreCollision; //(Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
bool bIgnoreSupplementalKillVolumeSweep; //(Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
Stack.StepCompiledIn(&WorldContextObject);
Stack.StepCompiledIn(&PlayerPawn);
Stack.StepCompiledIn(&DestLocation);
Stack.StepCompiledIn(&DestRotation);
Stack.StepCompiledIn(&bIgnoreCollision);
Stack.StepCompiledIn(&bIgnoreSupplementalKillVolumeSweep);
PlayerPawn->TeleportTo(DestLocation, DestRotation);
return TeleportPlayerPawnOriginal(Context, Stack, Ret);
}
/*
// Storm King Spawning, I might put this in its own class soon.
bool bStormKingSpawned = false;
static inline void (*DADBroOnGamephaseStepChangedOriginal)(UObject* Context, FFrame& Stack, void* Ret);
void DADBroOnGamephaseStepChangedHook(UObject* Context, FFrame& Stack, void* Ret)
{
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
if (!GameState)
return DADBroOnGamephaseStepChangedOriginal(Context, Stack, Ret);
FRotator Rotation;
Context->ProcessEvent(Context->FindFunction("GetDesiredDadBroRotation"), &Rotation);
if (GameState->GetGamePhaseStep() == EAthenaGamePhaseStep::StormShrinking && bStormKingSpawned == false)
{
auto StormKing = GetWorld()->SpawnActor<AActor>(FindObject<UClass>("/Game/Athena/DADBRO/DADBRO_Pawn.DADBRO_Pawn_C"), FVector{ 5150.0f, 4900.0f, -100.0f }, Rotation.Quaternion(), FVector{ 1,1,1 }, CreateSpawnParameters(ESpawnActorCollisionHandlingMethod::AlwaysSpawn));
if (StormKing)
{
bStormKingSpawned = true;
Context->Get<AActor*>(Context->GetOffset("DadBroPawn")) = StormKing;
Context->ProcessEvent(Context->FindFunction("OnRep_DadBroPawn"));
}
else
{
LOG_INFO(LogDev, "Failed to spawn StormKing!");
}
}
return DADBroOnGamephaseStepChangedOriginal(Context, Stack, Ret);
}
*/
static void (*StartEventAtIndexOriginal)(UObject* Context, FFrame& Stack, void* Ret);
void StartEventAtIndexHook(UObject* Context, FFrame& Stack, void* Ret)
{
int32 InStartingIndex;
Stack.StepCompiledIn(&InStartingIndex);
if (Fortnite_Version == 17.50)
{
auto Scripting = FindObject<UObject>("/Kiwi/Levels/Kiwi_P.Kiwi_P:PersistentLevel.BP_Kiwi_Master_Scripting_2");
auto EventPlaylist = GetEventPlaylist();
struct { UObject* GameState; UObject* Playlist; FGameplayTagContainer PlaylistContextTags; } OnReadyParams{ Cast<AFortGameStateAthena>(GetWorld()->GetGameState()), EventPlaylist };
if (EventPlaylist)
{
static auto GameplayTagContainerOffset = EventPlaylist->GetOffset("GameplayTagContainer");
OnReadyParams.PlaylistContextTags = EventPlaylist->Get<FGameplayTagContainer>(GameplayTagContainerOffset);
}
else
{
OnReadyParams.PlaylistContextTags = FGameplayTagContainer();
}
Scripting->ProcessEvent(Scripting->FindFunction("OnReady_F1A32853487CB7603278E6847A5F2625"), &OnReadyParams);
Context->ProcessEvent(Context->FindFunction("LoadKiwiAssets"), &OnReadyParams);
Context->ProcessEvent(Context->FindFunction("BP_OnScriptReady"), &OnReadyParams);
Scripting->ProcessEvent(Scripting->FindFunction("startevent"), &InStartingIndex);
}
return StartEventAtIndexOriginal(Context, Stack, Ret);
}
static __int64 (*FlowStep_SetPhaseToActiveOriginal)(AActor* SpecialEventPhase);
__int64 FlowStep_SetPhaseToActiveHook(AActor* SpecialEventPhase)
@@ -297,14 +702,17 @@ void ChangeLevels()
}
else
{
if (FindGIsServer())
if (Fortnite_Version != 18.10)
{
*(bool*)FindGIsServer() = true;
}
if (FindGIsServer())
{
*(bool*)FindGIsServer() = true;
}
if (FindGIsClient())
{
*(bool*)FindGIsClient() = false;
if (FindGIsClient())
{
*(bool*)FindGIsClient() = false;
}
}
if (bShouldRemoveLocalPlayer)
@@ -509,6 +917,8 @@ DWORD WINAPI Main(LPVOID)
if (Fortnite_Version == 17.30) // Rift Tour stuff
{
auto busCrash = Hooking::MinHook::Hook(Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 6C 24 ? 56 57 41 54 41 56 41 57 48 83 EC 40 48 8B 59 28 45 33 E4").GetAs<PVOID>(), (PVOID)EmptyHook);
Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3E07910), (PVOID)GetMeshNetworkNodeTypeHook, nullptr);
Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3DED158), (PVOID)ReturnTrueHook, nullptr); // 7FF7E556D158
Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3DECFC8), (PVOID)ReturnTrueHook, nullptr); // 7FF7E556CFC8
@@ -523,7 +933,8 @@ DWORD WINAPI Main(LPVOID)
Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3E5496C), (PVOID)ReturnTrueHook, nullptr); // 7FF638A0496C
Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3E54A68), (PVOID)ReturnTrueHook, nullptr); // 7FF638A04A68
// Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + ), (PVOID)ReturnFalseHook, nullptr);
Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3E4D768), (PVOID)ActivatePhaseAtIndexHook, (PVOID*)&ActivatePhaseAtIndexOriginal); // 07FF6389FD768
Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3E4D768), (PVOID)ActivatePhaseAtIndexHook, (PVOID*)&ActivatePhaseAtIndexOriginal); // 07FF6389FD768
Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3E4DFA4), (PVOID)AttemptFinishPhaseHook, (PVOID*)&AttemptFinishPhaseOriginal);
}
else if (Fortnite_Version == 18.40)
{
@@ -535,6 +946,30 @@ DWORD WINAPI Main(LPVOID)
Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x41624C8), (PVOID)ActivatePhaseAtIndexHook, (PVOID*)&ActivatePhaseAtIndexOriginal); // 7FF79E3E24C8
}
if (Globals::bGoingToPlayEvent)
{
if (Fortnite_Version >= 17.30)
{
Hooking::MinHook::Hook(FindObject<UObject>("/Script/FortniteGame.Default__FortMissionLibrary"), FindObject<UFunction>(L"/Script/FortniteGame.FortMissionLibrary:TeleportPlayerPawn"), TeleportPlayerPawnHook,
(PVOID*)&TeleportPlayerPawnOriginal, false, true);
// Todo hook UBuffetRacePlayerMovementComponent::ServerTeleportPlayer?
}
if (Fortnite_Version == 17.50)
{
Hooking::MinHook::Hook(FindObject<UObject>("/Script/SpecialEventGameplayRuntime.Default__SpecialEventScript"), FindObject<UFunction>(L"/Script/SpecialEventGameplayRuntime.SpecialEventScript:StartEventAtIndex"), StartEventAtIndexHook,
(PVOID*)&StartEventAtIndexOriginal, false, true);
}
}
if (Fortnite_Version >= 17.00) // Fixes random crash that happens a couple minutes after server starts for s17+
{
uintptr_t ServerCrashFix = Memcury::Scanner::FindPattern("48 89 5C 24 10 48 89 6C 24 20 56 57 41 54 41 56 41 57 48 81 EC ? ? ? ? 65 48 8B 04 25 ? ? ? ? 4C 8B F9").Get();
LOG_INFO(LogDev, "ServerCrashFix: 0x{:x}", ServerCrashFix);
Hooking::MinHook::Hook((PVOID)ServerCrashFix, (PVOID)ReturnFalseHook, nullptr);
}
/*
if (Fortnite_Version == 6.21)
@@ -648,10 +1083,17 @@ DWORD WINAPI Main(LPVOID)
Hooking::MinHook::Hook(GameModeDefault, FindObject<UFunction>(L"/Script/Engine.GameMode.ReadyToStartMatch"), AFortGameModeAthena::Athena_ReadyToStartMatchHook,
(PVOID*)&AFortGameModeAthena::Athena_ReadyToStartMatchOriginal, false, false, true);
Hooking::MinHook::Hook(GameModeDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortGameModeAthena.OnAircraftEnteredDropZone"), AFortGameModeAthena::OnAircraftEnteredDropZoneHook,
(PVOID*)&AFortGameModeAthena::OnAircraftEnteredDropZoneOriginal, false, false, true, true);
if (Fortnite_Version > 3.3) // 0xE9 on 3.3 (assumed every build below)
{
Hooking::MinHook::Hook(GameModeDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortGameModeAthena.OnAircraftEnteredDropZone"), AFortGameModeAthena::OnAircraftEnteredDropZoneHook,
(PVOID*)&AFortGameModeAthena::OnAircraftEnteredDropZoneOriginal, false, false, true, true);
}
Hooking::MinHook::Hook(GameModeDefault, FindObject<UFunction>(L"/Script/Engine.GameModeBase.SpawnDefaultPawnFor"),
AGameModeBase::SpawnDefaultPawnForHook, nullptr, false);
// Hooking::MinHook::Hook(GameModeDefault, FindObject<UFunction>(L"/Script/Engine.GameModeBase.PlayerCanRestart"),
// AGameModeBase::PlayerCanRestartHook, (PVOID*)&AGameModeBase::PlayerCanRestartOriginal, false, true);
Hooking::MinHook::Hook(GameModeDefault, FindObject<UFunction>(L"/Script/Engine.GameModeBase.HandleStartingNewPlayer"), AFortGameModeAthena::Athena_HandleStartingNewPlayerHook,
(PVOID*)&AFortGameModeAthena::Athena_HandleStartingNewPlayerOriginal, false);
@@ -768,8 +1210,12 @@ DWORD WINAPI Main(LPVOID)
AFortPlayerController::ServerLoadingScreenDroppedHook, (PVOID*)&AFortPlayerController::ServerLoadingScreenDroppedOriginal, false, true);
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.ServerReadyToStartMatch"),
AFortPlayerControllerAthena::ServerReadyToStartMatchHook, (PVOID*)&AFortPlayerControllerAthena::ServerReadyToStartMatchOriginal, false);
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerZone.ServerRequestSeatChange"),
AFortPlayerControllerAthena::ServerRequestSeatChangeHook, (PVOID*)&AFortPlayerControllerAthena::ServerRequestSeatChangeOriginal, false);
auto ServerRequestSeatChangeFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerZone.ServerRequestSeatChange");
if (ServerRequestSeatChangeFn)
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerZone.ServerRequestSeatChange"),
AFortPlayerControllerAthena::ServerRequestSeatChangeHook, (PVOID*)&AFortPlayerControllerAthena::ServerRequestSeatChangeOriginal, false);
// if (false)
if (Fortnite_Version > 6.10) // so on 6.10 there isa param and our little finder dont work for that so
@@ -798,14 +1244,25 @@ DWORD WINAPI Main(LPVOID)
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerAthena.ServerGiveCreativeItem"),
AFortPlayerControllerAthena::ServerGiveCreativeItemHook, nullptr, true);
static auto ServerCreativeSetFlightSpeedIndexFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerGameplay.ServerCreativeSetFlightSpeedIndex");
if (ServerCreativeSetFlightSpeedIndexFn)
Hooking::MinHook::Hook(FindObject<UObject>("/Script/FortniteGame.Default__FortPlayerControllerGameplay"), ServerCreativeSetFlightSpeedIndexFn,
AFortPlayerControllerAthena::ServerCreativeSetFlightSpeedIndexHook, nullptr, false, true);
if (Fortnite_Version < 19) // its all screwed up idk
{
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerAthena.ServerPlaySquadQuickChatMessage"),
AFortPlayerControllerAthena::ServerPlaySquadQuickChatMessageHook, nullptr, false);
}
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerAthena.ServerTeleportToPlaygroundLobbyIsland"),
AFortPlayerControllerAthena::ServerTeleportToPlaygroundLobbyIslandHook, nullptr, false);
auto ServerTeleportToPlaygroundIslandFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerAthena.ServerTeleportToPlaygroundLobbyIsland");
if (ServerTeleportToPlaygroundIslandFn)
{
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, ServerTeleportToPlaygroundIslandFn,
AFortPlayerControllerAthena::ServerTeleportToPlaygroundLobbyIslandHook, nullptr, false);
}
// Hooking::MinHook::Hook(FortPlayerStateAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerStateAthena.ServerSetInAircraft"),
// AFortPlayerStateAthena::ServerSetInAircraftHook, (PVOID*)&AFortPlayerStateAthena::ServerSetInAircraftOriginal, false, true); // We could use second method but eh
@@ -1070,9 +1527,11 @@ DWORD WINAPI Main(LPVOID)
LOG_INFO(LogDev, "ClientOnPawnDiedCallAddr: 0x{:x}", ClientOnPawnDiedCallAddr - __int64(GetModuleHandleW(0)));
Hooking::MinHook::Hook((PVOID)ClientOnPawnDiedCallAddr, AFortPlayerController::ClientOnPawnDiedHook, (PVOID*)&AFortPlayerController::ClientOnPawnDiedOriginal);
#if 0
auto OnSafeZoneStateChangeAddr = FindFunctionCall(L"OnSafeZoneStateChange", Engine_Version == 416 ? std::vector<uint8_t>{ 0x48, 0x89, 0x54 } : std::vector<uint8_t>{ 0x48, 0x89, 0x5C });
LOG_INFO(LogDev, "OnSafeZoneStateChangeAddr: 0x{:x}", OnSafeZoneStateChangeAddr - __int64(GetModuleHandleW(0)));
Hooking::MinHook::Hook((PVOID)OnSafeZoneStateChangeAddr, AFortSafeZoneIndicator::OnSafeZoneStateChangeHook, (PVOID*)&AFortSafeZoneIndicator::OnSafeZoneStateChangeOriginal);
#endif
LOG_INFO(LogDev, "PredictionKeySize: 0x{:x} {}", PredictionKeySize, PredictionKeySize);

View File

@@ -185,6 +185,34 @@ static inline std::vector<Event> Events =
false
),
Event
(
"The Showdown",
"/Game/Athena/Prototype/Blueprints/Cattus/BP_CattusDoggus_Scripting.BP_CattusDoggus_Scripting_C",
"/Game/Athena/Prototype/Blueprints/Cattus/BP_CattusDoggus_Scripting.BP_CattusDoggus_Scripting_C.LoadCattusLevel",
1,
{
{
true,
"/Game/Athena/Prototype/Blueprints/Cattus/BP_CattusDoggus_Scripting.BP_CattusDoggus_Scripting_C.OnReady_C11CA7624A74FBAEC54753A3C2BD4506"
}
},
{
{
{
true,
"/Game/Athena/Prototype/Blueprints/Cattus/BP_CattusDoggus_Scripting.BP_CattusDoggus_Scripting_C.startevent"
},
0
}
},
"/Game/Athena/Prototype/Blueprints/Cattus/BP_CattusDoggus_Scripting.BP_CattusDoggus_Scripting_C",
"/Game/Athena/Playlists/Music/Playlist_Music_High.Playlist_Music_High",
9.41,
false
),
Event
(
"The Unvaulting",
"/Game/Athena/Prototype/Blueprints/White/BP_SnowScripting.BP_SnowScripting_C",
@@ -269,7 +297,7 @@ static inline std::vector<Event> Events =
},
"/Junior/Blueprints/BP_Junior_Scripting.BP_Junior_Scripting_C",
"/Game/Athena/Playlists/Music/Playlist_Junior_32.Playlist_Junior_32",
"/Game/Athena/Playlists/Music/Playlist_Junior_32.Playlist_Junior_32", // ?
14.60
),
Event(
@@ -756,6 +784,42 @@ static inline void StartEvent()
auto SpecialEventScriptMeshActorClass = FindObject<UClass>("/Script/SpecialEventGameplayRuntime.SpecialEventScriptMeshActor");
auto AllSpecialEventScriptMeshActors = UGameplayStatics::GetAllActorsOfClass(GetWorld(), SpecialEventScriptMeshActorClass);
if (Fortnite_Version == 17.50)
{
auto Scripting = FindObject<UObject>("/Kiwi/Levels/Kiwi_P.Kiwi_P:PersistentLevel.BP_Kiwi_Master_Scripting_2");
float SecondsSinceEventBegan = 0;
auto EventPlaylist = GetEventPlaylist();
struct { UObject* GameState; UObject* Playlist; FGameplayTagContainer PlaylistContextTags; } OnReadyParams{ Cast<AFortGameStateAthena>(GetWorld()->GetGameState()), EventPlaylist };
if (EventPlaylist)
{
static auto GameplayTagContainerOffset = EventPlaylist->GetOffset("GameplayTagContainer");
OnReadyParams.PlaylistContextTags = EventPlaylist->Get<FGameplayTagContainer>(GameplayTagContainerOffset);
}
else
{
OnReadyParams.PlaylistContextTags = FGameplayTagContainer();
}
auto BB = FindObject<UFunction>("/Kiwi/Gameplay/BP_Kiwi_Master_Scripting.BP_Kiwi_Master_Scripting_C.OnReady_F1A32853487CB7603278E6847A5F2625");
Scripting->ProcessEvent(BB, &OnReadyParams);
auto eventscript = FindObject("/Kiwi/Levels/Kiwi_P.Kiwi_P:PersistentLevel.Kiwi_EventScript_2");
auto CC = FindObject<UFunction>("/Kiwi/Gameplay/Kiwi_EventScript.Kiwi_EventScript_C.OnReady_F51BF8E143832CE6C552938B26BEFA93");
auto DD = FindObject<UFunction>("/Kiwi/Gameplay/Kiwi_EventScript.Kiwi_EventScript_C.LoadKiwiAssets");
auto StartEventAtIndex = FindObject<UFunction>("/Script/SpecialEventGameplayRuntime.SpecialEventScript.StartEventAtIndex");
auto BP_OnScriptReady = FindObject<UFunction>("/Kiwi/Gameplay/Kiwi_EventScript.Kiwi_EventScript_C.BP_OnScriptReady");
// eventscript->ProcessEvent(CC, &bbparms);
eventscript->ProcessEvent(DD, &OnReadyParams);
eventscript->ProcessEvent(BP_OnScriptReady, &OnReadyParams);
eventscript->ProcessEvent(StartEventAtIndex, &SecondsSinceEventBegan);
static auto StartEvent = FindObject<UFunction>("/Kiwi/Gameplay/BP_Kiwi_Master_Scripting.BP_Kiwi_Master_Scripting_C.startevent");
Scripting->ProcessEvent(StartEvent, &SecondsSinceEventBegan);
}
if (AllSpecialEventScriptMeshActors.Num() > 0)
{
auto SpecialEventScriptMeshActor = AllSpecialEventScriptMeshActors.at(0);
@@ -824,4 +888,4 @@ static inline bool DoesEventRequireLoading()
}
return false;
}
}

View File

@@ -4,7 +4,7 @@
void SetZoneToIndexHook(AFortGameModeAthena* GameModeAthena, int OverridePhaseMaybeIDFK)
{
static auto ZoneDurationsOffset = Fortnite_Version >= 15 && Fortnite_Version < 18 ? 0x258
static auto ZoneDurationsOffset = Fortnite_Version >= 15.20 && Fortnite_Version < 18 ? 0x258
: std::floor(Fortnite_Version) >= 18 ? 0x248
: 0x1F8; // S13-S14
@@ -170,4 +170,4 @@ void SetZoneToIndexHook(AFortGameModeAthena* GameModeAthena, int OverridePhaseMa
else
LOG_WARN(LogZone, "Invalid SafeZoneIndicator!");
}
}
}

View File

@@ -44,6 +44,90 @@ uint64 FindStartAircraftPhase()
return 0;
}
uint64 FindGIsClient()
{
/* if (Fortnite_Version >= 20)
return 0; */
auto Addr = Memcury::Scanner::FindStringRef(L"AllowCommandletRendering");
std::vector<std::vector<uint8_t>> BytesArray = {
// {0x88, 0x05}, // Idk what version this is
{0xC6, 0x05}, // mov cs X // Checked on 1.11, 12.41
{0x88, 0x1D}, // mov cs bl // Checked on 17.50, 19.10
// {0x44, 0x88} // IDK WHAT VERSION This for but it scuffs older builds
};
int Skip = 2; // Skip GIsServer and some variable i forgot
uint64 Addy;
for (int i = 0; i < 50; i++) // we should subtract from skip if go up
{
auto CurrentByte = *(Memcury::ASM::MNEMONIC*)(Addr.Get() - i);
// if (bPrint)
// std::cout << "CurrentByte: " << std::hex << (int)CurrentByte << '\n';
bool ShouldBreak = false;
// LOG_INFO(LogDev, "[{}] Byte: 0x{:x}", i, (int)CurrentByte);
for (auto& Bytes : BytesArray)
{
if (CurrentByte == Bytes[0])
{
bool Found = true;
for (int j = 1; j < Bytes.size(); j++)
{
if (*(Memcury::ASM::MNEMONIC*)(Addr.Get() - i + j) != Bytes[j])
{
Found = false;
break;
}
}
if (Found)
{
int Relative = Bytes[0] == 0x44 ? 3 : 2;
auto current = Memcury::Scanner(Addr.Get() - i);
// LOG_INFO(LogDev, "[{}] No Rel 0x{:x} Rel: 0x{:x}", Skip, current.Get() - __int64(GetModuleHandleW(0)), Memcury::Scanner(Addr.Get() - i).RelativeOffset(Relative).Get() - __int64(GetModuleHandleW(0)));
if (Skip > 0)
{
Skip--;
continue;
}
Addy = Bytes[0] == 0xC6
? current.RelativeOffset(Relative, 1).Get() // If mov cs then we add 1 because the last byte is the value and makes whole instructions 1 byte longer
: current.RelativeOffset(Relative).Get();
ShouldBreak = true;
break;
}
}
}
if (ShouldBreak)
break;
// std::cout << std::format("CurrentByte: 0x{:x}\n", (uint8_t)CurrentByte);
}
// LOG_INFO(LogDev, "Addy: 0x{:x}", Addy - __int64(GetModuleHandleW(0)));
return Addy; // 0; // Memcury::Scanner(Addy3).RelativeOffset(2).Get();
/*
auto Addr = Memcury::Scanner::FindStringRef(L"AllowCommandletRendering");
int Skip = 1;
auto Addy = FindBytes(Addr, { 0xC6, 0x05 }, 50, 0, true, Skip);
Addy = Addy ? Addy : FindBytes(Addr, { 0x44, 0x88 }, 50, 0, true, Skip);
Addy = Addy ? Addy : FindBytes(Addr, { 0x88, 0x1D }, 50, 0, true, Skip);
return Memcury::Scanner(Addy).RelativeOffset(2).Get();
*/
}
uint64 FindGetSessionInterface()
{
auto strRef = Memcury::Scanner::FindStringRef(L"OnDestroyReservedSessionComplete %s bSuccess: %d", true, 0, Fortnite_Version >= 19).Get();

View File

@@ -171,6 +171,9 @@ static inline uint64 FindAddToAlivePlayers()
static inline uint64 FindFinishResurrection()
{
if (Engine_Version < 423)
return 0;
uintptr_t Addrr = Engine_Version >= 427 ? FindNameRef(L"OnResurrectionCompleted") : FindFunctionCall(L"OnResurrectionCompleted"); // Call is inlined
if (!Addrr)
@@ -244,7 +247,12 @@ static inline uint64 FindPickupInitialize()
if (Engine_Version == 419)
return Memcury::Scanner::FindPattern("48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 20 80 B9 ? ? ? ? ? 41 0F B6 E9").Get(); // 1.11
if (Engine_Version == 420)
{
if (Fortnite_Version <= 3.3)
return Memcury::Scanner::FindPattern("48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 20 80 B9 ? ? ? ? ? 41 0F B6 E9 49 8B F8 48 8B F1 0F 85 ? ? ? ? 48 83 7A").Get(); // 3.3
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 41 56 48 83 EC 20 80 B9 ? ? ? ? ? 45 0F B6 F1 49 8B E8").Get(); // 4.1
}
if (Engine_Version == 421)
{
auto addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 55 57 41 57 48 83 EC 30 80 B9 ? ? ? ? ? 41 0F B6", false).Get(); // 6.21
@@ -347,6 +355,9 @@ static inline uint64 FindInitHost()
if (!addr) // s18
addr = Memcury::Scanner::FindPattern("48 8B C4 48 89 58 10 48 89 70 18 48 89 78 20 55 41 56 41 57 48 8D 68 A1 48 81 EC ? ? ? ? 48 8B F1 4C 8D 35 ? ? ? ? 4D").Get();
if (Fortnite_Version == 18.10)
addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 55 57 41 56 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B F1 48 8D 1D ? ? ? ? 4C 8B C3 48 8D 4D D7 45").Get();
return addr;
}
@@ -504,7 +515,9 @@ static inline uint64 FindFree()
{
uint64 addr = 0;
if (Engine_Version >= 420 && Engine_Version <= 426)
if (Fortnite_Version <= 3.3) // todo check 3.4
addr = Memcury::Scanner::FindPattern("48 85 C9 74 1D 4C 8B 05 ? ? ? ? 4D 85 C0 0F 84").Get();
else if (Engine_Version >= 420 && Engine_Version <= 426)
addr = Memcury::Scanner::FindPattern("48 85 C9 74 2E 53 48 83 EC 20 48 8B D9").Get();
else if (Engine_Version >= 427)
addr = Memcury::Scanner::FindPattern("48 85 C9 0F 84 ? ? ? ? 53 48 83 EC 20 48 89 7C 24 ? 48 8B D9 48 8B 3D").Get();
@@ -519,7 +532,7 @@ static inline uint64 FindStepExplicitProperty()
static inline uint64 FindIsNetRelevantForOffset()
{
if (Engine_Version == 416) // checked on 1.7.2 & 1.8
if (Engine_Version == 416 || Fortnite_Version == 3.3) // checked on 1.7.2 & 1.8 & 3.3
return 0x420 / 8;
if (Fortnite_Version == 1.11 || (Fortnite_Version >= 2.42 && Fortnite_Version <= 3.2)) // checked 1.11, 2.4.2, 2.5, 3.0, 3.1
return 0x418 / 8;
@@ -544,7 +557,7 @@ static inline uint64 FindSpawnActor()
auto Addr = Memcury::Scanner::FindStringRef(L"SpawnActor failed because no class was specified");
if (Engine_Version >= 416 && Fortnite_Version <= 3.2)
if (Engine_Version >= 416 && Fortnite_Version <= 3.3)
return FindBytes(Addr, { 0x40, 0x55 }, 3000, 0, true);
return FindBytes(Addr, { 0x4C, 0x8B, 0xDC }, 3000, 0, true);
@@ -668,7 +681,9 @@ static inline uint64 FindSpecConstructor()
static inline uint64 FindCreateBuildingActorCallForDeco() // kill me
{
auto Addrr = Memcury::Scanner::FindStringRef(L"ServerCreateBuildingAndSpawnDeco called without a valid DecoItemDef").Get(); // honestly L (we should get it from the ufunc not string)
return 0;
auto Addrr = Memcury::Scanner::FindStringRef(L"ServerCreateBuildingAndSpawnDeco called without a valid DecoItemDef", false).Get(); // honestly L (we should get it from the ufunc not string)
if (!Addrr)
return 0;
@@ -821,7 +836,14 @@ static inline uint64 FindNoMCP()
return Memcury::Scanner::FindPattern("E8 ? ? ? ? 90 EB EA").RelativeOffset(1).Get();
if (std::floor(Fortnite_Version) == 3)
return Memcury::Scanner::FindPattern("E8 ? ? ? ? 83 A7 ? ? ? ? ? 48 8D 4C 24 ?").RelativeOffset(1).Get();
{
auto cuh = Memcury::Scanner::FindPattern("E8 ? ? ? ? 83 A7 ? ? ? ? ? 48 8D 4C 24 ?");
if (!cuh.Get())
cuh = Memcury::Scanner::FindPattern(""); // 3.3
return cuh.RelativeOffset(1).Get();
}
if (std::floor(Fortnite_Version) == 4)
return Memcury::Scanner::FindPattern("E8 ? ? ? ? 83 A7 ? ? ? ? ? 83 E0 01").RelativeOffset(1).Get();
@@ -1106,7 +1128,7 @@ static inline uint64 FindCollectGarbage()
static inline uint64 FindActorGetNetMode()
{
// return 0;
return 0; // We *shouldnt* need to hook this now because I fixed FindGIsClient
if (Engine_Version == 500) // hah well this and 427 does like nothing cuz inline mostly
{
@@ -1454,87 +1476,13 @@ static inline uint64 FindDispatchRequest()
static inline uint64 FindMcpIsDedicatedServerOffset()
{
if (Engine_Version == 421 || Engine_Version == 422) // checked on 5.41 & 6.21 & 7.30
if (Fortnite_Version >= 4.5 && Engine_Version <= 422) // checked on 4.5 & 5.41 & 6.21 & 7.30
return 0x28;
return 0x60; // 1.7.2 & 1.11 & 4.1
return 0x60; // 1.7.2 & 1.11 3.3 & & 4.1
}
static inline uint64 FindGIsClient()
{
/* if (Fortnite_Version >= 20)
return 0; */
auto Addr = Memcury::Scanner::FindStringRef(L"AllowCommandletRendering");
std::vector<std::vector<uint8_t>> BytesArray = { {0x88, 0x05}, {0xC6, 0x05}, {0x88, 0x1D}, {0x44, 0x88}};
int Skip = Engine_Version <= 420 ? 1 : 2;
uint64 Addy;
for (int i = 0; i < 50; i++) // we should subtract from skip if goup
{
auto CurrentByte = *(Memcury::ASM::MNEMONIC*)(Addr.Get() - i);
// if (bPrint)
// std::cout << "CurrentByte: " << std::hex << (int)CurrentByte << '\n';
bool ShouldBreak = false;
// LOG_INFO(LogDev, "[{}] Byte: 0x{:x}", i, (int)CurrentByte);
for (auto& Bytes : BytesArray)
{
if (CurrentByte == Bytes[0])
{
bool Found = true;
for (int j = 1; j < Bytes.size(); j++)
{
if (*(Memcury::ASM::MNEMONIC*)(Addr.Get() - i + j) != Bytes[j])
{
Found = false;
break;
}
}
if (Found)
{
int Relative = Bytes[0] == 0x44 ? 3 : 2;
// LOG_INFO(LogDev, "[{}] No Rel 0x{:x} Rel: 0x{:x}", Skip, Memcury::Scanner(Addr.Get() - i).Get() - __int64(GetModuleHandleW(0)), Memcury::Scanner(Addr.Get() - i).RelativeOffset(Relative).Get() - __int64(GetModuleHandleW(0)));
if (Skip > 0)
{
Skip--;
continue;
}
Addy = Memcury::Scanner(Addr.Get() - i).RelativeOffset(Relative).Get();
ShouldBreak = true;
break;
}
}
}
if (ShouldBreak)
break;
// std::cout << std::format("CurrentByte: 0x{:x}\n", (uint8_t)CurrentByte);
}
// LOG_INFO(LogDev, "Addy: 0x{:x}", Addy - __int64(GetModuleHandleW(0)));
return Addy; // 0; // Memcury::Scanner(Addy3).RelativeOffset(2).Get();
/*
auto Addr = Memcury::Scanner::FindStringRef(L"AllowCommandletRendering");
int Skip = 1;
auto Addy = FindBytes(Addr, { 0xC6, 0x05 }, 50, 0, true, Skip);
Addy = Addy ? Addy : FindBytes(Addr, { 0x44, 0x88 }, 50, 0, true, Skip);
Addy = Addy ? Addy : FindBytes(Addr, { 0x88, 0x1D }, 50, 0, true, Skip);
return Memcury::Scanner(Addy).RelativeOffset(2).Get();
*/
}
uint64 FindGIsClient(); // AHHH
static inline uint64 FindGetNetMode()
{
@@ -1812,18 +1760,15 @@ static inline uint64 FindReplaceBuildingActor()
static inline uint64 FindSendClientAdjustment()
{
if (Fortnite_Version <= 3.2)
return Memcury::Scanner::FindPattern("40 53 48 83 EC 20 48 8B 99 ? ? ? ? 48 39 99 ? ? ? ? 74 0A 48 83 B9").Get();
if (Fortnite_Version >= 20)
return Memcury::Scanner::FindPattern("40 53 48 83 EC 20 48 8B 99 ? ? ? ? 48 39 99 ? ? ? ? 74 0A 48 83 B9").Get();
return 0;
return Memcury::Scanner::FindPattern("40 53 48 83 EC 20 48 8B 99 ? ? ? ? 48 39 99 ? ? ? ? 74 0A 48 83 B9", false).Get();
}
static inline uint64 FindReplicateActor()
{
if (Engine_Version == 416)
return Memcury::Scanner::FindPattern("40 55 53 57 41 56 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 48 8D 59 68 4C 8B F1 48 8B").Get();
if (Fortnite_Version == 3.3)
return Memcury::Scanner::FindPattern("48 8B C4 55 53 48 8D A8 ? ? ? ? 48 81 EC ? ? ? ? 0F 29 70 A8 0F 29 78 98 48 89 70 E8 4C").Get();
if (Engine_Version >= 419 && Fortnite_Version <= 3.2)
{
auto addr = Memcury::Scanner::FindPattern("40 55 56 57 41 54 41 55 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 4C", false).Get(); // 3.0, we could just use this sig for everything?
@@ -1842,7 +1787,7 @@ static inline uint64 FindReplicateActor()
static inline uint64 FindCreateChannel()
{
if (Fortnite_Version <= 3.2)
if (Fortnite_Version <= 3.3)
return Memcury::Scanner::FindPattern("40 56 57 41 54 41 55 41 57 48 83 EC 60 48 8B 01 41 8B F9 45 0F B6 E0").Get();
if (Fortnite_Version >= 20)
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 44 89 4C 24 ? 55 57 41 54 41 56 41 57 48 8B EC 48 83 EC 50 45 33 E4 48 8D 05 ? ? ? ? 44 38 25").Get();
@@ -1852,14 +1797,19 @@ static inline uint64 FindCreateChannel()
static inline uint64 FindSetChannelActor()
{
// string ref??
if (Engine_Version == 416)
return Memcury::Scanner::FindPattern("4C 8B DC 55 53 57 41 54 49 8D AB ? ? ? ? 48 81 EC ? ? ? ? 45 33").Get();
if (Engine_Version >= 419 && Fortnite_Version <= 3.2)
if (Engine_Version >= 419 && Fortnite_Version <= 3.3)
{
if (Fortnite_Version == 3.3)
return Memcury::Scanner::FindPattern("48 8B C4 55 53 48 8D A8 ? ? ? ? 48 81 EC ? ? ? ? 48 89 70 10 48 8B D9 48 89 78 18 48 8D 35").Get();
auto aa = Memcury::Scanner::FindPattern("48 8B C4 55 53 57 41 54 48 8D A8 ? ? ? ? 48 81 EC ? ? ? ? 45 33 E4 48 89 70", false).Get();
if (!aa)
return Memcury::Scanner::FindPattern("48 8B C4 55 53 48 8D A8 ? ? ? ? 48 81 EC ? ? ? ? 48 89 70 E8 48 8B D9").Get();
return Memcury::Scanner::FindPattern("48 8B C4 55 53 48 8D A8 ? ? ? ? 48 81 EC ? ? ? ? 48 89 70 E8 48 8B D9").Get(); // 3.2
return aa;
}
@@ -1875,7 +1825,7 @@ static inline uint64 FindCallPreReplication()
return Memcury::Scanner::FindPattern("48 85 D2 0F 84 ? ? ? ? 48 8B C4 55 57 41 57 48 8D 68 A1 48 81 EC").Get();
if (Engine_Version == 419)
return Memcury::Scanner::FindPattern("48 85 D2 0F 84 ? ? ? ? 48 8B C4 55 57 41 54 48 8D 68 A1 48 81 EC ? ? ? ? 48 89 58 08 4C").Get();
if (Fortnite_Version >= 2.5 && Fortnite_Version <= 3.2)
if (Fortnite_Version >= 2.5 && Fortnite_Version <= 3.3)
return Memcury::Scanner::FindPattern("48 85 D2 0F 84 ? ? ? ? 56 41 56 48 83 EC 38 4C 8B F2").Get();
if (Fortnite_Version >= 20)
return Memcury::Scanner::FindPattern("48 85 D2 0F 84 ? ? ? ? 48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 41 56 41 57 48 83 EC 40 F6 41 58 30 48 8B EA 48 8B D9 40 B6 01").Get();

View File

@@ -16,6 +16,7 @@ namespace Globals
extern inline bool bInfiniteMaterials = false;
extern inline bool bInfiniteAmmo = false;
extern inline bool bShouldUseReplicationGraph = false;
extern inline bool bHitReadyToStartMatch = false;
extern inline bool bInitializedPlaylist = false;

View File

@@ -110,6 +110,11 @@ static inline void SetIsLategame(bool Value)
StartingShield = Value ? 100 : 0;
}
static inline bool HasAnyCalendarModification()
{
return Calendar::HasSnowModification() || Calendar::HasNYE() || std::floor(Fortnite_Version) == 13;
}
static inline void Restart() // todo move?
{
FString LevelA = Engine_Version < 424
@@ -378,7 +383,7 @@ static inline void MainTabs()
}
}
if (ImGui::BeginTabItem("Calendar Events"))
if (HasAnyCalendarModification() && ImGui::BeginTabItem("Calendar Events"))
{
Tab = CALENDAR_TAB;
PlayerTab = -1;
@@ -855,6 +860,23 @@ static inline void MainUI()
StartEvent();
}
if (Fortnite_Version == 18.40)
{
if (ImGui::Button("Remove Storm Effect"))
{
auto ClientConnections = GetWorld()->GetNetDriver()->GetClientConnections();
for (int i = 0; i < ClientConnections.Num(); i++)
{
auto CurrentController = (AFortPlayerControllerAthena*)ClientConnections.At(i)->GetPlayerController();
static auto StormEffectClass = FindObject<UClass>(L"/Game/Athena/SafeZone/GE_OutsideSafeZoneDamage.GE_OutsideSafeZoneDamage_C");
auto PlayerState = CurrentController->GetPlayerStateAthena();
PlayerState->GetAbilitySystemComponent()->RemoveActiveGameplayEffectBySourceEffect(StormEffectClass, 1, PlayerState->GetAbilitySystemComponent());
}
}
}
if (Fortnite_Version == 8.51)
{
if (ImGui::Button("Unvault DrumGun"))

View File

@@ -253,7 +253,9 @@ inline __int64 GetFunctionIdxOrPtr(UFunction* Function, bool bBreakWhenHitRet =
{
// LOG_INFO(LogDev, "[{}] 0x{:x}", i, *(uint8_t*)CurrentAddy);
if (*(uint8_t*)CurrentAddy == 0xE8)
if (*(uint8_t*)CurrentAddy == 0xE8
// || *(uint8_t*)CurrentAddy == 0xE9
)
{
// LOG_INFO(LogDev, "CurrentAddy 0x{:x}", CurrentAddy - __int64(GetModuleHandleW(0)));
functionAddy = (CurrentAddy + 1 + 4) + *(int*)(CurrentAddy + 1);

View File

@@ -82,4 +82,9 @@ public:
}
};
*/
*/
struct PadHex10 { char Pad[0x10]; };
struct PadHex18 { char Pad[0x18]; };
struct PadHexA8 { char Pad[0xA8]; };
struct PadHexB0 { char Pad[0xB0]; };

8
vendor/memcury.h vendored
View File

@@ -512,9 +512,9 @@
return _address != address._address;
}
auto RelativeOffset(uint32_t offset) -> Address
auto RelativeOffset(uint32_t offset, uint32_t off2 = 0) -> Address
{
_address = ((_address + offset + 4) + *(int32_t*)(_address + offset));
_address = ((_address + offset + 4 + off2) + *(int32_t*)(_address + offset));
return *this;
}
@@ -1010,7 +1010,7 @@
return *this;
}
auto RelativeOffset(uint32_t offset) -> Scanner
auto RelativeOffset(uint32_t offset, uint32_t off2 = 0) -> Scanner
{
if (!_address.Get())
{
@@ -1018,7 +1018,7 @@
return *this;
}
_address.RelativeOffset(offset);
_address.RelativeOffset(offset, off2);
return *this;
}