Thank you logic teacher (rep is almost done)

This commit is contained in:
Gray
2024-03-21 21:44:13 -04:00
parent 79bcabbbd0
commit d6ef444272
10 changed files with 359 additions and 46 deletions

View File

@@ -12,6 +12,97 @@ class TBitArray;
template<typename Allocator = FDefaultBitArrayAllocator>
class TConstSetBitIterator;
class FBitReference
{
public:
FORCEINLINE FBitReference(uint32& InData, uint32 InMask)
: Data(InData)
, Mask(InMask)
{}
FORCEINLINE operator bool() const
{
return (Data & Mask) != 0;
}
FORCEINLINE void operator=(const bool NewValue)
{
if (NewValue)
{
Data |= Mask;
}
else
{
Data &= ~Mask;
}
}
/*
FORCEINLINE void AtomicSet(const bool NewValue)
{
if (NewValue)
{
if (!(Data & Mask))
{
while (1)
{
uint32 Current = Data;
uint32 Desired = Current | Mask;
if (Current == Desired || FPlatformAtomics::InterlockedCompareExchange((volatile int32*)&Data, (int32)Desired, (int32)Current) == (int32)Current)
{
return;
}
}
}
}
else
{
if (Data & Mask)
{
while (1)
{
uint32 Current = Data;
uint32 Desired = Current & ~Mask;
if (Current == Desired || FPlatformAtomics::InterlockedCompareExchange((volatile int32*)&Data, (int32)Desired, (int32)Current) == (int32)Current)
{
return;
}
}
}
}
}
*/
FORCEINLINE FBitReference& operator=(const FBitReference& Copy)
{
// As this is emulating a reference, assignment should not rebind,
// it should write to the referenced bit.
*this = (bool)Copy;
return *this;
}
private:
uint32& Data;
uint32 Mask;
};
class FConstBitReference
{
public:
FORCEINLINE FConstBitReference(const uint32& InData, uint32 InMask)
: Data(InData)
, Mask(InMask)
{}
FORCEINLINE operator bool() const
{
return (Data & Mask) != 0;
}
private:
const uint32& Data;
uint32 Mask;
};
template<typename Allocator /*= FDefaultBitArrayAllocator*/>
class TBitArray
{
@@ -36,6 +127,23 @@ public:
*this = Copy;
}
FORCEINLINE FBitReference operator[](int32 Index)
{
// check(Index >= 0 && Index < NumBits);
return FBitReference(
GetData()[Index / NumBitsPerDWORD],
1 << (Index & (NumBitsPerDWORD - 1))
);
}
FORCEINLINE const FConstBitReference operator[](int32 Index) const
{
// check(Index >= 0 && Index < NumBits);
return FConstBitReference(
GetData()[Index / NumBitsPerDWORD],
1 << (Index & (NumBitsPerDWORD - 1))
);
}
FORCEINLINE const uint32* GetData() const
{
return (uint32*)AllocatorInstance.GetAllocation();

View File

@@ -0,0 +1,17 @@
#pragma once
#include "inc.h"
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);
}
};

View File

@@ -0,0 +1,9 @@
#pragma once
#include <type_traits>
template <typename T>
struct TIsTriviallyDestructible
{
enum { Value = std::is_trivially_destructible_v<T> };
};

View File

@@ -83,4 +83,4 @@ inline uint32 GetTypeHash(const FName N)
return N.ComparisonIndex.Value + N.GetNumber();
}
#define NAME_None FName(0);
#define NAME_None FName(0)

View File

@@ -79,11 +79,11 @@ public:
return Get<double>(LastReceiveTimeOffset);
}
/* TSet<FName>& GetClientVisibleLevelNames()
TSet<FName>& GetClientVisibleLevelNames()
{
static auto ClientVisibleLevelNamesOffset = 0x336C8;
return *(TSet<FName>*)(__int64(this) + ClientVisibleLevelNamesOffset);
} */
}
class UNetDriver*& GetDriver()
{

View File

@@ -9,6 +9,7 @@
#include <random>
#include "Package.h"
#include "AssertionMacros.h"
#include "CoreNet.h"
#include "ChildConnection.h"
#include "bots.h"
#include "NetworkingDistanceConstants.h"
@@ -131,13 +132,6 @@ bool UNetDriver::IsLevelInitializedForActor(const AActor* InActor, const UNetCon
return true;
}
/* #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) // (Milxnor) This is on some ue versions and others not.
if (!InActor || !InConnection)
return false;
// check(World == InActor->GetWorld());
#endif */
bool bFirstWorldCheck = Engine_Version == 416
? (InConnection->GetClientWorldPackageName() == GetWorld()->GetOutermost()->GetFName())
: (InConnection->GetClientWorldPackageName() == GetWorldPackage()->NamePrivate);
@@ -155,7 +149,7 @@ FNetViewer::FNetViewer(UNetConnection* InConnection, float DeltaSeconds) :
ViewDir(ForceInit)
{
if (!InConnection->GetOwningActor()) return;
if (InConnection->GetPlayerController() || (InConnection->GetPlayerController() != InConnection->GetOwningActor())) return;
if (InConnection->GetPlayerController() && (InConnection->GetPlayerController() != InConnection->GetOwningActor())) return;
APlayerController* ViewingController = InConnection->GetPlayerController();
@@ -163,7 +157,7 @@ FNetViewer::FNetViewer(UNetConnection* InConnection, float DeltaSeconds) :
if (ViewingController)
{
FRotator ViewRotation = ViewingController->GetControlRotation();
ViewingController->GetActorEyesViewPoint(&ViewLocation, &ViewRotation); // T(REP)
ViewingController->GetActorEyesViewPoint(&ViewLocation, &ViewRotation);
ViewDir = ViewRotation.Vector();
}
}
@@ -542,6 +536,58 @@ int32 UNetDriver::ServerReplicateActors_PrioritizeActors(UNetConnection* Connect
return FinalSortedCount;
}
using FArchive = void;
__declspec(noinline) void SetChannelActorForDestroy(UActorChannel* Channel, FActorDestructionInfo* DestructInfo)
{
auto Connection = Channel->GetConnection();
// check(Connection->Channels[ChIndex]==Channel);
if (
true
// T(REP)
)
{
// You can get size by searching "Making partial bunch from content bunch. bitsThisBunch: %d bitsLeft: %d", there is a new call.
struct FOutBunch
{
char pad[0x110];
};
LOG_INFO(LogDev, "SetChannelActorForDestroy PathName: {}", DestructInfo->PathName.ToString());
FOutBunch(*ConstructorFOutBunch)(FOutBunch*, UChannel*, bool) = decltype(ConstructorFOutBunch)(__int64(GetModuleHandleW(0)) + 0x194E800);
FOutBunch CloseBunch{};
auto Helloooo = ConstructorFOutBunch(&CloseBunch, Channel, 1);
// check(!CloseBunch.IsError());
// check(CloseBunch.bClose);
LOG_INFO(LogDev, "Called Constructor!");
// https://imgur.com/a/EtKFkrD
*(bool*)(__int64(&CloseBunch) + 0xE8) = 1; // bReliable
*(bool*)(__int64(&CloseBunch) + 0xE6) = 0; // bDormant
// NET_CHECKSUM(CloseBunch); // This is to mirror the Checksum in UPackageMapClient::SerializeNewActor
using UPackageMap = UObject;
reinterpret_cast<bool(*)(UPackageMap*,
// FArchive& Ar,
FOutBunch& Ar,
UObject* InOuter, FNetworkGUID NetGUID, FString ObjName)>(Connection->GetPackageMap()->VFTable[0x238 / 8])
(Connection->GetPackageMap(), CloseBunch, DestructInfo->ObjOuter.Get(), DestructInfo->NetGUID, DestructInfo->PathName); // WriteObject
// 0x196E9C0
reinterpret_cast<FPacketIdRange(*)(UActorChannel*, FOutBunch*, bool)>(Channel->VFTable[0x288 / 8])(Channel, &CloseBunch, false); // SendBunch
// TODO FARCHIVE::~FARHCIVE
}
}
int32 UNetDriver::ServerReplicateActors_ProcessPrioritizedActors(UNetConnection* Connection, const std::vector<FNetViewer>& ConnectionViewers, std::vector<FActorPriority*>& PriorityActors, const int32 FinalSortedCount, int32& OutUpdated)
{
int32 ActorUpdatesThisConnection = 0;
@@ -557,12 +603,11 @@ int32 UNetDriver::ServerReplicateActors_ProcessPrioritizedActors(UNetConnection*
{
FNetworkObjectInfo* ActorInfo = PriorityActors[j]->ActorInfo;
// Deletion entry
if (ActorInfo == NULL && PriorityActors[j]->DestructionInfo)
{
/*
if (PriorityActors[j]->DestructionInfo->StreamingLevelName != NAME_None &&
!Connection->GetClientVisibleLevelNames().Contains(PriorityActors[j]->DestructionInfo->StreamingLevelName)
if (PriorityActors[j]->DestructionInfo->StreamingLevelName != NAME_None
&& !Connection->GetClientVisibleLevelNames().Contains(PriorityActors[j]->DestructionInfo->StreamingLevelName)
)
{
continue;
@@ -573,7 +618,7 @@ int32 UNetDriver::ServerReplicateActors_ProcessPrioritizedActors(UNetConnection*
{
FinalRelevantCount++;
Channel->SetChannelActorForDestroy(PriorityActors[j]->DestructionInfo);
SetChannelActorForDestroy(Channel, PriorityActors[j]->DestructionInfo);
Connection->GetDestroyedStartupOrDormantActors().Remove(PriorityActors[j]->DestructionInfo->NetGUID);
}
@@ -621,6 +666,7 @@ int32 UNetDriver::ServerReplicateActors_ProcessPrioritizedActors(UNetConnection*
Channel = (UActorChannel*)Connection->CreateChannel(CHTYPE_Actor, 1, EChannelCreateFlags::OpenedLocally);
if (Channel)
{
LOG_INFO(LogDev, "Replicating: {}", Actor->GetFullName());
Channel->SetChannelActor(Actor, ESetChannelActorFlags::None1);
}
}

View File

@@ -315,6 +315,7 @@
<ClInclude Include="ContainerAllocationPolicies.h" />
<ClInclude Include="Controller.h" />
<ClInclude Include="builder.h" />
<ClInclude Include="CoreNet.h" />
<ClInclude Include="CurveTable.h" />
<ClInclude Include="DataTable.h" />
<ClInclude Include="DataTableFunctionLibrary.h" />
@@ -431,6 +432,7 @@
<ClInclude Include="IsPODType.h" />
<ClInclude Include="IsPointer.h" />
<ClInclude Include="IsTriviallyCopyConstructible.h" />
<ClInclude Include="IsTriviallyDestructible.h" />
<ClInclude Include="KismetMathLibrary.h" />
<ClInclude Include="KismetStringLibrary.h" />
<ClInclude Include="KismetSystemLibrary.h" />

View File

@@ -999,6 +999,12 @@
<ClInclude Include="NetworkingDistanceConstants.h">
<Filter>Engine\Source\Runtime\Engine\Public</Filter>
</ClInclude>
<ClInclude Include="CoreNet.h">
<Filter>Engine\Source\Runtime\CoreUObject\Public\UObject</Filter>
</ClInclude>
<ClInclude Include="IsTriviallyDestructible.h">
<Filter>Engine\Source\Runtime\Core\Public\Templates</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Engine">

View File

@@ -5,38 +5,9 @@
#include "SparseArray.h"
#include "ChooseClass.h"
#include "UnrealTypeTraits.h"
#include "UnrealTemplate.h"
template <typename ElementType>
class TSetElement
{
public:
ElementType Value;
mutable int32 HashNextId;
mutable int32 HashIndex;
TSetElement(ElementType InValue, int32 InHashNextId, int32 InHashIndex)
: Value(InValue)
, HashNextId(InHashNextId)
, HashIndex(InHashIndex)
{
}
FORCEINLINE TSetElement<ElementType>& operator=(const TSetElement<ElementType>& Other)
{
Value = Other.Value;
}
FORCEINLINE bool operator==(const TSetElement& Other) const
{
return Value == Other.Value;
}
FORCEINLINE bool operator!=(const TSetElement& Other) const
{
return Value != Other.Value;
}
};
/** Either NULL or an identifier for an element of a set. */
class FSetElementId
{
public:
@@ -90,6 +61,45 @@ private:
}
};
template <typename InElementType>
class TSetElement
{
public:
typedef InElementType ElementType;
ElementType Value;
mutable FSetElementId HashNextId;
mutable int32 HashIndex;
FORCEINLINE TSetElement()
{}
/** Initialization constructor. */
// template <typename InitType, typename = typename TEnableIf<!TAreTypesEqual<TSetElement, typename TDecay<InitType>::Type>::Value>::Type> explicit FORCEINLINE TSetElement(InitType&& InValue) : Value/////(Forward<InitType>(InValue)) {} // T(R)
FORCEINLINE TSetElement(const TSetElement& Rhs) : Value(Rhs.Value), HashNextId(Rhs.HashNextId), HashIndex(Rhs.HashIndex) {}
FORCEINLINE TSetElement(TSetElement&& Rhs) : Value(MoveTempIfPossible(Rhs.Value)), HashNextId(MoveTemp(Rhs.HashNextId)), HashIndex(Rhs.HashIndex) {}
FORCEINLINE TSetElement& operator=(const TSetElement& Rhs) { Value = Rhs.Value; HashNextId = Rhs.HashNextId; HashIndex = Rhs.HashIndex; return *this; }
FORCEINLINE TSetElement& operator=(TSetElement&& Rhs) { Value = MoveTempIfPossible(Rhs.Value); HashNextId = MoveTemp(Rhs.HashNextId); HashIndex = Rhs.HashIndex; return *this; }
/*
FORCEINLINE friend FArchive & operator<<(FArchive & Ar, TSetElement & Element)
{
return Ar << Element.Value;
}
*/
FORCEINLINE bool operator==(const TSetElement& Other) const
{
return Value == Other.Value;
}
FORCEINLINE bool operator!=(const TSetElement& Other) const
{
return Value != Other.Value;
}
};
template<typename ElementType, typename InKeyType, bool bInAllowDuplicateKeys = false>
struct BaseKeyFuncs
{
@@ -152,6 +162,9 @@ private:
public:
typedef typename KeyFuncs::KeyInitType KeyInitType;
typedef typename KeyFuncs::ElementInitType ElementInitType;
// using SizeType = typename Allocator::SparseArrayAllocator::ElementAllocator::SizeType; // Milxnor: Bruh idk
using SizeType = int32;
static_assert(std::is_same_v<SizeType, int32>, "TSet currently only supports 32-bit allocators");
typedef TSetElement<InElementType> SetElementType;
@@ -170,7 +183,82 @@ public:
return ((FSetElementId*)Hash.GetAllocation())[HashIndex & (HashSize - 1)];
}
private:
template<typename ComparableKey>
FORCEINLINE int32 RemoveImpl(uint32 KeyHash, const ComparableKey& Key)
{
int32 NumRemovedElements = 0;
FSetElementId* NextElementId = &GetTypedHash(KeyHash);
while (NextElementId->IsValidId())
{
SetElementType& Element = Elements[NextElementId->Index];
if (KeyFuncs::Matches(KeyFuncs::GetSetKey(Element.Value), Key))
{
// This element matches the key, remove it from the set. Note that Remove sets *NextElementId to point to the next
// element after the removed element in the hash bucket.
RemoveByIndex(NextElementId->Index);
NumRemovedElements++;
if (!KeyFuncs::bAllowDuplicateKeys)
{
// If the hash disallows duplicate keys, we're done removing after the first matched key.
break;
}
}
else
{
NextElementId = &Element.HashNextId;
}
}
return NumRemovedElements;
}
public:
void RemoveByIndex(SizeType ElementIndex)
{
// checkf(Elements.IsValidIndex(ElementIndex), TEXT("Invalid ElementIndex passed to TSet::RemoveByIndex"));
const SetElementType& ElementBeingRemoved = Elements[ElementIndex];
// Remove the element from the hash.
FSetElementId* HashPtr = Hash.GetAllocation();
SizeType* NextElementIndexIter = &HashPtr[ElementBeingRemoved.HashIndex].Index;
for (;;)
{
SizeType NextElementIndex = *NextElementIndexIter;
// checkf(NextElementIndex != INDEX_NONE, TEXT("Corrupt hash"));
if (NextElementIndex == ElementIndex)
{
*NextElementIndexIter = ElementBeingRemoved.HashNextId.Index;
break;
}
NextElementIndexIter = &Elements[NextElementIndex].HashNextId.Index;
}
// Remove the element from the elements array.
Elements.RemoveAt(ElementIndex);
}
void Remove(FSetElementId ElementId)
{
RemoveByIndex(ElementId.Index);
}
int32 Remove(KeyInitType Key)
{
if (Elements.Num())
{
return RemoveImpl(KeyFuncs::GetKeyHash(Key), Key);
}
return 0;
}
FORCEINLINE ElementType* Find(KeyInitType Key)
{
FSetElementId ElementId = FindId(Key);

View File

@@ -5,6 +5,7 @@
#include "ChooseClass.h"
#include "log.h"
#include "TypeCompatibleBytes.h"
#include "IsTriviallyDestructible.h"
#define INDEX_NONE -1
@@ -53,6 +54,42 @@ public:
{
return Data.Num() - NumFreeIndices;
}
void RemoveAt(int32 Index, int32 Count = 1)
{
if (!TIsTriviallyDestructible<ElementType>::Value)
{
for (int32 It = Index, ItCount = Count; ItCount; ++It, --ItCount)
{
((ElementType&)GetData(It).ElementData).~ElementType();
}
}
RemoveAtUninitialized(Index, Count);
}
/** Removes Count elements from the array, starting from Index, without destructing them. */
void RemoveAtUninitialized(int32 Index, int32 Count = 1)
{
for (; Count; --Count)
{
// check(AllocationFlags[Index]);
// Mark the element as free and add it to the free element list.
if (NumFreeIndices)
{
GetData(FirstFreeIndex).PrevFreeIndex = Index;
}
auto& IndexData = GetData(Index);
IndexData.PrevFreeIndex = -1;
IndexData.NextFreeIndex = NumFreeIndices > 0 ? FirstFreeIndex : INDEX_NONE;
FirstFreeIndex = Index;
++NumFreeIndices;
AllocationFlags[Index] = false;
++Index;
}
}
template<bool bConst>
class TBaseIterator
{