This commit is contained in:
Gray
2024-03-12 19:10:18 -04:00
parent 1169eb80cc
commit 512fb16ee4
10 changed files with 302 additions and 48 deletions

View File

@@ -56,7 +56,9 @@ void UNetDriver::TickFlushHook(UNetDriver* NetDriver)
if (Globals::bStartedListening)
{
static auto ReplicationDriverOffset = NetDriver->GetOffset("ReplicationDriver", false);
static auto ReplicationDriverOffset = NetDriver->GetOffset("ReplicationDriver"/*, false */);
// LOG_INFO(LogDev, "ReplicationDriverOffset{}", ReplicationDriverOffset);
// if (ReplicationDriverOffset == -1)
if (ReplicationDriverOffset == -1 || Fortnite_Version >= 20)
@@ -66,13 +68,25 @@ void UNetDriver::TickFlushHook(UNetDriver* NetDriver)
else
{
if (auto ReplicationDriver = NetDriver->Get(ReplicationDriverOffset))
{
reinterpret_cast<void(*)(UObject*)>(ReplicationDriver->VFTable[Offsets::ServerReplicateActors])(ReplicationDriver);
}
else
{
// LOG_INFO(LogDev, "ReplicationDriver is nul!!?1//33/221/4/124/123"); // 3.3 MOMENT
}
}
}
return TickFlushOriginal(NetDriver);
}
enum class EChannelCreateFlags : uint32_t
{
None = (1 << 0),
OpenedLocally = (1 << 1)
};
int32 ServerReplicateActors_PrepConnections(UNetDriver* NetDriver)
{
auto& ClientConnections = NetDriver->GetClientConnections();
@@ -448,6 +462,117 @@ bool UNetDriver::IsLevelInitializedForActor(const AActor* InActor, const UNetCon
return bCorrectWorld || bIsConnectionPC;
}
TMap<FNetworkGUID, FActorDestructionInfo>* GetDestroyedStartupOrDormantActors(UNetDriver* Driver)
{
static int off = Fortnite_Version == 1.11 ? 0x228 : 0; // 0x240
return off == 0 ? nullptr : (TMap<FNetworkGUID, FActorDestructionInfo>*)(__int64(Driver) + off);
}
TSet<FNetworkGUID>* GetDestroyedStartupOrDormantActors(UNetConnection* NetConnection)
{
static int off = Fortnite_Version == 1.11 ? 0x33678 : 0;
return off == 0 ? nullptr : (TSet<FNetworkGUID>*)(__int64(NetConnection) + off);
}
using FArchive = void;
bool IsError(FArchive* Ar)
{
return false;
}
void SerializeChecksum(FArchive* Ar, uint32 x, bool ErrorOK)
{
/*
if (Ar->IsLoading())
{
uint32 Magic = 0;
Ar << Magic;
if ((!ErrorOK || !IsError(Ar))
// && !ensure(Magic == x)
)
{
// UE_LOG(LogCoreNet, Warning, TEXT("%d == %d"), Magic, x);
}
}
else
{
uint32 Magic = x;
Ar << Magic;
}
*/
}
#define NET_CHECKSUM(Ser) \
{ \
SerializeChecksum(Ser,0xE282FA84, false); \
}
struct FPacketIdRange
{
FPacketIdRange(int32 _First, int32 _Last) : First(_First), Last(_Last) { }
FPacketIdRange(int32 PacketId) : First(PacketId), Last(PacketId) { }
FPacketIdRange() : First(INDEX_NONE), Last(INDEX_NONE) { }
int32 First;
int32 Last;
bool InRange(int32 PacketId) const
{
return (First <= PacketId && PacketId <= Last);
}
};
void SetChannelActorForDestroy(UActorChannel* Channel, FActorDestructionInfo* DestructInfo)
{
auto Connection = Channel->GetConnection();
if (
true
// && !Channel->IsClosing()
// && (Connection->State == USOCK_Open || Connection->State == USOCK_Pending)
)
{
// Send a close notify, and wait for ack.
struct FOutBunch
{
char pad[0x600]; // idk real size
};
FOutBunch CloseBunch{};
FOutBunch(*ConstructorFOutBunch)(FOutBunch*, UChannel* , bool) = decltype(ConstructorFOutBunch)(__int64(GetModuleHandleW(0)) + 0x194E800);
ConstructorFOutBunch(&CloseBunch, Channel, 1);
// check(!CloseBunch.IsError());
// check(CloseBunch.bClose);
// https://imgur.com/a/EtKFkrD
*(bool*)(__int64(&CloseBunch) + 0xE8) = 1;
*(bool*)(__int64(&CloseBunch) + 0xE6) = 0;
// Serialize DestructInfo
// NET_CHECKSUM(CloseBunch); // This is to mirror the Checksum in UPackageMapClient::SerializeNewActor
using UPackageMap = UObject;
reinterpret_cast<bool(*)(UPackageMap*, FArchive * Ar, UObject * InOuter,FNetworkGUID NetGUID, FString ObjName)>(Connection->GetPackageMap()->VFTable[0x238 / 8])(Connection->GetPackageMap(), &CloseBunch, DestructInfo->ObjOuter.Get(), DestructInfo->NetGUID, DestructInfo->PathName);
// UE_LOG(LogNetTraffic, Log, TEXT("SetChannelActorForDestroy: Channel %d. NetGUID <%s> Path: %s. Bits: %d"), ChIndex, *DestructInfo->NetGUID.ToString(), *DestructInfo->PathName, CloseBunch.GetNumBits());
// UE_LOG(LogNetDormancy, Verbose, TEXT("SetChannelActorForDestroy: Channel %d. NetGUID <%s> Path: %s. Bits: %d"), ChIndex, *DestructInfo->NetGUID.ToString(), *DestructInfo->PathName, CloseBunch.GetNumBits());
// 0x196E9C0
reinterpret_cast<FPacketIdRange(*)(UActorChannel*, FOutBunch*, bool)>(Channel->VFTable[0x288 / 8])(Channel, &CloseBunch, false);
}
}
TSet<FName>* GetClientVisibleLevelNames(UNetConnection* NetConnection)
{
return (TSet<FName>*)(__int64(NetConnection) + 0x336C8);
}
int32 UNetDriver::ServerReplicateActors()
{
int32 Updated = 0;
@@ -487,6 +612,11 @@ int32 UNetDriver::ServerReplicateActors()
// LOG_INFO(LogReplication, "Considering {} actors.", ConsiderList.size());
static UChannel* (*CreateChannel)(UNetConnection*, int, bool, int32_t) = decltype(CreateChannel)(Addresses::CreateChannel);
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);
for (int32 i = 0; i < this->GetClientConnections().Num(); i++)
{
UNetConnection* Connection = this->GetClientConnections().at(i);
@@ -522,6 +652,85 @@ int32 UNetDriver::ServerReplicateActors()
Connection->GetSentTemporaries().at(j)->GetNetTag() = GetNetTag();
} */
std::vector<FActorDestructionInfo*> DeletionEntries;
auto ConnectionDestroyedStartupOrDormantActors = GetDestroyedStartupOrDormantActors(Connection);
if (ConnectionDestroyedStartupOrDormantActors)
{
auto DriverDestroyedStartupOrDormantActors = GetDestroyedStartupOrDormantActors(this);
if (DriverDestroyedStartupOrDormantActors)
{
for (FNetworkGUID& ConnectionIt : *ConnectionDestroyedStartupOrDormantActors)
{
FActorDestructionInfo* DInfo = nullptr;
for (TPair<FNetworkGUID, FActorDestructionInfo>& DriverIt : *DriverDestroyedStartupOrDormantActors)
{
if (DriverIt.First == ConnectionIt)
{
DInfo = &DriverIt.Second;
break;
}
}
if (!DInfo) continue; // should never happen
DeletionEntries.push_back(DInfo);
}
}
}
LOG_INFO(LogDev, "DeletionEntries: {}", DeletionEntries.size());
for (FActorDestructionInfo* DeletionEntry : DeletionEntries)
{
LOG_INFO(LogDev, "AA: {}", DeletionEntry->PathName.Data.Data ? DeletionEntry->PathName.ToString() : "Null");
if (DeletionEntry->StreamingLevelName != -1)
{
auto ClientVisibleLevelNames = GetClientVisibleLevelNames(Connection);
bool bFound = false;
for (FName& ClientVisibleLevelName : *ClientVisibleLevelNames)
{
if (ClientVisibleLevelName == DeletionEntry->StreamingLevelName)
{
bFound = true;
break;
}
}
if (!bFound)
continue;
}
UActorChannel* Channel = nullptr;
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)
{
// FinalRelevantCount++;
SetChannelActorForDestroy(Channel, DeletionEntry); // Send a close bunch on the new channel
GetDestroyedStartupOrDormantActors(Connection)->Remove(DeletionEntry->NetGUID); // Remove from connections to-be-destroyed list (close bunch of reliable, so it will make it there)
}
}
for (auto& ActorInfo : ConsiderList)
{
if (!ActorInfo || !ActorInfo->Actor)
@@ -592,16 +801,6 @@ 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 __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);
if (!Channel)
{