diff --git a/Project Reboot 3.0/FortGameModeAthena.cpp b/Project Reboot 3.0/FortGameModeAthena.cpp index 2a48eee..a6dbabc 100644 --- a/Project Reboot 3.0/FortGameModeAthena.cpp +++ b/Project Reboot 3.0/FortGameModeAthena.cpp @@ -807,8 +807,8 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena Parts[(int)EFortCustomPartType::Head] = headPart; Parts[(int)EFortCustomPartType::Body] = bodyPart; - // if (Fortnite_Version > 2.5) - Parts[(int)EFortCustomPartType::Backpack] = backpackPart; + if (Fortnite_Version > 2.5) + Parts[(int)EFortCustomPartType::Backpack] = backpackPart; static auto OnRep_CharacterPartsFn = FindObject("/Script/FortniteGame.FortPlayerState.OnRep_CharacterParts"); PlayerStateAthena->ProcessEvent(OnRep_CharacterPartsFn); diff --git a/Project Reboot 3.0/FortInventory.cpp b/Project Reboot 3.0/FortInventory.cpp index a31bb33..9574008 100644 --- a/Project Reboot 3.0/FortInventory.cpp +++ b/Project Reboot 3.0/FortInventory.cpp @@ -1,14 +1,7 @@ #include "FortInventory.h" #include "FortPlayerController.h" #include "FortPickup.h" - -enum class EFortQuickBars : uint8_t -{ - Primary = 0, - Secondary = 1, - Max_None = 2, - EFortQuickBars_MAX = 3 -}; +#include "FortQuickBars.h" UFortItem* CreateItemInstance(AFortPlayerController* PlayerController, UFortItemDefinition* ItemDefinition, int Count) { @@ -261,19 +254,17 @@ bool AFortInventory::RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int if (FortPlayerController && Engine_Version < 420) { static auto QuickBarsOffset = FortPlayerController->GetOffset("QuickBars", false); - auto QuickBars = FortPlayerController->Get(QuickBarsOffset); + auto QuickBars = FortPlayerController->Get(QuickBarsOffset); if (QuickBars) { - static auto ServerRemoveItemInternalFn = FindObject("/Script/FortniteGame.FortQuickBars.ServerRemoveItemInternal"); + auto SlotIndex = QuickBars->GetSlotIndex(ItemGuid); - struct + if (SlotIndex != -1) { - FGuid Item; // (Parm, IsPlainOldData) - bool bFindReplacement; // (Parm, ZeroConstructor, IsPlainOldData) - bool bForce; // (Parm, ZeroConstructor, IsPlainOldData) - } AFortQuickBars_ServerRemoveItemInternal_Params{ItemGuid, false, true}; - QuickBars->ProcessEvent(ServerRemoveItemInternalFn, &AFortQuickBars_ServerRemoveItemInternal_Params); + QuickBars->ServerRemoveItemInternal(ItemGuid, false, true); + QuickBars->EmptySlot(IsPrimaryQuickbar(ItemDefinition) ? EFortQuickBars::Primary : EFortQuickBars::Secondary, SlotIndex); + } } } diff --git a/Project Reboot 3.0/FortInventoryInterface.cpp b/Project Reboot 3.0/FortInventoryInterface.cpp index 22e0876..c07d28e 100644 --- a/Project Reboot 3.0/FortInventoryInterface.cpp +++ b/Project Reboot 3.0/FortInventoryInterface.cpp @@ -34,5 +34,18 @@ char UFortInventoryInterface::RemoveInventoryItemHook(__int64 a1, FGuid a2, int if (bShouldUpdate) WorldInventory->Update(); + if (Engine_Version < 424) + { + auto Pawn = PlayerController->GetMyFortPawn(); + + if (Pawn) + { + auto CurrentWeapon = Pawn->GetCurrentWeapon(); + + if (CurrentWeapon) + WorldInventory->CorrectLoadedAmmo(CurrentWeapon->GetItemEntryGuid(), CurrentWeapon->GetAmmoCount()); + } + } + return true; } \ No newline at end of file diff --git a/Project Reboot 3.0/FortPawn.cpp b/Project Reboot 3.0/FortPawn.cpp index b133d37..4329e0d 100644 --- a/Project Reboot 3.0/FortPawn.cpp +++ b/Project Reboot 3.0/FortPawn.cpp @@ -67,8 +67,7 @@ void AFortPawn::NetMulticast_Athena_BatchedDamageCuesHook(UObject* Context, FFra if (!WorldInventory || !CurrentWeapon) return NetMulticast_Athena_BatchedDamageCuesOriginal(Context, Stack, Ret); - static auto AmmoCountOffset = CurrentWeapon->GetOffset("AmmoCount"); - auto AmmoCount = CurrentWeapon->Get(AmmoCountOffset); + auto AmmoCount = CurrentWeapon->GetAmmoCount(); WorldInventory->CorrectLoadedAmmo(CurrentWeapon->GetItemEntryGuid(), AmmoCount); diff --git a/Project Reboot 3.0/FortPlayerController.cpp b/Project Reboot 3.0/FortPlayerController.cpp index b08f603..af129fb 100644 --- a/Project Reboot 3.0/FortPlayerController.cpp +++ b/Project Reboot 3.0/FortPlayerController.cpp @@ -94,16 +94,6 @@ void AFortPlayerController::ServerExecuteInventoryItemHook(AFortPlayerController if (!ItemDefinition) return; - if (Engine_Version < 420) // wtf - { - static auto CurrentWeaponListOffset = Pawn->GetOffset("CurrentWeaponList"); - auto& CurrentWeaponList = Pawn->Get>(CurrentWeaponListOffset); - - CurrentWeaponList.Data = nullptr; - CurrentWeaponList.ArrayNum = 0; - CurrentWeaponList.ArrayMax = 0; - } - if (auto Weapon = Pawn->EquipWeaponDefinition((UFortWeaponItemDefinition*)ItemDefinition, ItemInstance->GetItemEntry()->GetItemGuid())) { if (Engine_Version < 420) diff --git a/Project Reboot 3.0/FortQuickBars.h b/Project Reboot 3.0/FortQuickBars.h new file mode 100644 index 0000000..380b26b --- /dev/null +++ b/Project Reboot 3.0/FortQuickBars.h @@ -0,0 +1,119 @@ +#pragma once + +#include "reboot.h" + +enum class EFortQuickBars : uint8_t // WRONG!!! It has a creative quickbar, do not use unless you know what you are doing. +{ + Primary = 0, + Secondary = 1, + Max_None = 2, + EFortQuickBars_MAX = 3 +}; + +struct FQuickBarSlot +{ + static UStruct* GetStruct() + { + static auto Struct = FindObject("/Script/FortniteGame.QuickBarSlot"); + return Struct; + } + + static int GetStructSize() + { + return GetStruct()->GetPropertiesSize(); + } + + TArray& GetItems() + { + static auto ItemsOffset = FindOffsetStruct("/Script/FortniteGame.QuickBarSlot", "Items"); + return *(TArray*)(__int64(this) + ItemsOffset); + } +}; + +struct FQuickBar +{ + TArray& GetSlots() + { + static auto SlotsOffset = FindOffsetStruct("/Script/FortniteGame.QuickBar", "Slots"); + return *(TArray*)(__int64(this) + SlotsOffset); + } +}; + +class AFortQuickBars : public AActor +{ +public: + void ServerRemoveItemInternal(const FGuid& Item, bool bFindReplacement, bool bForce) + { + static auto ServerRemoveItemInternalFn = FindObject("/Script/FortniteGame.FortQuickBars.ServerRemoveItemInternal"); + + struct + { + FGuid Item; // (Parm, IsPlainOldData) + bool bFindReplacement; // (Parm, ZeroConstructor, IsPlainOldData) + bool bForce; // (Parm, ZeroConstructor, IsPlainOldData) + } AFortQuickBars_ServerRemoveItemInternal_Params{ Item, bFindReplacement, bForce }; + ProcessEvent(ServerRemoveItemInternalFn, &AFortQuickBars_ServerRemoveItemInternal_Params); + } + + void EmptySlot(EFortQuickBars InQuickBar, int SlotIndex) + { + static auto EmptySlotFn = FindObject("/Script/FortniteGame.FortQuickBars.EmptySlot"); + struct + { + EFortQuickBars InQuickBar; // (Parm, ZeroConstructor, IsPlainOldData) + int SlotIndex; // (Parm, ZeroConstructor, IsPlainOldData) + } AFortQuickBars_EmptySlot_Params{ InQuickBar, SlotIndex }; + + this->ProcessEvent(EmptySlotFn, &AFortQuickBars_EmptySlot_Params); + } + + int GetSlotIndex(const FGuid& Item, EFortQuickBars QuickBars = EFortQuickBars::Max_None) + { + static auto PrimaryQuickBarOffset = GetOffset("PrimaryQuickBar"); + static auto SecondaryQuickBarOffset = GetOffset("SecondaryQuickBar"); + auto PrimaryQuickBar = GetPtr(PrimaryQuickBarOffset); + auto SecondaryQuickBar = GetPtr(SecondaryQuickBarOffset); + + if (QuickBars == EFortQuickBars::Primary || QuickBars == EFortQuickBars::Max_None) + { + auto& PrimaryQuickBarSlots = PrimaryQuickBar->GetSlots(); + + for (int i = 0; i < PrimaryQuickBarSlots.Num(); i++) + { + auto Slot = PrimaryQuickBarSlots.AtPtr(i, FQuickBarSlot::GetStructSize()); + + auto& SlotItems = Slot->GetItems(); + + for (int z = 0; z < SlotItems.Num(); z++) + { + auto& CurrentItem = SlotItems.at(z); + + if (CurrentItem == Item) + return i; + } + } + } + + if (QuickBars == EFortQuickBars::Secondary || QuickBars == EFortQuickBars::Max_None) + { + auto& SecondaryQuickBarSlots = SecondaryQuickBar->GetSlots(); + + for (int i = 0; i < SecondaryQuickBarSlots.Num(); i++) + { + auto Slot = SecondaryQuickBarSlots.AtPtr(i, FQuickBarSlot::GetStructSize()); + + auto& SlotItems = Slot->GetItems(); + + for (int z = 0; z < SlotItems.Num(); z++) + { + auto& CurrentItem = SlotItems.at(z); + + if (CurrentItem == Item) + return i; + } + } + } + + return -1; + } +}; \ No newline at end of file diff --git a/Project Reboot 3.0/FortWeapon.cpp b/Project Reboot 3.0/FortWeapon.cpp index 93c0de4..d42008a 100644 --- a/Project Reboot 3.0/FortWeapon.cpp +++ b/Project Reboot 3.0/FortWeapon.cpp @@ -22,8 +22,7 @@ void AFortWeapon::OnPlayImpactFXHook(AFortWeapon* Weapon, __int64 HitResult, uin if (!WorldInventory || !CurrentWeapon) return OnPlayImpactFXOriginal(Weapon, HitResult, ImpactPhysicalSurface, SpawnedPSC); - static auto AmmoCountOffset = CurrentWeapon->GetOffset("AmmoCount"); - auto AmmoCount = CurrentWeapon->Get(AmmoCountOffset); + auto AmmoCount = CurrentWeapon->GetAmmoCount(); WorldInventory->CorrectLoadedAmmo(CurrentWeapon->GetItemEntryGuid(), AmmoCount); diff --git a/Project Reboot 3.0/FortWeapon.h b/Project Reboot 3.0/FortWeapon.h index 0b95193..3cb8387 100644 --- a/Project Reboot 3.0/FortWeapon.h +++ b/Project Reboot 3.0/FortWeapon.h @@ -23,6 +23,12 @@ public: return Get(ItemEntryGuidOffset); } + int& GetAmmoCount() + { + static auto AmmoCountOffset = GetOffset("AmmoCount"); + return Get(AmmoCountOffset); + } + static void OnPlayImpactFXHook(AFortWeapon* Weapon, __int64 HitResult, uint8_t ImpactPhysicalSurface, UObject* SpawnedPSC); static void ServerReleaseWeaponAbilityHook(UObject* Context, FFrame* Stack, void* Ret); diff --git a/Project Reboot 3.0/Project Reboot 3.0.vcxproj b/Project Reboot 3.0/Project Reboot 3.0.vcxproj index f02d444..f0d72c8 100644 --- a/Project Reboot 3.0/Project Reboot 3.0.vcxproj +++ b/Project Reboot 3.0/Project Reboot 3.0.vcxproj @@ -272,6 +272,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 4edd6fd..aa92e87 100644 --- a/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters +++ b/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters @@ -479,6 +479,9 @@ Reboot\Public + + FortniteGame\Source\FortniteGame\Public\Items + diff --git a/Project Reboot 3.0/dllmain.cpp b/Project Reboot 3.0/dllmain.cpp index 4f8e328..5b11862 100644 --- a/Project Reboot 3.0/dllmain.cpp +++ b/Project Reboot 3.0/dllmain.cpp @@ -482,7 +482,8 @@ DWORD WINAPI Main(LPVOID) Hooking::MinHook::Hook((PVOID)Addresses::CompletePickupAnimation, (PVOID)AFortPickup::CompletePickupAnimationHook, (PVOID*)&AFortPickup::CompletePickupAnimationOriginal); Hooking::MinHook::Hook((PVOID)Addresses::CanActivateAbility, ReturnTrueHook); // ahhh wtf - if (Fortnite_Version >= 2.5) + // if (Fortnite_Version >= 2.5) + if (Engine_Version >= 419) { auto ServerRemoveInventoryItemFunctionCallRef = Memcury::Scanner::FindPointerRef((PVOID)FindFunctionCall(L"ServerRemoveInventoryItem", Fortnite_Version >= 16 ? std::vector{ 0x48, 0x8B, 0xC4 } : std::vector{ 0x48, 0x89, 0x5C }), 0, true); diff --git a/Project Reboot 3.0/finder.h b/Project Reboot 3.0/finder.h index bcb9032..3e746bc 100644 --- a/Project Reboot 3.0/finder.h +++ b/Project Reboot 3.0/finder.h @@ -325,7 +325,7 @@ static inline uint64 FindGetPlayerViewpoint() LOG_INFO(LogDev, "GetPlayerViewpoint StringRef: 0x{:x}", __int64(Addrr) - __int64(GetModuleHandleW(0))); - for (int i = 0; i < 1500; i++) + for (int i = 0; i < 1200; i++) { if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x40 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x55) { @@ -336,6 +336,11 @@ static inline uint64 FindGetPlayerViewpoint() { return Addrr - i; } + + if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0xC3) // hmm + { + break; + } } for (int i = 0; i < 1000; i++) @@ -954,9 +959,7 @@ static inline uint64 FindMcpIsDedicatedServerOffset() if (Engine_Version == 421 || Engine_Version == 422) // checked on 5.41 & 6.21 & 7.30 return 0x28; - return 0x60; // 1.7.2 & 4.1 - - return 0; + return 0x60; // 1.7.2 & 1.11 & 4.1 } static inline uint64 FindGIsClient() @@ -1200,10 +1203,27 @@ static inline uint64 FindGiveAbilityAndActivateOnce() if (Engine_Version == 426) return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 40 49 8B 40 10 49 8B D8 48 8B FA 48 8B F1").Get(); - auto Addr = Memcury::Scanner::FindStringRef(L"GiveAbilityAndActivateOnce called on ability %s on the client, not allowed!", true, 0, Engine_Version >= 500); + auto Addrr = Memcury::Scanner::FindStringRef(L"GiveAbilityAndActivateOnce called on ability %s on the client, not allowed!", true, 0, Engine_Version >= 500).Get(); + + for (int i = 0; i < 1000; i++) + { + if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x40 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x55) + { + return Addrr - i; + } + + if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x48 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x89 && *(uint8_t*)(uint8_t*)(Addrr - i + 2) == 0x5C) + { + return Addrr - i; + } + } + + return 0; + + /* auto Addr = Memcury::Scanner::FindStringRef(L"GiveAbilityAndActivateOnce called on ability %s on the client, not allowed!", true, 0, Engine_Version >= 500); auto res = FindBytes(Addr, { 0x48, 0x89, 0x5C }, 1000, 0, true); - return res; + return res; */ } static inline uint64 FindGiveAbility()