spectacular

fix s16+ no reserve (again), fix ltm crash on loot (again), fix s3-s6 respawning
This commit is contained in:
Milxnor
2023-05-12 19:03:57 -04:00
parent 8013f43a8b
commit 2335ad43a3
7 changed files with 126 additions and 105 deletions

View File

@@ -120,8 +120,10 @@ static void ShowFoundation(AActor* BuildingFoundation, bool bShow = true)
static auto StartEnabled_Dynamic = 2; static auto StartEnabled_Dynamic = 2;
static auto Static = 0; static auto Static = 0;
static auto DynamicFoundationTypeOffset = BuildingFoundation->GetOffset("DynamicFoundationType"); static auto DynamicFoundationTypeOffset = BuildingFoundation->GetOffset("DynamicFoundationType", false);
BuildingFoundation->Get<uint8_t>(DynamicFoundationTypeOffset) = bShow ? Static : StartDisabled;
if (DynamicFoundationTypeOffset != -1)
BuildingFoundation->Get<uint8_t>(DynamicFoundationTypeOffset) = bShow ? Static : StartDisabled;
/* static auto bShowHLODWhenDisabledOffset = BuildingFoundation->GetOffset("bShowHLODWhenDisabled", false); /* static auto bShowHLODWhenDisabledOffset = BuildingFoundation->GetOffset("bShowHLODWhenDisabled", false);

View File

@@ -16,14 +16,19 @@ struct FFortGameFeatureLootTableData
#ifdef EXPERIMENTAL_LOOTING #ifdef EXPERIMENTAL_LOOTING
template <typename RowStructType = uint8> template <typename RowStructType = uint8>
void CollectDataTablesRows(std::vector<UDataTable*> DataTables, std::map<FName, RowStructType*>* OutMap, std::function<bool(FName, RowStructType*)> Check = []() { return true; }) void CollectDataTablesRows(const std::vector<UDataTable*>& DataTables, std::map<FName, RowStructType*>* OutMap, std::function<bool(FName, RowStructType*)> Check = []() { return true; })
{ {
std::vector<UDataTable*> DataTablesToIterate; std::vector<UDataTable*> DataTablesToIterate;
static auto CompositeDataTableClass = FindObject<UClass>("/Script/Engine.CompositeDataTable"); static auto CompositeDataTableClass = FindObject<UClass>(L"/Script/Engine.CompositeDataTable");
for (auto DataTable : DataTables) for (UDataTable* DataTable : DataTables)
{ {
if (!DataTable->IsValidLowLevel())
{
continue; // Remove from vector?
}
// if (auto CompositeDataTable = Cast<UCompositeDataTable>(DataTable)) // if (auto CompositeDataTable = Cast<UCompositeDataTable>(DataTable))
if (DataTable->IsA(CompositeDataTableClass)) if (DataTable->IsA(CompositeDataTableClass))
{ {

View File

@@ -259,7 +259,7 @@ void AFortPlayerPawn::ServerHandlePickupHook(AFortPlayerPawn* Pawn, AFortPickup*
static auto bPickedUpOffset = Pickup->GetOffset("bPickedUp"); static auto bPickedUpOffset = Pickup->GetOffset("bPickedUp");
LOG_INFO(LogDev, "InFlyTime: {}", InFlyTime); // LOG_INFO(LogDev, "InFlyTime: {}", InFlyTime);
if (Pickup->Get<bool>(bPickedUpOffset)) if (Pickup->Get<bool>(bPickedUpOffset))
{ {

View File

@@ -55,13 +55,19 @@ AActor* AGameModeBase::K2_FindPlayerStart(AController* Player, FString IncomingN
APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AController* NewPlayer, AActor* StartSpot) APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AController* NewPlayer, AActor* StartSpot)
{ {
// LOG_INFO(LogDev, "SpawnDefaultPawnFor: 0x{:x}!", __int64(_ReturnAddress()) - __int64(GetModuleHandleW(0))); auto NewPlayerAsAthena = Cast<AFortPlayerControllerAthena>(NewPlayer);
// auto PawnClass = GameMode->GetDefaultPawnClassForController(NewPlayer); if (!NewPlayerAsAthena)
// LOG_INFO(LogDev, "PawnClass: {}", PawnClass->GetFullName()); return nullptr; // return original?
auto PlayerStateAthena = NewPlayerAsAthena->GetPlayerStateAthena();
if (!PlayerStateAthena)
return nullptr; // return original?
static auto PawnClass = FindObject<UClass>("/Game/Athena/PlayerPawn_Athena.PlayerPawn_Athena_C"); static auto PawnClass = FindObject<UClass>("/Game/Athena/PlayerPawn_Athena.PlayerPawn_Athena_C");
GameMode->Get<UClass*>("DefaultPawnClass") = PawnClass; static auto DefaultPawnClassOffset = GameMode->GetOffset("DefaultPawnClass");
GameMode->Get<UClass*>(DefaultPawnClassOffset) = PawnClass;
constexpr bool bUseSpawnActor = false; constexpr bool bUseSpawnActor = false;
@@ -92,95 +98,111 @@ APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AControll
bool bIsRespawning = false; bool bIsRespawning = false;
static auto RespawnDataOffset = PlayerStateAthena->GetOffset("RespawnData", false);
if (RespawnDataOffset != -1)
{
static auto bServerIsReadyOffset = FindOffsetStruct("/Script/FortniteGame.FortRespawnData", "bServerIsReady");
static auto bRespawnDataAvailableOffset = FindOffsetStruct("/Script/FortniteGame.FortRespawnData", "bRespawnDataAvailable");
auto RespawnDataPtr = PlayerStateAthena->GetPtr<__int64>(RespawnDataOffset);
if (*(bool*)(__int64(RespawnDataPtr) + bServerIsReadyOffset) && *(bool*)(__int64(RespawnDataPtr) + bRespawnDataAvailableOffset)) // && GameState->IsRespawningAllowed(PlayerState);
{
// SpawnTransform.Translation = PlayerState->RespawnData.RespawnLocation;
// SpawnTransform.Rotation = Quaternion(PlayerState->RespawnData.RespawnRotation);
bIsRespawning = true;
}
}
auto ASC = PlayerStateAthena->GetAbilitySystemComponent();
auto GameState = ((AFortGameModeAthena*)GameMode)->GetGameStateAthena();
GET_PLAYLIST(GameState);
if (CurrentPlaylist) // Apply gameplay effects from playlist // We need to move this maybe?
{
CurrentPlaylist->ApplyModifiersToActor(PlayerStateAthena);
}
auto PlayerAbilitySet = GetPlayerAbilitySet(); // Apply default gameplay effects // We need to move maybe?
if (PlayerAbilitySet && ASC)
{
PlayerAbilitySet->ApplyGrantedGameplayAffectsToAbilitySystem(ASC);
}
if (!bIsRespawning) if (!bIsRespawning)
{ {
auto NewPlayerAsAthena = Cast<AFortPlayerControllerAthena>(NewPlayer); auto WorldInventory = NewPlayerAsAthena->GetWorldInventory();
auto GameState = ((AFortGameModeAthena*)GameMode)->GetGameStateAthena(); if (!WorldInventory)
auto PlayerStateAthena = NewPlayerAsAthena->GetPlayerStateAthena(); return NewPawn;
if (!PlayerStateAthena)
return nullptr;
auto ASC = PlayerStateAthena->GetAbilitySystemComponent(); if (!WorldInventory->GetPickaxeInstance())
GET_PLAYLIST(GameState);
if (CurrentPlaylist) // Apply gameplay effects from playlist // We need to move this!
{ {
CurrentPlaylist->ApplyModifiersToActor(PlayerStateAthena); // TODO Check Playlist->bRequirePickaxeInStartingInventory
}
auto PlayerAbilitySet = GetPlayerAbilitySet(); // Apply default gameplay effects // We need to move maybe? auto& StartingItems = ((AFortGameModeAthena*)GameMode)->GetStartingItems();
if (PlayerAbilitySet && ASC) NewPlayerAsAthena->AddPickaxeToInventory();
{
PlayerAbilitySet->ApplyGrantedGameplayAffectsToAbilitySystem(ASC);
}
if (NewPlayerAsAthena) for (int i = 0; i < StartingItems.Num(); i++)
{
auto WorldInventory = NewPlayerAsAthena->GetWorldInventory();
if (!WorldInventory)
return NewPawn;
if (!WorldInventory->GetPickaxeInstance())
{ {
// TODO Check Playlist->bRequirePickaxeInStartingInventory auto& StartingItem = StartingItems.at(i);
auto& StartingItems = ((AFortGameModeAthena*)GameMode)->GetStartingItems(); WorldInventory->AddItem(StartingItem.GetItem(), nullptr, StartingItem.GetCount());
NewPlayerAsAthena->AddPickaxeToInventory();
for (int i = 0; i < StartingItems.Num(); i++)
{
auto& StartingItem = StartingItems.at(i);
WorldInventory->AddItem(StartingItem.GetItem(), nullptr, StartingItem.GetCount());
}
/* if (Globals::bLateGame)
{
auto SpawnIslandTierGroup = UKismetStringLibrary::Conv_StringToName(L"Loot_AthenaFloorLoot_Warmup");
for (int i = 0; i < 5; i++)
{
auto LootDrops = PickLootDrops(SpawnIslandTierGroup);
for (auto& LootDrop : LootDrops)
{
WorldInventory->AddItem(LootDrop.ItemDefinition, nullptr, LootDrop.Count, LootDrop.LoadedAmmo);
}
}
} */
auto AddInventoryOverrideTeamLoadouts = [&](AFortAthenaMutator* Mutator)
{
if (auto InventoryOverride = Cast<AFortAthenaMutator_InventoryOverride>(Mutator))
{
auto TeamIndex = PlayerStateAthena->GetTeamIndex();
auto LoadoutTeam = InventoryOverride->GetLoadoutTeamForTeamIndex(TeamIndex);
if (LoadoutTeam.UpdateOverrideType == EAthenaInventorySpawnOverride::Always)
{
auto LoadoutContainer = InventoryOverride->GetLoadoutContainerForTeamIndex(TeamIndex);
for (int i = 0; i < LoadoutContainer.Loadout.Num(); i++)
{
auto& ItemAndCount = LoadoutContainer.Loadout.at(i);
WorldInventory->AddItem(ItemAndCount.GetItem(), nullptr, ItemAndCount.GetCount());
}
}
}
};
LoopMutators(AddInventoryOverrideTeamLoadouts);
WorldInventory->Update();
} }
/* if (Globals::bLateGame)
{
auto SpawnIslandTierGroup = UKismetStringLibrary::Conv_StringToName(L"Loot_AthenaFloorLoot_Warmup");
for (int i = 0; i < 5; i++)
{
auto LootDrops = PickLootDrops(SpawnIslandTierGroup);
for (auto& LootDrop : LootDrops)
{
WorldInventory->AddItem(LootDrop.ItemDefinition, nullptr, LootDrop.Count, LootDrop.LoadedAmmo);
}
}
} */
auto AddInventoryOverrideTeamLoadouts = [&](AFortAthenaMutator* Mutator)
{
if (auto InventoryOverride = Cast<AFortAthenaMutator_InventoryOverride>(Mutator))
{
auto TeamIndex = PlayerStateAthena->GetTeamIndex();
auto LoadoutTeam = InventoryOverride->GetLoadoutTeamForTeamIndex(TeamIndex);
if (LoadoutTeam.UpdateOverrideType == EAthenaInventorySpawnOverride::Always)
{
auto LoadoutContainer = InventoryOverride->GetLoadoutContainerForTeamIndex(TeamIndex);
for (int i = 0; i < LoadoutContainer.Loadout.Num(); i++)
{
auto& ItemAndCount = LoadoutContainer.Loadout.at(i);
WorldInventory->AddItem(ItemAndCount.GetItem(), nullptr, ItemAndCount.GetCount());
}
}
}
};
LoopMutators(AddInventoryOverrideTeamLoadouts);
WorldInventory->Update();
} }
} }
else
{
auto DeathInfo = (void*)(__int64(PlayerStateAthena) + MemberOffsets::FortPlayerStateAthena::DeathInfo);
static auto DeathInfoStruct = FindObject<UStruct>(L"/Script/FortniteGame.DeathInfo");
static auto DeathInfoStructSize = DeathInfoStruct->GetPropertiesSize();
RtlSecureZeroMemory(DeathInfo, DeathInfoStructSize);
}
return NewPawn; return NewPawn;
} }

View File

@@ -546,27 +546,17 @@ std::vector<uint64> Addresses::GetFunctionsToNull()
toNull.push_back(Memcury::Scanner::FindPattern("40 55 57 41 57 48 8D 6C 24 ? 48 81 EC ? ? ? ? 80 3D ? ? ? ? ? 0F B6 FA 44 8B F9 74 3B 80 3D ? ? ? ? ? 0F").Get()); toNull.push_back(Memcury::Scanner::FindPattern("40 55 57 41 57 48 8D 6C 24 ? 48 81 EC ? ? ? ? 80 3D ? ? ? ? ? 0F B6 FA 44 8B F9 74 3B 80 3D ? ? ? ? ? 0F").Get());
} }
if (std::floor(Fortnite_Version) == 16)
{
toNull.push_back(Memcury::Scanner::FindPattern("48 8B C4 48 89 58 08 48 89 70 10 48 89 78 18 4C 89 60 20 55 41 56 41 57 48 8B EC 48 83 EC 60 49 8B D9 45 8A F8 4C 8B F2 48").Get()); // no reservation in gakme
}
if (std::floor(Fortnite_Version) == 17)
{
// toNull.push_back(Memcury::Scanner::FindPattern("48 8B C4 48 89 70 08 48 89 78 10 55 41 54 41 55 41 56 41 57 48 8D 68 A1 48 81 EC ? ? ? ? 45 33 ED").Get()); // collectgarbage
}
if (Fortnite_Version == 17.50)
{
toNull.push_back(Memcury::Scanner::FindPattern("48 8B C4 48 89 58 08 48 89 70 10 48 89 78 18 4C 89 60 20 55 41 56 41 57 48 8B EC 48 83 EC 60 49 8B D9 45 8A").Get()); // no reservation in game
}
if (Engine_Version == 500) if (Engine_Version == 500)
{ {
// toNull.push_back(Memcury::Scanner::FindPattern("48 8B C4 55 53 56 57 41 54 41 55 41 56 41 57 48 8D 68 A1 48 81 EC ? ? ? ? 45 33 F6 0F 29 70 A8 44 38 35").Get()); // zone // toNull.push_back(Memcury::Scanner::FindPattern("48 8B C4 55 53 56 57 41 54 41 55 41 56 41 57 48 8D 68 A1 48 81 EC ? ? ? ? 45 33 F6 0F 29 70 A8 44 38 35").Get()); // zone
toNull.push_back(Memcury::Scanner::FindPattern("48 8B C4 48 89 58 08 55 56 57 41 54 41 55 41 56 41 57 48 8D 68 A8 48 81 EC ? ? ? ? 45").Get()); // GC toNull.push_back(Memcury::Scanner::FindPattern("48 8B C4 48 89 58 08 55 56 57 41 54 41 55 41 56 41 57 48 8D 68 A8 48 81 EC ? ? ? ? 45").Get()); // GC
} }
if (Engine_Version >= 426)
{
toNull.push_back(Memcury::Scanner::FindPattern("48 8B C4 48 89 58 08 48 89 70 10 48 89 78 18 4C 89 60 20 55 41 56 41 57 48 8B EC 48 83 EC 60 49 8B D9 45 8A").Get()); // No reserve
}
toNull.push_back(Addresses::ChangeGameSessionId); toNull.push_back(Addresses::ChangeGameSessionId);
return toNull; return toNull;

View File

@@ -183,7 +183,7 @@ DWORD WINAPI Main(LPVOID)
static auto FortKismetLibraryDefault = FindObject<UFortKismetLibrary>(L"/Script/FortniteGame.Default__FortKismetLibrary"); static auto FortKismetLibraryDefault = FindObject<UFortKismetLibrary>(L"/Script/FortniteGame.Default__FortKismetLibrary");
static auto AthenaMarkerComponentDefault = FindObject<UAthenaMarkerComponent>(L"/Script/FortniteGame.Default__AthenaMarkerComponent"); static auto AthenaMarkerComponentDefault = FindObject<UAthenaMarkerComponent>(L"/Script/FortniteGame.Default__AthenaMarkerComponent");
static auto FortWeaponDefault = FindObject<AFortWeapon>(L"/Script/FortniteGame.Default__FortWeapon"); static auto FortWeaponDefault = FindObject<AFortWeapon>(L"/Script/FortniteGame.Default__FortWeapon");
static auto FortOctopusVehicleDefault = FindObject<AFortOctopusVehicle>("/Script/FortniteGame.Default__FortOctopusVehicle"); static auto FortOctopusVehicleDefault = FindObject<AFortOctopusVehicle>(L"/Script/FortniteGame.Default__FortOctopusVehicle");
// UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogNetPackageMap VeryVerbose", nullptr); // UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogNetPackageMap VeryVerbose", nullptr);
// UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogNetTraffic VeryVerbose", nullptr); // UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogNetTraffic VeryVerbose", nullptr);
@@ -546,7 +546,7 @@ DWORD WINAPI Main(LPVOID)
AFortPlayerPawn::ServerSendZiplineStateHook, nullptr, false); AFortPlayerPawn::ServerSendZiplineStateHook, nullptr, false);
Hooking::MinHook::Hook((PVOID)GetFunctionIdxOrPtr(FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerPawn.ServerOnExitVehicle"), true), AFortPlayerPawn::ServerOnExitVehicleHook, (PVOID*)&AFortPlayerPawn::ServerOnExitVehicleOriginal); Hooking::MinHook::Hook((PVOID)GetFunctionIdxOrPtr(FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerPawn.ServerOnExitVehicle"), true), AFortPlayerPawn::ServerOnExitVehicleHook, (PVOID*)&AFortPlayerPawn::ServerOnExitVehicleOriginal);
static auto FortGameplayAbilityAthena_PeriodicItemGrantDefault = FindObject<UFortGameplayAbilityAthena_PeriodicItemGrant>("/Script/FortniteGame.Default__FortGameplayAbilityAthena_PeriodicItemGrant"); static auto FortGameplayAbilityAthena_PeriodicItemGrantDefault = FindObject<UFortGameplayAbilityAthena_PeriodicItemGrant>(L"/Script/FortniteGame.Default__FortGameplayAbilityAthena_PeriodicItemGrant");
if (FortGameplayAbilityAthena_PeriodicItemGrantDefault) if (FortGameplayAbilityAthena_PeriodicItemGrantDefault)
{ {
@@ -650,7 +650,7 @@ DWORD WINAPI Main(LPVOID)
Hooking::MinHook::Hook(InventoryManagementLibraryDefault, FindObject<UFunction>(L"/Script/FortniteGame.InventoryManagementLibrary.SwapItems"), Hooking::MinHook::Hook(InventoryManagementLibraryDefault, FindObject<UFunction>(L"/Script/FortniteGame.InventoryManagementLibrary.SwapItems"),
UInventoryManagementLibrary::SwapItemsHook, (PVOID*)&UInventoryManagementLibrary::SwapItemsOriginal, false, true); UInventoryManagementLibrary::SwapItemsHook, (PVOID*)&UInventoryManagementLibrary::SwapItemsOriginal, false, true);
Hooking::MinHook::Hook(FindObject("/Script/FortniteGame.Default__FortAthenaVehicleSpawner"), FindObject<UFunction>(L"/Script/FortniteGame.FortAthenaVehicleSpawner.SpawnVehicle"), Hooking::MinHook::Hook(FindObject(L"/Script/FortniteGame.Default__FortAthenaVehicleSpawner"), FindObject<UFunction>(L"/Script/FortniteGame.FortAthenaVehicleSpawner.SpawnVehicle"),
AFortAthenaVehicleSpawner::SpawnVehicleHook, nullptr, false); AFortAthenaVehicleSpawner::SpawnVehicleHook, nullptr, false);
static auto ServerHandlePickupInfoFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerPawn.ServerHandlePickupInfo"); static auto ServerHandlePickupInfoFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerPawn.ServerHandlePickupInfo");
@@ -785,7 +785,7 @@ DWORD WINAPI Main(LPVOID)
LOG_INFO(LogDev, "PredictionKeySize: 0x{:x} {}", PredictionKeySize, PredictionKeySize); LOG_INFO(LogDev, "PredictionKeySize: 0x{:x} {}", PredictionKeySize, PredictionKeySize);
static auto GameplayEventDataSize = FindObject<UStruct>("/Script/GameplayAbilities.GameplayEventData")->GetPropertiesSize(); static auto GameplayEventDataSize = FindObject<UStruct>(L"/Script/GameplayAbilities.GameplayEventData")->GetPropertiesSize();
LOG_INFO(LogDev, "GameplayEventDataSize: 0x{:x} {}", GameplayEventDataSize, GameplayEventDataSize); LOG_INFO(LogDev, "GameplayEventDataSize: 0x{:x} {}", GameplayEventDataSize, GameplayEventDataSize);
{ {

View File

@@ -144,6 +144,8 @@ static inline uint64 FindObjectArray()
static inline uint64 FindPickupInitialize() 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 (Engine_Version == 420)
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 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) if (Engine_Version == 421)