fix 16.50, fix failing abilities s16+, ammo in bottom right

This commit is contained in:
Milxnor
2023-04-02 11:58:32 -04:00
parent 3bca6f76fe
commit 20e9fb87df
9 changed files with 106 additions and 21 deletions

View File

@@ -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))

View File

@@ -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");

View File

@@ -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();
};

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -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();

View File

@@ -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">

View File

@@ -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);

View File

@@ -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()