2.4.2 & zone times proper

This commit is contained in:
Milxnor
2023-03-21 15:20:11 -04:00
parent 6d14b42a4f
commit 97ab80fef0
36 changed files with 1237 additions and 270 deletions

View File

@@ -100,6 +100,33 @@ bool AActor::TeleportTo(const FVector& DestLocation, const FRotator& DestRotatio
return AActor_K2_TeleportTo_Params.ReturnValue;
}
bool AActor::IsActorBeingDestroyed()
{
static auto bActorIsBeingDestroyedOffset = GetOffset("bActorIsBeingDestroyed");
static auto bActorIsBeingDestroyedFieldMask = GetFieldMask(GetProperty("bActorIsBeingDestroyed"));
return ReadBitfieldValue(bActorIsBeingDestroyedOffset, bActorIsBeingDestroyedFieldMask);
}
bool AActor::IsNetStartup()
{
static auto bNetStartupOffset = GetOffset("bNetStartup");
static auto bNetStartupFieldMask = GetFieldMask(GetProperty("bNetStartup"));
return ReadBitfieldValue(bNetStartupOffset, bNetStartupFieldMask);
}
void AActor::SetOwner(AActor* Owner)
{
static auto SetOwnerFn = FindObject<UFunction>("/Script/Engine.Actor.SetOwner");
this->ProcessEvent(SetOwnerFn, &Owner);
}
bool AActor::IsAlwaysRelevant()
{
static auto bAlwaysRelevantOffset = GetOffset("bAlwaysRelevant");
static auto bAlwaysRelevantFieldMask = GetFieldMask(GetProperty("bAlwaysRelevant"));
return ReadBitfieldValue(bAlwaysRelevantOffset, bAlwaysRelevantFieldMask);
}
UClass* AActor::StaticClass()
{
static auto Class = FindObject<UClass>(L"/Script/Engine.Actor");

View File

@@ -16,6 +16,10 @@ public:
struct FRotator GetActorRotation();
void FlushNetDormancy();
bool TeleportTo(const FVector& DestLocation, const FRotator& DestRotation);
bool IsActorBeingDestroyed();
bool IsNetStartup();
bool IsAlwaysRelevant();
void SetOwner(AActor* Owner);
static class UClass* StaticClass();
};

View File

@@ -0,0 +1,11 @@
#include "Controller.h"
#include "reboot.h"
AActor* AController::GetViewTarget()
{
static auto GetViewTargetFn = FindObject<UFunction>("/Script/Engine.Controller.GetViewTarget");
AActor* ViewTarget = nullptr;
this->ProcessEvent(GetViewTargetFn, &ViewTarget);
return ViewTarget;
}

View File

@@ -5,4 +5,5 @@
class AController : public AActor
{
public:
AActor* GetViewTarget();
};

View File

@@ -4,16 +4,13 @@
#include "NameTypes.h"
#include "reboot.h"
#include "DataTable.h"
class UCurveTable : public UObject
enum class ECurveTableMode : unsigned char
{
public:
};
struct FCurveTableRowHandle
{
UCurveTable* CurveTable;
FName RowName;
Empty,
SimpleCurves,
RichCurves
};
struct FSimpleCurveKey
@@ -39,3 +36,59 @@ struct FSimpleCurve : public FRealCurve
return *(TArray<FSimpleCurveKey>*)(__int64(this) + KeysOffset);
}
};
class UCurveTable : public UObject
{
public:
static int GetCurveTableSize()
{
static auto CurveTableClass = FindObject<UClass>("/Script/Engine.CurveTable");
return CurveTableClass->GetPropertiesSize();
}
ECurveTableMode GetCurveTableMode() const
{
static auto CurveTableModeOffset = GetCurveTableSize() - 8;
return *(ECurveTableMode*)(__int64(this) + CurveTableModeOffset);
}
void* GetKey(const FName& RowName, int Index)
{
auto CurveTableMode = GetCurveTableMode();
LOG_INFO(LogDev, "RowName {} CurveTableMode {} Size {}", RowName.ComparisonIndex.Value ? RowName.ToString() : "InvalidComparision", (int)CurveTableMode, GetCurveTableSize());
if (CurveTableMode == ECurveTableMode::SimpleCurves)
{
auto& RowMap = ((UDataTable*)this)->GetRowMap<FSimpleCurve>(); // its the same offset so
auto Curve = RowMap.Find(RowName);
auto& Keys = Curve->GetKeys();
return Keys.Num() > Index ? &Curve->GetKeys().at(Index) : nullptr;
}
else if (CurveTableMode == ECurveTableMode::RichCurves)
{
}
return nullptr;
}
float GetValueOfKey(void* Key)
{
if (!Key)
return 0.f;
auto CurveTableMode = GetCurveTableMode();
if (CurveTableMode == ECurveTableMode::SimpleCurves) return ((FSimpleCurveKey*)Key)->Value;
else if (CurveTableMode == ECurveTableMode::RichCurves) return 0.f;
return 0.f;
}
};
struct FCurveTableRowHandle
{
UCurveTable* CurveTable;
FName RowName;
};

View File

@@ -41,7 +41,10 @@ enum class EDynamicFoundationType : uint8_t
void ShowFoundation(UObject* BuildingFoundation)
{
if (!BuildingFoundation)
{
LOG_WARN(LogGame, "Attempting to show invalid building foundation.");
return;
}
static auto bServerStreamedInLevelFieldMask = GetFieldMask(BuildingFoundation->GetProperty("bServerStreamedInLevel"));
static auto bServerStreamedInLevelOffset = BuildingFoundation->GetOffset("bServerStreamedInLevel");
@@ -212,9 +215,18 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
GameMode->Get<int>("WarmupRequiredPlayerCount") = 1;
{
SetPlaylist(GetPlaylistToUse());
auto PlaylistToUse = GetPlaylistToUse();
if (!PlaylistToUse)
{
LOG_ERROR(LogPlaylist, "Failed to find playlist! Proceeding, but will probably not work as expected!");
}
else
{
SetPlaylist(PlaylistToUse);
LOG_INFO(LogDev, "Set playlist!");
}
}
// if (false)
{
@@ -270,11 +282,8 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
ShowFoundation(PleasantParkGround);
}
auto PolarPeak = FindObject(("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.LF_Athena_POI_25x36"));
ShowFoundation(PolarPeak);
auto tiltedtower = FindObject("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.ShopsNew");
ShowFoundation(tiltedtower); // 7.40 specific?
ShowFoundation(FindObject("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.LF_Athena_POI_25x36")); // Polar Peak
ShowFoundation(FindObject("/Game/Athena/Maps/Athena_POI_Foundations.Athena_POI_Foundations.PersistentLevel.ShopsNew")); // Tilted Tower Shops, is this 7.40 specific?
}
else if (Fortnite_Season == 8)
@@ -298,9 +307,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
if (Fortnite_Version == 14.60 && Globals::bGoingToPlayEvent)
{
auto aircraftcarrier = FindObject("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.Lobby_Foundation3");
LOG_INFO(LogDev, "aircraftcarrier: {}", __int64(aircraftcarrier));
ShowFoundation(aircraftcarrier);
ShowFoundation(FindObject("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.Lobby_Foundation3")); // Aircraft Carrier
}
if (Fortnite_Version == 17.50) {
@@ -312,60 +319,48 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
}
if (Fortnite_Version == 17.40) {
auto AbductedCoral = FindObject(("/Game/Athena/Apollo/Maps/Apollo_Mother.Apollo_Mother.PersistentLevel.CoralPhase_02")); // Coral Castle Phases (CoralPhase_01, CoralPhase_02 and CoralPhase_03)
ShowFoundation(AbductedCoral);
auto CoralFoundation_01 = FindObject(("/Game/Athena/Apollo/Maps/Apollo_Mother.Apollo_Mother.PersistentLevel.LF_Athena_16x16_Foundation_0"));
ShowFoundation(CoralFoundation_01);
auto CoralFoundation_05 = FindObject(("/Game/Athena/Apollo/Maps/Apollo_Mother.Apollo_Mother.PersistentLevel.LF_Athena_16x16_Foundation6"));
ShowFoundation(CoralFoundation_05);
auto CoralFoundation_07 = FindObject(("/Game/Athena/Apollo/Maps/Apollo_Mother.Apollo_Mother.PersistentLevel.LF_Athena_16x16_Foundation3"));
ShowFoundation(CoralFoundation_07);
auto CoralFoundation_10 = FindObject(("/Game/Athena/Apollo/Maps/Apollo_Mother.Apollo_Mother.PersistentLevel.LF_Athena_16x16_Foundation2_1"));
ShowFoundation(CoralFoundation_10);
auto CoralFoundation_13 = FindObject(("/Game/Athena/Apollo/Maps/Apollo_Mother.Apollo_Mother.PersistentLevel.LF_Athena_16x16_Foundation4"));
ShowFoundation(CoralFoundation_13);
auto CoralFoundation_17 = FindObject(("/Game/Athena/Apollo/Maps/Apollo_Mother.Apollo_Mother.PersistentLevel.LF_Athena_16x16_Foundation5"));
ShowFoundation(CoralFoundation_17);
ShowFoundation(FindObject("/Game/Athena/Apollo/Maps/Apollo_Mother.Apollo_Mother.PersistentLevel.CoralPhase_02")); // Coral Castle Phases (CoralPhase_01, CoralPhase_02 and CoralPhase_03)
ShowFoundation(FindObject("/Game/Athena/Apollo/Maps/Apollo_Mother.Apollo_Mother.PersistentLevel.LF_Athena_16x16_Foundation_0")); // CoralFoundation_01
ShowFoundation(FindObject("/Game/Athena/Apollo/Maps/Apollo_Mother.Apollo_Mother.PersistentLevel.LF_Athena_16x16_Foundation6")); // CoralFoundation_05
ShowFoundation(FindObject("/Game/Athena/Apollo/Maps/Apollo_Mother.Apollo_Mother.PersistentLevel.LF_Athena_16x16_Foundation3")); // CoralFoundation_07
ShowFoundation(FindObject("/Game/Athena/Apollo/Maps/Apollo_Mother.Apollo_Mother.PersistentLevel.LF_Athena_16x16_Foundation2_1")); // CoralFoundation_10
ShowFoundation(FindObject("/Game/Athena/Apollo/Maps/Apollo_Mother.Apollo_Mother.PersistentLevel.LF_Athena_16x16_Foundation4"));
ShowFoundation(FindObject("/Game/Athena/Apollo/Maps/Apollo_Mother.Apollo_Mother.PersistentLevel.LF_Athena_16x16_Foundation5"));
}
if (Fortnite_Version == 17.30) {
auto AbductedSlurpy = FindObject(("LF_Athena_POI_50x50_C /Game/Athena/Apollo/Maps/Apollo_Mother.Apollo_Mother.PersistentLevel.Slurpy_Phase03")); // Slurpy Swamp Phases (Slurpy_Phase01, Slurpy_Phase02 and Slurpy_Phase03)
ShowFoundation(AbductedSlurpy);
ShowFoundation(FindObject("/Game/Athena/Apollo/Maps/Apollo_Mother.Apollo_Mother.PersistentLevel.Slurpy_Phase03")); // There are 1, 2 and 3
}
if (Fortnite_Season == 13)
{
auto SpawnIsland = FindObject("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.Lobby_Foundation");
ShowFoundation(SpawnIsland);
ShowFoundation(FindObject("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.Lobby_Foundation"));
// SpawnIsland->RepData->Soemthing = FoundationSetup->LobbyLocation;
}
if (Fortnite_Version == 12.41)
{
auto JS03 = FindObject(("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.LF_Athena_POI_19x19_2"));
ShowFoundation(JS03);
ShowFoundation(FindObject("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.LF_Athena_POI_19x19_2"));
ShowFoundation(FindObject("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.BP_Jerky_Head6_18"));
ShowFoundation(FindObject("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.BP_Jerky_Head5_14"));
ShowFoundation(FindObject("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.BP_Jerky_Head3_8"));
ShowFoundation(FindObject("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.BP_Jerky_Head_2"));
ShowFoundation(FindObject("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.BP_Jerky_Head4_11"));
}
auto JH00 = FindObject(("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.BP_Jerky_Head6_18"));
ShowFoundation(JH00);
if (Fortnite_Version == 11.31)
{
// There are also christmas trees & stuff but we need to find a better way to stream that because there's a lot.
auto JH01 = FindObject(("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.BP_Jerky_Head5_14"));
ShowFoundation(JH01);
auto JH02 = FindObject(("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.BP_Jerky_Head3_8"));
ShowFoundation(JH02);
auto JH03 = FindObject(("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.BP_Jerky_Head_2"));
ShowFoundation(JH03);
auto JH04 = FindObject(("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.BP_Jerky_Head4_11"));
ShowFoundation(JH04);
if (false) // If the client loads this, it says the package doesnt exist...
{
ShowFoundation(FindObject("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.LF_5x5_Galileo_Ferry_1"));
ShowFoundation(FindObject("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.LF_5x5_Galileo_Ferry_2"));
ShowFoundation(FindObject("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.LF_5x5_Galileo_Ferry_3"));
ShowFoundation(FindObject("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.LF_5x5_Galileo_Ferry_4"));
ShowFoundation(FindObject("/Game/Athena/Apollo/Maps/Apollo_POI_Foundations.Apollo_POI_Foundations.PersistentLevel.LF_5x5_Galileo_Ferry_5"));
}
}
auto PlaylistToUse = GetPlaylistToUse();
@@ -505,20 +500,6 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
LOG_INFO(LogDev, "Initialized!");
}
if (Engine_Version >= 424) // returning true is stripped on c2+
{
if (GameState->GetPlayersLeft() >= GameMode->Get<int>("WarmupRequiredPlayerCount"))
{
if (MapInfo)
{
static auto FlightInfosOffset = MapInfo->GetOffset("FlightInfos");
if (MapInfo->Get<TArray<__int64>>(FlightInfosOffset).ArrayNum <= 0)
return true;
}
}
}
static auto TeamsOffset = GameState->GetOffset("Teams");
auto& Teams = GameState->Get<TArray<UObject*>>(TeamsOffset);
@@ -540,6 +521,20 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
// return false;
}
if (Engine_Version >= 424) // returning true is stripped on c2+
{
if (GameState->GetPlayersLeft() >= GameMode->Get<int>("WarmupRequiredPlayerCount"))
{
if (MapInfo)
{
static auto FlightInfosOffset = MapInfo->GetOffset("FlightInfos");
if (MapInfo->Get<TArray<__int64>>(FlightInfosOffset).ArrayNum <= 0)
return true;
}
}
}
return Athena_ReadyToStartMatchOriginal(GameMode);
}
@@ -658,13 +653,27 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
{
bSpawnedVehicles = true;
SpawnVehicles();
/* static auto GalileoSpawnerClass = FindObject<UClass>("/Game/Athena/AI/Galileo/BP_Galileo_Spawner.BP_Galileo_Spawner_C");
auto GalileoSpawners = UGameplayStatics::GetAllActorsOfClass(GetWorld(), GalileoSpawnerClass);
LOG_INFO(LogDev, "GalileoSpawners.Num(): {}", GalileoSpawners.Num());
for (int i = 0; i < GalileoSpawners.Num(); i++)
{
auto GalileoSpawner = GalileoSpawners.at(i);
auto NewPawn = SpawnAIFromCustomizationData(GalileoSpawner->GetActorLocation(), GalileoSpawner->Get("BotData"));
} */
// SpawnVehicles();
}
auto NewPlayer = (AFortPlayerControllerAthena*)NewPlayerActor;
auto PlayerStateAthena = NewPlayer->GetPlayerStateAthena();
LOG_INFO(LogDev, "PlayerStateAthena: {}", __int64(PlayerStateAthena));
if (!PlayerStateAthena)
return Athena_HandleStartingNewPlayerOriginal(GameMode, NewPlayerActor);
@@ -677,7 +686,7 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
{
auto CharacterParts = PlayerStateAthena->GetPtr<__int64>("CharacterParts");
static auto PartsOffset = FindOffsetStruct("/Script/FortniteGame.CustomCharacterParts", "Parts");
static auto PartsOffset = FindOffsetStruct("/Script/FortniteGame.CustomCharacterParts", "Parts", false);
auto Parts = (UObject**)(__int64(CharacterParts) + PartsOffset); // UCustomCharacterPart* Parts[0x6]
static auto headPart = LoadObject("/Game/Characters/CharacterParts/Female/Medium/Heads/F_Med_Head1.F_Med_Head1");
@@ -695,8 +704,6 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
PlayerStateAthena->GetSquadId() = PlayerStateAthena->GetTeamIndex() - 2;
// if (false)
{
// idk if this is needed
static auto bHasServerFinishedLoadingOffset = NewPlayer->GetOffset("bHasServerFinishedLoading");
@@ -706,13 +713,13 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
NewPlayer->ProcessEvent(OnRep_bHasServerFinishedLoadingFn);
static auto bHasStartedPlayingOffset = PlayerStateAthena->GetOffset("bHasStartedPlaying");
PlayerStateAthena->Get<bool>(bHasStartedPlayingOffset) = true; // this is a bitfield!!!
static auto bHasStartedPlayingFieldMask = GetFieldMask(PlayerStateAthena->GetProperty("bHasStartedPlaying"));
PlayerStateAthena->SetBitfieldValue(bHasStartedPlayingOffset, bHasStartedPlayingFieldMask, true);
static auto OnRep_bHasStartedPlayingFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerState.OnRep_bHasStartedPlaying");
PlayerStateAthena->ProcessEvent(OnRep_bHasStartedPlayingFn);
}
// LOG_INFO(LogDev, "Old ID: {}", PlayerStateAthena->GetWorldPlayerId());
LOG_INFO(LogDev, "Old ID: {}", PlayerStateAthena->GetWorldPlayerId());
// if (PlayerStateAthena->GetWorldPlayerId() == -1)
{
@@ -754,16 +761,17 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
}
}
static auto GameMemberInfoArrayOffset = GameState->GetOffset("GameMemberInfoArray", false);
struct FUniqueNetIdReplExperimental
{
unsigned char ahh[0x0028];
};
FUniqueNetIdReplExperimental bugha{};
FUniqueNetIdReplExperimental Bugha{};
auto& PlayerStateUniqueId = PlayerStateAthena->Get<FUniqueNetIdReplExperimental>("UniqueId");
{
static auto GameMemberInfoArrayOffset = GameState->GetOffset("GameMemberInfoArray", false);
// if (false)
// if (GameMemberInfoArrayOffset != 0)
if (Engine_Version >= 423)
@@ -811,6 +819,7 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
((TArray<FGameMemberInfo>*)(__int64(GameMemberInfoArray) + GameMemberInfoArray_MembersOffset))->Add(*GameMemberInfo, GameMemberInfoStructSize);
GameMemberInfoArray->MarkArrayDirty();
}
}
if (Globals::bCreative)
{
@@ -920,12 +929,18 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
}
}
static auto SpawnActorDataListOffset = GameMode->GetOffset("SpawnActorDataList", false);
LOG_INFO(LogDev, "HandleStartingNewPlayer end");
if (SpawnActorDataListOffset != 0)
if (Engine_Version < 420)
{
auto& SpawnActorDataList = GameMode->Get<TArray<__int64>>(SpawnActorDataListOffset);
LOG_INFO(LogDev, "SpawnActorDataList.Num(): {}", SpawnActorDataList.Num());
static auto QuickBarsOffset = NewPlayer->GetOffset("QuickBars", false);
if (QuickBarsOffset != 0)
{
static auto FortQuickBarsClass = FindObject<UClass>("/Script/FortniteGame.FortQuickBars");
NewPlayer->Get<AActor*>(QuickBarsOffset) = GetWorld()->SpawnActor<AActor>(FortQuickBarsClass);
NewPlayer->Get<AActor*>(QuickBarsOffset)->SetOwner(NewPlayer);
}
}
return Athena_HandleStartingNewPlayerOriginal(GameMode, NewPlayerActor);

View File

@@ -35,6 +35,8 @@ void AFortGameStateAthena::OnRep_CurrentPlaylistInfo()
else
{
static auto OnRep_CurrentPlaylistInfo = FindObject<UFunction>("/Script/FortniteGame.FortGameStateAthena.OnRep_CurrentPlaylistInfo");
if (OnRep_CurrentPlaylistInfo)
this->ProcessEvent(OnRep_CurrentPlaylistInfo);
}
}

View File

@@ -6,7 +6,7 @@ UFortItem* CreateItemInstance(AFortPlayerController* PlayerController, UFortItem
{
UFortItem* NewItemInstance = ItemDefinition->CreateTemporaryItemInstanceBP(Count);
if (NewItemInstance)
if (NewItemInstance && PlayerController)
NewItemInstance->SetOwningControllerForTemporaryItem(PlayerController);
return NewItemInstance;
@@ -96,23 +96,24 @@ std::pair<std::vector<UFortItem*>, std::vector<UFortItem*>> AFortInventory::AddI
Count = OverStack > 0 ? OverStack : Count;
auto PlayerController = Cast<AFortPlayerController>(GetOwner());
auto PlayerController = Cast<APlayerController>(GetOwner());
if (!PlayerController)
return std::make_pair(NewItemInstances, ModifiedItemInstances);
if (OverStack > 0 && !bAllowMultipleStacks)
{
auto Pawn = PlayerController->GetMyFortPawn();
auto Pawn = PlayerController->GetPawn();
if (!Pawn)
return std::make_pair(NewItemInstances, ModifiedItemInstances);
AFortPickup::SpawnPickup(ItemDefinition, Pawn->GetActorLocation(), Count, EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::Unset, -1, Pawn);
AFortPickup::SpawnPickup(ItemDefinition, Pawn->GetActorLocation(), Count, EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::Unset, -1, Cast<AFortPawn>(Pawn));
return std::make_pair(NewItemInstances, ModifiedItemInstances);
}
UFortItem* NewItemInstance = CreateItemInstance(PlayerController, ItemDefinition, Count);
auto FortPlayerController = Cast<AFortPlayerController>(PlayerController);
UFortItem* NewItemInstance = CreateItemInstance(FortPlayerController, ItemDefinition, Count);
if (NewItemInstance)
{
@@ -132,6 +133,36 @@ std::pair<std::vector<UFortItem*>, std::vector<UFortItem*>> AFortInventory::AddI
ItemInstances.Add(NewItemInstance);
GetItemList().GetReplicatedEntries().Add(*NewItemInstance->GetItemEntry(), FortItemEntrySize);
if (FortPlayerController && Engine_Version < 420)
{
static auto QuickBarsOffset = FortPlayerController->GetOffset("QuickBars", false);
auto QuickBars = FortPlayerController->Get<AActor*>(QuickBarsOffset);
enum class EFortQuickBars : uint8_t
{
Primary = 0,
Secondary = 1,
Max_None = 2,
EFortQuickBars_MAX = 3
};
struct
{
FGuid Item; // (Parm, IsPlainOldData)
EFortQuickBars InQuickBar; // (Parm, ZeroConstructor, IsPlainOldData)
int Slot; // (Parm, ZeroConstructor, IsPlainOldData)
}
AFortQuickBars_ServerAddItemInternal_Params
{
NewItemInstance->GetItemEntry()->GetItemGuid(),
IsPrimaryQuickbar(ItemDefinition) ? EFortQuickBars ::Primary : EFortQuickBars::Secondary,
-1
};
static auto ServerAddItemInternalFn = FindObject<UFunction>("/Script/FortniteGame.FortQuickBars.ServerAddItemInternal");
QuickBars->ProcessEvent(ServerAddItemInternalFn, &AFortQuickBars_ServerAddItemInternal_Params);
}
if (bShouldUpdate)
*bShouldUpdate = true;
}

View File

@@ -4,6 +4,77 @@
#include "KismetMathLibrary.h"
#include "FortWeaponItemDefinition.h"
static FFortLootTierData* GetLootTierData2(std::vector<FFortLootTierData*>& LootTierData, bool bPrint)
{
float TotalWeight = 0;
for (auto Item : LootTierData)
{
TotalWeight += Item->GetWeight();
}
float RandomNumber = TotalWeight * (rand() * 0.000030518509); // UKismetMathLibrary::RandomFloatInRange(0, TotalWeight); // is -1 needed?
FFortLootTierData* SelectedItem = nullptr;
if (bPrint)
{
std::cout << std::format("TotalWeight: {}\n", TotalWeight);
}
for (auto Item : LootTierData)
{
if (bPrint)
{
std::cout << std::format("Rand: {} Weight: {}\n", RandomNumber, Item->GetWeight());
}
if (RandomNumber <= Item->GetWeight())
{
SelectedItem = Item;
break;
}
RandomNumber -= Item->GetWeight();
}
if (!SelectedItem)
return GetLootTierData2(LootTierData, bPrint);
return SelectedItem;
}
static FFortLootPackageData* GetLootPackage2(std::vector<FFortLootPackageData*>& LootPackages)
{
float TotalWeight = 0;
for (auto Item : LootPackages)
{
TotalWeight += Item->GetWeight();
}
float RandomNumber = TotalWeight * (rand() * 0.000030518509); // UKismetMathLibrary::RandomFloatInRange(0, TotalWeight); // is -1 needed?
FFortLootPackageData* SelectedItem = nullptr;
for (auto Item : LootPackages)
{
if (RandomNumber <= Item->GetWeight())
{
SelectedItem = Item;
break;
}
RandomNumber -= Item->GetWeight();
}
if (!SelectedItem)
return GetLootPackage2(LootPackages);
return SelectedItem;
}
static FFortLootTierData* GetLootTierData(std::vector<FFortLootTierData*>& LootTierData, bool bPrint)
{
float TotalWeight = 0;
@@ -280,6 +351,8 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, bool bPrint, int recurs
LOG_INFO(LogLoot, "randomNumberFloat: {} randomNumberFloored: {}", randomNumberFloat, randomNumberFloored);
TierGroupLP = TierGroupLPs.at(randomNumberFloored); */
TierGroupLP = TierGroupLPs.at(i - NumLootPackageDrops); // Once we fix chapter 2 loot package drops, we can use this
}
else
{

View File

@@ -73,9 +73,61 @@ void AFortPlayerController::ServerExecuteInventoryItemHook(AFortPlayerController
if (!ItemDefinition)
return;
if (Engine_Version < 420) // wtf
{
static auto CurrentWeaponListOffset = Pawn->GetOffset("CurrentWeaponList");
auto& CurrentWeaponList = Pawn->Get<TArray<AFortWeapon*>>(CurrentWeaponListOffset);
CurrentWeaponList.Data = nullptr;
CurrentWeaponList.ArrayNum = 0;
CurrentWeaponList.ArrayMax = 0;
}
if (auto Weapon = Pawn->EquipWeaponDefinition((UFortWeaponItemDefinition*)ItemDefinition, ItemInstance->GetItemEntry()->GetItemGuid()))
{
if (Engine_Version < 420)
{
static auto FortWeap_BuildingToolClass = FindObject<UClass>("/Script/FortniteGame.FortWeap_BuildingTool");
if (!Weapon->IsA(FortWeap_BuildingToolClass))
return;
auto BuildingTool = Weapon;
using UBuildingEditModeMetadata = UObject;
using UFortBuildingItemDefinition = UObject;
static auto OnRep_DefaultMetadataFn = FindObject<UFunction>("/Script/FortniteGame.FortWeap_BuildingTool.OnRep_DefaultMetadata");
static auto DefaultMetadataOffset = BuildingTool->GetOffset("DefaultMetadata");
static auto RoofPiece = FindObject<UFortBuildingItemDefinition>("/Game/Items/Weapons/BuildingTools/BuildingItemData_RoofS.BuildingItemData_RoofS");
static auto FloorPiece = FindObject<UFortBuildingItemDefinition>("/Game/Items/Weapons/BuildingTools/BuildingItemData_Floor.BuildingItemData_Floor");
static auto WallPiece = FindObject<UFortBuildingItemDefinition>("/Game/Items/Weapons/BuildingTools/BuildingItemData_Wall.BuildingItemData_Wall");
static auto StairPiece = FindObject<UFortBuildingItemDefinition>("/Game/Items/Weapons/BuildingTools/BuildingItemData_Stair_W.BuildingItemData_Stair_W");
if (ItemDefinition == RoofPiece)
{
static auto RoofMetadata = FindObject<UBuildingEditModeMetadata>("/Game/Building/EditModePatterns/Roof/EMP_Roof_RoofC.EMP_Roof_RoofC");
BuildingTool->Get<UBuildingEditModeMetadata*>(DefaultMetadataOffset) = RoofMetadata;
}
else if (ItemDefinition == StairPiece)
{
static auto StairMetadata = FindObject<UBuildingEditModeMetadata>("/Game/Building/EditModePatterns/Stair/EMP_Stair_StairW.EMP_Stair_StairW");
BuildingTool->Get<UBuildingEditModeMetadata*>(DefaultMetadataOffset) = StairMetadata;
}
else if (ItemDefinition == WallPiece)
{
static auto WallMetadata = FindObject<UBuildingEditModeMetadata>("/Game/Building/EditModePatterns/Wall/EMP_Wall_Solid.EMP_Wall_Solid");
BuildingTool->Get<UBuildingEditModeMetadata*>(DefaultMetadataOffset) = WallMetadata;
}
else if (ItemDefinition == FloorPiece)
{
static auto FloorMetadata = FindObject<UBuildingEditModeMetadata>("/Game/Building/EditModePatterns/Floor/EMP_Floor_Floor.EMP_Floor_Floor");
BuildingTool->Get<UBuildingEditModeMetadata*>(DefaultMetadataOffset) = FloorMetadata;
}
BuildingTool->ProcessEvent(OnRep_DefaultMetadataFn);
}
}
}
@@ -523,7 +575,8 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
auto DeathInfo = (void*)(__int64(DeadPlayerState) + MemberOffsets::FortPlayerStateAthena::DeathInfo); // Alloc<void>(DeathInfoStructSize);
RtlSecureZeroMemory(DeathInfo, DeathInfoStructSize);
auto& Tags = DeadPawn->Get<FGameplayTagContainer>(MemberOffsets::FortPlayerPawn::CorrectTags);
auto/*&*/ Tags = MemberOffsets::FortPlayerPawn::CorrectTags == 0 ? FGameplayTagContainer()
: DeadPawn->Get<FGameplayTagContainer>(MemberOffsets::FortPlayerPawn::CorrectTags);
// *(FGameplayTagContainer*)(__int64(DeathReport) + MemberOffsets::DeathReport::Tags);
// LOG_INFO(LogDev, "Tags: {}", Tags.ToStringSimple(true));
@@ -535,6 +588,8 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
*(bool*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::bDBNO) = DeadPawn->IsDBNO();
*(uint8*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::DeathCause) = DeathCause;
*(AActor**)(__int64(DeathInfo) + MemberOffsets::DeathInfo::FinisherOrDowner) = KillerPlayerState ? KillerPlayerState : DeadPlayerState;
if (MemberOffsets::DeathInfo::DeathLocation != 0)
*(FVector*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::DeathLocation) = DeathLocation;
if (MemberOffsets::DeathInfo::DeathTags != 0)
@@ -545,6 +600,7 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
if (DeathCause == FallDamageEnumValue)
{
if (MemberOffsets::FortPlayerPawnAthena::LastFallDistance != 0)
*(float*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::Distance) = DeadPawn->Get<float>(MemberOffsets::FortPlayerPawnAthena::LastFallDistance);
}
else
@@ -552,6 +608,7 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
*(float*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::Distance) = KillerPawn ? KillerPawn->GetDistanceTo(DeadPawn) : 0;
}
if (MemberOffsets::FortPlayerState::PawnDeathLocation != 0)
DeadPlayerState->Get<FVector>(MemberOffsets::FortPlayerState::PawnDeathLocation) = DeathLocation;
static auto OnRep_DeathInfoFn = FindObject<UFunction>("/Script/FortniteGame.FortPlayerStateAthena.OnRep_DeathInfo");

View File

@@ -6,52 +6,6 @@
#include "globals.h"
#include "GameplayStatics.h"
void ApplyCID(AFortPlayerPawn* Pawn, UObject* CID)
{
if (!CID)
return;
static auto HeroDefinitionOffset = CID->GetOffset("HeroDefinition");
auto HeroDefinition = CID->Get(HeroDefinitionOffset);
using UFortHeroSpecialization = UObject;
static auto SpecializationsOffset = HeroDefinition->GetOffset("Specializations");
auto& Specializations = HeroDefinition->Get<TArray<TSoftObjectPtr<UFortHeroSpecialization>>>(SpecializationsOffset);
auto PlayerState = Pawn->GetPlayerState();
for (int i = 0; i < Specializations.Num(); i++)
{
auto& SpecializationSoft = Specializations.at(i);
auto Specialization = SpecializationSoft.Get();
if (Specialization)
{
static auto Specialization_CharacterPartsOffset = Specialization->GetOffset("CharacterParts");
auto& CharacterParts = Specialization->Get<TArray<TSoftObjectPtr<UObject>>>(Specialization_CharacterPartsOffset);
bool aa;
TArray<UObject*> CharacterPartsaa;
for (int z = 0; z < CharacterParts.Num(); z++)
{
auto& CharacterPartSoft = CharacterParts.at(z);
auto CharacterPart = CharacterPartSoft.Get();
CharacterPartsaa.Add(CharacterPart);
continue;
}
UFortKismetLibrary::ApplyCharacterCosmetics(GetWorld(), CharacterPartsaa, PlayerState, &aa);
CharacterPartsaa.Free();
}
}
}
void AFortPlayerControllerAthena::ServerGiveCreativeItemHook(AFortPlayerControllerAthena* Controller, FFortItemEntry CreativeItem)
{
// Don't worry, the validate has a check if it is a creative enabled mode or not, but we need to add a volume check.

View File

@@ -2,6 +2,55 @@
#include "FortPlayerController.h"
#include "FortPlayerStateAthena.h"
#include "FortPlayerPawn.h"
#include "SoftObjectPtr.h"
#include "FortKismetLibrary.h"
static void ApplyCID(AFortPlayerPawn* Pawn, UObject* CID)
{
if (!CID)
return;
static auto HeroDefinitionOffset = CID->GetOffset("HeroDefinition");
auto HeroDefinition = CID->Get(HeroDefinitionOffset);
using UFortHeroSpecialization = UObject;
static auto SpecializationsOffset = HeroDefinition->GetOffset("Specializations");
auto& Specializations = HeroDefinition->Get<TArray<TSoftObjectPtr<UFortHeroSpecialization>>>(SpecializationsOffset);
auto PlayerState = Pawn->GetPlayerState();
for (int i = 0; i < Specializations.Num(); i++)
{
auto& SpecializationSoft = Specializations.at(i);
auto Specialization = SpecializationSoft.Get();
if (Specialization)
{
static auto Specialization_CharacterPartsOffset = Specialization->GetOffset("CharacterParts");
auto& CharacterParts = Specialization->Get<TArray<TSoftObjectPtr<UObject>>>(Specialization_CharacterPartsOffset);
bool aa;
TArray<UObject*> CharacterPartsaa;
for (int z = 0; z < CharacterParts.Num(); z++)
{
auto& CharacterPartSoft = CharacterParts.at(z);
auto CharacterPart = CharacterPartSoft.Get();
CharacterPartsaa.Add(CharacterPart);
continue;
}
UFortKismetLibrary::ApplyCharacterCosmetics(GetWorld(), CharacterPartsaa, PlayerState, &aa);
CharacterPartsaa.Free();
}
}
}
class AFortPlayerControllerAthena : public AFortPlayerController
{

View File

@@ -43,6 +43,8 @@ void AFortPlayerPawn::ServerSendZiplineStateHook(AFortPlayerPawn* Pawn, FZipline
if (!Addrr)
Addrr = Memcury::Scanner::FindStringRef(L"ZIPLINES!! GetLocalRole()(%s) AFortPlayerPawn::OnRep_ZiplineState ZiplineState.bIsZiplining=%d").Get();
// L"%s LocalRole[%s] ZiplineState.bIsZiplining[%d]" for 18.40???
// std::cout << "Addrr: " << Addrr << '\n';
if (Addrr)

View File

@@ -3,12 +3,27 @@
#include "reboot.h"
#include "FortPlayerControllerAthena.h"
UClass* AGameModeBase::GetDefaultPawnClassForController(AController* InController)
{
static auto GetDefaultPawnClassForControllerFn = FindObject<UFunction>("/Script/Engine.GameModeBase.GetDefaultPawnClassForController");
struct
{
AController* InController; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
UClass* ReturnValue; // (Parm, OutParm, ZeroConstructor, ReturnParm, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
} AGameModeBase_GetDefaultPawnClassForController_Params{InController};
this->ProcessEvent(GetDefaultPawnClassForControllerFn, &AGameModeBase_GetDefaultPawnClassForController_Params);
return AGameModeBase_GetDefaultPawnClassForController_Params.ReturnValue;
}
APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AController* NewPlayer, AActor* StartSpot)
{
LOG_INFO(LogDev, "SpawnDefaultPawnFor: 0x{:x}!", __int64(_ReturnAddress()) - __int64(GetModuleHandleW(0)));
static auto PawnClass = FindObject<UClass>("/Game/Athena/PlayerPawn_Athena.PlayerPawn_Athena_C");
GameMode->Get<UClass*>("DefaultPawnClass") = PawnClass;
// static auto PawnClass = FindObject<UClass>("/Game/Athena/PlayerPawn_Athena.PlayerPawn_Athena_C");
// GameMode->Get<UClass*>("DefaultPawnClass") = PawnClass;
auto PawnClass = GameMode->GetDefaultPawnClassForController(NewPlayer);
static auto fn = FindObject<UFunction>(L"/Script/Engine.GameModeBase.SpawnDefaultPawnAtTransform");

View File

@@ -8,5 +8,7 @@
class AGameModeBase : public AActor // AInfo
{
public:
UClass* GetDefaultPawnClassForController(AController* InController);
static APawn* SpawnDefaultPawnForHook(AGameModeBase* GameMode, AController* NewPlayer, AActor* StartSpot);
};

View File

@@ -39,6 +39,17 @@ public:
typedef TSet<ElementType/*, KeyFuncs, SetAllocator */> ElementSetType;
ElementSetType Pairs;
FORCEINLINE ValueType& Find(const KeyType& Key)
{
for (int j = 0; j < this->Pairs.Elements.Num(); j++)
{
ElementType& Pair = this->Pairs.Elements.operator[](j).ElementData.Value;
if (Key == Pair.Key())
return Pair.Value();
}
}
};
template <typename KeyType, typename ValueType> //, typename SetAllocator, typename KeyFuncs>

View File

@@ -12,6 +12,7 @@ struct FName
FNameEntryId ComparisonIndex;
uint32 Number;
std::string ToString() const;
std::string ToString();
bool IsValid() { return ComparisonIndex.Value > 0; }

View File

@@ -0,0 +1,19 @@
#pragma once
#include "Player.h"
class UNetConnection : public UPlayer
{
public:
AActor*& GetOwningActor()
{
static auto OwningActorOffset = GetOffset("OwningActor");
return Get<AActor*>(OwningActorOffset);
}
AActor*& GetViewTarget()
{
static auto ViewTargetOffset = GetOffset("ViewTarget");
return Get<AActor*>(ViewTargetOffset);
}
};

View File

@@ -1,6 +1,9 @@
#include "NetDriver.h"
#include "reboot.h"
#include "Actor.h"
#include "NetConnection.h"
#include "GameplayStatics.h"
void UNetDriver::TickFlushHook(UNetDriver* NetDriver)
{
@@ -19,7 +22,283 @@ void UNetDriver::TickFlushHook(UNetDriver* NetDriver)
return TickFlushOriginal(NetDriver);
}
void UNetDriver::ServerReplicateActors()
int32 ServerReplicateActors_PrepConnections(UNetDriver* NetDriver)
{
auto& ClientConnections = NetDriver->GetClientConnections();
int32 NumClientsToTick = ClientConnections.Num();
bool bFoundReadyConnection = false;
for (int32 ConnIdx = 0; ConnIdx < ClientConnections.Num(); ConnIdx++)
{
UNetConnection* Connection = ClientConnections.at(ConnIdx);
// check(Connection);
// check(Connection->State == USOCK_Pending || Connection->State == USOCK_Open || Connection->State == USOCK_Closed);
// checkSlow(Connection->GetUChildConnection() == NULL);
AActor* OwningActor = Connection->GetOwningActor();
if (OwningActor != NULL) // && /* Connection->State == USOCK_Open && */ (Connection->Driver->Time - Connection->LastReceiveTime < 1.5f))
{
// check(World == OwningActor->GetWorld());
bFoundReadyConnection = true;
// the view target is what the player controller is looking at OR the owning actor itself when using beacons
Connection->GetViewTarget() = Connection->GetPlayerController() ? Connection->GetPlayerController()->GetViewTarget() : OwningActor;
}
else
{
Connection->GetViewTarget() = NULL;
}
}
return bFoundReadyConnection ? NumClientsToTick : 0;
}
enum class ENetRole : uint8_t
{
ROLE_None = 0,
ROLE_SimulatedProxy = 1,
ROLE_AutonomousProxy = 2,
ROLE_Authority = 3,
ROLE_MAX = 4
};
enum class ENetDormancy : uint8_t
{
DORM_Never = 0,
DORM_Awake = 1,
DORM_DormantAll = 2,
DORM_DormantPartial = 3,
DORM_Initial = 4,
DORN_MAX = 5,
ENetDormancy_MAX = 6
};
struct FNetworkObjectInfo
{
AActor* Actor;
/* TWeakObjectPtr<AActor> WeakActor;
double NextUpdateTime;
double LastNetReplicateTime;
float OptimalNetUpdateDelta;
float LastNetUpdateTime;
uint32 bPendingNetUpdate : 1;
uint32 bForceRelevantNextUpdate : 1;
TSet<TWeakObjectPtr<UNetConnection>> DormantConnections;
TSet<TWeakObjectPtr<UNetConnection>> RecentlyDormantConnections; */
};
static void ServerReplicateActors_BuildConsiderList(UNetDriver* NetDriver, std::vector<FNetworkObjectInfo*>& OutConsiderList)
{
TArray<AActor*> Actors = UGameplayStatics::GetAllActorsOfClass(GetWorld(), AActor::StaticClass());
/* auto& ActiveObjects = GetNetworkObjectList(NetDriver).ActiveNetworkObjects;
for (int i = 0; i < ActiveObjects.Num(); i++)
{
auto ActorInfo = ActiveObjects.GetElements().GetData()[i].ElementData.Value.Get();
auto Actor = ActorInfo->Actor; */
for (int i = 0; i < Actors.Num(); i++)
{
auto Actor = Actors.at(i);
if (!Actor)
continue;
// if (!Actor->bActorInitialized) continue;
if (Actor->IsActorBeingDestroyed())
{
continue;
}
static auto RemoteRoleOffset = Actor->GetOffset("RemoteRole");
if (Actor->Get<ENetRole>(RemoteRoleOffset) == ENetRole::ROLE_None)
{
continue;
}
static auto NetDormancyOffset = Actor->GetOffset("NetDormancy");
if (Actor->Get<ENetDormancy>(NetDormancyOffset) == ENetDormancy::DORM_Initial && Actor->IsNetStartup())
{
continue;
}
static void (*CallPreReplication)(AActor*, UNetDriver*) = decltype(CallPreReplication)(Addresses::CallPreReplication);
CallPreReplication(Actor, NetDriver);
FNetworkObjectInfo* ActorInfo = new FNetworkObjectInfo;
ActorInfo->Actor = Actor;
OutConsiderList.push_back(ActorInfo);
}
Actors.Free();
}
using UChannel = UObject;
using UActorChannel = UObject;
static UActorChannel* FindChannel(AActor* Actor, UNetConnection* Connection)
{
static auto OpenChannelsOffset = Connection->GetOffset("OpenChannels");
auto& OpenChannels = Connection->Get<TArray<UChannel*>>(OpenChannelsOffset);
static auto ActorChannelClass = FindObject<UClass>("/Script/Engine.ActorChannel");
// LOG_INFO(LogReplication, "OpenChannels.Num(): {}", OpenChannels.Num());
for (int i = 0; i < OpenChannels.Num(); i++)
{
auto Channel = OpenChannels.at(i);
if (!Channel)
continue;
// LOG_INFO(LogReplication, "[{}] Class {}", i, Channel->ClassPrivate ? Channel->ClassPrivate->GetFullName() : "InvalidObject");
if (!Channel->IsA(ActorChannelClass)) // (Channel->ClassPrivate == ActorChannelClass)
continue;
static auto ActorOffset = Channel->GetOffset("Actor");
auto ChannelActor = Channel->Get<AActor*>(ActorOffset);
// LOG_INFO(LogReplication, "[{}] {}", i, ChannelActor->GetFullName());
if (ChannelActor != Actor)
continue;
return (UActorChannel*)Channel;
}
return NULL;
}
int32 UNetDriver::ServerReplicateActors()
{
int32 Updated = 0;
++*(int*)(this + Offsets::ReplicationFrame);
const int32 NumClientsToTick = ServerReplicateActors_PrepConnections(this);
if (NumClientsToTick == 0)
{
// No connections are ready this frame
return 0;
}
// AFortWorldSettings* WorldSettings = GetFortWorldSettings(NetDriver->World);
// bool bCPUSaturated = false;
float ServerTickTime = 30.f; // Globals::MaxTickRate; // GEngine->GetMaxTickRate(DeltaSeconds);
/* if (ServerTickTime == 0.f)
{
ServerTickTime = DeltaSeconds;
}
else */
{
ServerTickTime = 1.f / ServerTickTime;
// bCPUSaturated = DeltaSeconds > 1.2f * ServerTickTime;
}
std::vector<FNetworkObjectInfo*> ConsiderList;
// ConsiderList.reserve(GetNetworkObjectList(NetDriver).ActiveNetworkObjects.Num());
// std::cout << "ConsiderList.size(): " << GetNetworkObjectList(NetDriver).ActiveNetworkObjects.Num() << '\n';
ServerReplicateActors_BuildConsiderList(this, ConsiderList);
for (int32 i = 0; i < this->GetClientConnections().Num(); i++)
{
UNetConnection* Connection = this->GetClientConnections().at(i);
if (!Connection)
continue;
if (i >= NumClientsToTick)
continue;
if (!Connection->GetViewTarget())
continue;
if (Connection->GetPlayerController())
{
static void (*SendClientAdjustment)(APlayerController*) = decltype(SendClientAdjustment)(Addresses::SendClientAdjustment);
SendClientAdjustment(Connection->GetPlayerController());
}
for (auto& ActorInfo : ConsiderList)
{
if (!ActorInfo || !ActorInfo->Actor)
continue;
auto Actor = ActorInfo->Actor;
auto Channel = FindChannel(Actor, Connection);
/* std::vector<FNetViewer> ConnectionViewers;
ConnectionViewers.push_back(ConstructNetViewer(Connection));
if (!Actor->bAlwaysRelevant && !Actor->bNetUseOwnerRelevancy && !Actor->bOnlyRelevantToOwner)
{
if (Connection && Connection->ViewTarget)
{
auto Viewer = Connection->ViewTarget;
auto Loc = Viewer->K2_GetActorLocation();
if (!IsActorRelevantToConnection(Actor, ConnectionViewers))
{
if (Channel)
CloseChannel(Channel);
continue;
}
}
} */
static UChannel* (*CreateChannel)(UNetConnection*, int, bool, int32_t) = decltype(CreateChannel)(Addresses::CreateChannel);
static __int64 (*ReplicateActor)(UActorChannel*) = decltype(ReplicateActor)(Addresses::ReplicateActor);
static __int64 (*SetChannelActor)(UActorChannel*, AActor*) = decltype(SetChannelActor)(Addresses::SetChannelActor);
if (!Channel)
{
if (Actor->IsA(APlayerController::StaticClass()) && Actor != Connection->GetPlayerController()) // isnetreelvantfor should handle this iirc
continue;
Channel = (UActorChannel*)CreateChannel(Connection, 2, true, -1);
if (Channel) {
SetChannelActor(Channel, Actor);
// Channel->Connection = Connection;
}
}
if (Channel)
ReplicateActor(Channel);
}
}
// shuffle the list of connections if not all connections were ticked
/*
if (NumClientsToTick < NetDriver->ClientConnections.Num())
{
int32 NumConnectionsToMove = NumClientsToTick;
while (NumConnectionsToMove > 0)
{
// move all the ticked connections to the end of the list so that the other connections are considered first for the next frame
UNetConnection* Connection = NetDriver->ClientConnections[0];
NetDriver->ClientConnections.RemoveAt(0, 1);
NetDriver->ClientConnections.Add(Connection);
NumConnectionsToMove--;
}
}
*/
return Updated;
}

View File

@@ -4,6 +4,8 @@
#include "UnrealString.h"
#include "World.h"
#include "NetConnection.h"
#include "Array.h"
class UWorld;
@@ -29,7 +31,13 @@ public:
static void TickFlushHook(UNetDriver* NetDriver);
TArray<UNetConnection*>& GetClientConnections()
{
static auto ClientConnectionsOffset = GetOffset("ClientConnections");
return Get<TArray<UNetConnection*>>(ClientConnectionsOffset);
}
bool InitListen(FNetworkNotify* InNotify, FURL& ListenURL, bool bReuseAddressAndPort, FString& Error) { return InitListenOriginal(this, InNotify, ListenURL, bReuseAddressAndPort, Error); }
void SetWorld(UWorld* World) { return SetWorldOriginal(this, World); }
void ServerReplicateActors();
int32 ServerReplicateActors();
};

View File

@@ -0,0 +1,14 @@
#pragma once
#include "Object.h"
#include "PlayerController.h"
class UPlayer : public UObject
{
public:
APlayerController*& GetPlayerController()
{
static auto PlayerControllerOffset = GetOffset("PlayerController");
return Get<APlayerController*>(PlayerControllerOffset);
}
};

View File

@@ -1,11 +1,11 @@
#pragma once
#include "Class.h"
#include "Actor.h"
#include "Controller.h"
#include "Rotator.h"
class APlayerController : public AActor
class APlayerController : public AController
{
public:
/* void Possess(APawn* Pawn)

View File

@@ -173,6 +173,7 @@
<ClCompile Include="BuildingTrap.cpp" />
<ClCompile Include="BuildingWeapons.cpp" />
<ClCompile Include="Class.cpp" />
<ClCompile Include="Controller.cpp" />
<ClCompile Include="DataTableFunctionLibrary.cpp" />
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="events.cpp" />
@@ -205,6 +206,7 @@
<ClCompile Include="KismetStringLibrary.cpp" />
<ClCompile Include="LevelActor.cpp" />
<ClCompile Include="NameTypes.cpp" />
<ClCompile Include="NetConnection.h" />
<ClCompile Include="NetDriver.cpp" />
<ClCompile Include="Object.cpp" />
<ClCompile Include="PlayerController.cpp" />
@@ -293,6 +295,7 @@
<ClInclude Include="OutputDevice.h" />
<ClInclude Include="Pawn.h" />
<ClInclude Include="PersistentObjectPtr.h" />
<ClInclude Include="Player.h" />
<ClInclude Include="PlayerController.h" />
<ClInclude Include="PlayerState.h" />
<ClInclude Include="Quat.h" />

View File

@@ -110,9 +110,6 @@
<ClCompile Include="events.cpp">
<Filter>Reboot\Private\Gameplay</Filter>
</ClCompile>
<ClCompile Include="addresses.cpp">
<Filter>Reboot\Private\Gameplay</Filter>
</ClCompile>
<ClCompile Include="FortPlayerControllerAthena.cpp">
<Filter>FortniteGame\Source\FortniteGame\Private\Player</Filter>
</ClCompile>
@@ -143,6 +140,15 @@
<ClCompile Include="GameState.cpp">
<Filter>Engine\Source\Runtime\Engine\Private</Filter>
</ClCompile>
<ClCompile Include="addresses.cpp">
<Filter>Reboot\Private</Filter>
</ClCompile>
<ClCompile Include="NetConnection.h">
<Filter>Engine\Source\Runtime\Engine\Classes\Engine</Filter>
</ClCompile>
<ClCompile Include="Controller.cpp">
<Filter>Engine\Source\Runtime\Engine\Private</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="log.h" />
@@ -395,9 +401,6 @@
<ClInclude Include="MegaStormManager.h">
<Filter>FortniteGame\Source\FortniteGame\Public</Filter>
</ClInclude>
<ClInclude Include="ai.h">
<Filter>Reboot\Public</Filter>
</ClInclude>
<ClInclude Include="FortVolume.h">
<Filter>FortniteGame\Source\FortniteGame\Public\Creative</Filter>
</ClInclude>
@@ -434,6 +437,12 @@
<ClInclude Include="commands.h">
<Filter>Reboot\Public</Filter>
</ClInclude>
<ClInclude Include="ai.h">
<Filter>Reboot\Public\Gameplay</Filter>
</ClInclude>
<ClInclude Include="Player.h">
<Filter>Engine\Source\Runtime\Engine\Classes\Engine</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Engine">

View File

@@ -5,6 +5,23 @@
#include "KismetStringLibrary.h"
std::string FName::ToString() const
{
static auto KismetStringLibrary = FindObject<UKismetStringLibrary>(L"/Script/Engine.Default__KismetStringLibrary");
static auto Conv_NameToString = FindObject<UFunction>(L"/Script/Engine.KismetStringLibrary.Conv_NameToString");
struct { FName InName; FString OutStr; } Conv_NameToString_Params{ *this };
KismetStringLibrary->ProcessEvent(Conv_NameToString, &Conv_NameToString_Params);
auto Str = Conv_NameToString_Params.OutStr.ToString();
// Conv_NameToString_Params.OutStr.Free();
return Str;
}
std::string FName::ToString()
{
static auto KismetStringLibrary = FindObject<UKismetStringLibrary>(L"/Script/Engine.Default__KismetStringLibrary");

View File

@@ -114,95 +114,129 @@ void Addresses::FindAll()
{
auto Base = __int64(GetModuleHandleW(0));
LOG_INFO(LogDev, "9241");
LOG_INFO(LogDev, "Finding ProcessEvent");
Addresses::ProcessEvent = FindProcessEvent();
UObject::ProcessEventOriginal = decltype(UObject::ProcessEventOriginal)(ProcessEvent);
LOG_INFO(LogDev, "151");
LOG_INFO(LogDev, "Finding StaticFindObject");
Addresses::StaticFindObject = FindStaticFindObject();
StaticFindObjectOriginal = decltype(StaticFindObjectOriginal)(StaticFindObject);
LOG_INFO(LogDev, "StaticFindObject: 0x{:x}", StaticFindObject - Base);
LOG_INFO(LogDev, "2151");
LOG_INFO(LogDev, "Finding GetPlayerViewpoint");
Addresses::GetPlayerViewpoint = FindGetPlayerViewpoint();
LOG_INFO(LogDev, "1246");
LOG_INFO(LogDev, "Finding CreateNetDriver");
Addresses::CreateNetDriver = FindCreateNetDriver();
LOG_INFO(LogDev, "2561");
LOG_INFO(LogDev, "Finding InitHost");
Addresses::InitHost = FindInitHost();
LOG_INFO(LogDev, "1341");
LOG_INFO(LogDev, "Finding PauseBeaconRequests");
Addresses::PauseBeaconRequests = FindPauseBeaconRequests();
LOG_INFO(LogDev, "1351");
LOG_INFO(LogDev, "Finding SpawnActor");
Addresses::SpawnActor = FindSpawnActor();
LOG_INFO(LogDev, "1`231");
LOG_INFO(LogDev, "Finding InitListen");
Addresses::InitListen = FindInitListen();
LOG_INFO(LogDev, "52175");
LOG_INFO(LogDev, "Finding SetWorld");
Addresses::SetWorld = FindSetWorld();
LOG_INFO(LogDev, "5432");
LOG_INFO(LogDev, "Finding Kickplayer");
Addresses::KickPlayer = FindKickPlayer();
LOG_INFO(LogDev, "123");
LOG_INFO(LogDev, "Finding TickFlush");
Addresses::TickFlush = FindTickFlush();
LOG_INFO(LogDev, "1123");
LOG_INFO(LogDev, "Finding GetNetMode");
Addresses::GetNetMode = FindGetNetMode();
LOG_INFO(LogDev, "113");
LOG_INFO(LogDev, "Finding Realloc");
Addresses::Realloc = FindRealloc();
LOG_INFO(LogDev, "1231");
LOG_INFO(LogDev, "Finding CollectGarbage");
Addresses::CollectGarbage = FindCollectGarbage();
LOG_INFO(LogDev, "112113");
LOG_INFO(LogDev, "Finding NoMCP");
Addresses::NoMCP = FindNoMCP();
LOG_INFO(LogDev, "131");
LOG_INFO(LogDev, "Finding PickTeam");
Addresses::PickTeam = FindPickTeam();
LOG_INFO(LogDev, "132");
LOG_INFO(LogDev, "Finding InternalTryActivateAbility");
Addresses::InternalTryActivateAbility = FindInternalTryActivateAbility();
LOG_INFO(LogDev, "17");
LOG_INFO(LogDev, "Finding GiveAbility");
Addresses::GiveAbility = FindGiveAbility();
LOG_INFO(LogDev, "156");
LOG_INFO(LogDev, "Finding CantBuild");
Addresses::CantBuild = FindCantBuild();
LOG_INFO(LogDev, "16");
LOG_INFO(LogDev, "Finding ReplaceBuildingActor");
Addresses::ReplaceBuildingActor = FindReplaceBuildingActor();
LOG_INFO(LogDev, "15");
LOG_INFO(LogDev, "Finding GiveAbilityAndActivateOnce");
Addresses::GiveAbilityAndActivateOnce = FindGiveAbilityAndActivateOnce();
LOG_INFO(LogDev, "14");
LOG_INFO(LogDev, "Finding OnDamageServer");
Addresses::OnDamageServer = FindOnDamageServer();
LOG_INFO(LogDev, "13");
LOG_INFO(LogDev, "Finding StaticLoadObject");
Addresses::StaticLoadObject = FindStaticLoadObject();
LOG_INFO(LogDev, "12");
LOG_INFO(LogDev, "Finding ActorGetNetMode");
Addresses::ActorGetNetMode = FindActorGetNetMode();
LOG_INFO(LogDev, "11");
LOG_INFO(LogDev, "Finding ChangeGameSessionId");
Addresses::ChangeGameSessionId = FindChangeGameSessionId();
LOG_INFO(LogDev, "10");
LOG_INFO(LogDev, "Finding DispatchRequest");
Addresses::DispatchRequest = FindDispatchRequest();
LOG_INFO(LogDev, "Finding AddNavigationSystemToWorld");
Addresses::AddNavigationSystemToWorld = FindAddNavigationSystemToWorld();
LOG_INFO(LogDev, "Finding NavSystemCleanUp");
Addresses::NavSystemCleanUp = FindNavSystemCleanUp();
LOG_INFO(LogDev, "Finding LoadPlayset");
Addresses::LoadPlayset = FindLoadPlayset();
LOG_INFO(LogDev, "Finding SetZoneToIndex");
Addresses::SetZoneToIndex = FindSetZoneToIndex();
LOG_INFO(LogDev, "Finding CompletePickupAnimation");
Addresses::CompletePickupAnimation = FindCompletePickupAnimation();
LOG_INFO(LogDev, "Finding CanActivateAbility");
Addresses::CanActivateAbility = FindCanActivateAbility();
LOG_INFO(LogDev, "Finding SpecConstructor");
Addresses::SpecConstructor = FindSpecConstructor();
LOG_INFO(LogDev, "Finding FrameStep");
Addresses::FrameStep = FindFrameStep();
LOG_INFO(LogDev, "Finding ObjectArray");
Addresses::ObjectArray = FindObjectArray();
LOG_INFO(LogDev, "Finding ReplicateActor");
Addresses::ReplicateActor = FindReplicateActor();
LOG_INFO(LogDev, "Finding SetChannelActor");
Addresses::SetChannelActor = FindSetChannelActor();
LOG_INFO(LogDev, "Finding SendClientAdjustment");
Addresses::SendClientAdjustment = FindSendClientAdjustment();
LOG_INFO(LogDev, "Finding CreateChannel");
Addresses::CreateChannel = FindCreateChannel();
LOG_INFO(LogDev, "Finding CallPreReplication");
Addresses::CallPreReplication = FindCallPreReplication();
LOG_INFO(LogDev, "Finished finding!");
}
void Addresses::Print()
@@ -245,6 +279,11 @@ void Addresses::Print()
LOG_INFO(LogDev, "SpecConstructor: 0x{:x}", SpecConstructor - Base);
LOG_INFO(LogDev, "FrameStep: 0x{:x}", FrameStep - Base);
LOG_INFO(LogDev, "ObjectArray: 0x{:x}", ObjectArray - Base);
LOG_INFO(LogDev, "ReplicateActor: 0x{:x}", ReplicateActor - Base);
LOG_INFO(LogDev, "SetChannelActor: 0x{:x}", SetChannelActor - Base);
LOG_INFO(LogDev, "SendClientAdjustment: 0x{:x}", SendClientAdjustment - Base);
LOG_INFO(LogDev, "CreateChannel: 0x{:x}", CreateChannel - Base);
LOG_INFO(LogDev, "CallPreReplication: 0x{:x}", CallPreReplication - Base);
}
void Offsets::FindAll()
@@ -254,7 +293,7 @@ void Offsets::FindAll()
Offsets::Children = Engine_Version >= 425 ? 0x50 : Offsets::SuperStruct + 8;
Offsets::PropertiesSize = Offsets::Children + 8;
if (Engine_Version == 420 || Engine_Version == 421)
if (Engine_Version >= 419 && Engine_Version <= 421)
Offsets::Func = 0xB0;
else if (Engine_Version >= 422 && Engine_Version <= 424)
Offsets::Func = 0xC0;
@@ -284,6 +323,9 @@ void Offsets::FindAll()
Offsets::ServerReplicateActors = 0x66;
else if (std::floor(Fortnite_Version) >= 21)
Offsets::ServerReplicateActors = 0x67; // checked onb 22.30
if (Engine_Version == 419)
Offsets::ReplicationFrame = 0xB2;
}
void Offsets::Print()
@@ -293,6 +335,8 @@ void Offsets::Print()
LOG_INFO(LogDev, "Children: 0x{:x}", Children);
LOG_INFO(LogDev, "PropertiesSize: 0x{:x}", PropertiesSize);
LOG_INFO(LogDev, "Func: 0x{:x}", Func);
LOG_INFO(LogDev, "ServerReplicateActors: 0x{:x}", ServerReplicateActors);
LOG_INFO(LogDev, "ReplicationFrame: 0x{:x}", ReplicationFrame);
}
void Addresses::Init()

View File

@@ -44,6 +44,11 @@ namespace Addresses
extern inline uint64 CompletePickupAnimation = 0;
extern inline uint64 CanActivateAbility = 0;
extern inline uint64 SpecConstructor = 0;
extern inline uint64 ReplicateActor = 0;
extern inline uint64 CallPreReplication = 0;
extern inline uint64 CreateChannel = 0;
extern inline uint64 SetChannelActor = 0;
extern inline uint64 SendClientAdjustment = 0;
extern inline uint64 FrameStep = 0;
void SetupVersion(); // Finds Engine Version
@@ -62,6 +67,7 @@ namespace Offsets
extern inline uint64 SuperStruct = 0;
extern inline uint64 Offset_Internal = 0;
extern inline uint64 ServerReplicateActors = 0;
extern inline uint64 ReplicationFrame = 0;
void FindAll();
void Print();

View File

@@ -5,6 +5,9 @@
#include "SoftObjectPath.h"
#include "KismetStringLibrary.h"
#include "GameplayStatics.h"
#include "FortPlayerPawn.h"
#include "FortPlayerController.h"
#include "FortPlayerControllerAthena.h"
using UNavigationSystemV1 = UObject;
using UNavigationSystemConfig = UObject;
@@ -60,7 +63,7 @@ static void SetNavigationSystem(AAthenaNavSystemConfigOverride* NavSystemOverrid
if (!NewNavSystemClass)
return;
LOG_INFO(LogAI, "Setup navigation system.\n");
LOG_INFO(LogAI, "Setup navigation system.");
AddNavigationSystemToWorldOriginal(*GetWorld(), EFNavigationSystemRunMode::GameMode, NavSystemOverride->Get("NavigationSystemConfig"), true, false);
}
@@ -82,10 +85,69 @@ static void SetupNavConfig()
AthenaNavConfig->Get<bool>("bAutoSpawnMissingNavData") = true; // BITFIELD
AthenaNavConfig->Get<bool>("bSpawnNavDataInNavBoundsLevel") = true; // BITFIELD
AthenaNavConfig->Get<bool>("bUseNavigationInvokers") = false;
AthenaNavConfig->Get<FName>("DefaultAgentName") = UKismetStringLibrary::Conv_StringToName(L"MANG");
AthenaNavConfig->Get<FName>("DefaultAgentName") = UKismetStringLibrary::Conv_StringToName(L"Galileo");
// NavSystemOverride->Get<ENavSystemOverridePolicy>("OverridePolicy") = ENavSystemOverridePolicy::Append;
NavSystemOverride->Get("NavigationSystemConfig") = AthenaNavConfig;
SetNavigationSystem(NavSystemOverride);
}
static AFortPlayerPawn* SpawnAIFromCustomizationData(const FVector& Location, UObject* CustomizationData)
{
static auto PawnClassOffset = CustomizationData->GetOffset("PawnClass");
auto PawnClass = CustomizationData->Get<UClass*>(PawnClassOffset);
if (!PawnClass)
{
LOG_INFO(LogAI, "Invalid PawnClass for AI!");
return nullptr;
}
auto Pawn = GetWorld()->SpawnActor<AFortPlayerPawn>(PawnClass, Location);
static auto CharacterCustomizationOffset = CustomizationData->GetOffset("CharacterCustomization");
auto CharacterCustomization = CustomizationData->Get(CharacterCustomizationOffset);
auto CharacterCustomizationLoadoutOffset = CharacterCustomization->GetOffset("CustomizationLoadout");
auto CharacterCustomizationLoadout = CharacterCustomization->GetPtr<FFortAthenaLoadout>(CharacterCustomizationLoadoutOffset);
ApplyCID(Pawn, CharacterCustomizationLoadout->GetCharacter());
struct FItemAndCount
{
int Count; // 0x0000(0x0004) (Edit, BlueprintVisible, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
unsigned char UnknownData00[0x4]; // 0x0004(0x0004) MISSED OFFSET
UFortItemDefinition* Item; // 0x0008(0x0008) (Edit, BlueprintVisible, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
};
static auto StartupInventoryOffset = CustomizationData->GetOffset("StartupInventory");
auto StartupInventory = CustomizationData->Get(StartupInventoryOffset);
static auto StartupInventoryItemsOffset = StartupInventory->GetOffset("Items");
auto& StartupInventoryItems = StartupInventory->Get<TArray<FItemAndCount>>(StartupInventoryItemsOffset);
auto Controller = Pawn->GetController();
LOG_INFO(LogDev, "Controller: {} StartupInventoryItems.Num: {}", Controller ? Controller->GetFullName() : "InvalidObject", StartupInventoryItems.Num());
if (Controller)
{
/* static auto InventoryOffset = Controller->GetOffset("Inventory");
auto Inventory = Controller->Get<AFortInventory*>(InventoryOffset);
for (int i = 0; i < StartupInventoryItems.Num(); i++)
{
auto pair = Inventory->AddItem(StartupInventoryItems.at(i).Item, nullptr, StartupInventoryItems.at(i).Count);
LOG_INFO(LogDev, "pair.first.size(): {}", pair.first.size());
if (pair.first.size() > 0)
{
if (auto weaponDef = Cast<UFortWeaponItemDefinition>(StartupInventoryItems.at(i).Item))
Pawn->EquipWeaponDefinition(weaponDef, pair.first.at(0)->GetItemEntry()->GetItemGuid());
}
} */
// Inventory->Update(); // crashes idk why
}
return Pawn;
}

View File

@@ -246,6 +246,25 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg)
else if (Command == "spawnaidata")
{
}
else if (Command == "sethealth")
{
auto Pawn = ReceivingController->GetMyFortPawn();
if (!Pawn)
{
SendMessageToConsole(PlayerController, L"No pawn!");
return;
}
float Health = 100.f;
try { Health = std::stof(Arguments[1]); }
catch (...) {}
static auto SetHealthFn = FindObject<UFunction>("/Script/FortniteGame.FortPawn.SetHealth");
Pawn->ProcessEvent(SetHealthFn, &Health);
SendMessageToConsole(PlayerController, L"Set health!\n");
}
else if (Command == "testspawn")
{

View File

@@ -21,6 +21,7 @@ static void SetZoneToIndexHook(AFortGameModeAthena* GameModeAthena, int Override
static auto SafeZoneFinishShrinkTimeOffset = SafeZoneIndicator->GetOffset("SafeZoneFinishShrinkTime");
static auto SafeZoneStartShrinkTimeOffset = SafeZoneIndicator->GetOffset("SafeZoneStartShrinkTime");
static auto RadiusOffset = SafeZoneIndicator->GetOffset("Radius");
static auto SafeZonePhaseOffset = GameModeAthena->GetOffset("SafeZonePhase");
@@ -30,7 +31,9 @@ static void SetZoneToIndexHook(AFortGameModeAthena* GameModeAthena, int Override
static auto SafeZoneDefinitionOffset = MapInfo->GetOffset("SafeZoneDefinition");
auto SafeZoneDefinition = MapInfo->GetPtr<__int64>(SafeZoneDefinitionOffset);
static auto ZoneDurationsOffset = 0x1F8;
LOG_INFO(LogDev, "SafeZoneDefinitionOffset: 0x{:x}", SafeZoneDefinitionOffset);
static auto ZoneDurationsOffset = std::floor(Fortnite_Version) >= 18 ? 0x248 : 0x1F8;
static auto ZoneHoldDurationsOffset = ZoneDurationsOffset - 0x10;
auto& ZoneDurations = *(TArray<float>*)(__int64(SafeZoneDefinition) + ZoneDurationsOffset);
@@ -51,9 +54,17 @@ static void SetZoneToIndexHook(AFortGameModeAthena* GameModeAthena, int Override
if (!FortGameData)
FortGameData = FindObject<UCurveTable>("/Game/Balance/AthenaGameData.AthenaGameData");
LOG_INFO(LogDev, "FortGameData: {}", FortGameData ? FortGameData->GetFullName() : "InvalidObject");
auto ShrinkTimeFName = UKismetStringLibrary::Conv_StringToName(L"Default.SafeZone.ShrinkTime");
auto HoldTimeFName = UKismetStringLibrary::Conv_StringToName(L"Default.SafeZone.WaitTime");
FString ContextString;
/* for (int i = 0; i < 10; i++)
{
LOG_INFO(LogDev, "[{}] Value {}", i, FortGameData->GetValueOfKey(FortGameData->GetKey(ShrinkTimeFName, i)));
} */
/* for (float i = 0; i < 1.1; i += 0.1)
{
float res;
@@ -61,6 +72,26 @@ static void SetZoneToIndexHook(AFortGameModeAthena* GameModeAthena, int Override
LOG_INFO(LogZone, "[{}] {}", i, res);
} */
for (int i = 0; i < ZoneDurations.Num(); i++)
{
ZoneDurations.at(i) = FortGameData->GetValueOfKey(FortGameData->GetKey(ShrinkTimeFName, i));
}
for (int i = 0; i < ZoneHoldDurations.Num(); i++)
{
ZoneHoldDurations.at(i) = FortGameData->GetValueOfKey(FortGameData->GetKey(HoldTimeFName, i));
}
for (int i = 0; i < ZoneDurations.Num(); i++)
{
LOG_INFO(LogZone, "Move [{}] {}", i, ZoneDurations.at(i));
}
for (int i = 0; i < ZoneHoldDurations.Num(); i++)
{
LOG_INFO(LogZone, "Hold [{}] {}", i, ZoneHoldDurations.at(i));
}
/*
if (ZoneDurations.ArrayNum >= 1) ZoneDurations.at(0) = 0;
if (ZoneDurations.ArrayNum >= 2) ZoneDurations.at(1) = 180;
if (ZoneDurations.ArrayNum >= 3) ZoneDurations.at(2) = 120;
@@ -84,22 +115,13 @@ static void SetZoneToIndexHook(AFortGameModeAthena* GameModeAthena, int Override
if (ZoneHoldDurations.ArrayNum >= 9) ZoneHoldDurations.at(8) = 0;
if (ZoneHoldDurations.ArrayNum >= 10) ZoneHoldDurations.at(9) = 0;
if (ZoneHoldDurations.ArrayNum >= 11) ZoneHoldDurations.at(10) = 0;
*/
}
LOG_INFO(LogZone, "SafeZonePhase: {}", GameModeAthena->Get<int>(SafeZonePhaseOffset));
LOG_INFO(LogZone, "OverridePhaseMaybeIDFK: {}", OverridePhaseMaybeIDFK);
LOG_INFO(LogZone, "TimeSeconds: {}", UGameplayStatics::GetTimeSeconds(GetWorld()));
for (int i = 0; i < ZoneDurations.Num(); i++)
{
LOG_INFO(LogZone, "Move [{}] {}", i, ZoneDurations.at(i));
}
for (int i = 0; i < ZoneHoldDurations.Num(); i++)
{
LOG_INFO(LogZone, "Hold [{}] {}", i, ZoneHoldDurations.at(i));
}
SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK);
LOG_INFO(LogZone, "SafeZonePhase After: {}", GameModeAthena->Get<int>(SafeZonePhaseOffset));
@@ -117,6 +139,7 @@ static void SetZoneToIndexHook(AFortGameModeAthena* GameModeAthena, int Override
ZoneDuration = ZoneDurations.at(GameModeAthena->Get<int>(SafeZonePhaseOffset));
LOG_INFO(LogZone, "ZoneDuration: {}", ZoneDuration);
LOG_INFO(LogZone, "Duration: {}", SafeZoneIndicator->Get<float>(RadiusOffset));
SafeZoneIndicator->Get<float>(SafeZoneFinishShrinkTimeOffset) = SafeZoneIndicator->Get<float>(SafeZoneStartShrinkTimeOffset) + ZoneDuration;
}

View File

@@ -256,11 +256,11 @@ DWORD WINAPI Main(LPVOID)
AFortPlayerPawn::ServerHandlePickupHook, nullptr, false);
}
if (Globals::bAbilitiesEnabled)
{
static auto PredictionKeyStruct = FindObject<UStruct>("/Script/GameplayAbilities.PredictionKey");
static auto PredictionKeySize = PredictionKeyStruct->GetPropertiesSize();
if (Globals::bAbilitiesEnabled)
{
if (PredictionKeySize == 0x10)
{
Hooking::MinHook::Hook(FortAbilitySystemComponentAthenaDefault, FindObject<UFunction>(L"/Script/GameplayAbilities.AbilitySystemComponent.ServerTryActivateAbility"),
@@ -307,12 +307,23 @@ DWORD WINAPI Main(LPVOID)
LOG_INFO(LogDev, "Test: 0x{:x}", FindFunctionCall(L"ClientOnPawnDied") - __int64(GetModuleHandleW(0)));
Hooking::MinHook::Hook((PVOID)FindFunctionCall(L"ClientOnPawnDied"), AFortPlayerController::ClientOnPawnDiedHook, (PVOID*)&AFortPlayerController::ClientOnPawnDiedOriginal);
{
int increaseOffset = 0x18; // 0x10;
MemberOffsets::FortPlayerPawn::CorrectTags = FindOffsetStruct("/Script/FortniteGame.FortPlayerPawn", "MoveSoundStimulusBroadcastInterval") + increaseOffset;
MemberOffsets::FortPlayerState::PawnDeathLocation = FindOffsetStruct("/Script/FortniteGame.FortPlayerState", "PawnDeathLocation");
LOG_INFO(LogDev, "PredictionKeySize: 0x{:x} {}", PredictionKeySize, PredictionKeySize);
MemberOffsets::FortPlayerPawnAthena::LastFallDistance = FindOffsetStruct("/Script/FortniteGame.FortPlayerPawnAthena", "LastFallDistance");
static auto GameplayEventDataSize = FindObject<UStruct>("/Script/GameplayAbilities.GameplayEventData")->GetPropertiesSize();
LOG_INFO(LogDev, "GameplayEventDataSize: 0x{:x} {}", GameplayEventDataSize, GameplayEventDataSize);
{
int increaseOffset = 0x10;
if (Engine_Version >= 424 && std::floor(Fortnite_Version) < 18) // checked on 11.31, 12.41, 14.60, 15.10, 16.40, 17.30 and 18.40
increaseOffset += 0x8;
auto MoveSoundStimulusBroadcastIntervalOffset = FindOffsetStruct("/Script/FortniteGame.FortPlayerPawn", "MoveSoundStimulusBroadcastInterval");
MemberOffsets::FortPlayerPawn::CorrectTags = MoveSoundStimulusBroadcastIntervalOffset + increaseOffset;
LOG_INFO(LogDev, "CorrectTags: 0x{:x}", MemberOffsets::FortPlayerPawn::CorrectTags);
MemberOffsets::FortPlayerState::PawnDeathLocation = FindOffsetStruct("/Script/FortniteGame.FortPlayerState", "PawnDeathLocation", false);
MemberOffsets::FortPlayerPawnAthena::LastFallDistance = FindOffsetStruct("/Script/FortniteGame.FortPlayerPawnAthena", "LastFallDistance", false);
MemberOffsets::FortPlayerStateAthena::DeathInfo = FindOffsetStruct("/Script/FortniteGame.FortPlayerStateAthena", "DeathInfo");
MemberOffsets::FortPlayerStateAthena::KillScore = FindOffsetStruct("/Script/FortniteGame.FortPlayerStateAthena", "KillScore");
@@ -323,7 +334,7 @@ DWORD WINAPI Main(LPVOID)
MemberOffsets::DeathInfo::bInitialized = FindOffsetStruct("/Script/FortniteGame.DeathInfo", "bInitialized", false);
MemberOffsets::DeathInfo::Distance = FindOffsetStruct("/Script/FortniteGame.DeathInfo", "Distance");
MemberOffsets::DeathInfo::DeathTags = FindOffsetStruct("/Script/FortniteGame.DeathInfo", "DeathTags", false);
MemberOffsets::DeathInfo::DeathLocation = FindOffsetStruct("/Script/FortniteGame.DeathInfo", "DeathLocation");
MemberOffsets::DeathInfo::DeathLocation = FindOffsetStruct("/Script/FortniteGame.DeathInfo", "DeathLocation", false);
MemberOffsets::DeathReport::Tags = FindOffsetStruct("/Script/FortniteGame.FortPlayerDeathReport", "Tags");
MemberOffsets::DeathReport::KillerPawn = FindOffsetStruct("/Script/FortniteGame.FortPlayerDeathReport", "KillerPawn");

View File

@@ -121,6 +121,9 @@ static inline uint64 FindCreateNetDriver()
static inline uint64 FindKickPlayer()
{
if (std::floor(Fortnite_Version) == 18)
return Memcury::Scanner::FindPattern("48 8B C4 48 89 58 08 48 89 70 10 48 89 78 18 4C 89 60 20 55 41 56 41 57 48 8B EC 48 83 EC 60 48 83 65 ? ? 4C 8B F2 83 65 E8 00 4C 8B E1 83 65 EC").Get();
if (Engine_Version >= 423 || Engine_Version <= 425)
return Memcury::Scanner::FindPattern("48 89 5C 24 08 48 89 74 24 10 57 48 83 EC ? 49 8B F0 48 8B DA 48 85 D2").Get();
@@ -164,7 +167,14 @@ static inline uint64 FindKickPlayer()
static inline uint64 FindInitHost()
{
if (Engine_Version == 427) // idk im dumb
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 55 57 41 56 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B F1 4C 8D 05").Get();
{
auto addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 55 57 41 56 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B F1 4C 8D 05").Get();
if (!addr) // s18
addr = Memcury::Scanner::FindPattern("48 8B C4 48 89 58 10 48 89 70 18 48 89 78 20 55 41 56 41 57 48 8D 68 A1 48 81 EC ? ? ? ? 48 8B F1 4C 8D 35 ? ? ? ? 4D").Get();
return addr;
}
auto Addr = Memcury::Scanner::FindStringRef(L"BeaconPort=");
return FindBytes(Addr, (Engine_Version == 427 ? std::vector<uint8_t>{ 0x48, 0x8B, 0x5C } : std::vector<uint8_t>{ 0x48, 0x8B, 0xC4 }), 1000, 0, true);
@@ -178,12 +188,17 @@ static inline uint64 FindPauseBeaconRequests()
if (Engine_Version == 427)
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 30 33 F6 48 8B F9 84 D2 74").Get();
// todo try 40 53 48 83 EC 30 48 8B ? 84 D2 74 ? 80 3D for S1-S15
if (Engine_Version == 426)
return Memcury::Scanner::FindPattern("40 57 48 83 EC 30 48 8B F9 84 D2 74 62 80 3D").Get();
if (Engine_Version == 420)
return Memcury::Scanner::FindPattern("40 53 48 83 EC 30 48 8B D9 84 D2 74 68 80 3D ? ? ? ? ? 72 2C 48 8B 05 ? ? ? ? 4C 8D 44").Get();
if (Engine_Version == 419)
return Memcury::Scanner::FindPattern("40 53 48 83 EC 30 48 8B D9 84 D2 74 68 80 3D ? ? ? ? ? 72").Get(); // i supposed this is just because its getitng wrong string ref
auto Addr = Memcury::Scanner::FindStringRef(L"All Beacon Requests Resumed.");
return FindBytes(Addr, { 0x40, 0x53 }, 1000, 0, true);
}
@@ -206,6 +221,10 @@ static inline uint64 FindSpawnActor()
}
auto Addr = Memcury::Scanner::FindStringRef(L"SpawnActor failed because no class was specified");
if (Engine_Version == 419)
return FindBytes(Addr, { 0x40, 0x55 }, 3000, 0, true);
return FindBytes(Addr, { 0x4C, 0x8B, 0xDC }, 3000, 0, true);
}
@@ -256,7 +275,15 @@ static inline uint64 FindOnDamageServer()
static inline uint64 FindStaticLoadObject()
{
auto Addr = Memcury::Scanner::FindStringRef(L"STAT_LoadObject").ScanFor({ 0x4C, 0x89, 0x4C }, false);
auto strRef = Memcury::Scanner::FindStringRef(L"STAT_LoadObject", false);
if (!strRef.Get())
{
auto StrRef2 = Memcury::Scanner::FindStringRef(L"Calling StaticLoadObject during PostLoad may result in hitches during streaming.");
return FindBytes(StrRef2, { 0x40, 0x55 }, 1000, 0, true);
}
auto Addr = strRef.ScanFor({ 0x4C, 0x89, 0x4C }, false);
return Addr.Get();
}
@@ -324,12 +351,12 @@ static inline uint64 FindCompletePickupAnimation()
static inline uint64 FindNoMCP()
{
if (Fortnite_Version >= 17) // idk if needed
/* if (Fortnite_Version >= 17) // idk if needed
{
// todo make this relative
// 19.10
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 41 54 41 55 41 56 41 57 48 83 EC 20 65 48 8B 04 25 ? ? ? ? BA ? ? ? ? 48 8B 08 8B 04 0A 39 05 ? ? ? ? 7F 23 8A 05 ? ? ? ? 48 8B 5C 24 ? 48 8B 6C 24 ? 48 8B 74 24 ? 48 83 C4 20 41 5F 41 5E 41 5D 41 5C 5F C3 48 8D 0D ? ? ? ? E8 ? ? ? ? 83 3D ? ? ? ? ? 75 C8 E8 ? ? ? ? 45 33").Get();
}
} */
if (std::floor(Fortnite_Version) == 3)
return Memcury::Scanner::FindPattern("E8 ? ? ? ? 83 A7 ? ? ? ? ? 48 8D 4C 24 ?").Get();
@@ -373,10 +400,11 @@ static inline uint64 FindSetZoneToIndex() // actually StartNewSafeZonePhase
// if (Fortnite_Version == 14.60)
// return __int64(GetModuleHandleW(0)) + 0x207F9B0;
return Memcury::Scanner::FindPattern("48 8B C4 48 89 58 10 48 89 70 18 48 89 78 20 55 41 54 41 55 41 56 41 57 48 8D 68 98 48 81 EC ? ? ? ? 0F 29 70 C8 0F 29 78 B8 44 0F 29 40 ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 45 08 44 8B F2 89 54 24 48 48 8B F1 48 89 4C 24 ? E8 ? ? ? ? 45 33 E4 48 89 44 24 ? 4C 8B F8 48 85 C0 74 09").Get();
return Memcury::Scanner::FindPattern("48 8B C4 48 89 58 10 48 89 70 18 48 89 78 20 55 41 54 41 55 41 56 41 57 48 8D 68 88 48 81 EC ? ? ? ? 0F 29 70 C8 0F 29 78 B8 44 0F 29 40 ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 45 10 44 8B F2 89 54 24 48 48 8B F1 48 89 4C 24 ? E8 ? ? ? ? 45 33 E4 48 89 45 80 4C 8B F8 48 85 C0 74 09 48 8B B8").Get();
return Memcury::Scanner::FindPattern("48 8B C4 48 89 58 10 48 89 70 18 48 89 78 20 55 41 54 41 55 41 56 41 57 48 8D A8 ? ? ? ? 48 81 EC ? ? ? ? 0F 29 70 C8 0F 29 78 B8 44 0F 29 40 ? 44 0F 29 48 ? 44 0F 29 50 ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 4C 8B B1 ? ? ? ? 45 33 ED 89 54 24 70 44 8B FA 48 89 4C 24").Get();
return Memcury::Scanner::FindPattern("40 55 53 56 41 55 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 45 18 48 8B").Get();
return Memcury::Scanner::FindPattern("48 8B C4 48 89 58 10 48 89 70 18 48 89 78 20 55 41 54 41 55 41 56 41 57 48 8D A8 ? ? ? ? 48 81 EC ? ? ? ? 0F 29 70 C8 0F 29 78 B8 44 0F 29 40 ? 44 0F 29 48 ? 44 0F 29 50 ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 44 8B F2 89 54 24 48 4C 8B F9 48 89 4D 90 E8 ? ? ? ? 45 33 ED 48 89 45 A0 48 8B F0").Get(); // 19.10
// return Memcury::Scanner::FindPattern("48 8B C4 48 89 58 10 48 89 70 18 48 89 78 20 55 41 54 41 55 41 56 41 57 48 8D 68 98 48 81 EC ? ? ? ? 0F 29 70 C8 0F 29 78 B8 44 0F 29 40 ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 45 08 44 8B F2 89 54 24 48 48 8B F1 48 89 4C 24 ? E8 ? ? ? ? 45 33 E4 48 89 44 24 ? 4C 8B F8 48 85 C0 74 09").Get(); // 17.30
// return Memcury::Scanner::FindPattern("48 8B C4 48 89 58 10 48 89 70 18 48 89 78 20 55 41 54 41 55 41 56 41 57 48 8D 68 88 48 81 EC ? ? ? ? 0F 29 70 C8 0F 29 78 B8 44 0F 29 40 ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 45 10 44 8B F2 89 54 24 48 48 8B F1 48 89 4C 24 ? E8 ? ? ? ? 45 33 E4 48 89 45 80 4C 8B F8 48 85 C0 74 09 48 8B B8").Get(); // 17.50
return Memcury::Scanner::FindPattern("48 8B C4 48 89 58 10 48 89 70 18 48 89 78 20 55 41 54 41 55 41 56 41 57 48 8D A8 ? ? ? ? 48 81 EC ? ? ? ? 0F 29 70 C8 0F 29 78 B8 44 0F 29 40 ? 44 0F 29 48 ? 44 0F 29 50 ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 4C 8B B1 ? ? ? ? 45 33 ED 89 54 24 70 44 8B FA 48 89 4C 24").Get(); // 18.40
return Memcury::Scanner::FindPattern("40 55 53 56 41 55 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 45 18 48 8B").Get(); // 14.60
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);
@@ -396,10 +424,17 @@ static inline uint64 FindActorGetNetMode()
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 57 48 83 EC 20 F6 41 08 10 48 8B D9 0F 85 ? ? ? ? 48 8B 41 20 48 85 C0 0F 84 ? ? ? ? F7 40").Get();
if (Engine_Version == 427)
{
// note this sig doesnt work on s18
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 57 48 83 EC 20 48 8B D9 E8 ? ? ? ? 48 8B 93 ? ? ? ? 48 8B C8 48 8B F8 E8 ? ? ? ? 48 85 C0 75 29").Get();
}
auto AActorGetNetmode = Memcury::Scanner::FindStringRef(L"STAT_ServerUpdateCamera");
return Memcury::Scanner(FindBytes(AActorGetNetmode, { 0xE8 }, 255, 0, true)).RelativeOffset(1).Get();
auto AActorGetNetmodeStrRef = Memcury::Scanner::FindStringRef(L"STAT_ServerUpdateCamera", false);
if (!AActorGetNetmodeStrRef.Get())
return 0;
return Memcury::Scanner(FindBytes(AActorGetNetmodeStrRef, { 0xE8 }, 255, 0, true)).RelativeOffset(1).Get();
}
static inline uint64 FindTickFlush()
@@ -407,8 +442,20 @@ static inline uint64 FindTickFlush()
// auto add = Memcury::Scanner::FindStringRef(L"UDemoNetDriver::TickFlush: ReplayStreamer ERROR: %s");
// return Memcury::Scanner(FindBytes(add, { 0xE8 }, 500, 0, true, 1)).RelativeOffset(1).Get();
if (Engine_Version == 419)
{
return Memcury::Scanner::FindPattern("4C 8B DC 55 49 8D AB ? ? ? ? 48 81 EC ? ? ? ? 45 0F 29 43 ? 45 0F 29 4B ? 48 8B 05 ? ? ? ? 48").Get(); // 2.4.2
}
if (Engine_Version == 427)
return Memcury::Scanner::FindPattern("48 8B C4 48 89 58 18 55 56 57 41 54 41 55 41 56 41 57 48 8D A8 ? ? ? ? 48 81 EC ? ? ? ? 0F 29 70 B8 0F 29 78 A8 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 8A").Get();
{
auto addr = Memcury::Scanner::FindPattern("48 8B C4 48 89 58 18 55 56 57 41 54 41 55 41 56 41 57 48 8D A8 ? ? ? ? 48 81 EC ? ? ? ? 0F 29 70 B8 0F 29 78 A8 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 8A").Get();
if (!addr) // s18
addr = Memcury::Scanner::FindPattern("48 8B C4 48 89 58 18 55 56 57 41 54 41 55 41 56 41 57 48 8D A8 ? ? ? ? 48 81 EC ? ? ? ? 0F 29 70 B8 0F 29 78 A8 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 44 0F").Get();
return addr;
}
auto Addr = Memcury::Scanner::FindStringRef(L"STAT_NetTickFlush");
return FindBytes(Addr, (Fortnite_Version < 18 ? std::vector<uint8_t>{ 0x4C, 0x8B } : std::vector<uint8_t>{ 0x48, 0x8B, 0xC4 }), 1000, 0, true);
@@ -567,12 +614,15 @@ static inline uint64 FindChangeGameSessionId()
static inline uint64 FindDispatchRequest()
{
auto Addr = Memcury::Scanner::FindStringRef(L"MCP-Profile: Dispatching request to %s", true, 0, Fortnite_Version >= 18); // todo check s18
return FindBytes(Addr, { 0x48, 0x89, 0x5C }, 300, 0, true);
auto Addr = Memcury::Scanner::FindStringRef(L"MCP-Profile: Dispatching request to %s", true, 0, Fortnite_Version >= 19);
return FindBytes(Addr, std::floor(Fortnite_Version) == 18 ? std::vector<uint8_t>{0x48, 0x8B, 0xC4 } : std::vector<uint8_t>{ 0x48, 0x89, 0x5C }, 300, 0, true);
}
static inline uint64 FindGIsClient()
{
if (Fortnite_Version == 11.31)
return __int64(GetModuleHandleW(0)) + 0x6F41270;
if (Fortnite_Version == 14.60)
return __int64(GetModuleHandleW(0)) + 0x939930D;
@@ -661,6 +711,9 @@ static inline uint64 FindGetNetMode()
.RelativeOffset(4)
.Get(); // credit ender */
if (std::floor(Fortnite_Version) == 18)
return Memcury::Scanner::FindPattern("48 83 EC 28 48 83 79 ? ? 75 20 48 8B 91 ? ? ? ? 48 85 D2 74 1E 48 8B 02 48 8B CA FF 90").Get();
auto Addr = Memcury::Scanner::FindStringRef(L"PREPHYSBONES");
auto BeginningFunction = Memcury::Scanner(FindBytes(Addr, { 0x40, 0x55 }, 1000, 0, true));
auto CallToFunc = Memcury::Scanner(FindBytes(BeginningFunction, { 0xE8 }));
@@ -692,6 +745,9 @@ static inline uint64 FindRealloc()
static inline uint64 FindPickTeam()
{
if (Engine_Version >= 427) // different start
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 88 54 24 10 55 56 57 41 54 41 55 41 56 41 57 48 8B EC 48 83 EC 70 4C 8B A1").Get();
auto Addr = Memcury::Scanner::FindStringRef(L"PickTeam for [%s] used beacon value [%d]", false);
if (!Addr.Get())
@@ -789,3 +845,43 @@ static inline uint64 FindReplaceBuildingActor()
return FindBytes(StringRef, (Engine_Version == 420 || Engine_Version == 421 ? std::vector<uint8_t>{ 0x48, 0x8B, 0xC4 } : std::vector<uint8_t>{ 0x4C, 0x8B }), 1000, 0, true);
}
static inline uint64 FindSendClientAdjustment()
{
if (Engine_Version == 419)
return Memcury::Scanner::FindPattern("40 53 48 83 EC 20 48 8B 99 ? ? ? ? 48 39 99 ? ? ? ? 74 0A 48 83 B9 ? ? ? ? ? 74").Get();
return 0;
}
static inline uint64 FindReplicateActor()
{
if (Engine_Version == 419)
return Memcury::Scanner::FindPattern("40 55 56 41 54 41 55 41 56 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 4C 8B E9 48 8B 49 68 48").Get();
return 0;
}
static inline uint64 FindCreateChannel()
{
if (Engine_Version == 419)
return Memcury::Scanner::FindPattern("40 56 57 41 54 41 55 41 57 48 83 EC 60 48 8B 01 41 8B F9 45 0F B6 E0").Get();
return 0;
}
static inline uint64 FindSetChannelActor()
{
if (Engine_Version == 419)
return Memcury::Scanner::FindPattern("48 8B C4 55 53 48 8D A8 ? ? ? ? 48 81 EC ? ? ? ? 48 89 70 E8 48 8B D9").Get();
return 0;
}
static inline uint64 FindCallPreReplication()
{
if (Engine_Version == 419)
return Memcury::Scanner::FindPattern("48 85 D2 0F 84 ? ? ? ? 48 8B C4 55 57 41 54 48 8D 68 A1 48 81 EC ? ? ? ? 48 89 58 08 4C").Get();
return 0;
}

View File

@@ -72,6 +72,7 @@ inline void InitLogger()
MakeLogger("LogInteraction");
MakeLogger("LogCreative");
MakeLogger("LogZone");
MakeLogger("LogReplication");
}
#define LOG_DEBUG(loggerName, ...) \

View File

@@ -309,7 +309,7 @@ namespace MemberOffsets
static UObject* GetPlaylistToUse()
{
auto Playlist = FindObject("/Game/Athena/Playlists/Playlist_DefaultSolo.Playlist_DefaultSolo");
Playlist = FindObject("/BlueCheese/Playlists/Playlist_ShowdownAlt_BlueCheese_Trios.Playlist_ShowdownAlt_BlueCheese_Trios");
// Playlist = FindObject("/BlueCheese/Playlists/Playlist_ShowdownAlt_BlueCheese_Trios.Playlist_ShowdownAlt_BlueCheese_Trios");
/*
if (Globals::bCreative)

View File

@@ -101,6 +101,40 @@ static inline void AddVehicleHook()
}
}
static inline AActor* SpawnVehicleFromSpawner(AActor* VehicleSpawner)
{
FTransform SpawnTransform{};
SpawnTransform.Translation = VehicleSpawner->GetActorLocation();
SpawnTransform.Rotation = VehicleSpawner->GetActorRotation().Quaternion();
SpawnTransform.Scale3D = { 1, 1, 1 };
static auto VehicleClassOffset = VehicleSpawner->GetOffset("VehicleClass", false);
if (VehicleClassOffset != 0) // 10.40 and below?
{
auto VehicleClass = VehicleSpawner->Get<UClass*>(VehicleClassOffset);
if (!VehicleClass)
return nullptr;
return GetWorld()->SpawnActor<AActor>(VehicleClass, SpawnTransform);
}
}
static inline void SpawnVehicles2()
{
static auto FortAthenaVehicleSpawnerClass = FindObject<UClass>("/Script/FortniteGame.FortAthenaVehicleSpawner");
TArray<AActor*> AllVehicleSpawners = UGameplayStatics::GetAllActorsOfClass(GetWorld(), FortAthenaVehicleSpawnerClass);
for (int i = 0; i < AllVehicleSpawners.Num(); i++)
{
auto VehicleSpawner = AllVehicleSpawners.at(i);
auto Vehicle = SpawnVehicleFromSpawner(VehicleSpawner);
}
AllVehicleSpawners.Free();
}
static inline void SpawnVehicles()
{
static auto FortAthenaVehicleSpawnerClass = FindObject<UClass>("/Script/FortniteGame.FortAthenaVehicleSpawner");
@@ -164,6 +198,11 @@ static inline void SpawnVehicles()
{
static auto FortVehicleItemDefOffset = VehicleSpawner->GetOffset("FortVehicleItemDef");
if (FortVehicleItemDefOffset == 0)
{
}
auto FortVehicleItemDefSoft = VehicleSpawner->GetPtr<TSoftObjectPtr<UFortItemDefinition>>(FortVehicleItemDefOffset);
auto FortVehicleItemDefAssetPath = FortVehicleItemDefSoft->SoftObjectPtr.ObjectID.AssetPathName;

17
vendor/memcury.h vendored
View File

@@ -49,6 +49,8 @@
#include <source_location>
#include <DbgHelp.h>
#pragma comment(lib, "Dbghelp.lib")
#include "../Project Reboot 3.0/log.h"
#define MemcuryAssert(cond) \
if (!(cond)) \
@@ -747,7 +749,10 @@
if (bWarnIfNotFound)
{
if (add == 0)
MessageBoxA(0, ("FindPattern " + std::string(signature) + " null").c_str(), "Memcury", MB_ICONERROR);
{
LOG_WARN(LogMemory, "Failed to find {}", signature);
// MessageBoxA(0, ("FindPattern " + std::string(signature) + " null").c_str(), "Memcury", MB_ICONERROR);
}
}
return Scanner(add);
@@ -880,12 +885,16 @@
{
if constexpr (bIsWide)
{
auto aaa = (L"failed FindStringRef " + std::wstring(string));
MessageBoxA(0, std::string(aaa.begin(), aaa.end()).c_str(), "Memcury", MB_ICONERROR);
std::wstring wstr = std::wstring(string);
LOG_WARN(LogMemory, "Failed to find String {}", std::string(wstr.begin(), wstr.end()));
// auto aaa = (L"failed FindStringRef " + std::wstring(string));
// MessageBoxA(0, std::string(aaa.begin(), aaa.end()).c_str(), "Memcury", MB_ICONERROR);
}
else
{
MessageBoxA(0, ("failed FindStringRef " + std::string(string)).c_str(), "Memcury", MB_ICONERROR);
LOG_WARN(LogMemory, "Failed to find String {}", string);
// MessageBoxA(0, ("failed FindStringRef " + std::string(string)).c_str(), "Memcury", MB_ICONERROR);
}
}
}