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