mirror of
https://github.com/Milxnor/Project-Reboot-3.0.git
synced 2026-01-13 02:42:22 +01:00
performace
This commit is contained in:
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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 };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 }
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user