mirror of
https://github.com/Milxnor/Project-Reboot-3.0.git
synced 2026-01-13 02:42:22 +01:00
fix 16.50, fix failing abilities s16+, ammo in bottom right
This commit is contained in:
@@ -189,6 +189,12 @@ bool AFortInventory::RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int
|
||||
if (!ItemDefinition)
|
||||
return false;
|
||||
|
||||
if (Count < 0)
|
||||
{
|
||||
Count = 0;
|
||||
bForceRemoval = true;
|
||||
}
|
||||
|
||||
auto NewCount = ReplicatedEntry->GetCount() - Count;
|
||||
|
||||
if (NewCount > 0 || (ItemDefinition->ShouldPersistWhenFinalStackEmpty() && !bForceRemoval))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "FortPawn.h"
|
||||
|
||||
#include "reboot.h"
|
||||
#include "FortPlayerControllerAthena.h"
|
||||
|
||||
AFortWeapon* AFortPawn::EquipWeaponDefinition(UFortWeaponItemDefinition* WeaponData, const FGuid& ItemEntryGuid)
|
||||
{
|
||||
@@ -56,6 +57,24 @@ void AFortPawn::SetShield(float NewShield)
|
||||
this->ProcessEvent(SetShieldFn, &NewShield);
|
||||
}
|
||||
|
||||
void AFortPawn::NetMulticast_Athena_BatchedDamageCuesHook(UObject* Context, FFrame* Stack, void* Ret)
|
||||
{
|
||||
auto Pawn = (AFortPawn*)Context;
|
||||
auto Controller = Cast<AFortPlayerController>(Pawn->GetController());
|
||||
auto CurrentWeapon = Pawn->GetCurrentWeapon();
|
||||
auto WorldInventory = Controller ? Controller->GetWorldInventory() : nullptr;
|
||||
|
||||
if (!WorldInventory || !CurrentWeapon)
|
||||
return NetMulticast_Athena_BatchedDamageCuesOriginal(Context, Stack, Ret);
|
||||
|
||||
static auto AmmoCountOffset = CurrentWeapon->GetOffset("AmmoCount");
|
||||
auto AmmoCount = CurrentWeapon->Get<int>(AmmoCountOffset);
|
||||
|
||||
WorldInventory->CorrectLoadedAmmo(CurrentWeapon->GetItemEntryGuid(), AmmoCount);
|
||||
|
||||
return NetMulticast_Athena_BatchedDamageCuesOriginal(Context, Stack, Ret);
|
||||
}
|
||||
|
||||
UClass* AFortPawn::StaticClass()
|
||||
{
|
||||
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortPawn");
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
class AFortPawn : public APawn
|
||||
{
|
||||
public:
|
||||
static inline void (*NetMulticast_Athena_BatchedDamageCuesOriginal)(UObject* Context, FFrame* Stack, void* Ret);
|
||||
AFortWeapon* EquipWeaponDefinition(UFortWeaponItemDefinition* WeaponData, const FGuid& ItemEntryGuid);
|
||||
bool PickUpActor(AActor* PickupTarget, UFortDecoItemDefinition* PlacementDecoItemDefinition);
|
||||
|
||||
@@ -26,6 +27,7 @@ public:
|
||||
|
||||
void SetHealth(float NewHealth);
|
||||
void SetShield(float NewShield);
|
||||
static void NetMulticast_Athena_BatchedDamageCuesHook(UObject* Context, FFrame* Stack, void* Ret);
|
||||
|
||||
static UClass* StaticClass();
|
||||
};
|
||||
@@ -640,10 +640,10 @@ void AFortPlayerController::ServerPlayEmoteItemHook(AFortPlayerController* Playe
|
||||
|
||||
FGameplayAbilitySpec* Spec = MakeNewSpec((UClass*)AbilityToUse, EmoteAsset, true);
|
||||
|
||||
static unsigned int* (*GiveAbilityAndActivateOnce)(UAbilitySystemComponent* ASC, int* outHandle, __int64 Spec, FGameplayEventData* TriggerEventData)
|
||||
= decltype(GiveAbilityAndActivateOnce)(Addresses::GiveAbilityAndActivateOnce); // EventData is only on ue500?
|
||||
static unsigned int* (*GiveAbilityAndActivateOnce)(UAbilitySystemComponent* ASC, int* outHandle, __int64 Spec, FGameplayEventData* TriggerEventData) = decltype(GiveAbilityAndActivateOnce)(Addresses::GiveAbilityAndActivateOnce); // EventData is only on ue500?
|
||||
|
||||
GiveAbilityAndActivateOnce(PlayerState->GetAbilitySystemComponent(), &outHandle, __int64(Spec), nullptr);
|
||||
if (GiveAbilityAndActivateOnce)
|
||||
GiveAbilityAndActivateOnce(PlayerState->GetAbilitySystemComponent(), &outHandle, __int64(Spec), nullptr);
|
||||
}
|
||||
|
||||
uint8 ToDeathCause(const FGameplayTagContainer& TagContainer, bool bWasDBNO = false)
|
||||
|
||||
@@ -4,30 +4,32 @@
|
||||
#include "reboot.h"
|
||||
#include "FortPlayerController.h"
|
||||
|
||||
void AFortWeapon::ServerReleaseWeaponAbilityHook(UObject* Context, FFrame* Stack, void* Ret)
|
||||
void AFortWeapon::OnPlayImpactFXHook(AFortWeapon* Weapon, __int64 HitResult, uint8_t ImpactPhysicalSurface, UObject* SpawnedPSC)
|
||||
{
|
||||
// I don't know where to put this..
|
||||
|
||||
auto Weapon = (AFortWeapon*)Context;
|
||||
auto Pawn = Cast<AFortPlayerPawn>(Weapon->GetOwner());
|
||||
// grappler
|
||||
|
||||
// LOG_INFO(LogDev, "Owner: {}", Weapon->GetOwner() ? Weapon->GetOwner()->GetFullName() : "InvalidObject");
|
||||
auto Pawn = Cast<AFortPawn>(Weapon->GetOwner());
|
||||
|
||||
if (!Pawn)
|
||||
return ServerReleaseWeaponAbilityOriginal(Context, Stack, Ret);
|
||||
return OnPlayImpactFXOriginal(Weapon, HitResult, ImpactPhysicalSurface, SpawnedPSC);
|
||||
|
||||
auto Controller = Cast<AFortPlayerController>(Pawn->GetController());
|
||||
auto CurrentWeapon = Weapon; // Pawn->GetCurrentWeapon();
|
||||
auto CurrentWeapon = Pawn->GetCurrentWeapon();
|
||||
auto WorldInventory = Controller ? Controller->GetWorldInventory() : nullptr;
|
||||
|
||||
if (!WorldInventory || !CurrentWeapon)
|
||||
return ServerReleaseWeaponAbilityOriginal(Context, Stack, Ret);
|
||||
return OnPlayImpactFXOriginal(Weapon, HitResult, ImpactPhysicalSurface, SpawnedPSC);
|
||||
|
||||
static auto AmmoCountOffset = CurrentWeapon->GetOffset("AmmoCount");
|
||||
auto AmmoCount = CurrentWeapon->Get<int>(AmmoCountOffset);
|
||||
|
||||
WorldInventory->CorrectLoadedAmmo(CurrentWeapon->GetItemEntryGuid(), AmmoCount);
|
||||
|
||||
return OnPlayImpactFXOriginal(Weapon, HitResult, ImpactPhysicalSurface, SpawnedPSC);
|
||||
}
|
||||
|
||||
void AFortWeapon::ServerReleaseWeaponAbilityHook(UObject* Context, FFrame* Stack, void* Ret)
|
||||
{
|
||||
return ServerReleaseWeaponAbilityOriginal(Context, Stack, Ret);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ class AFortWeapon : public AActor
|
||||
{
|
||||
public:
|
||||
static inline void (*ServerReleaseWeaponAbilityOriginal)(UObject* Context, FFrame* Stack, void* Ret);
|
||||
static inline void (*OnPlayImpactFXOriginal)(AFortWeapon* Weapon, __int64 HitResult, uint8_t ImpactPhysicalSurface, UObject* SpawnedPSC);
|
||||
|
||||
template <typename T = class UFortWeaponItemDefinition>
|
||||
T* GetWeaponData()
|
||||
@@ -22,6 +23,7 @@ public:
|
||||
return Get<FGuid>(ItemEntryGuidOffset);
|
||||
}
|
||||
|
||||
static void OnPlayImpactFXHook(AFortWeapon* Weapon, __int64 HitResult, uint8_t ImpactPhysicalSurface, UObject* SpawnedPSC);
|
||||
static void ServerReleaseWeaponAbilityHook(UObject* Context, FFrame* Stack, void* Ret);
|
||||
|
||||
static UClass* StaticClass();
|
||||
|
||||
@@ -431,9 +431,6 @@
|
||||
<ClInclude Include="AthenaMarkerComponent.h">
|
||||
<Filter>FortniteGame\Source\FortniteGame\Public</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="vehicles.h">
|
||||
<Filter>Reboot\Public</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FortInventoryInterface.h">
|
||||
<Filter>FortniteGame\Source\FortniteGame\Public\Items</Filter>
|
||||
</ClInclude>
|
||||
@@ -479,6 +476,9 @@
|
||||
<ClInclude Include="GameplayAbilityTypes.h">
|
||||
<Filter>Engine\Plugins\Runtime\GameplayAbilities\Source\GameplayAbilities\Public</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="vehicles.h">
|
||||
<Filter>Reboot\Public</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Engine">
|
||||
|
||||
@@ -271,6 +271,28 @@ DWORD WINAPI Main(LPVOID)
|
||||
Hooking::MinHook::Hook(FortWeaponDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortWeapon.ServerReleaseWeaponAbility"),
|
||||
AFortWeapon::ServerReleaseWeaponAbilityHook, (PVOID*)&AFortWeapon::ServerReleaseWeaponAbilityOriginal, false, true);
|
||||
|
||||
auto OnPlayImpactFXFunctionPtr = Memcury::Scanner::FindStringRef(L"OnPlayImpactFX", true, 0).ScanFor({ 0x48, 0x8D, 0x0D }).RelativeOffset(3).GetAs<void*>();
|
||||
auto OnPlayImpactFXPtrRef = Memcury::Scanner::FindPointerRef(OnPlayImpactFXFunctionPtr).Get();
|
||||
__int64 OnPlayImpactFXAddr = 0;
|
||||
|
||||
for (int i = 0; i < 2000; i++)
|
||||
{
|
||||
if (*(uint8_t*)(uint8_t*)(OnPlayImpactFXPtrRef - i) == 0x48 && *(uint8_t*)(uint8_t*)(OnPlayImpactFXPtrRef - i + 1) == 0x89 && *(uint8_t*)(uint8_t*)(OnPlayImpactFXPtrRef - i + 2) == 0x5C)
|
||||
{
|
||||
OnPlayImpactFXAddr = OnPlayImpactFXPtrRef - i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*(uint8_t*)(uint8_t*)(OnPlayImpactFXPtrRef - i) == 0x4C && *(uint8_t*)(uint8_t*)(OnPlayImpactFXPtrRef - i + 1) == 0x8B)
|
||||
{
|
||||
OnPlayImpactFXAddr = OnPlayImpactFXPtrRef - i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_INFO(LogDev, "OnPlayImpactFX: 0x{:x}", OnPlayImpactFXAddr - __int64(GetModuleHandleW(0)));
|
||||
Hooking::MinHook::Hook((PVOID)OnPlayImpactFXAddr, AFortWeapon::OnPlayImpactFXHook, (PVOID*)&AFortWeapon::OnPlayImpactFXOriginal);
|
||||
|
||||
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.ServerDropAllItems"),
|
||||
AFortPlayerController::ServerDropAllItemsHook, nullptr, false);
|
||||
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.ServerAttemptInventoryDrop"),
|
||||
@@ -301,6 +323,10 @@ DWORD WINAPI Main(LPVOID)
|
||||
Hooking::MinHook::Hook(FortPlayerStateAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerStateAthena.ServerSetInAircraft"),
|
||||
AFortPlayerStateAthena::ServerSetInAircraftHook, (PVOID*)&AFortPlayerStateAthena::ServerSetInAircraftOriginal, false, true); // We could use second method but eh
|
||||
|
||||
static auto NetMulticast_Athena_BatchedDamageCuesFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPawn.NetMulticast_Athena_BatchedDamageCues") ? FindObject<UFunction>(L"/Script/FortniteGame.FortPawn.NetMulticast_Athena_BatchedDamageCues") : FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerPawnAthena.NetMulticast_Athena_BatchedDamageCues");
|
||||
|
||||
Hooking::MinHook::Hook(FortPlayerPawnAthenaDefault, NetMulticast_Athena_BatchedDamageCuesFn,
|
||||
AFortPawn::NetMulticast_Athena_BatchedDamageCuesHook, (PVOID*)&AFortPawn::NetMulticast_Athena_BatchedDamageCuesOriginal, false, true);
|
||||
Hooking::MinHook::Hook(FortPlayerPawnAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerPawn.ServerSendZiplineState"),
|
||||
AFortPlayerPawn::ServerSendZiplineStateHook, nullptr, false);
|
||||
|
||||
|
||||
@@ -71,7 +71,12 @@ static inline uint64 FindStaticFindObject(int StringSkip = 1)
|
||||
if (Engine_Version >= 427) // ok so like the func is split up in ida idfk what to do about it
|
||||
{
|
||||
if (Fortnite_Version < 18)
|
||||
{
|
||||
if (Fortnite_Version == 16.50)
|
||||
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 55 41 54 41 55 41 56 41 57 48 8B EC 48 83 EC 60 45 33 ED 45 8A F9 44 38 2D ? ? ? ? 49 8B F8 48 8B F2 4C 8B E1").Get();
|
||||
|
||||
return Memcury::Scanner::FindPattern("40 55 53 57 41 54 41 55 41 57 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85").Get();
|
||||
}
|
||||
else
|
||||
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 55 41 54 41 55 41 56 41 57 48 8B EC 48 83 EC 60 45 33 ED 45 8A F9 44 38 2D ? ? ? ? 49 8B F8 48 8B").Get();
|
||||
}
|
||||
@@ -521,7 +526,10 @@ static inline uint64 FindCompletePickupAnimation()
|
||||
auto sig = Memcury::Scanner::FindPattern("48 8B C4 48 89 58 08 48 89 68 10 48 89 70 18 48 89 78 20 41 54 41 56 41 57 48 83 EC 20 48 8B B1 ? ? ? ? 48 8B D9 48 85 F6", false).Get(); // 17.30
|
||||
|
||||
if (!sig)
|
||||
sig = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 55 57 41 54 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 48 8B B9 ? ? ? ? 48 8B D9 48 85 FF 74 16 48 89").Get(); // 18.40
|
||||
sig = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 55 57 41 54 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 48 8B B9 ? ? ? ? 48 8B D9 48 85 FF 74 16 48 89", false).Get(); // 18.40
|
||||
|
||||
if (!sig)
|
||||
sig = Memcury::Scanner::FindPattern("48 8B C4 48 89 58 10 48 89 68 18 57 48 83 EC 20 48 8B D9 48 8B 89 ? ? ? ? 48 85").Get(); // 16.50
|
||||
|
||||
return sig;
|
||||
}
|
||||
@@ -698,11 +706,14 @@ static inline uint64 FindTickFlush()
|
||||
|
||||
if (Engine_Version == 427)
|
||||
{
|
||||
auto addr = 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();
|
||||
auto addr = 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", false).Get();
|
||||
|
||||
if (!addr) // s18
|
||||
addr = 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 ? ? ? ? 44 0F").Get();
|
||||
addr = 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 ? ? ? ? 44 0F", false).Get();
|
||||
|
||||
if (!addr)
|
||||
addr = 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 ? ? ? ? 48 8B F9 48 89 4D 38 48 8D 4D 40").Get(); // 16.50
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
@@ -1104,7 +1115,7 @@ static inline uint64 FindPickTeam()
|
||||
|
||||
static inline uint64 FindInternalTryActivateAbility()
|
||||
{
|
||||
auto Addrr = Memcury::Scanner::FindStringRef(L"InternalTryActivateAbility called with invalid Handle! ASC: %s. AvatarActor: %s", true, 0, Fortnite_Version >= 17).Get();
|
||||
auto Addrr = Memcury::Scanner::FindStringRef(L"InternalTryActivateAbility called with invalid Handle! ASC: %s. AvatarActor: %s", true, 0, Fortnite_Version >= 16.50).Get();
|
||||
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
@@ -1140,8 +1151,25 @@ static inline uint64 FindCanActivateAbility()
|
||||
if (Engine_Version == 421 || Engine_Version == 422)
|
||||
return Memcury::Scanner::FindPattern("4C 89 4C 24 20 55 56 57 41 56 48 8D 6C 24 D1").Get();
|
||||
|
||||
auto Addr = Memcury::Scanner::FindStringRef(L"CanActivateAbility %s failed, blueprint refused", true, 0, Engine_Version >= 500);
|
||||
return FindBytes(Addr, { 0x48, 0x89, 0x5C }, 2000, 0, true);
|
||||
auto Addrr = Memcury::Scanner::FindStringRef(L"CanActivateAbility %s failed, blueprint refused", true, 0, Engine_Version >= 500).Get();
|
||||
|
||||
for (int i = 0; i < 2000; 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;
|
||||
}
|
||||
|
||||
if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x48 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x8B && *(uint8_t*)(uint8_t*)(Addrr - i + 2) == 0xC4)
|
||||
{
|
||||
return Addrr - i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
// auto Addr = Memcury::Scanner::FindStringRef(L"CanActivateAbility %s failed, blueprint refused", true, 0, Engine_Version >= 500);
|
||||
// return FindBytes(Addr, { 0x48, 0x89, 0x5C }, 2000, 0, true);
|
||||
}
|
||||
|
||||
static inline uint64 FindGiveAbilityAndActivateOnce()
|
||||
|
||||
Reference in New Issue
Block a user