This commit is contained in:
Milxnor
2023-03-19 11:44:05 -04:00
parent 8a4f50fd71
commit dccaca63d6
22 changed files with 361 additions and 80 deletions

View File

@@ -10,5 +10,5 @@ class AFortAthenaSupplyDrop : public ABuildingGameplayActor
public:
static inline AFortPickup* (*SpawnPickupOriginal)(UObject* Context, FFrame& Stack, AFortPickup** Ret);
static AFortPickup* SpawnPickupHook(UObject* Context, FFrame& Stack, AFortPickup** Ret);
static AFortPickup* SpawnPickupHook(UObject* Context, FFrame& Stack, AFortPickup** Ret); // Unfortuanetly this function will never get called since we dont hook picklootdrops
};

View File

@@ -140,6 +140,8 @@ UObject* GetPlaylistToUse()
}
}
Playlist = FindObject("/Game/Athena/Playlists/Playground/Playlist_Playground.Playlist_Playground");
// Playlist = FindObject("/MoleGame/Playlists/Playlist_MoleGame.Playlist_MoleGame");
// Playlist = FindObject("/Game/Athena/Playlists/DADBRO/Playlist_DADBRO_Squads_8.Playlist_DADBRO_Squads_8");
@@ -205,7 +207,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
if (aeuh)
{
if (Fortnite_Version >= 13)
/* if (Fortnite_Version >= 13)
{
static auto LastSafeZoneIndexOffset = aeuh->GetOffset("LastSafeZoneIndex");
@@ -213,7 +215,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
{
*(int*)(__int64(aeuh) + LastSafeZoneIndexOffset) = 0;
}
}
} */
}
GameState->OnRep_CurrentPlaylistInfo();
@@ -497,7 +499,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
float Duration = 1000.f;
float EarlyDuration = Duration;
float TimeSeconds = 35.f; // UGameplayStatics::GetTimeSeconds(GetWorld());
float TimeSeconds = UGameplayStatics::GetTimeSeconds(GetWorld());
LOG_INFO(LogDev, "Initializing!");
LOG_INFO(LogDev, "GameMode 0x{:x}", __int64(GameMode));
@@ -578,7 +580,7 @@ int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint
{
LOG_INFO(LogTeam, "PickTeam called!");
static auto NextTeamIndex = 3;
return NextTeamIndex;
return NextTeamIndex++;
}
void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena* GameMode, AActor* NewPlayerActor)
@@ -738,9 +740,13 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
PlayerStateAthena->ProcessEvent(OnRep_bHasStartedPlayingFn);
}
static int CurrentPlayerId = 1;
// static auto PlayerIdOffset = PlayerStateAthena->GetOffset("PlayerId"); // Unable to find tf
PlayerStateAthena->GetWorldPlayerId() = ++CurrentPlayerId; // PlayerStateAthena->Get<int>(PlayerIdOffset); //
if (PlayerStateAthena->GetWorldPlayerId() == -1)
{
static int CurrentPlayerId = 1;
// static auto PlayerIdOffset = PlayerStateAthena->GetOffset("PlayerId"); // Unable to find tf
LOG_INFO(LogDev, "Old ID: {}", PlayerStateAthena->GetWorldPlayerId());
PlayerStateAthena->GetWorldPlayerId() = ++CurrentPlayerId; // PlayerStateAthena->Get<int>(PlayerIdOffset); //
}
if (Globals::bAbilitiesEnabled)
{
@@ -869,7 +875,7 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
{
auto CurrentPortal = AllPortals.at(i);
if (CurrentPortal->GetUserInitiatedLoad())
if (!CurrentPortal->GetLinkedVolume() || CurrentPortal->GetLinkedVolume()->GetVolumeState() == EVolumeState::Ready)
continue;
Portal = CurrentPortal;
@@ -888,7 +894,7 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
Portal->GetPortalOpen() = true;
static auto PlayersReadyOffset = Portal->GetOffset("PlayersReady");
static auto PlayersReadyOffset = Portal->GetOffset("PlayersReady", false);
if (PlayersReadyOffset != 0)
{
@@ -896,7 +902,11 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
PlayersReady.Add(PlayerStateUniqueId); // im not even sure what this is
}
Portal->GetUserInitiatedLoad() = true;
static auto bUserInitiatedLoadOffset = Portal->GetOffset("bUserInitiatedLoad", false);
if (bUserInitiatedLoadOffset != 0)
Portal->GetUserInitiatedLoad() = true;
Portal->GetInErrorState() = false;
static auto OwnedPortalOffset = NewPlayer->GetOffset("OwnedPortal");
@@ -907,8 +917,13 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
Portal->GetLinkedVolume()->GetVolumeState() = EVolumeState::Ready;
static auto IslandPlayset = FindObject<UFortPlaysetItemDefinition>("/Game/Playsets/PID_Playset_60x60_Composed.PID_Playset_60x60_Composed");
if (auto Volume = NewPlayer->Get<AFortVolume*>(CreativePlotLinkedVolumeOffset))
{
// if (IslandPlayset)
// Volume->UpdateSize({ (float)IslandPlayset->Get<int>("SizeX"), (float)IslandPlayset->Get<int>("SizeY"), (float)IslandPlayset->Get<int>("SizeZ") });
static auto FortLevelSaveComponentClass = FindObject<UClass>("/Script/FortniteGame.FortLevelSaveComponent");
auto LevelSaveComponent = (UObject*)Volume->GetComponentByClass(FortLevelSaveComponentClass);
@@ -922,8 +937,6 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
}
}
static auto IslandPlayset = FindObject<UFortPlaysetItemDefinition>("/Game/Playsets/PID_Playset_60x60_Composed.PID_Playset_60x60_Composed");
UFortPlaysetItemDefinition::ShowPlayset(IslandPlayset, Portal->GetLinkedVolume());
LOG_INFO(LogCreative, "Initialized player portal!");

View File

@@ -7,6 +7,15 @@
} */
bool AFortGameStateAthena::IsRespawningAllowed(AFortPlayerState* PlayerState) // actually in zone
{
static auto IsRespawningAllowedFn = FindObject<UFunction>("/Script/FortniteGame.FortGameStateZone.IsRespawningAllowed");
struct { AFortPlayerState* PlayerState; bool ReturnValue; } AFortGameStateZone_IsRespawningAllowed_Params{PlayerState};
this->ProcessEvent(IsRespawningAllowedFn, &AFortGameStateZone_IsRespawningAllowed_Params);
return AFortGameStateZone_IsRespawningAllowed_Params.ReturnValue;
}
void AFortGameStateAthena::OnRep_GamePhase()
{
EAthenaGamePhase OldGamePhase = GetGamePhase();

View File

@@ -1,6 +1,7 @@
#pragma once
#include "GameState.h"
#include "FortPlayerState.h"
enum class EAthenaGamePhase : uint8_t
{
@@ -31,6 +32,7 @@ public:
// void AddPlayerStateToGameMemberInfo(class AFortPlayerStateAthena* PlayerState);
bool IsRespawningAllowed(AFortPlayerState* PlayerState); // actually in zone
void OnRep_GamePhase();
void OnRep_CurrentPlaylistInfo();
};

View File

@@ -105,6 +105,8 @@ void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame*
// LOG_INFO(LogInteraction, "ReceivingActor Name: {}", ReceivingActor->GetFullName());
static auto FortAthenaVehicleClass = FindObject<UClass>("/Script/FortniteGame.FortAthenaVehicle");
if (auto BuildingContainer = Cast<ABuildingContainer>(ReceivingActor))
{
static auto bAlreadySearchedOffset = BuildingContainer->GetOffset("bAlreadySearched");
@@ -145,6 +147,78 @@ void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame*
// if (BuildingContainer->ShouldDestroyOnSearch())
// BuildingContainer->K2_DestroyActor();
}
else if (ReceivingActor->IsA(FortAthenaVehicleClass))
{
auto Vehicle = ReceivingActor;
ServerAttemptInteractOriginal(Context, Stack, Ret);
return;
auto Pawn = (AFortPlayerPawn*)PlayerController->GetMyFortPawn();
if (!Pawn)
return;
static auto FindSeatIndexFn = FindObject<UFunction>("/Script/FortniteGame.FortAthenaVehicle.FindSeatIndex");
static auto GetSeatWeaponComponentFn = FindObject<UFunction>("/Script/FortniteGame.FortAthenaVehicle.GetSeatWeaponComponent");
if (!GetSeatWeaponComponentFn)
return;
struct { AFortPlayerPawn* PlayerPawn; int ReturnValue; } AFortAthenaVehicle_FindSeatIndex_Params{Pawn};
Vehicle->ProcessEvent(FindSeatIndexFn, &AFortAthenaVehicle_FindSeatIndex_Params);
auto SeatIndex = AFortAthenaVehicle_FindSeatIndex_Params.ReturnValue;
struct { int SeatIndex; UObject* ReturnValue; } AFortAthenaVehicle_GetSeatWeaponComponent_Params{};
Vehicle->ProcessEvent(GetSeatWeaponComponentFn, &AFortAthenaVehicle_GetSeatWeaponComponent_Params);
auto 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++)
{
auto WeaponSeat = WeaponSeatDefinitions.AtPtr(i, WeaponSeatDefinitionStructSize);
if (*(int*)(__int64(WeaponSeat) + SeatIndexOffset) != SeatIndex)
continue;
auto VehicleWeaponDef = *(UFortWeaponItemDefinition**)(__int64(WeaponSeat) + VehicleWeaponOffset);
LOG_INFO(LogDev, "Vehicle eaponb: {}", __int64(VehicleWeaponDef));
if (!VehicleWeaponDef)
continue;
LOG_INFO(LogDev, "Vehicle eaponb name: {}", VehicleWeaponDef->GetFullName());
auto WorldInventory = PlayerController->GetWorldInventory();
auto ahh = WorldInventory->AddItem(VehicleWeaponDef, nullptr);
auto newitem = ahh.first[0];
LOG_INFO(LogDev, "newitem: {}", __int64(newitem));
if (!newitem)
return;
PlayerController->ServerExecuteInventoryItemHook(PlayerController, newitem->GetItemEntry()->GetItemGuid());
WorldInventory->Update();
break;
}
return;
}
return ServerAttemptInteractOriginal(Context, Stack, Ret);
}
@@ -179,6 +253,46 @@ void AFortPlayerController::ServerAttemptAircraftJumpHook(AFortPlayerController*
// PC->ServerRestartPlayer();
}
void AFortPlayerController::ServerDropAllItemsHook(AFortPlayerController* PlayerController, UFortItemDefinition* IgnoreItemDef)
{
auto Pawn = PlayerController->GetMyFortPawn();
if (!Pawn)
return;
auto WorldInventory = PlayerController->GetWorldInventory();
if (!WorldInventory)
return;
auto& ItemInstances = WorldInventory->GetItemList().GetItemInstances();
auto Location = Pawn->GetActorLocation();
for (int i = 0; i < ItemInstances.Num(); i++)
{
auto ItemInstance = ItemInstances.at(i);
if (!ItemInstance)
continue;
auto ItemEntry = ItemInstance->GetItemEntry();
auto WorldItemDefinition = Cast<UFortWorldItemDefinition>(ItemEntry->GetItemDefinition());
if (!WorldItemDefinition)
continue;
// if (!WorldItemDefinition->ShouldDropOnDeath())
// continue;
AFortPickup::SpawnPickup(WorldItemDefinition, Location, ItemEntry->GetCount(), EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::PlayerElimination,
ItemEntry->GetLoadedAmmo()); // I do playerelimation flag here ik we shouldnt but it makes it go in circle iirc
WorldInventory->RemoveItem(ItemEntry->GetItemGuid(), nullptr, ItemEntry->GetCount());
}
WorldInventory->Update();
}
void AFortPlayerController::ServerCreateBuildingActorHook(UObject* Context, FFrame* Stack, void* Ret)
{
auto PlayerController = Cast<AFortPlayerController>(Context);
@@ -388,11 +502,13 @@ uint8 ToDeathCause(const FGameplayTagContainer& TagContainer, bool bWasDBNO = fa
void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerController, void* DeathReport)
{
auto GameState = Cast<AFortGameStateAthena>(((AFortGameMode*)GetWorld()->GetGameMode())->GetGameState());
auto DeadPawn = Cast<AFortPlayerPawn>(PlayerController->GetPawn());
auto DeadPlayerState = Cast<AFortPlayerStateAthena>(PlayerController->GetPlayerState());
auto KillerPawn = Cast<AFortPlayerPawn>(*(AFortPawn**)(__int64(DeathReport) + MemberOffsets::DeathReport::KillerPawn));
auto KillerPlayerState = Cast<AFortPlayerStateAthena>(*(AFortPlayerState**)(__int64(DeathReport) + MemberOffsets::DeathReport::KillerPlayerState));
if (!DeadPawn)
if (!DeadPawn || !GameState || !DeadPlayerState)
return ClientOnPawnDiedOriginal(PlayerController, DeathReport);
static auto DeathInfoStruct = FindObject<UStruct>("/Script/FortniteGame.DeathInfo");
@@ -405,7 +521,7 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
auto DeathInfo = (void*)(__int64(DeadPlayerState) + MemberOffsets::FortPlayerStateAthena::DeathInfo); // Alloc<void>(DeathInfoStructSize);
RtlSecureZeroMemory(DeathInfo, DeathInfoStructSize);
auto Tags = *(FGameplayTagContainer*)(__int64(DeathReport) + MemberOffsets::DeathReport::Tags);
auto& Tags = DeadPawn->Get<FGameplayTagContainer>(MemberOffsets::FortPlayerPawn::CorrectTags); // *(FGameplayTagContainer*)(__int64(DeathReport) + /MemberOffsets::DeathReport::Tags);
// LOG_INFO(LogDev, "Tags: {}", Tags.ToStringSimple(true));
@@ -415,6 +531,7 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
*(bool*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::bDBNO) = DeadPawn->IsDBNO();
*(uint8*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::DeathCause) = DeathCause;
*(AActor**)(__int64(DeathInfo) + MemberOffsets::DeathInfo::FinisherOrDowner) = KillerPlayerState ? KillerPlayerState : DeadPlayerState;
*(FVector*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::DeathLocation) = DeathLocation;
if (MemberOffsets::DeathInfo::DeathTags != 0)
@@ -425,21 +542,30 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
if (DeathCause == FallDamageEnumValue)
{
static auto LastFallDistanceOffset = DeadPawn->GetOffset("LastFallDistance");
*(float*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::Distance) = DeadPawn->Get<float>(LastFallDistanceOffset);
*(float*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::Distance) = DeadPawn->Get<float>(MemberOffsets::FortPlayerPawnAthena::LastFallDistance);
}
else
{
*(float*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::Distance) = KillerPawn ? KillerPawn->GetDistanceTo(DeadPawn) : 0;
}
static auto PawnDeathLocationOffset = DeadPlayerState->GetOffset("PawnDeathLocation");
DeadPlayerState->Get<FVector>(PawnDeathLocationOffset) = DeathLocation;
DeadPlayerState->Get<FVector>(MemberOffsets::FortPlayerState::PawnDeathLocation) = DeathLocation;
static auto OnRep_DeathInfoFn = FindObject<UFunction>("/Script/FortniteGame.FortPlayerStateAthena.OnRep_DeathInfo");
DeadPlayerState->ProcessEvent(OnRep_DeathInfoFn);
bool bIsRespawningAllowed = true;
if (KillerPlayerState && KillerPlayerState != DeadPlayerState)
{
KillerPlayerState->Get<int>(MemberOffsets::FortPlayerStateAthena::KillScore)++;
if (MemberOffsets::FortPlayerStateAthena::TeamKillScore != 0)
KillerPlayerState->Get<int>(MemberOffsets::FortPlayerStateAthena::TeamKillScore)++;
KillerPlayerState->ClientReportKill(DeadPlayerState);
// KillerPlayerState->OnRep_Kills();
}
bool bIsRespawningAllowed = GameState->IsRespawningAllowed(DeadPlayerState);
if (!bIsRespawningAllowed)
{

View File

@@ -63,6 +63,8 @@ public:
// static void ServerCreateBuildingActorHook(AFortPlayerController* PlayerController, FCreateBuildingActorData CreateBuildingData);
static void ServerCreateBuildingActorHook(UObject* Context, FFrame* Stack, void* Ret);
static void ServerDropAllItemsHook(AFortPlayerController* PlayerController, UFortItemDefinition* IgnoreItemDef);
static void ServerAttemptInventoryDropHook(AFortPlayerController* PlayerController, FGuid ItemGuid, int Count);
static void ServerPlayEmoteItemHook(AFortPlayerController* PlayerController, UObject* EmoteAsset);
static void ClientOnPawnDiedHook(AFortPlayerController* PlayerController, void* DeathReport);

View File

@@ -47,9 +47,9 @@ void AFortPlayerPawn::ServerSendZiplineStateHook(AFortPlayerPawn* Pawn, FZipline
if (Addrr)
{
for (int i = 600; i >= 0; i--)
for (int i = 0; i < 400; i++)
{
// LOG("[{}] 0x{:x} 0x{:x}", i, (int)*(uint8_t*)Addr - i, (int)*(uint8_t*)(Addr - i), (int)*(uint8_t*)(Addr - i + 1));
// LOG_INFO(LogDev, "[{}] 0x{:x} 0x{:x}", i, (int)*(uint8_t*)Addrr - i, (int)*(uint8_t*)(Addrr - i + 1), (int)*(uint8_t*)(Addrr - i + 2));
if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x40 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x53)
{
@@ -63,6 +63,23 @@ void AFortPlayerPawn::ServerSendZiplineStateHook(AFortPlayerPawn* Pawn, FZipline
break;
}
}
/* for (int i = 600; i >= 0; i--)
{
LOG_INFO(LogDev, "[{}] 0x{:x} 0x{:x}", i, (int)*(uint8_t*)Addrr - i, (int)*(uint8_t*)(Addrr - i + 1), (int)*(uint8_t*)(Addrr - i + 2));
if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x40 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x53)
{
OnRep_ZiplineState = decltype(OnRep_ZiplineState)(Addrr - i);
break;
}
if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x48 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x89 && *(uint8_t*)(uint8_t*)(Addrr - i + 2) == 0x5C)
{
OnRep_ZiplineState = decltype(OnRep_ZiplineState)(Addrr - i);
break;
}
} */
}
LOG_INFO(LogDev, "OnRep_ZiplineState: 0x{:x}\n", (uintptr_t)OnRep_ZiplineState - __int64(GetModuleHandleW(0)));

View File

@@ -25,6 +25,12 @@ public:
return PlayerName;
}
void ClientReportKill(AFortPlayerStateAthena* Player)
{
static auto ClientReportKillFn = FindObject<UFunction>("/Script/FortniteGame.FortPlayerStateAthena.ClientReportKill");
this->ProcessEvent(ClientReportKillFn, &Player);
}
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortPlayerStateAthena");

View File

@@ -19,4 +19,10 @@ public:
static auto VolumeStateOffset = GetOffset("VolumeState");
return Get<EVolumeState>(VolumeStateOffset);
}
void UpdateSize(const FVector& Scale)
{
static auto UpdateSizeFn = FindObject<UFunction>("/Script/FortniteGame.FortVolume.UpdateSize");
this->ProcessEvent(UpdateSizeFn, (FVector*)&Scale);
}
};

View File

@@ -56,23 +56,33 @@ static FGameplayAbilitySpec* MakeNewSpec(UClass* GameplayAbilityClass, UObject*
auto DefaultAbility = bAlreadyIsDefault ? GameplayAbilityClass : GameplayAbilityClass->CreateDefaultObject();
static __int64 (*SpecConstructor)(__int64 spec, UObject* Ability, int Level, int InputID, UObject* SourceObject) = decltype(SpecConstructor)(Addresses::SpecConstructor);
static auto ActiveCountOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpec", "ActiveCount", false);
SpecConstructor(__int64(NewSpec), DefaultAbility, 0, -1, SourceObject);
constexpr bool bUseNativeSpecConstructor = true;
/* static auto LevelOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpec", "Level");
static auto SourceObjectOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpec", "SourceObject");
static auto InputIDOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpec", "InputID");
if constexpr (bUseNativeSpecConstructor)
{
static __int64 (*SpecConstructor)(__int64 spec, UObject* Ability, int Level, int InputID, UObject* SourceObject) = decltype(SpecConstructor)(Addresses::SpecConstructor);
((FFastArraySerializerItem*)NewSpec)->MostRecentArrayReplicationKey = -1;
((FFastArraySerializerItem*)NewSpec)->ReplicationID = -1;
((FFastArraySerializerItem*)NewSpec)->ReplicationKey = -1;
SpecConstructor(__int64(NewSpec), DefaultAbility, 1, -1, SourceObject);
}
else
{
static auto LevelOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpec", "Level");
static auto SourceObjectOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpec", "SourceObject");
static auto InputIDOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpec", "InputID");
static auto GameplayEffectHandleOffset = FindOffsetStruct("/Script/GameplayAbilities.GameplayAbilitySpec", "GameplayEffectHandle", false);
NewSpec->GetHandle().GenerateNewHandle();
NewSpec->GetAbility() = DefaultAbility;
*(int*)(__int64(NewSpec) + LevelOffset) = 0;
*(int*)(__int64(NewSpec) + InputIDOffset) = -1;
*(UObject**)(__int64(NewSpec) + SourceObjectOffset) = SourceObject; */
((FFastArraySerializerItem*)NewSpec)->MostRecentArrayReplicationKey = -1;
((FFastArraySerializerItem*)NewSpec)->ReplicationID = -1;
((FFastArraySerializerItem*)NewSpec)->ReplicationKey = -1;
NewSpec->GetHandle().Handle = rand(); // proper!
NewSpec->GetAbility() = DefaultAbility;
*(int*)(__int64(NewSpec) + LevelOffset) = 1;
*(int*)(__int64(NewSpec) + InputIDOffset) = -1;
*(UObject**)(__int64(NewSpec) + SourceObjectOffset) = SourceObject;
}
return NewSpec;
}

View File

@@ -15,16 +15,16 @@ TArray<AActor*> UGameplayStatics::GetAllActorsOfClass(const UObject* WorldContex
return UGameplayStatics_GetAllActorsOfClass_Params.OutActors;
}
float UGameplayStatics::GetTimeSeconds(const UObject* WorldContextObject)
float UGameplayStatics::GetTimeSeconds(UObject* WorldContextObject)
{
static auto fn = FindObject<UFunction>(L"/Script/Engine.GameplayStatics.GetTimeSeconds");
float TimeSeconds = 0;
struct { UObject* WorldContextObject; float TimeSeconds; } GetTimeSecondsParams{WorldContextObject};
static auto defaultObj = StaticClass();
defaultObj->ProcessEvent(fn, &TimeSeconds);
defaultObj->ProcessEvent(fn, &GetTimeSecondsParams);
return TimeSeconds;
return GetTimeSecondsParams.TimeSeconds;
}
UObject* UGameplayStatics::SpawnObject(UClass* ObjectClass, UObject* Outer)

View File

@@ -8,7 +8,7 @@ class UGameplayStatics : public UObject
{
public:
static TArray<AActor*> GetAllActorsOfClass(const UObject* WorldContextObject, UClass* ActorClass);
static float GetTimeSeconds(const UObject* WorldContextObject);
static float GetTimeSeconds(UObject* WorldContextObject);
static UObject* SpawnObject(UClass* ObjectClass, UObject* Outer);
static UClass* StaticClass();

View File

@@ -234,6 +234,7 @@
<ClInclude Include="CurveTable.h" />
<ClInclude Include="DataTable.h" />
<ClInclude Include="DataTableFunctionLibrary.h" />
<ClInclude Include="die.h" />
<ClInclude Include="Engine.h" />
<ClInclude Include="EngineTypes.h" />
<ClInclude Include="events.h" />

View File

@@ -416,9 +416,6 @@
<ClInclude Include="BuildingTrap.h">
<Filter>FortniteGame\Source\FortniteGame\Public\Building</Filter>
</ClInclude>
<ClInclude Include="commands.h">
<Filter>Reboot</Filter>
</ClInclude>
<ClInclude Include="FortAthenaSupplyDrop.h">
<Filter>FortniteGame\Source\FortniteGame\Public\Building\GameplayActors</Filter>
</ClInclude>
@@ -428,6 +425,12 @@
<ClInclude Include="FortMinigame.h">
<Filter>FortniteGame\Source\FortniteGame\Public\Creative\Minigame</Filter>
</ClInclude>
<ClInclude Include="die.h">
<Filter>Reboot\Public</Filter>
</ClInclude>
<ClInclude Include="commands.h">
<Filter>Reboot\Public</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Engine">

38
Project Reboot 3.0/die.h Normal file
View File

@@ -0,0 +1,38 @@
#pragma once
#include "reboot.h"
#include "FortGameModeAthena.h"
#include "GameplayStatics.h"
static inline void (*SetZoneToIndexOriginal)(AFortGameModeAthena* GameModeAthena, int OverridePhaseMaybeIDFK);
static void SetZoneToIndexHook(AFortGameModeAthena* GameModeAthena, int OverridePhaseMaybeIDFK)
{
static auto SafeZoneIndicatorOffset = GameModeAthena->GetOffset("SafeZoneIndicator");
auto SafeZoneIndicator = GameModeAthena->Get<AActor*>(SafeZoneIndicatorOffset);
static auto SafeZoneFinishShrinkTimeOffset = SafeZoneIndicator->GetOffset("SafeZoneFinishShrinkTime");
static auto SafeZoneStartShrinkTimeOffset = SafeZoneIndicator->GetOffset("SafeZoneStartShrinkTime");
static auto SafeZonePhaseOffset = GameModeAthena->GetOffset("SafeZonePhase");
auto SafeZonePhase = GameModeAthena->Get<int>(SafeZonePhaseOffset);
LOG_INFO(LogDev, "aa");
LOG_INFO(LogZone, "SafeZonePhase: {}", SafeZonePhase);
LOG_INFO(LogZone, "OverridePhaseMaybeIDFK: {}", OverridePhaseMaybeIDFK);
LOG_INFO(LogZone, "SafeZoneFinishShrinkTime Before Call: {}", SafeZoneIndicator->Get<float>(SafeZoneFinishShrinkTimeOffset));
LOG_INFO(LogZone, "SafeZoneStartShrinkTime Before Call: {}", SafeZoneIndicator->Get<float>(SafeZoneStartShrinkTimeOffset));
LOG_INFO(LogZone, "TimeSeconds: {}", UGameplayStatics::GetTimeSeconds(GetWorld()));
SafeZoneIndicator->Get<float>(SafeZoneStartShrinkTimeOffset) = UGameplayStatics::GetTimeSeconds(GetWorld());
SafeZoneIndicator->Get<float>(SafeZoneFinishShrinkTimeOffset) = SafeZoneIndicator->Get<float>(SafeZoneStartShrinkTimeOffset) + 100;
SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK);
static auto NextMegaStormGridCellThicknessOffset = SafeZoneIndicator->GetOffset("NextMegaStormGridCellThickness");
auto NextMegaStormGridCellThickness = SafeZoneIndicator->Get<float>(NextMegaStormGridCellThicknessOffset);
LOG_INFO(LogZone, "NextMegaStormGridCellThickness: {}", NextMegaStormGridCellThickness);
LOG_INFO(LogZone, "SafeZoneFinishShrinkTime After Call: {}", SafeZoneIndicator->Get<float>(SafeZoneFinishShrinkTimeOffset));
LOG_INFO(LogZone, "SafeZoneStartShrinkTime After Call: {}", SafeZoneIndicator->Get<float>(SafeZoneStartShrinkTimeOffset));
}

View File

@@ -23,6 +23,7 @@
#include "FortAthenaSupplyDrop.h"
#include "FortMinigame.h"
#include "KismetSystemLibrary.h"
#include "die.h"
enum ENetMode
{
@@ -79,7 +80,7 @@ DWORD WINAPI Main(LPVOID)
static auto FortAbilitySystemComponentAthenaDefault = FindObject<UClass>(L"/Script/FortniteGame.Default__FortAbilitySystemComponentAthena");
static auto FortKismetLibraryDefault = FindObject<UClass>(L"/Script/FortniteGame.Default__FortKismetLibrary");
// UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogAbilitySystem VeryVerbose", nullptr);
UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogAbilitySystem VeryVerbose", nullptr);
static auto SwitchLevel = FindObject<UFunction>(L"/Script/Engine.PlayerController.SwitchLevel");
FString Level = Engine_Version < 424
@@ -182,6 +183,8 @@ DWORD WINAPI Main(LPVOID)
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/Engine.PlayerController.ServerAcknowledgePossession"),
AFortPlayerControllerAthena::ServerAcknowledgePossessionHook, nullptr, false);
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.ServerDropAllItems"),
AFortPlayerController::ServerDropAllItemsHook, nullptr, false);
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.ServerAttemptInventoryDrop"),
AFortPlayerController::ServerAttemptInventoryDropHook, nullptr, false);
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.ServerCheat"),
@@ -297,14 +300,22 @@ DWORD WINAPI Main(LPVOID)
Hooking::MinHook::Hook((PVOID)Addresses::CompletePickupAnimation, (PVOID)AFortPickup::CompletePickupAnimationHook, (PVOID*)&AFortPickup::CompletePickupAnimationOriginal);
Hooking::MinHook::Hook((PVOID)Addresses::CanActivateAbility, ReturnTrueHook); // ahhh wtf
// Hooking::MinHook::Hook((PVOID)FindFunctionCall(L"ServerRemoveInventoryItem"), UFortInventoryInterface::RemoveInventoryItemHook);
// LOG_INFO(LogDev, "Hook Res: {}", Hooking::MinHook::Hook((PVOID)Addresses::SetZoneToIndex, (PVOID)SetZoneToIndexHook, (PVOID*)&SetZoneToIndexOriginal));
AddVehicleHook();
LOG_INFO(LogDev, "Test: 0x{:x}", FindFunctionCall(L"ClientOnPawnDied") - __int64(GetModuleHandleW(0)));
Hooking::MinHook::Hook((PVOID)FindFunctionCall(L"ClientOnPawnDied"), AFortPlayerController::ClientOnPawnDiedHook, (PVOID*)&AFortPlayerController::ClientOnPawnDiedOriginal);
{
MemberOffsets::FortPlayerPawn::CorrectTags = FindOffsetStruct("/Script/FortniteGame.FortPlayerPawn", "MoveSoundStimulusBroadcastInterval") + 0x10;
MemberOffsets::FortPlayerState::PawnDeathLocation = FindOffsetStruct("/Script/FortniteGame.FortPlayerState", "PawnDeathLocation");
MemberOffsets::FortPlayerPawnAthena::LastFallDistance = FindOffsetStruct("/Script/FortniteGame.FortPlayerPawnAthena", "LastFallDistance");
MemberOffsets::FortPlayerStateAthena::DeathInfo = FindOffsetStruct("/Script/FortniteGame.FortPlayerStateAthena", "DeathInfo");
MemberOffsets::FortPlayerStateAthena::KillScore = FindOffsetStruct("/Script/FortniteGame.FortPlayerStateAthena", "KillScore");
MemberOffsets::FortPlayerStateAthena::TeamKillScore = FindOffsetStruct("/Script/FortniteGame.FortPlayerStateAthena", "TeamKillScore");
MemberOffsets::DeathInfo::bDBNO = FindOffsetStruct("/Script/FortniteGame.DeathInfo", "bDBNO");
MemberOffsets::DeathInfo::DeathCause = FindOffsetStruct("/Script/FortniteGame.DeathInfo", "DeathCause");
@@ -358,11 +369,6 @@ DWORD WINAPI Main(LPVOID)
GameState->Get<float>("WarmupCountdownStartTime") = 0;
GameMode->Get<float>("WarmupEarlyCountdownDuration") = 0;
}
/* else if (GetAsyncKeyState(VK_F9) & 1)
{
GetWorld()->Listen();
} */
Sleep(1000 / 30);
}

View File

@@ -190,8 +190,9 @@ static inline uint64 FindPauseBeaconRequests()
static inline uint64 FindGetPlayerViewpoint()
{
auto Addr = Memcury::Scanner::FindStringRef(L"APlayerController::GetPlayerViewPoint: out_Location, ViewTarget=%s");
return FindBytes(Addr, { 0x48, 0x89, 0x5C }, 2000, 0, true, 1);
auto Addr = Memcury::Scanner::FindStringRef(L"APlayerController::GetPlayerViewPoint: out_Location, ViewTarget=%s", true);
// return FindBytes(Addr, { 0x48, 0x89 /*, 0x5C */}, 2000, 0, true, 1);
return FindBytes(Addr, { 0x48, 0x89, 0x74 }, 2000, 0, true);
}
static inline uint64 FindSpawnActor()
@@ -365,11 +366,13 @@ static inline uint64 FindNoMCP()
static inline uint64 FindSetZoneToIndex()
{
if (Fortnite_Version == 14.60)
return __int64(GetModuleHandleW(0)) + 0x207F9B0;
return 0;
// if (Fortnite_Version == 14.60)
// return __int64(GetModuleHandleW(0)) + 0x207F9B0;
return Memcury::Scanner::FindPattern("40 55 53 56 41 55 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 45 18 48 8B").Get();
auto Addr = Memcury::Scanner::FindStringRef(L"FortGameModeAthena: No MegaStorm on SafeZone[%d]. GridCellThickness is less than 1.0.");
return FindBytes(Addr, { 0x40, 0x55 }, 30000, 0, true);
}

View File

@@ -2,7 +2,7 @@
namespace Globals
{
extern inline bool bCreative = true;
extern inline bool bCreative = false;
extern inline bool bGoingToPlayEvent = false;
extern inline bool bNoMCP = true;
extern inline bool bLateGame = false;

View File

@@ -12,8 +12,6 @@ inline __int64 GetFunctionIdxOrPtr2(UFunction* Function)
auto FuncName = Function->GetName();
std::cout << std::format("{} Exec: 0x{:x}\n", Function->GetName(), NativeAddr - __int64(GetModuleHandleW(0)));
std::wstring ValidateWStr = (std::wstring(FuncName.begin(), FuncName.end()) + L"_Validate");
const wchar_t* ValidateWCStr = ValidateWStr.c_str();
bool bHasValidateFunc = Memcury::Scanner::FindStringRef(ValidateWCStr, false).Get();
@@ -33,8 +31,6 @@ inline __int64 GetFunctionIdxOrPtr2(UFunction* Function)
}
}
std::cout << std::format("RETT {}: 0x{:x}\n", Function->GetName(), RetAddr - __int64(GetModuleHandleW(0)));
int i = 0;
__int64 functionAddyOrOffset = 0;
@@ -53,8 +49,6 @@ inline __int64 GetFunctionIdxOrPtr2(UFunction* Function)
else */ if ((*(uint8_t*)(CurrentAddy) == 0xFF && *(uint8_t*)(CurrentAddy + 1) == 0x90) ||
*(uint8_t*)(CurrentAddy) == 0xFF && *(uint8_t*)(CurrentAddy + 1) == 0x93)
{
std::cout << "found vcall!\n";
auto SecondByte = *(uint8_t*)(CurrentAddy + 2);
auto ThirdByte = *(uint8_t*)(CurrentAddy + 3);
@@ -80,8 +74,6 @@ inline __int64 GetFunctionIdxOrPtr2(UFunction* Function)
i++;
}
std::cout << "FOUND: " << functionAddyOrOffset << '\n';
return functionAddyOrOffset;
}
@@ -90,16 +82,14 @@ inline __int64 GetFunctionIdxOrPtr(UFunction* Function)
{
auto NativeAddr = __int64(Function->GetFunc());
std::cout << std::format("{} Exec: 0x{:x}\n", Function->GetName(), NativeAddr - __int64(GetModuleHandleW(0)));
auto FuncName = Function->GetName();
std::wstring ValidateWStr = (std::wstring(FuncName.begin(), FuncName.end()) + L"_Validate");
const wchar_t* ValidateWCStr = ValidateWStr.c_str();
bool bHasValidateFunc = Memcury::Scanner::FindStringRef(ValidateWCStr, false).Get();
LOG_INFO(LogDev, "[{}] bHasValidateFunc: {}", Function->GetName(), bHasValidateFunc);
LOG_INFO(LogDev, "NativeAddr: 0x{:x}", __int64(NativeAddr) - __int64(GetModuleHandleW(0)));
// LOG_INFO(LogDev, "[{}] bHasValidateFunc: {}", Function->GetName(), bHasValidateFunc);
// LOG_INFO(LogDev, "NativeAddr: 0x{:x}", __int64(NativeAddr) - __int64(GetModuleHandleW(0)));
bool bFoundValidate = !bHasValidateFunc;
@@ -109,8 +99,8 @@ inline __int64 GetFunctionIdxOrPtr(UFunction* Function)
{
// LOG_INFO(LogDev, "0x{:x}", *(uint8_t*)(NativeAddr + i));
if ((*(uint8_t*)(NativeAddr + i) == 0xFF && *(uint8_t*)(NativeAddr + i + 1) == 0x90) ||
*(uint8_t*)(NativeAddr + i) == 0xFF && *(uint8_t*)(NativeAddr + i + 1) == 0x93)
if ((*(uint8_t*)(NativeAddr + i) == 0xFF && *(uint8_t*)(NativeAddr + i + 1) == 0x90) || // call qword ptr
*(uint8_t*)(NativeAddr + i) == 0xFF && *(uint8_t*)(NativeAddr + i + 1) == 0x93) // call qword ptr
{
if (bFoundValidate)
{
@@ -139,7 +129,7 @@ inline __int64 GetFunctionIdxOrPtr(UFunction* Function)
std::transform(wtf.begin(), wtf.end(), wtf.begin(), ::toupper);
LOG_INFO(LogDev, "wtf: {}", wtf);
// LOG_INFO(LogDev, "wtf: {}", wtf);
return HexToDec(wtf);
}
@@ -150,6 +140,41 @@ inline __int64 GetFunctionIdxOrPtr(UFunction* Function)
}
}
if ((*(uint8_t*)(NativeAddr + i) == 0x48 && *(uint8_t*)(NativeAddr + i + 1) == 0xFF) && *(uint8_t*)(NativeAddr + i + 2) == 0xA0) // jmp qword ptr
{
if (bFoundValidate)
{
std::string wtf = "";
int shots = 0;
bool bFoundFirstNumber = false;
for (__int64 z = (NativeAddr + i + 6); z != (NativeAddr + i + 2); z -= 1)
{
auto anafa = (int)(*(uint8_t*)z);
auto asfk = anafa < 10 ? "0" + std::format("{:x}", anafa) : std::format("{:x}", anafa);
// std::cout << std::format("[{}] 0x{}\n", shots, asfk);
if (*(uint8_t*)z == 0 ? bFoundFirstNumber : true)
{
wtf += asfk;
bFoundFirstNumber = true;
}
shots++;
}
std::transform(wtf.begin(), wtf.end(), wtf.begin(), ::toupper);
// LOG_INFO(LogDev, "wtf: {}", wtf);
return HexToDec(wtf);
}
}
if (!RetAddr && *(uint8_t*)(NativeAddr + i) == 0xC3)
{
RetAddr = NativeAddr + i;
@@ -163,17 +188,17 @@ inline __int64 GetFunctionIdxOrPtr(UFunction* Function)
if (RetAddr)
{
LOG_INFO(LogDev, "RetAddr 0x{:x}", RetAddr - __int64(GetModuleHandleW(0)));
// LOG_INFO(LogDev, "RetAddr 0x{:x}", RetAddr - __int64(GetModuleHandleW(0)));
int i = 0;
for (__int64 CurrentAddy = RetAddr; CurrentAddy != NativeAddr && i < 2000; CurrentAddy -= 1) // Find last call
{
LOG_INFO(LogDev, "[{}] 0x{:x}", i, *(uint8_t*)CurrentAddy);
// LOG_INFO(LogDev, "[{}] 0x{:x}", i, *(uint8_t*)CurrentAddy);
if (*(uint8_t*)CurrentAddy == 0xE8)
{
LOG_INFO(LogDev, "CurrentAddy 0x{:x}", CurrentAddy - __int64(GetModuleHandleW(0)));
// LOG_INFO(LogDev, "CurrentAddy 0x{:x}", CurrentAddy - __int64(GetModuleHandleW(0)));
functionAddy = (CurrentAddy + 1 + 4) + *(int*)(CurrentAddy + 1);
break;
}
@@ -191,6 +216,7 @@ namespace Hooking
{
static bool Hook(void* Addr, void* Detour, void** Original = nullptr)
{
LOG_INFO(LogDev, "Hooking 0x{:x}", __int64(Addr) - __int64(GetModuleHandleW(0)));
auto ret1 = MH_CreateHook(Addr, Detour, Original);
auto ret2 = MH_EnableHook(Addr);
return ret1 == MH_OK && ret2 == MH_OK;
@@ -240,6 +266,8 @@ namespace Hooking
if (Original)
*Original = DefaultClass->VFTable[Idx];
LOG_INFO(LogDev, "Hooking {} with Idx 0x{:x}", Function->GetName(), AddrOrIdx);
VirtualSwap(DefaultClass->VFTable, Idx, Detour);
return true;
@@ -253,9 +281,4 @@ namespace Hooking
return MH_DisableHook((PVOID)Addr) == MH_OK;
}
}
static bool Hook(UFunction* Function, std::function<void(UObject*, void*)> Detour) // ProcessEvent hook
{
return true;
}
}

View File

@@ -71,6 +71,7 @@ inline void InitLogger()
MakeLogger("LogAI");
MakeLogger("LogInteraction");
MakeLogger("LogCreative");
MakeLogger("LogZone");
}
#define LOG_DEBUG(loggerName, ...) \

View File

@@ -278,9 +278,23 @@ static T* Alloc(size_t Size)
namespace MemberOffsets
{
namespace FortPlayerPawnAthena
{
extern inline int LastFallDistance = 0;
}
namespace FortPlayerPawn
{
extern inline int CorrectTags = 0;
}
namespace FortPlayerState
{
extern inline int PawnDeathLocation = 0;
}
namespace FortPlayerStateAthena
{
extern inline int DeathInfo = 0;
extern inline int KillScore = 0;
extern inline int TeamKillScore = 0;
}
namespace DeathReport
{

View File

@@ -95,7 +95,8 @@ static inline void AddVehicleHook()
if (FortPhysicsPawnDefault)
{
Hooking::MinHook::Hook(FortPhysicsPawnDefault, FindObject<UFunction>("/Script/FortniteGame.FortPhysicsPawn.ServerMove"),
Hooking::MinHook::Hook(FortPhysicsPawnDefault, FindObject<UFunction>("/Script/FortniteGame.FortPhysicsPawn.ServerMove") ?
FindObject<UFunction>("/Script/FortniteGame.FortPhysicsPawn.ServerMove") : FindObject<UFunction>("/Script/FortniteGame.FortPhysicsPawn.ServerUpdatePhysicsParams"),
ServerVehicleUpdate, nullptr, false, true);
}
}