From 769dfa08ef3c6bb2c5fe05c51ccdb62e23160216 Mon Sep 17 00:00:00 2001 From: Milxnor Date: Fri, 21 Apr 2023 22:09:20 -0400 Subject: [PATCH] a bit added some specific playlist items, fix s8-s10 markers because i broke, fixed removing items on aircraft on every version, added thanos stone automatic spawning, fix a bug with lategame, add marshmello stage, fix multiple battle buses, fix teams on large team gamemodes, fix some items not removing automatically --- Project Reboot 3.0/AthenaMarkerComponent.cpp | 2 +- Project Reboot 3.0/FortAthenaMutator.h | 8 ++ Project Reboot 3.0/FortAthenaMutator_GG.h | 69 +++++++++++++ ...AthenaMutator_GiveItemsAtGamePhaseStep.cpp | 8 ++ ...rtAthenaMutator_GiveItemsAtGamePhaseStep.h | 40 ++++++++ .../FortAthenaMutator_InventoryOverride.h | 8 ++ ...rtAthenaMutator_InventoryOverride_Bucket.h | 35 +++++++ .../FortAthenaMutator_ItemDropOnDeath.h | 23 +++++ Project Reboot 3.0/FortAthenaSupplyDrop.cpp | 34 ++++++- Project Reboot 3.0/FortAthenaSupplyDrop.h | 4 + Project Reboot 3.0/FortGameModeAthena.cpp | 95 ++++++++++++++++-- Project Reboot 3.0/FortInventory.cpp | 7 +- Project Reboot 3.0/FortPickup.cpp | 3 +- Project Reboot 3.0/FortPlayerController.cpp | 39 ++++---- .../FortPlayerControllerAthena.cpp | 99 +++++++++++++++++++ .../FortPlayerControllerAthena.h | 2 + Project Reboot 3.0/FortPlayerStateAthena.cpp | 30 +----- Project Reboot 3.0/GameModeBase.cpp | 15 +-- Project Reboot 3.0/MegaStormManager.h | 2 - Project Reboot 3.0/Project Reboot 3.0.vcxproj | 7 ++ .../Project Reboot 3.0.vcxproj.filters | 27 +++++ Project Reboot 3.0/addresses.cpp | 4 + Project Reboot 3.0/addresses.h | 1 + Project Reboot 3.0/commands.h | 18 +--- Project Reboot 3.0/dllmain.cpp | 11 ++- Project Reboot 3.0/events.h | 3 +- Project Reboot 3.0/finder.h | 39 +++++++- Project Reboot 3.0/gui.h | 25 ++++- Project Reboot 3.0/hooking.h | 7 +- 29 files changed, 572 insertions(+), 93 deletions(-) create mode 100644 Project Reboot 3.0/FortAthenaMutator.h create mode 100644 Project Reboot 3.0/FortAthenaMutator_GG.h create mode 100644 Project Reboot 3.0/FortAthenaMutator_GiveItemsAtGamePhaseStep.cpp create mode 100644 Project Reboot 3.0/FortAthenaMutator_GiveItemsAtGamePhaseStep.h create mode 100644 Project Reboot 3.0/FortAthenaMutator_InventoryOverride.h create mode 100644 Project Reboot 3.0/FortAthenaMutator_InventoryOverride_Bucket.h create mode 100644 Project Reboot 3.0/FortAthenaMutator_ItemDropOnDeath.h diff --git a/Project Reboot 3.0/AthenaMarkerComponent.cpp b/Project Reboot 3.0/AthenaMarkerComponent.cpp index f504425..8fafc89 100644 --- a/Project Reboot 3.0/AthenaMarkerComponent.cpp +++ b/Project Reboot 3.0/AthenaMarkerComponent.cpp @@ -19,7 +19,7 @@ void UAthenaMarkerComponent::ServerAddMapMarkerHook(UAthenaMarkerComponent* Mark auto MarkerRequestPtr = &MarkerRequest; - bool useRealloc = true; + bool useRealloc = false; auto MarkerData = Alloc(FFortWorldMarkerData::GetStructSize(), useRealloc); static auto IconOffset = FindOffsetStruct("/Script/FortniteGame.MarkedActorDisplayInfo", "Icon"); diff --git a/Project Reboot 3.0/FortAthenaMutator.h b/Project Reboot 3.0/FortAthenaMutator.h new file mode 100644 index 0000000..be3aabd --- /dev/null +++ b/Project Reboot 3.0/FortAthenaMutator.h @@ -0,0 +1,8 @@ +#pragma once + +#include "Actor.h" + +class AFortAthenaMutator : public AActor // AFortGameplayMutator +{ +public: +}; \ No newline at end of file diff --git a/Project Reboot 3.0/FortAthenaMutator_GG.h b/Project Reboot 3.0/FortAthenaMutator_GG.h new file mode 100644 index 0000000..b329f46 --- /dev/null +++ b/Project Reboot 3.0/FortAthenaMutator_GG.h @@ -0,0 +1,69 @@ +#pragma once + +#include "Actor.h" +#include "CurveTable.h" +#include "GameplayAbilityTypes.h" +#include "FortWeaponItemDefinition.h" +#include "Stack.h" +#include "FortPlayerStateAthena.h" +#include "FortAthenaMutator.h" + +struct FGunGameGunEntry +{ + UFortWeaponItemDefinition* Weapon; // 0x0000(0x0008) (Edit, ZeroConstructor, DisableEditOnInstance, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + FScalableFloat Enabled; // 0x0008(0x0020) (Edit, DisableEditOnInstance, NativeAccessSpecifierPublic) + FScalableFloat AwardAtElim; // 0x0028(0x0020) (Edit, DisableEditOnInstance, NativeAccessSpecifierPublic) +}; + +struct FGunGameGunEntries +{ + TArray Entries; // 0x0000(0x0010) (ZeroConstructor, NativeAccessSpecifierPublic) +}; + +struct FGunGamePlayerData +{ + TArray CurrentlyAssignedWeapons; // 0x0000(0x0010) (ZeroConstructor, NativeAccessSpecifierPublic) +}; + +class AFortAthenaMutator_GG : public AFortAthenaMutator +{ +public: + TArray& GetWeaponEntries() + { + static auto WeaponEntriesOffset = GetOffset("WeaponEntries"); + return Get>(WeaponEntriesOffset); + } + + TMap& GetAwardEntriesAtElimMap() + { + static auto AwardEntriesAtElimMapOffset = GetOffset("AwardEntriesAtElimMap"); + return Get>(AwardEntriesAtElimMapOffset); + } + + TMap& GetPlayerData() + { + static auto PlayerDataOffset = GetOffset("PlayerData"); + return Get>(PlayerDataOffset); + } + + FGunGameGunEntries GetEntriesFromAward(const FScalableFloat& AwardAtElim) + { + auto& AwardEntriesAtElimMap = GetAwardEntriesAtElimMap(); + + float Value = 0; + + for (auto& AwardEntry : AwardEntriesAtElimMap) + { + if (AwardEntry.First == Value) + { + return AwardEntry.Second; + } + } + } + + static UClass* StaticClass() + { + static auto Class = FindObject("/Script/FortniteGame.FortAthenaMutator_GG"); + return Class; + } +}; \ No newline at end of file diff --git a/Project Reboot 3.0/FortAthenaMutator_GiveItemsAtGamePhaseStep.cpp b/Project Reboot 3.0/FortAthenaMutator_GiveItemsAtGamePhaseStep.cpp new file mode 100644 index 0000000..68985b5 --- /dev/null +++ b/Project Reboot 3.0/FortAthenaMutator_GiveItemsAtGamePhaseStep.cpp @@ -0,0 +1,8 @@ +#include "FortAthenaMutator_GiveItemsAtGamePhaseStep.h" + +void AFortAthenaMutator_GiveItemsAtGamePhaseStep::OnGamePhaseStepChangedHook(UObject* Context, FFrame& Stack, void* Ret) +{ + LOG_INFO(LogDev, "OnGamePhaseStepChangedHook!"); + + return OnGamePhaseStepChangedOriginal(Context, Stack, Ret); +} \ No newline at end of file diff --git a/Project Reboot 3.0/FortAthenaMutator_GiveItemsAtGamePhaseStep.h b/Project Reboot 3.0/FortAthenaMutator_GiveItemsAtGamePhaseStep.h new file mode 100644 index 0000000..805093e --- /dev/null +++ b/Project Reboot 3.0/FortAthenaMutator_GiveItemsAtGamePhaseStep.h @@ -0,0 +1,40 @@ +#pragma once + +#include "Actor.h" +#include "CurveTable.h" +#include "GameplayAbilityTypes.h" +#include "FortWorldItemDefinition.h" +#include "Stack.h" +#include "FortAthenaMutator.h" + +struct FItemsToGive +{ + UFortWorldItemDefinition* ItemToDrop; // 0x0000(0x0008) (Edit, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + FScalableFloat NumberToGive; // 0x0008(0x0020) (Edit, NativeAccessSpecifierPublic) +}; + +class AFortAthenaMutator_GiveItemsAtGamePhaseStep : public AFortAthenaMutator +{ +public: + static inline void (*OnGamePhaseStepChangedOriginal)(UObject* Context, FFrame& Stack, void* Ret); + + uint8_t& GetPhaseToGiveItems() + { + static auto PhaseToGiveItemsOffset = GetOffset("PhaseToGiveItems"); + return Get(PhaseToGiveItemsOffset); + } + + TArray& GetItemsToGive() + { + static auto ItemsToGiveOffset = GetOffset("ItemsToGive"); + return Get>(ItemsToGiveOffset); + } + + static void OnGamePhaseStepChangedHook(UObject* Context, FFrame& Stack, void* Ret); + + static UClass* StaticClass() + { + static auto Class = FindObject("/Script/FortniteGame.FortAthenaMutator_GiveItemsAtGamePhaseStep"); + return Class; + } +}; \ No newline at end of file diff --git a/Project Reboot 3.0/FortAthenaMutator_InventoryOverride.h b/Project Reboot 3.0/FortAthenaMutator_InventoryOverride.h new file mode 100644 index 0000000..a305c22 --- /dev/null +++ b/Project Reboot 3.0/FortAthenaMutator_InventoryOverride.h @@ -0,0 +1,8 @@ +#pragma once + +#include "FortAthenaMutator.h" + +class AFortAthenaMutator_InventoryOverride : public AFortAthenaMutator +{ +public: +}; \ No newline at end of file diff --git a/Project Reboot 3.0/FortAthenaMutator_InventoryOverride_Bucket.h b/Project Reboot 3.0/FortAthenaMutator_InventoryOverride_Bucket.h new file mode 100644 index 0000000..0a45c2d --- /dev/null +++ b/Project Reboot 3.0/FortAthenaMutator_InventoryOverride_Bucket.h @@ -0,0 +1,35 @@ +#pragma once + +#include "FortAthenaMutator_InventoryOverride.h" +#include "GameplayAbilityTypes.h" +#include "CurveTable.h" +#include "FortItemDefinition.h" +#include "FortInventory.h" + +struct FHotfixableInventoryOverrideItem +{ +public: + FScalableFloat Count; // 0x0(0x20)(Edit, BlueprintVisible, NativeAccessSpecifierPublic) + UFortItemDefinition* Item; // 0x20(0x8)(Edit, BlueprintVisible, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) +}; + +struct FItemLoadoutContainer +{ +public: + FScalableFloat bEnabled; // 0x0(0x20)(Edit, DisableEditOnInstance, NativeAccessSpecifierPublic) + TArray Loadout; // 0x20(0x10)(ZeroConstructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + TArray LoadoutList; // 0x30(0x10)(Edit, BlueprintVisible, ZeroConstructor, DisableEditOnInstance, HasGetValueTypeHash, NativeAccessSpecifierPublic) +}; + +struct FItemLoadoutBucket +{ +public: + FScalableFloat bEnabled; // 0x0(0x20)(Edit, DisableEditOnInstance, NativeAccessSpecifierPublic) + TArray Loadouts; // 0x20(0x10)(Edit, ZeroConstructor, DisableEditOnInstance, HasGetValueTypeHash, NativeAccessSpecifierPublic) + uint8 Pad_3D83[0x8]; // Fixing Size Of Struct [ Dumper-7 ] +}; + +class AFortAthenaMutator_InventoryOverride_Bucket : public AFortAthenaMutator_InventoryOverride +{ +public: +}; \ No newline at end of file diff --git a/Project Reboot 3.0/FortAthenaMutator_ItemDropOnDeath.h b/Project Reboot 3.0/FortAthenaMutator_ItemDropOnDeath.h new file mode 100644 index 0000000..f946e33 --- /dev/null +++ b/Project Reboot 3.0/FortAthenaMutator_ItemDropOnDeath.h @@ -0,0 +1,23 @@ +#pragma once + +#include "FortAthenaMutator.h" +#include "GameplayAbilityTypes.h" +#include "CurveTable.h" +#include "FortWorldItemDefinition.h" +#include "FortInventory.h" + +struct FItemsToDropOnDeath +{ + UFortWorldItemDefinition* ItemToDrop; // 0x0000(0x0008) (Edit, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + FScalableFloat NumberToDrop; // 0x0008(0x0020) (Edit, NativeAccessSpecifierPublic) +}; + +class AFortAthenaMutator_ItemDropOnDeath : public AFortAthenaMutator +{ +public: + TArray& GetItemsToDrop() + { + static auto ItemsToDropOffset = GetOffset("ItemsToDrop"); + return Get>(ItemsToDropoOffset); + } +}; \ No newline at end of file diff --git a/Project Reboot 3.0/FortAthenaSupplyDrop.cpp b/Project Reboot 3.0/FortAthenaSupplyDrop.cpp index 1f5aee2..b49d688 100644 --- a/Project Reboot 3.0/FortAthenaSupplyDrop.cpp +++ b/Project Reboot 3.0/FortAthenaSupplyDrop.cpp @@ -1,5 +1,36 @@ #include "FortAthenaSupplyDrop.h" +AFortPickup* AFortAthenaSupplyDrop::SpawnPickupFromItemEntryHook(UObject* Context, FFrame& Stack, AFortPickup** Ret) +{ + LOG_INFO(LogDev, __FUNCTION__); + return SpawnPickupFromItemEntryOriginal(Context, Stack, Ret); +} + +AFortPickup* AFortAthenaSupplyDrop::SpawnGameModePickupHook(UObject* Context, FFrame& Stack, AFortPickup** Ret) +{ + UFortWorldItemDefinition* ItemDefinition = nullptr; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + UClass* PickupClass = nullptr; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, UObjectWrapper, HasGetValueTypeHash, NativeAccessSpecifierPublic) + int NumberToSpawn; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + AFortPawn* TriggeringPawn = nullptr; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + FVector Position; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + FVector Direction; + + Stack.StepCompiledIn(&ItemDefinition); + Stack.StepCompiledIn(&PickupClass); + Stack.StepCompiledIn(&NumberToSpawn); + Stack.StepCompiledIn(&TriggeringPawn); + Stack.StepCompiledIn(&Position); + Stack.StepCompiledIn(&Direction); + + SpawnGameModePickupOriginal(Context, Stack, Ret); + + if (!ItemDefinition || !PickupClass) + return nullptr; + + *Ret = AFortPickup::SpawnPickup(ItemDefinition, Position, NumberToSpawn, EFortPickupSourceTypeFlag::Other, EFortPickupSpawnSource::SupplyDrop, -1, TriggeringPawn, PickupClass); + return *Ret; +} + AFortPickup* AFortAthenaSupplyDrop::SpawnPickupHook(UObject* Context, FFrame& Stack, AFortPickup** Ret) { UFortWorldItemDefinition* ItemDefinition = nullptr; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) @@ -21,4 +52,5 @@ AFortPickup* AFortAthenaSupplyDrop::SpawnPickupHook(UObject* Context, FFrame& St *Ret = AFortPickup::SpawnPickup(ItemDefinition, Position, NumberToSpawn, EFortPickupSourceTypeFlag::Other, EFortPickupSpawnSource::SupplyDrop, -1, TriggeringPawn); return *Ret; -} \ No newline at end of file +} + diff --git a/Project Reboot 3.0/FortAthenaSupplyDrop.h b/Project Reboot 3.0/FortAthenaSupplyDrop.h index ff19ae7..fbf92da 100644 --- a/Project Reboot 3.0/FortAthenaSupplyDrop.h +++ b/Project Reboot 3.0/FortAthenaSupplyDrop.h @@ -9,6 +9,10 @@ class AFortAthenaSupplyDrop : public ABuildingGameplayActor { public: static inline AFortPickup* (*SpawnPickupOriginal)(UObject* Context, FFrame& Stack, AFortPickup** Ret); + static inline AFortPickup* (*SpawnGameModePickupOriginal)(UObject* Context, FFrame& Stack, AFortPickup** Ret); + static inline AFortPickup* (*SpawnPickupFromItemEntryOriginal)(UObject* Context, FFrame& Stack, AFortPickup** Ret); + static AFortPickup* SpawnPickupFromItemEntryHook(UObject* Context, FFrame& Stack, AFortPickup** Ret); + static AFortPickup* SpawnGameModePickupHook(UObject* Context, FFrame& Stack, AFortPickup** Ret); static AFortPickup* SpawnPickupHook(UObject* Context, FFrame& Stack, AFortPickup** Ret); }; \ No newline at end of file diff --git a/Project Reboot 3.0/FortGameModeAthena.cpp b/Project Reboot 3.0/FortGameModeAthena.cpp index 9afe8cc..5591c64 100644 --- a/Project Reboot 3.0/FortGameModeAthena.cpp +++ b/Project Reboot 3.0/FortGameModeAthena.cpp @@ -327,6 +327,15 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game } } + if (Fortnite_Version == 7.30) + { + auto PleasantParkIdk = FindObject(("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.PleasentParkFestivus")); + ShowFoundation(PleasantParkIdk); + + auto PleasantParkGround = FindObject("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.PleasentParkDefault"); + ShowFoundation(PleasantParkGround); + } + if (Fortnite_Season == 6) { if (Fortnite_Version != 6.10) @@ -374,7 +383,24 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game if (TheBlock) ShowFoundation(TheBlock); - SetBitfield(GameMode->GetPtr("bWorldIsReady"), 1, true); + static auto GameState_AirCraftBehaviorOffset = GameState->GetOffset("AirCraftBehavior", false); + + if (GameState_AirCraftBehaviorOffset != -1) + { + GET_PLAYLIST(GameState); + + if (CurrentPlaylist) + { + static auto Playlist_AirCraftBehaviorOffset = CurrentPlaylist->GetOffset("AirCraftBehavior", false); + + if (Playlist_AirCraftBehaviorOffset != -1) + { + GameState->Get(GameState_AirCraftBehaviorOffset) = CurrentPlaylist->Get(Playlist_AirCraftBehaviorOffset); + } + } + } + + SetBitfield(GameMode->GetPtr("bWorldIsReady"), 1, true); // idk when we actually set this Globals::bInitializedPlaylist = true; } @@ -478,6 +504,23 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game static auto bAlwaysDBNOOffset = GameMode->GetOffset("bAlwaysDBNO"); // GameMode->Get(bAlwaysDBNOOffset) = true; + static auto GameState_AirCraftBehaviorOffset = GameState->GetOffset("AirCraftBehavior", false); + + if (GameState_AirCraftBehaviorOffset != -1) + { + GET_PLAYLIST(GameState); + + if (CurrentPlaylist) + { + static auto Playlist_AirCraftBehaviorOffset = CurrentPlaylist->GetOffset("AirCraftBehavior", false); + + if (Playlist_AirCraftBehaviorOffset != -1) + { + GameState->Get(GameState_AirCraftBehaviorOffset) = CurrentPlaylist->Get(Playlist_AirCraftBehaviorOffset); + } + } + } + LOG_INFO(LogDev, "Initialized!"); } @@ -529,6 +572,8 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint8 preferredTeam, AActor* Controller) { + // VERY BASIC IMPLEMENTATION + LOG_INFO(LogTeams, "PickTeam called!"); auto GameState = Cast(GameMode->GetGameState()); @@ -537,6 +582,7 @@ int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint UObject* Playlist = nullptr; + static int DefaultFirstTeam = 3; static int CurrentTeamMembers = 0; // bad static int Current = 3; @@ -553,6 +599,9 @@ int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint // std::cout << "Dru!\n"; int MaxSquadSize = 1; + int TeamsNum = 0; + + bool bShouldSpreadTeams = false; if (CurrentPlaylistDataOffset != -1 || Fortnite_Version >= 6) { @@ -568,6 +617,16 @@ int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint static auto MaxSquadSizeOffset = Playlist->GetOffset("MaxSquadSize"); MaxSquadSize = Playlist->Get(MaxSquadSizeOffset); + + static auto bShouldSpreadTeamsOffset = Playlist->GetOffset("bShouldSpreadTeams", false); + + if (bShouldSpreadTeamsOffset != -1) + bShouldSpreadTeams = Playlist->Get(bShouldSpreadTeamsOffset); + + static auto MaxTeamCountOffset = Playlist->GetOffset("MaxTeamCount", false); + + if (MaxTeamCountOffset != -1) + TeamsNum = Playlist->Get(MaxTeamCountOffset); } else { @@ -576,9 +635,12 @@ int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint : OldPlaylist == EFortAthenaPlaylist::AthenaDuo ? 2 : OldPlaylist == EFortAthenaPlaylist::AthenaSquad ? 4 : 1; + + TeamsNum = 100; } - static int NextTeamIndex = 3; // Playlist->Get("DefaultFirstTeam"); // + 1? + static int NextTeamIndex = DefaultFirstTeam; + static int LastTeamIndex = NextTeamIndex; static int LastNum1 = 1; @@ -586,17 +648,34 @@ int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint { LastNum1 = AmountOfRestarts; - NextTeamIndex = 3; // Playlist->Get("DefaultFirstTeam"); // + 1? + NextTeamIndex = DefaultFirstTeam; } - // std::cout << "CurrentTeamMembers: " << CurrentTeamMembers << '\n'; + LastTeamIndex = NextTeamIndex; - if (CurrentTeamMembers >= MaxSquadSize) + if (!bShouldSpreadTeams) { - // std::cout << "Moving next team!\n"; + if (CurrentTeamMembers >= MaxSquadSize) + { + NextTeamIndex++; + CurrentTeamMembers = 0; + } + } + else + { + // Basically, this goes through all the teams, and whenever we hit the last team, we go back to the first. - NextTeamIndex++; - CurrentTeamMembers = 0; + auto Idx = NextTeamIndex - 2; // 1-100 + + if (CurrentTeamMembers >= 1) // We spread every player. + { + if (Idx > TeamsNum) + NextTeamIndex = DefaultFirstTeam; + else + NextTeamIndex++; + + CurrentTeamMembers = 0; + } } LOG_INFO(LogTeams, "Player is going on team {} with {} members.", NextTeamIndex, CurrentTeamMembers); diff --git a/Project Reboot 3.0/FortInventory.cpp b/Project Reboot 3.0/FortInventory.cpp index e022637..f73026f 100644 --- a/Project Reboot 3.0/FortInventory.cpp +++ b/Project Reboot 3.0/FortInventory.cpp @@ -275,7 +275,9 @@ bool AFortInventory::RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int if (!ItemDefinition) return false; - if (Count < 0) + int OldCount = Count; + + if (Count < 0) // idk why i have this { Count = 0; bForceRemoval = true; @@ -310,7 +312,7 @@ bool AFortInventory::RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int } } - if (NewCount > 0 || bOverrideChangeStackSize) + if (OldCount != -1 && (NewCount > 0 || bOverrideChangeStackSize)) { ItemInstance->GetItemEntry()->GetCount() = NewCount; ReplicatedEntry->GetCount() = NewCount; @@ -339,6 +341,7 @@ bool AFortInventory::RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int { if (auto GadgetItemDefinition = Cast(ItemDefinition)) { + LOG_INFO(LogDev, "Unequipping Gadget!"); GadgetItemDefinition->UnequipGadgetData(FortPlayerController, ItemInstances.at(i)); } } diff --git a/Project Reboot 3.0/FortPickup.cpp b/Project Reboot 3.0/FortPickup.cpp index 2976363..ba63975 100644 --- a/Project Reboot 3.0/FortPickup.cpp +++ b/Project Reboot 3.0/FortPickup.cpp @@ -177,7 +177,8 @@ char AFortPickup::CompletePickupAnimationHook(AFortPickup* Pickup) if (ItemDefGoingInPrimary && IsPrimaryQuickbar(CurrentItemEntry->GetItemDefinition())) { - PrimarySlotsFilled++; + int AmountOfSlotsTakenUp = 1; // TODO + PrimarySlotsFilled += AmountOfSlotsTakenUp; } // LOG_INFO(LogDev, "[{}] PrimarySlotsFilled: {}", i, PrimarySlotsFilled); diff --git a/Project Reboot 3.0/FortPlayerController.cpp b/Project Reboot 3.0/FortPlayerController.cpp index b3c7f49..66c189d 100644 --- a/Project Reboot 3.0/FortPlayerController.cpp +++ b/Project Reboot 3.0/FortPlayerController.cpp @@ -596,12 +596,32 @@ void AFortPlayerController::ServerAttemptAircraftJumpHook(AFortPlayerController* auto NewPawnAsFort = Cast(NewPawn); if (NewPawnAsFort) + { NewPawnAsFort->SetHealth(100); + + if (Globals::bLateGame) + NewPawnAsFort->SetShield(100); + } // PlayerController->ServerRestartPlayer(); if (Globals::bLateGame) { + static int LastNum1 = 124; + + if (LastNum1 != AmountOfRestarts) + { + auto SafeZoneIndicator = GameMode->GetSafeZoneIndicator(); + + if (SafeZoneIndicator) + { + LastNum1 = AmountOfRestarts; + + SafeZoneIndicator->SkipShrinkSafeZone(); + SafeZoneIndicator->SkipShrinkSafeZone(); + } + } + static auto WoodItemData = FindObject("/Game/Items/ResourcePickups/WoodItemData.WoodItemData"); static auto StoneItemData = FindObject("/Game/Items/ResourcePickups/StoneItemData.StoneItemData"); static auto MetalItemData = FindObject("/Game/Items/ResourcePickups/MetalItemData.MetalItemData"); @@ -637,21 +657,6 @@ void AFortPlayerController::ServerAttemptAircraftJumpHook(AFortPlayerController* WorldInventory->Update(); } - static int LastNum1 = 124; - - if (LastNum1 != AmountOfRestarts) - { - auto SafeZoneIndicator = GameMode->GetSafeZoneIndicator(); - - if (SafeZoneIndicator) - { - LastNum1 = AmountOfRestarts; - - SafeZoneIndicator->SkipShrinkSafeZone(); - SafeZoneIndicator->SkipShrinkSafeZone(); - } - } - // return ServerAttemptAircraftJumpOriginal(PC, ClientRotation); } @@ -1019,7 +1024,6 @@ uint8 ToDeathCause(const FGameplayTagContainer& TagContainer, bool bWasDBNO = fa Addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 20 41 0F B6 F8 48 8B DA 48 8B F1 E8 ? ? ? ? 33 ED").Get(); if (Engine_Version == 420) Addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 20 0F B6 FA 48 8B D9 E8 ? ? ? ? 33 F6 48 89 74 24").Get(); - if (Engine_Version == 421) // 5.1 Addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 20 0F B6 FA 48 8B D9 E8 ? ? ? ? 33").Get(); @@ -1222,7 +1226,8 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo if (DamageCauser->IsA(FortProjectileBaseClass)) { LOG_INFO(LogDev, "From a projectile!"); - KillerWeaponDef = ((AFortWeapon*)DamageCauser->GetOwner())->GetWeaponData(); + auto Owner = Cast(DamageCauser->GetOwner()); + KillerWeaponDef = Owner->IsValidLowLevel() ? Owner->GetWeaponData() : nullptr; // I just added the IsValidLowLevel check because what if the weapon destroys? } if (auto Weapon = Cast(DamageCauser)) { diff --git a/Project Reboot 3.0/FortPlayerControllerAthena.cpp b/Project Reboot 3.0/FortPlayerControllerAthena.cpp index 3739049..00c3c36 100644 --- a/Project Reboot 3.0/FortPlayerControllerAthena.cpp +++ b/Project Reboot 3.0/FortPlayerControllerAthena.cpp @@ -6,6 +6,103 @@ #include "globals.h" #include "GameplayStatics.h" #include "hooking.h" +#include "FortAthenaMutator_GiveItemsAtGamePhaseStep.h" +#include "DataTableFunctionLibrary.h" + +void AFortPlayerControllerAthena::EnterAircraftHook(UObject* PC, AActor* Aircraft) +{ + auto PlayerController = Cast(Engine_Version < 424 ? PC : ((UActorComponent*)PC)->GetOwner()); + + if (!PlayerController) + return; + + LOG_INFO(LogDev, "EnterAircraftHook"); + + EnterAircraftOriginal(PC, Aircraft); + + // TODO Check if the player successfully got in the aircraft. + + auto WorldInventory = PlayerController->GetWorldInventory(); + + if (!WorldInventory) + return; + + std::vector> GuidAndCountsToRemove; + + auto& InventoryList = WorldInventory->GetItemList(); + + auto& ItemInstances = InventoryList.GetItemInstances(); + + for (int i = 0; i < ItemInstances.Num(); i++) + { + auto ItemEntry = ItemInstances.at(i)->GetItemEntry(); + auto ItemDefinition = Cast(ItemEntry->GetItemDefinition()); + + if (!ItemDefinition) + continue; + + if (!ItemDefinition->CanBeDropped()) + continue; + + GuidAndCountsToRemove.push_back({ ItemEntry->GetItemGuid(), ItemEntry->GetCount() }); + } + + for (auto& Pair : GuidAndCountsToRemove) + { + WorldInventory->RemoveItem(Pair.first, nullptr, Pair.second, true); + } + + static auto mutatorClass = FindObject("/Script/FortniteGame.FortAthenaMutator"); + auto AllMutators = UGameplayStatics::GetAllActorsOfClass(GetWorld(), mutatorClass); + + for (int i = 0; i < AllMutators.Num(); i++) + { + auto Mutator = AllMutators.at(i); + + LOG_INFO(LogDev, "[{}] Mutator: {}", i, Mutator->GetFullName()); + + if (auto GiveItemsAtGamePhaseStepMutator = Cast(Mutator)) + { + auto PhaseToGive = GiveItemsAtGamePhaseStepMutator->GetPhaseToGiveItems(); + + LOG_INFO(LogDev, "[{}] PhaseToGiveItems: {}", i, (int)PhaseToGive); + + auto& ItemsToGive = GiveItemsAtGamePhaseStepMutator->GetItemsToGive(); + + LOG_INFO(LogDev, "[{}] ItemsToGive.Num(): {}", i, ItemsToGive.Num()); + + if (PhaseToGive <= 5) // Flying or lower + { + for (int j = 0; j < ItemsToGive.Num(); j++) + { + auto& ItemToGive = ItemsToGive.at(j); + + float Out = 1; + FString ContextString; + EEvaluateCurveTableResult result; + // UDataTableFunctionLibrary::EvaluateCurveTableRow(ItemToGive.NumberToGive.GetCurve().CurveTable, ItemToGive.NumberToGive.GetCurve().RowName, 0.f, ContextString, &result, &Out); + + LOG_INFO(LogDev, "Out: {}", Out); + + WorldInventory->AddItem(ItemToGive.ItemToDrop, nullptr, Out); + } + } + } + /* else if (auto GGMutator = Cast(Mutator)) + { + auto& WeaponEntries = GGMutator->GetWeaponEntries(); + + LOG_INFO(LogDev, "[{}] WeaponEntries.Num(): {}", i, WeaponEntries.Num()); + + for (int j = 0; j < WeaponEntries.Num(); j++) + { + WorldInventory->AddItem(WeaponEntries.at(j).Weapon, nullptr, 1); + } + } */ + } + + WorldInventory->Update(); +} void AFortPlayerControllerAthena::ServerRequestSeatChangeHook(AFortPlayerControllerAthena* PlayerController, int TargetSeatIndex) { @@ -104,6 +201,8 @@ void AFortPlayerControllerAthena::ServerTeleportToPlaygroundLobbyIslandHook(AFor if (!Pawn) return; + // TODO IsTeleportToCreativeHubAllowed + static auto FortPlayerStartCreativeClass = FindObject("/Script/FortniteGame.FortPlayerStartCreative"); auto AllCreativePlayerStarts = UGameplayStatics::GetAllActorsOfClass(GetWorld(), FortPlayerStartCreativeClass); diff --git a/Project Reboot 3.0/FortPlayerControllerAthena.h b/Project Reboot 3.0/FortPlayerControllerAthena.h index ce112d6..eb87bc5 100644 --- a/Project Reboot 3.0/FortPlayerControllerAthena.h +++ b/Project Reboot 3.0/FortPlayerControllerAthena.h @@ -79,6 +79,7 @@ public: static inline void (*GetPlayerViewPointOriginal)(AFortPlayerControllerAthena* PlayerController, FVector& Location, FRotator& Rotation); static inline void (*ServerReadyToStartMatchOriginal)(AFortPlayerControllerAthena* PlayerController); static inline void (*ServerRequestSeatChangeOriginal)(AFortPlayerControllerAthena* PlayerController, int TargetSeatIndex); + static inline void (*EnterAircraftOriginal)(UObject* PC, AActor* Aircraft); AFortPlayerStateAthena* GetPlayerStateAthena() { @@ -91,6 +92,7 @@ public: return Get(MarkerComponentOffset); } + static void EnterAircraftHook(UObject* PC, AActor* Aircraft); static void ServerRequestSeatChangeHook(AFortPlayerControllerAthena* PlayerController, int TargetSeatIndex); // actually in zone static void ServerRestartPlayerHook(AFortPlayerControllerAthena* Controller); static void ServerGiveCreativeItemHook(AFortPlayerControllerAthena* Controller, FFortItemEntry CreativeItem); diff --git a/Project Reboot 3.0/FortPlayerStateAthena.cpp b/Project Reboot 3.0/FortPlayerStateAthena.cpp index 8da9fa6..6b961bd 100644 --- a/Project Reboot 3.0/FortPlayerStateAthena.cpp +++ b/Project Reboot 3.0/FortPlayerStateAthena.cpp @@ -26,33 +26,11 @@ void AFortPlayerStateAthena::ServerSetInAircraftHook(UObject* Context, FFrame& S auto& ItemInstances = InventoryList.GetItemInstances(); - if (/* (bNewInAircraft && !PlayerController->IsInAircraft()) || */ /* (Globals::bLateGame ? bNewInAircraft : true)) && */ !Globals::bLateGame.load() && ItemInstances.Num()) + bool bOverrideDontClearInventory = false; + + if (/* (bNewInAircraft && !PlayerController->IsInAircraft()) || */ /* (Globals::bLateGame ? bNewInAircraft : true)) && */ + !Globals::bLateGame.load() && ItemInstances.Num() && !bOverrideDontClearInventory) { - // std::cout << "InventoryList.ItemInstances.Num(): " << InventoryList.ItemInstances.Num() << '\n'; - - std::vector> GuidAndCountsToRemove; - - for (int i = 0; i < ItemInstances.Num(); i++) - { - auto ItemEntry = ItemInstances.at(i)->GetItemEntry(); - auto ItemDefinition = Cast(ItemEntry->GetItemDefinition()); - - if (!ItemDefinition) - continue; - - if (!ItemDefinition->CanBeDropped()) - continue; - - GuidAndCountsToRemove.push_back({ ItemEntry->GetItemGuid(), ItemEntry->GetCount() }); - } - - for (auto& Pair : GuidAndCountsToRemove) - { - WorldInventory->RemoveItem(Pair.first, nullptr, Pair.second, true); - } - - WorldInventory->Update(); - static auto CurrentShieldOffset = PlayerState->GetOffset("CurrentShield"); if (CurrentShieldOffset != -1) diff --git a/Project Reboot 3.0/GameModeBase.cpp b/Project Reboot 3.0/GameModeBase.cpp index 0d95c0b..a44e227 100644 --- a/Project Reboot 3.0/GameModeBase.cpp +++ b/Project Reboot 3.0/GameModeBase.cpp @@ -4,6 +4,9 @@ #include "FortPlayerControllerAthena.h" #include "FortGameModeAthena.h" #include "FortLootPackage.h" +#include "FortAthenaMutator_GiveItemsAtGamePhaseStep.h" +#include "DataTableFunctionLibrary.h" +#include "FortAthenaMutator_GG.h" UClass* AGameModeBase::GetDefaultPawnClassForController(AController* InController) { @@ -41,16 +44,16 @@ APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AControll if constexpr (bUseSpawnActor) { - NewPawn = GetWorld()->SpawnActor(PawnClass, SpawnTransform, SpawnParameters); +NewPawn = GetWorld()->SpawnActor(PawnClass, SpawnTransform, SpawnParameters); } else { - struct { AController* NewPlayer; FTransform SpawnTransform; APawn* ReturnValue; } - AGameModeBase_SpawnDefaultPawnAtTransform_Params{ NewPlayer, SpawnTransform }; + struct { AController* NewPlayer; FTransform SpawnTransform; APawn* ReturnValue; } + AGameModeBase_SpawnDefaultPawnAtTransform_Params{ NewPlayer, SpawnTransform }; - GameMode->ProcessEvent(fn, &AGameModeBase_SpawnDefaultPawnAtTransform_Params); + GameMode->ProcessEvent(fn, &AGameModeBase_SpawnDefaultPawnAtTransform_Params); - NewPawn = AGameModeBase_SpawnDefaultPawnAtTransform_Params.ReturnValue; + NewPawn = AGameModeBase_SpawnDefaultPawnAtTransform_Params.ReturnValue; } if (!NewPawn) @@ -77,7 +80,7 @@ APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AControll auto PlayerState = NewPlayerAsAthena->GetPlayerStateAthena(); PlayerState->GetAbilitySystemComponent()->RemoveActiveGameplayEffectBySourceEffect(StormEffectClass, 1, PlayerState->GetAbilitySystemComponent()); } */ - + if (NewPlayerAsAthena) { auto WorldInventory = NewPlayerAsAthena->GetWorldInventory(); diff --git a/Project Reboot 3.0/MegaStormManager.h b/Project Reboot 3.0/MegaStormManager.h index fb6d30d..8f0b640 100644 --- a/Project Reboot 3.0/MegaStormManager.h +++ b/Project Reboot 3.0/MegaStormManager.h @@ -11,8 +11,6 @@ struct FMegaStormCircle static auto MegaStormCircleStruct = FindObject("/Script/FortniteGame.MegaStormCircle"); return MegaStormCircleStruct->GetPropertiesSize(); } - - }; class AMegaStormManager : public AActor diff --git a/Project Reboot 3.0/Project Reboot 3.0.vcxproj b/Project Reboot 3.0/Project Reboot 3.0.vcxproj index a3ed1a4..809f3e5 100644 --- a/Project Reboot 3.0/Project Reboot 3.0.vcxproj +++ b/Project Reboot 3.0/Project Reboot 3.0.vcxproj @@ -192,6 +192,7 @@ + @@ -289,6 +290,12 @@ + + + + + + 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 8ff8b55..c8d4e09 100644 --- a/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters +++ b/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters @@ -236,6 +236,9 @@ FortniteGame\Source\FortniteGame\Private + + FortniteGame\Source\FortniteGame\Private\Mutators + @@ -725,6 +728,24 @@ FortniteGame\Source\FortniteGame\Public + + FortniteGame\Source\FortniteGame\Public\Mutators + + + FortniteGame\Source\FortniteGame\Public\Mutators + + + FortniteGame\Source\FortniteGame\Public\Mutators + + + FortniteGame\Source\FortniteGame\Public\Mutators + + + FortniteGame\Source\FortniteGame\Public\Mutators + + + FortniteGame\Source\FortniteGame\Public\Mutators + @@ -949,6 +970,12 @@ {b1cc2ad4-6196-455c-bda7-d0a2e7be2e70} + + {bfeeff9b-a86e-47a9-973c-47f6d0dfe5d5} + + + {6efc7bff-2d7b-4fdb-bae8-3d2e736cc82e} + diff --git a/Project Reboot 3.0/addresses.cpp b/Project Reboot 3.0/addresses.cpp index eed8c60..5a5f457 100644 --- a/Project Reboot 3.0/addresses.cpp +++ b/Project Reboot 3.0/addresses.cpp @@ -260,6 +260,9 @@ void Addresses::FindAll() LOG_INFO(LogDev, "Finding ApplyCharacterCustomization"); Addresses::ApplyCharacterCustomization = FindApplyCharacterCustomization(); + LOG_INFO(LogDev, "Finding EnterAircraft"); + Addresses::EnterAircraft = FindEnterAircraft(); + LOG_INFO(LogDev, "Finished finding!"); } @@ -319,6 +322,7 @@ void Addresses::Print() LOG_INFO(LogDev, "RemoveGadgetData: 0x{:x}", RemoveGadgetData - Base); LOG_INFO(LogDev, "GetInterfaceAddress: 0x{:x}", GetInterfaceAddress - Base); LOG_INFO(LogDev, "ApplyCharacterCustomization: 0x{:x}", ApplyCharacterCustomization - Base); + LOG_INFO(LogDev, "EnterAircraft: 0x{:x}", EnterAircraft - Base); } void Offsets::FindAll() diff --git a/Project Reboot 3.0/addresses.h b/Project Reboot 3.0/addresses.h index 227ec6c..79c4802 100644 --- a/Project Reboot 3.0/addresses.h +++ b/Project Reboot 3.0/addresses.h @@ -60,6 +60,7 @@ namespace Addresses extern inline uint64 RemoveGadgetData = 0; extern inline uint64 ApplyCharacterCustomization = 0; extern inline uint64 GetInterfaceAddress = 0; + extern inline uint64 EnterAircraft = 0; void SetupVersion(); // Finds Engine Version void FindAll(); diff --git a/Project Reboot 3.0/commands.h b/Project Reboot 3.0/commands.h index 21f6b3c..fea9e36 100644 --- a/Project Reboot 3.0/commands.h +++ b/Project Reboot 3.0/commands.h @@ -447,23 +447,7 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg) CheatManager->Teleport(); CheatManager = nullptr; - } - else if (Command == "setsafezonephase") - { - int NewSafeZonePhase = 1; - - try { NewSafeZonePhase = std::stof(Arguments[1]); } - catch (...) {} - - auto GameMode = (AFortGameMode*)GetWorld()->GetGameMode(); - auto GameState = GameMode->GetGameState(); - - static auto GameMode_SafeZonePhaseOffset = GameMode->GetOffset("SafeZonePhase"); - static auto GameState_SafeZonePhaseOffset = GameState->GetOffset("SafeZonePhase"); - - GameMode->Get(GameMode_SafeZonePhaseOffset) = NewSafeZonePhase; - GameState->Get(GameState_SafeZonePhaseOffset) = NewSafeZonePhase; - SendMessageToConsole(PlayerController, L"Set safe zone phase!"); + SendMessageToConsole(PlayerController, L"Teleported!"); } else if (Command == "bugitgo") { diff --git a/Project Reboot 3.0/dllmain.cpp b/Project Reboot 3.0/dllmain.cpp index 77305b7..4570fcb 100644 --- a/Project Reboot 3.0/dllmain.cpp +++ b/Project Reboot 3.0/dllmain.cpp @@ -13,6 +13,7 @@ #include "FortInventoryInterface.h" #include #include "GenericPlatformTime.h" +#include "FortAthenaMutator_GiveItemsAtGamePhaseStep.h" #include "BuildingFoundation.h" #include "Map.h" @@ -363,7 +364,7 @@ DWORD WINAPI Main(LPVOID) } Hooking::MinHook::Hook(GameModeDefault, FindObject(L"/Script/Engine.GameMode.ReadyToStartMatch"), AFortGameModeAthena::Athena_ReadyToStartMatchHook, - (PVOID*)&AFortGameModeAthena::Athena_ReadyToStartMatchOriginal, false); + (PVOID*)&AFortGameModeAthena::Athena_ReadyToStartMatchOriginal, false, false, true); Hooking::MinHook::Hook(GameModeDefault, FindObject(L"/Script/Engine.GameModeBase.SpawnDefaultPawnFor"), AGameModeBase::SpawnDefaultPawnForHook, nullptr, false); @@ -473,6 +474,9 @@ DWORD WINAPI Main(LPVOID) Hooking::MinHook::Hook(FortPlayerStateAthenaDefault, FindObject(L"/Script/FortniteGame.FortPlayerStateAthena.ServerSetInAircraft"), AFortPlayerStateAthena::ServerSetInAircraftHook, (PVOID*)&AFortPlayerStateAthena::ServerSetInAircraftOriginal, false, true); // We could use second method but eh + Hooking::MinHook::Hook(FindObject("/Script/FortniteGame.Default__FortAthenaMutator_GiveItemsAtGamePhaseStep"), FindObject(L"/Script/FortniteGame.FortAthenaMutator_GiveItemsAtGamePhaseStep.OnGamePhaseStepChanged"), + AFortAthenaMutator_GiveItemsAtGamePhaseStep::OnGamePhaseStepChangedHook, (PVOID*)&AFortAthenaMutator_GiveItemsAtGamePhaseStep::OnGamePhaseStepChangedOriginal, false, true); + if (FortOctopusVehicleDefault) { static auto ServerUpdateTowhookFn = FindObject("/Script/FortniteGame.FortOctopusVehicle.ServerUpdateTowhook"); @@ -554,6 +558,10 @@ DWORD WINAPI Main(LPVOID) Hooking::MinHook::Hook(FortAthenaSupplyDropDefault, FindObject(L"/Script/FortniteGame.FortAthenaSupplyDrop.SpawnPickup"), AFortAthenaSupplyDrop::SpawnPickupHook, (PVOID*)&AFortAthenaSupplyDrop::SpawnPickupOriginal, false, true); + Hooking::MinHook::Hook(FortAthenaSupplyDropDefault, FindObject(L"/Script/FortniteGame.FortAthenaSupplyDrop.SpawnGameModePickup"), + AFortAthenaSupplyDrop::SpawnGameModePickupHook, (PVOID*)&AFortAthenaSupplyDrop::SpawnGameModePickupOriginal, false, true); + Hooking::MinHook::Hook(FortAthenaSupplyDropDefault, FindObject(L"/Script/FortniteGame.FortAthenaSupplyDrop.SpawnPickupFromItemEntry"), + AFortAthenaSupplyDrop::SpawnPickupFromItemEntryHook, (PVOID*)&AFortAthenaSupplyDrop::SpawnPickupFromItemEntryOriginal, false, true); static auto FortAthenaCreativePortalDefault = FindObject(L"/Script/FortniteGame.Default__FortAthenaCreativePortal"); @@ -693,6 +701,7 @@ DWORD WINAPI Main(LPVOID) // if (Fortnite_Version >= 13) Hooking::MinHook::Hook((PVOID)Addresses::SetZoneToIndex, (PVOID)SetZoneToIndexHook, (PVOID*)&SetZoneToIndexOriginal); + Hooking::MinHook::Hook((PVOID)Addresses::EnterAircraft, (PVOID)AFortPlayerControllerAthena::EnterAircraftHook, (PVOID*)&AFortPlayerControllerAthena::EnterAircraftOriginal); #ifndef PROD Hooking::MinHook::Hook((PVOID)Addresses::ProcessEvent, ProcessEventHook, (PVOID*)&UObject::ProcessEventOriginal); diff --git a/Project Reboot 3.0/events.h b/Project Reboot 3.0/events.h index 00e4363..6d9a7bd 100644 --- a/Project Reboot 3.0/events.h +++ b/Project Reboot 3.0/events.h @@ -248,7 +248,7 @@ static inline std::vector Events = { false, // "/Game/Athena/Environments/Festivus/Blueprints/BP_FestivusManager.BP_FestivusManager_C.PlayConcert" - "/Game/Athena/Environments/Festivus/Blueprints/BP_FestivusManager.BP_FestivusManager_C.ServerPlayFestivus" + "/Game/Athena/Environments/Festivus/Blueprints/BP_FestivusManager.BP_FestivusManager_C.ServerPlayFestivus" // StartEventFromCalendarAsBackup calls this }, 0 @@ -260,7 +260,6 @@ static inline std::vector Events = 7.30 // Not sure if this requires playlist. ), - Event ( "Rift Tour", diff --git a/Project Reboot 3.0/finder.h b/Project Reboot 3.0/finder.h index 7d392b0..181f9ae 100644 --- a/Project Reboot 3.0/finder.h +++ b/Project Reboot 3.0/finder.h @@ -659,6 +659,27 @@ static inline uint64 FindSetZoneToIndex() // actually StartNewSafeZonePhase return 0; } +static inline uint64 FindEnterAircraft() +{ + auto Addr = Memcury::Scanner::FindStringRef(L"EnterAircraft: [%s] is attempting to enter aircraft after having already exited.", true, 0, Engine_Version >= 500).Get(); + + for (int i = 0; i < 1000; i++) + { + if ((*(uint8_t*)(uint8_t*)(Addr - i) == 0x40 && *(uint8_t*)(uint8_t*)(Addr - i + 1) == 0x53) + || (*(uint8_t*)(uint8_t*)(Addr - i) == 0x40 && *(uint8_t*)(uint8_t*)(Addr - i + 1) == 0x55)) + { + return Addr - i; + } + + if (*(uint8_t*)(uint8_t*)(Addr - i) == 0x48 && *(uint8_t*)(uint8_t*)(Addr - i + 1) == 0x89 && *(uint8_t*)(uint8_t*)(Addr - i + 2) == 0x5C && *(uint8_t*)(uint8_t*)(Addr - i + 2) == 0x24) + { + return Addr - i; + } + } + + return 0; +} + static inline uint64 FindRemoveGadgetData() { if (Engine_Version <= 423) @@ -666,15 +687,27 @@ static inline uint64 FindRemoveGadgetData() auto Addr = Memcury::Scanner::FindStringRef(L"UFortGadgetItemDefinition::RemoveGadgetData - Removing Gadget Data for Gadget Item [%s]!", false).Get(); if (!Addr) - Addr = Memcury::Scanner::FindStringRef(L"UFortGadgetItemDefinition::RemoveGadgetData - Removing Gadget Data for Gadet Item [%s]!").Get(); + Addr = Memcury::Scanner::FindStringRef(L"UFortGadgetItemDefinition::RemoveGadgetData - Removing Gadget Data for Gadet Item [%s]!", false).Get(); + + if (!Addr) + { + Addr = Memcury::Scanner::FindStringRef(L"UFortGadgetItemDefinition::RemoveGadgetData - Failed to get the Player Controller to cleanup Gadget Item [%s]!").Get(); + } if (!Addr) return 0; for (int i = 0; i < 1000; i++) { - if (/* (*(uint8_t*)(uint8_t*)(Addr - i) == 0x40 && *(uint8_t*)(uint8_t*)(Addr - i + 1) == 0x53) - || */ (*(uint8_t*)(uint8_t*)(Addr - i) == 0x40 && *(uint8_t*)(uint8_t*)(Addr - i + 1) == 0x55)) + if (Fortnite_Version >= 10) + { + if ((*(uint8_t*)(uint8_t*)(Addr - i) == 0x40 && *(uint8_t*)(uint8_t*)(Addr - i + 1) == 0x53)) + { + return Addr - i; + } + } + + if ((*(uint8_t*)(uint8_t*)(Addr - i) == 0x40 && *(uint8_t*)(uint8_t*)(Addr - i + 1) == 0x55)) { return Addr - i; } diff --git a/Project Reboot 3.0/gui.h b/Project Reboot 3.0/gui.h index e58865b..a9da4ca 100644 --- a/Project Reboot 3.0/gui.h +++ b/Project Reboot 3.0/gui.h @@ -221,7 +221,7 @@ void StaticUI() ImGui::Checkbox("No MCP (Don't change unless you know what this is)", &Globals::bNoMCP); - if (Addresses::ApplyGadgetData && Addresses::RemoveGadgetData) + if (Addresses::ApplyGadgetData && Addresses::RemoveGadgetData && Engine_Version < 424) { ImGui::Checkbox("Enable AGIDs (Don't change unless you know what this is)", &Globals::bEnableAGIDs); } @@ -368,6 +368,13 @@ void MainUI() #ifndef PROD ImGui::Checkbox("Log ProcessEvent", &Globals::bLogProcessEvent); #endif + if (!bStartedBus) + { + bool bWillBeLategame = Globals::bLateGame.load(); + ImGui::Checkbox("Lategame", &bWillBeLategame); + Globals::bLateGame.store(bWillBeLategame); + } + ImGui::Text(std::format("Joinable {}", Globals::bStartedListening).c_str()); static std::string ConsoleCommand; @@ -384,9 +391,9 @@ void MainUI() UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), cmd, nullptr); } - if (ImGui::Button("Restart")) + if (Engine_Version < 424 && ImGui::Button("Restart")) { - if (true) // Engine_Version < 424) + if (Engine_Version < 424) { FString LevelA = Engine_Version < 424 ? L"open Athena_Terrain" : Engine_Version >= 500 ? Engine_Version >= 501 @@ -409,6 +416,17 @@ void MainUI() LOG_INFO(LogDev, "Switching!"); ((AGameMode*)GetWorld()->GetGameMode())->RestartGame(); // UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), LevelA, nullptr); + + /* + + auto& LevelCollections = GetWorld()->Get>("LevelCollections"); + int LevelCollectionSize = FindObject("/Script/Engine.LevelCollection")->GetPropertiesSize(); + + *(UNetDriver**)(__int64(LevelCollections.AtPtr(0, LevelCollectionSize)) + 0x10) = nullptr; + *(UNetDriver**)(__int64(LevelCollections.AtPtr(1, LevelCollectionSize)) + 0x10) = nullptr; + + */ + // UGameplayStatics::OpenLevel(GetWorld(), UKismetStringLibrary::Conv_StringToName(LevelA), true, FString()); LOG_INFO(LogGame, "Restarting!"); Globals::bInitializedPlaylist = false; @@ -591,7 +609,6 @@ void MainUI() if (EventScripting) { - FName Name = UKismetStringLibrary::Conv_StringToName(L"DrumGun"); EventScripting->ProcessEvent(SetUnvaultItemNameFn, &Name); diff --git a/Project Reboot 3.0/hooking.h b/Project Reboot 3.0/hooking.h index 3d1eb6c..fdf1377 100644 --- a/Project Reboot 3.0/hooking.h +++ b/Project Reboot 3.0/hooking.h @@ -248,8 +248,11 @@ namespace Hooking // *(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 + static bool Hook(UObject* DefaultClass, UFunction* Function, void* Detour, void** Original = nullptr, bool bUseSecondMethod = true, bool bHookExec = false, bool bOverride = true) // Native hook { + if (!bOverride) + return false; + if (!Function) return false; @@ -263,7 +266,7 @@ namespace Hooking if (bHookExec) { - LOG_INFO(LogDev, "Hooking Exec {}", Function->GetName()); + LOG_INFO(LogDev, "Hooking Exec {} at 0x{:x}", Function->GetName(), __int64(Exec) - __int64(GetModuleHandleW(0))); if (Original) *Original = Exec;