From 1fd8f0f93f26fa943eeeef24d0ca98bb8bb5c9d9 Mon Sep 17 00:00:00 2001 From: Milxnor Date: Wed, 8 Mar 2023 01:39:09 -0500 Subject: [PATCH] dispatch request --- Project Reboot 3.0/AbilitySystemComponent.h | 6 +- .../AbilitySystemComponent_Abilities.cpp | 2 +- Project Reboot 3.0/Actor.cpp | 14 + Project Reboot 3.0/Actor.h | 1 + Project Reboot 3.0/Array.h | 1 + Project Reboot 3.0/BuildingActor.h | 6 + Project Reboot 3.0/Class.h | 2 +- Project Reboot 3.0/FortAthenaCreativePortal.h | 66 ++++ Project Reboot 3.0/FortDecoItemDefinition.cpp | 2 +- Project Reboot 3.0/FortGameModeAthena.cpp | 320 +++++++++++------- Project Reboot 3.0/FortGameStateAthena.cpp | 5 + Project Reboot 3.0/FortGameStateAthena.h | 1 + Project Reboot 3.0/FortKismetLibrary.cpp | 19 ++ Project Reboot 3.0/FortKismetLibrary.h | 1 + Project Reboot 3.0/FortLootPackage.cpp | 5 +- Project Reboot 3.0/FortPlayerController.cpp | 22 +- Project Reboot 3.0/FortPlayerController.h | 27 ++ .../FortPlayerControllerAthena.cpp | 80 +++++ .../FortPlayerControllerAthena.h | 7 +- Project Reboot 3.0/FortPlayerPawn.cpp | 66 ++-- Project Reboot 3.0/FortPlayerPawn.h | 16 + .../FortPlaysetItemDefinition.cpp | 19 ++ .../FortPlaysetItemDefinition.h | 14 + Project Reboot 3.0/FortVolume.h | 22 ++ Project Reboot 3.0/GameModeBase.cpp | 34 +- Project Reboot 3.0/GameplayStatics.cpp | 17 + Project Reboot 3.0/GameplayStatics.h | 1 + Project Reboot 3.0/MegaStormManager.h | 26 ++ Project Reboot 3.0/Pawn.h | 5 + Project Reboot 3.0/Project Reboot 3.0.vcxproj | 7 + .../Project Reboot 3.0.vcxproj.filters | 24 ++ Project Reboot 3.0/SoftObjectPtr.h | 3 + Project Reboot 3.0/World.cpp | 8 + Project Reboot 3.0/World.h | 2 + Project Reboot 3.0/addresses.cpp | 23 +- Project Reboot 3.0/addresses.h | 4 + Project Reboot 3.0/ai.h | 91 +++++ Project Reboot 3.0/dllmain.cpp | 91 +++-- Project Reboot 3.0/finder.h | 180 +++++++++- Project Reboot 3.0/globals.h | 9 + Project Reboot 3.0/hooking.h | 16 +- Project Reboot 3.0/log.h | 1 + Project Reboot 3.0/reboot.h | 6 - 43 files changed, 1048 insertions(+), 224 deletions(-) create mode 100644 Project Reboot 3.0/FortAthenaCreativePortal.h create mode 100644 Project Reboot 3.0/FortPlaysetItemDefinition.cpp create mode 100644 Project Reboot 3.0/FortPlaysetItemDefinition.h create mode 100644 Project Reboot 3.0/FortVolume.h create mode 100644 Project Reboot 3.0/MegaStormManager.h create mode 100644 Project Reboot 3.0/ai.h create mode 100644 Project Reboot 3.0/globals.h diff --git a/Project Reboot 3.0/AbilitySystemComponent.h b/Project Reboot 3.0/AbilitySystemComponent.h index bb829e6..19fdc88 100644 --- a/Project Reboot 3.0/AbilitySystemComponent.h +++ b/Project Reboot 3.0/AbilitySystemComponent.h @@ -7,14 +7,14 @@ struct PadHex18 { char Pad[0x18]; }; struct PadHexA8 { char Pad[0xA8]; }; struct PadHexB0 { char Pad[0xB0]; }; -using FPredictionKey = PadHex18; -using FGameplayEventData = PadHexB0; +using FPredictionKey = __int64; // PadHex18; +using FGameplayEventData = __int64; // PadHexB0; class UAbilitySystemComponent : public UObject { public: static inline FGameplayAbilitySpecHandle* (*GiveAbilityOriginal)(UAbilitySystemComponent*, FGameplayAbilitySpecHandle*, __int64 inSpec); - static inline bool (*InternalTryActivateAbilityOriginal)(UAbilitySystemComponent*, FGameplayAbilitySpecHandle Handle, PadHex18 InPredictionKey, UObject** OutInstancedAbility, void* OnGameplayAbilityEndedDelegate, const FGameplayEventData* TriggerEventData); + static inline bool (*InternalTryActivateAbilityOriginal)(UAbilitySystemComponent*, FGameplayAbilitySpecHandle Handle, __int64 InPredictionKey, UObject** OutInstancedAbility, void* OnGameplayAbilityEndedDelegate, const FGameplayEventData* TriggerEventData); void ClientActivateAbilityFailed(FGameplayAbilitySpecHandle AbilityToActivate, int16_t PredictionKey) { diff --git a/Project Reboot 3.0/AbilitySystemComponent_Abilities.cpp b/Project Reboot 3.0/AbilitySystemComponent_Abilities.cpp index f477703..1e90e82 100644 --- a/Project Reboot 3.0/AbilitySystemComponent_Abilities.cpp +++ b/Project Reboot 3.0/AbilitySystemComponent_Abilities.cpp @@ -46,7 +46,7 @@ void InternalServerTryActivateAbility(UAbilitySystemComponent* AbilitySystemComp UGameplayAbility* InstancedAbility = nullptr; SetBitfield(Spec, 1, true); // InputPressed = true - if (!AbilitySystemComponent->InternalTryActivateAbilityOriginal(AbilitySystemComponent, Handle, *(PadHex18*)PredictionKey, &InstancedAbility, nullptr, TriggerEventData)) + if (!AbilitySystemComponent->InternalTryActivateAbilityOriginal(AbilitySystemComponent, Handle, __int64(PredictionKey), &InstancedAbility, nullptr, TriggerEventData)) { AbilitySystemComponent->ClientActivateAbilityFailed(Handle, *(int16_t*)(__int64(PredictionKey) + CurrentOffset)); SetBitfield(Spec, 1, false); // InputPressed = false diff --git a/Project Reboot 3.0/Actor.cpp b/Project Reboot 3.0/Actor.cpp index 16ebe55..e8b6027 100644 --- a/Project Reboot 3.0/Actor.cpp +++ b/Project Reboot 3.0/Actor.cpp @@ -29,6 +29,20 @@ void AActor::K2_DestroyActor() this->ProcessEvent(DestroyActorFn); } +UActorComponent* AActor::GetComponentByClass(class UClass* ComponentClass) +{ + static auto fn = FindObject("/Script/Engine.Actor.GetComponentByClass"); + struct + { + class UClass* ComponentClass; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, UObjectWrapper, HasGetValueTypeHash, NativeAccessSpecifierPublic) + UActorComponent* ReturnValue; // (ExportObject, Parm, OutParm, ZeroConstructor, ReturnParm, InstancedReference, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + } AActor_GetComponentByClass_Params{ComponentClass}; + + this->ProcessEvent(fn, &AActor_GetComponentByClass_Params); + + return AActor_GetComponentByClass_Params.ReturnValue; +} + FVector AActor::GetActorLocation() { static auto K2_GetActorLocationFn = FindObject("/Script/Engine.Actor.K2_GetActorLocation"); diff --git a/Project Reboot 3.0/Actor.h b/Project Reboot 3.0/Actor.h index 44f5c5f..6ff935e 100644 --- a/Project Reboot 3.0/Actor.h +++ b/Project Reboot 3.0/Actor.h @@ -10,4 +10,5 @@ public: AActor* GetOwner(); struct FVector GetActorLocation(); void K2_DestroyActor(); + class UActorComponent* GetComponentByClass(class UClass* ComponentClass); }; \ No newline at end of file diff --git a/Project Reboot 3.0/Array.h b/Project Reboot 3.0/Array.h index 332f5f9..50f3f7f 100644 --- a/Project Reboot 3.0/Array.h +++ b/Project Reboot 3.0/Array.h @@ -105,6 +105,7 @@ public: { if (Data && ArrayNum > 0 && sizeof(InElementType) > 0) { + // VirtualFree(Data, _msize(Data), MEM_RELEASE); VirtualFree(Data, sizeof(InElementType) * ArrayNum, MEM_RELEASE); } diff --git a/Project Reboot 3.0/BuildingActor.h b/Project Reboot 3.0/BuildingActor.h index d89b9cb..16c01d9 100644 --- a/Project Reboot 3.0/BuildingActor.h +++ b/Project Reboot 3.0/BuildingActor.h @@ -30,6 +30,12 @@ public: return MaxHealth; } + void SetTeam(unsigned char InTeam) + { + static auto fn = FindObject("/Script/FortniteGame.BuildingActor.SetTeam"); + this->ProcessEvent(fn, &InTeam); + } + static inline void (*OnDamageServerOriginal)(ABuildingActor* BuildingActor, float Damage, FGameplayTagContainer DamageTags, FVector Momentum, /* FHitResult */ __int64 HitInfo, APlayerController* InstigatedBy, AActor* DamageCauser, /* FGameplayEffectContextHandle */ __int64 EffectContext); diff --git a/Project Reboot 3.0/Class.h b/Project Reboot 3.0/Class.h index 99fef22..060a16a 100644 --- a/Project Reboot 3.0/Class.h +++ b/Project Reboot 3.0/Class.h @@ -25,5 +25,5 @@ public: class UFunction : public UStruct { public: - void* GetFunc() { return *(void**)(__int64(this) + Offsets::Func); } + void*& GetFunc() { return *(void**)(__int64(this) + Offsets::Func); } }; diff --git a/Project Reboot 3.0/FortAthenaCreativePortal.h b/Project Reboot 3.0/FortAthenaCreativePortal.h new file mode 100644 index 0000000..0cdf5c1 --- /dev/null +++ b/Project Reboot 3.0/FortAthenaCreativePortal.h @@ -0,0 +1,66 @@ +#pragma once + +#include "BuildingActor.h" + +struct FCreativeLoadedLinkData +{ + +}; + +class AFortAthenaCreativePortal : public ABuildingActor // ABuildingGameplayActor +{ +public: + FCreativeLoadedLinkData* GetIslandInfo() + { + static auto CreativeLoadedLinkDataStruct = FindObject("/Script/FortniteGame.CreativeLoadedLinkData"); + + if (!CreativeLoadedLinkDataStruct) + return nullptr; + + static auto IslandInfoOffset = GetOffset("IslandInfo"); + return GetPtr(IslandInfoOffset); + } + + void* GetOwningPlayer() + { + static auto OwningPlayerOffset = GetOffset("OwningPlayer"); + return GetPtr(OwningPlayerOffset); + } + + bool& GetPortalOpen() + { + static auto bPortalOpenOffset = GetOffset("bPortalOpen"); + return Get(bPortalOpenOffset); + } + + bool& GetUserInitiatedLoad() + { + static auto bUserInitiatedLoadOffset = GetOffset("bUserInitiatedLoad"); + return Get(bUserInitiatedLoadOffset); + } + + bool& GetInErrorState() + { + static auto bInErrorStateOffset = GetOffset("bInErrorState"); + return Get(bInErrorStateOffset); + } + + AFortVolume*& GetLinkedVolume() + { + static auto LinkedVolumeOffset = GetOffset("LinkedVolume"); + return Get(LinkedVolumeOffset); + } + + FString& GetCreatorName() + { + auto IslandInfo = GetIslandInfo(); + + if (!IslandInfo) + { + return *(FString*)0; + } + + static auto CreatorNameOffset = FindOffsetStruct("/Script/FortniteGame.CreativeLoadedLinkData", "CreatorName"); + return *(FString*)(__int64(IslandInfo) + CreatorNameOffset); + } +}; \ No newline at end of file diff --git a/Project Reboot 3.0/FortDecoItemDefinition.cpp b/Project Reboot 3.0/FortDecoItemDefinition.cpp index 9eb391a..7c2bd4d 100644 --- a/Project Reboot 3.0/FortDecoItemDefinition.cpp +++ b/Project Reboot 3.0/FortDecoItemDefinition.cpp @@ -1,6 +1,6 @@ #include "FortDecoItemDefinition.h" -static UClass* StaticClass() +UClass* UFortDecoItemDefinition::StaticClass() { static auto ptr = FindObject("/Script/FortniteGame.FortDecoItemDefinition"); return ptr; diff --git a/Project Reboot 3.0/FortGameModeAthena.cpp b/Project Reboot 3.0/FortGameModeAthena.cpp index e41dd36..817c3a2 100644 --- a/Project Reboot 3.0/FortGameModeAthena.cpp +++ b/Project Reboot 3.0/FortGameModeAthena.cpp @@ -1,15 +1,23 @@ #include "FortGameModeAthena.h" -#include "reboot.h" -#include "NetSerialization.h" #include "FortPlayerControllerAthena.h" +#include "FortPlaysetItemDefinition.h" +#include "FortAthenaCreativePortal.h" +#include "BuildingContainer.h" +#include "MegaStormManager.h" +#include "FortLootPackage.h" +#include "FortPlayerPawn.h" +#include "FortPickup.h" + +#include "NetSerialization.h" #include "GameplayStatics.h" #include "KismetStringLibrary.h" #include "SoftObjectPtr.h" -#include "FortPickup.h" -#include "FortLootPackage.h" -#include "BuildingContainer.h" + +#include "globals.h" #include "events.h" +#include "reboot.h" +#include "ai.h" static bool bFirstPlayerJoined = false; @@ -189,6 +197,21 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game FindObject(("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.LF_FloatingIsland")); ShowFoundation(FloatingIsland); + + UObject* Scripting = FindObject("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.BP_IslandScripting3"); // bruh + + if (Scripting) + { + static auto UpdateMapOffset = Scripting->GetOffset("UpdateMap", false); + + if (UpdateMapOffset != 0) + { + Scripting->Get(UpdateMapOffset) = true; + + static auto OnRep_UpdateMap = FindObject("/Game/Athena/Prototype/Blueprints/Island/BP_IslandScripting.BP_IslandScripting_C.OnRep_UpdateMap"); + Scripting->ProcessEvent(OnRep_UpdateMap); + } + } } if (Fortnite_Season >= 7 && Fortnite_Season <= 10) @@ -308,10 +331,14 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game { // auto World = Cast(Playlist->AdditionalLevels[i].Get()); // StreamLevel(UKismetSystemLibrary::GetPathName(World->PersistentLevel).ToString()); - StreamLevel(AdditionalLevels.at(i).SoftObjectPtr.ObjectID.AssetPathName.ToString()); + auto LevelName = AdditionalLevels.at(i).SoftObjectPtr.ObjectID.AssetPathName.ToString(); + LOG_INFO(LogPlaylist, "Loading level {}.", LevelName); + StreamLevel(LevelName); } } } + + SetBitfield(GameMode->GetPtr("bWorldIsReady"), 1, true); } static int LastNum6 = 1; @@ -373,22 +400,6 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game static auto FlightInfosOffset = MapInfo->GetOffset("FlightInfos"); - static int LastNum3 = 1; - - if (AmountOfRestarts != LastNum3) - { - LastNum3 = AmountOfRestarts; - - LOG_INFO(LogNet, "Attempting to listen!"); - - GetWorld()->Listen(); - SetBitfield(GameMode->GetPtr("bWorldIsReady"), 1, true); - - // GameState->OnRep_CurrentPlaylistInfo(); - - // return false; - } - // if (GameState->GetPlayersLeft() < GameMode->Get("WarmupRequiredPlayerCount")) // if (!bFirstPlayerJoined) // return false; @@ -399,7 +410,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game { LastNum = AmountOfRestarts; - float Duration = 40.f; + float Duration = 1000.f; float EarlyDuration = Duration; float TimeSeconds = 35.f; // UGameplayStatics::GetTimeSeconds(GetWorld()); @@ -412,9 +423,28 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game GameState->Get("WarmupCountdownStartTime") = TimeSeconds; GameMode->Get("WarmupEarlyCountdownDuration") = EarlyDuration; + auto AllMegaStormManagers = UGameplayStatics::GetAllActorsOfClass(GetWorld(), GameMode->Get("MegaStormManagerClass")); + + LOG_INFO(LogDev, "AllMegaStormManagers.Num() {}", AllMegaStormManagers.Num()); + + if (AllMegaStormManagers.Num()) + { + auto MegaStormManager = (AMegaStormManager*)AllMegaStormManagers.at(0); // GameMode->Get(MegaStormManagerOffset); + + LOG_INFO(LogDev, "MegaStormManager {}", __int64(MegaStormManager)); + + if (MegaStormManager) + { + LOG_INFO(LogDev, "MegaStormManager->GetMegaStormCircles().Num() {}", MegaStormManager->GetMegaStormCircles().Num()); + } + } + // GameState->Get("bGameModeWillSkipAircraft") = Globals::bGoingToPlayEvent && Fortnite_Version == 17.30; - // GameState->OnRep_CurrentPlaylistInfo(); + if (Engine_Version < 424) + GameState->OnRep_CurrentPlaylistInfo(); // ? + + // SetupNavConfig(); LOG_INFO(LogDev, "Initialized!"); } @@ -428,6 +458,27 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game } } + /* static auto TeamsOffset = GameState->GetOffset("Teams"); + auto& Teams = GameState->Get>(TeamsOffset); + + if (Teams.Num() <= 0) + return false; */ + + static int LastNum3 = 1; + + if (AmountOfRestarts != LastNum3) + { + LastNum3 = AmountOfRestarts; + + LOG_INFO(LogNet, "Attempting to listen!"); + + GetWorld()->Listen(); + + // GameState->OnRep_CurrentPlaylistInfo(); + + // return false; + } + return Athena_ReadyToStartMatchOriginal(GameMode); } @@ -437,23 +488,13 @@ int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint return ++NextTeamIndex; } -enum class EFortCustomPartType : uint8_t // todo move -{ - Head = 0, - Body = 1, - Hat = 2, - Backpack = 3, - Charm = 4, - Face = 5, - NumTypes = 6, - EFortCustomPartType_MAX = 7 -}; - void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena* GameMode, AActor* NewPlayerActor) { if (!NewPlayerActor) return; + LOG_INFO(LogPlayer, "HandleStartingNewPlayer!"); + static bool bFirst = Engine_Version >= 424; auto GameState = GameMode->GetGameStateAthena(); @@ -466,114 +507,100 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena GameState->OnRep_GamePhase(); } - auto SpawnIsland_FloorLoot = FindObject("/Game/Athena/Environments/Blueprints/Tiered_Athena_FloorLoot_Warmup.Tiered_Athena_FloorLoot_Warmup_C"); - auto BRIsland_FloorLoot = FindObject("/Game/Athena/Environments/Blueprints/Tiered_Athena_FloorLoot_01.Tiered_Athena_FloorLoot_01_C"); - - TArray SpawnIsland_FloorLoot_Actors = UGameplayStatics::GetAllActorsOfClass(GetWorld(), SpawnIsland_FloorLoot); - - TArray BRIsland_FloorLoot_Actors = UGameplayStatics::GetAllActorsOfClass(GetWorld(), BRIsland_FloorLoot); - - auto SpawnIslandTierGroup = UKismetStringLibrary::Conv_StringToName(L"Loot_AthenaFloorLoot_Warmup"); - auto BRIslandTierGroup = UKismetStringLibrary::Conv_StringToName(L"Loot_AthenaFloorLoot"); - - float UpZ = 50; - - EFortPickupSourceTypeFlag SpawnFlag = EFortPickupSourceTypeFlag::Container; - - bool bPrintWarmup = false; - - for (int i = 0; i < SpawnIsland_FloorLoot_Actors.Num(); i++) + if (false) { - ABuildingContainer* CurrentActor = (ABuildingContainer*)SpawnIsland_FloorLoot_Actors.at(i); + auto SpawnIsland_FloorLoot = FindObject("/Game/Athena/Environments/Blueprints/Tiered_Athena_FloorLoot_Warmup.Tiered_Athena_FloorLoot_Warmup_C"); + auto BRIsland_FloorLoot = FindObject("/Game/Athena/Environments/Blueprints/Tiered_Athena_FloorLoot_01.Tiered_Athena_FloorLoot_01_C"); - // CurrentActor->K2_DestroyActor(); - // continue; + TArray SpawnIsland_FloorLoot_Actors = UGameplayStatics::GetAllActorsOfClass(GetWorld(), SpawnIsland_FloorLoot); - auto Location = CurrentActor->GetActorLocation(); - Location.Z += UpZ; + TArray BRIsland_FloorLoot_Actors = UGameplayStatics::GetAllActorsOfClass(GetWorld(), BRIsland_FloorLoot); - std::vector> LootDrops = PickLootDrops(SpawnIslandTierGroup, bPrintWarmup); + auto SpawnIslandTierGroup = UKismetStringLibrary::Conv_StringToName(L"Loot_AthenaFloorLoot_Warmup"); + auto BRIslandTierGroup = UKismetStringLibrary::Conv_StringToName(L"Loot_AthenaFloorLoot"); - if (bPrintWarmup) + float UpZ = 50; + + EFortPickupSourceTypeFlag SpawnFlag = EFortPickupSourceTypeFlag::Container; + + bool bPrintWarmup = false; + + for (int i = 0; i < SpawnIsland_FloorLoot_Actors.Num(); i++) { - std::cout << "\n\n"; + ABuildingContainer* CurrentActor = (ABuildingContainer*)SpawnIsland_FloorLoot_Actors.at(i); + + // CurrentActor->K2_DestroyActor(); + // continue; + + auto Location = CurrentActor->GetActorLocation(); + Location.Z += UpZ; + + std::vector> LootDrops = PickLootDrops(SpawnIslandTierGroup, bPrintWarmup); + + if (bPrintWarmup) + { + std::cout << "\n\n"; + } + + if (LootDrops.size()) + { + for (auto& LootDrop : LootDrops) + AFortPickup::SpawnPickup(LootDrop.first, Location, LootDrop.second, SpawnFlag); + } } - if (LootDrops.size()) + bool bPrint = false; + + int spawned = 0; + + for (int i = 0; i < BRIsland_FloorLoot_Actors.Num(); i++) { - for (auto& LootDrop : LootDrops) - AFortPickup::SpawnPickup(LootDrop.first, Location, LootDrop.second, SpawnFlag); - } - } + ABuildingContainer* CurrentActor = (ABuildingContainer*)BRIsland_FloorLoot_Actors.at(i); - bool bPrint = false; + // CurrentActor->K2_DestroyActor(); + spawned++; + // continue; - int spawned = 0; + auto Location = CurrentActor->GetActorLocation(); + Location.Z += UpZ; - for (int i = 0; i < BRIsland_FloorLoot_Actors.Num(); i++) - { - ABuildingContainer* CurrentActor = (ABuildingContainer*)BRIsland_FloorLoot_Actors.at(i); + std::vector> LootDrops = PickLootDrops(BRIslandTierGroup, bPrint); - // CurrentActor->K2_DestroyActor(); - spawned++; - // continue; + if (bPrint) + std::cout << "\n"; - auto Location = CurrentActor->GetActorLocation(); - Location.Z += UpZ; - - std::vector> LootDrops = PickLootDrops(BRIslandTierGroup, bPrint); - - if (bPrint) - std::cout << "\n"; - - if (LootDrops.size()) - { - for (auto& LootDrop : LootDrops) - AFortPickup::SpawnPickup(LootDrop.first, Location, LootDrop.second, SpawnFlag); + if (LootDrops.size()) + { + for (auto& LootDrop : LootDrops) + AFortPickup::SpawnPickup(LootDrop.first, Location, LootDrop.second, SpawnFlag); + } } } auto NewPlayer = (AFortPlayerControllerAthena*)NewPlayerActor; - auto WorldInventory = NewPlayer->GetWorldInventory(); - - static UFortItemDefinition* EditToolItemDefinition = FindObject(L"/Game/Items/Weapons/BuildingTools/EditTool.EditTool"); - static UFortItemDefinition* PickaxeDefinition = FindObject(L"/Game/Athena/Items/Weapons/WID_Harvest_Pickaxe_Athena_C_T01.WID_Harvest_Pickaxe_Athena_C_T01"); - static UFortItemDefinition* BuildingItemData_Wall = FindObject(L"/Game/Items/Weapons/BuildingTools/BuildingItemData_Wall.BuildingItemData_Wall"); - static UFortItemDefinition* BuildingItemData_Floor = FindObject(L"/Game/Items/Weapons/BuildingTools/BuildingItemData_Floor.BuildingItemData_Floor"); - static UFortItemDefinition* BuildingItemData_Stair_W = FindObject(L"/Game/Items/Weapons/BuildingTools/BuildingItemData_Stair_W.BuildingItemData_Stair_W"); - static UFortItemDefinition* BuildingItemData_RoofS = FindObject(L"/Game/Items/Weapons/BuildingTools/BuildingItemData_RoofS.BuildingItemData_RoofS"); - static UFortItemDefinition* WoodItemData = FindObject(L"/Game/Items/ResourcePickups/WoodItemData.WoodItemData"); - - WorldInventory->AddItem(EditToolItemDefinition, nullptr); - WorldInventory->AddItem(BuildingItemData_Wall, nullptr); - WorldInventory->AddItem(BuildingItemData_Floor, nullptr); - WorldInventory->AddItem(BuildingItemData_Stair_W, nullptr); - WorldInventory->AddItem(BuildingItemData_RoofS, nullptr); - WorldInventory->AddItem(PickaxeDefinition, nullptr); - WorldInventory->AddItem(WoodItemData, nullptr, 100); - - WorldInventory->Update(true); - auto PlayerStateAthena = NewPlayer->GetPlayerStateAthena(); - static auto CharacterPartsOffset = PlayerStateAthena->GetOffset("CharacterParts", false); - - if (CharacterPartsOffset != 0) + if (Globals::bNoMCP) { - auto CharacterParts = PlayerStateAthena->GetPtr<__int64>("CharacterParts"); - - static auto PartsOffset = FindOffsetStruct("/Script/FortniteGame.CustomCharacterParts", "Parts"); - auto Parts = (UObject**)(__int64(CharacterParts) + PartsOffset); // UCustomCharacterPart* Parts[0x6] + static auto CharacterPartsOffset = PlayerStateAthena->GetOffset("CharacterParts", false); - static auto headPart = LoadObject("/Game/Characters/CharacterParts/Female/Medium/Heads/F_Med_Head1.F_Med_Head1"); - static auto bodyPart = LoadObject("/Game/Characters/CharacterParts/Female/Medium/Bodies/F_Med_Soldier_01.F_Med_Soldier_01"); + if (CharacterPartsOffset != 0) + { + auto CharacterParts = PlayerStateAthena->GetPtr<__int64>("CharacterParts"); - Parts[(int)EFortCustomPartType::Head] = headPart; - Parts[(int)EFortCustomPartType::Body] = bodyPart; + static auto PartsOffset = FindOffsetStruct("/Script/FortniteGame.CustomCharacterParts", "Parts"); + auto Parts = (UObject**)(__int64(CharacterParts) + PartsOffset); // UCustomCharacterPart* Parts[0x6] - static auto OnRep_CharacterPartsFn = FindObject("/Script/FortniteGame.FortPlayerState.OnRep_CharacterParts"); - PlayerStateAthena->ProcessEvent(OnRep_CharacterPartsFn); + static auto headPart = LoadObject("/Game/Characters/CharacterParts/Female/Medium/Heads/F_Med_Head1.F_Med_Head1"); + static auto bodyPart = LoadObject("/Game/Characters/CharacterParts/Female/Medium/Bodies/F_Med_Soldier_01.F_Med_Soldier_01"); + + Parts[(int)EFortCustomPartType::Head] = headPart; + Parts[(int)EFortCustomPartType::Body] = bodyPart; + + static auto OnRep_CharacterPartsFn = FindObject("/Script/FortniteGame.FortPlayerState.OnRep_CharacterParts"); + PlayerStateAthena->ProcessEvent(OnRep_CharacterPartsFn); + } } PlayerStateAthena->GetSquadId() = PlayerStateAthena->GetTeamIndex() - 2; @@ -629,21 +656,23 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena static auto GameMemberInfoArrayOffset = GameState->GetOffset("GameMemberInfoArray", false); + struct FUniqueNetIdReplExperimental + { + unsigned char ahh[0x0028]; + }; + + auto& PlayerStateUniqueId = PlayerStateAthena->Get("UniqueId"); + // if (false) // if (GameMemberInfoArrayOffset != 0) if (Engine_Version >= 423) { - struct FUniqueNetIdRepl - { - unsigned char ahh[0x0028]; - }; - struct FGameMemberInfo : public FFastArraySerializerItem { unsigned char SquadId; // 0x000C(0x0001) (ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) unsigned char TeamIndex; // 0x000D(0x0001) (ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) unsigned char UnknownData00[0x2]; // 0x000E(0x0002) MISSED OFFSET - FUniqueNetIdRepl MemberUniqueId; // 0x0010(0x0028) (HasGetValueTypeHash, NativeAccessSpecifierPublic) + FUniqueNetIdReplExperimental MemberUniqueId; // 0x0010(0x0028) (HasGetValueTypeHash, NativeAccessSpecifierPublic) }; static auto GameMemberInfoStructSize = 0x38; @@ -671,7 +700,7 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena { GameMemberInfo->SquadId = PlayerStateAthena->GetSquadId(); GameMemberInfo->TeamIndex = PlayerStateAthena->GetTeamIndex(); - GameMemberInfo->MemberUniqueId = PlayerStateAthena->Get("UniqueId"); + GameMemberInfo->MemberUniqueId = PlayerStateUniqueId; } static auto GameMemberInfoArray_MembersOffset = FindOffsetStruct("/Script/FortniteGame.GameMemberInfoArray", "Members"); @@ -682,5 +711,44 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena GameMemberInfoArray->MarkArrayDirty(); } + if (Globals::bCreative) + { + static auto CreativePortalManagerOffset = GameState->GetOffset("CreativePortalManager"); + auto CreativePortalManager = GameState->Get(CreativePortalManagerOffset); + + static auto AvailablePortalsOffset = CreativePortalManager->GetOffset("AvailablePortals"); + auto& AvailablePortals = CreativePortalManager->Get>(AvailablePortalsOffset); + auto Portal = (AFortAthenaCreativePortal*)AvailablePortals.at(0); + AvailablePortals.Remove(0); + + static auto UsedPortalsOffset = CreativePortalManager->GetOffset("UsedPortals"); + auto& UsedPortals = CreativePortalManager->Get>(UsedPortalsOffset); + UsedPortals.Add(Portal); + + // Portal->GetCreatorName() = PlayerStateAthena->GetPlayerName(); + + *(FUniqueNetIdReplExperimental*)Portal->GetOwningPlayer() = PlayerStateUniqueId; + Portal->GetPortalOpen() = true; + + static auto PlayersReadyOffset = Portal->GetOffset("PlayersReady"); + auto& PlayersReady = Portal->Get>(PlayersReadyOffset); + PlayersReady.Add(PlayerStateUniqueId); + + Portal->GetUserInitiatedLoad() = true; + Portal->GetInErrorState() = false; + + static auto OwnedPortalOffset = NewPlayer->GetOffset("OwnedPortal"); + NewPlayer->Get(OwnedPortalOffset) = Portal; + + static auto CreativePlotLinkedVolumeOffset = NewPlayer->GetOffset("CreativePlotLinkedVolume"); + NewPlayer->Get(CreativePlotLinkedVolumeOffset) = Portal->GetLinkedVolume(); + + Portal->GetLinkedVolume()->GetVolumeState() = EVolumeState::Ready; + + static auto IslandPlayset = FindObject("/Game/Playsets/PID_Playset_60x60_Composed.PID_Playset_60x60_Composed"); + + UFortPlaysetItemDefinition::ShowPlayset(IslandPlayset, Portal->GetLinkedVolume()); + } + return Athena_HandleStartingNewPlayerOriginal(GameMode, NewPlayerActor); } \ No newline at end of file diff --git a/Project Reboot 3.0/FortGameStateAthena.cpp b/Project Reboot 3.0/FortGameStateAthena.cpp index 129cdbe..9fd338c 100644 --- a/Project Reboot 3.0/FortGameStateAthena.cpp +++ b/Project Reboot 3.0/FortGameStateAthena.cpp @@ -2,6 +2,11 @@ #include "reboot.h" +/* void AFortGameStateAthena::AddPlayerStateToGameMemberInfo(class AFortPlayerStateAthena* PlayerState) +{ + +} */ + void AFortGameStateAthena::OnRep_GamePhase() { EAthenaGamePhase OldGamePhase = GetGamePhase(); diff --git a/Project Reboot 3.0/FortGameStateAthena.h b/Project Reboot 3.0/FortGameStateAthena.h index f029aa6..66c1cbd 100644 --- a/Project Reboot 3.0/FortGameStateAthena.h +++ b/Project Reboot 3.0/FortGameStateAthena.h @@ -29,6 +29,7 @@ public: return Get(GamePhaseOffset); } + // void AddPlayerStateToGameMemberInfo(class AFortPlayerStateAthena* PlayerState); void OnRep_GamePhase(); void OnRep_CurrentPlaylistInfo(); diff --git a/Project Reboot 3.0/FortKismetLibrary.cpp b/Project Reboot 3.0/FortKismetLibrary.cpp index 6eb7837..f73602f 100644 --- a/Project Reboot 3.0/FortKismetLibrary.cpp +++ b/Project Reboot 3.0/FortKismetLibrary.cpp @@ -11,6 +11,25 @@ UFortResourceItemDefinition* UFortKismetLibrary::K2_GetResourceItemDefinition(EF return params.ret; } +void UFortKismetLibrary::ApplyCharacterCosmetics(UObject* WorldContextObject, const TArray& CharacterParts, UObject* PlayerState, bool* bSuccess) +{ + static auto fn = FindObject("/Script/FortniteGame.FortKismetLibrary.ApplyCharacterCosmetics"); + + struct + { + UObject* WorldContextObject; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + TArray CharacterParts; // (Parm, ZeroConstructor, NativeAccessSpecifierPublic) + UObject* PlayerState; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + bool bSuccess; // (Parm, OutParm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + } UFortKismetLibrary_ApplyCharacterCosmetics_Params{WorldContextObject, CharacterParts, PlayerState }; + + static auto DefaultClass = StaticClass(); + DefaultClass->ProcessEvent(fn, &UFortKismetLibrary_ApplyCharacterCosmetics_Params); + + if (bSuccess) + *bSuccess = UFortKismetLibrary_ApplyCharacterCosmetics_Params.bSuccess; +} + UClass* UFortKismetLibrary::StaticClass() { static auto ptr = FindObject(L"/Script/FortniteGame.FortKismetLibrary"); diff --git a/Project Reboot 3.0/FortKismetLibrary.h b/Project Reboot 3.0/FortKismetLibrary.h index 16f7bc4..3729127 100644 --- a/Project Reboot 3.0/FortKismetLibrary.h +++ b/Project Reboot 3.0/FortKismetLibrary.h @@ -9,6 +9,7 @@ class UFortKismetLibrary : public UObject { public: static UFortResourceItemDefinition* K2_GetResourceItemDefinition(EFortResourceType ResourceType); + static void ApplyCharacterCosmetics(UObject* WorldContextObject, const TArray& CharacterParts, UObject* PlayerState, bool* bSuccess); static UClass* StaticClass(); }; \ No newline at end of file diff --git a/Project Reboot 3.0/FortLootPackage.cpp b/Project Reboot 3.0/FortLootPackage.cpp index 03de19f..903b10d 100644 --- a/Project Reboot 3.0/FortLootPackage.cpp +++ b/Project Reboot 3.0/FortLootPackage.cpp @@ -95,8 +95,11 @@ std::vector> PickLootDrops(FName TierGroupN for (int p = 0; p < LTDTables.size(); p++) { auto LTD = LTDTables[p]; - auto& LTDRowMap = LTD->GetRowMap(); + if (!LTD) + continue; + + auto& LTDRowMap = LTD->GetRowMap(); auto LTDRowMapNum = LTDRowMap.Pairs.Elements.Num(); // auto TierGroupNameStr = TierGroupName.ToString(); diff --git a/Project Reboot 3.0/FortPlayerController.cpp b/Project Reboot 3.0/FortPlayerController.cpp index 194adff..a5ef45c 100644 --- a/Project Reboot 3.0/FortPlayerController.cpp +++ b/Project Reboot 3.0/FortPlayerController.cpp @@ -9,6 +9,7 @@ #include "ActorComponent.h" #include "FortPlayerStateAthena.h" +#include "globals.h" void AFortPlayerController::ClientReportDamagedResourceBuilding(ABuildingSMActor* BuildingSMActor, EFortResourceType PotentialResourceType, int PotentialResourceCount, bool bDestroyed, bool bJustHitWeakspot) { @@ -29,7 +30,7 @@ void AFortPlayerController::ServerExecuteInventoryItemHook(AFortPlayerController return; auto ItemDefinition = ItemInstance->GetItemEntry()->GetItemDefinition(); - + if (auto DecoItemDefinition = Cast(ItemDefinition)) { Pawn->PickUpActor(nullptr, DecoItemDefinition); // todo check ret value? @@ -53,7 +54,7 @@ void AFortPlayerController::ServerExecuteInventoryItemHook(AFortPlayerController { } - +} void AFortPlayerController::ServerAttemptAircraftJumpHook(AFortPlayerController* PC, FRotator ClientRotation) { @@ -87,6 +88,11 @@ void AFortPlayerController::ServerAttemptAircraftJumpHook(AFortPlayerController* void AFortPlayerController::ServerCreateBuildingActorHook(AFortPlayerController* PlayerController, FCreateBuildingActorData CreateBuildingData) { + auto PlayerStateAthena = Cast(PlayerController->GetPlayerState()); + + if (!PlayerStateAthena) + return; + UClass* BuildingClass = nullptr; FVector BuildLocation; FRotator BuildRotator; @@ -132,6 +138,8 @@ void AFortPlayerController::ServerCreateBuildingActorHook(AFortPlayerController* ExistingBuilding->K2_DestroyActor(); } + ExistingBuildings.Free(); + FTransform Transform{}; Transform.Translation = BuildLocation; Transform.Rotation = BuildRotator.Quaternion(); @@ -142,6 +150,8 @@ void AFortPlayerController::ServerCreateBuildingActorHook(AFortPlayerController* if (!BuildingActor) return; + BuildingActor->SetPlayerPlaced(true); + BuildingActor->SetTeam(PlayerStateAthena->GetTeamIndex()); BuildingActor->InitializeBuildingActor(PlayerController, BuildingActor, true); } @@ -164,7 +174,6 @@ void AFortPlayerController::ServerPlayEmoteItemHook(AFortPlayerController* Playe if (!AbilityToUse) return; - int outHandle = 0; FGameplayAbilitySpecHandle Handle{}; @@ -220,8 +229,8 @@ void AFortPlayerController::ServerEditBuildingActorHook(AFortPlayerController* P { BuildingActor->SetPlayerPlaced(true); - // if (auto PlayerState = Cast(PlayerController->PlayerState)) - // BuildingActor->SetTeam(PlayerState->TeamIndex); + if (auto PlayerState = Cast(PlayerController->GetPlayerState())) + BuildingActor->SetTeam(PlayerState->GetTeamIndex()); // BuildingActor->OnRep_Team(); } @@ -232,7 +241,7 @@ void AFortPlayerController::ServerEndEditingBuildingActorHook(AFortPlayerControl auto Pawn = PlayerController->GetMyFortPawn(); if (!BuildingActorToStopEditing || !Pawn - // || BuildingActorToStopEditing->EditingPlayer != PlayerController->PlayerState + || BuildingActorToStopEditing->GetEditingPlayer() != PlayerController->GetPlayerState() || BuildingActorToStopEditing->IsDestroyed()) return; @@ -243,7 +252,6 @@ void AFortPlayerController::ServerEndEditingBuildingActorHook(AFortPlayerControl if (EditTool) { - // EditTool->bEditConfirmed = true; EditTool->GetEditActor() = nullptr; // EditTool->OnRep_EditActor(); } diff --git a/Project Reboot 3.0/FortPlayerController.h b/Project Reboot 3.0/FortPlayerController.h index a31ae69..823756f 100644 --- a/Project Reboot 3.0/FortPlayerController.h +++ b/Project Reboot 3.0/FortPlayerController.h @@ -9,6 +9,21 @@ struct FCreateBuildingActorData { uint32_t BuildingClassHandle; FVector BuildLoc; FRotator BuildRot; bool bMirrored; }; +struct FFortAthenaLoadout +{ + UObject*& GetCharacter() + { + static auto CharacterOffset = FindOffsetStruct("/Script/FortniteGame.FortAthenaLoadout", "Character"); + return *(UObject**)(__int64(this) + CharacterOffset); + } + + UObject*& GetPickaxe() + { + static auto PickaxeOffset = FindOffsetStruct("/Script/FortniteGame.FortAthenaLoadout", "Pickaxe"); + return *(UObject**)(__int64(this) + PickaxeOffset); + } +}; + class AFortPlayerController : public APlayerController { public: @@ -32,6 +47,18 @@ public: return Class; } + FFortAthenaLoadout* GetCosmeticLoadout() + { + static auto CosmeticLoadoutPCOffset = this->GetOffset("CosmeticLoadoutPC", false); + + if (CosmeticLoadoutPCOffset == 0) + CosmeticLoadoutPCOffset = this->GetOffset("CustomizationLoadout"); + + auto CosmeticLoadout = this->GetPtr(CosmeticLoadoutPCOffset); + + return CosmeticLoadout; + } + static void ServerExecuteInventoryItemHook(AFortPlayerController* PlayerController, FGuid ItemGuid); static void ServerAttemptAircraftJumpHook(AFortPlayerController* PC, FRotator ClientRotation); diff --git a/Project Reboot 3.0/FortPlayerControllerAthena.cpp b/Project Reboot 3.0/FortPlayerControllerAthena.cpp index 3923d36..c22046e 100644 --- a/Project Reboot 3.0/FortPlayerControllerAthena.cpp +++ b/Project Reboot 3.0/FortPlayerControllerAthena.cpp @@ -1,4 +1,84 @@ #include "FortPlayerControllerAthena.h" +#include "FortPlayerPawn.h" +#include "FortKismetLibrary.h" + +#include "SoftObjectPtr.h" + +void ApplyCID(AFortPlayerPawn* Pawn, UObject* CID) +{ + if (!CID) + return; + + static auto HeroDefinitionOffset = CID->GetOffset("HeroDefinition"); + auto HeroDefinition = CID->Get(HeroDefinitionOffset); + + using UFortHeroSpecialization = UObject; + + static auto SpecializationsOffset = HeroDefinition->GetOffset("Specializations"); + auto& Specializations = HeroDefinition->Get>>(SpecializationsOffset); + + auto PlayerState = Pawn->GetPlayerState(); + + for (int i = 0; i < Specializations.Num(); i++) + { + auto& SpecializationSoft = Specializations.at(i); + + auto Specialization = SpecializationSoft.Get(); + + if (Specialization) + { + static auto Specialization_CharacterPartsOffset = Specialization->GetOffset("CharacterParts"); + auto& CharacterParts = Specialization->Get>>(Specialization_CharacterPartsOffset); + + bool aa; + + TArray CharacterPartsaa; + + for (int z = 0; z < CharacterParts.Num(); z++) + { + auto& CharacterPartSoft = CharacterParts.at(z); + auto CharacterPart = CharacterPartSoft.Get(); + + CharacterPartsaa.Add(CharacterPart); + + continue; + } + + UFortKismetLibrary::ApplyCharacterCosmetics(GetWorld(), CharacterPartsaa, PlayerState, &aa); + CharacterPartsaa.Free(); + } + } +} + +void AFortPlayerControllerAthena::ServerAcknowledgePossessionHook(APlayerController* Controller, APawn* Pawn) +{ + static auto AcknowledgedPawnOffset = Controller->GetOffset("AcknowledgedPawn"); + Controller->Get(AcknowledgedPawnOffset) = Pawn; + + auto ControllerAsFort = Cast(Controller); + auto PawnAsFort = Cast(Pawn); + auto PlayerStateAsFort = Cast(Pawn->GetPlayerState()); + + if (!PawnAsFort) + return; + + static auto UpdatePlayerCustomCharacterPartsVisualizationFn = FindObject("/Script/FortniteGame.FortKismetLibrary.UpdatePlayerCustomCharacterPartsVisualization"); + + if (!UpdatePlayerCustomCharacterPartsVisualizationFn) + { + static auto CosmeticLoadoutPCOffset = Controller->GetOffset("CosmeticLoadoutPC"); + auto CosmeticLoadout = ControllerAsFort->GetCosmeticLoadout(); + + ApplyCID(PawnAsFort, CosmeticLoadout->GetCharacter()); + + return; + } + + if (!PlayerStateAsFort) + return; + + UFortKismetLibrary::StaticClass()->ProcessEvent(UpdatePlayerCustomCharacterPartsVisualizationFn, &PlayerStateAsFort); +} void AFortPlayerControllerAthena::GetPlayerViewPointHook(AFortPlayerControllerAthena* PlayerController, FVector& Location, FRotator& Rotation) { diff --git a/Project Reboot 3.0/FortPlayerControllerAthena.h b/Project Reboot 3.0/FortPlayerControllerAthena.h index 8ffd655..5f7bdd5 100644 --- a/Project Reboot 3.0/FortPlayerControllerAthena.h +++ b/Project Reboot 3.0/FortPlayerControllerAthena.h @@ -13,11 +13,6 @@ public: return (AFortPlayerStateAthena*)GetPlayerState(); } - static void ServerAcknowledgePossessionHook(APlayerController* Controller, APawn* Pawn) - { - static auto AcknowledgedPawnOffset = Controller->GetOffset("AcknowledgedPawn"); - Controller->Get(AcknowledgedPawnOffset) = Pawn; - } - + static void ServerAcknowledgePossessionHook(APlayerController* Controller, APawn* Pawn); static void GetPlayerViewPointHook(AFortPlayerControllerAthena* PlayerController, FVector& Location, FRotator& Rotation); }; \ No newline at end of file diff --git a/Project Reboot 3.0/FortPlayerPawn.cpp b/Project Reboot 3.0/FortPlayerPawn.cpp index 420ddd8..095ee5a 100644 --- a/Project Reboot 3.0/FortPlayerPawn.cpp +++ b/Project Reboot 3.0/FortPlayerPawn.cpp @@ -1,6 +1,19 @@ #include "FortPlayerPawn.h" #include +void AFortPlayerPawn::ServerChoosePart(EFortCustomPartType Part, UObject* ChosenCharacterPart) +{ + static auto fn = FindObject("/Script/FortniteGame.FortPlayerPawn.ServerChoosePart"); + + struct + { + EFortCustomPartType Part; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + UObject* ChosenCharacterPart; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + } AFortPlayerPawn_ServerChoosePart_Params{Part, ChosenCharacterPart}; + + this->ProcessEvent(fn, &AFortPlayerPawn_ServerChoosePart_Params); +} + void AFortPlayerPawn::ServerSendZiplineStateHook(AFortPlayerPawn* Pawn, FZiplinePawnState InZiplineState) { static auto ZiplineStateOffset = Pawn->GetOffset("ZiplineState"); @@ -51,34 +64,43 @@ void AFortPlayerPawn::ServerSendZiplineStateHook(AFortPlayerPawn* Pawn, FZipline void AFortPlayerPawn::ServerHandlePickupHook(AFortPlayerPawn* Pawn, AFortPickup* Pickup, float InFlyTime, FVector InStartDirection, bool bPlayPickupSound) { + if (!Pickup) + return; + static auto bPickedUpOffset = Pickup->GetOffset("bPickedUp"); - if (Pickup && !Pickup->Get(bPickedUpOffset)) - { - static auto IncomingPickupsOffset = Pawn->GetOffset("IncomingPickups"); - static auto PickupLocationDataOffset = Pickup->GetOffset("PickupLocationData"); - auto PickupLocationData = Pickup->GetPtr<__int64>(PickupLocationDataOffset); + if (Pickup->Get(bPickedUpOffset)) + return; - Pawn->Get>(IncomingPickupsOffset).Add(Pickup); + static auto IncomingPickupsOffset = Pawn->GetOffset("IncomingPickups"); + static auto PickupLocationDataOffset = Pickup->GetOffset("PickupLocationData"); + auto PickupLocationData = Pickup->GetPtr<__int64>(PickupLocationDataOffset); - static auto PickupTargetOffset = FindOffsetStruct("/Script/FortniteGame.FortPickupLocationData", "PickupTarget"); - static auto FlyTimeOffset = FindOffsetStruct("/Script/FortniteGame.FortPickupLocationData", "FlyTime"); - static auto ItemOwnerOffset = FindOffsetStruct("/Script/FortniteGame.FortPickupLocationData", "ItemOwner"); - static auto StartDirectionOffset = FindOffsetStruct("/Script/FortniteGame.FortPickupLocationData", "StartDirection"); - static auto PickupGuidOffset = FindOffsetStruct("/Script/FortniteGame.FortPickupLocationData", "PickupGuid"); + Pawn->Get>(IncomingPickupsOffset).Add(Pickup); - *(AFortPawn**)(__int64(PickupLocationData) + PickupTargetOffset) = Pawn; - *(float*)(__int64(PickupLocationData) + FlyTimeOffset) = 0.40f; - *(AFortPawn**)(__int64(PickupLocationData) + ItemOwnerOffset) = Pawn; - *(FVector*)(__int64(PickupLocationData) + StartDirectionOffset) = InStartDirection; - *(FGuid*)(__int64(PickupLocationData) + PickupGuidOffset) = Pawn->GetCurrentWeapon() ? Pawn->GetCurrentWeapon()->GetItemEntryGuid() : FGuid(); + static auto PickupTargetOffset = FindOffsetStruct("/Script/FortniteGame.FortPickupLocationData", "PickupTarget"); + static auto FlyTimeOffset = FindOffsetStruct("/Script/FortniteGame.FortPickupLocationData", "FlyTime"); + static auto ItemOwnerOffset = FindOffsetStruct("/Script/FortniteGame.FortPickupLocationData", "ItemOwner"); + static auto StartDirectionOffset = FindOffsetStruct("/Script/FortniteGame.FortPickupLocationData", "StartDirection"); + static auto PickupGuidOffset = FindOffsetStruct("/Script/FortniteGame.FortPickupLocationData", "PickupGuid"); - static auto OnRep_PickupLocationDataFn = FindObject(L"/Script/FortniteGame.FortPickup.OnRep_PickupLocationData"); - Pickup->ProcessEvent(OnRep_PickupLocationDataFn); + *(AFortPawn**)(__int64(PickupLocationData) + PickupTargetOffset) = Pawn; + *(float*)(__int64(PickupLocationData) + FlyTimeOffset) = 0.40f; + *(AFortPawn**)(__int64(PickupLocationData) + ItemOwnerOffset) = Pawn; + *(FVector*)(__int64(PickupLocationData) + StartDirectionOffset) = InStartDirection; + *(FGuid*)(__int64(PickupLocationData) + PickupGuidOffset) = Pawn->GetCurrentWeapon() ? Pawn->GetCurrentWeapon()->GetItemEntryGuid() : FGuid(); - Pickup->Get(bPickedUpOffset) = true; + static auto OnRep_PickupLocationDataFn = FindObject(L"/Script/FortniteGame.FortPickup.OnRep_PickupLocationData"); + Pickup->ProcessEvent(OnRep_PickupLocationDataFn); - static auto OnRep_bPickedUpFn = FindObject(L"/Script/FortniteGame.FortPickup.OnRep_bPickedUp"); - Pickup->ProcessEvent(OnRep_bPickedUpFn); - } + Pickup->Get(bPickedUpOffset) = true; + + static auto OnRep_bPickedUpFn = FindObject(L"/Script/FortniteGame.FortPickup.OnRep_bPickedUp"); + Pickup->ProcessEvent(OnRep_bPickedUpFn); +} + +UClass* AFortPlayerPawn::StaticClass() +{ + static auto Class = FindObject("/Script/FortniteGame.FortPlayerPawn"); + return Class; } \ No newline at end of file diff --git a/Project Reboot 3.0/FortPlayerPawn.h b/Project Reboot 3.0/FortPlayerPawn.h index 8b65a92..cf9adf9 100644 --- a/Project Reboot 3.0/FortPlayerPawn.h +++ b/Project Reboot 3.0/FortPlayerPawn.h @@ -7,9 +7,25 @@ struct PadHex100 { char pad[0x100]; }; using FZiplinePawnState = PadHex100; +enum class EFortCustomPartType : uint8_t // todo move +{ + Head = 0, + Body = 1, + Hat = 2, + Backpack = 3, + Charm = 4, + Face = 5, + NumTypes = 6, + EFortCustomPartType_MAX = 7 +}; + class AFortPlayerPawn : public AFortPawn { public: + void ServerChoosePart(EFortCustomPartType Part, class UObject* ChosenCharacterPart); + static void ServerSendZiplineStateHook(AFortPlayerPawn* Pawn, FZiplinePawnState InZiplineState); static void ServerHandlePickupHook(AFortPlayerPawn* Pawn, AFortPickup* Pickup, float InFlyTime, FVector InStartDirection, bool bPlayPickupSound); + + static UClass* StaticClass(); }; \ No newline at end of file diff --git a/Project Reboot 3.0/FortPlaysetItemDefinition.cpp b/Project Reboot 3.0/FortPlaysetItemDefinition.cpp new file mode 100644 index 0000000..a3b1c8d --- /dev/null +++ b/Project Reboot 3.0/FortPlaysetItemDefinition.cpp @@ -0,0 +1,19 @@ +#include "FortPlaysetItemDefinition.h" + +void UFortPlaysetItemDefinition::ShowPlayset(UFortPlaysetItemDefinition* PlaysetItemDef, AFortVolume* Volume) +{ + auto VolumeToUse = Volume; + + static auto PlaysetLevelStreamComponentClass = FindObject("/Script/FortniteGame.PlaysetLevelStreamComponent"); + auto LevelStreamComponent = (UPlaysetLevelStreamComponent*)VolumeToUse->GetComponentByClass(PlaysetLevelStreamComponentClass); + + if (!LevelStreamComponent) + { + return; + } + + static auto SetPlaysetFn = FindObject("/Script/FortniteGame.PlaysetLevelStreamComponent.SetPlayset"); + LevelStreamComponent->ProcessEvent(SetPlaysetFn, &PlaysetItemDef); + + LoadPlaysetOriginal(LevelStreamComponent); +} \ No newline at end of file diff --git a/Project Reboot 3.0/FortPlaysetItemDefinition.h b/Project Reboot 3.0/FortPlaysetItemDefinition.h new file mode 100644 index 0000000..77e8429 --- /dev/null +++ b/Project Reboot 3.0/FortPlaysetItemDefinition.h @@ -0,0 +1,14 @@ +#pragma once + +#include "FortItemDefinition.h" +#include "FortVolume.h" + +using UPlaysetLevelStreamComponent = UObject; + +extern inline __int64 (*LoadPlaysetOriginal)(UPlaysetLevelStreamComponent* a1) = nullptr; + +class UFortPlaysetItemDefinition : public UFortItemDefinition // UFortAccountItemDefinition +{ +public: + static void ShowPlayset(UFortPlaysetItemDefinition* PlaysetItemDef, AFortVolume* Volume); +}; \ No newline at end of file diff --git a/Project Reboot 3.0/FortVolume.h b/Project Reboot 3.0/FortVolume.h new file mode 100644 index 0000000..f516c35 --- /dev/null +++ b/Project Reboot 3.0/FortVolume.h @@ -0,0 +1,22 @@ +#pragma once + +#include "BuildingActor.h" + +enum class EVolumeState : uint8_t +{ + Uninitialized = 0, + ReadOnly = 1, + Initializing = 2, + Ready = 3, + EVolumeState_MAX = 4 +}; + +class AFortVolume : public ABuildingActor // ABuildingGameplayActor +{ +public: + EVolumeState& GetVolumeState() + { + static auto VolumeStateOffset = GetOffset("VolumeState"); + return Get(VolumeStateOffset); + } +}; \ No newline at end of file diff --git a/Project Reboot 3.0/GameModeBase.cpp b/Project Reboot 3.0/GameModeBase.cpp index 0366421..d90ea42 100644 --- a/Project Reboot 3.0/GameModeBase.cpp +++ b/Project Reboot 3.0/GameModeBase.cpp @@ -1,7 +1,7 @@ #include "GameModeBase.h" #include "reboot.h" -#include "FortPlayerController.h" +#include "FortPlayerControllerAthena.h" APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AController* NewPlayer, AActor* StartSpot) { @@ -17,5 +17,37 @@ APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AControll GameMode->ProcessEvent(fn, &AGameModeBase_SpawnDefaultPawnAtTransform_Params); + auto NewPlayerAsAthena = Cast(NewPlayer); + + if (NewPlayerAsAthena) + { + auto WorldInventory = NewPlayerAsAthena->GetWorldInventory(); + + auto CosmeticLoadoutPickaxe = NewPlayerAsAthena->GetCosmeticLoadout()->GetPickaxe(); + static auto WeaponDefinitionOffset = FindOffsetStruct("/Script/FortniteGame.AthenaPickaxeItemDefinition", "WeaponDefinition"); + + auto Pickaxe = CosmeticLoadoutPickaxe ? CosmeticLoadoutPickaxe->Get(WeaponDefinitionOffset) + : FindObject(L"/Game/Athena/Items/Weapons/WID_Harvest_Pickaxe_Athena_C_T01.WID_Harvest_Pickaxe_Athena_C_T01"); + + static UFortItemDefinition* EditToolItemDefinition = FindObject(L"/Game/Items/Weapons/BuildingTools/EditTool.EditTool"); + static UFortItemDefinition* PickaxeDefinition = Pickaxe; + static UFortItemDefinition* BuildingItemData_Wall = FindObject(L"/Game/Items/Weapons/BuildingTools/BuildingItemData_Wall.BuildingItemData_Wall"); + static UFortItemDefinition* BuildingItemData_Floor = FindObject(L"/Game/Items/Weapons/BuildingTools/BuildingItemData_Floor.BuildingItemData_Floor"); + static UFortItemDefinition* BuildingItemData_Stair_W = FindObject(L"/Game/Items/Weapons/BuildingTools/BuildingItemData_Stair_W.BuildingItemData_Stair_W"); + static UFortItemDefinition* BuildingItemData_RoofS = FindObject(L"/Game/Items/Weapons/BuildingTools/BuildingItemData_RoofS.BuildingItemData_RoofS"); + static UFortItemDefinition* WoodItemData = FindObject(L"/Game/Items/ResourcePickups/WoodItemData.WoodItemData"); + + WorldInventory->AddItem(EditToolItemDefinition, nullptr); + WorldInventory->AddItem(BuildingItemData_Wall, nullptr); + WorldInventory->AddItem(BuildingItemData_Floor, nullptr); + WorldInventory->AddItem(BuildingItemData_Stair_W, nullptr); + WorldInventory->AddItem(BuildingItemData_RoofS, nullptr); + WorldInventory->AddItem(PickaxeDefinition, nullptr); + WorldInventory->AddItem(WoodItemData, nullptr, 100); + + WorldInventory->Update(true); + } + + return AGameModeBase_SpawnDefaultPawnAtTransform_Params.ReturnValue; } \ No newline at end of file diff --git a/Project Reboot 3.0/GameplayStatics.cpp b/Project Reboot 3.0/GameplayStatics.cpp index 9b53096..c7321ec 100644 --- a/Project Reboot 3.0/GameplayStatics.cpp +++ b/Project Reboot 3.0/GameplayStatics.cpp @@ -27,6 +27,23 @@ float UGameplayStatics::GetTimeSeconds(const UObject* WorldContextObject) return TimeSeconds; } +UObject* UGameplayStatics::SpawnObject(UClass* ObjectClass, UObject* Outer) +{ + static auto fn = FindObject("/Script/Engine.GameplayStatics.SpawnObject"); + + struct + { + UClass* ObjectClass; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, UObjectWrapper, HasGetValueTypeHash, NativeAccessSpecifierPublic) + UObject* Outer; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + UObject* ReturnValue; // (Parm, OutParm, ZeroConstructor, ReturnParm, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + } UGameplayStatics_SpawnObject_Params{ObjectClass, Outer}; + + static auto defaultObj = StaticClass(); + defaultObj->ProcessEvent(fn, &UGameplayStatics_SpawnObject_Params); + + return UGameplayStatics_SpawnObject_Params.ReturnValue; +} + UClass* UGameplayStatics::StaticClass() { static auto Class = FindObject(L"/Script/Engine.GameplayStatics"); diff --git a/Project Reboot 3.0/GameplayStatics.h b/Project Reboot 3.0/GameplayStatics.h index 66961e3..4435b1e 100644 --- a/Project Reboot 3.0/GameplayStatics.h +++ b/Project Reboot 3.0/GameplayStatics.h @@ -9,6 +9,7 @@ class UGameplayStatics : public UObject public: static TArray GetAllActorsOfClass(const UObject* WorldContextObject, UClass* ActorClass); static float GetTimeSeconds(const UObject* WorldContextObject); + static UObject* SpawnObject(UClass* ObjectClass, UObject* Outer); static UClass* StaticClass(); }; \ No newline at end of file diff --git a/Project Reboot 3.0/MegaStormManager.h b/Project Reboot 3.0/MegaStormManager.h new file mode 100644 index 0000000..fb6d30d --- /dev/null +++ b/Project Reboot 3.0/MegaStormManager.h @@ -0,0 +1,26 @@ +#pragma once + +#include "Actor.h" + +#include "reboot.h" + +struct FMegaStormCircle +{ + int GetStructSize() + { + static auto MegaStormCircleStruct = FindObject("/Script/FortniteGame.MegaStormCircle"); + return MegaStormCircleStruct->GetPropertiesSize(); + } + + +}; + +class AMegaStormManager : public AActor +{ +public: + TArray<__int64>& GetMegaStormCircles() + { + static auto MegaStormCirclesOffset = GetOffset("MegaStormCircles"); + return Get>(MegaStormCirclesOffset); + } +}; \ No newline at end of file diff --git a/Project Reboot 3.0/Pawn.h b/Project Reboot 3.0/Pawn.h index 5c54117..4ce8c76 100644 --- a/Project Reboot 3.0/Pawn.h +++ b/Project Reboot 3.0/Pawn.h @@ -5,4 +5,9 @@ class APawn : public AActor { public: + UObject* GetPlayerState() + { + static auto PlayerStateOffset = GetOffset("PlayerState"); + return Get(PlayerStateOffset); + } }; \ No newline at end of file diff --git a/Project Reboot 3.0/Project Reboot 3.0.vcxproj b/Project Reboot 3.0/Project Reboot 3.0.vcxproj index 8766db5..799ce02 100644 --- a/Project Reboot 3.0/Project Reboot 3.0.vcxproj +++ b/Project Reboot 3.0/Project Reboot 3.0.vcxproj @@ -190,6 +190,7 @@ + @@ -210,6 +211,7 @@ + @@ -226,6 +228,7 @@ + @@ -243,7 +246,9 @@ + + @@ -256,6 +261,7 @@ + @@ -263,6 +269,7 @@ + diff --git a/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters b/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters index f310c48..17d8857 100644 --- a/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters +++ b/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters @@ -119,6 +119,9 @@ FortniteGame\Source\FortniteGame\Private\Items + + FortniteGame\Source\FortniteGame\Private\Items + @@ -365,6 +368,24 @@ FortniteGame\Source\FortniteGame\Public\Items + + Reboot\Public + + + FortniteGame\Source\FortniteGame\Public + + + Reboot\Public + + + FortniteGame\Source\FortniteGame\Public\Creative + + + FortniteGame\Source\FortniteGame\Public\Creative + + + FortniteGame\Source\FortniteGame\Public\Items + @@ -529,6 +550,9 @@ {9923af6f-0a65-43f7-ad58-8a66e83814ba} + + {51b57917-fec7-41b7-bdc8-ad284a5385a4} + diff --git a/Project Reboot 3.0/SoftObjectPtr.h b/Project Reboot 3.0/SoftObjectPtr.h index 9b4a9b9..7a46e67 100644 --- a/Project Reboot 3.0/SoftObjectPtr.h +++ b/Project Reboot 3.0/SoftObjectPtr.h @@ -20,6 +20,9 @@ public: T* Get() { + if (SoftObjectPtr.ObjectID.AssetPathName.ComparisonIndex.Value <= 0) + return nullptr; + return FindObject(SoftObjectPtr.ObjectID.AssetPathName.ToString()); } }; \ No newline at end of file diff --git a/Project Reboot 3.0/World.cpp b/Project Reboot 3.0/World.cpp index a4cdae1..b932228 100644 --- a/Project Reboot 3.0/World.cpp +++ b/Project Reboot 3.0/World.cpp @@ -5,6 +5,14 @@ #include "reboot.h" +UObject* UWorld::K2_GetWorldSettings() +{ + static auto fn = FindObject("/Script/Engine.World.K2_GetWorldSettings"); + UObject* WorldSettings; + this->ProcessEvent(fn, &WorldSettings); + return WorldSettings; +} + void UWorld::Listen() { auto GameNetDriverName = UKismetStringLibrary::Conv_StringToName(L"GameNetDriver"); diff --git a/Project Reboot 3.0/World.h b/Project Reboot 3.0/World.h index 47854ed..efd6c65 100644 --- a/Project Reboot 3.0/World.h +++ b/Project Reboot 3.0/World.h @@ -56,5 +56,7 @@ public: return SpawnActor(Class, UserTransformPtr, SpawnParameters); } + UObject* K2_GetWorldSettings(); + void Listen(); }; \ No newline at end of file diff --git a/Project Reboot 3.0/addresses.cpp b/Project Reboot 3.0/addresses.cpp index 678c478..6d4ceb4 100644 --- a/Project Reboot 3.0/addresses.cpp +++ b/Project Reboot 3.0/addresses.cpp @@ -13,7 +13,9 @@ #include "finder.h" #include +#include "ai.h" #include "BuildingActor.h" +#include "FortPlaysetItemDefinition.h" void Addresses::SetupVersion() { @@ -110,9 +112,11 @@ void Addresses::FindAll() { LOG_INFO(LogDev, "9241"); Addresses::ProcessEvent = FindProcessEvent(); + UObject::ProcessEventOriginal = decltype(UObject::ProcessEventOriginal)(ProcessEvent); LOG_INFO(LogDev, "151"); Addresses::StaticFindObject = FindStaticFindObject(); + StaticFindObjectOriginal = decltype(StaticFindObjectOriginal)(StaticFindObject); LOG_INFO(LogDev, "2151"); Addresses::GetPlayerViewpoint = FindGetPlayerViewpoint(); @@ -149,7 +153,7 @@ void Addresses::FindAll() LOG_INFO(LogDev, "1231"); Addresses::CollectGarbage = FindCollectGarbage(); - LOG_INFO(LogDev, "1123"); + LOG_INFO(LogDev, "112113"); Addresses::NoMCP = FindNoMCP(); LOG_INFO(LogDev, "131"); @@ -184,6 +188,10 @@ void Addresses::FindAll() Addresses::ChangeGameSessionId = FindChangeGameSessionId(); LOG_INFO(LogDev, "10"); + Addresses::DispatchRequest = FindDispatchRequest(); + Addresses::AddNavigationSystemToWorld = FindAddNavigationSystemToWorld(); + Addresses::NavSystemCleanUp = FindNavSystemCleanUp(); + Addresses::LoadPlayset = FindLoadPlayset(); } void Addresses::Print() @@ -216,6 +224,10 @@ void Addresses::Print() LOG_INFO(LogDev, "StaticLoadObject: 0x{:x}", StaticLoadObject - Base); LOG_INFO(LogDev, "ActorGetNetMode: 0x{:x}", ActorGetNetMode - Base); LOG_INFO(LogDev, "ChangeGameSessionId: 0x{:x}", ChangeGameSessionId - Base); + LOG_INFO(LogDev, "DispatchRequest: 0x{:x}", DispatchRequest - Base); + LOG_INFO(LogDev, "AddNavigationSystemToWorld: 0x{:x}", AddNavigationSystemToWorld - Base); + LOG_INFO(LogDev, "NavSystemCleanUp: 0x{:x}", NavSystemCleanUp - Base); + LOG_INFO(LogDev, "LoadPlayset: 0x{:x}", LoadPlayset - Base); } void Offsets::FindAll() @@ -268,8 +280,8 @@ void Offsets::Print() void Addresses::Init() { - UObject::ProcessEventOriginal = decltype(UObject::ProcessEventOriginal)(ProcessEvent); - StaticFindObjectOriginal = decltype(StaticFindObjectOriginal)(StaticFindObject); + // UObject::ProcessEventOriginal = decltype(UObject::ProcessEventOriginal)(ProcessEvent); // we do this in Addresses::FindAll() + // StaticFindObjectOriginal = decltype(StaticFindObjectOriginal)(StaticFindObject); // we do this in Addresses::FindAll() UWorld::SpawnActorOriginal = decltype(UWorld::SpawnActorOriginal)(SpawnActor); UNetDriver::InitListenOriginal = decltype(UNetDriver::InitListenOriginal)(InitListen); AGameSession::KickPlayerOriginal = decltype(AGameSession::KickPlayerOriginal)(KickPlayer); @@ -284,6 +296,10 @@ void Addresses::Init() Addresses::SetWorld = Engine_Version < 426 ? Addresses::SetWorld : __int64(DefaultNetDriver->VFTable[Addresses::SetWorld]); UNetDriver::SetWorldOriginal = decltype(UNetDriver::SetWorldOriginal)(SetWorld); + AddNavigationSystemToWorldOriginal = decltype(AddNavigationSystemToWorldOriginal)(AddNavigationSystemToWorld); + NavSystemCleanUpOriginal = decltype(NavSystemCleanUpOriginal)(Addresses::NavSystemCleanUp); + LoadPlaysetOriginal = decltype(LoadPlaysetOriginal)(Addresses::LoadPlayset); + // if (Engine_Version >= 421) ChunkedObjects = decltype(ChunkedObjects)(ObjectArray); // else UnchunkedObjects = decltype(UnchunkedObjects)(ObjectArray); } @@ -295,6 +311,7 @@ std::vector Addresses::GetFunctionsToNull() if (Engine_Version == 420) { toNull.push_back(Memcury::Scanner::FindPattern("48 8B C4 57 48 81 EC ? ? ? ? 4C 8B 82 ? ? ? ? 48 8B F9 0F 29 70 E8 0F 29 78 D8").Get()); // Pawn Overlap + // toNull.push_back(Memcury::Scanner::FindPattern("E8 ? ? ? ? EB 26 40 38 3D ? ? ? ?").RelativeOffset(1).Get()); // collectgarbage } if (Engine_Version == 421) diff --git a/Project Reboot 3.0/addresses.h b/Project Reboot 3.0/addresses.h index 2d3480d..dc3fc56 100644 --- a/Project Reboot 3.0/addresses.h +++ b/Project Reboot 3.0/addresses.h @@ -36,6 +36,10 @@ namespace Addresses extern inline uint64 GIsClient = 0; extern inline uint64 ActorGetNetMode = 0; extern inline uint64 ChangeGameSessionId = 0; + extern inline uint64 DispatchRequest = 0; + extern inline uint64 AddNavigationSystemToWorld = 0; + extern inline uint64 NavSystemCleanUp = 0; + extern inline uint64 LoadPlayset = 0; void SetupVersion(); // Finds Engine Version void FindAll(); diff --git a/Project Reboot 3.0/ai.h b/Project Reboot 3.0/ai.h new file mode 100644 index 0000000..515a414 --- /dev/null +++ b/Project Reboot 3.0/ai.h @@ -0,0 +1,91 @@ +#pragma once + +#include "reboot.h" +#include "Actor.h" +#include "SoftObjectPath.h" +#include "KismetStringLibrary.h" +#include "GameplayStatics.h" + +using UNavigationSystemV1 = UObject; +using UNavigationSystemConfig = UObject; +using AAthenaNavSystemConfigOverride = UObject; +using UAthenaNavSystem = UObject; +using UAthenaNavSystemConfig = UObject; + +enum class EFNavigationSystemRunMode : uint8_t +{ + InvalidMode = 0, + GameMode = 1, + EditorMode = 2, + SimulationMode = 3, + PIEMode = 4, + FNavigationSystemRunMode_MAX = 5 +}; + +enum class ENavSystemOverridePolicy : uint8_t +{ + Override = 0, + Append = 1, + Skip = 2, + ENavSystemOverridePolicy_MAX = 3 +}; + +extern inline void (*NavSystemCleanUpOriginal)(UNavigationSystemV1*, uint8) = nullptr; + +extern inline void (*AddNavigationSystemToWorldOriginal)(UWorld& WorldOwner, EFNavigationSystemRunMode RunMode, UNavigationSystemConfig* NavigationSystemConfig, char bInitializeForWorld, + char bOverridePreviousNavSys) = nullptr; + +static void SetNavigationSystem(AAthenaNavSystemConfigOverride* NavSystemOverride) +{ + auto WorldSettings = GetWorld()->K2_GetWorldSettings(); + + NavSystemOverride->Get("OverridePolicy") = ENavSystemOverridePolicy::Append; + + WorldSettings->Get("NavigationSystemConfigOverride") = NavSystemOverride->Get("NavigationSystemConfig"); + WorldSettings->Get("NavigationSystemConfig")->Get("bIsOverriden") = true; + + auto NavSystem = (UAthenaNavSystem*)GetWorld()->Get("NavigationSystem"); + + NavSystemCleanUpOriginal(NavSystem, 0); + + GetWorld()->Get("NavigationSystem") = nullptr; + + if (!NavSystemOverride->Get("NavigationSystemConfig")) + return; + + auto& ClassPath = NavSystemOverride->Get("NavigationSystemConfig")->Get("NavigationSystemClass"); + + auto NewNavSystemClass = FindObject(ClassPath.AssetPathName.ToString()); + + if (!NewNavSystemClass) + return; + + LOG_INFO(LogAI, "Setup navigation system.\n"); + + AddNavigationSystemToWorldOriginal(*GetWorld(), EFNavigationSystemRunMode::GameMode, NavSystemOverride->Get("NavigationSystemConfig"), true, false); +} + +static void SetupNavConfig() +{ + static auto AthenaNavSystemConfigOverrideClass = FindObject("/Script/FortniteGame.AthenaNavSystemConfigOverride"); + auto NavSystemOverride = GetWorld()->SpawnActor(AthenaNavSystemConfigOverrideClass); + + if (!NavSystemOverride) + return; + + static auto AthenaNavSystemConfigClass = FindObject("/Script/FortniteGame.AthenaNavSystemConfig"); + auto AthenaNavConfig = (UAthenaNavSystemConfig*)UGameplayStatics::SpawnObject(AthenaNavSystemConfigClass, NavSystemOverride); + AthenaNavConfig->Get("bUseBuildingGridAsNavigableSpace") = false; + AthenaNavConfig->Get("bUsesStreamedInNavLevel") = true; + AthenaNavConfig->Get("bAllowAutoRebuild") = true; + AthenaNavConfig->Get("bCreateOnClient") = true; // BITFIELD + AthenaNavConfig->Get("bAutoSpawnMissingNavData") = true; // BITFIELD + AthenaNavConfig->Get("bSpawnNavDataInNavBoundsLevel") = true; // BITFIELD + AthenaNavConfig->Get("bUseNavigationInvokers") = false; + AthenaNavConfig->Get("DefaultAgentName") = UKismetStringLibrary::Conv_StringToName(L"MANG"); + + // NavSystemOverride->Get("OverridePolicy") = ENavSystemOverridePolicy::Append; + NavSystemOverride->Get("NavigationSystemConfig") = AthenaNavConfig; + + SetNavigationSystem(NavSystemOverride); +} \ No newline at end of file diff --git a/Project Reboot 3.0/dllmain.cpp b/Project Reboot 3.0/dllmain.cpp index dc4c15d..c186df7 100644 --- a/Project Reboot 3.0/dllmain.cpp +++ b/Project Reboot 3.0/dllmain.cpp @@ -9,6 +9,7 @@ #include "FortPlayerControllerAthena.h" #include "AbilitySystemComponent.h" #include "FortPlayerPawn.h" +#include "globals.h" #include "Map.h" #include "events.h" @@ -31,6 +32,9 @@ static int Return2Hook() { return 2; } static void NoMCPHook() { return; } static void CollectGarbageHook() { return; } +static __int64 (*DispatchRequestOriginal)(__int64 a1, __int64* a2, int a3); +static __int64 DispatchRequestHook(__int64 a1, __int64* a2, int a3) { return DispatchRequestOriginal(a1, a2, 3); } + DWORD WINAPI Main(LPVOID) { InitLogger(); @@ -72,10 +76,20 @@ DWORD WINAPI Main(LPVOID) : Globals::bCreative ? L"Creative_NoApollo_Terrain" : L"Apollo_Terrain"; - if (Hooking::MinHook::Hook((PVOID)Addresses::NoMCP, (PVOID)NoMCPHook, nullptr)) + if (Globals::bNoMCP) { - LOG_INFO(LogHook, "Hooking GetNetMode!"); + if (Hooking::MinHook::Hook((PVOID)Addresses::NoMCP, (PVOID)NoMCPHook, nullptr)) + { + LOG_INFO(LogHook, "Hooking GetNetMode!"); + Hooking::MinHook::Hook((PVOID)Addresses::GetNetMode, (PVOID)GetNetModeHook, nullptr); + } + } + else + { + Hooking::MinHook::Hook((PVOID)Addresses::KickPlayer, (PVOID)AGameSession::KickPlayerHook, (PVOID*)&AGameSession::KickPlayerOriginal); + Hooking::MinHook::Hook((PVOID)Addresses::DispatchRequest, (PVOID)DispatchRequestHook, (PVOID*)&DispatchRequestOriginal); Hooking::MinHook::Hook((PVOID)Addresses::GetNetMode, (PVOID)GetNetModeHook, nullptr); + LOG_INFO(LogHook, "Hooking GetNetMode!"); } LOG_INFO(LogDev, "Size: 0x{:x}", sizeof(TMap)); @@ -89,11 +103,14 @@ DWORD WINAPI Main(LPVOID) LOG_INFO(LogDev, "FindGIsServer: 0x{:x}", FindGIsServer() - __int64(GetModuleHandleW(0))); LOG_INFO(LogDev, "FindGIsClient: 0x{:x}", FindGIsClient() - __int64(GetModuleHandleW(0))); - if (FindGIsServer()) - *(bool*)FindGIsServer() = true; + // if (false) + { + if (FindGIsServer()) + *(bool*)FindGIsServer() = true; - if (FindGIsClient()) - *(bool*)FindGIsClient() = false; + if (FindGIsClient()) + *(bool*)FindGIsClient() = false; + } if (Fortnite_Version == 17.30) { @@ -102,30 +119,6 @@ DWORD WINAPI Main(LPVOID) Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x3DED158), (PVOID)ReturnTrueHook, nullptr); } - /* - auto GIsClient = Memcury::Scanner(FindGIsServer()); - - *GIsClient.GetAs() = false; - *(bool*)((uintptr_t)GIsClient.Get() + 1) = true; - */ - - /* auto GIsServer = Memcury::Scanner(__int64(GetModuleHandleW(0)) + 0x804B65A); // Memcury::Scanner::FindStringRef(L"STAT_UpdateLevelStreaming").ScanFor({ 0x80, 0x3D }, false, 1).RelativeOffset(2); - - LOG_INFO(LogDev, "GIsServer: 0x{:x}", GIsServer.Get() - __int64(GetModuleHandleW(0))); - LOG_INFO(LogDev, "gisserver - 1: 0x{:x}", __int64(((uintptr_t)GIsServer.Get() - 1)) - __int64(GetModuleHandleW(0))); - LOG_INFO(LogDev, "FindGIsServer: 0x{:x}", FindGIsServer() - __int64(GetModuleHandleW(0))); - LOG_INFO(LogDev, "FindGIsClient: 0x{:x}", FindGIsClient() - __int64(GetModuleHandleW(0))); - - *GIsServer.GetAs() = true; - *(bool*)((uintptr_t)GIsServer.Get() - 1) = false; */ - - /* struct { UObject* World; bool ret; } parms{GetWorld()}; - - static auto IsDedicatedServerFn = FindObject(L"/Script/Engine.KismetSystemLibrary.IsDedicatedServer"); - UGameplayStatics::StaticClass()->ProcessEvent(IsDedicatedServerFn, &parms); - - LOG_INFO(LogDev, "isded: {}", parms.ret); */ - auto& LocalPlayers = GetLocalPlayers(); if (LocalPlayers.Num() && LocalPlayers.Data) @@ -153,6 +146,9 @@ DWORD WINAPI Main(LPVOID) Hooking::MinHook::Hook(GameModeDefault, FindObject(L"/Script/Engine.GameMode.ReadyToStartMatch"), AFortGameModeAthena::Athena_ReadyToStartMatchHook, (PVOID*)&AFortGameModeAthena::Athena_ReadyToStartMatchOriginal, false); + + // return false; + Hooking::MinHook::Hook(GameModeDefault, FindObject(L"/Script/Engine.GameModeBase.SpawnDefaultPawnFor"), AGameModeBase::SpawnDefaultPawnForHook, nullptr, false); Hooking::MinHook::Hook(GameModeDefault, FindObject(L"/Script/Engine.GameModeBase.HandleStartingNewPlayer"), AFortGameModeAthena::Athena_HandleStartingNewPlayerHook, @@ -178,12 +174,15 @@ DWORD WINAPI Main(LPVOID) Hooking::MinHook::Hook(FortPlayerPawnAthenaDefault, FindObject(L"/Script/FortniteGame.FortPlayerPawn.ServerHandlePickup"), AFortPlayerPawn::ServerHandlePickupHook, nullptr, false); - /* Hooking::MinHook::Hook(FortAbilitySystemComponentAthenaDefault, FindObject(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerTryActivateAbility"), - UAbilitySystemComponent::ServerTryActivateAbilityHook, nullptr, false); - Hooking::MinHook::Hook(FortAbilitySystemComponentAthenaDefault, FindObject(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerTryActivateAbilityWithEventData"), - UAbilitySystemComponent::ServerTryActivateAbilityWithEventDataHook, nullptr, false); */ - // Hooking::MinHook::Hook(FortAbilitySystemComponentAthenaDefault, FindObject(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerAbilityRPCBatch"), - // UAbilitySystemComponent::ServerAbilityRPCBatchHook, nullptr, false); + if (false) + { + Hooking::MinHook::Hook(FortAbilitySystemComponentAthenaDefault, FindObject(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerTryActivateAbility"), + UAbilitySystemComponent::ServerTryActivateAbilityHook, nullptr, false); + Hooking::MinHook::Hook(FortAbilitySystemComponentAthenaDefault, FindObject(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerTryActivateAbilityWithEventData"), + UAbilitySystemComponent::ServerTryActivateAbilityWithEventDataHook, nullptr, false); + // Hooking::MinHook::Hook(FortAbilitySystemComponentAthenaDefault, FindObject(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerAbilityRPCBatch"), + // UAbilitySystemComponent::ServerAbilityRPCBatchHook, nullptr, false); + } if (Engine_Version >= 424) { @@ -194,7 +193,6 @@ DWORD WINAPI Main(LPVOID) } Hooking::MinHook::Hook((PVOID)Addresses::GetPlayerViewpoint, (PVOID)AFortPlayerControllerAthena::GetPlayerViewPointHook, (PVOID*)&AFortPlayerControllerAthena::GetPlayerViewPointOriginal); - // Hooking::MinHook::Hook((PVOID)Addresses::KickPlayer, (PVOID)AGameSession::KickPlayerHook, (PVOID*)&AGameSession::KickPlayerOriginal); Hooking::MinHook::Hook((PVOID)Addresses::TickFlush, (PVOID)UNetDriver::TickFlushHook, (PVOID*)&UNetDriver::TickFlushOriginal); // Hooking::MinHook::Hook((PVOID)Addresses::OnDamageServer, (PVOID)ABuildingActor::OnDamageServerHook, (PVOID*)&ABuildingActor::OnDamageServerOriginal); // Hooking::MinHook::Hook((PVOID)Addresses::CollectGarbage, (PVOID)CollectGarbageHook, nullptr); @@ -212,6 +210,25 @@ DWORD WINAPI Main(LPVOID) StartEvent(); } + else if (GetAsyncKeyState(VK_F8) & 1) + { + float Duration = 0; + float EarlyDuration = Duration; + + float TimeSeconds = 0; // UGameplayStatics::GetTimeSeconds(GetWorld()); + + LOG_INFO(LogDev, "Starting bus!"); + + auto GameMode = (AFortGameMode*)GetWorld()->GetGameMode(); + auto GameState = GameMode->GetGameState(); + + GameState->Get("WarmupCountdownEndTime") = 0; + GameMode->Get("WarmupCountdownDuration") = 0; + + GameState->Get("WarmupCountdownStartTime") = 0; + GameMode->Get("WarmupEarlyCountdownDuration") = 0; + } + Sleep(1000 / 30); } diff --git a/Project Reboot 3.0/finder.h b/Project Reboot 3.0/finder.h index 008d7d9..82d583c 100644 --- a/Project Reboot 3.0/finder.h +++ b/Project Reboot 3.0/finder.h @@ -226,6 +226,15 @@ static inline uint64 FindStaticLoadObject() static inline uint64 FindNoMCP() { + auto fn = FindObject("/Script/FortniteGame.FortKismetLibrary.IsRunningNoMCP"); + LOG_INFO(LogDev, "fn: {}", __int64(fn)); + + if (!fn) + return 0; + + auto noMcpIthink = GetFunctionIdxOrPtr(fn); + return noMcpIthink; + if (Fortnite_Version == 4) return Memcury::Scanner::FindPattern("E8 ? ? ? ? 83 A7 ? ? ? ? ? 83 E0 01").RelativeOffset(1).Get(); @@ -282,6 +291,9 @@ static inline uint64 FindActorGetNetMode() static inline uint64 FindTickFlush() { + // auto add = Memcury::Scanner::FindStringRef(L"UDemoNetDriver::TickFlush: ReplayStreamer ERROR: %s"); + // return Memcury::Scanner(FindBytes(add, { 0xE8 }, 500, 0, true, 1)).RelativeOffset(1).Get(); + if (Engine_Version == 427) return Memcury::Scanner::FindPattern("48 8B C4 48 89 58 18 55 56 57 41 54 41 55 41 56 41 57 48 8D A8 ? ? ? ? 48 81 EC ? ? ? ? 0F 29 70 B8 0F 29 78 A8 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 8A").Get(); @@ -289,10 +301,38 @@ static inline uint64 FindTickFlush() return FindBytes(Addr, (Fortnite_Version < 18 ? std::vector{ 0x4C, 0x8B } : std::vector{ 0x48, 0x8B, 0xC4 }), 1000, 0, true); } +static inline uint64 FindAddNavigationSystemToWorld() +{ + return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 20 33 ED 41").Get(); +} + +static inline uint64 FindNavSystemCleanUp() +{ + auto Addr = Memcury::Scanner::FindStringRef(L"UNavigationSystemV1::CleanUp", false); + + if (!Addr.Get()) + return 0; + + return FindBytes(Addr, { 0x48, 0x89, 0x5C }, 500, 0, true); +} + +static inline uint64 FindLoadPlayset() +{ + auto StringRef = Memcury::Scanner::FindStringRef(L"UPlaysetLevelStreamComponent::LoadPlayset Error: no owner for %s", Fortnite_Version >= 7); + + if (!StringRef.Get()) + return 0; + + return FindBytes(StringRef, { 0x48, 0x89, 0x5C }, 1000, 0, true); +} + static inline uint64 FindGIsServer() { - if (Fortnite_Version == 19.10) - return __int64(GetModuleHandleW(0)) + 0xB30CF9D; + // auto add = Memcury::Scanner::FindStringRef(L"STAT_UpdateLevelStreaming"); + // return Memcury::Scanner(FindBytes(add, { 0x80, 0x3D }, 100, 0, true, 1)).RelativeOffset(2).Get(); + + // if (Fortnite_Version == 19.10) + // return __int64(GetModuleHandleW(0)) + 0xB30CF9D; if (Fortnite_Version == 17.30) return __int64(GetModuleHandleW(0)) + 0x973E499; @@ -300,8 +340,64 @@ static inline uint64 FindGIsServer() return 0; auto Addr = Memcury::Scanner::FindStringRef(L"AllowCommandletRendering"); - auto Addy = FindBytes(Addr, { 0xC6, 0x05 }, 50, 0, true, 1); - Addy = Addy ? Addy : FindBytes(Addr, { 0x44, 0x88 }, 50, 0, true, 1); + + std::vector> BytesArray = { { 0xC6, 0x05 }, { 0x88, 0x1D } }; + + int Skip = 1; + + 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; + + 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) + { + LOG_INFO(LogDev, "[{}] Skip: 0x{:x}", Skip, Memcury::Scanner(Addr.Get() - i).RelativeOffset(2).Get() - __int64(GetModuleHandleW(0))); + + if (Skip > 0) + { + Skip--; + continue; + } + + Addy = Addr.Get() - i; + ShouldBreak = true; + break; + } + } + } + + if (ShouldBreak) + break; + + // std::cout << std::format("CurrentByte: 0x{:x}\n", (uint8_t)CurrentByte); + } + + /* int Skip = 2; + 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); */ + + LOG_INFO(LogDev, "Addy: 0x{:x}", Addy - __int64(GetModuleHandleW(0))); return Memcury::Scanner(Addy).RelativeOffset(2).Get(); } @@ -323,6 +419,12 @@ static inline uint64 FindChangeGameSessionId() return FindBytes(Addr, { 0x40, 0x55 }, 2000, 0, true); } +static inline uint64 FindDispatchRequest() +{ + auto Addr = Memcury::Scanner::FindStringRef(L"MCP-Profile: Dispatching request to %s", true, 0, Fortnite_Version >= 18); // todo check s18 + return FindBytes(Addr, { 0x48, 0x89, 0x5C }, 300, 0, true); +} + static inline uint64 FindGIsClient() { if (Fortnite_Version == 17.30) @@ -331,10 +433,76 @@ static inline uint64 FindGIsClient() return 0; auto Addr = Memcury::Scanner::FindStringRef(L"AllowCommandletRendering"); - auto Addy = FindBytes(Addr, { 0xC6, 0x05 }, 50, 0, true, 2); - Addy = Addy ? Addy : FindBytes(Addr, { 0x44, 0x88 }, 50, 0, true, 2); + + std::vector> BytesArray = { { 0xC6, 0x05 }, { 0x88, 0x1D } }; + + int Skip = 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; + + 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) + { + LOG_INFO(LogDev, "[{}] Skip: 0x{:x}", Skip, Memcury::Scanner(Addr.Get() - i).RelativeOffset(2).Get() - __int64(GetModuleHandleW(0))); + + if (Skip > 0) + { + Skip--; + continue; + } + + Addy = Addr.Get() - i; + ShouldBreak = true; + break; + } + } + } + + if (ShouldBreak) + break; + + // std::cout << std::format("CurrentByte: 0x{:x}\n", (uint8_t)CurrentByte); + } + + /* int Skip = 2; + 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); */ + + LOG_INFO(LogDev, "Addy: 0x{:x}", Addy - __int64(GetModuleHandleW(0))); return Memcury::Scanner(Addy).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(); + */ } static inline uint64 FindGetNetMode() diff --git a/Project Reboot 3.0/globals.h b/Project Reboot 3.0/globals.h new file mode 100644 index 0000000..8aeeddb --- /dev/null +++ b/Project Reboot 3.0/globals.h @@ -0,0 +1,9 @@ +#pragma once + +namespace Globals +{ + extern inline bool bCreative = true; + extern inline bool bGoingToPlayEvent = false; + extern inline bool bNoMCP = false; + extern inline bool bLateGame = false; +} \ No newline at end of file diff --git a/Project Reboot 3.0/hooking.h b/Project Reboot 3.0/hooking.h index b018dd3..b5722c1 100644 --- a/Project Reboot 3.0/hooking.h +++ b/Project Reboot 3.0/hooking.h @@ -196,6 +196,13 @@ namespace Hooking return ret1 == MH_OK && ret2 == MH_OK; } + static bool PatchCall(void* Addr, void* Detour/*, void** Original = nullptr*/) + { + + // int64_t delta = targetAddr - (instrAddr + 5); + // *(int32_t*)(instrAddr + 1) = static_cast(delta); + } + static bool Hook(UObject* DefaultClass, UFunction* Function, void* Detour, void** Original = nullptr, bool bUseSecondMethod = true, bool bHookExec = false) // Native hook { if (!Function) @@ -207,10 +214,13 @@ namespace Hooking return false; } - auto Exec = Function->GetFunc(); + auto& Exec = Function->GetFunc(); - if (bHookExec) - return Hook(Exec, Detour, Original); + if (bHookExec) + { + Exec = Detour; + return true; + } auto AddrOrIdx = bUseSecondMethod ? GetFunctionIdxOrPtr2(Function) : GetFunctionIdxOrPtr(Function); diff --git a/Project Reboot 3.0/log.h b/Project Reboot 3.0/log.h index f58de27..cdbb77a 100644 --- a/Project Reboot 3.0/log.h +++ b/Project Reboot 3.0/log.h @@ -69,6 +69,7 @@ inline void InitLogger() MakeLogger("LogEvent"); MakeLogger("LogPlaylist"); MakeLogger("LogGame"); + MakeLogger("LogAI"); } #define LOG_DEBUG(loggerName, ...) \ diff --git a/Project Reboot 3.0/reboot.h b/Project Reboot 3.0/reboot.h index c1e8a91..b899aab 100644 --- a/Project Reboot 3.0/reboot.h +++ b/Project Reboot 3.0/reboot.h @@ -13,12 +13,6 @@ FAILED_LISTEN = 3 }; */ -namespace Globals -{ - extern inline bool bCreative = false; - extern inline bool bGoingToPlayEvent = false; -} - extern inline UObject* (*StaticLoadObjectOriginal)(UClass*, UObject*, const wchar_t* InName, const wchar_t* Filename, uint32_t LoadFlags, UObject* Sandbox, bool bAllowObjectReconciliation) = nullptr; template