interacting

This commit is contained in:
Milxnor
2023-03-08 21:37:55 -05:00
parent 1fd8f0f93f
commit 59c338c401
26 changed files with 432 additions and 52 deletions

View File

@@ -3,18 +3,19 @@
#include "Object.h" #include "Object.h"
#include "GameplayAbilitySpec.h" #include "GameplayAbilitySpec.h"
struct PadHex10 { char Pad[0x10]; };
struct PadHex18 { char Pad[0x18]; }; struct PadHex18 { char Pad[0x18]; };
struct PadHexA8 { char Pad[0xA8]; }; struct PadHexA8 { char Pad[0xA8]; };
struct PadHexB0 { char Pad[0xB0]; }; struct PadHexB0 { char Pad[0xB0]; };
using FPredictionKey = __int64; // PadHex18; using FPredictionKey = PadHex18;
using FGameplayEventData = __int64; // PadHexB0; using FGameplayEventData = PadHexA8;
class UAbilitySystemComponent : public UObject class UAbilitySystemComponent : public UObject
{ {
public: public:
static inline FGameplayAbilitySpecHandle* (*GiveAbilityOriginal)(UAbilitySystemComponent*, FGameplayAbilitySpecHandle*, __int64 inSpec); 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) void ClientActivateAbilityFailed(FGameplayAbilitySpecHandle AbilityToActivate, int16_t PredictionKey)
{ {

View File

@@ -46,7 +46,7 @@ void InternalServerTryActivateAbility(UAbilitySystemComponent* AbilitySystemComp
UGameplayAbility* InstancedAbility = nullptr; UGameplayAbility* InstancedAbility = nullptr;
SetBitfield(Spec, 1, true); // InputPressed = true 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)); AbilitySystemComponent->ClientActivateAbilityFailed(Handle, *(int16_t*)(__int64(PredictionKey) + CurrentOffset));
SetBitfield(Spec, 1, false); // InputPressed = false SetBitfield(Spec, 1, false); // InputPressed = false

View File

@@ -5,4 +5,9 @@
class ABuildingContainer : public ABuildingSMActor class ABuildingContainer : public ABuildingSMActor
{ {
public: public:
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.BuildingContainer");
return Class;
}
}; };

View File

@@ -18,8 +18,7 @@
#include "events.h" #include "events.h"
#include "reboot.h" #include "reboot.h"
#include "ai.h" #include "ai.h"
#include "Map.h"
static bool bFirstPlayerJoined = false;
enum class EDynamicFoundationEnabledState : uint8_t enum class EDynamicFoundationEnabledState : uint8_t
{ {
@@ -29,8 +28,6 @@ enum class EDynamicFoundationEnabledState : uint8_t
EDynamicFoundationEnabledState_MAX = 3 EDynamicFoundationEnabledState_MAX = 3
}; };
// Enum FortniteGame.EDynamicFoundationType
enum class EDynamicFoundationType : uint8_t enum class EDynamicFoundationType : uint8_t
{ {
Static = 0, Static = 0,
@@ -123,6 +120,42 @@ UObject* GetPlaylistToUse()
return Playlist; 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) bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* GameMode)
{ {
auto GameState = GameMode->GetGameStateAthena(); auto GameState = GameMode->GetGameStateAthena();
@@ -416,6 +449,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
float TimeSeconds = 35.f; // UGameplayStatics::GetTimeSeconds(GetWorld()); float TimeSeconds = 35.f; // UGameplayStatics::GetTimeSeconds(GetWorld());
LOG_INFO(LogDev, "Initializing!"); LOG_INFO(LogDev, "Initializing!");
LOG_INFO(LogDev, "GameMode 0x{:x}", __int64(GameMode));
GameState->Get<float>("WarmupCountdownEndTime") = TimeSeconds + Duration; GameState->Get<float>("WarmupCountdownEndTime") = TimeSeconds + Duration;
GameMode->Get<float>("WarmupCountdownDuration") = Duration; GameMode->Get<float>("WarmupCountdownDuration") = Duration;
@@ -622,13 +656,13 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
PlayerStateAthena->ProcessEvent(OnRep_bHasStartedPlayingFn); 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") ? 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_AthenaPlayer.GAS_AthenaPlayer") :
LoadObject<UObject>(L"/Game/Abilities/Player/Generic/Traits/DefaultPlayer/GAS_DefaultPlayer.GAS_DefaultPlayer"); 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) if (GameplayAbilitySet)
{ {
@@ -661,11 +695,12 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
unsigned char ahh[0x0028]; unsigned char ahh[0x0028];
}; };
auto& PlayerStateUniqueId = PlayerStateAthena->Get<FUniqueNetIdReplExperimental>("UniqueId"); FUniqueNetIdReplExperimental bugha{};
auto& PlayerStateUniqueId = bugha; // PlayerStateAthena->Get<FUniqueNetIdReplExperimental>("UniqueId");
// if (false) // if (false)
// if (GameMemberInfoArrayOffset != 0) // if (GameMemberInfoArrayOffset != 0)
if (Engine_Version >= 423) if (Engine_Version >= 423 && false)
{ {
struct FGameMemberInfo : public FFastArraySerializerItem struct FGameMemberInfo : public FFastArraySerializerItem
{ {
@@ -750,5 +785,19 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
UFortPlaysetItemDefinition::ShowPlayset(IslandPlayset, Portal->GetLinkedVolume()); 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); return Athena_HandleStartingNewPlayerOriginal(GameMode, NewPlayerActor);
} }
void AFortGameModeAthena::SetZoneToIndexHook(AFortGameModeAthena* GameModeAthena, int OverridePhaseMaybeIDFK)
{
LOG_INFO(LogDev, "OverridePhaseMaybeIDFK: {}", OverridePhaseMaybeIDFK);
return SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK);
}

View File

@@ -9,13 +9,17 @@ class AFortGameModeAthena : public AFortGameModePvPBase
public: public:
static inline bool (*Athena_ReadyToStartMatchOriginal)(AFortGameModeAthena* GameMode); static inline bool (*Athena_ReadyToStartMatchOriginal)(AFortGameModeAthena* GameMode);
static inline void (*Athena_HandleStartingNewPlayerOriginal)(AFortGameModeAthena* GameMode, AActor* NewPlayer); static inline void (*Athena_HandleStartingNewPlayerOriginal)(AFortGameModeAthena* GameMode, AActor* NewPlayer);
static inline void (*SetZoneToIndexOriginal)(AFortGameModeAthena* GameModeAthena, int OverridePhaseMaybeIDFK);
static bool Athena_ReadyToStartMatchHook(AFortGameModeAthena* GameMode);
static int Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint8 preferredTeam, AActor* Controller);
static void Athena_HandleStartingNewPlayerHook(AFortGameModeAthena* GameMode, AActor* NewPlayerActor);
AFortGameStateAthena* GetGameStateAthena() AFortGameStateAthena* GetGameStateAthena()
{ {
return (AFortGameStateAthena*)GetGameState(); 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);
}; };

View File

@@ -15,6 +15,8 @@ void UFortKismetLibrary::ApplyCharacterCosmetics(UObject* WorldContextObject, co
{ {
static auto fn = FindObject<UFunction>("/Script/FortniteGame.FortKismetLibrary.ApplyCharacterCosmetics"); static auto fn = FindObject<UFunction>("/Script/FortniteGame.FortKismetLibrary.ApplyCharacterCosmetics");
if (fn)
{
struct struct
{ {
UObject* WorldContextObject; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) UObject* WorldContextObject; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
@@ -28,6 +30,31 @@ void UFortKismetLibrary::ApplyCharacterCosmetics(UObject* WorldContextObject, co
if (bSuccess) if (bSuccess)
*bSuccess = UFortKismetLibrary_ApplyCharacterCosmetics_Params.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() UClass* UFortKismetLibrary::StaticClass()

View File

@@ -16,5 +16,13 @@ public:
return Get<AFortWeapon*>(CurrentWeaponOffset); return Get<AFortWeapon*>(CurrentWeaponOffset);
} }
bool IsDBNO()
{
static auto bIsDBNOFieldMask = GetFieldMask(GetProperty("bIsDBNO"));
static auto bIsDBNOOffset = GetOffset("bIsDBNO");
return ReadBitfieldValue(bIsDBNOOffset, bIsDBNOFieldMask);
}
static UClass* StaticClass(); static UClass* StaticClass();
}; };

View File

@@ -10,6 +10,11 @@
#include "ActorComponent.h" #include "ActorComponent.h"
#include "FortPlayerStateAthena.h" #include "FortPlayerStateAthena.h"
#include "globals.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) 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) void AFortPlayerController::ServerAttemptAircraftJumpHook(AFortPlayerController* PC, FRotator ClientRotation)
{ {
if (Fortnite_Version == 17.30 && Globals::bGoingToPlayEvent) if (Fortnite_Version == 17.30 && Globals::bGoingToPlayEvent)
@@ -187,6 +256,46 @@ void AFortPlayerController::ServerPlayEmoteItemHook(AFortPlayerController* Playe
GiveAbilityAndActivateOnce(PlayerState->GetAbilitySystemComponent(), &outHandle, __int64(Spec)); 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) void AFortPlayerController::ServerBeginEditingBuildingActorHook(AFortPlayerController* PlayerController, ABuildingSMActor* BuildingActorToEdit)
{ {
if (!BuildingActorToEdit || !BuildingActorToEdit->IsPlayerPlaced()) if (!BuildingActorToEdit || !BuildingActorToEdit->IsPlayerPlaced())

View File

@@ -6,6 +6,7 @@
#include "Rotator.h" #include "Rotator.h"
#include "BuildingSMActor.h" #include "BuildingSMActor.h"
#include "Stack.h"
struct FCreateBuildingActorData { uint32_t BuildingClassHandle; FVector BuildLoc; FRotator BuildRot; bool bMirrored; }; struct FCreateBuildingActorData { uint32_t BuildingClassHandle; FVector BuildLoc; FRotator BuildRot; bool bMirrored; };
@@ -27,6 +28,8 @@ struct FFortAthenaLoadout
class AFortPlayerController : public APlayerController class AFortPlayerController : public APlayerController
{ {
public: public:
static inline void (*ServerAttemptInteractOriginal)(UObject* Context, FFrame* Stack, void* Ret);
void ClientReportDamagedResourceBuilding(ABuildingSMActor* BuildingSMActor, EFortResourceType PotentialResourceType, int PotentialResourceCount, bool bDestroyed, bool bJustHitWeakspot); void ClientReportDamagedResourceBuilding(ABuildingSMActor* BuildingSMActor, EFortResourceType PotentialResourceType, int PotentialResourceCount, bool bDestroyed, bool bJustHitWeakspot);
AFortInventory*& GetWorldInventory() AFortInventory*& GetWorldInventory()
@@ -41,12 +44,6 @@ public:
return Get<AFortPawn*>(MyFortPawnOffset); return Get<AFortPawn*>(MyFortPawnOffset);
} }
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortPlayerController");
return Class;
}
FFortAthenaLoadout* GetCosmeticLoadout() FFortAthenaLoadout* GetCosmeticLoadout()
{ {
static auto CosmeticLoadoutPCOffset = this->GetOffset("CosmeticLoadoutPC", false); static auto CosmeticLoadoutPCOffset = this->GetOffset("CosmeticLoadoutPC", false);
@@ -60,13 +57,21 @@ public:
} }
static void ServerExecuteInventoryItemHook(AFortPlayerController* PlayerController, FGuid ItemGuid); 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 ServerAttemptAircraftJumpHook(AFortPlayerController* PC, FRotator ClientRotation);
static void ServerCreateBuildingActorHook(AFortPlayerController* PlayerController, FCreateBuildingActorData CreateBuildingData); static void ServerCreateBuildingActorHook(AFortPlayerController* PlayerController, FCreateBuildingActorData CreateBuildingData);
static void ServerPlayEmoteItemHook(AFortPlayerController* PlayerController, UObject* EmoteAsset); static void ServerPlayEmoteItemHook(AFortPlayerController* PlayerController, UObject* EmoteAsset);
static void ClientOnPawnDiedHook(AFortPlayerController* PlayerController, __int64 DeathReport);
static void ServerBeginEditingBuildingActorHook(AFortPlayerController* PlayerController, ABuildingSMActor* BuildingActorToEdit); static void ServerBeginEditingBuildingActorHook(AFortPlayerController* PlayerController, ABuildingSMActor* BuildingActorToEdit);
static void ServerEditBuildingActorHook(AFortPlayerController* PlayerController, ABuildingSMActor* BuildingActorToEdit, UClass* NewBuildingClass, int RotationIterations, char bMirrored); static void ServerEditBuildingActorHook(AFortPlayerController* PlayerController, ABuildingSMActor* BuildingActorToEdit, UClass* NewBuildingClass, int RotationIterations, char bMirrored);
static void ServerEndEditingBuildingActorHook(AFortPlayerController* PlayerController, ABuildingSMActor* BuildingActorToStopEditing); static void ServerEndEditingBuildingActorHook(AFortPlayerController* PlayerController, ABuildingSMActor* BuildingActorToStopEditing);
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortPlayerController");
return Class;
}
}; };

View File

@@ -66,7 +66,6 @@ void AFortPlayerControllerAthena::ServerAcknowledgePossessionHook(APlayerControl
if (!UpdatePlayerCustomCharacterPartsVisualizationFn) if (!UpdatePlayerCustomCharacterPartsVisualizationFn)
{ {
static auto CosmeticLoadoutPCOffset = Controller->GetOffset("CosmeticLoadoutPC");
auto CosmeticLoadout = ControllerAsFort->GetCosmeticLoadout(); auto CosmeticLoadout = ControllerAsFort->GetCosmeticLoadout();
ApplyCID(PawnAsFort, CosmeticLoadout->GetCharacter()); ApplyCID(PawnAsFort, CosmeticLoadout->GetCharacter());
@@ -80,6 +79,14 @@ void AFortPlayerControllerAthena::ServerAcknowledgePossessionHook(APlayerControl
UFortKismetLibrary::StaticClass()->ProcessEvent(UpdatePlayerCustomCharacterPartsVisualizationFn, &PlayerStateAsFort); 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) void AFortPlayerControllerAthena::GetPlayerViewPointHook(AFortPlayerControllerAthena* PlayerController, FVector& Location, FRotator& Rotation)
{ {
if (auto MyFortPawn = PlayerController->GetMyFortPawn()) if (auto MyFortPawn = PlayerController->GetMyFortPawn())

View File

@@ -14,5 +14,6 @@ public:
} }
static void ServerAcknowledgePossessionHook(APlayerController* Controller, APawn* Pawn); 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); static void GetPlayerViewPointHook(AFortPlayerControllerAthena* PlayerController, FVector& Location, FRotator& Rotation);
}; };

View File

@@ -99,6 +99,11 @@ void AFortPlayerPawn::ServerHandlePickupHook(AFortPlayerPawn* Pawn, AFortPickup*
Pickup->ProcessEvent(OnRep_bPickedUpFn); Pickup->ProcessEvent(OnRep_bPickedUpFn);
} }
void AFortPlayerPawn::ServerHandlePickupInfoHook(AFortPlayerPawn* Pawn, AFortPickup* Pickup, __int64 Params)
{
return ServerHandlePickupHook(Pawn, Pickup, 0.40f, FVector(), false);
}
UClass* AFortPlayerPawn::StaticClass() UClass* AFortPlayerPawn::StaticClass()
{ {
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortPlayerPawn"); static auto Class = FindObject<UClass>("/Script/FortniteGame.FortPlayerPawn");

View File

@@ -26,6 +26,7 @@ public:
static void ServerSendZiplineStateHook(AFortPlayerPawn* Pawn, FZiplinePawnState InZiplineState); static void ServerSendZiplineStateHook(AFortPlayerPawn* Pawn, FZiplinePawnState InZiplineState);
static void ServerHandlePickupHook(AFortPlayerPawn* Pawn, AFortPickup* Pickup, float InFlyTime, FVector InStartDirection, bool bPlayPickupSound); 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(); static UClass* StaticClass();
}; };

View File

@@ -11,4 +11,10 @@ public:
static auto AbilitySystemComponentOffset = GetOffset("AbilitySystemComponent"); static auto AbilitySystemComponentOffset = GetOffset("AbilitySystemComponent");
return this->Get<UAbilitySystemComponent*>(AbilitySystemComponentOffset); return this->Get<UAbilitySystemComponent*>(AbilitySystemComponentOffset);
} }
static UClass* StaticClass()
{
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortPlayerState");
return Class;
}
}; };

View File

@@ -4,5 +4,24 @@
class UFortWorldItemDefinition : public UFortItemDefinition 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;
}
}; };

View File

@@ -23,6 +23,7 @@ struct FGameplayAbilitySpec : FFastArraySerializerItem
static auto GameplayAbilitySpecStruct = FindObject<UClass>("/Script/GameplayAbilities.GameplayAbilitySpec"); static auto GameplayAbilitySpecStruct = FindObject<UClass>("/Script/GameplayAbilities.GameplayAbilitySpec");
static auto StructSize = GameplayAbilitySpecStruct->GetPropertiesSize(); static auto StructSize = GameplayAbilitySpecStruct->GetPropertiesSize();
// *(int*)(__int64(GameplayAbilitySpecStruct) + Offsets::PropertiesSize); // *(int*)(__int64(GameplayAbilitySpecStruct) + Offsets::PropertiesSize);
LOG_INFO(LogAbility, "StructSize: {}", StructSize);
return StructSize; return StructSize;
} }

View File

@@ -5,9 +5,7 @@
#include "Class.h" #include "Class.h"
#include "KismetSystemLibrary.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; FName* NamePrivate = nullptr;
@@ -19,6 +17,39 @@ int UObject::GetOffset(const std::string& ChildName, bool bWarnIfNotFound)
return 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)) for (auto CurrentClass = ClassPrivate; CurrentClass; CurrentClass = *(UClass**)(__int64(CurrentClass) + Offsets::SuperStruct))
{ {
void* Property = *(void**)(__int64(CurrentClass) + Offsets::Children); void* Property = *(void**)(__int64(CurrentClass) + Offsets::Children);
@@ -31,14 +62,14 @@ int UObject::GetOffset(const std::string& ChildName, bool bWarnIfNotFound)
if (PropName == ChildName) if (PropName == ChildName)
{ {
return *(int*)(__int64(Property) + Offsets::Offset_Internal); return Property;
} }
while (Property) while (Property)
{ {
if (PropName == ChildName) if (PropName == ChildName)
{ {
return *(int*)(__int64(Property) + Offsets::Offset_Internal); return Property;
} }
Property = Engine_Version >= 425 ? *(void**)(__int64(Property) + 0x20) : ((UField*)Property)->Next; 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; 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() std::string UObject::GetFullName()
{ {
return ClassPrivate ? ClassPrivate->GetName() + " " + UKismetSystemLibrary::GetPathName(this).ToString() : "NoClassPrivate"; return ClassPrivate ? ClassPrivate->GetName() + " " + UKismetSystemLibrary::GetPathName(this).ToString() : "NoClassPrivate";
@@ -73,8 +124,8 @@ bool UObject::IsA(UClass* otherClass)
return false; return false;
} }
class UClass* UObject::StaticClass() /* class UClass* UObject::StaticClass()
{ {
static auto Class = FindObject<UClass>("/Script/CoreUObject.Object"); static auto Class = FindObject<UClass>("/Script/CoreUObject.Object");
return Class; return Class;
} } */

View File

@@ -44,11 +44,19 @@ public:
bool IsA(UClass* Other); 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); int GetOffset(const std::string& ChildName, bool bWarnIfNotFound = true);
template <typename T = UObject*> template <typename T = UObject*>
T& Get(int Offset) { return *(T*)(__int64(this) + Offset); } 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*> template <typename T = UObject*>
T& GetCached(const std::string& ChildName) T& GetCached(const std::string& ChildName)
{ {
@@ -81,5 +89,5 @@ public:
template <typename T = UObject*> template <typename T = UObject*>
T* GetPtr(const std::string& ChildName) { return GetPtr<T>(GetOffset(ChildName)); } T* GetPtr(const std::string& ChildName) { return GetPtr<T>(GetOffset(ChildName)); }
static class UClass* StaticClass(); // static class UClass* StaticClass();
}; };

View File

@@ -16,6 +16,7 @@
#include "ai.h" #include "ai.h"
#include "BuildingActor.h" #include "BuildingActor.h"
#include "FortPlaysetItemDefinition.h" #include "FortPlaysetItemDefinition.h"
#include "FortGameModeAthena.h"
void Addresses::SetupVersion() void Addresses::SetupVersion()
{ {
@@ -192,6 +193,7 @@ void Addresses::FindAll()
Addresses::AddNavigationSystemToWorld = FindAddNavigationSystemToWorld(); Addresses::AddNavigationSystemToWorld = FindAddNavigationSystemToWorld();
Addresses::NavSystemCleanUp = FindNavSystemCleanUp(); Addresses::NavSystemCleanUp = FindNavSystemCleanUp();
Addresses::LoadPlayset = FindLoadPlayset(); Addresses::LoadPlayset = FindLoadPlayset();
Addresses::SetZoneToIndex = FindSetZoneToIndex();
} }
void Addresses::Print() void Addresses::Print()
@@ -228,6 +230,7 @@ void Addresses::Print()
LOG_INFO(LogDev, "AddNavigationSystemToWorld: 0x{:x}", AddNavigationSystemToWorld - Base); LOG_INFO(LogDev, "AddNavigationSystemToWorld: 0x{:x}", AddNavigationSystemToWorld - Base);
LOG_INFO(LogDev, "NavSystemCleanUp: 0x{:x}", NavSystemCleanUp - Base); LOG_INFO(LogDev, "NavSystemCleanUp: 0x{:x}", NavSystemCleanUp - Base);
LOG_INFO(LogDev, "LoadPlayset: 0x{:x}", LoadPlayset - Base); LOG_INFO(LogDev, "LoadPlayset: 0x{:x}", LoadPlayset - Base);
LOG_INFO(LogDev, "SetZoneToIndex: 0x{:x}", SetZoneToIndex - Base);
} }
void Offsets::FindAll() void Offsets::FindAll()
@@ -299,6 +302,7 @@ void Addresses::Init()
AddNavigationSystemToWorldOriginal = decltype(AddNavigationSystemToWorldOriginal)(AddNavigationSystemToWorld); AddNavigationSystemToWorldOriginal = decltype(AddNavigationSystemToWorldOriginal)(AddNavigationSystemToWorld);
NavSystemCleanUpOriginal = decltype(NavSystemCleanUpOriginal)(Addresses::NavSystemCleanUp); NavSystemCleanUpOriginal = decltype(NavSystemCleanUpOriginal)(Addresses::NavSystemCleanUp);
LoadPlaysetOriginal = decltype(LoadPlaysetOriginal)(Addresses::LoadPlayset); LoadPlaysetOriginal = decltype(LoadPlaysetOriginal)(Addresses::LoadPlayset);
AFortGameModeAthena::SetZoneToIndexOriginal = decltype(AFortGameModeAthena::SetZoneToIndexOriginal)(Addresses::SetZoneToIndex);
// if (Engine_Version >= 421) ChunkedObjects = decltype(ChunkedObjects)(ObjectArray); // if (Engine_Version >= 421) ChunkedObjects = decltype(ChunkedObjects)(ObjectArray);
// else UnchunkedObjects = decltype(UnchunkedObjects)(ObjectArray); // else UnchunkedObjects = decltype(UnchunkedObjects)(ObjectArray);

View File

@@ -40,6 +40,7 @@ namespace Addresses
extern inline uint64 AddNavigationSystemToWorld = 0; extern inline uint64 AddNavigationSystemToWorld = 0;
extern inline uint64 NavSystemCleanUp = 0; extern inline uint64 NavSystemCleanUp = 0;
extern inline uint64 LoadPlayset = 0; extern inline uint64 LoadPlayset = 0;
extern inline uint64 SetZoneToIndex = 0;
void SetupVersion(); // Finds Engine Version void SetupVersion(); // Finds Engine Version
void FindAll(); void FindAll();

View File

@@ -154,6 +154,20 @@ DWORD WINAPI Main(LPVOID)
Hooking::MinHook::Hook(GameModeDefault, FindObject<UFunction>(L"/Script/Engine.GameModeBase.HandleStartingNewPlayer"), AFortGameModeAthena::Athena_HandleStartingNewPlayerHook, Hooking::MinHook::Hook(GameModeDefault, FindObject<UFunction>(L"/Script/Engine.GameModeBase.HandleStartingNewPlayer"), AFortGameModeAthena::Athena_HandleStartingNewPlayerHook,
(PVOID*)&AFortGameModeAthena::Athena_HandleStartingNewPlayerOriginal, false); (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"), Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.ServerExecuteInventoryItem"),
AFortPlayerController::ServerExecuteInventoryItemHook, nullptr, false); AFortPlayerController::ServerExecuteInventoryItemHook, nullptr, false);
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.ServerPlayEmoteItem"), Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.ServerPlayEmoteItem"),
@@ -168,13 +182,25 @@ DWORD WINAPI Main(LPVOID)
AFortPlayerController::ServerEndEditingBuildingActorHook, nullptr, false); AFortPlayerController::ServerEndEditingBuildingActorHook, nullptr, false);
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/Engine.PlayerController.ServerAcknowledgePossession"), Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/Engine.PlayerController.ServerAcknowledgePossession"),
AFortPlayerControllerAthena::ServerAcknowledgePossessionHook, nullptr, false); 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"), Hooking::MinHook::Hook(FortPlayerPawnAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerPawn.ServerSendZiplineState"),
AFortPlayerPawn::ServerSendZiplineStateHook, nullptr, false); 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"), Hooking::MinHook::Hook(FortPlayerPawnAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerPawn.ServerHandlePickup"),
AFortPlayerPawn::ServerHandlePickupHook, nullptr, false); AFortPlayerPawn::ServerHandlePickupHook, nullptr, false);
}
if (false) if (Globals::bAbilitiesEnabled)
{ {
Hooking::MinHook::Hook(FortAbilitySystemComponentAthenaDefault, FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerTryActivateAbility"), Hooking::MinHook::Hook(FortAbilitySystemComponentAthenaDefault, FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerTryActivateAbility"),
UAbilitySystemComponent::ServerTryActivateAbilityHook, nullptr, false); 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::OnDamageServer, (PVOID)ABuildingActor::OnDamageServerHook, (PVOID*)&ABuildingActor::OnDamageServerOriginal);
// Hooking::MinHook::Hook((PVOID)Addresses::CollectGarbage, (PVOID)CollectGarbageHook, nullptr); // 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::PickTeam, (PVOID)AFortGameModeAthena::Athena_PickTeamHook, nullptr);
Hooking::MinHook::Hook((PVOID)Addresses::SetZoneToIndex, (PVOID)AFortGameModeAthena::SetZoneToIndexHook, (PVOID*)&AFortGameModeAthena::SetZoneToIndexOriginal);
srand(time(0)); srand(time(0));

View File

@@ -265,9 +265,20 @@ static inline uint64 FindNoMCP()
// return (uintptr_t)GetModuleHandleW(0) + 0x161d600; // 10.40 // 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() static inline uint64 FindCollectGarbage()
{ {
return 0; // return 0;
auto Addr = Memcury::Scanner::FindStringRef(L"STAT_CollectGarbageInternal"); auto Addr = Memcury::Scanner::FindStringRef(L"STAT_CollectGarbageInternal");
return FindBytes(Addr, { 0x48, 0x89, 0x5C }, 2000, 0, true, 1); return FindBytes(Addr, { 0x48, 0x89, 0x5C }, 2000, 0, true, 1);

View File

@@ -2,8 +2,9 @@
namespace Globals namespace Globals
{ {
extern inline bool bCreative = true; extern inline bool bCreative = false;
extern inline bool bGoingToPlayEvent = false; extern inline bool bGoingToPlayEvent = false;
extern inline bool bNoMCP = false; extern inline bool bNoMCP = false;
extern inline bool bLateGame = false; extern inline bool bLateGame = false;
extern inline bool bAbilitiesEnabled = true;
} }

View File

@@ -218,6 +218,9 @@ namespace Hooking
if (bHookExec) if (bHookExec)
{ {
if (Original)
*Original = Exec;
Exec = Detour; Exec = Detour;
return true; return true;
} }

View File

@@ -70,6 +70,7 @@ inline void InitLogger()
MakeLogger("LogPlaylist"); MakeLogger("LogPlaylist");
MakeLogger("LogGame"); MakeLogger("LogGame");
MakeLogger("LogAI"); MakeLogger("LogAI");
MakeLogger("LogInteraction");
} }
#define LOG_DEBUG(loggerName, ...) \ #define LOG_DEBUG(loggerName, ...) \

View File

@@ -134,6 +134,23 @@ struct PlaceholderBitfield
uint8_t Eighth : 1; 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) inline bool ReadBitfield(void* Addr, uint8_t FieldMask)
{ {
auto Bitfield = (PlaceholderBitfield*)Addr; 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); 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;
}
}