performace

This commit is contained in:
Milxnor
2023-06-11 14:34:35 -04:00
parent 8bdd33d936
commit ed0c9005e6
10 changed files with 269 additions and 107 deletions

View File

@@ -17,6 +17,11 @@ FNetworkObjectList& UNetDriver::GetNetworkObjectList()
return *(*(TSharedPtr<FNetworkObjectList>*)(__int64(this) + Offsets::NetworkObjectList)); return *(*(TSharedPtr<FNetworkObjectList>*)(__int64(this) + Offsets::NetworkObjectList));
} }
bool ShouldUseNetworkObjectList()
{
return Fortnite_Version < 20;
}
void UNetDriver::RemoveNetworkActor(AActor* Actor) void UNetDriver::RemoveNetworkActor(AActor* Actor)
{ {
GetNetworkObjectList().Remove(Actor); GetNetworkObjectList().Remove(Actor);
@@ -35,7 +40,8 @@ void UNetDriver::TickFlushHook(UNetDriver* NetDriver)
{ {
static auto ReplicationDriverOffset = NetDriver->GetOffset("ReplicationDriver", false); static auto ReplicationDriverOffset = NetDriver->GetOffset("ReplicationDriver", false);
if (ReplicationDriverOffset == -1) // if (ReplicationDriverOffset == -1)
if (ReplicationDriverOffset == -1 || Fortnite_Version >= 20)
{ {
NetDriver->ServerReplicateActors(); NetDriver->ServerReplicateActors();
} }
@@ -149,98 +155,148 @@ void UNetDriver::ServerReplicateActors_BuildConsiderList(std::vector<FNetworkObj
{ {
std::vector<AActor*> ActorsToRemove; std::vector<AActor*> ActorsToRemove;
auto& ActiveObjects = GetNetworkObjectList().ActiveNetworkObjects; if (ShouldUseNetworkObjectList())
auto World = GetWorld();
for (const TSharedPtr<FNetworkObjectInfo>& ActorInfo : ActiveObjects)
{ {
if (!ActorInfo->bPendingNetUpdate && UGameplayStatics::GetTimeSeconds(GetWorld()) <= ActorInfo->NextUpdateTime) auto& ActiveObjects = GetNetworkObjectList().ActiveNetworkObjects;
auto World = GetWorld();
for (const TSharedPtr<FNetworkObjectInfo>& ActorInfo : ActiveObjects)
{ {
continue; if (!ActorInfo->bPendingNetUpdate && UGameplayStatics::GetTimeSeconds(GetWorld()) <= ActorInfo->NextUpdateTime)
}
auto Actor = ActorInfo->Actor;
if (!Actor)
continue;
if (Actor->IsPendingKillPending())
// if (Actor->IsPendingKill())
{
ActorsToRemove.push_back(Actor);
continue;
}
static auto RemoteRoleOffset = Actor->GetOffset("RemoteRole");
if (Actor->Get<ENetRole>(RemoteRoleOffset) == ENetRole::ROLE_None)
{
ActorsToRemove.push_back(Actor);
continue;
}
// We should add a NetDriverName check but I don't believe it is needed.
// We should check if the actor is initialized here.
// We should check the level stuff here.
static auto NetDormancyOffset = Actor->GetOffset("NetDormancy");
if (Actor->Get<ENetDormancy>(NetDormancyOffset) == ENetDormancy::DORM_Initial && Actor->IsNetStartupActor()) // IsDormInitialStartupActor
{
continue;
}
// We should check NeedsLoadForClient here.
// We should make sure the actor is in the same world here but I don't believe it is needed.
if (ActorInfo->LastNetReplicateTime == 0)
{
ActorInfo->LastNetReplicateTime = UGameplayStatics::GetTimeSeconds(World);
ActorInfo->OptimalNetUpdateDelta = 1.0f / Actor->GetNetUpdateFrequency();
}
const float ScaleDownStartTime = 2.0f;
const float ScaleDownTimeRange = 5.0f;
const float LastReplicateDelta = UGameplayStatics::GetTimeSeconds(World) - ActorInfo->LastNetReplicateTime;
if (LastReplicateDelta > ScaleDownStartTime)
{
static auto MinNetUpdateFrequencyOffset = Actor->GetOffset("MinNetUpdateFrequency");
if (Actor->Get<float>(MinNetUpdateFrequencyOffset) == 0.0f)
{ {
Actor->Get<float>(MinNetUpdateFrequencyOffset) = 2.0f; continue;
} }
const float MinOptimalDelta = 1.0f / Actor->GetNetUpdateFrequency(); // Don't go faster than NetUpdateFrequency auto Actor = ActorInfo->Actor;
const float MaxOptimalDelta = max(1.0f / Actor->GetMinNetUpdateFrequency(), MinOptimalDelta); // Don't go slower than MinNetUpdateFrequency (or NetUpdateFrequency if it's slower)
const float Alpha = std::clamp((LastReplicateDelta - ScaleDownStartTime) / ScaleDownTimeRange, 0.0f, 1.0f); // should we use fmath? if (!Actor)
ActorInfo->OptimalNetUpdateDelta = std::lerp(MinOptimalDelta, MaxOptimalDelta, Alpha); // should we use fmath? continue;
if (Actor->IsPendingKillPending())
// if (Actor->IsPendingKill())
{
ActorsToRemove.push_back(Actor);
continue;
}
static auto RemoteRoleOffset = Actor->GetOffset("RemoteRole");
if (Actor->Get<ENetRole>(RemoteRoleOffset) == ENetRole::ROLE_None)
{
ActorsToRemove.push_back(Actor);
continue;
}
// We should add a NetDriverName check but I don't believe it is needed.
// We should check if the actor is initialized here.
// We should check the level stuff here.
static auto NetDormancyOffset = Actor->GetOffset("NetDormancy");
if (Actor->Get<ENetDormancy>(NetDormancyOffset) == ENetDormancy::DORM_Initial && Actor->IsNetStartupActor()) // IsDormInitialStartupActor
{
continue;
}
// We should check NeedsLoadForClient here.
// We should make sure the actor is in the same world here but I don't believe it is needed.
if (ActorInfo->LastNetReplicateTime == 0)
{
ActorInfo->LastNetReplicateTime = UGameplayStatics::GetTimeSeconds(World);
ActorInfo->OptimalNetUpdateDelta = 1.0f / Actor->GetNetUpdateFrequency();
}
const float ScaleDownStartTime = 2.0f;
const float ScaleDownTimeRange = 5.0f;
const float LastReplicateDelta = UGameplayStatics::GetTimeSeconds(World) - ActorInfo->LastNetReplicateTime;
if (LastReplicateDelta > ScaleDownStartTime)
{
static auto MinNetUpdateFrequencyOffset = Actor->GetOffset("MinNetUpdateFrequency");
if (Actor->Get<float>(MinNetUpdateFrequencyOffset) == 0.0f)
{
Actor->Get<float>(MinNetUpdateFrequencyOffset) = 2.0f;
}
const float MinOptimalDelta = 1.0f / Actor->GetNetUpdateFrequency(); // Don't go faster than NetUpdateFrequency
const float MaxOptimalDelta = max(1.0f / Actor->GetMinNetUpdateFrequency(), MinOptimalDelta); // Don't go slower than MinNetUpdateFrequency (or NetUpdateFrequency if it's slower)
const float Alpha = std::clamp((LastReplicateDelta - ScaleDownStartTime) / ScaleDownTimeRange, 0.0f, 1.0f); // should we use fmath?
ActorInfo->OptimalNetUpdateDelta = std::lerp(MinOptimalDelta, MaxOptimalDelta, Alpha); // should we use fmath?
}
if (!ActorInfo->bPendingNetUpdate)
{
constexpr bool bUseAdapativeNetFrequency = false;
const float NextUpdateDelta = bUseAdapativeNetFrequency ? ActorInfo->OptimalNetUpdateDelta : 1.0f / Actor->GetNetUpdateFrequency();
// then set the next update time
float ServerTickTime = 1.f / 30;
ActorInfo->NextUpdateTime = UGameplayStatics::GetTimeSeconds(World) + FRand() * ServerTickTime + NextUpdateDelta;
static auto TimeOffset = GetOffset("Time");
ActorInfo->LastNetUpdateTime = Get<float>(TimeOffset);
}
ActorInfo->bPendingNetUpdate = false;
OutConsiderList.push_back(ActorInfo.Get());
static void (*CallPreReplication)(AActor*, UNetDriver*) = decltype(CallPreReplication)(Addresses::CallPreReplication);
CallPreReplication(Actor, this);
} }
}
else
{
auto Actors = UGameplayStatics::GetAllActorsOfClass(GetWorld(), AActor::StaticClass());
if (!ActorInfo->bPendingNetUpdate) for (int i = 0; i < Actors.Num(); ++i)
{ {
constexpr bool bUseAdapativeNetFrequency = false; auto Actor = Actors.at(i);
const float NextUpdateDelta = bUseAdapativeNetFrequency ? ActorInfo->OptimalNetUpdateDelta : 1.0f / Actor->GetNetUpdateFrequency();
// then set the next update time if (Actor->IsPendingKillPending())
float ServerTickTime = 1.f / 30; // if (Actor->IsPendingKill())
ActorInfo->NextUpdateTime = UGameplayStatics::GetTimeSeconds(World) + FRand() * ServerTickTime + NextUpdateDelta; {
static auto TimeOffset = GetOffset("Time"); ActorsToRemove.push_back(Actor);
ActorInfo->LastNetUpdateTime = Get<float>(TimeOffset); continue;
}
static auto RemoteRoleOffset = Actor->GetOffset("RemoteRole");
if (Actor->Get<ENetRole>(RemoteRoleOffset) == ENetRole::ROLE_None)
{
ActorsToRemove.push_back(Actor);
continue;
}
// We should add a NetDriverName check but I don't believe it is needed.
// We should check if the actor is initialized here.
// We should check the level stuff here.
static auto NetDormancyOffset = Actor->GetOffset("NetDormancy");
if (Actor->Get<ENetDormancy>(NetDormancyOffset) == ENetDormancy::DORM_Initial && Actor->IsNetStartupActor()) // IsDormInitialStartupActor
{
continue;
}
auto ActorInfo = new FNetworkObjectInfo;
ActorInfo->Actor = Actor;
OutConsiderList.push_back(ActorInfo);
static void (*CallPreReplication)(AActor*, UNetDriver*) = decltype(CallPreReplication)(Addresses::CallPreReplication);
CallPreReplication(Actor, this);
} }
ActorInfo->bPendingNetUpdate = false; Actors.Free();
OutConsiderList.push_back(ActorInfo.Get());
static void (*CallPreReplication)(AActor*, UNetDriver*) = decltype(CallPreReplication)(Addresses::CallPreReplication);
CallPreReplication(Actor, this);
} }
for (auto Actor : ActorsToRemove) for (auto Actor : ActorsToRemove)
@@ -401,7 +457,9 @@ int32 UNetDriver::ServerReplicateActors()
} }
std::vector<FNetworkObjectInfo*> ConsiderList; std::vector<FNetworkObjectInfo*> ConsiderList;
ConsiderList.reserve(GetNetworkObjectList().ActiveNetworkObjects.Num());
if (ShouldUseNetworkObjectList())
ConsiderList.reserve(GetNetworkObjectList().ActiveNetworkObjects.Num());
// std::cout << "ConsiderList.size(): " << GetNetworkObjectList(NetDriver).ActiveNetworkObjects.Num() << '\n'; // std::cout << "ConsiderList.size(): " << GetNetworkObjectList(NetDriver).ActiveNetworkObjects.Num() << '\n';
@@ -424,10 +482,13 @@ int32 UNetDriver::ServerReplicateActors()
if (!Connection->GetViewTarget()) if (!Connection->GetViewTarget())
continue; continue;
if (Connection->GetPlayerController()) if (Addresses::SendClientAdjustment)
{ {
static void (*SendClientAdjustment)(APlayerController*) = decltype(SendClientAdjustment)(Addresses::SendClientAdjustment); if (Connection->GetPlayerController())
SendClientAdjustment(Connection->GetPlayerController()); {
static void (*SendClientAdjustment)(APlayerController*) = decltype(SendClientAdjustment)(Addresses::SendClientAdjustment);
SendClientAdjustment(Connection->GetPlayerController());
}
} }
// Make weak ptr once for IsActorDormant call // Make weak ptr once for IsActorDormant call
@@ -513,8 +574,15 @@ int32 UNetDriver::ServerReplicateActors()
} }
} }
enum class EChannelCreateFlags : uint32_t
{
None = (1 << 0),
OpenedLocally = (1 << 1)
};
static UChannel* (*CreateChannel)(UNetConnection*, int, bool, int32_t) = decltype(CreateChannel)(Addresses::CreateChannel); static UChannel* (*CreateChannel)(UNetConnection*, int, bool, int32_t) = decltype(CreateChannel)(Addresses::CreateChannel);
static __int64 (*ReplicateActor)(UActorChannel*) = decltype(ReplicateActor)(Addresses::ReplicateActor); static __int64 (*ReplicateActor)(UActorChannel*) = decltype(ReplicateActor)(Addresses::ReplicateActor);
static UObject* (*CreateChannelByName)(UNetConnection* Connection, FName* ChName, EChannelCreateFlags CreateFlags, int32_t ChannelIndex) = decltype(CreateChannelByName)(Addresses::CreateChannel);
static __int64 (*SetChannelActor)(UActorChannel*, AActor*) = decltype(SetChannelActor)(Addresses::SetChannelActor); static __int64 (*SetChannelActor)(UActorChannel*, AActor*) = decltype(SetChannelActor)(Addresses::SetChannelActor);
if (!Channel) if (!Channel)
@@ -524,7 +592,18 @@ int32 UNetDriver::ServerReplicateActors()
if (bLevelInitializedForActor) if (bLevelInitializedForActor)
{ {
Channel = (UActorChannel*)CreateChannel(Connection, 2, true, -1); if (Engine_Version >= 422)
{
FString ActorStr = L"Actor";
FName ActorName = UKismetStringLibrary::Conv_StringToName(ActorStr);
int ChannelIndex = -1; // 4294967295
Channel = (UActorChannel*)CreateChannelByName(Connection, &ActorName, EChannelCreateFlags::OpenedLocally, ChannelIndex);
}
else
{
Channel = (UActorChannel*)CreateChannel(Connection, 2, true, -1);
}
if (Channel) if (Channel)
{ {

View File

@@ -130,6 +130,18 @@ public:
static void TickFlushHook(UNetDriver* NetDriver); static void TickFlushHook(UNetDriver* NetDriver);
int& GetMaxInternetClientRate()
{
static auto MaxInternetClientRateOffset = GetOffset("MaxInternetClientRate");
return Get<int>(MaxInternetClientRateOffset);
}
int& GetMaxClientRate()
{
static auto MaxClientRateOffset = GetOffset("MaxClientRate");
return Get<int>(MaxClientRateOffset);
}
FNetGUIDCache* GetGuidCache() FNetGUIDCache* GetGuidCache()
{ {
static auto GuidCacheOffset = GetOffset("WorldPackage") + 8; // checked for 1.11 static auto GuidCacheOffset = GetOffset("WorldPackage") + 8; // checked for 1.11

View File

@@ -7,9 +7,15 @@
struct FRotator struct FRotator
{ {
#ifdef ABOVE_S20
double Pitch;
double Yaw;
double Roll;
#else
float Pitch; float Pitch;
float Yaw; float Yaw;
float Roll; float Roll;
#endif
FQuat Quaternion(); FQuat Quaternion();

View File

@@ -1,11 +1,19 @@
#pragma once #pragma once
#include "inc.h"
struct FVector struct FVector
{ {
public: public:
float X; #ifdef ABOVE_S20
float Y; using VectorDataType = double;
float Z; #else
using VectorDataType = float;
#endif
VectorDataType X;
VectorDataType Y;
VectorDataType Z;
bool CompareVectors(const FVector& A) bool CompareVectors(const FVector& A)
{ {
@@ -13,7 +21,7 @@ public:
} }
FVector() : X(0), Y(0), Z(0) {} FVector() : X(0), Y(0), Z(0) {}
FVector(float x, float y, float z) : X(x), Y(y), Z(z) {} FVector(VectorDataType x, VectorDataType y, VectorDataType z) : X(x), Y(y), Z(z) {}
FVector operator+(const FVector& A) FVector operator+(const FVector& A)
{ {
@@ -25,17 +33,17 @@ public:
return FVector{ this->X - A.X, this->Y - A.Y, this->Z - A.Z }; return FVector{ this->X - A.X, this->Y - A.Y, this->Z - A.Z };
} }
FORCEINLINE float SizeSquared() const FORCEINLINE VectorDataType SizeSquared() const
{ {
return X * X + Y * Y + Z * Z; return X * X + Y * Y + Z * Z;
} }
FORCEINLINE float operator|(const FVector& V) const FORCEINLINE VectorDataType operator|(const FVector& V) const
{ {
return X * V.X + Y * V.Y + Z * V.Z; return X * V.X + Y * V.Y + Z * V.Z;
} }
FVector operator*(const float A) FVector operator*(const VectorDataType A)
{ {
return FVector{ this->X * A, this->Y * A, this->Z * A }; return FVector{ this->X * A, this->Y * A, this->Z * A };
} }

View File

@@ -66,14 +66,6 @@ void UWorld::Listen()
FURL URL = FURL(); FURL URL = FURL();
URL.Port = Port - (Engine_Version >= 426); URL.Port = Port - (Engine_Version >= 426);
FString Error;
if (!NewNetDriver->InitListen(GetWorld(), URL, false, Error))
{
LOG_ERROR(LogNet, "Failed to init listen!");
return;
}
NewNetDriver->SetWorld(GetWorld()); NewNetDriver->SetWorld(GetWorld());
// LEVEL COLLECTIONS // LEVEL COLLECTIONS
@@ -85,6 +77,21 @@ void UWorld::Listen()
*(UNetDriver**)(__int64(LevelCollections.AtPtr(0, LevelCollectionSize)) + 0x10) = NewNetDriver; *(UNetDriver**)(__int64(LevelCollections.AtPtr(0, LevelCollectionSize)) + 0x10) = NewNetDriver;
*(UNetDriver**)(__int64(LevelCollections.AtPtr(1, LevelCollectionSize)) + 0x10) = NewNetDriver; *(UNetDriver**)(__int64(LevelCollections.AtPtr(1, LevelCollectionSize)) + 0x10) = NewNetDriver;
FString Error;
if (!NewNetDriver->InitListen(GetWorld(), URL, false, Error))
{
LOG_ERROR(LogNet, "Failed to init listen!");
return;
}
const bool bLanSpeed = false;
if (!bLanSpeed && (NewNetDriver->GetMaxInternetClientRate() < NewNetDriver->GetMaxClientRate()) && (NewNetDriver->GetMaxInternetClientRate() > 2500))
{
NewNetDriver->GetMaxClientRate() = NewNetDriver->GetMaxInternetClientRate();
}
LOG_INFO(LogNet, "Listening on port {}!", Port + Globals::AmountOfListens - 1); LOG_INFO(LogNet, "Listening on port {}!", Port + Globals::AmountOfListens - 1);
} }

View File

@@ -467,6 +467,10 @@ void Offsets::FindAll()
Offsets::NetworkObjectList = 0x490; Offsets::NetworkObjectList = 0x490;
Offsets::ReplicationFrame = 0x2C8; Offsets::ReplicationFrame = 0x2C8;
} }
if (Fortnite_Version >= 20 && Fortnite_Version < 22)
{
Offsets::ReplicationFrame = 0x3D8;
}
Offsets::IsNetRelevantFor = FindIsNetRelevantForOffset(); Offsets::IsNetRelevantFor = FindIsNetRelevantForOffset();
Offsets::Script = Offsets::Children + 8 + 4 + 4; Offsets::Script = Offsets::Children + 8 + 4 + 4;

View File

@@ -256,6 +256,8 @@ void ChangeLevels()
constexpr bool bUseSwitchLevel = false; constexpr bool bUseSwitchLevel = false;
constexpr bool bShouldRemoveLocalPlayer = true; constexpr bool bShouldRemoveLocalPlayer = true;
LOG_INFO(LogDev, "FindGIsClient(): 0x{:x}", FindGIsClient() - __int64(GetModuleHandleW(0)));
FString LevelB = Engine_Version < 424 FString LevelB = Engine_Version < 424
? L"open Athena_Terrain" : Engine_Version >= 500 ? Engine_Version >= 501 ? L"open Athena_Terrain" : Engine_Version >= 500 ? Engine_Version >= 501
? L"open Asteria_Terrain" ? L"open Asteria_Terrain"
@@ -371,7 +373,8 @@ DWORD WINAPI Main(LPVOID)
Addresses::Print(); Addresses::Print();
LOG_INFO(LogDev, "Fortnite_CL: {}", Fortnite_CL); LOG_INFO(LogDev, "Fortnite_CL: {}", Fortnite_CL);
LOG_INFO(LogDev, "Version: {}", Fortnite_Version); LOG_INFO(LogDev, "Fortnite_Version: {}", Fortnite_Version);
LOG_INFO(LogDev, "Engine_Version: {}", Engine_Version);
CreateThread(0, 0, GuiThread, 0, 0, 0); CreateThread(0, 0, GuiThread, 0, 0, 0);
@@ -434,8 +437,6 @@ DWORD WINAPI Main(LPVOID)
Hooking::MinHook::Hook((PVOID)Addresses::KickPlayer, (PVOID)AGameSession::KickPlayerHook, (PVOID*)&AGameSession::KickPlayerOriginal); Hooking::MinHook::Hook((PVOID)Addresses::KickPlayer, (PVOID)AGameSession::KickPlayerHook, (PVOID*)&AGameSession::KickPlayerOriginal);
LOG_INFO(LogDev, "Built on {} {}", __DATE__, __TIME__); LOG_INFO(LogDev, "Built on {} {}", __DATE__, __TIME__);
LOG_INFO(LogDev, "[bNoMCP] {}", Globals::bNoMCP);
LOG_INFO(LogDev, "[bGoingToPlayEvent] {}", Globals::bGoingToPlayEvent);
LOG_INFO(LogDev, "Size: 0x{:x}", sizeof(TMap<FName, void*>)); LOG_INFO(LogDev, "Size: 0x{:x}", sizeof(TMap<FName, void*>));
Hooking::MinHook::Hook((PVOID)Addresses::ActorGetNetMode, (PVOID)GetNetModeHook2, nullptr); Hooking::MinHook::Hook((PVOID)Addresses::ActorGetNetMode, (PVOID)GetNetModeHook2, nullptr);
@@ -525,6 +526,8 @@ DWORD WINAPI Main(LPVOID)
ChangeLevels(); ChangeLevels();
LOG_INFO(LogDev, "Switch levels.");
auto AddressesToNull = Addresses::GetFunctionsToNull(); auto AddressesToNull = Addresses::GetFunctionsToNull();
auto ServerCheatAllIndex = GetFunctionIdxOrPtr(FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.ServerCheatAll")); auto ServerCheatAllIndex = GetFunctionIdxOrPtr(FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.ServerCheatAll"));
@@ -794,6 +797,7 @@ DWORD WINAPI Main(LPVOID)
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);
Hooking::MinHook::Hook((PVOID)GetFunctionIdxOrPtr(FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerPawn.ServerOnExitVehicle"), true), AFortPlayerPawn::ServerOnExitVehicleHook, (PVOID*)&AFortPlayerPawn::ServerOnExitVehicleOriginal); Hooking::MinHook::Hook((PVOID)GetFunctionIdxOrPtr(FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerPawn.ServerOnExitVehicle"), true), AFortPlayerPawn::ServerOnExitVehicleHook, (PVOID*)&AFortPlayerPawn::ServerOnExitVehicleOriginal);
if (Fortnite_Version == 1.11 || Fortnite_Version > 1.8) if (Fortnite_Version == 1.11 || Fortnite_Version > 1.8)
@@ -994,6 +998,7 @@ DWORD WINAPI Main(LPVOID)
uint64 ServerRemoveInventoryItemFunctionCallBeginFunctionAddr = 0; uint64 ServerRemoveInventoryItemFunctionCallBeginFunctionAddr = 0;
// if (Engine_Version >= 419) // if (Engine_Version >= 419)
if (Fortnite_Version < 20)
{ {
std::vector<uint8_t> ServerRemoveInventoryItemCallFunctionStarts = Engine_Version == 416 std::vector<uint8_t> ServerRemoveInventoryItemCallFunctionStarts = Engine_Version == 416
? std::vector<uint8_t>{ 0x44, 0x88, 0x4C } ? std::vector<uint8_t>{ 0x44, 0x88, 0x4C }

View File

@@ -65,8 +65,17 @@ static inline uintptr_t FindBytes(Memcury::Scanner& Scanner, const std::vector<u
static inline uint64 FindStaticFindObject(int StringSkip = 1) static inline uint64 FindStaticFindObject(int StringSkip = 1)
{ {
// ServerStatReplicatorInst then first jmp??
if (Engine_Version == 500) if (Engine_Version == 500)
return Memcury::Scanner::FindPattern("40 55 53 56 57 41 54 41 55 41 56 41 57 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 45 33 F6 4C 8B E1 45 0F B6 E9 49 8B F8 41 8B C6").Get(); {
auto addr = Memcury::Scanner::FindPattern("40 55 53 56 57 41 54 41 55 41 56 41 57 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 45 33 F6 4C 8B E1 45 0F B6 E9 49 8B F8 41 8B C6", false).Get();
if (!addr)
addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 4C 89 64 24 ? 55 41 55 41 57 48 8B EC 48 83 EC 60 45 8A E1 4C 8B E9 48 83 FA").Get(); // 20.00
return addr;
}
if (Engine_Version >= 427) // ok so like the func is split up in ida idfk what to do about it if (Engine_Version >= 427) // ok so like the func is split up in ida idfk what to do about it
{ {
@@ -608,6 +617,8 @@ static inline uint64 FindSetWorld()
SetWorldIndex = 0x73; SetWorldIndex = 0x73;
else if (Fortnite_Season >= 19 && Fortnite_Season < 21) else if (Fortnite_Season >= 19 && Fortnite_Season < 21)
SetWorldIndex = 0x7A; SetWorldIndex = 0x7A;
if (Fortnite_Version == 20.40)
SetWorldIndex = 0x7B;
// static auto DefaultNetDriver = FindObject("/Script/Engine.Default__NetDriver"); // static auto DefaultNetDriver = FindObject("/Script/Engine.Default__NetDriver");
return SetWorldIndex; return SetWorldIndex;
@@ -1447,7 +1458,12 @@ static inline uint64 FindChangeGameSessionId()
static inline uint64 FindDispatchRequest() static inline uint64 FindDispatchRequest()
{ {
auto Addrr = Memcury::Scanner::FindStringRef(L"MCP-Profile: Dispatching request to %s", true, 0, Fortnite_Version >= 19).Get(); auto Addrr = Memcury::Scanner::FindStringRef(L"MCP-Profile: Dispatching request to %s", false, 0, Fortnite_Version >= 19).Get();
if (!Addrr)
{
return 0;
}
for (int i = 0; i < 1000; i++) for (int i = 0; i < 1000; i++)
{ {
@@ -1477,6 +1493,9 @@ static inline uint64 FindMcpIsDedicatedServerOffset()
static inline uint64 FindGIsClient() static inline uint64 FindGIsClient()
{ {
if (Fortnite_Version >= 20)
return 0;
// if (Fortnite_Version == 2.5) // if (Fortnite_Version == 2.5)
// return __int64(GetModuleHandleW(0)) + 0x46AD734; // return __int64(GetModuleHandleW(0)) + 0x46AD734;
/* if (Fortnite_Version == 1.72) /* if (Fortnite_Version == 1.72)
@@ -1821,9 +1840,12 @@ static inline uint64 FindCantBuild()
if (!add) if (!add)
add = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 41 56 41 57 48 83 EC 60 49 8B E9 4D 8B F8 48 8B DA 48 8B F9 BE ? ? ? ? 48").Get(); // 5.00 add = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 41 56 41 57 48 83 EC 60 49 8B E9 4D 8B F8 48 8B DA 48 8B F9 BE ? ? ? ? 48").Get(); // 5.00
if (!add)
add = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 41 56 41 57 48 83 EC 70 49 8B E9 4D 8B F8 48 8B DA 48 8B F9").Get(); // 20.00
return add; return add;
auto CreateBuildingActorAddr = Memcury::Scanner(GetFunctionIdxOrPtr(FindObject<UFunction>("/Script/FortniteGame.FortAIController.CreateBuildingActor"))); auto CreateBuildingActorAddr = Memcury::Scanner(GetFunctionIdxOrPtr(FindObject<UFunction>(L"/Script/FortniteGame.FortAIController.CreateBuildingActor")));
auto LikeHuh = Memcury::Scanner(FindBytes(CreateBuildingActorAddr, { 0x40, 0x88 }, 3000)); auto LikeHuh = Memcury::Scanner(FindBytes(CreateBuildingActorAddr, { 0x40, 0x88 }, 3000));
auto callaa = Memcury::Scanner(FindBytes(LikeHuh, { 0xE8 })); auto callaa = Memcury::Scanner(FindBytes(LikeHuh, { 0xE8 }));
@@ -1848,6 +1870,8 @@ static inline uint64 FindSendClientAdjustment()
{ {
if (Fortnite_Version <= 3.2) if (Fortnite_Version <= 3.2)
return Memcury::Scanner::FindPattern("40 53 48 83 EC 20 48 8B 99 ? ? ? ? 48 39 99 ? ? ? ? 74 0A 48 83 B9").Get(); return Memcury::Scanner::FindPattern("40 53 48 83 EC 20 48 8B 99 ? ? ? ? 48 39 99 ? ? ? ? 74 0A 48 83 B9").Get();
if (Fortnite_Version >= 20)
return Memcury::Scanner::FindPattern("40 53 48 83 EC 20 48 8B 99 ? ? ? ? 48 39 99 ? ? ? ? 74 0A 48 83 B9").Get();
return 0; return 0;
} }
@@ -1866,6 +1890,9 @@ static inline uint64 FindReplicateActor()
return addr; return addr;
} }
if (Fortnite_Version >= 20)
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 ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 4C 8D 69 68").Get();
return 0; return 0;
} }
@@ -1873,6 +1900,8 @@ static inline uint64 FindCreateChannel()
{ {
if (Fortnite_Version <= 3.2) if (Fortnite_Version <= 3.2)
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 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();
if (Fortnite_Version >= 20)
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 44 89 4C 24 ? 55 57 41 54 41 56 41 57 48 8B EC 48 83 EC 50 45 33 E4 48 8D 05 ? ? ? ? 44 38 25").Get();
return 0; return 0;
} }
@@ -1890,6 +1919,8 @@ static inline uint64 FindSetChannelActor()
return aa; return aa;
} }
if (Fortnite_Version >= 20)
return Memcury::Scanner::FindPattern("40 55 53 56 57 41 54 41 56 41 57 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 45 33 E4 48 8D 3D ? ? ? ? 44 89 A5").Get();
return 0; return 0;
} }
@@ -1902,6 +1933,8 @@ static inline uint64 FindCallPreReplication()
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 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();
if (Fortnite_Version >= 2.5 && Fortnite_Version <= 3.2) if (Fortnite_Version >= 2.5 && Fortnite_Version <= 3.2)
return Memcury::Scanner::FindPattern("48 85 D2 0F 84 ? ? ? ? 56 41 56 48 83 EC 38 4C 8B F2").Get(); return Memcury::Scanner::FindPattern("48 85 D2 0F 84 ? ? ? ? 56 41 56 48 83 EC 38 4C 8B F2").Get();
if (Fortnite_Version >= 20)
return Memcury::Scanner::FindPattern("48 85 D2 0F 84 ? ? ? ? 48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 41 56 41 57 48 83 EC 40 F6 41 58 30 48 8B EA 48 8B D9 40 B6 01").Get();
return 0; return 0;
} }

View File

@@ -263,9 +263,15 @@ static inline bool ButtonCentered(const std::string& text, bool bNewLine = true)
static inline void InputVector(const std::string& baseText, FVector* vec) static inline void InputVector(const std::string& baseText, FVector* vec)
{ {
#ifdef ABOVE_S20
ImGui::InputDouble((baseText + " X").c_str(), &vec->X);
ImGui::InputDouble((baseText + " Y").c_str(), &vec->Y);
ImGui::InputDouble((baseText + " Z").c_str(), &vec->Z);
#else
ImGui::InputFloat((baseText + " X").c_str(), &vec->X); ImGui::InputFloat((baseText + " X").c_str(), &vec->X);
ImGui::InputFloat((baseText + " Y").c_str(), &vec->Y); ImGui::InputFloat((baseText + " Y").c_str(), &vec->Y);
ImGui::InputFloat((baseText + " Z").c_str(), &vec->Z); ImGui::InputFloat((baseText + " Z").c_str(), &vec->Z);
#endif
} }
static int Width = 640; static int Width = 640;

View File

@@ -59,6 +59,8 @@ inline bool IsRestartingSupported()
return Engine_Version >= 419 && Engine_Version < 424; return Engine_Version >= 419 && Engine_Version < 424;
} }
// #define ABOVE_S20
/* /*
enum class AllocatorType enum class AllocatorType