mirror of
https://github.com/Milxnor/Project-Reboot-3.0.git
synced 2026-01-13 02:42:22 +01:00
interacting
This commit is contained in:
@@ -3,18 +3,19 @@
|
||||
#include "Object.h"
|
||||
#include "GameplayAbilitySpec.h"
|
||||
|
||||
struct PadHex10 { char Pad[0x10]; };
|
||||
struct PadHex18 { char Pad[0x18]; };
|
||||
struct PadHexA8 { char Pad[0xA8]; };
|
||||
struct PadHexB0 { char Pad[0xB0]; };
|
||||
|
||||
using FPredictionKey = __int64; // PadHex18;
|
||||
using FGameplayEventData = __int64; // PadHexB0;
|
||||
using FPredictionKey = PadHex18;
|
||||
using FGameplayEventData = PadHexA8;
|
||||
|
||||
class UAbilitySystemComponent : public UObject
|
||||
{
|
||||
public:
|
||||
static inline FGameplayAbilitySpecHandle* (*GiveAbilityOriginal)(UAbilitySystemComponent*, FGameplayAbilitySpecHandle*, __int64 inSpec);
|
||||
static inline bool (*InternalTryActivateAbilityOriginal)(UAbilitySystemComponent*, FGameplayAbilitySpecHandle Handle, __int64 InPredictionKey, UObject** OutInstancedAbility, void* OnGameplayAbilityEndedDelegate, const FGameplayEventData* TriggerEventData);
|
||||
static inline bool (*InternalTryActivateAbilityOriginal)(UAbilitySystemComponent*, FGameplayAbilitySpecHandle Handle, FPredictionKey InPredictionKey, UObject** OutInstancedAbility, void* OnGameplayAbilityEndedDelegate, const FGameplayEventData* TriggerEventData);
|
||||
|
||||
void ClientActivateAbilityFailed(FGameplayAbilitySpecHandle AbilityToActivate, int16_t PredictionKey)
|
||||
{
|
||||
|
||||
@@ -46,7 +46,7 @@ void InternalServerTryActivateAbility(UAbilitySystemComponent* AbilitySystemComp
|
||||
UGameplayAbility* InstancedAbility = nullptr;
|
||||
SetBitfield(Spec, 1, true); // InputPressed = true
|
||||
|
||||
if (!AbilitySystemComponent->InternalTryActivateAbilityOriginal(AbilitySystemComponent, Handle, __int64(PredictionKey), &InstancedAbility, nullptr, TriggerEventData))
|
||||
if (!AbilitySystemComponent->InternalTryActivateAbilityOriginal(AbilitySystemComponent, Handle, *(FPredictionKey*)PredictionKey, &InstancedAbility, nullptr, TriggerEventData))
|
||||
{
|
||||
AbilitySystemComponent->ClientActivateAbilityFailed(Handle, *(int16_t*)(__int64(PredictionKey) + CurrentOffset));
|
||||
SetBitfield(Spec, 1, false); // InputPressed = false
|
||||
|
||||
@@ -5,4 +5,9 @@
|
||||
class ABuildingContainer : public ABuildingSMActor
|
||||
{
|
||||
public:
|
||||
static UClass* StaticClass()
|
||||
{
|
||||
static auto Class = FindObject<UClass>("/Script/FortniteGame.BuildingContainer");
|
||||
return Class;
|
||||
}
|
||||
};
|
||||
@@ -18,8 +18,7 @@
|
||||
#include "events.h"
|
||||
#include "reboot.h"
|
||||
#include "ai.h"
|
||||
|
||||
static bool bFirstPlayerJoined = false;
|
||||
#include "Map.h"
|
||||
|
||||
enum class EDynamicFoundationEnabledState : uint8_t
|
||||
{
|
||||
@@ -29,8 +28,6 @@ enum class EDynamicFoundationEnabledState : uint8_t
|
||||
EDynamicFoundationEnabledState_MAX = 3
|
||||
};
|
||||
|
||||
|
||||
// Enum FortniteGame.EDynamicFoundationType
|
||||
enum class EDynamicFoundationType : uint8_t
|
||||
{
|
||||
Static = 0,
|
||||
@@ -123,6 +120,42 @@ UObject* GetPlaylistToUse()
|
||||
return Playlist;
|
||||
}
|
||||
|
||||
FName AFortGameModeAthena::RedirectLootTier(const FName& LootTier)
|
||||
{
|
||||
static auto RedirectAthenaLootTierGroupsOffset = this->GetOffset("RedirectAthenaLootTierGroups", false);
|
||||
|
||||
if (RedirectAthenaLootTierGroupsOffset == 0)
|
||||
{
|
||||
static auto Loot_TreasureFName = UKismetStringLibrary::Conv_StringToName(L"Loot_Treasure");
|
||||
static auto Loot_AmmoFName = UKismetStringLibrary::Conv_StringToName(L"Loot_Ammo");
|
||||
|
||||
if (LootTier == Loot_TreasureFName)
|
||||
return UKismetStringLibrary::Conv_StringToName(L"Loot_AthenaTreasure");
|
||||
|
||||
if (LootTier == Loot_AmmoFName)
|
||||
return UKismetStringLibrary::Conv_StringToName(L"Loot_AthenaAmmoLarge");
|
||||
|
||||
return LootTier;
|
||||
}
|
||||
|
||||
auto& RedirectAthenaLootTierGroups = Get<TMap<FName, FName>>(RedirectAthenaLootTierGroupsOffset);
|
||||
|
||||
for (int i = 0; i < RedirectAthenaLootTierGroups.Pairs.Elements.Num(); i++)
|
||||
{
|
||||
auto& Pair = RedirectAthenaLootTierGroups.Pairs.Elements.Data.at(i).ElementData.Value;
|
||||
|
||||
auto& Key = Pair.Key();
|
||||
auto& Value = Pair.Value();
|
||||
|
||||
LOG_INFO(LogDev, "[{}] {} {}", i, Key.ComparisonIndex.Value ? Key.ToString() : "NULL", Key.ComparisonIndex.Value ? Value.ToString() : "NULL");
|
||||
|
||||
if (Key == LootTier)
|
||||
return Value;
|
||||
}
|
||||
|
||||
return LootTier;
|
||||
}
|
||||
|
||||
bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* GameMode)
|
||||
{
|
||||
auto GameState = GameMode->GetGameStateAthena();
|
||||
@@ -416,6 +449,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
|
||||
float TimeSeconds = 35.f; // UGameplayStatics::GetTimeSeconds(GetWorld());
|
||||
|
||||
LOG_INFO(LogDev, "Initializing!");
|
||||
LOG_INFO(LogDev, "GameMode 0x{:x}", __int64(GameMode));
|
||||
|
||||
GameState->Get<float>("WarmupCountdownEndTime") = TimeSeconds + Duration;
|
||||
GameMode->Get<float>("WarmupCountdownDuration") = Duration;
|
||||
@@ -622,13 +656,13 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
||||
PlayerStateAthena->ProcessEvent(OnRep_bHasStartedPlayingFn);
|
||||
}
|
||||
|
||||
if (false)
|
||||
if (Globals::bAbilitiesEnabled)
|
||||
{
|
||||
static auto GameplayAbilitySet = LoadObject<UObject>(L"/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_AthenaPlayer.GAS_AthenaPlayer") ?
|
||||
LoadObject<UObject>(L"/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_AthenaPlayer.GAS_AthenaPlayer") :
|
||||
LoadObject<UObject>(L"/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_DefaultPlayer.GAS_DefaultPlayer");
|
||||
|
||||
// LOG_INFO(LogDev, "GameplayAbilitySet {}", __int64(GameplayAbilitySet));
|
||||
LOG_INFO(LogDev, "GameplayAbilitySet {}", __int64(GameplayAbilitySet));
|
||||
|
||||
if (GameplayAbilitySet)
|
||||
{
|
||||
@@ -661,11 +695,12 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
||||
unsigned char ahh[0x0028];
|
||||
};
|
||||
|
||||
auto& PlayerStateUniqueId = PlayerStateAthena->Get<FUniqueNetIdReplExperimental>("UniqueId");
|
||||
FUniqueNetIdReplExperimental bugha{};
|
||||
auto& PlayerStateUniqueId = bugha; // PlayerStateAthena->Get<FUniqueNetIdReplExperimental>("UniqueId");
|
||||
|
||||
// if (false)
|
||||
// if (GameMemberInfoArrayOffset != 0)
|
||||
if (Engine_Version >= 423)
|
||||
if (Engine_Version >= 423 && false)
|
||||
{
|
||||
struct FGameMemberInfo : public FFastArraySerializerItem
|
||||
{
|
||||
@@ -750,5 +785,19 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
|
||||
UFortPlaysetItemDefinition::ShowPlayset(IslandPlayset, Portal->GetLinkedVolume());
|
||||
}
|
||||
|
||||
static auto SpawnActorDataListOffset = GameMode->GetOffset("SpawnActorDataList");
|
||||
|
||||
if (SpawnActorDataListOffset != 0)
|
||||
{
|
||||
auto& SpawnActorDataList = GameMode->Get<TArray<__int64>>(SpawnActorDataListOffset);
|
||||
LOG_INFO(LogDev, "SpawnActorDataList.Num(): {}", SpawnActorDataList.Num());
|
||||
}
|
||||
|
||||
return Athena_HandleStartingNewPlayerOriginal(GameMode, NewPlayerActor);
|
||||
}
|
||||
|
||||
void AFortGameModeAthena::SetZoneToIndexHook(AFortGameModeAthena* GameModeAthena, int OverridePhaseMaybeIDFK)
|
||||
{
|
||||
LOG_INFO(LogDev, "OverridePhaseMaybeIDFK: {}", OverridePhaseMaybeIDFK);
|
||||
return SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK);
|
||||
}
|
||||
@@ -9,13 +9,17 @@ class AFortGameModeAthena : public AFortGameModePvPBase
|
||||
public:
|
||||
static inline bool (*Athena_ReadyToStartMatchOriginal)(AFortGameModeAthena* GameMode);
|
||||
static inline void (*Athena_HandleStartingNewPlayerOriginal)(AFortGameModeAthena* GameMode, AActor* NewPlayer);
|
||||
|
||||
static bool Athena_ReadyToStartMatchHook(AFortGameModeAthena* GameMode);
|
||||
static int Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint8 preferredTeam, AActor* Controller);
|
||||
static void Athena_HandleStartingNewPlayerHook(AFortGameModeAthena* GameMode, AActor* NewPlayerActor);
|
||||
static inline void (*SetZoneToIndexOriginal)(AFortGameModeAthena* GameModeAthena, int OverridePhaseMaybeIDFK);
|
||||
|
||||
AFortGameStateAthena* GetGameStateAthena()
|
||||
{
|
||||
return (AFortGameStateAthena*)GetGameState();
|
||||
}
|
||||
|
||||
FName RedirectLootTier(const FName& LootTier);
|
||||
|
||||
static bool Athena_ReadyToStartMatchHook(AFortGameModeAthena* GameMode);
|
||||
static int Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint8 preferredTeam, AActor* Controller);
|
||||
static void Athena_HandleStartingNewPlayerHook(AFortGameModeAthena* GameMode, AActor* NewPlayerActor);
|
||||
static void SetZoneToIndexHook(AFortGameModeAthena* GameModeAthena, int OverridePhaseMaybeIDFK);
|
||||
};
|
||||
@@ -15,19 +15,46 @@ void UFortKismetLibrary::ApplyCharacterCosmetics(UObject* WorldContextObject, co
|
||||
{
|
||||
static auto fn = FindObject<UFunction>("/Script/FortniteGame.FortKismetLibrary.ApplyCharacterCosmetics");
|
||||
|
||||
if (fn)
|
||||
{
|
||||
struct
|
||||
{
|
||||
UObject* WorldContextObject; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
TArray<UObject*> CharacterParts; // (Parm, ZeroConstructor, NativeAccessSpecifierPublic)
|
||||
UObject* PlayerState; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
bool bSuccess; // (Parm, OutParm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||
} UFortKismetLibrary_ApplyCharacterCosmetics_Params{WorldContextObject, CharacterParts, PlayerState };
|
||||
} UFortKismetLibrary_ApplyCharacterCosmetics_Params{ WorldContextObject, CharacterParts, PlayerState };
|
||||
|
||||
static auto DefaultClass = StaticClass();
|
||||
DefaultClass->ProcessEvent(fn, &UFortKismetLibrary_ApplyCharacterCosmetics_Params);
|
||||
|
||||
if (bSuccess)
|
||||
*bSuccess = UFortKismetLibrary_ApplyCharacterCosmetics_Params.bSuccess;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static auto CharacterPartsOffset = PlayerState->GetOffset("CharacterParts", false);
|
||||
|
||||
if (CharacterPartsOffset != 0)
|
||||
{
|
||||
auto CharacterPartsPS = PlayerState->GetPtr<__int64>("CharacterParts");
|
||||
|
||||
static auto PartsOffset = FindOffsetStruct("/Script/FortniteGame.CustomCharacterParts", "Parts");
|
||||
auto Parts = (UObject**)(__int64(CharacterPartsPS) + PartsOffset); // UCustomCharacterPart* Parts[0x6]
|
||||
|
||||
for (int i = 0; i < CharacterParts.Num(); i++)
|
||||
{
|
||||
Parts[i] = CharacterParts.at(i);
|
||||
}
|
||||
|
||||
static auto OnRep_CharacterPartsFn = FindObject<UFunction>("/Script/FortniteGame.FortPlayerState.OnRep_CharacterParts");
|
||||
PlayerState->ProcessEvent(OnRep_CharacterPartsFn);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO Add character data support
|
||||
}
|
||||
}
|
||||
|
||||
UClass* UFortKismetLibrary::StaticClass()
|
||||
|
||||
@@ -16,5 +16,13 @@ public:
|
||||
return Get<AFortWeapon*>(CurrentWeaponOffset);
|
||||
}
|
||||
|
||||
bool IsDBNO()
|
||||
{
|
||||
static auto bIsDBNOFieldMask = GetFieldMask(GetProperty("bIsDBNO"));
|
||||
static auto bIsDBNOOffset = GetOffset("bIsDBNO");
|
||||
|
||||
return ReadBitfieldValue(bIsDBNOOffset, bIsDBNOFieldMask);
|
||||
}
|
||||
|
||||
static UClass* StaticClass();
|
||||
};
|
||||
@@ -10,6 +10,11 @@
|
||||
#include "ActorComponent.h"
|
||||
#include "FortPlayerStateAthena.h"
|
||||
#include "globals.h"
|
||||
#include "FortPlayerControllerAthena.h"
|
||||
#include "BuildingContainer.h"
|
||||
#include "FortLootPackage.h"
|
||||
#include "FortPickup.h"
|
||||
#include "FortPlayerPawn.h"
|
||||
|
||||
void AFortPlayerController::ClientReportDamagedResourceBuilding(ABuildingSMActor* BuildingSMActor, EFortResourceType PotentialResourceType, int PotentialResourceCount, bool bDestroyed, bool bJustHitWeakspot)
|
||||
{
|
||||
@@ -56,6 +61,70 @@ void AFortPlayerController::ServerExecuteInventoryItemHook(AFortPlayerController
|
||||
}
|
||||
}
|
||||
|
||||
void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame* Stack, void* Ret)
|
||||
{
|
||||
LOG_INFO(LogInteraction, "ServerAttemptInteract!");
|
||||
|
||||
auto Params = Stack->Locals;
|
||||
|
||||
static bool bIsUsingComponent = FindObject<UClass>("/Script/FortniteGame.FortControllerComponent_Interaction");
|
||||
|
||||
AFortPlayerControllerAthena* PlayerController = bIsUsingComponent ? Cast<AFortPlayerControllerAthena>(((UActorComponent*)Context)->GetOwner()) :
|
||||
Cast<AFortPlayerControllerAthena>(Context);
|
||||
|
||||
if (!PlayerController)
|
||||
return;
|
||||
|
||||
std::string StructName = bIsUsingComponent ? "/Script/FortniteGame.FortControllerComponent_Interaction.ServerAttemptInteract" : "/Script/FortniteGame.FortPlayerController.ServerAttemptInteract";
|
||||
|
||||
static auto ReceivingActorOffset = FindOffsetStruct(StructName, "ReceivingActor");
|
||||
auto ReceivingActor = *(AActor**)(__int64(Params) + ReceivingActorOffset);
|
||||
|
||||
// LOG_INFO(LogInteraction, "ReceivingActor: {}", __int64(ReceivingActor));
|
||||
|
||||
if (!ReceivingActor)
|
||||
return;
|
||||
|
||||
// LOG_INFO(LogInteraction, "ReceivingActor Name: {}", ReceivingActor->GetFullName());
|
||||
|
||||
if (auto BuildingContainer = Cast<ABuildingContainer>(ReceivingActor))
|
||||
{
|
||||
static auto bAlreadySearchedOffset = BuildingContainer->GetOffset("bAlreadySearched");
|
||||
static auto SearchBounceDataOffset = BuildingContainer->GetOffset("SearchBounceData");
|
||||
static auto SearchAnimationCountOffset = FindOffsetStruct("/Script/FortniteGame.FortSearchBounceData", "SearchAnimationCount");
|
||||
static auto bAlreadySearchedFieldMask = GetFieldMask(BuildingContainer->GetProperty(bAlreadySearchedOffset));
|
||||
|
||||
auto SearchBounceData = BuildingContainer->GetPtr<void>(SearchBounceDataOffset);
|
||||
|
||||
if (BuildingContainer->ReadBitfieldValue(bAlreadySearchedOffset, bAlreadySearchedFieldMask))
|
||||
return;
|
||||
|
||||
LOG_INFO(LogInteraction, "bAlreadySearchedFieldMask: {}", bAlreadySearchedFieldMask);
|
||||
|
||||
BuildingContainer->SetBitfieldValue(bAlreadySearchedOffset, bAlreadySearchedFieldMask, true);
|
||||
(*(int*)(__int64(SearchBounceData) + SearchAnimationCountOffset))++;
|
||||
|
||||
static auto OnRep_bAlreadySearchedFn = FindObject<UFunction>("/Script/FortniteGame.BuildingContainer.OnRep_bAlreadySearched");
|
||||
BuildingContainer->ProcessEvent(OnRep_bAlreadySearchedFn);
|
||||
|
||||
static auto SearchLootTierGroupOffset = BuildingContainer->GetOffset("SearchLootTierGroup");
|
||||
auto RedirectedLootTier = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode(), false)->RedirectLootTier(BuildingContainer->Get<FName>(SearchLootTierGroupOffset));
|
||||
|
||||
auto LootDrops = PickLootDrops(RedirectedLootTier);
|
||||
|
||||
FVector LocationToSpawnLoot = BuildingContainer->GetActorLocation();
|
||||
|
||||
for (int i = 0; i < LootDrops.size(); i++)
|
||||
{
|
||||
AFortPickup::SpawnPickup(LootDrops.at(i).first, LocationToSpawnLoot, LootDrops.at(i).second, EFortPickupSourceTypeFlag::Container, EFortPickupSpawnSource::Unset, -1
|
||||
// , (AFortPawn*)PlayerController->GetPawn() // should we put this here?
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return ServerAttemptInteractOriginal(Context, Stack, Ret);
|
||||
}
|
||||
|
||||
void AFortPlayerController::ServerAttemptAircraftJumpHook(AFortPlayerController* PC, FRotator ClientRotation)
|
||||
{
|
||||
if (Fortnite_Version == 17.30 && Globals::bGoingToPlayEvent)
|
||||
@@ -187,6 +256,46 @@ void AFortPlayerController::ServerPlayEmoteItemHook(AFortPlayerController* Playe
|
||||
GiveAbilityAndActivateOnce(PlayerState->GetAbilitySystemComponent(), &outHandle, __int64(Spec));
|
||||
}
|
||||
|
||||
void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerController, __int64 DeathReport)
|
||||
{
|
||||
auto DeadPawn = Cast<AFortPlayerPawn>(PlayerController->GetPawn());
|
||||
|
||||
if (!DeadPawn)
|
||||
return;
|
||||
|
||||
static auto DeathInfoStruct = FindObject<UStruct>("/Script/FortniteGame.DeathInfo");
|
||||
static auto DeathInfoStructSize = DeathInfoStruct->GetPropertiesSize();
|
||||
|
||||
auto DeathInfo = Alloc<void>(DeathInfoStructSize);
|
||||
|
||||
*(bool*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::bDBNO) = DeadPawn->IsDBNO();
|
||||
|
||||
auto DeathLocation = DeadPawn->GetActorLocation();
|
||||
auto WorldInventory = PlayerController->GetWorldInventory();
|
||||
|
||||
auto& ItemInstances = WorldInventory->GetItemList().GetItemInstances();
|
||||
|
||||
for (int i = 0; i < ItemInstances.Num(); i++)
|
||||
{
|
||||
auto ItemInstance = ItemInstances.at(i);
|
||||
|
||||
if (!ItemInstance)
|
||||
continue;
|
||||
|
||||
auto ItemEntry = ItemInstance->GetItemEntry();
|
||||
auto WorldItemDefinition = Cast<UFortWorldItemDefinition>(ItemEntry->GetItemDefinition());
|
||||
|
||||
if (!WorldItemDefinition)
|
||||
continue;
|
||||
|
||||
if (!WorldItemDefinition->ShouldDropOnDeath())
|
||||
continue;
|
||||
|
||||
AFortPickup::SpawnPickup(WorldItemDefinition, DeathLocation, ItemEntry->GetCount(), EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::PlayerElimination,
|
||||
ItemEntry->GetLoadedAmmo());
|
||||
}
|
||||
}
|
||||
|
||||
void AFortPlayerController::ServerBeginEditingBuildingActorHook(AFortPlayerController* PlayerController, ABuildingSMActor* BuildingActorToEdit)
|
||||
{
|
||||
if (!BuildingActorToEdit || !BuildingActorToEdit->IsPlayerPlaced())
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "Rotator.h"
|
||||
#include "BuildingSMActor.h"
|
||||
#include "Stack.h"
|
||||
|
||||
struct FCreateBuildingActorData { uint32_t BuildingClassHandle; FVector BuildLoc; FRotator BuildRot; bool bMirrored; };
|
||||
|
||||
@@ -27,6 +28,8 @@ struct FFortAthenaLoadout
|
||||
class AFortPlayerController : public APlayerController
|
||||
{
|
||||
public:
|
||||
static inline void (*ServerAttemptInteractOriginal)(UObject* Context, FFrame* Stack, void* Ret);
|
||||
|
||||
void ClientReportDamagedResourceBuilding(ABuildingSMActor* BuildingSMActor, EFortResourceType PotentialResourceType, int PotentialResourceCount, bool bDestroyed, bool bJustHitWeakspot);
|
||||
|
||||
AFortInventory*& GetWorldInventory()
|
||||
@@ -41,12 +44,6 @@ public:
|
||||
return Get<AFortPawn*>(MyFortPawnOffset);
|
||||
}
|
||||
|
||||
static UClass* StaticClass()
|
||||
{
|
||||
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortPlayerController");
|
||||
return Class;
|
||||
}
|
||||
|
||||
FFortAthenaLoadout* GetCosmeticLoadout()
|
||||
{
|
||||
static auto CosmeticLoadoutPCOffset = this->GetOffset("CosmeticLoadoutPC", false);
|
||||
@@ -60,13 +57,21 @@ public:
|
||||
}
|
||||
|
||||
static void ServerExecuteInventoryItemHook(AFortPlayerController* PlayerController, FGuid ItemGuid);
|
||||
static void ServerAttemptInteractHook(UObject* Context, FFrame* Stack, void* Ret);
|
||||
|
||||
static void ServerAttemptAircraftJumpHook(AFortPlayerController* PC, FRotator ClientRotation);
|
||||
static void ServerCreateBuildingActorHook(AFortPlayerController* PlayerController, FCreateBuildingActorData CreateBuildingData);
|
||||
|
||||
static void ServerPlayEmoteItemHook(AFortPlayerController* PlayerController, UObject* EmoteAsset);
|
||||
static void ClientOnPawnDiedHook(AFortPlayerController* PlayerController, __int64 DeathReport);
|
||||
|
||||
static void ServerBeginEditingBuildingActorHook(AFortPlayerController* PlayerController, ABuildingSMActor* BuildingActorToEdit);
|
||||
static void ServerEditBuildingActorHook(AFortPlayerController* PlayerController, ABuildingSMActor* BuildingActorToEdit, UClass* NewBuildingClass, int RotationIterations, char bMirrored);
|
||||
static void ServerEndEditingBuildingActorHook(AFortPlayerController* PlayerController, ABuildingSMActor* BuildingActorToStopEditing);
|
||||
|
||||
static UClass* StaticClass()
|
||||
{
|
||||
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortPlayerController");
|
||||
return Class;
|
||||
}
|
||||
};
|
||||
@@ -66,7 +66,6 @@ void AFortPlayerControllerAthena::ServerAcknowledgePossessionHook(APlayerControl
|
||||
|
||||
if (!UpdatePlayerCustomCharacterPartsVisualizationFn)
|
||||
{
|
||||
static auto CosmeticLoadoutPCOffset = Controller->GetOffset("CosmeticLoadoutPC");
|
||||
auto CosmeticLoadout = ControllerAsFort->GetCosmeticLoadout();
|
||||
|
||||
ApplyCID(PawnAsFort, CosmeticLoadout->GetCharacter());
|
||||
@@ -80,6 +79,14 @@ void AFortPlayerControllerAthena::ServerAcknowledgePossessionHook(APlayerControl
|
||||
UFortKismetLibrary::StaticClass()->ProcessEvent(UpdatePlayerCustomCharacterPartsVisualizationFn, &PlayerStateAsFort);
|
||||
}
|
||||
|
||||
void AFortPlayerControllerAthena::ServerPlaySquadQuickChatMessage(AFortPlayerControllerAthena* PlayerController, __int64 ChatEntry, __int64 SenderID)
|
||||
{
|
||||
using UAthenaEmojiItemDefinition = UFortItemDefinition;
|
||||
|
||||
static auto EmojiComm = FindObject<UAthenaEmojiItemDefinition>("/Game/Athena/Items/Cosmetics/Dances/Emoji/Emoji_Comm.Emoji_Comm");
|
||||
PlayerController->ServerPlayEmoteItemHook(PlayerController, EmojiComm);
|
||||
}
|
||||
|
||||
void AFortPlayerControllerAthena::GetPlayerViewPointHook(AFortPlayerControllerAthena* PlayerController, FVector& Location, FRotator& Rotation)
|
||||
{
|
||||
if (auto MyFortPawn = PlayerController->GetMyFortPawn())
|
||||
|
||||
@@ -14,5 +14,6 @@ public:
|
||||
}
|
||||
|
||||
static void ServerAcknowledgePossessionHook(APlayerController* Controller, APawn* Pawn);
|
||||
static void ServerPlaySquadQuickChatMessage(AFortPlayerControllerAthena* PlayerController, __int64 ChatEntry, __int64 SenderID);
|
||||
static void GetPlayerViewPointHook(AFortPlayerControllerAthena* PlayerController, FVector& Location, FRotator& Rotation);
|
||||
};
|
||||
@@ -99,6 +99,11 @@ void AFortPlayerPawn::ServerHandlePickupHook(AFortPlayerPawn* Pawn, AFortPickup*
|
||||
Pickup->ProcessEvent(OnRep_bPickedUpFn);
|
||||
}
|
||||
|
||||
void AFortPlayerPawn::ServerHandlePickupInfoHook(AFortPlayerPawn* Pawn, AFortPickup* Pickup, __int64 Params)
|
||||
{
|
||||
return ServerHandlePickupHook(Pawn, Pickup, 0.40f, FVector(), false);
|
||||
}
|
||||
|
||||
UClass* AFortPlayerPawn::StaticClass()
|
||||
{
|
||||
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortPlayerPawn");
|
||||
|
||||
@@ -26,6 +26,7 @@ public:
|
||||
|
||||
static void ServerSendZiplineStateHook(AFortPlayerPawn* Pawn, FZiplinePawnState InZiplineState);
|
||||
static void ServerHandlePickupHook(AFortPlayerPawn* Pawn, AFortPickup* Pickup, float InFlyTime, FVector InStartDirection, bool bPlayPickupSound);
|
||||
static void ServerHandlePickupInfoHook(AFortPlayerPawn* Pawn, AFortPickup* Pickup, __int64 Params);
|
||||
|
||||
static UClass* StaticClass();
|
||||
};
|
||||
@@ -11,4 +11,10 @@ public:
|
||||
static auto AbilitySystemComponentOffset = GetOffset("AbilitySystemComponent");
|
||||
return this->Get<UAbilitySystemComponent*>(AbilitySystemComponentOffset);
|
||||
}
|
||||
|
||||
static UClass* StaticClass()
|
||||
{
|
||||
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortPlayerState");
|
||||
return Class;
|
||||
}
|
||||
};
|
||||
@@ -4,5 +4,24 @@
|
||||
|
||||
class UFortWorldItemDefinition : public UFortItemDefinition
|
||||
{
|
||||
public:
|
||||
bool CanBeDropped()
|
||||
{
|
||||
static auto bCanBeDroppedOffset = GetOffset("bCanBeDropped");
|
||||
static auto bCanBeDroppedFieldMask = GetFieldMask(GetProperty("bCanBeDropped"));
|
||||
return ReadBitfieldValue(bCanBeDroppedOffset, bCanBeDroppedFieldMask);
|
||||
}
|
||||
|
||||
bool ShouldDropOnDeath()
|
||||
{
|
||||
static auto bDropOnDeathOffset = GetOffset("bDropOnDeath");
|
||||
static auto bDropOnDeathFieldMask = GetFieldMask(GetProperty("bDropOnDeath"));
|
||||
return ReadBitfieldValue(bDropOnDeathOffset, bDropOnDeathFieldMask);
|
||||
}
|
||||
|
||||
static UClass* StaticClass()
|
||||
{
|
||||
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortWorldItemDefinition");
|
||||
return Class;
|
||||
}
|
||||
};
|
||||
@@ -23,6 +23,7 @@ struct FGameplayAbilitySpec : FFastArraySerializerItem
|
||||
static auto GameplayAbilitySpecStruct = FindObject<UClass>("/Script/GameplayAbilities.GameplayAbilitySpec");
|
||||
static auto StructSize = GameplayAbilitySpecStruct->GetPropertiesSize();
|
||||
// *(int*)(__int64(GameplayAbilitySpecStruct) + Offsets::PropertiesSize);
|
||||
LOG_INFO(LogAbility, "StructSize: {}", StructSize);
|
||||
return StructSize;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,10 +5,8 @@
|
||||
#include "Class.h"
|
||||
#include "KismetSystemLibrary.h"
|
||||
|
||||
int UObject::GetOffset(const std::string& ChildName, bool bWarnIfNotFound)
|
||||
FName* getFNameOfProp(void* Property)
|
||||
{
|
||||
auto getFNameOfProp = [](void* Property) -> FName*
|
||||
{
|
||||
FName* NamePrivate = nullptr;
|
||||
|
||||
if (Engine_Version >= 425)
|
||||
@@ -17,8 +15,41 @@ int UObject::GetOffset(const std::string& ChildName, bool bWarnIfNotFound)
|
||||
NamePrivate = &((UField*)Property)->NamePrivate;
|
||||
|
||||
return NamePrivate;
|
||||
};
|
||||
};
|
||||
|
||||
void* UObject::GetProperty(int Offset, bool bWarnIfNotFound)
|
||||
{
|
||||
for (auto CurrentClass = ClassPrivate; CurrentClass; CurrentClass = *(UClass**)(__int64(CurrentClass) + Offsets::SuperStruct))
|
||||
{
|
||||
void* Property = *(void**)(__int64(CurrentClass) + Offsets::Children);
|
||||
|
||||
if (Property)
|
||||
{
|
||||
if (*(int*)(__int64(Property) + Offsets::Offset_Internal) == Offset)
|
||||
{
|
||||
return Property;
|
||||
}
|
||||
|
||||
while (Property)
|
||||
{
|
||||
if (*(int*)(__int64(Property) + Offsets::Offset_Internal) == Offset)
|
||||
{
|
||||
return Property;
|
||||
}
|
||||
|
||||
Property = Engine_Version >= 425 ? *(void**)(__int64(Property) + 0x20) : ((UField*)Property)->Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bWarnIfNotFound)
|
||||
LOG_WARN(LogFinder, "Unable to find2{}", Offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* UObject::GetProperty(const std::string& ChildName, bool bWarnIfNotFound)
|
||||
{
|
||||
for (auto CurrentClass = ClassPrivate; CurrentClass; CurrentClass = *(UClass**)(__int64(CurrentClass) + Offsets::SuperStruct))
|
||||
{
|
||||
void* Property = *(void**)(__int64(CurrentClass) + Offsets::Children);
|
||||
@@ -31,14 +62,14 @@ int UObject::GetOffset(const std::string& ChildName, bool bWarnIfNotFound)
|
||||
|
||||
if (PropName == ChildName)
|
||||
{
|
||||
return *(int*)(__int64(Property) + Offsets::Offset_Internal);
|
||||
return Property;
|
||||
}
|
||||
|
||||
while (Property)
|
||||
{
|
||||
if (PropName == ChildName)
|
||||
{
|
||||
return *(int*)(__int64(Property) + Offsets::Offset_Internal);
|
||||
return Property;
|
||||
}
|
||||
|
||||
Property = Engine_Version >= 425 ? *(void**)(__int64(Property) + 0x20) : ((UField*)Property)->Next;
|
||||
@@ -53,6 +84,26 @@ int UObject::GetOffset(const std::string& ChildName, bool bWarnIfNotFound)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UObject::GetOffset(const std::string& ChildName, bool bWarnIfNotFound)
|
||||
{
|
||||
auto Property = GetProperty(ChildName, bWarnIfNotFound);
|
||||
|
||||
if (!Property)
|
||||
return 0;
|
||||
|
||||
return *(int*)(__int64(Property) + Offsets::Offset_Internal);
|
||||
}
|
||||
|
||||
bool UObject::ReadBitfieldValue(int Offset, uint8_t FieldMask)
|
||||
{
|
||||
return ReadBitfield(this->GetPtr<PlaceholderBitfield>(Offset), FieldMask);
|
||||
}
|
||||
|
||||
void UObject::SetBitfieldValue(int Offset, uint8_t FieldMask, bool NewValue)
|
||||
{
|
||||
SetBitfield(this->GetPtr<PlaceholderBitfield>(Offset), FieldMask, NewValue);
|
||||
}
|
||||
|
||||
std::string UObject::GetFullName()
|
||||
{
|
||||
return ClassPrivate ? ClassPrivate->GetName() + " " + UKismetSystemLibrary::GetPathName(this).ToString() : "NoClassPrivate";
|
||||
@@ -73,8 +124,8 @@ bool UObject::IsA(UClass* otherClass)
|
||||
return false;
|
||||
}
|
||||
|
||||
class UClass* UObject::StaticClass()
|
||||
/* class UClass* UObject::StaticClass()
|
||||
{
|
||||
static auto Class = FindObject<UClass>("/Script/CoreUObject.Object");
|
||||
return Class;
|
||||
}
|
||||
} */
|
||||
@@ -44,11 +44,19 @@ public:
|
||||
|
||||
bool IsA(UClass* Other);
|
||||
|
||||
void* GetProperty(int Offset, bool bWarnIfNotFound = true);
|
||||
void* GetProperty(const std::string& ChildName, bool bWarnIfNotFound = true);
|
||||
int GetOffset(const std::string& ChildName, bool bWarnIfNotFound = true);
|
||||
|
||||
template <typename T = UObject*>
|
||||
T& Get(int Offset) { return *(T*)(__int64(this) + Offset); }
|
||||
|
||||
bool ReadBitfieldValue(int Offset, uint8_t FieldMask);
|
||||
bool ReadBitfieldValue(const std::string& ChildName, uint8_t FieldMask) { return ReadBitfieldValue(GetOffset(ChildName), FieldMask); }
|
||||
|
||||
void SetBitfieldValue(int Offset, uint8_t FieldMask, bool NewValue);
|
||||
void SetBitfieldValue(const std::string& ChildName, uint8_t FieldMask, bool NewValue) { return SetBitfieldValue(GetOffset(ChildName), FieldMask, NewValue); }
|
||||
|
||||
template <typename T = UObject*>
|
||||
T& GetCached(const std::string& ChildName)
|
||||
{
|
||||
@@ -81,5 +89,5 @@ public:
|
||||
template <typename T = UObject*>
|
||||
T* GetPtr(const std::string& ChildName) { return GetPtr<T>(GetOffset(ChildName)); }
|
||||
|
||||
static class UClass* StaticClass();
|
||||
// static class UClass* StaticClass();
|
||||
};
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "ai.h"
|
||||
#include "BuildingActor.h"
|
||||
#include "FortPlaysetItemDefinition.h"
|
||||
#include "FortGameModeAthena.h"
|
||||
|
||||
void Addresses::SetupVersion()
|
||||
{
|
||||
@@ -192,6 +193,7 @@ void Addresses::FindAll()
|
||||
Addresses::AddNavigationSystemToWorld = FindAddNavigationSystemToWorld();
|
||||
Addresses::NavSystemCleanUp = FindNavSystemCleanUp();
|
||||
Addresses::LoadPlayset = FindLoadPlayset();
|
||||
Addresses::SetZoneToIndex = FindSetZoneToIndex();
|
||||
}
|
||||
|
||||
void Addresses::Print()
|
||||
@@ -228,6 +230,7 @@ void Addresses::Print()
|
||||
LOG_INFO(LogDev, "AddNavigationSystemToWorld: 0x{:x}", AddNavigationSystemToWorld - Base);
|
||||
LOG_INFO(LogDev, "NavSystemCleanUp: 0x{:x}", NavSystemCleanUp - Base);
|
||||
LOG_INFO(LogDev, "LoadPlayset: 0x{:x}", LoadPlayset - Base);
|
||||
LOG_INFO(LogDev, "SetZoneToIndex: 0x{:x}", SetZoneToIndex - Base);
|
||||
}
|
||||
|
||||
void Offsets::FindAll()
|
||||
@@ -299,6 +302,7 @@ void Addresses::Init()
|
||||
AddNavigationSystemToWorldOriginal = decltype(AddNavigationSystemToWorldOriginal)(AddNavigationSystemToWorld);
|
||||
NavSystemCleanUpOriginal = decltype(NavSystemCleanUpOriginal)(Addresses::NavSystemCleanUp);
|
||||
LoadPlaysetOriginal = decltype(LoadPlaysetOriginal)(Addresses::LoadPlayset);
|
||||
AFortGameModeAthena::SetZoneToIndexOriginal = decltype(AFortGameModeAthena::SetZoneToIndexOriginal)(Addresses::SetZoneToIndex);
|
||||
|
||||
// if (Engine_Version >= 421) ChunkedObjects = decltype(ChunkedObjects)(ObjectArray);
|
||||
// else UnchunkedObjects = decltype(UnchunkedObjects)(ObjectArray);
|
||||
|
||||
@@ -40,6 +40,7 @@ namespace Addresses
|
||||
extern inline uint64 AddNavigationSystemToWorld = 0;
|
||||
extern inline uint64 NavSystemCleanUp = 0;
|
||||
extern inline uint64 LoadPlayset = 0;
|
||||
extern inline uint64 SetZoneToIndex = 0;
|
||||
|
||||
void SetupVersion(); // Finds Engine Version
|
||||
void FindAll();
|
||||
|
||||
@@ -154,6 +154,20 @@ DWORD WINAPI Main(LPVOID)
|
||||
Hooking::MinHook::Hook(GameModeDefault, FindObject<UFunction>(L"/Script/Engine.GameModeBase.HandleStartingNewPlayer"), AFortGameModeAthena::Athena_HandleStartingNewPlayerHook,
|
||||
(PVOID*)&AFortGameModeAthena::Athena_HandleStartingNewPlayerOriginal, false);
|
||||
|
||||
static auto ControllerServerAttemptInteractFn = FindObject<UFunction>("/Script/FortniteGame.FortPlayerController.ServerAttemptInteract");
|
||||
|
||||
if (ControllerServerAttemptInteractFn)
|
||||
{
|
||||
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, ControllerServerAttemptInteractFn, AFortPlayerController::ServerAttemptInteractHook,
|
||||
(PVOID*)&AFortPlayerController::ServerAttemptInteractOriginal, false, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Hooking::MinHook::Hook(FindObject("/Script/FortniteGame.Default__FortControllerComponent_Interaction"),
|
||||
FindObject<UFunction>("/Script/FortniteGame.FortControllerComponent_Interaction.ServerAttemptInteract"),
|
||||
AFortPlayerController::ServerAttemptInteractHook, (PVOID*)&AFortPlayerController::ServerAttemptInteractOriginal, false, true);
|
||||
}
|
||||
|
||||
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.ServerExecuteInventoryItem"),
|
||||
AFortPlayerController::ServerExecuteInventoryItemHook, nullptr, false);
|
||||
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.ServerPlayEmoteItem"),
|
||||
@@ -168,13 +182,25 @@ DWORD WINAPI Main(LPVOID)
|
||||
AFortPlayerController::ServerEndEditingBuildingActorHook, nullptr, false);
|
||||
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/Engine.PlayerController.ServerAcknowledgePossession"),
|
||||
AFortPlayerControllerAthena::ServerAcknowledgePossessionHook, nullptr, false);
|
||||
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerAthena.ServerPlaySquadQuickChatMessage"),
|
||||
AFortPlayerControllerAthena::ServerPlaySquadQuickChatMessage, nullptr, false);
|
||||
|
||||
Hooking::MinHook::Hook(FortPlayerPawnAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerPawn.ServerSendZiplineState"),
|
||||
AFortPlayerPawn::ServerSendZiplineStateHook, nullptr, false);
|
||||
|
||||
static auto ServerHandlePickupInfoFn = FindObject<UFunction>("/Script/FortniteGame.FortPlayerPawn.ServerHandlePickupInfo");
|
||||
|
||||
if (ServerHandlePickupInfoFn)
|
||||
{
|
||||
Hooking::MinHook::Hook(FortPlayerPawnAthenaDefault, ServerHandlePickupInfoFn, AFortPlayerPawn::ServerHandlePickupInfoHook, nullptr, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Hooking::MinHook::Hook(FortPlayerPawnAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerPawn.ServerHandlePickup"),
|
||||
AFortPlayerPawn::ServerHandlePickupHook, nullptr, false);
|
||||
}
|
||||
|
||||
if (false)
|
||||
if (Globals::bAbilitiesEnabled)
|
||||
{
|
||||
Hooking::MinHook::Hook(FortAbilitySystemComponentAthenaDefault, FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerTryActivateAbility"),
|
||||
UAbilitySystemComponent::ServerTryActivateAbilityHook, nullptr, false);
|
||||
@@ -197,6 +223,7 @@ DWORD WINAPI Main(LPVOID)
|
||||
// Hooking::MinHook::Hook((PVOID)Addresses::OnDamageServer, (PVOID)ABuildingActor::OnDamageServerHook, (PVOID*)&ABuildingActor::OnDamageServerOriginal);
|
||||
// Hooking::MinHook::Hook((PVOID)Addresses::CollectGarbage, (PVOID)CollectGarbageHook, nullptr);
|
||||
Hooking::MinHook::Hook((PVOID)Addresses::PickTeam, (PVOID)AFortGameModeAthena::Athena_PickTeamHook, nullptr);
|
||||
Hooking::MinHook::Hook((PVOID)Addresses::SetZoneToIndex, (PVOID)AFortGameModeAthena::SetZoneToIndexHook, (PVOID*)&AFortGameModeAthena::SetZoneToIndexOriginal);
|
||||
|
||||
srand(time(0));
|
||||
|
||||
|
||||
@@ -265,9 +265,20 @@ static inline uint64 FindNoMCP()
|
||||
// return (uintptr_t)GetModuleHandleW(0) + 0x161d600; // 10.40
|
||||
}
|
||||
|
||||
static inline uint64 FindSetZoneToIndex()
|
||||
{
|
||||
if (Fortnite_Version == 14.60)
|
||||
return __int64(GetModuleHandleW(0)) + 0x207F9B0;
|
||||
|
||||
return 0;
|
||||
|
||||
auto Addr = Memcury::Scanner::FindStringRef(L"FortGameModeAthena: No MegaStorm on SafeZone[%d]. GridCellThickness is less than 1.0.");
|
||||
return FindBytes(Addr, { 0x40, 0x55 }, 30000, 0, true);
|
||||
}
|
||||
|
||||
static inline uint64 FindCollectGarbage()
|
||||
{
|
||||
return 0;
|
||||
// return 0;
|
||||
|
||||
auto Addr = Memcury::Scanner::FindStringRef(L"STAT_CollectGarbageInternal");
|
||||
return FindBytes(Addr, { 0x48, 0x89, 0x5C }, 2000, 0, true, 1);
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
namespace Globals
|
||||
{
|
||||
extern inline bool bCreative = true;
|
||||
extern inline bool bCreative = false;
|
||||
extern inline bool bGoingToPlayEvent = false;
|
||||
extern inline bool bNoMCP = false;
|
||||
extern inline bool bLateGame = false;
|
||||
extern inline bool bAbilitiesEnabled = true;
|
||||
}
|
||||
@@ -218,6 +218,9 @@ namespace Hooking
|
||||
|
||||
if (bHookExec)
|
||||
{
|
||||
if (Original)
|
||||
*Original = Exec;
|
||||
|
||||
Exec = Detour;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ inline void InitLogger()
|
||||
MakeLogger("LogPlaylist");
|
||||
MakeLogger("LogGame");
|
||||
MakeLogger("LogAI");
|
||||
MakeLogger("LogInteraction");
|
||||
}
|
||||
|
||||
#define LOG_DEBUG(loggerName, ...) \
|
||||
|
||||
@@ -134,6 +134,23 @@ struct PlaceholderBitfield
|
||||
uint8_t Eighth : 1;
|
||||
};
|
||||
|
||||
inline uint8_t GetFieldMask(void* Property)
|
||||
{
|
||||
if (!Property)
|
||||
return -1;
|
||||
|
||||
// 3 = sizeof(FieldSize) + sizeof(ByteOffset) + sizeof(ByteMask)
|
||||
|
||||
if (Engine_Version <= 420)
|
||||
return *(uint8_t*)(__int64(Property) + (112 + 3));
|
||||
else if (Engine_Version >= 421 && Engine_Version <= 424)
|
||||
return *(uint8_t*)(__int64(Property) + (112 + 3));
|
||||
else if (Engine_Version >= 425)
|
||||
return *(uint8_t*)(__int64(Property) + (120 + 3));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
inline bool ReadBitfield(void* Addr, uint8_t FieldMask)
|
||||
{
|
||||
auto Bitfield = (PlaceholderBitfield*)Addr;
|
||||
@@ -255,3 +272,11 @@ static T* Alloc(size_t Size)
|
||||
{
|
||||
return (T*)VirtualAlloc(0, Size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||
}
|
||||
|
||||
namespace MemberOffsets
|
||||
{
|
||||
namespace DeathInfo
|
||||
{
|
||||
static inline int bDBNO, Downer, FinisherOrDowner, DeathCause, Distance, DeathLocation, bInitialized, DeathTags;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user