add mat depletion, ammo cost, fixed dying crashing on s16+, fix aircraft starting on some versions, fix zone on s17
This commit is contained in:
Milxnor
2023-03-31 20:24:21 -04:00
parent d53626a850
commit fbfb6bbe54
16 changed files with 179 additions and 30 deletions

View File

@@ -32,6 +32,7 @@ public:
this->ProcessEvent(fn, &UAbilitySystemComponent_ClientActivateAbilityFailed_Params);
}
void ConsumeAllReplicatedData(FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey* AbilityOriginalPredictionKey);
FGameplayAbilitySpecHandle GiveAbilityEasy(UClass* AbilityClass);
FGameplayAbilitySpec* FindAbilitySpecFromHandle(FGameplayAbilitySpecHandle Handle);

View File

@@ -25,6 +25,13 @@ void LoopSpecs(UAbilitySystemComponent* AbilitySystemComponent, std::function<vo
}
}
void UAbilitySystemComponent::ConsumeAllReplicatedData(FGameplayAbilitySpecHandle AbilityHandle, FPredictionKey* AbilityOriginalPredictionKey)
{
// static auto AbilityTargetDataMapOffset = ActivatableAbilitiesOffset + FGameplayAbilitySpecContainerSize ?
return;
}
void UAbilitySystemComponent::InternalServerTryActivateAbilityHook(UAbilitySystemComponent* AbilitySystemComponent, FGameplayAbilitySpecHandle Handle, bool InputPressed, const FPredictionKey* PredictionKey, const FGameplayEventData* TriggerEventData) // https://github.com/EpicGames/UnrealEngine/blob/4.23/Engine/Plugins/Runtime/GameplayAbilities/Source/GameplayAbilities/Private/AbilitySystemComponent_Abilities.cpp#L1445
{
using UGameplayAbility = UObject;
@@ -42,7 +49,7 @@ void UAbilitySystemComponent::InternalServerTryActivateAbilityHook(UAbilitySyste
return;
}
// ConsumeAllReplicatedData(Handle, PredictionKey);
AbilitySystemComponent->ConsumeAllReplicatedData(Handle, (FPredictionKey*)PredictionKey);
/* const */ UGameplayAbility * AbilityToActivate = Spec->GetAbility();

View File

@@ -22,6 +22,12 @@ public:
this->ProcessEvent(fn, &IBAParams);
}
void SilentDie()
{
static auto SilentDieFn = FindObject<UFunction>("/ScriptFortniteGame.BuildingActor.SilentDie");
this->ProcessEvent(SilentDieFn);
}
float GetMaxHealth()
{
float MaxHealth = 0;

View File

@@ -677,7 +677,7 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
LOG_INFO(LogPlayer, "HandleStartingNewPlayer!");
if (Engine_Version < 427)
// if (Engine_Version < 427)
{
static int LastNum69 = 19451;
@@ -689,7 +689,6 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
auto BRIsland_FloorLoot = FindObject<UClass>("/Game/Athena/Environments/Blueprints/Tiered_Athena_FloorLoot_01.Tiered_Athena_FloorLoot_01_C");
TArray<AActor*> SpawnIsland_FloorLoot_Actors = UGameplayStatics::GetAllActorsOfClass(GetWorld(), SpawnIsland_FloorLoot);
TArray<AActor*> BRIsland_FloorLoot_Actors = UGameplayStatics::GetAllActorsOfClass(GetWorld(), BRIsland_FloorLoot);
auto SpawnIslandTierGroup = UKismetStringLibrary::Conv_StringToName(L"Loot_AthenaFloorLoot_Warmup");
@@ -755,10 +754,13 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
CurrentActor->K2_DestroyActor();
}
}
}
LOG_INFO(LogDev, "Spawned loot!");
// SpawnIsland_FloorLoot_Actors.Free();
// BRIsland_FloorLoot_Actors.Free();
}
LOG_INFO(LogDev, "Spawned loot!");
}
if (Engine_Version >= 423 && Engine_Version < 426) // 423+ we need to spawn manually and vehicle sync doesn't work on >S13.
{

View File

@@ -1,14 +1,37 @@
#include "FortInventoryInterface.h"
#include "reboot.h"
#include "FortPlayerControllerAthena.h"
char UFortInventoryInterface::RemoveInventoryItemHook(__int64 a1, FGuid a2, int Count, char bForceRemoveFromQuickBars, char bForceRemoval)
{
// kms bruh
static auto FortPlayerControllerSuperSize = (*(UClass**)(__int64(FindObject<UClass>("/Script/FortniteGame.FortPlayerController")) + Offsets::SuperStruct))->GetPropertiesSize();
auto Controller = *(UObject**)(__int64(a1) - (FortPlayerControllerSuperSize + 8));
int SuperAdditionalOffset = Engine_Version >= 427 ? 16 : 8;
auto ControllerObject = (UObject*)(__int64(a1) - (FortPlayerControllerSuperSize + SuperAdditionalOffset));
LOG_INFO(LogDev, "FortPlayerControllerSuperSize: {}", FortPlayerControllerSuperSize);
LOG_INFO(LogDev, "Controller: {}", Controller->GetFullName());
LOG_INFO(LogDev, "ControllerObject: {}", ControllerObject->GetFullName());
if (!ControllerObject)
return false;
auto PlayerController = Cast<AFortPlayerControllerAthena>(ControllerObject);
if (!PlayerController)
return false;
auto WorldInventory = PlayerController->GetWorldInventory();
if (!WorldInventory)
return false;
bool bShouldUpdate = false;
WorldInventory->RemoveItem(a2, &bShouldUpdate, Count);
if (bShouldUpdate)
WorldInventory->Update();
return true;
}

View File

@@ -28,6 +28,13 @@ void AFortPlayerController::ClientReportDamagedResourceBuilding(ABuildingSMActor
this->ProcessEvent(fn, &AFortPlayerController_ClientReportDamagedResourceBuilding_Params);
}
bool AFortPlayerController::DoesBuildFree()
{
static auto bBuildFreeOffset = GetOffset("bBuildFree");
static auto bBuildFreeFieldMask = GetFieldMask(GetProperty("bBuildFree"));
return ReadBitfieldValue(bBuildFreeOffset, bBuildFreeFieldMask);
}
void AFortPlayerController::ServerExecuteInventoryItemHook(AFortPlayerController* PlayerController, FGuid ItemGuid)
{
auto ItemInstance = PlayerController->GetWorldInventory()->FindItemInstance(ItemGuid);
@@ -454,12 +461,30 @@ void AFortPlayerController::ServerCreateBuildingActorHook(UObject* Context, FFra
if (!BuildingActor)
return ServerCreateBuildingActorOriginal(Context, Stack, Ret);
// static auto OwnerPersistentIDOffset = BuildingActor->GetOffset("OwnerPersistentID");
// BuildingActor->Get<int>(OwnerPersistentIDOffset) = PlayerStateAthena->GetWorldPlayerId();
auto MatDefinition = UFortKismetLibrary::K2_GetResourceItemDefinition(BuildingActor->GetResourceType());
auto WorldInventory = PlayerController->GetWorldInventory();
auto MatInstance = WorldInventory->FindItemInstance(MatDefinition);
bool bShouldDestroy = MatInstance ? PlayerController->DoesBuildFree() ? false : MatInstance->GetItemEntry()->GetCount() < 10 : true;
if (bShouldDestroy)
{
BuildingActor->SilentDie();
return ServerCreateBuildingActorOriginal(Context, Stack, Ret);
}
BuildingActor->SetPlayerPlaced(true);
BuildingActor->InitializeBuildingActor(PlayerController, BuildingActor, true);
BuildingActor->SetTeam(PlayerStateAthena->GetTeamIndex());
BuildingActor->SetTeam(PlayerStateAthena->GetTeamIndex()); // required?
if (!PlayerController->DoesBuildFree())
{
bool bShouldUpdate = false;
WorldInventory->RemoveItem(MatInstance->GetItemEntry()->GetItemGuid(), &bShouldUpdate, 10);
if (bShouldUpdate)
WorldInventory->Update();
}
return ServerCreateBuildingActorOriginal(Context, Stack, Ret);
}

View File

@@ -61,6 +61,8 @@ public:
return CosmeticLoadout;
}
bool DoesBuildFree();
static void ServerExecuteInventoryItemHook(AFortPlayerController* PlayerController, FGuid ItemGuid);
static void ServerAttemptInteractHook(UObject* Context, FFrame* Stack, void* Ret);

View File

@@ -27,19 +27,29 @@ APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AControll
static auto PawnClass = FindObject<UClass>("/Game/Athena/PlayerPawn_Athena.PlayerPawn_Athena_C");
GameMode->Get<UClass*>("DefaultPawnClass") = PawnClass;
constexpr bool bUseSpawnActor = false;
static auto fn = FindObject<UFunction>(L"/Script/Engine.GameModeBase.SpawnDefaultPawnAtTransform");
FTransform SpawnTransform = StartSpot->GetTransform();
struct { AController* NewPlayer; FTransform SpawnTransform; APawn* ReturnValue; }
AGameModeBase_SpawnDefaultPawnAtTransform_Params{NewPlayer, SpawnTransform };
// GameMode->ProcessEvent(fn, &AGameModeBase_SpawnDefaultPawnAtTransform_Params);
APawn* NewPawn = nullptr;
FActorSpawnParameters SpawnParameters{};
SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
auto NewPawn = GetWorld()->SpawnActor<APawn>(PawnClass, SpawnTransform, SpawnParameters); // AGameModeBase_SpawnDefaultPawnAtTransform_Params.ReturnValue;
if constexpr (bUseSpawnActor)
{
NewPawn = GetWorld()->SpawnActor<APawn>(PawnClass, SpawnTransform, SpawnParameters);
}
else
{
struct { AController* NewPlayer; FTransform SpawnTransform; APawn* ReturnValue; }
AGameModeBase_SpawnDefaultPawnAtTransform_Params{ NewPlayer, SpawnTransform };
GameMode->ProcessEvent(fn, &AGameModeBase_SpawnDefaultPawnAtTransform_Params);
NewPawn = AGameModeBase_SpawnDefaultPawnAtTransform_Params.ReturnValue;
}
if (!NewPawn)
return nullptr;

View File

@@ -0,0 +1,19 @@
#pragma once
#include "Array.h"
#include "Map.h"
#include "GameplayAbilitySpec.h"
struct FGameplayAbilitySpecHandleAndPredictionKey
{
FGameplayAbilitySpecHandle AbilityHandle;
int32 PredictionKeyAtCreation;
};
/*struct FGameplayAbilityReplicatedDataContainer
{
typedef TPair<FGameplayAbilitySpecHandleAndPredictionKey, TSharedRef<FAbilityReplicatedDataCache>> FKeyDataPair;
TArray<FKeyDataPair> InUseData;
TArray<TSharedRef<FAbilityReplicatedDataCache>> FreeData;
}; */

View File

@@ -282,6 +282,7 @@
<ClInclude Include="GameMode.h" />
<ClInclude Include="GameModeBase.h" />
<ClInclude Include="GameplayAbilitySpec.h" />
<ClInclude Include="GameplayAbilityTypes.h" />
<ClInclude Include="GameplayStatics.h" />
<ClInclude Include="GameplayTagContainer.h" />
<ClInclude Include="GameSession.h" />

View File

@@ -476,6 +476,9 @@
<ClInclude Include="BuildingGameplayActorSpawnMachine.h">
<Filter>FortniteGame\Source\FortniteGame\Public\Building\GameplayActors</Filter>
</ClInclude>
<ClInclude Include="GameplayAbilityTypes.h">
<Filter>Engine\Plugins\Runtime\GameplayAbilities\Source\GameplayAbilities\Public</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Engine">

View File

@@ -33,7 +33,7 @@ static void SetZoneToIndexHook(AFortGameModeAthena* GameModeAthena, int Override
LOG_INFO(LogDev, "SafeZoneDefinitionOffset: 0x{:x}", SafeZoneDefinitionOffset);
static auto ZoneDurationsOffset = std::floor(Fortnite_Version) >= 18 ? 0x248 : 0x1F8;
static auto ZoneDurationsOffset = std::floor(Fortnite_Version) == 17 ? 0x258 : std::floor(Fortnite_Version) >= 18 ? 0x248 : 0x1F8;
static auto ZoneHoldDurationsOffset = ZoneDurationsOffset - 0x10;
auto& ZoneDurations = *(TArray<float>*)(__int64(SafeZoneDefinition) + ZoneDurationsOffset);

View File

@@ -430,19 +430,41 @@ DWORD WINAPI Main(LPVOID)
Hooking::MinHook::Hook((PVOID)Addresses::GetPlayerViewpoint, (PVOID)AFortPlayerControllerAthena::GetPlayerViewPointHook, (PVOID*)&AFortPlayerControllerAthena::GetPlayerViewPointOriginal);
Hooking::MinHook::Hook((PVOID)Addresses::TickFlush, (PVOID)UNetDriver::TickFlushHook, (PVOID*)&UNetDriver::TickFlushOriginal);
// Hooking::MinHook::Hook((PVOID)(__int64(GetModuleHandleW(0)) + 0x1A001D0), GetServerDeltaTimeFromObjectHook);
// if (Engine_Version < 427)
{
Hooking::MinHook::Hook((PVOID)Addresses::OnDamageServer, (PVOID)ABuildingActor::OnDamageServerHook, (PVOID*)&ABuildingActor::OnDamageServerOriginal);
}
Hooking::MinHook::Hook((PVOID)Addresses::OnDamageServer, (PVOID)ABuildingActor::OnDamageServerHook, (PVOID*)&ABuildingActor::OnDamageServerOriginal);
Hooking::MinHook::Hook((PVOID)Addresses::GetMaxTickRate, GetMaxTickRateHook);
// Hooking::MinHook::Hook((PVOID)Addresses::CollectGarbage, (PVOID)CollectGarbageHook, nullptr);
Hooking::MinHook::Hook((PVOID)Addresses::PickTeam, (PVOID)AFortGameModeAthena::Athena_PickTeamHook);
// Hooking::MinHook::Hook((PVOID)Addresses::SetZoneToIndex, (PVOID)AFortGameModeAthena::SetZoneToIndexHook, (PVOID*)&AFortGameModeAthena::SetZoneToIndexOriginal);
Hooking::MinHook::Hook((PVOID)Addresses::CompletePickupAnimation, (PVOID)AFortPickup::CompletePickupAnimationHook, (PVOID*)&AFortPickup::CompletePickupAnimationOriginal);
// Hooking::MinHook::Hook((PVOID)Addresses::CanActivateAbility, ReturnTrueHook); // ahhh wtf
// Hooking::MinHook::Hook((PVOID)FindFunctionCall(L"ServerRemoveInventoryItem"), UFortInventoryInterface::RemoveInventoryItemHook);
Hooking::MinHook::Hook((PVOID)Addresses::CanActivateAbility, ReturnTrueHook); // ahhh wtf
auto ServerRemoveInventoryItemFunctionCallRef = Memcury::Scanner::FindPointerRef((PVOID)FindFunctionCall(L"ServerRemoveInventoryItem",
Fortnite_Version >= 16 ? std::vector<uint8_t>{ 0x48, 0x8B, 0xC4 } : std::vector<uint8_t>{ 0x48, 0x89, 0x5C }), 0, true);
LOG_INFO(LogDev, "ServerRemoveInventoryItemFunctionCallRef: 0x{:x}", ServerRemoveInventoryItemFunctionCallRef.Get() - __int64(GetModuleHandleW(0)));
uint64 ServerRemoveInventoryItemFunctionCallBeginFunctionAddr = 0;
for (int i = 0; i < 400; i++)
{
if (*(uint8_t*)(uint8_t*)(ServerRemoveInventoryItemFunctionCallRef.Get() - i) == 0x48 && *(uint8_t*)(uint8_t*)(ServerRemoveInventoryItemFunctionCallRef.Get() - i + 1) == 0x89 && *(uint8_t*)(uint8_t*)(ServerRemoveInventoryItemFunctionCallRef.Get() - i + 2) == 0x5C)
{
ServerRemoveInventoryItemFunctionCallBeginFunctionAddr = ServerRemoveInventoryItemFunctionCallRef.Get() - i;
break;
}
if (*(uint8_t*)(uint8_t*)(ServerRemoveInventoryItemFunctionCallRef.Get() - i) == 0x48 && *(uint8_t*)(uint8_t*)(ServerRemoveInventoryItemFunctionCallRef.Get() - i + 1) == 0x83 && *(uint8_t*)(uint8_t*)(ServerRemoveInventoryItemFunctionCallRef.Get() - i + 2) == 0xEC)
{
ServerRemoveInventoryItemFunctionCallBeginFunctionAddr = ServerRemoveInventoryItemFunctionCallRef.Get() - i;
break;
}
}
Hooking::MinHook::Hook(
Memcury::Scanner(ServerRemoveInventoryItemFunctionCallBeginFunctionAddr).GetAs<PVOID>(),
UFortInventoryInterface::RemoveInventoryItemHook
);
if (Fortnite_Version >= 13)
Hooking::MinHook::Hook((PVOID)Addresses::SetZoneToIndex, (PVOID)SetZoneToIndexHook, (PVOID*)&SetZoneToIndexOriginal);
@@ -516,11 +538,16 @@ DWORD WINAPI Main(LPVOID)
auto GameMode = (AFortGameMode*)GetWorld()->GetGameMode();
auto GameState = GameMode->GetGameState();
/*
GameState->Get<float>("WarmupCountdownEndTime") = 0;
GameMode->Get<float>("WarmupCountdownDuration") = 0;
GameState->Get<float>("WarmupCountdownStartTime") = 0;
GameMode->Get<float>("WarmupEarlyCountdownDuration") = 0;
*/
FString cmd = L"startaircraft";
UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), cmd, nullptr);
}
else if (GetAsyncKeyState(VK_F9) & 1)

View File

@@ -397,7 +397,7 @@ static inline uint64 FindInitListen()
static inline uint64 FindOnDamageServer()
{
auto Addr = FindFunctionCall(L"OnDamageServer",
Engine_Version == 416 ? std::vector<uint8_t>{ 0x4C, 0x89, 0x4C} :
Engine_Version == 416 ? std::vector<uint8_t>{ 0x4C, 0x89, 0x4C } :
Engine_Version == 419 || Engine_Version >= 427 ? std::vector<uint8_t>{ 0x48, 0x8B, 0xC4 } : std::vector<uint8_t>{ 0x40, 0x55 }
);
@@ -621,7 +621,7 @@ static inline uint64 FindRemoveFromAlivePlayers()
Addrr = Memcury::Scanner::FindStringRef(L"FortGameModeAthena: Player [%s] removed from alive players list (Team [%d]). Player count is now [%d]. PlayerBots count is now [%d]. Team count is now [%d].", false).Get();
if (!Addrr)
Addrr = Memcury::Scanner::FindStringRef(L"FortGameModeAthena::RemoveFromAlivePlayers: Player [%s] PC [%s] removed from alive players list (Team [%d]). Player count is now [%d]. PlayerBots count is now [%d]. Team count is now [%d].", true, 0, Fortnite_Version >= 18).Get(); // todo check version
Addrr = Memcury::Scanner::FindStringRef(L"FortGameModeAthena::RemoveFromAlivePlayers: Player [%s] PC [%s] removed from alive players list (Team [%d]). Player count is now [%d]. PlayerBots count is now [%d]. Team count is now [%d].", true, 0, Fortnite_Version >= 16).Get(); // checked on 16.40
for (int i = 0; i < 2000; i++)
{

View File

@@ -4,7 +4,7 @@ namespace Globals
{
extern inline bool bCreative = false;
extern inline bool bGoingToPlayEvent = false;
extern inline bool bNoMCP = false;
extern inline bool bNoMCP = true;
extern inline bool bLateGame = false;
extern inline bool bAbilitiesEnabled = true;
extern inline bool bLogProcessEvent = false;

27
vendor/memcury.h vendored
View File

@@ -758,7 +758,7 @@
return Scanner(add);
}
static auto FindPointerRef(void* Pointer) -> Scanner // credit me and ender
static auto FindPointerRef(void* Pointer, int useRefNum = 0, bool bUseFirstResult = false) -> Scanner // credit me and ender
{
PE::Address add{ nullptr };
@@ -766,6 +766,8 @@
const auto scanBytes = reinterpret_cast<std::uint8_t*>(textSection.GetSectionStart().Get());
int aa = 0;
// scan only text section
for (DWORD i = 0x0; i < textSection.GetSectionSize(); i++)
{
@@ -774,6 +776,12 @@
if (PE::Address(&scanBytes[i]).RelativeOffset(3).GetAs<void*>() == Pointer)
{
add = PE::Address(&scanBytes[i]);
if (bUseFirstResult)
return Scanner(add);
/* if (++aa > useRefNum)
break; */
}
}
@@ -782,6 +790,12 @@
if (PE::Address(&scanBytes[i]).RelativeOffset(1).GetAs<void*>() == Pointer)
{
add = PE::Address(&scanBytes[i]);
if (bUseFirstResult)
return Scanner(add);
/* if (++aa > useRefNum)
break; */
}
}
}
@@ -1394,5 +1408,14 @@
{
auto FunctionPtr = Memcury::Scanner::FindStringRef(Name, true, skip).ScanFor({ 0x48, 0x8D, 0x0D }).RelativeOffset(3).GetAs<void*>();
return Memcury::Scanner::FindPointerRef(FunctionPtr).ScanFor(Bytes, false).Get();
auto PtrRef = Memcury::Scanner::FindPointerRef(FunctionPtr);
/* if (!PtrRef.Get() || PtrRef.Get() == __int64(FunctionPtr))
{
std::wstring NameWStr = std::wstring(Name);
LOG_WARN(LogMemory, "Failed to find pointer reference for {}", std::string(NameWStr.begin(), NameWStr.end()));
return 0;
} */
return PtrRef.ScanFor(Bytes, false).Get();
}