mirror of
https://github.com/Milxnor/Project-Reboot-3.0.git
synced 2026-01-13 02:42:22 +01:00
Dude 💀
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "reboot.h"
|
||||
#include "GameplayStatics.h"
|
||||
#include "Level.h"
|
||||
|
||||
bool AActor::HasAuthority()
|
||||
{
|
||||
@@ -11,6 +12,11 @@ bool AActor::HasAuthority()
|
||||
return Get<uint8_t>(RoleOffset) == 3;
|
||||
}
|
||||
|
||||
bool AActor::GetNetDormancy(const FVector& ViewPos, const FVector& ViewDir, AActor* Viewer, AActor* ViewTarget, class UActorChannel* InChannel, float Time, bool bLowBandwidth) // T(REP)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AActor::IsTearOff()
|
||||
{
|
||||
static auto bTearOffOffset = GetOffset("bTearOff");
|
||||
@@ -18,7 +24,12 @@ bool AActor::IsTearOff()
|
||||
return ReadBitfieldValue(bTearOffOffset, bTearOffFieldMask);
|
||||
}
|
||||
|
||||
/* FORCEINLINE */ ENetDormancy& AActor::GetNetDormancy()
|
||||
ULevel* AActor::GetLevel() const
|
||||
{
|
||||
return GetTypedOuter<ULevel>();
|
||||
}
|
||||
|
||||
/* FORCEINLINE */ ENetDormancy& AActor::NetDormancy()
|
||||
{
|
||||
static auto NetDormancyOffset = GetOffset("NetDormancy");
|
||||
return Get<ENetDormancy>(NetDormancyOffset);
|
||||
@@ -38,15 +49,6 @@ FTransform AActor::GetTransform()
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
UWorld* AActor::GetWorld()
|
||||
{
|
||||
return GetWorld(); // for real
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
void AActor::SetNetDormancy(ENetDormancy Dormancy)
|
||||
{
|
||||
static auto SetNetDormancyFn = FindObject<UFunction>(L"/Script/Engine.Actor.SetNetDormancy");
|
||||
@@ -63,6 +65,18 @@ AActor* AActor::GetOwner()
|
||||
return Owner;
|
||||
}
|
||||
|
||||
FName& AActor::GetNetDriverName()
|
||||
{
|
||||
static auto NetDriverNameOffset = GetOffset("NetDriverName");
|
||||
return Get<FName>(NetDriverNameOffset);
|
||||
}
|
||||
|
||||
ENetRole& AActor::GetRemoteRole()
|
||||
{
|
||||
static auto RemoteRoleOffset = GetOffset("RemoteRole");
|
||||
return Get<ENetRole>(RemoteRoleOffset);
|
||||
}
|
||||
|
||||
void AActor::K2_DestroyActor()
|
||||
{
|
||||
static auto DestroyActorFn = FindObject<UFunction>("/Script/Engine.Actor.K2_DestroyActor");
|
||||
@@ -195,12 +209,12 @@ void AActor::ForceNetUpdate()
|
||||
this->ProcessEvent(ForceNetUpdateFn);
|
||||
}
|
||||
|
||||
bool AActor::IsNetStartupActor()
|
||||
bool AActor::IsNetStartupActor() // T(REP)
|
||||
{
|
||||
return IsNetStartup(); // The implementation on this function depends on the version.
|
||||
}
|
||||
|
||||
bool AActor::IsPendingKillPending()
|
||||
bool AActor::IsPendingKillPending() // T(REP)
|
||||
{
|
||||
return IsActorBeingDestroyed() || !IsValidChecked(this);
|
||||
}
|
||||
@@ -246,6 +260,11 @@ const AActor* AActor::GetNetOwner() const
|
||||
return GetNetOwnerOriginal(this);
|
||||
}
|
||||
|
||||
bool AActor::IsActorInitialized() // T(REP)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void AActor::GetActorEyesViewPoint(FVector* OutLocation, FRotator* OutRotation) const
|
||||
{
|
||||
static auto GetActorEyesViewPointFn = FindObject<UFunction>(L"/Script/Engine.Actor.GetActorEyesViewPoint");
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "Object.h"
|
||||
#include "anticheat.h"
|
||||
#include "Vector.h"
|
||||
|
||||
enum class ENetDormancy : uint8_t
|
||||
{
|
||||
@@ -17,15 +18,19 @@ enum class ENetDormancy : uint8_t
|
||||
class AActor : public UObject
|
||||
{
|
||||
public:
|
||||
static inline void (*originalCallPreReplication)(AActor*, class UNetDriver*);
|
||||
struct FTransform GetTransform();
|
||||
|
||||
// class UWorld* GetWorld();
|
||||
bool GetNetDormancy(const FVector& ViewPos, const FVector& ViewDir, AActor* Viewer, AActor* ViewTarget, class UActorChannel* InChannel, float Time, bool bLowBandwidth);
|
||||
bool HasAuthority();
|
||||
bool IsTearOff();
|
||||
/* FORCEINLINE */ ENetDormancy& GetNetDormancy();
|
||||
class ULevel* GetLevel() const;
|
||||
/* FORCEINLINE */ ENetDormancy& NetDormancy();
|
||||
int32& GetNetTag();
|
||||
void SetNetDormancy(ENetDormancy Dormancy);
|
||||
AActor* GetOwner();
|
||||
FName& GetNetDriverName();
|
||||
ENetRole& GetRemoteRole();
|
||||
struct FVector GetActorScale3D();
|
||||
struct FVector GetActorLocation();
|
||||
struct FVector GetActorForwardVector();
|
||||
@@ -52,12 +57,12 @@ public:
|
||||
float& GetNetUpdateFrequency();
|
||||
float& GetMinNetUpdateFrequency();
|
||||
const AActor* GetNetOwner() const;
|
||||
bool IsActorInitialized();
|
||||
void GetActorEyesViewPoint(FVector* OutLocation, FRotator* OutRotation) const;
|
||||
AActor* GetClosestActor(UClass* ActorClass, float DistMax, std::function<bool(AActor*)> AdditionalCheck = [&](AActor*) { return true; });
|
||||
|
||||
bool IsRelevancyOwnerFor(const AActor* ReplicatedActor, const AActor* ActorOwner, const AActor* ConnectionActor) const
|
||||
bool IsRelevancyOwnerFor(const AActor* ReplicatedActor, const AActor* ActorOwner, const AActor* ConnectionActor) const // T(REP)
|
||||
{
|
||||
// we should call virtual function but eh
|
||||
// return (ActorOwner == this);
|
||||
|
||||
static auto IsRelevancyOwnerForOffset = 0x428;
|
||||
|
||||
@@ -3,9 +3,29 @@
|
||||
#include "Channel.h"
|
||||
#include "NetworkGuid.h"
|
||||
|
||||
enum ESetChannelActorFlags
|
||||
{
|
||||
None1 = 0, // Bro compiler what
|
||||
SkipReplicatorCreation = (1 << 0),
|
||||
SkipMarkActive = (1 << 1),
|
||||
};
|
||||
|
||||
class UActorChannel : public UChannel
|
||||
{
|
||||
public:
|
||||
static inline void (*originalSetChannelActor)(UActorChannel*, AActor*);
|
||||
static inline __int64 (*originalReplicateActor)(UActorChannel*);
|
||||
|
||||
void SetChannelActor(AActor* Actor, ESetChannelActorFlags Flags)
|
||||
{
|
||||
originalSetChannelActor(this, Actor); // T(REP) ADD FLAGS FOR NEWER BUILDS
|
||||
}
|
||||
|
||||
__int64 ReplicateActor() // Returns how many bits were replicated (does not include non-bunch packet overhead)
|
||||
{
|
||||
return originalReplicateActor(this);
|
||||
}
|
||||
|
||||
double& GetLastUpdateTime()
|
||||
{
|
||||
static auto LastUpdateTimeOffset = GetOffset("Actor") + 8 + 4 + 4 + 8; // checked on 4.19
|
||||
|
||||
@@ -5,17 +5,7 @@
|
||||
|
||||
#include "MemoryOps.h"
|
||||
#include "ContainerAllocationPolicies.h"
|
||||
|
||||
struct FMemory
|
||||
{
|
||||
static inline void* (*Realloc)(void* Original, SIZE_T Count, uint32_t Alignment /* = DEFAULT_ALIGNMENT */);
|
||||
};
|
||||
|
||||
template <typename T = __int64>
|
||||
static T* AllocUnreal(size_t Size)
|
||||
{
|
||||
return (T*)FMemory::Realloc(0, Size, 0);
|
||||
}
|
||||
#include "IsPointer.h"
|
||||
|
||||
template<typename InElementType> //, typename InAllocatorType>
|
||||
class TArray
|
||||
@@ -26,6 +16,7 @@ public:
|
||||
|
||||
using ElementAllocatorType = InElementType*;
|
||||
using SizeType = int32;
|
||||
typedef InElementType ElementType;
|
||||
|
||||
ElementAllocatorType Data = nullptr; // AllocatorInstance;
|
||||
SizeType ArrayNum;
|
||||
@@ -33,14 +24,46 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
#if TARRAY_RANGED_FOR_CHECKS
|
||||
typedef TCheckedPointerIterator< ElementType, SizeType> RangedForIteratorType;
|
||||
typedef TCheckedPointerIterator<const ElementType, SizeType> RangedForConstIteratorType;
|
||||
#else
|
||||
typedef ElementType* RangedForIteratorType;
|
||||
typedef const ElementType* RangedForConstIteratorType;
|
||||
#endif
|
||||
|
||||
#if TARRAY_RANGED_FOR_CHECKS
|
||||
FORCEINLINE friend RangedForIteratorType begin(TArray& Array) { return RangedForIteratorType(Array.ArrayNum, Array.GetData()); }
|
||||
FORCEINLINE friend RangedForConstIteratorType begin(const TArray& Array) { return RangedForConstIteratorType(Array.ArrayNum, Array.GetData()); }
|
||||
FORCEINLINE friend RangedForIteratorType end(TArray& Array) { return RangedForIteratorType(Array.ArrayNum, Array.GetData() + Array.Num()); }
|
||||
FORCEINLINE friend RangedForConstIteratorType end(const TArray& Array) { return RangedForConstIteratorType(Array.ArrayNum, Array.GetData() + Array.Num()); }
|
||||
#else
|
||||
FORCEINLINE friend RangedForIteratorType begin(TArray& Array) { return Array.GetData(); }
|
||||
FORCEINLINE friend RangedForConstIteratorType begin(const TArray& Array) { return Array.GetData(); }
|
||||
FORCEINLINE friend RangedForIteratorType end(TArray& Array) { return Array.GetData() + Array.Num(); }
|
||||
FORCEINLINE friend RangedForConstIteratorType end(const TArray& Array) { return Array.GetData() + Array.Num(); }
|
||||
#endif
|
||||
|
||||
inline InElementType& At(int i, size_t Size = sizeof(InElementType)) const { return *(InElementType*)(__int64(Data) + (static_cast<long long>(Size) * i)); }
|
||||
inline InElementType& at(int i, size_t Size = sizeof(InElementType)) const { return *(InElementType*)(__int64(Data) + (static_cast<long long>(Size) * i)); }
|
||||
inline InElementType* AtPtr(int i, size_t Size = sizeof(InElementType)) const { return (InElementType*)(__int64(Data) + (static_cast<long long>(Size) * i)); }
|
||||
|
||||
bool IsValidIndex(int i) { return i > 0 && i < ArrayNum; }
|
||||
|
||||
ElementAllocatorType& GetData() const { return Data; }
|
||||
ElementAllocatorType& GetData() { return Data; }
|
||||
InElementType* GetData()
|
||||
{
|
||||
return (InElementType*)Data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for returning a typed pointer to the first array entry.
|
||||
*
|
||||
* @returns Pointer to first array entry or nullptr if ArrayMax == 0.
|
||||
*/
|
||||
const InElementType* GetData() const
|
||||
{
|
||||
return (const InElementType*)Data;
|
||||
}
|
||||
|
||||
void Reserve(int Number, size_t Size = sizeof(InElementType))
|
||||
{
|
||||
|
||||
@@ -1,329 +1,225 @@
|
||||
#pragma once
|
||||
|
||||
#include "ContainerAllocationPolicies.h"
|
||||
|
||||
static FORCEINLINE uint32 CountLeadingZeros(uint32 Value)
|
||||
{
|
||||
unsigned long Log2;
|
||||
if (_BitScanReverse(&Log2, Value) != 0)
|
||||
{
|
||||
return 31 - Log2;
|
||||
}
|
||||
|
||||
return 32;
|
||||
}
|
||||
#include "UnrealMathUtility.h"
|
||||
|
||||
#define NumBitsPerDWORD ((int32)32)
|
||||
#define NumBitsPerDWORDLogTwo ((int32)5)
|
||||
|
||||
template<typename Allocator = FDefaultBitArrayAllocator>
|
||||
class TBitArray;
|
||||
|
||||
template<typename Allocator = FDefaultBitArrayAllocator>
|
||||
class TConstSetBitIterator;
|
||||
|
||||
template<typename Allocator /*= FDefaultBitArrayAllocator*/>
|
||||
class TBitArray
|
||||
{
|
||||
public:
|
||||
TInlineAllocator<4>::ForElementType<unsigned int> Data;
|
||||
int NumBits;
|
||||
int MaxBits;
|
||||
/**
|
||||
* Move constructor.
|
||||
*/
|
||||
FORCEINLINE TBitArray(TBitArray&& Other)
|
||||
{
|
||||
MoveOrCopy(*this, Other);
|
||||
}
|
||||
|
||||
struct FRelativeBitReference
|
||||
{
|
||||
public:
|
||||
FORCEINLINE explicit FRelativeBitReference(int32 BitIndex)
|
||||
: DWORDIndex(BitIndex >> NumBitsPerDWORDLogTwo)
|
||||
, Mask(1 << (BitIndex & (NumBitsPerDWORD -1)))
|
||||
{
|
||||
}
|
||||
FORCEINLINE int32 Num() const { return NumBits; }
|
||||
|
||||
int32 DWORDIndex;
|
||||
uint32 Mask;
|
||||
};
|
||||
/**
|
||||
* Copy constructor.
|
||||
*/
|
||||
FORCEINLINE TBitArray(const TBitArray& Copy)
|
||||
: NumBits(0)
|
||||
, MaxBits(0)
|
||||
{
|
||||
*this = Copy;
|
||||
}
|
||||
|
||||
FORCEINLINE const uint32* GetData() const
|
||||
{
|
||||
return (uint32*)AllocatorInstance.GetAllocation();
|
||||
}
|
||||
|
||||
FORCEINLINE uint32* GetData()
|
||||
{
|
||||
return (uint32*)AllocatorInstance.GetAllocation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Move assignment.
|
||||
*/
|
||||
FORCEINLINE TBitArray& operator=(TBitArray&& Other)
|
||||
{
|
||||
if (this != &Other)
|
||||
{
|
||||
MoveOrCopy(*this, Other);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
typedef typename Allocator::template ForElementType<uint32> AllocatorType;
|
||||
|
||||
AllocatorType AllocatorInstance;
|
||||
int32 NumBits;
|
||||
int32 MaxBits;
|
||||
|
||||
template <typename BitArrayType>
|
||||
static FORCEINLINE typename TEnableIf<TContainerTraits<BitArrayType>::MoveWillEmptyContainer>::Type MoveOrCopy(BitArrayType& ToArray, BitArrayType& FromArray)
|
||||
{
|
||||
ToArray.AllocatorInstance.MoveToEmpty(FromArray.AllocatorInstance);
|
||||
|
||||
ToArray.NumBits = FromArray.NumBits;
|
||||
ToArray.MaxBits = FromArray.MaxBits;
|
||||
FromArray.NumBits = 0;
|
||||
FromArray.MaxBits = 0;
|
||||
}
|
||||
|
||||
template <typename BitArrayType>
|
||||
static FORCEINLINE typename TEnableIf<!TContainerTraits<BitArrayType>::MoveWillEmptyContainer>::Type MoveOrCopy(BitArrayType& ToArray, BitArrayType& FromArray)
|
||||
{
|
||||
ToArray = FromArray;
|
||||
}
|
||||
|
||||
FORCENOINLINE void Realloc(int32 PreviousNumBits)
|
||||
{
|
||||
const int32 PreviousNumDWORDs = FMath::DivideAndRoundUp(PreviousNumBits, NumBitsPerDWORD);
|
||||
const int32 MaxDWORDs = FMath::DivideAndRoundUp(MaxBits, NumBitsPerDWORD);
|
||||
|
||||
AllocatorInstance.ResizeAllocation(PreviousNumDWORDs, MaxDWORDs, sizeof(uint32));
|
||||
|
||||
if (MaxDWORDs)
|
||||
{
|
||||
// Reset the newly allocated slack DWORDs.
|
||||
FMemory::Memzero((uint32*)AllocatorInstance.GetAllocation() + PreviousNumDWORDs, (MaxDWORDs - PreviousNumDWORDs) * sizeof(uint32));
|
||||
}
|
||||
}
|
||||
public:
|
||||
struct FBitReference
|
||||
{
|
||||
FORCEINLINE FBitReference(uint32& InData, uint32 InMask)
|
||||
: Data(InData)
|
||||
, Mask(InMask)
|
||||
{
|
||||
}
|
||||
FORCEINLINE const FBitReference(const uint32& InData, const uint32 InMask)
|
||||
: Data(const_cast<uint32&>(InData))
|
||||
, Mask(InMask)
|
||||
{
|
||||
}
|
||||
|
||||
FORCEINLINE void SetBit(const bool Value)
|
||||
{
|
||||
Value ? Data |= Mask : Data &= ~Mask;
|
||||
|
||||
// 10011101 - Data // 10011101 - Data
|
||||
// 00000010 - Mask - true | // 00000010 - Mask - false
|
||||
// 10011111 - |= // 11111101 - ~
|
||||
// // 10011111 - &=
|
||||
}
|
||||
|
||||
FORCEINLINE operator bool() const
|
||||
{
|
||||
return (Data & Mask) != 0;
|
||||
}
|
||||
FORCEINLINE void operator=(const bool Value)
|
||||
{
|
||||
this->SetBit(Value);
|
||||
}
|
||||
|
||||
private:
|
||||
uint32& Data;
|
||||
uint32 Mask;
|
||||
};
|
||||
};
|
||||
|
||||
class FRelativeBitReference
|
||||
{
|
||||
public:
|
||||
class FBitIterator : public FRelativeBitReference
|
||||
{
|
||||
private:
|
||||
int32 Index;
|
||||
const TBitArray& IteratedArray;
|
||||
FORCEINLINE explicit FRelativeBitReference(int32 BitIndex)
|
||||
: DWORDIndex(BitIndex >> NumBitsPerDWORDLogTwo)
|
||||
, Mask(1 << (BitIndex & (NumBitsPerDWORD - 1)))
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
FORCEINLINE const FBitIterator(const TBitArray& ToIterate, const int32 StartIndex) // Begin
|
||||
: IteratedArray(ToIterate)
|
||||
, Index(StartIndex)
|
||||
, FRelativeBitReference(StartIndex)
|
||||
{
|
||||
}
|
||||
FORCEINLINE const FBitIterator(const TBitArray& ToIterate) // End
|
||||
: IteratedArray(ToIterate)
|
||||
, Index(ToIterate.NumBits)
|
||||
, FRelativeBitReference(ToIterate.NumBits)
|
||||
{
|
||||
}
|
||||
|
||||
FORCEINLINE explicit operator bool() const
|
||||
{
|
||||
return Index < IteratedArray.Num();
|
||||
}
|
||||
FORCEINLINE FBitIterator& operator++()
|
||||
{
|
||||
++Index;
|
||||
this->Mask <<= 1;
|
||||
if (!this->Mask)
|
||||
{
|
||||
this->Mask = 1;
|
||||
++this->DWORDIndex;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
FORCEINLINE bool operator*() const
|
||||
{
|
||||
// Thesis: Once there are more elements in the BitArray than InlineData can hold it'll just allocate all of
|
||||
// them through SecondaryElements, leaving InlineData all true
|
||||
|
||||
if (IteratedArray.NumBits < IteratedArray.Data.NumInlineBits())
|
||||
{
|
||||
return (bool)FBitReference(IteratedArray.Data.GetInlineElement(this->DWORDIndex), this->Mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (bool)FBitReference(IteratedArray.Data.GetSecondaryElement(this->DWORDIndex), this->Mask);
|
||||
}
|
||||
}
|
||||
FORCEINLINE bool operator==(const FBitIterator& OtherIt) const
|
||||
{
|
||||
return Index == OtherIt.Index;
|
||||
}
|
||||
FORCEINLINE bool operator!=(const FBitIterator& OtherIt) const
|
||||
{
|
||||
return Index </*=*/ OtherIt.Index;
|
||||
}
|
||||
FORCEINLINE bool operator < (const int32 Other) const
|
||||
{
|
||||
return Index < Other;
|
||||
}
|
||||
FORCEINLINE bool operator > (const int32 Other) const
|
||||
{
|
||||
return Index < Other;
|
||||
}
|
||||
|
||||
FORCEINLINE int32 GetIndex() const
|
||||
{
|
||||
return Index;
|
||||
}
|
||||
};
|
||||
|
||||
class FSetBitIterator : public FRelativeBitReference
|
||||
{
|
||||
private:
|
||||
const TBitArray& IteratedArray;
|
||||
|
||||
uint32 UnvisitedBitMask;
|
||||
int32 CurrentBitIndex;
|
||||
int32 BaseBitIndex;
|
||||
|
||||
public:
|
||||
FORCEINLINE FSetBitIterator(const TBitArray& ToIterate, int32 StartIndex)
|
||||
: FRelativeBitReference(StartIndex)
|
||||
, IteratedArray(const_cast<TBitArray&>(ToIterate))
|
||||
, UnvisitedBitMask((~0U) << (StartIndex & (NumBitsPerDWORD - 1)))
|
||||
, CurrentBitIndex(StartIndex)
|
||||
, BaseBitIndex(StartIndex & ~(NumBitsPerDWORD - 1))
|
||||
{
|
||||
if (StartIndex != IteratedArray.NumBits)
|
||||
{
|
||||
FindNextSetBit();
|
||||
}
|
||||
}
|
||||
FORCEINLINE FSetBitIterator(const TBitArray& ToIterate)
|
||||
: FRelativeBitReference(ToIterate.NumBits)
|
||||
, IteratedArray(const_cast<TBitArray&>(ToIterate))
|
||||
, UnvisitedBitMask(0)
|
||||
, CurrentBitIndex(ToIterate.NumBits)
|
||||
, BaseBitIndex(ToIterate.NumBits)
|
||||
{
|
||||
}
|
||||
|
||||
FORCEINLINE FSetBitIterator& operator++()
|
||||
{
|
||||
UnvisitedBitMask &= ~this->Mask;
|
||||
|
||||
FindNextSetBit();
|
||||
|
||||
return *this;
|
||||
}
|
||||
FORCEINLINE bool operator*() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
FORCEINLINE bool operator==(const FSetBitIterator& Other) const
|
||||
{
|
||||
return CurrentBitIndex == Other.CurrentBitIndex;
|
||||
}
|
||||
FORCEINLINE bool operator!=(const FSetBitIterator& Other) const
|
||||
{
|
||||
return CurrentBitIndex </*=*/ Other.CurrentBitIndex;
|
||||
}
|
||||
|
||||
FORCEINLINE explicit operator bool() const
|
||||
{
|
||||
return CurrentBitIndex < IteratedArray.NumBits;
|
||||
}
|
||||
|
||||
FORCEINLINE int32 GetIndex() const
|
||||
{
|
||||
return CurrentBitIndex;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void FindNextSetBit()
|
||||
{
|
||||
//InlineData is the first 16-bytes of TBitArray
|
||||
const uint32* ArrayData = (IteratedArray.Data.SecondaryData ? IteratedArray.Data.SecondaryData : (uint32*)&IteratedArray.Data.InlineData);
|
||||
|
||||
if (!ArrayData)
|
||||
return;
|
||||
|
||||
const int32 ArrayNum = IteratedArray.NumBits;
|
||||
const int32 LastDWORDIndex = (ArrayNum - 1) / NumBitsPerDWORD;
|
||||
|
||||
uint32 RemainingBitMask = ArrayData[this->DWORDIndex] & UnvisitedBitMask;
|
||||
|
||||
while (!RemainingBitMask)
|
||||
{
|
||||
++this->DWORDIndex;
|
||||
BaseBitIndex += NumBitsPerDWORD;
|
||||
|
||||
if (this->DWORDIndex > LastDWORDIndex)
|
||||
{
|
||||
CurrentBitIndex = ArrayNum;
|
||||
return;
|
||||
}
|
||||
|
||||
RemainingBitMask = ArrayData[this->DWORDIndex];
|
||||
UnvisitedBitMask = ~0;
|
||||
}
|
||||
|
||||
const uint32 NewRemainingBitMask = RemainingBitMask & (RemainingBitMask - 1);
|
||||
|
||||
this->Mask = NewRemainingBitMask ^ RemainingBitMask;
|
||||
|
||||
CurrentBitIndex = BaseBitIndex + NumBitsPerDWORD - 1 - CountLeadingZeros(this->Mask);
|
||||
|
||||
if (CurrentBitIndex > ArrayNum)
|
||||
{
|
||||
CurrentBitIndex = ArrayNum;
|
||||
}
|
||||
}
|
||||
};
|
||||
int32 DWORDIndex;
|
||||
uint32 Mask;
|
||||
};
|
||||
|
||||
template<typename Allocator>
|
||||
class TConstSetBitIterator : public FRelativeBitReference
|
||||
{
|
||||
public:
|
||||
FORCEINLINE FBitIterator Iterator(int32 StartIndex)
|
||||
{
|
||||
return FBitIterator(*this, StartIndex);
|
||||
}
|
||||
FORCEINLINE FSetBitIterator SetBitIterator(int32 StartIndex)
|
||||
{
|
||||
return FSetBitIterator(*this, StartIndex);
|
||||
}
|
||||
|
||||
FORCEINLINE FBitIterator begin()
|
||||
{
|
||||
return FBitIterator(*this, 0);
|
||||
}
|
||||
FORCEINLINE const FBitIterator begin() const
|
||||
{
|
||||
return FBitIterator(*this, 0);
|
||||
}
|
||||
FORCEINLINE FBitIterator end()
|
||||
{
|
||||
return FBitIterator(*this);
|
||||
}
|
||||
FORCEINLINE const FBitIterator end() const
|
||||
{
|
||||
return FBitIterator(*this);
|
||||
}
|
||||
/** Constructor. */
|
||||
TConstSetBitIterator(const TBitArray<Allocator>& InArray, int32 StartIndex = 0)
|
||||
: FRelativeBitReference(StartIndex)
|
||||
, Array(InArray)
|
||||
, UnvisitedBitMask((~0U) << (StartIndex & (NumBitsPerDWORD - 1)))
|
||||
, CurrentBitIndex(StartIndex)
|
||||
, BaseBitIndex(StartIndex & ~(NumBitsPerDWORD - 1))
|
||||
{
|
||||
// check(StartIndex >= 0 && StartIndex <= Array.Num());
|
||||
if (StartIndex != Array.Num())
|
||||
{
|
||||
FindFirstSetBit();
|
||||
}
|
||||
}
|
||||
|
||||
FORCEINLINE FSetBitIterator SetBitsItBegin()
|
||||
{
|
||||
return FSetBitIterator(*this, 0);
|
||||
}
|
||||
FORCEINLINE const FSetBitIterator SetBitsItBegin() const
|
||||
{
|
||||
return FSetBitIterator(*this, 0);
|
||||
}
|
||||
FORCEINLINE const FSetBitIterator SetBitsItEnd()
|
||||
{
|
||||
return FSetBitIterator(*this);
|
||||
}
|
||||
FORCEINLINE const FSetBitIterator SetBitsItEnd() const
|
||||
{
|
||||
return FSetBitIterator(*this);
|
||||
}
|
||||
/** Forwards iteration operator. */
|
||||
FORCEINLINE TConstSetBitIterator& operator++()
|
||||
{
|
||||
// Mark the current bit as visited.
|
||||
UnvisitedBitMask &= ~this->Mask;
|
||||
|
||||
FORCEINLINE int32 Num() const
|
||||
{
|
||||
return NumBits;
|
||||
}
|
||||
FORCEINLINE int32 Max() const
|
||||
{
|
||||
return MaxBits;
|
||||
}
|
||||
FORCEINLINE bool IsSet(int32 Index) const
|
||||
{
|
||||
return *FBitIterator(*this, Index);
|
||||
}
|
||||
FORCEINLINE void Set(const int32 Index, const bool Value, bool bIsSettingAllZero = false)
|
||||
{
|
||||
const int32 DWORDIndex = (Index >> ((int32)5));
|
||||
const int32 Mask = (1 << (Index & (((int32)32) - 1)));
|
||||
// Find the first set bit that hasn't been visited yet.
|
||||
FindFirstSetBit();
|
||||
|
||||
if (!bIsSettingAllZero)
|
||||
NumBits = Index >= NumBits ? Index < MaxBits ? Index + 1 : NumBits : NumBits;
|
||||
return *this;
|
||||
}
|
||||
|
||||
FBitReference(Data[DWORDIndex], Mask).SetBit(Value);
|
||||
}
|
||||
FORCEINLINE void ZeroAll()
|
||||
{
|
||||
for (int i = 0; i < MaxBits; ++i)
|
||||
{
|
||||
Set(i, false, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
FORCEINLINE friend bool operator==(const TConstSetBitIterator& Lhs, const TConstSetBitIterator& Rhs)
|
||||
{
|
||||
// We only need to compare the bit index and the array... all the rest of the state is unobservable.
|
||||
return Lhs.CurrentBitIndex == Rhs.CurrentBitIndex && &Lhs.Array == &Rhs.Array;
|
||||
}
|
||||
|
||||
FORCEINLINE friend bool operator!=(const TConstSetBitIterator& Lhs, const TConstSetBitIterator& Rhs)
|
||||
{
|
||||
return !(Lhs == Rhs);
|
||||
}
|
||||
|
||||
/** conversion to "bool" returning true if the iterator is valid. */
|
||||
FORCEINLINE explicit operator bool() const
|
||||
{
|
||||
return CurrentBitIndex < Array.Num();
|
||||
}
|
||||
/** inverse of the "bool" operator */
|
||||
FORCEINLINE bool operator !() const
|
||||
{
|
||||
return !(bool)*this;
|
||||
}
|
||||
|
||||
/** Index accessor. */
|
||||
FORCEINLINE int32 GetIndex() const
|
||||
{
|
||||
return CurrentBitIndex;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
const TBitArray<Allocator>& Array;
|
||||
|
||||
uint32 UnvisitedBitMask;
|
||||
int32 CurrentBitIndex;
|
||||
int32 BaseBitIndex;
|
||||
|
||||
|
||||
/** Find the first set bit starting with the current bit, inclusive. */
|
||||
void FindFirstSetBit()
|
||||
{
|
||||
const uint32* ArrayData = Array.GetData();
|
||||
const int32 ArrayNum = Array.Num();
|
||||
const int32 LastDWORDIndex = (ArrayNum - 1) / NumBitsPerDWORD;
|
||||
|
||||
// Advance to the next non-zero uint32.
|
||||
uint32 RemainingBitMask = ArrayData[this->DWORDIndex] & UnvisitedBitMask;
|
||||
while (!RemainingBitMask)
|
||||
{
|
||||
++this->DWORDIndex;
|
||||
BaseBitIndex += NumBitsPerDWORD;
|
||||
if (this->DWORDIndex > LastDWORDIndex)
|
||||
{
|
||||
// We've advanced past the end of the array.
|
||||
CurrentBitIndex = ArrayNum;
|
||||
return;
|
||||
}
|
||||
|
||||
RemainingBitMask = ArrayData[this->DWORDIndex];
|
||||
UnvisitedBitMask = ~0;
|
||||
}
|
||||
|
||||
// This operation has the effect of unsetting the lowest set bit of BitMask
|
||||
const uint32 NewRemainingBitMask = RemainingBitMask & (RemainingBitMask - 1);
|
||||
|
||||
// This operation XORs the above mask with the original mask, which has the effect
|
||||
// of returning only the bits which differ; specifically, the lowest bit
|
||||
this->Mask = NewRemainingBitMask ^ RemainingBitMask;
|
||||
|
||||
// If the Nth bit was the lowest set bit of BitMask, then this gives us N
|
||||
CurrentBitIndex = BaseBitIndex + NumBitsPerDWORD - 1 - FMath::CountLeadingZeros(this->Mask);
|
||||
|
||||
// If we've accidentally iterated off the end of an array but still within the same DWORD
|
||||
// then set the index to the last index of the array
|
||||
if (CurrentBitIndex > ArrayNum)
|
||||
{
|
||||
CurrentBitIndex = ArrayNum;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,10 +2,26 @@
|
||||
|
||||
#include "Object.h"
|
||||
|
||||
enum EChannelType
|
||||
{
|
||||
CHTYPE_None = 0,
|
||||
CHTYPE_Control = 1,
|
||||
CHTYPE_Actor = 2,
|
||||
CHTYPE_File = 3,
|
||||
CHTYPE_Voice = 4,
|
||||
CHTYPE_MAX = 8,
|
||||
};
|
||||
|
||||
enum EChannelCreateFlags
|
||||
{
|
||||
None = (1 << 0),
|
||||
OpenedLocally = (1 << 1),
|
||||
};
|
||||
|
||||
class UChannel : public UObject
|
||||
{
|
||||
public:
|
||||
void StartBecomingDormant()
|
||||
void StartBecomingDormant() // T(REP)
|
||||
{
|
||||
void (*StartBecomingDormantOriginal)(UChannel* Channel) = decltype(StartBecomingDormantOriginal)(this->VFTable[0x298 / 8]);
|
||||
StartBecomingDormantOriginal(this);
|
||||
|
||||
9
Project Reboot 3.0/ChildConnection.h
Normal file
9
Project Reboot 3.0/ChildConnection.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "NetConnection.h"
|
||||
|
||||
class UChildConnection : public UNetConnection
|
||||
{
|
||||
public:
|
||||
|
||||
};
|
||||
18
Project Reboot 3.0/ChooseClass.h
Normal file
18
Project Reboot 3.0/ChooseClass.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
template<bool Predicate, typename TrueClass, typename FalseClass>
|
||||
class TChooseClass;
|
||||
|
||||
template<typename TrueClass, typename FalseClass>
|
||||
class TChooseClass<true, TrueClass, FalseClass>
|
||||
{
|
||||
public:
|
||||
typedef TrueClass Result;
|
||||
};
|
||||
|
||||
template<typename TrueClass, typename FalseClass>
|
||||
class TChooseClass<false, TrueClass, FalseClass>
|
||||
{
|
||||
public:
|
||||
typedef FalseClass Result;
|
||||
};
|
||||
@@ -68,8 +68,8 @@ public:
|
||||
for (int i = 0; i < Names->Num(); ++i)
|
||||
{
|
||||
auto& Pair = Names->At(i);
|
||||
auto& Name = Pair.Key();
|
||||
auto Value = Pair.Value();
|
||||
auto& Name = Pair.Key;
|
||||
auto Value = Pair.Value;
|
||||
|
||||
if (Name.ComparisonIndex.Value)
|
||||
{
|
||||
|
||||
@@ -1,95 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include "NumericLimits.h"
|
||||
#include "UnrealTemplate.h"
|
||||
#include "TypeCompatibleBytes.h"
|
||||
|
||||
template <int NumElements>
|
||||
class TInlineAllocator
|
||||
struct FMemory // so real place
|
||||
{
|
||||
private:
|
||||
template <int Size, int Alignment>
|
||||
struct alignas(Alignment) TAlignedBytes
|
||||
static inline void* (*Realloc)(void* Original, SIZE_T Count, uint32_t Alignment /* = DEFAULT_ALIGNMENT */);
|
||||
|
||||
static void Free(void* Data)
|
||||
{
|
||||
unsigned char Pad[Size];
|
||||
};
|
||||
// We could use actual free..
|
||||
|
||||
template <typename ElementType>
|
||||
struct TTypeCompatibleBytes : public TAlignedBytes<sizeof(ElementType), alignof(ElementType)>
|
||||
{
|
||||
};
|
||||
Realloc(Data, 0, 0);
|
||||
}
|
||||
|
||||
public:
|
||||
template <typename ElementType>
|
||||
class ForElementType
|
||||
{
|
||||
friend class TBitArray;
|
||||
|
||||
private:
|
||||
TTypeCompatibleBytes<ElementType> InlineData[NumElements];
|
||||
|
||||
ElementType* SecondaryData;
|
||||
|
||||
public:
|
||||
|
||||
FORCEINLINE int32 NumInlineBytes() const
|
||||
{
|
||||
return sizeof(ElementType) * NumElements;
|
||||
}
|
||||
FORCEINLINE int32 NumInlineBits() const
|
||||
{
|
||||
return NumInlineBytes() * 8;
|
||||
}
|
||||
|
||||
FORCEINLINE ElementType& operator[](int32 Index)
|
||||
{
|
||||
return *(ElementType*)(&InlineData[Index]);
|
||||
}
|
||||
FORCEINLINE const ElementType& operator[](int32 Index) const
|
||||
{
|
||||
return *(ElementType*)(&InlineData[Index]);
|
||||
}
|
||||
|
||||
FORCEINLINE void operator=(void* InElements)
|
||||
{
|
||||
SecondaryData = InElements;
|
||||
}
|
||||
|
||||
FORCEINLINE ElementType& GetInlineElement(int32 Index)
|
||||
{
|
||||
return *(ElementType*)(&InlineData[Index]);
|
||||
}
|
||||
FORCEINLINE const ElementType& GetInlineElement(int32 Index) const
|
||||
{
|
||||
return *(ElementType*)(&InlineData[Index]);
|
||||
}
|
||||
FORCEINLINE ElementType& GetSecondaryElement(int32 Index)
|
||||
{
|
||||
return SecondaryData[Index];
|
||||
}
|
||||
FORCEINLINE const ElementType& GetSecondaryElement(int32 Index) const
|
||||
{
|
||||
return SecondaryData[Index];
|
||||
}
|
||||
ElementType* GetInlineElements() const
|
||||
{
|
||||
return (ElementType*)InlineData;
|
||||
}
|
||||
FORCEINLINE ElementType* GetAllocation() const
|
||||
{
|
||||
return IfAThenAElseB<ElementType>(SecondaryData, GetInlineElements());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
FORCEINLINE /*FMEMORY_INLINE_FUNCTION_DECORATOR*/ size_t /*FMemory::*/QuantizeSize(SIZE_T Count, uint32 Alignment)
|
||||
{
|
||||
return Count;
|
||||
/*
|
||||
if (!FMEMORY_INLINE_GMalloc)
|
||||
static size_t QuantizeSize(size_t Count, uint32 Alignment) // T(R)
|
||||
{
|
||||
return Count;
|
||||
}
|
||||
return FMEMORY_INLINE_GMalloc->QuantizeSize(Count, Alignment); */
|
||||
|
||||
static void* Memmove(void* Dest, const void* Src, SIZE_T Count)
|
||||
{
|
||||
memmove(Dest, Src, Count);
|
||||
}
|
||||
|
||||
static FORCEINLINE void* Memzero(void* Dest, SIZE_T Count)
|
||||
{
|
||||
// return FPlatformMemory::Memzero(Dest, Count);
|
||||
return RtlSecureZeroMemory(Dest, Count);
|
||||
}
|
||||
|
||||
template< class T >
|
||||
static FORCEINLINE void Memzero(T& Src)
|
||||
{
|
||||
static_assert(!TIsPointer<T>::Value, "For pointers use the two parameters function");
|
||||
Memzero(&Src, sizeof(T));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T = __int64>
|
||||
static T* AllocUnreal(size_t Size)
|
||||
{
|
||||
return (T*)FMemory::Realloc(0, Size, 0);
|
||||
}
|
||||
|
||||
enum
|
||||
@@ -97,21 +50,467 @@ enum
|
||||
DEFAULT_ALIGNMENT = 0
|
||||
};
|
||||
|
||||
template <typename SizeType>
|
||||
FORCEINLINE SizeType DefaultCalculateSlackReserve(SizeType NumElements, SIZE_T BytesPerElement, bool bAllowQuantize, uint32 Alignment = DEFAULT_ALIGNMENT)
|
||||
// 4.19
|
||||
|
||||
template <typename DestinationElementType, typename SourceElementType, typename SizeType>
|
||||
FORCEINLINE void RelocateConstructItems(void* Dest, const SourceElementType* Source, SizeType Count)
|
||||
{
|
||||
SizeType Retval = NumElements;
|
||||
FMemory::Memmove(Dest, Source, sizeof(SourceElementType) * Count);
|
||||
/*
|
||||
|
||||
if constexpr (UE::Core::Private::MemoryOps::TCanBitwiseRelocate<DestinationElementType, SourceElementType>::Value)
|
||||
{
|
||||
FMemory::Memmove(Dest, Source, sizeof(SourceElementType) * Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (Count)
|
||||
{
|
||||
// We need a typedef here because VC won't compile the destructor call below if SourceElementType itself has a member called SourceElementType
|
||||
typedef SourceElementType RelocateConstructItemsElementTypeTypedef;
|
||||
|
||||
new (Dest) DestinationElementType(*Source);
|
||||
++(DestinationElementType*&)Dest;
|
||||
(Source++)->RelocateConstructItemsElementTypeTypedef::~RelocateConstructItemsElementTypeTypedef();
|
||||
--Count;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
class FDefaultAllocator;
|
||||
|
||||
template <uint32 NumInlineElements, typename SecondaryAllocator = FDefaultAllocator>
|
||||
class TInlineAllocator
|
||||
{
|
||||
public:
|
||||
|
||||
enum { NeedsElementType = true };
|
||||
enum { RequireRangeCheck = true };
|
||||
|
||||
template<typename ElementType>
|
||||
class ForElementType
|
||||
{
|
||||
public:
|
||||
ForElementType()
|
||||
{
|
||||
}
|
||||
|
||||
FORCEINLINE void MoveToEmpty(ForElementType& Other)
|
||||
{
|
||||
// checkSlow(this != &Other);
|
||||
|
||||
if (!Other.SecondaryData.GetAllocation())
|
||||
{
|
||||
RelocateConstructItems<ElementType>((void*)InlineData, Other.GetInlineElements(), NumInlineElements);
|
||||
}
|
||||
|
||||
// Move secondary storage in any case.
|
||||
// This will move secondary storage if it exists but will also handle the case where secondary storage is used in Other but not in *this.
|
||||
SecondaryData.MoveToEmpty(Other.SecondaryData);
|
||||
}
|
||||
|
||||
// FContainerAllocatorInterface
|
||||
FORCEINLINE ElementType* GetAllocation() const
|
||||
{
|
||||
return IfAThenAElseB<ElementType>(SecondaryData.GetAllocation(), GetInlineElements());
|
||||
}
|
||||
|
||||
void ResizeAllocation(int32 PreviousNumElements, int32 NumElements, SIZE_T NumBytesPerElement)
|
||||
{
|
||||
// Check if the new allocation will fit in the inline data area.
|
||||
if (NumElements <= NumInlineElements)
|
||||
{
|
||||
// If the old allocation wasn't in the inline data area, relocate it into the inline data area.
|
||||
if (SecondaryData.GetAllocation())
|
||||
{
|
||||
RelocateConstructItems<ElementType>((void*)InlineData, (ElementType*)SecondaryData.GetAllocation(), PreviousNumElements);
|
||||
|
||||
// Free the old indirect allocation.
|
||||
SecondaryData.ResizeAllocation(0, 0, NumBytesPerElement);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!SecondaryData.GetAllocation())
|
||||
{
|
||||
// Allocate new indirect memory for the data.
|
||||
SecondaryData.ResizeAllocation(0, NumElements, NumBytesPerElement);
|
||||
|
||||
// Move the data out of the inline data area into the new allocation.
|
||||
RelocateConstructItems<ElementType>((void*)SecondaryData.GetAllocation(), GetInlineElements(), PreviousNumElements);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reallocate the indirect data for the new size.
|
||||
SecondaryData.ResizeAllocation(PreviousNumElements, NumElements, NumBytesPerElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FORCEINLINE int32 CalculateSlackReserve(int32 NumElements, SIZE_T NumBytesPerElement) const
|
||||
{
|
||||
// If the elements use less space than the inline allocation, only use the inline allocation as slack.
|
||||
return NumElements <= NumInlineElements ?
|
||||
NumInlineElements :
|
||||
SecondaryData.CalculateSlackReserve(NumElements, NumBytesPerElement);
|
||||
}
|
||||
FORCEINLINE int32 CalculateSlackShrink(int32 NumElements, int32 NumAllocatedElements, int32 NumBytesPerElement) const
|
||||
{
|
||||
// If the elements use less space than the inline allocation, only use the inline allocation as slack.
|
||||
return NumElements <= NumInlineElements ?
|
||||
NumInlineElements :
|
||||
SecondaryData.CalculateSlackShrink(NumElements, NumAllocatedElements, NumBytesPerElement);
|
||||
}
|
||||
FORCEINLINE int32 CalculateSlackGrow(int32 NumElements, int32 NumAllocatedElements, int32 NumBytesPerElement) const
|
||||
{
|
||||
// If the elements use less space than the inline allocation, only use the inline allocation as slack.
|
||||
return NumElements <= NumInlineElements ?
|
||||
NumInlineElements :
|
||||
SecondaryData.CalculateSlackGrow(NumElements, NumAllocatedElements, NumBytesPerElement);
|
||||
}
|
||||
|
||||
SIZE_T GetAllocatedSize(int32 NumAllocatedElements, SIZE_T NumBytesPerElement) const
|
||||
{
|
||||
return SecondaryData.GetAllocatedSize(NumAllocatedElements, NumBytesPerElement);
|
||||
}
|
||||
|
||||
bool HasAllocation()
|
||||
{
|
||||
return SecondaryData.HasAllocation();
|
||||
}
|
||||
|
||||
private:
|
||||
ForElementType(const ForElementType&);
|
||||
ForElementType& operator=(const ForElementType&);
|
||||
|
||||
/** The data is stored in this array if less than NumInlineElements is needed. */
|
||||
TTypeCompatibleBytes<ElementType> InlineData[NumInlineElements];
|
||||
|
||||
/** The data is allocated through the indirect allocation policy if more than NumInlineElements is needed. */
|
||||
typename SecondaryAllocator::template ForElementType<ElementType> SecondaryData;
|
||||
|
||||
/** @return the base of the aligned inline element data */
|
||||
ElementType* GetInlineElements() const
|
||||
{
|
||||
return (ElementType*)InlineData;
|
||||
}
|
||||
};
|
||||
|
||||
typedef void ForAnyElementType;
|
||||
};
|
||||
|
||||
|
||||
struct FScriptContainerElement
|
||||
{
|
||||
};
|
||||
|
||||
FORCEINLINE int32 DefaultCalculateSlackShrink(int32 NumElements, int32 NumAllocatedElements, SIZE_T BytesPerElement, bool bAllowQuantize, uint32 Alignment = DEFAULT_ALIGNMENT)
|
||||
{
|
||||
int32 Retval;
|
||||
// checkSlow(NumElements < NumAllocatedElements);
|
||||
|
||||
const uint32 CurrentSlackElements = NumAllocatedElements - NumElements;
|
||||
const SIZE_T CurrentSlackBytes = (NumAllocatedElements - NumElements) * BytesPerElement;
|
||||
const bool bTooManySlackBytes = CurrentSlackBytes >= 16384;
|
||||
const bool bTooManySlackElements = 3 * NumElements < 2 * NumAllocatedElements;
|
||||
if ((bTooManySlackBytes || bTooManySlackElements) && (CurrentSlackElements > 64 || !NumElements)) // hard coded 64 :-(
|
||||
{
|
||||
Retval = NumElements;
|
||||
if (Retval > 0)
|
||||
{
|
||||
if (bAllowQuantize)
|
||||
{
|
||||
Retval = FMemory::QuantizeSize(Retval * BytesPerElement, Alignment) / BytesPerElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Retval = NumAllocatedElements;
|
||||
}
|
||||
|
||||
return Retval;
|
||||
}
|
||||
|
||||
FORCEINLINE int32 DefaultCalculateSlackGrow(int32 NumElements, int32 NumAllocatedElements, SIZE_T BytesPerElement, bool bAllowQuantize, uint32 Alignment = DEFAULT_ALIGNMENT)
|
||||
{
|
||||
int32 Retval;
|
||||
// checkSlow(NumElements > NumAllocatedElements && NumElements > 0);
|
||||
|
||||
SIZE_T Grow = 4;
|
||||
if (NumAllocatedElements || SIZE_T(NumElements) > Grow)
|
||||
{
|
||||
// Allocate slack for the array proportional to its size.
|
||||
Grow = SIZE_T(NumElements) + 3 * SIZE_T(NumElements) / 8 + 16;
|
||||
}
|
||||
if (bAllowQuantize)
|
||||
{
|
||||
Retval = FMemory::QuantizeSize(Grow * BytesPerElement, Alignment) / BytesPerElement;
|
||||
}
|
||||
else
|
||||
{
|
||||
Retval = Grow;
|
||||
}
|
||||
|
||||
if (NumElements > Retval)
|
||||
{
|
||||
Retval = MAX_int32;
|
||||
}
|
||||
|
||||
return Retval;
|
||||
}
|
||||
|
||||
FORCEINLINE int32 DefaultCalculateSlackReserve(int32 NumElements, SIZE_T BytesPerElement, bool bAllowQuantize, uint32 Alignment = DEFAULT_ALIGNMENT)
|
||||
{
|
||||
int32 Retval = NumElements;
|
||||
// checkSlow(NumElements > 0);
|
||||
if (bAllowQuantize)
|
||||
{
|
||||
auto Count = SIZE_T(Retval) * SIZE_T(BytesPerElement);
|
||||
Retval = (SizeType)(QuantizeSize(Count, Alignment) / BytesPerElement);
|
||||
Retval = FMemory::QuantizeSize(SIZE_T(Retval) * SIZE_T(BytesPerElement), Alignment) / BytesPerElement;
|
||||
// NumElements and MaxElements are stored in 32 bit signed integers so we must be careful not to overflow here.
|
||||
if (NumElements > Retval)
|
||||
{
|
||||
Retval = TNumericLimits<SizeType>::Max();
|
||||
Retval = MAX_int32;
|
||||
}
|
||||
}
|
||||
|
||||
return Retval;
|
||||
}
|
||||
}
|
||||
|
||||
class FHeapAllocator
|
||||
{
|
||||
public:
|
||||
|
||||
enum { NeedsElementType = false };
|
||||
enum { RequireRangeCheck = true };
|
||||
|
||||
class ForAnyElementType
|
||||
{
|
||||
public:
|
||||
/** Default constructor. */
|
||||
ForAnyElementType()
|
||||
: Data(nullptr)
|
||||
{}
|
||||
|
||||
FORCEINLINE void MoveToEmpty(ForAnyElementType& Other)
|
||||
{
|
||||
// checkSlow(this != &Other);
|
||||
|
||||
if (Data)
|
||||
{
|
||||
FMemory::Free(Data);
|
||||
}
|
||||
|
||||
Data = Other.Data;
|
||||
Other.Data = nullptr;
|
||||
}
|
||||
|
||||
/** Destructor. */
|
||||
FORCEINLINE ~ForAnyElementType()
|
||||
{
|
||||
if (Data)
|
||||
{
|
||||
FMemory::Free(Data);
|
||||
}
|
||||
}
|
||||
|
||||
// FContainerAllocatorInterface
|
||||
FORCEINLINE FScriptContainerElement* GetAllocation() const
|
||||
{
|
||||
return Data;
|
||||
}
|
||||
FORCEINLINE void ResizeAllocation(int32 PreviousNumElements, int32 NumElements, SIZE_T NumBytesPerElement)
|
||||
{
|
||||
// Avoid calling FMemory::Realloc( nullptr, 0 ) as ANSI C mandates returning a valid pointer which is not what we want.
|
||||
if (Data || NumElements)
|
||||
{
|
||||
//checkSlow(((uint64)NumElements*(uint64)ElementTypeInfo.GetSize() < (uint64)INT_MAX));
|
||||
Data = (FScriptContainerElement*)FMemory::Realloc(Data, NumElements * NumBytesPerElement, DEFAULT_ALIGNMENT);
|
||||
}
|
||||
}
|
||||
FORCEINLINE int32 CalculateSlackReserve(int32 NumElements, int32 NumBytesPerElement) const
|
||||
{
|
||||
return DefaultCalculateSlackReserve(NumElements, NumBytesPerElement, true);
|
||||
}
|
||||
FORCEINLINE int32 CalculateSlackShrink(int32 NumElements, int32 NumAllocatedElements, int32 NumBytesPerElement) const
|
||||
{
|
||||
return DefaultCalculateSlackShrink(NumElements, NumAllocatedElements, NumBytesPerElement, true);
|
||||
}
|
||||
FORCEINLINE int32 CalculateSlackGrow(int32 NumElements, int32 NumAllocatedElements, int32 NumBytesPerElement) const
|
||||
{
|
||||
return DefaultCalculateSlackGrow(NumElements, NumAllocatedElements, NumBytesPerElement, true);
|
||||
}
|
||||
|
||||
SIZE_T GetAllocatedSize(int32 NumAllocatedElements, SIZE_T NumBytesPerElement) const
|
||||
{
|
||||
return NumAllocatedElements * NumBytesPerElement;
|
||||
}
|
||||
|
||||
bool HasAllocation()
|
||||
{
|
||||
return !!Data;
|
||||
}
|
||||
|
||||
private:
|
||||
ForAnyElementType(const ForAnyElementType&);
|
||||
ForAnyElementType& operator=(const ForAnyElementType&);
|
||||
|
||||
/** A pointer to the container's elements. */
|
||||
FScriptContainerElement* Data;
|
||||
};
|
||||
|
||||
template<typename ElementType>
|
||||
class ForElementType : public ForAnyElementType
|
||||
{
|
||||
public:
|
||||
|
||||
/** Default constructor. */
|
||||
ForElementType()
|
||||
{}
|
||||
|
||||
FORCEINLINE ElementType* GetAllocation() const
|
||||
{
|
||||
return (ElementType*)ForAnyElementType::GetAllocation();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
class FDefaultAllocator;
|
||||
class FDefaultBitArrayAllocator;
|
||||
|
||||
/** Encapsulates the allocators used by a sparse array in a single type. */
|
||||
template<typename InElementAllocator = FDefaultAllocator, typename InBitArrayAllocator = FDefaultBitArrayAllocator>
|
||||
class TSparseArrayAllocator
|
||||
{
|
||||
public:
|
||||
|
||||
typedef InElementAllocator ElementAllocator;
|
||||
typedef InBitArrayAllocator BitArrayAllocator;
|
||||
};
|
||||
|
||||
/** An inline sparse array allocator that allows sizing of the inline allocations for a set number of elements. */
|
||||
template<
|
||||
uint32 NumInlineElements,
|
||||
typename SecondaryAllocator = TSparseArrayAllocator<FDefaultAllocator, FDefaultAllocator>
|
||||
>
|
||||
class TInlineSparseArrayAllocator
|
||||
{
|
||||
private:
|
||||
|
||||
/** The size to allocate inline for the bit array. */
|
||||
enum { InlineBitArrayDWORDs = (NumInlineElements + NumBitsPerDWORD - 1) / NumBitsPerDWORD };
|
||||
|
||||
public:
|
||||
|
||||
typedef TInlineAllocator<NumInlineElements, typename SecondaryAllocator::ElementAllocator> ElementAllocator;
|
||||
typedef TInlineAllocator<InlineBitArrayDWORDs, typename SecondaryAllocator::BitArrayAllocator> BitArrayAllocator;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define DEFAULT_NUMBER_OF_ELEMENTS_PER_HASH_BUCKET 2
|
||||
#define DEFAULT_BASE_NUMBER_OF_HASH_BUCKETS 8
|
||||
#define DEFAULT_MIN_NUMBER_OF_HASHED_ELEMENTS 4
|
||||
|
||||
static FORCEINLINE uint32 CountLeadingZeros(uint32 Value)
|
||||
{
|
||||
unsigned long Log2;
|
||||
if (_BitScanReverse(&Log2, Value) != 0)
|
||||
{
|
||||
return 31 - Log2;
|
||||
}
|
||||
|
||||
return 32;
|
||||
}
|
||||
|
||||
static /* constexpr */ FORCEINLINE uint32 CeilLogTwo(uint32 Arg) // Milxnor: really in FPlatformMath
|
||||
{
|
||||
Arg = Arg ? Arg : 1;
|
||||
return 32 - CountLeadingZeros(Arg - 1);
|
||||
}
|
||||
|
||||
static /* constexpr */ FORCEINLINE uint32 RoundUpToPowerOfTwo(uint32 Arg) // Milxnor: really in FPlatformMath
|
||||
{
|
||||
return 1 << CeilLogTwo(Arg);
|
||||
}
|
||||
|
||||
template<
|
||||
typename InSparseArrayAllocator = TSparseArrayAllocator<>,
|
||||
typename InHashAllocator = TInlineAllocator<1, FDefaultAllocator>,
|
||||
uint32 AverageNumberOfElementsPerHashBucket = DEFAULT_NUMBER_OF_ELEMENTS_PER_HASH_BUCKET,
|
||||
uint32 BaseNumberOfHashBuckets = DEFAULT_BASE_NUMBER_OF_HASH_BUCKETS,
|
||||
uint32 MinNumberOfHashedElements = DEFAULT_MIN_NUMBER_OF_HASHED_ELEMENTS
|
||||
>
|
||||
class TSetAllocator
|
||||
{
|
||||
public:
|
||||
|
||||
/** Computes the number of hash buckets to use for a given number of elements. */
|
||||
static FORCEINLINE uint32 GetNumberOfHashBuckets(uint32 NumHashedElements)
|
||||
{
|
||||
if (NumHashedElements >= MinNumberOfHashedElements)
|
||||
{
|
||||
return RoundUpToPowerOfTwo(NumHashedElements / AverageNumberOfElementsPerHashBucket + BaseNumberOfHashBuckets);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
typedef InSparseArrayAllocator SparseArrayAllocator;
|
||||
typedef InHashAllocator HashAllocator;
|
||||
};
|
||||
|
||||
class FDefaultAllocator;
|
||||
|
||||
/** An inline set allocator that allows sizing of the inline allocations for a set number of elements. */
|
||||
template<
|
||||
uint32 NumInlineElements,
|
||||
typename SecondaryAllocator = TSetAllocator<TSparseArrayAllocator<FDefaultAllocator, FDefaultAllocator>, FDefaultAllocator>,
|
||||
uint32 AverageNumberOfElementsPerHashBucket = DEFAULT_NUMBER_OF_ELEMENTS_PER_HASH_BUCKET,
|
||||
uint32 MinNumberOfHashedElements = DEFAULT_MIN_NUMBER_OF_HASHED_ELEMENTS
|
||||
>
|
||||
class TInlineSetAllocator
|
||||
{
|
||||
private:
|
||||
|
||||
enum { NumInlineHashBuckets = (NumInlineElements + AverageNumberOfElementsPerHashBucket - 1) / AverageNumberOfElementsPerHashBucket };
|
||||
|
||||
static_assert(!(NumInlineHashBuckets& (NumInlineHashBuckets - 1)), "Number of inline buckets must be a power of two");
|
||||
|
||||
public:
|
||||
|
||||
/** Computes the number of hash buckets to use for a given number of elements. */
|
||||
static FORCEINLINE uint32 GetNumberOfHashBuckets(uint32 NumHashedElements)
|
||||
{
|
||||
const uint32 NumDesiredHashBuckets = RoundUpToPowerOfTwo(NumHashedElements / AverageNumberOfElementsPerHashBucket);
|
||||
if (NumDesiredHashBuckets < NumInlineHashBuckets)
|
||||
{
|
||||
return NumInlineHashBuckets;
|
||||
}
|
||||
|
||||
if (NumHashedElements < MinNumberOfHashedElements)
|
||||
{
|
||||
return NumInlineHashBuckets;
|
||||
}
|
||||
|
||||
return NumDesiredHashBuckets;
|
||||
}
|
||||
|
||||
typedef TInlineSparseArrayAllocator<NumInlineElements, typename SecondaryAllocator::SparseArrayAllocator> SparseArrayAllocator;
|
||||
typedef TInlineAllocator<NumInlineHashBuckets, typename SecondaryAllocator::HashAllocator> HashAllocator;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 'typedefs' for various allocator defaults.
|
||||
*
|
||||
* These should be replaced with actual typedefs when Core.h include order is sorted out, as then we won't need to
|
||||
* 'forward' these TAllocatorTraits specializations below.
|
||||
*/
|
||||
|
||||
class FDefaultAllocator : public FHeapAllocator { public: typedef FHeapAllocator Typedef; };
|
||||
class FDefaultSetAllocator : public TSetAllocator<> { public: typedef TSetAllocator<> Typedef; };
|
||||
class FDefaultBitArrayAllocator : public TInlineAllocator<4> { public: typedef TInlineAllocator<4> Typedef; };
|
||||
class FDefaultSparseArrayAllocator : public TSparseArrayAllocator<> { public: typedef TSparseArrayAllocator<> Typedef; };
|
||||
|
||||
@@ -14,11 +14,11 @@ class UDataTable : public UObject
|
||||
{
|
||||
public:
|
||||
template <typename RowDataType = uint8_t>
|
||||
TMap<FName, RowDataType*>& GetRowMap()
|
||||
TMap<FName, RowDataType>& GetRowMap()
|
||||
{
|
||||
static auto RowStructOffset = FindOffsetStruct("/Script/Engine.DataTable", "RowStruct");
|
||||
|
||||
return *(TMap<FName, RowDataType*>*)(__int64(this) + (RowStructOffset + sizeof(UObject*))); // because after rowstruct is rowmap
|
||||
return *(TMap<FName, RowDataType>*)(__int64(this) + (RowStructOffset + sizeof(UObject*))); // because after rowstruct is rowmap
|
||||
}
|
||||
|
||||
static UClass* StaticClass()
|
||||
|
||||
@@ -78,9 +78,9 @@ public:
|
||||
|
||||
for (auto& AwardEntry : AwardEntriesAtElimMap)
|
||||
{
|
||||
if (AwardEntry.First == Value)
|
||||
if (AwardEntry.Key == Value)
|
||||
{
|
||||
return AwardEntry.Second;
|
||||
return AwardEntry.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,8 +109,8 @@ FName AFortGameModeAthena::RedirectLootTier(const FName& LootTier)
|
||||
|
||||
for (auto& Pair : RedirectAthenaLootTierGroups)
|
||||
{
|
||||
auto& Key = Pair.Key();
|
||||
auto& Value = Pair.Value();
|
||||
auto& Key = Pair.Key;
|
||||
auto& Value = Pair.Value;
|
||||
|
||||
// LOG_INFO(LogDev, "[{}] {} {}", i, Key.ComparisonIndex.Value ? Key.ToString() : "NULL", Key.ComparisonIndex.Value ? Value.ToString() : "NULL");
|
||||
|
||||
@@ -428,6 +428,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
|
||||
else
|
||||
{
|
||||
auto OldPlaylist = GetPlaylistForOldVersion();
|
||||
SetupEverythingAI();
|
||||
}
|
||||
|
||||
auto Fortnite_Season = std::floor(Fortnite_Version);
|
||||
|
||||
@@ -41,9 +41,9 @@ float UFortItemDefinition::GetMaxStackSize()
|
||||
|
||||
for (auto& Pair : RowMap)
|
||||
{
|
||||
if (Pair.Key() == ScalableFloat.Curve.RowName)
|
||||
if (Pair.Key == ScalableFloat.Curve.RowName)
|
||||
{
|
||||
Curve = (FSimpleCurve*)Pair.Value();
|
||||
Curve = (FSimpleCurve*)Pair.Value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,10 +22,10 @@ int UFortLootLevel::GetItemLevel(const FDataTableCategoryHandle& LootLevelData,
|
||||
|
||||
for (auto& LootLevelDataPair : LootLevelData.DataTable->GetRowMap<FFortLootLevelData>())
|
||||
{
|
||||
if (LootLevelDataPair.Second->Category != LootLevelData.RowContents)
|
||||
if (LootLevelDataPair.Value.Category != LootLevelData.RowContents)
|
||||
continue;
|
||||
|
||||
OurLootLevelDatas.push_back(LootLevelDataPair.Second);
|
||||
OurLootLevelDatas.push_back(&LootLevelDataPair.Value);
|
||||
}
|
||||
|
||||
if (OurLootLevelDatas.size() > 0)
|
||||
|
||||
@@ -47,14 +47,16 @@ void CollectDataTablesRows(const std::vector<UDataTable*>& DataTables, LOOTING_M
|
||||
DataTablesToIterate.push_back(DataTable);
|
||||
}
|
||||
|
||||
return; // T(1)
|
||||
|
||||
for (auto CurrentDataTable : DataTablesToIterate)
|
||||
{
|
||||
for (TPair<FName, uint8_t*>& CurrentPair : CurrentDataTable->GetRowMap())
|
||||
for (auto& CurrentPair : CurrentDataTable->GetRowMap())
|
||||
{
|
||||
if (Check(CurrentPair.Key(), (RowStructType*)CurrentPair.Value()))
|
||||
if (Check(CurrentPair.Key, (RowStructType*)CurrentPair.Value))
|
||||
{
|
||||
// LOG_INFO(LogDev, "Setting key with {} comp {} num: {} then iterating through map!", CurrentPair.Key().ToString(), CurrentPair.Key().ComparisonIndex.Value, CurrentPair.Key().Number);
|
||||
(*OutMap)[CurrentPair.Key()] = (RowStructType*)CurrentPair.Value();
|
||||
(*OutMap)[CurrentPair.Key] = (RowStructType*)CurrentPair.Value;
|
||||
|
||||
/* for (auto PairInOutMap : *OutMap)
|
||||
{
|
||||
@@ -503,14 +505,14 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, int WorldLevel, int For
|
||||
|
||||
for (auto& Value : PlaylistOverrideLootTableData)
|
||||
{
|
||||
auto CurrentOverrideTag = Value.First;
|
||||
auto CurrentOverrideTag = Value.Key;
|
||||
|
||||
if (Tag.TagName == CurrentOverrideTag.TagName)
|
||||
{
|
||||
auto OverrideLootPackageTableStr = Value.Second.LootPackageData.SoftObjectPtr.ObjectID.AssetPathName.ToString();
|
||||
auto OverrideLootPackageTableStr = Value.Value.LootPackageData.SoftObjectPtr.ObjectID.AssetPathName.ToString();
|
||||
auto bOverrideIsComposite = OverrideLootPackageTableStr.contains("Composite");
|
||||
|
||||
auto ptr = Value.Second.LootPackageData.Get(bOverrideIsComposite ? CompositeDataTableClass : UDataTable::StaticClass(), true);
|
||||
auto ptr = Value.Value.LootPackageData.Get(bOverrideIsComposite ? CompositeDataTableClass : UDataTable::StaticClass(), true);
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
@@ -557,14 +559,14 @@ std::vector<LootDrop> PickLootDrops(FName TierGroupName, int WorldLevel, int For
|
||||
|
||||
for (auto& Value : PlaylistOverrideLootTableData)
|
||||
{
|
||||
auto CurrentOverrideTag = Value.First;
|
||||
auto CurrentOverrideTag = Value.Key;
|
||||
|
||||
if (Tag.TagName == CurrentOverrideTag.TagName)
|
||||
{
|
||||
auto OverrideLootTierDataStr = Value.Second.LootTierData.SoftObjectPtr.ObjectID.AssetPathName.ToString();
|
||||
auto OverrideLootTierDataStr = Value.Value.LootTierData.SoftObjectPtr.ObjectID.AssetPathName.ToString();
|
||||
auto bOverrideIsComposite = OverrideLootTierDataStr.contains("Composite");
|
||||
|
||||
auto ptr = Value.Second.LootTierData.Get(bOverrideIsComposite ? CompositeDataTableClass : UDataTable::StaticClass(), true);
|
||||
auto ptr = Value.Value.LootTierData.Get(bOverrideIsComposite ? CompositeDataTableClass : UDataTable::StaticClass(), true);
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
|
||||
@@ -567,6 +567,10 @@ void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame*
|
||||
|
||||
FWeaponUpgradeItemRow* FoundRow = nullptr;
|
||||
|
||||
/*
|
||||
|
||||
T(3)
|
||||
|
||||
for (int i = 0; i < LootPackagesRowMap.Pairs.Elements.Data.Num(); i++)
|
||||
{
|
||||
auto& Pair = LootPackagesRowMap.Pairs.Elements.Data.at(i).ElementData.Value;
|
||||
@@ -579,6 +583,8 @@ void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame*
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
if (!FoundRow)
|
||||
{
|
||||
|
||||
@@ -17,6 +17,10 @@ int UFortWeaponItemDefinition::GetClipSize()
|
||||
|
||||
void* Row = nullptr;
|
||||
|
||||
/*
|
||||
|
||||
T(1)
|
||||
|
||||
for (int i = 0; i < RowMap.Pairs.Elements.Data.Num(); ++i)
|
||||
{
|
||||
auto& Pair = RowMap.Pairs.Elements.Data.at(i).ElementData.Value;
|
||||
@@ -28,6 +32,8 @@ int UFortWeaponItemDefinition::GetClipSize()
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
if (!Row)
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "Level.h"
|
||||
#include "reboot.h"
|
||||
|
||||
UWorld*& ULevel::GetOwningWorld()
|
||||
{
|
||||
@@ -6,7 +7,7 @@ UWorld*& ULevel::GetOwningWorld()
|
||||
return Get<UWorld*>(OwningWorldOffset);
|
||||
}
|
||||
|
||||
bool ULevel::HasVisibilityChangeRequestPending()
|
||||
bool ULevel::HasVisibilityChangeRequestPending() // T(REP)
|
||||
{
|
||||
// I believe implementation on this changes depending on the version
|
||||
|
||||
@@ -24,6 +25,11 @@ bool ULevel::HasVisibilityChangeRequestPending()
|
||||
return this == CurrentLevelPendingVisibility || this == CurrentLevelPendingInvisibility;
|
||||
}
|
||||
|
||||
bool ULevel::IsAssociatingLevel() // T(REP)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AWorldSettings* ULevel::GetWorldSettings(bool bChecked) const
|
||||
{
|
||||
if (bChecked)
|
||||
@@ -33,4 +39,10 @@ AWorldSettings* ULevel::GetWorldSettings(bool bChecked) const
|
||||
|
||||
static auto WorldSettingsOffset = GetOffset("WorldSettings");
|
||||
return Get<AWorldSettings*>(WorldSettingsOffset);
|
||||
}
|
||||
|
||||
UClass* ULevel::StaticClass()
|
||||
{
|
||||
static auto Class = FindObject<UClass>(L"/Script/Engine.Level");
|
||||
return Class;
|
||||
}
|
||||
@@ -7,5 +7,8 @@ class ULevel : public UObject
|
||||
public:
|
||||
UWorld*& GetOwningWorld();
|
||||
bool HasVisibilityChangeRequestPending();
|
||||
bool IsAssociatingLevel();
|
||||
AWorldSettings* GetWorldSettings(bool bChecked = true) const;
|
||||
|
||||
static class UClass* StaticClass();
|
||||
};
|
||||
@@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "Set.h"
|
||||
#include "UnrealTemplate.h"
|
||||
#include "ChooseClass.h"
|
||||
|
||||
// template <typename KeyType, typename ValueType>
|
||||
// using TPair = TTuple<KeyType, ValueType>;
|
||||
@@ -9,151 +11,370 @@ template <typename KeyType, typename ValueType>
|
||||
class TPair
|
||||
{
|
||||
public:
|
||||
KeyType First;
|
||||
ValueType Second;
|
||||
|
||||
FORCEINLINE KeyType& Key()
|
||||
{
|
||||
return First;
|
||||
}
|
||||
FORCEINLINE const KeyType& Key() const
|
||||
{
|
||||
return First;
|
||||
}
|
||||
FORCEINLINE ValueType& Value()
|
||||
{
|
||||
return Second;
|
||||
}
|
||||
FORCEINLINE const ValueType& Value() const
|
||||
{
|
||||
return Second;
|
||||
}
|
||||
KeyType Key;
|
||||
ValueType Value;
|
||||
};
|
||||
|
||||
template <typename KeyType, typename ValueType>
|
||||
class TMap
|
||||
template <typename KeyInitType, typename ValueInitType>
|
||||
class TPairInitializer
|
||||
{
|
||||
public:
|
||||
typename TRValueToLValueReference<KeyInitType >::Type Key;
|
||||
typename TRValueToLValueReference<ValueInitType>::Type Value;
|
||||
|
||||
/** Initialization constructor. */
|
||||
FORCEINLINE TPairInitializer(KeyInitType InKey, ValueInitType InValue)
|
||||
: Key(InKey)
|
||||
, Value(InValue)
|
||||
{
|
||||
}
|
||||
|
||||
/** Implicit conversion to pair initializer. */
|
||||
template <typename KeyType, typename ValueType>
|
||||
FORCEINLINE TPairInitializer(const TPair<KeyType, ValueType>& Pair)
|
||||
: Key(Pair.Key)
|
||||
, Value(Pair.Value)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename KeyType, typename ValueType>
|
||||
operator TPair<KeyType, ValueType>() const
|
||||
{
|
||||
#define StaticCast static_cast // Milxnor: ??
|
||||
return TPair<KeyType, ValueType>(StaticCast<KeyInitType>(Key), StaticCast<ValueInitType>(Value));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename KeyType, typename ValueType, bool bInAllowDuplicateKeys>
|
||||
struct TDefaultMapKeyFuncs : BaseKeyFuncs<TPair<KeyType, ValueType>, KeyType, bInAllowDuplicateKeys>
|
||||
{
|
||||
typedef typename TTypeTraits<KeyType>::ConstPointerType KeyInitType;
|
||||
typedef const TPairInitializer<typename TTypeTraits<KeyType>::ConstInitType, typename TTypeTraits<ValueType>::ConstInitType>& ElementInitType;
|
||||
|
||||
static FORCEINLINE KeyInitType GetSetKey(ElementInitType Element)
|
||||
{
|
||||
return Element.Key;
|
||||
}
|
||||
static FORCEINLINE bool Matches(KeyInitType A, KeyInitType B)
|
||||
{
|
||||
return A == B;
|
||||
}
|
||||
static FORCEINLINE uint32 GetKeyHash(KeyInitType Key)
|
||||
{
|
||||
return GetTypeHash(Key);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename KeyType, typename ValueType, bool bInAllowDuplicateKeys>
|
||||
struct TDefaultMapHashableKeyFuncs : TDefaultMapKeyFuncs<KeyType, ValueType, bInAllowDuplicateKeys>
|
||||
{
|
||||
// static_assert(THasGetTypeHash<KeyType>::Value, "TMap must have a hashable KeyType unless a custom key func is provided."); // T(R)
|
||||
};
|
||||
|
||||
template <typename KeyType, typename ValueType, typename SetAllocator, typename KeyFuncs>
|
||||
class TMapBase
|
||||
{
|
||||
template <typename OtherKeyType, typename OtherValueType, typename OtherSetAllocator, typename OtherKeyFuncs>
|
||||
friend class TMapBase;
|
||||
|
||||
friend struct TContainerTraits<TMapBase>;
|
||||
|
||||
public:
|
||||
typedef typename TTypeTraits<KeyType >::ConstPointerType KeyConstPointerType;
|
||||
typedef typename TTypeTraits<KeyType >::ConstInitType KeyInitType;
|
||||
typedef typename TTypeTraits<ValueType>::ConstInitType ValueInitType;
|
||||
typedef TPair<KeyType, ValueType> ElementType;
|
||||
|
||||
protected:
|
||||
TMapBase() = default;
|
||||
TMapBase(TMapBase&&) = default;
|
||||
TMapBase(const TMapBase&) = default;
|
||||
TMapBase& operator=(TMapBase&&) = default;
|
||||
TMapBase& operator=(const TMapBase&) = default;
|
||||
|
||||
typedef TSet<ElementType, KeyFuncs, SetAllocator> ElementSetType;
|
||||
|
||||
/** The base of TMapBase iterators. */
|
||||
template<bool bConst, bool bRangedFor = false>
|
||||
class TBaseIterator
|
||||
{
|
||||
public:
|
||||
typedef typename TChooseClass<
|
||||
bConst,
|
||||
typename TChooseClass<bRangedFor, typename ElementSetType::TRangedForConstIterator, typename ElementSetType::TConstIterator>::Result,
|
||||
typename TChooseClass<bRangedFor, typename ElementSetType::TRangedForIterator, typename ElementSetType::TIterator >::Result
|
||||
>::Result PairItType;
|
||||
private:
|
||||
typedef typename TChooseClass<bConst, const TMapBase, TMapBase>::Result MapType;
|
||||
typedef typename TChooseClass<bConst, const KeyType, KeyType>::Result ItKeyType;
|
||||
typedef typename TChooseClass<bConst, const ValueType, ValueType>::Result ItValueType;
|
||||
typedef typename TChooseClass<bConst, const typename ElementSetType::ElementType, typename ElementSetType::ElementType>::Result PairType;
|
||||
|
||||
public:
|
||||
FORCEINLINE TBaseIterator(const PairItType& InElementIt)
|
||||
: PairIt(InElementIt)
|
||||
{
|
||||
}
|
||||
|
||||
FORCEINLINE TBaseIterator& operator++()
|
||||
{
|
||||
++PairIt;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** conversion to "bool" returning true if the iterator is valid. */
|
||||
FORCEINLINE explicit operator bool() const
|
||||
{
|
||||
return !!PairIt;
|
||||
}
|
||||
/** inverse of the "bool" operator */
|
||||
FORCEINLINE bool operator !() const
|
||||
{
|
||||
return !(bool)*this;
|
||||
}
|
||||
|
||||
FORCEINLINE friend bool operator==(const TBaseIterator& Lhs, const TBaseIterator& Rhs) { return Lhs.PairIt == Rhs.PairIt; }
|
||||
FORCEINLINE friend bool operator!=(const TBaseIterator& Lhs, const TBaseIterator& Rhs) { return Lhs.PairIt != Rhs.PairIt; }
|
||||
|
||||
FORCEINLINE ItKeyType& Key() const { return PairIt->Key; }
|
||||
FORCEINLINE ItValueType& Value() const { return PairIt->Value; }
|
||||
|
||||
FORCEINLINE PairType& operator* () const { return *PairIt; }
|
||||
FORCEINLINE PairType* operator->() const { return &*PairIt; }
|
||||
|
||||
protected:
|
||||
PairItType PairIt;
|
||||
};
|
||||
|
||||
/** The base type of iterators that iterate over the values associated with a specified key. */
|
||||
template<bool bConst>
|
||||
class TBaseKeyIterator
|
||||
{
|
||||
private:
|
||||
typedef typename TChooseClass<bConst, typename ElementSetType::TConstKeyIterator, typename ElementSetType::TKeyIterator>::Result SetItType;
|
||||
typedef typename TChooseClass<bConst, const KeyType, KeyType>::Result ItKeyType;
|
||||
typedef typename TChooseClass<bConst, const ValueType, ValueType>::Result ItValueType;
|
||||
|
||||
public:
|
||||
/** Initialization constructor. */
|
||||
FORCEINLINE TBaseKeyIterator(const SetItType& InSetIt)
|
||||
: SetIt(InSetIt)
|
||||
{
|
||||
}
|
||||
|
||||
FORCEINLINE TBaseKeyIterator& operator++()
|
||||
{
|
||||
++SetIt;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** conversion to "bool" returning true if the iterator is valid. */
|
||||
FORCEINLINE explicit operator bool() const
|
||||
{
|
||||
return !!SetIt;
|
||||
}
|
||||
/** inverse of the "bool" operator */
|
||||
FORCEINLINE bool operator !() const
|
||||
{
|
||||
return !(bool)*this;
|
||||
}
|
||||
|
||||
FORCEINLINE ItKeyType& Key() const { return SetIt->Key; }
|
||||
FORCEINLINE ItValueType& Value() const { return SetIt->Value; }
|
||||
|
||||
protected:
|
||||
SetItType SetIt;
|
||||
};
|
||||
|
||||
/** A set of the key-value pairs in the map. */
|
||||
ElementSetType Pairs;
|
||||
|
||||
public:
|
||||
|
||||
/** Map iterator. */
|
||||
class TIterator : public TBaseIterator<false>
|
||||
{
|
||||
public:
|
||||
|
||||
/** Initialization constructor. */
|
||||
FORCEINLINE TIterator(TMapBase& InMap, bool bInRequiresRehashOnRemoval = false)
|
||||
: TBaseIterator<false>(InMap.Pairs.CreateIterator())
|
||||
, Map(InMap)
|
||||
, bElementsHaveBeenRemoved(false)
|
||||
, bRequiresRehashOnRemoval(bInRequiresRehashOnRemoval)
|
||||
{
|
||||
}
|
||||
|
||||
/** Destructor. */
|
||||
FORCEINLINE ~TIterator()
|
||||
{
|
||||
if (bElementsHaveBeenRemoved && bRequiresRehashOnRemoval)
|
||||
{
|
||||
Map.Pairs.Relax();
|
||||
}
|
||||
}
|
||||
|
||||
/** Removes the current pair from the map. */
|
||||
FORCEINLINE void RemoveCurrent()
|
||||
{
|
||||
TBaseIterator<false>::PairIt.RemoveCurrent();
|
||||
bElementsHaveBeenRemoved = true;
|
||||
}
|
||||
|
||||
private:
|
||||
TMapBase& Map;
|
||||
bool bElementsHaveBeenRemoved;
|
||||
bool bRequiresRehashOnRemoval;
|
||||
};
|
||||
|
||||
/** Const map iterator. */
|
||||
class TConstIterator : public TBaseIterator<true>
|
||||
{
|
||||
public:
|
||||
FORCEINLINE TConstIterator(const TMapBase& InMap)
|
||||
: TBaseIterator<true>(InMap.Pairs.CreateConstIterator())
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
using TRangedForIterator = TBaseIterator<false, true>;
|
||||
using TRangedForConstIterator = TBaseIterator<true, true>;
|
||||
|
||||
/** Iterates over values associated with a specified key in a const map. */
|
||||
class TConstKeyIterator : public TBaseKeyIterator<true>
|
||||
{
|
||||
public:
|
||||
FORCEINLINE TConstKeyIterator(const TMapBase& InMap, KeyInitType InKey)
|
||||
: TBaseKeyIterator<true>(typename ElementSetType::TConstKeyIterator(InMap.Pairs, InKey))
|
||||
{}
|
||||
};
|
||||
|
||||
/** Iterates over values associated with a specified key in a map. */
|
||||
class TKeyIterator : public TBaseKeyIterator<false>
|
||||
{
|
||||
public:
|
||||
FORCEINLINE TKeyIterator(TMapBase& InMap, KeyInitType InKey)
|
||||
: TBaseKeyIterator<false>(typename ElementSetType::TKeyIterator(InMap.Pairs, InKey))
|
||||
{}
|
||||
|
||||
/** Removes the current key-value pair from the map. */
|
||||
FORCEINLINE void RemoveCurrent()
|
||||
{
|
||||
TBaseKeyIterator<false>::SetIt.RemoveCurrent();
|
||||
}
|
||||
};
|
||||
|
||||
/** Creates an iterator over all the pairs in this map */
|
||||
FORCEINLINE TIterator CreateIterator()
|
||||
{
|
||||
return TIterator(*this);
|
||||
}
|
||||
|
||||
/** Creates a const iterator over all the pairs in this map */
|
||||
FORCEINLINE TConstIterator CreateConstIterator() const
|
||||
{
|
||||
return TConstIterator(*this);
|
||||
}
|
||||
|
||||
/** Creates an iterator over the values associated with a specified key in a map */
|
||||
FORCEINLINE TKeyIterator CreateKeyIterator(KeyInitType InKey)
|
||||
{
|
||||
return TKeyIterator(*this, InKey);
|
||||
}
|
||||
|
||||
/** Creates a const iterator over the values associated with a specified key in a map */
|
||||
FORCEINLINE TConstKeyIterator CreateConstKeyIterator(KeyInitType InKey) const
|
||||
{
|
||||
return TConstKeyIterator(*this, InKey);
|
||||
}
|
||||
|
||||
FORCEINLINE ValueType* Find(KeyConstPointerType Key)
|
||||
{
|
||||
if (auto* Pair = Pairs.Find(Key))
|
||||
{
|
||||
return &Pair->Value;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FORCEINLINE const ValueType& FindChecked(KeyConstPointerType Key) const
|
||||
{
|
||||
const auto* Pair = Pairs.Find(Key);
|
||||
// check(Pair != nullptr);
|
||||
return Pair->Value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a reference to the value associated with a specified key.
|
||||
*
|
||||
* @param Key The key to search for.
|
||||
* @return The value associated with the specified key, or triggers an assertion if the key does not exist.
|
||||
*/
|
||||
FORCEINLINE ValueType& FindChecked(KeyConstPointerType Key)
|
||||
{
|
||||
auto* Pair = Pairs.Find(Key);
|
||||
// check(Pair != nullptr);
|
||||
return Pair->Value;
|
||||
}
|
||||
|
||||
FORCEINLINE ValueType FindRef(KeyConstPointerType Key) const
|
||||
{
|
||||
if (const auto* Pair = Pairs.Find(Key))
|
||||
{
|
||||
return Pair->Value;
|
||||
}
|
||||
|
||||
return ValueType();
|
||||
}
|
||||
|
||||
FORCEINLINE int32 Num() const
|
||||
{
|
||||
return Pairs.Num();
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* DO NOT USE DIRECTLY
|
||||
* STL-like iterators to enable range-based for loop support.
|
||||
*/
|
||||
FORCEINLINE friend TRangedForIterator begin(TMapBase& MapBase) { return TRangedForIterator(begin(MapBase.Pairs)); }
|
||||
FORCEINLINE friend TRangedForConstIterator begin(const TMapBase& MapBase) { return TRangedForConstIterator(begin(MapBase.Pairs)); }
|
||||
FORCEINLINE friend TRangedForIterator end(TMapBase& MapBase) { return TRangedForIterator(end(MapBase.Pairs)); }
|
||||
FORCEINLINE friend TRangedForConstIterator end(const TMapBase& MapBase) { return TRangedForConstIterator(end(MapBase.Pairs)); }
|
||||
};
|
||||
|
||||
template <typename KeyType, typename ValueType, typename SetAllocator, typename KeyFuncs>
|
||||
class TSortableMapBase : public TMapBase<KeyType, ValueType, SetAllocator, KeyFuncs>
|
||||
{
|
||||
// friend struct TContainerTraits<TSortableMapBase>;
|
||||
|
||||
protected:
|
||||
typedef TMapBase<KeyType, ValueType, SetAllocator, KeyFuncs> Super;
|
||||
|
||||
TSortableMapBase() = default;
|
||||
TSortableMapBase(TSortableMapBase&&) = default;
|
||||
TSortableMapBase(const TSortableMapBase&) = default;
|
||||
TSortableMapBase& operator=(TSortableMapBase&&) = default;
|
||||
TSortableMapBase& operator=(const TSortableMapBase&) = default;
|
||||
};
|
||||
|
||||
template<typename KeyType, typename ValueType, typename SetAllocator = FDefaultSetAllocator, typename KeyFuncs = TDefaultMapHashableKeyFuncs<KeyType,ValueType,false>>
|
||||
class TMap : public TSortableMapBase<KeyType, ValueType, SetAllocator, KeyFuncs>
|
||||
{
|
||||
public:
|
||||
typedef TSortableMapBase<KeyType, ValueType, SetAllocator, KeyFuncs> Super;
|
||||
typedef typename Super::KeyInitType KeyInitType;
|
||||
typedef typename Super::KeyConstPointerType KeyConstPointerType;
|
||||
|
||||
typedef TPair<KeyType, ValueType> ElementType;
|
||||
public:
|
||||
typedef TSet<ElementType, KeyFuncs, SetAllocator> ElementSetType;
|
||||
|
||||
public:
|
||||
TSet<ElementType> Pairs;
|
||||
|
||||
public:
|
||||
class FBaseIterator
|
||||
{
|
||||
private:
|
||||
TMap<KeyType, ValueType>& IteratedMap;
|
||||
TSet<ElementType>::FBaseIterator SetIt;
|
||||
|
||||
public:
|
||||
FBaseIterator(TMap<KeyType, ValueType>& InMap, TSet<ElementType>::FBaseIterator InSet)
|
||||
: IteratedMap(InMap)
|
||||
, SetIt(InSet)
|
||||
{
|
||||
}
|
||||
FORCEINLINE TMap<KeyType, ValueType>::FBaseIterator operator++()
|
||||
{
|
||||
++SetIt;
|
||||
return *this;
|
||||
}
|
||||
FORCEINLINE TMap<KeyType, ValueType>::ElementType& operator*()
|
||||
{
|
||||
return *SetIt;
|
||||
}
|
||||
FORCEINLINE const TMap<KeyType, ValueType>::ElementType& operator*() const
|
||||
{
|
||||
return *SetIt;
|
||||
}
|
||||
FORCEINLINE bool operator==(const TMap<KeyType, ValueType>::FBaseIterator& Other) const
|
||||
{
|
||||
return SetIt == Other.SetIt;
|
||||
}
|
||||
FORCEINLINE bool operator!=(const TMap<KeyType, ValueType>::FBaseIterator& Other) const
|
||||
{
|
||||
return SetIt != Other.SetIt;
|
||||
}
|
||||
FORCEINLINE bool IsElementValid() const
|
||||
{
|
||||
return SetIt.IsElementValid();
|
||||
}
|
||||
};
|
||||
|
||||
FORCEINLINE TMap<KeyType, ValueType>::FBaseIterator begin()
|
||||
{
|
||||
return TMap<KeyType, ValueType>::FBaseIterator(*this, Pairs.begin());
|
||||
}
|
||||
FORCEINLINE const TMap<KeyType, ValueType>::FBaseIterator begin() const
|
||||
{
|
||||
return TMap<KeyType, ValueType>::FBaseIterator(*this, Pairs.begin());
|
||||
}
|
||||
FORCEINLINE TMap<KeyType, ValueType>::FBaseIterator end()
|
||||
{
|
||||
return TMap<KeyType, ValueType>::FBaseIterator(*this, Pairs.end());
|
||||
}
|
||||
FORCEINLINE const TMap<KeyType, ValueType>::FBaseIterator end() const
|
||||
{
|
||||
return TMap<KeyType, ValueType>::FBaseIterator(*this, Pairs.end());
|
||||
}
|
||||
FORCEINLINE ValueType& operator[](const KeyType& Key)
|
||||
{
|
||||
return this->GetByKey(Key);
|
||||
}
|
||||
FORCEINLINE const ValueType& operator[](const KeyType& Key) const
|
||||
{
|
||||
return this->GetByKey(Key);
|
||||
}
|
||||
FORCEINLINE int32 Num() const
|
||||
{
|
||||
return Pairs.Num();
|
||||
}
|
||||
FORCEINLINE bool IsValid() const
|
||||
{
|
||||
return Pairs.IsValid();
|
||||
}
|
||||
FORCEINLINE bool IsIndexValid(int32 IndexToCheck) const
|
||||
{
|
||||
return Pairs.IsIndexValid(IndexToCheck);
|
||||
}
|
||||
FORCEINLINE bool Contains(const KeyType& ElementToLookFor) const
|
||||
{
|
||||
for (auto& Element : *this)
|
||||
{
|
||||
if (Element.Key() == ElementToLookFor)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
FORCEINLINE ValueType& GetByKey(const KeyType& Key, bool* wasSuccessful = nullptr)
|
||||
{
|
||||
for (auto& Pair : *this)
|
||||
{
|
||||
if (Pair.Key() == Key)
|
||||
{
|
||||
if (wasSuccessful)
|
||||
*wasSuccessful = true;
|
||||
|
||||
return Pair.Value();
|
||||
}
|
||||
}
|
||||
|
||||
// LOG_INFO(LogDev, "Failed to find Key!!!");
|
||||
|
||||
if (wasSuccessful)
|
||||
*wasSuccessful = false;
|
||||
}
|
||||
FORCEINLINE ValueType& Find(const KeyType& Key, bool* wasSuccessful = nullptr)
|
||||
{
|
||||
return GetByKey(Key, wasSuccessful);
|
||||
}
|
||||
FORCEINLINE ValueType GetByKeyNoRef(const KeyType& Key)
|
||||
{
|
||||
for (auto& Pair : *this)
|
||||
{
|
||||
if (Pair.Key() == Key)
|
||||
{
|
||||
return Pair.Value();
|
||||
}
|
||||
}
|
||||
}
|
||||
TMap() = default;
|
||||
TMap(TMap&&) = default;
|
||||
TMap(const TMap&) = default;
|
||||
TMap& operator=(TMap&&) = default;
|
||||
TMap& operator=(const TMap&) = default;
|
||||
};
|
||||
@@ -76,4 +76,11 @@ struct FName
|
||||
|
||||
return GetComparisonIndexFast() < Rhs.GetComparisonIndexFast();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
inline uint32 GetTypeHash(const FName N)
|
||||
{
|
||||
return N.ComparisonIndex.Value + N.GetNumber();
|
||||
}
|
||||
|
||||
#define NAME_None FName(0);
|
||||
@@ -6,10 +6,37 @@
|
||||
#include "WeakObjectPtrTemplates.h"
|
||||
#include "ActorChannel.h"
|
||||
#include <memcury.h>
|
||||
#include "KismetStringLibrary.h"
|
||||
|
||||
class UNetConnection : public UPlayer
|
||||
{
|
||||
public:
|
||||
static inline UChannel* (*originalCreateChannel)(UNetConnection*, int, bool, int32_t);
|
||||
static inline UChannel* (*originalCreateChannelByName)(UNetConnection* Connection, FName* ChName, EChannelCreateFlags CreateFlags, int32_t ChannelIndex);
|
||||
|
||||
TSet<FNetworkGUID>& GetDestroyedStartupOrDormantActors() // T(REP)
|
||||
{
|
||||
static int off = Fortnite_Version == 1.11 ? 0x33678 : 0;
|
||||
|
||||
return *(TSet<FNetworkGUID>*)(__int64(this) + off);
|
||||
}
|
||||
|
||||
UChannel* CreateChannel(EChannelType ChannelType, bool bOpenedLocally, EChannelCreateFlags CreateFlags, int32 ChannelIndex = INDEX_NONE)
|
||||
{
|
||||
if (Engine_Version >= 422)
|
||||
{
|
||||
FString ActorStr = L"Actor";
|
||||
FName ActorName = UKismetStringLibrary::Conv_StringToName(ActorStr);
|
||||
|
||||
int ChannelIndex = -1; // 4294967295
|
||||
return (UActorChannel*)originalCreateChannelByName(this, &ActorName, CreateFlags, ChannelIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (UActorChannel*)originalCreateChannel(this, ChannelType, bOpenedLocally, ChannelIndex);
|
||||
}
|
||||
}
|
||||
|
||||
AActor*& GetOwningActor()
|
||||
{
|
||||
static auto OwningActorOffset = GetOffset("OwningActor");
|
||||
@@ -22,13 +49,24 @@ public:
|
||||
return *(FName*)(__int64(this) + ClientWorldPackageNameOffset);
|
||||
}
|
||||
|
||||
AActor*& GetViewTarget()
|
||||
inline AActor*& GetViewTarget()
|
||||
{
|
||||
static auto ViewTargetOffset = GetOffset("ViewTarget");
|
||||
return Get<AActor*>(ViewTargetOffset);
|
||||
}
|
||||
|
||||
int32 IsNetReady(bool Saturate)
|
||||
bool& GetTimeSensitive() // T(REP)
|
||||
{
|
||||
return *(bool*)(0);
|
||||
}
|
||||
|
||||
TArray<class UChildConnection*>& GetChildren()
|
||||
{
|
||||
static auto ChildrenOffset = GetOffset("Children");
|
||||
return Get<TArray<class UChildConnection*>>(ChildrenOffset);
|
||||
}
|
||||
|
||||
int32 IsNetReady(bool Saturate) // T(REP)
|
||||
{
|
||||
static auto IsNetReadyOffset = 0x298; // 1.11
|
||||
int32 (*IsNetReadyOriginal)(UNetConnection* Connection, bool Saturate) = decltype(IsNetReadyOriginal)(this->VFTable[IsNetReadyOffset / 8]);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -56,15 +56,6 @@ struct FNetworkObjectInfo
|
||||
TSet<TWeakObjectPtr<UNetConnection>> RecentlyDormantConnections;
|
||||
};
|
||||
|
||||
struct FNetViewer
|
||||
{
|
||||
UNetConnection* Connection; // 0x0000(0x0008) (ZeroConstructor, IsPlainOldData)
|
||||
AActor* InViewer; // 0x0008(0x0008) (ZeroConstructor, IsPlainOldData)
|
||||
AActor* ViewTarget; // 0x0010(0x0008) (ZeroConstructor, IsPlainOldData)
|
||||
FVector ViewLocation; // 0x0018(0x000C) (IsPlainOldData)
|
||||
FVector ViewDir;
|
||||
};
|
||||
|
||||
class FNetworkObjectList
|
||||
{
|
||||
public:
|
||||
@@ -77,6 +68,7 @@ public:
|
||||
TMap<TWeakObjectPtr<UNetConnection>, int32> NumDormantObjectsPerConnection;
|
||||
|
||||
void Remove(AActor* const Actor);
|
||||
const FNetworkObjectSet& GetActiveObjects() const { return ActiveNetworkObjects; }
|
||||
};
|
||||
|
||||
struct FActorPriority
|
||||
@@ -130,6 +122,13 @@ public:
|
||||
|
||||
static void TickFlushHook(UNetDriver* NetDriver);
|
||||
|
||||
TMap<FNetworkGUID, FActorDestructionInfo>& GetDestroyedStartupOrDormantActors() // T(REP)
|
||||
{
|
||||
static int off = Fortnite_Version == 1.11 ? 0x228 : 0; // 0x240
|
||||
|
||||
return *(TMap<FNetworkGUID, FActorDestructionInfo>*)(__int64(this) + off);
|
||||
}
|
||||
|
||||
int& GetMaxInternetClientRate()
|
||||
{
|
||||
static auto MaxInternetClientRateOffset = GetOffset("MaxInternetClientRate");
|
||||
@@ -142,13 +141,19 @@ public:
|
||||
return Get<int>(MaxClientRateOffset);
|
||||
}
|
||||
|
||||
FName& GetNetDriverName()
|
||||
{
|
||||
static auto NetDriverNameOffset = GetOffset("NetDriverName");
|
||||
return Get<FName>(NetDriverNameOffset);
|
||||
}
|
||||
|
||||
FNetGUIDCache* GetGuidCache()
|
||||
{
|
||||
static auto GuidCacheOffset = GetOffset("WorldPackage") + 8; // checked for 1.11
|
||||
return GetPtr<FNetGUIDCache>(GuidCacheOffset);
|
||||
}
|
||||
|
||||
UWorld*& GetNetDriverWorld() const
|
||||
UWorld*& World() const
|
||||
{
|
||||
static auto WorldOffset = GetOffset("World");
|
||||
return Get<UWorld*>(WorldOffset);
|
||||
@@ -195,8 +200,9 @@ public:
|
||||
bool InitListen(FNetworkNotify* InNotify, FURL& ListenURL, bool bReuseAddressAndPort, FString& Error) { return InitListenOriginal(this, InNotify, ListenURL, bReuseAddressAndPort, Error); }
|
||||
void SetWorld(UWorld* World) { return SetWorldOriginal(this, World); }
|
||||
int32 ServerReplicateActors();
|
||||
int32 ServerReplicateActors_ProcessPrioritizedActors(UNetConnection* Connection, const std::vector<FNetViewer>& ConnectionViewers, FActorPriority** PriorityActors, const int32 FinalSortedCount, int32& OutUpdated);
|
||||
int32 ServerReplicateActors_PrepConnections();
|
||||
int32 ServerReplicateActors_ProcessPrioritizedActors(UNetConnection* Connection, const std::vector<FNetViewer>& ConnectionViewers, std::vector<FActorPriority*>& PriorityActors, const int32 FinalSortedCount, int32& OutUpdated);
|
||||
void ServerReplicateActors_BuildConsiderList(std::vector<FNetworkObjectInfo*>& OutConsiderList, const float ServerTickTime);
|
||||
int32 ServerReplicateActors_PrioritizeActors(UNetConnection* Connection, const std::vector<FNetViewer>& ConnectionViewers, const std::vector<FNetworkObjectInfo*> ConsiderList, const bool bCPUSaturated, FActorPriority*& OutPriorityList, FActorPriority**& OutPriorityActors);
|
||||
int32 ServerReplicateActors_PrioritizeActors(UNetConnection* Connection, const std::vector<FNetViewer>& ConnectionViewers, const std::vector<FNetworkObjectInfo*>& ConsiderList, const bool bCPUSaturated, std::vector<FActorPriority>& OutPriorityList, std::vector<FActorPriority*>& OutPriorityActors);
|
||||
FNetworkObjectList& GetNetworkObjectList();
|
||||
};
|
||||
@@ -1,7 +1,8 @@
|
||||
#include "NetDriver.h"
|
||||
|
||||
void FNetworkObjectList::Remove(AActor* const Actor)
|
||||
void FNetworkObjectList::Remove(AActor* const Actor) // T(REP)
|
||||
{
|
||||
#if 0
|
||||
if (Actor == nullptr)
|
||||
{
|
||||
return;
|
||||
@@ -103,5 +104,7 @@ void FNetworkObjectList::Remove(AActor* const Actor)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// check((ActiveNetworkObjects.Num() + ObjectsDormantOnAllConnections.Num()) == AllNetworkObjects.Num());
|
||||
}
|
||||
11
Project Reboot 3.0/NetworkingDistanceConstants.h
Normal file
11
Project Reboot 3.0/NetworkingDistanceConstants.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
// magic number distances used by AI/networking
|
||||
#define CLOSEPROXIMITY 500.f
|
||||
#define NEARSIGHTTHRESHOLD 2000.f
|
||||
#define MEDSIGHTTHRESHOLD 3162.f
|
||||
#define FARSIGHTTHRESHOLD 8000.f
|
||||
#define CLOSEPROXIMITYSQUARED (CLOSEPROXIMITY*CLOSEPROXIMITY)
|
||||
#define NEARSIGHTTHRESHOLDSQUARED (NEARSIGHTTHRESHOLD*NEARSIGHTTHRESHOLD)
|
||||
#define MEDSIGHTTHRESHOLDSQUARED (MEDSIGHTTHRESHOLD*MEDSIGHTTHRESHOLD)
|
||||
#define FARSIGHTTHRESHOLDSQUARED (FARSIGHTTHRESHOLD*FARSIGHTTHRESHOLD)
|
||||
@@ -7,6 +7,21 @@
|
||||
#include "UObjectArray.h"
|
||||
#include "Package.h"
|
||||
|
||||
UObject* UObject::GetTypedOuter(UClass* Target) const
|
||||
{
|
||||
// ensureMsgf(Target != UPackage::StaticClass(), TEXT("Calling GetTypedOuter to retrieve a package is now invalid, you should use GetPackage() instead."));
|
||||
|
||||
UObject* Result = NULL;
|
||||
for (UObject* NextOuter = GetOuter(); Result == NULL && NextOuter != NULL; NextOuter = NextOuter->GetOuter())
|
||||
{
|
||||
if (NextOuter->IsA(Target))
|
||||
{
|
||||
Result = NextOuter;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
void* UObject::GetProperty(const std::string& ChildName, bool bWarnIfNotFound) const
|
||||
{
|
||||
for (auto CurrentClass = ClassPrivate; CurrentClass; CurrentClass = *(UClass**)(__int64(CurrentClass) + Offsets::SuperStruct))
|
||||
|
||||
@@ -78,6 +78,14 @@ public:
|
||||
void SetBitfieldValue(int Offset, uint8_t FieldMask, bool NewValue);
|
||||
void SetBitfieldValue(const std::string& ChildName, uint8_t FieldMask, bool NewValue) { return SetBitfieldValue(GetOffset(ChildName), FieldMask, NewValue); }
|
||||
|
||||
UObject* GetTypedOuter(UClass* Target) const;
|
||||
|
||||
template<typename T>
|
||||
T* GetTypedOuter() const
|
||||
{
|
||||
return (T*)GetTypedOuter(T::StaticClass());
|
||||
}
|
||||
|
||||
/* template <typename T = UObject*>
|
||||
T& GetCached(const std::string& ChildName)
|
||||
{
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
class APlayerController : public AController
|
||||
{
|
||||
public:
|
||||
static inline void (*originalSendClientAdjustment)(APlayerController*);
|
||||
|
||||
UCheatManager*& GetCheatManager()
|
||||
{
|
||||
static auto CheatManagerOffset = this->GetOffset("CheatManager");
|
||||
|
||||
@@ -308,6 +308,8 @@
|
||||
<ClInclude Include="BuildingTrap.h" />
|
||||
<ClInclude Include="Channel.h" />
|
||||
<ClInclude Include="CheatManager.h" />
|
||||
<ClInclude Include="ChildConnection.h" />
|
||||
<ClInclude Include="ChooseClass.h" />
|
||||
<ClInclude Include="Class.h" />
|
||||
<ClInclude Include="commands.h" />
|
||||
<ClInclude Include="ContainerAllocationPolicies.h" />
|
||||
@@ -446,6 +448,7 @@
|
||||
<ClInclude Include="NetDriver.h" />
|
||||
<ClInclude Include="NetSerialization.h" />
|
||||
<ClInclude Include="NetworkGuid.h" />
|
||||
<ClInclude Include="NetworkingDistanceConstants.h" />
|
||||
<ClInclude Include="NumericLimits.h" />
|
||||
<ClInclude Include="Object.h" />
|
||||
<ClInclude Include="ObjectMacros.h" />
|
||||
@@ -499,6 +502,7 @@
|
||||
<ClInclude Include="WeakObjectPtr.h" />
|
||||
<ClInclude Include="WeakObjectPtrTemplates.h" />
|
||||
<ClInclude Include="World.h" />
|
||||
<ClInclude Include="WorldSettings.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="DelegateSignatureImpl.inl" />
|
||||
|
||||
@@ -987,6 +987,18 @@
|
||||
<ClInclude Include="botnames.h">
|
||||
<Filter>Reboot\Public</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ChildConnection.h">
|
||||
<Filter>Engine\Source\Runtime\Engine\Classes\Engine</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="WorldSettings.h">
|
||||
<Filter>Engine\Source\Runtime\Engine\Classes\GameFramework</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ChooseClass.h">
|
||||
<Filter>Engine\Source\Runtime\Core\Public\Templates</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="NetworkingDistanceConstants.h">
|
||||
<Filter>Engine\Source\Runtime\Engine\Public</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Engine">
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
// Copied from 4.19
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SparseArray.h"
|
||||
#include "ChooseClass.h"
|
||||
#include "UnrealTypeTraits.h"
|
||||
|
||||
template <typename ElementType>
|
||||
class TSetElement
|
||||
@@ -32,112 +36,434 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <typename SetType>
|
||||
/** Either NULL or an identifier for an element of a set. */
|
||||
class FSetElementId
|
||||
{
|
||||
public:
|
||||
|
||||
template<typename, typename, typename>
|
||||
friend class TSet;
|
||||
|
||||
friend class FScriptSet;
|
||||
|
||||
/** Default constructor. */
|
||||
FORCEINLINE FSetElementId() :
|
||||
Index(INDEX_NONE)
|
||||
{}
|
||||
|
||||
/** @return a boolean value representing whether the id is NULL. */
|
||||
FORCEINLINE bool IsValidId() const
|
||||
{
|
||||
return Index != INDEX_NONE;
|
||||
}
|
||||
|
||||
/** Comparison operator. */
|
||||
FORCEINLINE friend bool operator==(const FSetElementId& A, const FSetElementId& B)
|
||||
{
|
||||
return A.Index == B.Index;
|
||||
}
|
||||
|
||||
FORCEINLINE int32 AsInteger() const
|
||||
{
|
||||
return Index;
|
||||
}
|
||||
|
||||
FORCEINLINE static FSetElementId FromInteger(int32 Integer)
|
||||
{
|
||||
return FSetElementId(Integer);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** The index of the element in the set's element array. */
|
||||
int32 Index;
|
||||
|
||||
/** Initialization constructor. */
|
||||
FORCEINLINE FSetElementId(int32 InIndex) :
|
||||
Index(InIndex)
|
||||
{}
|
||||
|
||||
/** Implicit conversion to the element index. */
|
||||
FORCEINLINE operator int32() const
|
||||
{
|
||||
return Index;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ElementType, typename InKeyType, bool bInAllowDuplicateKeys = false>
|
||||
struct BaseKeyFuncs
|
||||
{
|
||||
typedef InKeyType KeyType;
|
||||
typedef typename TCallTraits<InKeyType>::ParamType KeyInitType;
|
||||
typedef typename TCallTraits<ElementType>::ParamType ElementInitType;
|
||||
|
||||
enum { bAllowDuplicateKeys = bInAllowDuplicateKeys };
|
||||
};
|
||||
|
||||
/**
|
||||
* A default implementation of the KeyFuncs used by TSet which uses the element as a key.
|
||||
*/
|
||||
template<typename ElementType, bool bInAllowDuplicateKeys = false>
|
||||
struct DefaultKeyFuncs : BaseKeyFuncs<ElementType, ElementType, bInAllowDuplicateKeys>
|
||||
{
|
||||
typedef typename TCallTraits<ElementType>::ParamType KeyInitType;
|
||||
typedef typename TCallTraits<ElementType>::ParamType ElementInitType;
|
||||
|
||||
/**
|
||||
* @return The key used to index the given element.
|
||||
*/
|
||||
static FORCEINLINE KeyInitType GetSetKey(ElementInitType Element)
|
||||
{
|
||||
return Element;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if the keys match.
|
||||
*/
|
||||
static FORCEINLINE bool Matches(KeyInitType A, KeyInitType B)
|
||||
{
|
||||
return A == B;
|
||||
}
|
||||
|
||||
/** Calculates a hash index for a key. */
|
||||
static FORCEINLINE uint32 GetKeyHash(KeyInitType Key)
|
||||
{
|
||||
return GetTypeHash(Key);
|
||||
}
|
||||
};
|
||||
|
||||
template<
|
||||
typename InElementType,
|
||||
typename KeyFuncs = DefaultKeyFuncs<InElementType>,
|
||||
typename Allocator = FDefaultSetAllocator
|
||||
>
|
||||
class TSet;
|
||||
|
||||
template<
|
||||
typename InElementType,
|
||||
typename KeyFuncs /*= DefaultKeyFuncs<ElementType>*/,
|
||||
typename Allocator /*= FDefaultSetAllocator*/
|
||||
>
|
||||
class TSet
|
||||
{
|
||||
private:
|
||||
friend TSparseArray;
|
||||
|
||||
public:
|
||||
typedef TSetElement<SetType> ElementType;
|
||||
typedef TSparseArrayElementOrListLink<ElementType> ArrayElementType;
|
||||
typedef typename KeyFuncs::KeyInitType KeyInitType;
|
||||
typedef typename KeyFuncs::ElementInitType ElementInitType;
|
||||
|
||||
typedef TSetElement<InElementType> SetElementType;
|
||||
|
||||
typedef InElementType ElementType;
|
||||
public:
|
||||
typedef TSparseArray<SetElementType, typename Allocator::SparseArrayAllocator> ElementArrayType;
|
||||
typedef typename Allocator::HashAllocator::template ForElementType<FSetElementId> HashType;
|
||||
|
||||
ElementArrayType Elements;
|
||||
|
||||
mutable HashType Hash;
|
||||
mutable int32 HashSize;
|
||||
|
||||
FORCEINLINE FSetElementId& GetTypedHash(int32 HashIndex) const
|
||||
{
|
||||
return ((FSetElementId*)Hash.GetAllocation())[HashIndex & (HashSize - 1)];
|
||||
}
|
||||
|
||||
public:
|
||||
TSparseArray<ElementType> Elements;
|
||||
FORCEINLINE ElementType* Find(KeyInitType Key)
|
||||
{
|
||||
FSetElementId ElementId = FindId(Key);
|
||||
if (ElementId.IsValidId())
|
||||
{
|
||||
return &Elements[ElementId].Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
mutable TInlineAllocator<1>::ForElementType<int> Hash;
|
||||
mutable int32 HashSize;
|
||||
/**
|
||||
* Finds an element with the given key in the set.
|
||||
* @param Key - The key to search for.
|
||||
* @return A const pointer to an element with the given key. If no element in the set has the given key, this will return NULL.
|
||||
*/
|
||||
FORCEINLINE const ElementType* Find(KeyInitType Key) const
|
||||
{
|
||||
FSetElementId ElementId = FindId(Key);
|
||||
if (ElementId.IsValidId())
|
||||
{
|
||||
return &Elements[ElementId].Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
class FBaseIterator
|
||||
|
||||
/** Adds an element to the hash. */
|
||||
FORCEINLINE void HashElement(FSetElementId ElementId, const SetElementType& Element) const
|
||||
{
|
||||
// Compute the hash bucket the element goes in.
|
||||
Element.HashIndex = KeyFuncs::GetKeyHash(KeyFuncs::GetSetKey(Element.Value)) & (HashSize - 1);
|
||||
|
||||
// Link the element into the hash bucket.
|
||||
Element.HashNextId = GetTypedHash(Element.HashIndex);
|
||||
GetTypedHash(Element.HashIndex) = ElementId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the hash has an appropriate number of buckets, and if not resizes it.
|
||||
* @param NumHashedElements - The number of elements to size the hash for.
|
||||
* @param bAllowShrinking - true if the hash is allowed to shrink.
|
||||
* @return true if the set was rehashed.
|
||||
*/
|
||||
bool ConditionalRehash(int32 NumHashedElements, bool bAllowShrinking = false) const
|
||||
{
|
||||
// Calculate the desired hash size for the specified number of elements.
|
||||
const int32 DesiredHashSize = Allocator::GetNumberOfHashBuckets(NumHashedElements);
|
||||
|
||||
// If the hash hasn't been created yet, or is smaller than the desired hash size, rehash.
|
||||
if (NumHashedElements > 0 &&
|
||||
(!HashSize ||
|
||||
HashSize < DesiredHashSize ||
|
||||
(HashSize > DesiredHashSize && bAllowShrinking)))
|
||||
{
|
||||
HashSize = DesiredHashSize;
|
||||
Rehash();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Resizes the hash. */
|
||||
void Rehash() const
|
||||
{
|
||||
// Free the old hash.
|
||||
Hash.ResizeAllocation(0, 0, sizeof(FSetElementId));
|
||||
|
||||
int32 LocalHashSize = HashSize;
|
||||
if (LocalHashSize)
|
||||
{
|
||||
// Allocate the new hash.
|
||||
// checkSlow(FMath::IsPowerOfTwo(HashSize));
|
||||
Hash.ResizeAllocation(0, LocalHashSize, sizeof(FSetElementId));
|
||||
for (int32 HashIndex = 0; HashIndex < LocalHashSize; ++HashIndex)
|
||||
{
|
||||
GetTypedHash(HashIndex) = FSetElementId();
|
||||
}
|
||||
|
||||
// Add the existing elements to the new hash.
|
||||
for (typename ElementArrayType::TConstIterator ElementIt(Elements); ElementIt; ++ElementIt)
|
||||
{
|
||||
HashElement(FSetElementId(ElementIt.GetIndex()), *ElementIt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<bool bConst, bool bRangedFor = false>
|
||||
class TBaseIterator
|
||||
{
|
||||
private:
|
||||
TSet<SetType>& IteratedSet;
|
||||
TSparseArray<ElementType>::FBaseIterator ElementIt;
|
||||
friend class TSet;
|
||||
|
||||
typedef typename TChooseClass<bConst, const ElementType, ElementType>::Result ItElementType;
|
||||
|
||||
public:
|
||||
FORCEINLINE FBaseIterator(const TSet<SetType>& InSet, TSparseArray<TSetElement<SetType>>::FBaseIterator InElementIt)
|
||||
: IteratedSet(const_cast<TSet<SetType>&>(InSet))
|
||||
, ElementIt(InElementIt)
|
||||
typedef typename TChooseClass<
|
||||
bConst,
|
||||
typename TChooseClass<bRangedFor, typename ElementArrayType::TRangedForConstIterator, typename ElementArrayType::TConstIterator>::Result,
|
||||
typename TChooseClass<bRangedFor, typename ElementArrayType::TRangedForIterator, typename ElementArrayType::TIterator >::Result
|
||||
>::Result ElementItType;
|
||||
|
||||
FORCEINLINE TBaseIterator(const ElementItType& InElementIt)
|
||||
: ElementIt(InElementIt)
|
||||
{
|
||||
}
|
||||
|
||||
FORCEINLINE explicit operator bool() const
|
||||
{
|
||||
return (bool)ElementIt;
|
||||
}
|
||||
FORCEINLINE TSet<SetType>::FBaseIterator& operator++()
|
||||
/** Advances the iterator to the next element. */
|
||||
FORCEINLINE TBaseIterator& operator++()
|
||||
{
|
||||
++ElementIt;
|
||||
return *this;
|
||||
}
|
||||
FORCEINLINE bool operator==(const TSet<SetType>::FBaseIterator& OtherIt) const
|
||||
|
||||
/** conversion to "bool" returning true if the iterator is valid. */
|
||||
FORCEINLINE explicit operator bool() const
|
||||
{
|
||||
return ElementIt == OtherIt.ElementIt;
|
||||
return !!ElementIt;
|
||||
}
|
||||
FORCEINLINE bool operator!=(const TSet<SetType>::FBaseIterator& OtherIt) const
|
||||
/** inverse of the "bool" operator */
|
||||
FORCEINLINE bool operator !() const
|
||||
{
|
||||
return ElementIt != OtherIt.ElementIt;
|
||||
return !(bool)*this;
|
||||
}
|
||||
FORCEINLINE TSet<SetType>::FBaseIterator& operator=(TSet<SetType>::FBaseIterator& OtherIt)
|
||||
|
||||
// Accessors.
|
||||
FORCEINLINE FSetElementId GetId() const
|
||||
{
|
||||
return ElementIt = OtherIt.ElementIt;
|
||||
return TSet::IndexToId(ElementIt.GetIndex());
|
||||
}
|
||||
FORCEINLINE SetType& operator*()
|
||||
FORCEINLINE ItElementType* operator->() const
|
||||
{
|
||||
return (*ElementIt).Value;
|
||||
return &ElementIt->Value;
|
||||
}
|
||||
FORCEINLINE const SetType& operator*() const
|
||||
FORCEINLINE ItElementType& operator*() const
|
||||
{
|
||||
return &((*ElementIt).Value);
|
||||
return ElementIt->Value;
|
||||
}
|
||||
FORCEINLINE SetType* operator->()
|
||||
|
||||
FORCEINLINE friend bool operator==(const TBaseIterator& Lhs, const TBaseIterator& Rhs) { return Lhs.ElementIt == Rhs.ElementIt; }
|
||||
FORCEINLINE friend bool operator!=(const TBaseIterator& Lhs, const TBaseIterator& Rhs) { return Lhs.ElementIt != Rhs.ElementIt; }
|
||||
|
||||
ElementItType ElementIt;
|
||||
};
|
||||
|
||||
/** The base type of whole set iterators. */
|
||||
template<bool bConst>
|
||||
class TBaseKeyIterator
|
||||
{
|
||||
private:
|
||||
typedef typename TChooseClass<bConst, const TSet, TSet>::Result SetType;
|
||||
typedef typename TChooseClass<bConst, const ElementType, ElementType>::Result ItElementType;
|
||||
|
||||
public:
|
||||
/** Initialization constructor. */
|
||||
FORCEINLINE TBaseKeyIterator(SetType& InSet, KeyInitType InKey)
|
||||
: Set(InSet)
|
||||
, Key(InKey)
|
||||
, Id()
|
||||
{
|
||||
return &((*ElementIt).Value);
|
||||
// The set's hash needs to be initialized to find the elements with the specified key.
|
||||
Set.ConditionalRehash(Set.Elements.Num());
|
||||
if (Set.HashSize)
|
||||
{
|
||||
NextId = Set.GetTypedHash(KeyFuncs::GetKeyHash(Key));
|
||||
++(*this);
|
||||
}
|
||||
/* // Milxnor: This is only on newer builds?
|
||||
else
|
||||
{
|
||||
NextIndex = INDEX_NONE;
|
||||
}
|
||||
*/
|
||||
}
|
||||
FORCEINLINE const SetType* operator->() const
|
||||
|
||||
/** Advances the iterator to the next element. */
|
||||
FORCEINLINE TBaseKeyIterator& operator++()
|
||||
{
|
||||
return &(*ElementIt).Value;
|
||||
Id = NextId;
|
||||
|
||||
while (Id.IsValidId())
|
||||
{
|
||||
NextId = Set.GetInternalElement(Id).HashNextId;
|
||||
// checkSlow(Id != NextId);
|
||||
|
||||
if (KeyFuncs::Matches(KeyFuncs::GetSetKey(Set[Id]), Key))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Id = NextId;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
FORCEINLINE const int32 GetIndex() const
|
||||
|
||||
/** conversion to "bool" returning true if the iterator is valid. */
|
||||
FORCEINLINE explicit operator bool() const
|
||||
{
|
||||
return ElementIt.GetIndex();
|
||||
return Id.IsValidId();
|
||||
}
|
||||
FORCEINLINE ElementType& GetSetElement()
|
||||
/** inverse of the "bool" operator */
|
||||
FORCEINLINE bool operator !() const
|
||||
{
|
||||
return *ElementIt;
|
||||
return !(bool)*this;
|
||||
}
|
||||
FORCEINLINE const ElementType& GetSetElement() const
|
||||
|
||||
// Accessors.
|
||||
FORCEINLINE ItElementType* operator->() const
|
||||
{
|
||||
return *ElementIt;
|
||||
return &Set[Id];
|
||||
}
|
||||
FORCEINLINE bool IsElementValid() const
|
||||
FORCEINLINE ItElementType& operator*() const
|
||||
{
|
||||
return Set[Id];
|
||||
}
|
||||
|
||||
protected:
|
||||
SetType& Set;
|
||||
typename TTypeTraits<typename KeyFuncs::KeyType>::ConstPointerType Key;
|
||||
FSetElementId Id;
|
||||
FSetElementId NextId;
|
||||
};
|
||||
|
||||
FORCEINLINE const SetElementType& GetInternalElement(FSetElementId Id) const
|
||||
{
|
||||
return Elements[Id];
|
||||
}
|
||||
FORCEINLINE SetElementType& GetInternalElement(FSetElementId Id)
|
||||
{
|
||||
return Elements[Id];
|
||||
}
|
||||
|
||||
public:
|
||||
class TConstIterator : public TBaseIterator<true>
|
||||
{
|
||||
friend class TSet;
|
||||
|
||||
public:
|
||||
FORCEINLINE TConstIterator(const TSet& InSet)
|
||||
: TBaseIterator<true>(begin(InSet.Elements))
|
||||
{
|
||||
return ElementIt.IsElementValid();
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
FORCEINLINE TSet<SetType>::FBaseIterator begin()
|
||||
class TIterator : public TBaseIterator<false>
|
||||
{
|
||||
return TSet<SetType>::FBaseIterator(*this, Elements.begin());
|
||||
}
|
||||
FORCEINLINE const TSet<SetType>::FBaseIterator begin() const
|
||||
friend class TSet;
|
||||
|
||||
public:
|
||||
FORCEINLINE TIterator(TSet& InSet)
|
||||
: TBaseIterator<false>(begin(InSet.Elements))
|
||||
, Set(InSet)
|
||||
{
|
||||
}
|
||||
|
||||
/** Removes the current element from the set. */
|
||||
/* // T(R)
|
||||
FORCEINLINE void RemoveCurrent()
|
||||
{
|
||||
Set.Remove(TBaseIterator<false>::GetId());
|
||||
}
|
||||
*/
|
||||
|
||||
private:
|
||||
TSet& Set;
|
||||
};
|
||||
|
||||
using TRangedForConstIterator = TBaseIterator<true, true>;
|
||||
using TRangedForIterator = TBaseIterator<false, true>;
|
||||
|
||||
static FORCEINLINE FSetElementId IndexToId(int32 Index)
|
||||
{
|
||||
return TSet<SetType>::FBaseIterator(*this, Elements.begin());
|
||||
}
|
||||
FORCEINLINE TSet<SetType>::FBaseIterator end()
|
||||
{
|
||||
return TSet<SetType>::FBaseIterator(*this, Elements.end());
|
||||
}
|
||||
FORCEINLINE const TSet<SetType>::FBaseIterator end() const
|
||||
{
|
||||
return TSet<SetType>::FBaseIterator(*this, Elements.end());
|
||||
return FSetElementId(Index);
|
||||
}
|
||||
|
||||
FORCEINLINE SetType& operator[](int Index)
|
||||
/** Creates an iterator for the contents of this set */
|
||||
FORCEINLINE TIterator CreateIterator()
|
||||
{
|
||||
return Elements[Index].ElementData.Value;
|
||||
return TIterator(*this);
|
||||
}
|
||||
|
||||
/** Creates a const iterator for the contents of this set */
|
||||
FORCEINLINE TConstIterator CreateConstIterator() const
|
||||
{
|
||||
return TConstIterator(*this);
|
||||
}
|
||||
|
||||
FORCEINLINE int32 Num() const
|
||||
@@ -156,65 +482,39 @@ public:
|
||||
{
|
||||
return Elements;
|
||||
}
|
||||
FORCEINLINE const TBitArray& GetAllocationFlags() const
|
||||
{
|
||||
return Elements.GetAllocationFlags();
|
||||
}
|
||||
FORCEINLINE bool IsIndexValid(int32 IndexToCheck) const
|
||||
{
|
||||
return Elements.IsIndexValid(IndexToCheck);
|
||||
}
|
||||
FORCEINLINE const bool Contains(const SetType& ElementToLookFor) const
|
||||
FSetElementId FindId(KeyInitType Key) const
|
||||
{
|
||||
if (Num() <= 0)
|
||||
return false;
|
||||
|
||||
for (SetType Element : *this)
|
||||
if (Elements.Num())
|
||||
{
|
||||
if (Element == ElementToLookFor)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
FORCEINLINE const int32 Find(const SetType& ElementToLookFor) const
|
||||
{
|
||||
for (auto It = this->begin(); It != this->end(); ++It)
|
||||
{
|
||||
if (*It == ElementToLookFor)
|
||||
for (FSetElementId ElementId = GetTypedHash(KeyFuncs::GetKeyHash(Key));
|
||||
ElementId.IsValidId();
|
||||
ElementId = Elements[ElementId].HashNextId)
|
||||
{
|
||||
return It.GetIndex();
|
||||
if (KeyFuncs::Matches(KeyFuncs::GetSetKey(Elements[ElementId].Value), Key))
|
||||
{
|
||||
return ElementId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
return FSetElementId();
|
||||
}
|
||||
FORCEINLINE bool Remove(const SetType& ElementToRemove)
|
||||
|
||||
FORCEINLINE bool Contains(KeyInitType Key) const
|
||||
{
|
||||
auto Idx = Find(ElementToRemove);
|
||||
|
||||
if (Idx == -1)
|
||||
return false;
|
||||
|
||||
Elements.RemoveAt(Idx);
|
||||
return true;
|
||||
}
|
||||
FORCEINLINE bool Remove(int Index)
|
||||
{
|
||||
Elements.RemoveAt(Index);
|
||||
return true;
|
||||
return FindId(Key).IsValidId();
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* DO NOT USE DIRECTLY
|
||||
* STL-like iterators to enable range-based for loop support.
|
||||
*/
|
||||
FORCEINLINE friend TRangedForIterator begin(TSet& Set) { return TRangedForIterator(begin(Set.Elements)); }
|
||||
FORCEINLINE friend TRangedForConstIterator begin(const TSet& Set) { return TRangedForConstIterator(begin(Set.Elements)); }
|
||||
FORCEINLINE friend TRangedForIterator end(TSet& Set) { return TRangedForIterator(end(Set.Elements)); }
|
||||
FORCEINLINE friend TRangedForConstIterator end(const TSet& Set) { return TRangedForConstIterator(end(Set.Elements)); }
|
||||
};
|
||||
|
||||
|
||||
/* template<typename InElementType> //, typename KeyFuncs, typename Allocator>
|
||||
class TSet
|
||||
{
|
||||
public:
|
||||
typedef TSetElement<InElementType> ElementType;
|
||||
typedef TSparseArrayElementOrListLink<ElementType> ArrayElementType;
|
||||
|
||||
TSparseArray<ElementType> Elements;
|
||||
|
||||
mutable TInlineAllocator<1>::ForElementType<int> Hash;
|
||||
mutable int32 HashSize;
|
||||
}; */
|
||||
@@ -2,259 +2,229 @@
|
||||
|
||||
#include "Array.h"
|
||||
#include "BitArray.h"
|
||||
#include "ChooseClass.h"
|
||||
#include "log.h"
|
||||
#include "TypeCompatibleBytes.h"
|
||||
|
||||
#define INDEX_NONE -1
|
||||
|
||||
template <typename ElementType>
|
||||
union TSparseArrayElementOrListLink
|
||||
template<typename ElementType>
|
||||
union TSparseArrayElementOrFreeListLink
|
||||
{
|
||||
TSparseArrayElementOrListLink(ElementType& InElement)
|
||||
: ElementData(InElement)
|
||||
{
|
||||
}
|
||||
TSparseArrayElementOrListLink(ElementType&& InElement)
|
||||
: ElementData(InElement)
|
||||
{
|
||||
}
|
||||
|
||||
TSparseArrayElementOrListLink(int32 InPrevFree, int32 InNextFree)
|
||||
: PrevFreeIndex(InPrevFree)
|
||||
, NextFreeIndex(InNextFree)
|
||||
{
|
||||
}
|
||||
|
||||
TSparseArrayElementOrListLink<ElementType> operator=(const TSparseArrayElementOrListLink<ElementType>& Other)
|
||||
{
|
||||
return TSparseArrayElementOrListLink(Other.NextFreeIndex, Other.PrevFreeIndex);
|
||||
}
|
||||
|
||||
/** If the element is allocated, its value is stored here. */
|
||||
ElementType ElementData;
|
||||
|
||||
struct
|
||||
{
|
||||
/** If the element isn't allocated, this is a link to the previous element in the array's free list. */
|
||||
int PrevFreeIndex;
|
||||
int32 PrevFreeIndex;
|
||||
|
||||
/** If the element isn't allocated, this is a link to the next element in the array's free list. */
|
||||
int NextFreeIndex;
|
||||
int32 NextFreeIndex;
|
||||
};
|
||||
};
|
||||
|
||||
template <typename ArrayType>
|
||||
template<typename ElementType, typename Allocator = FDefaultSparseArrayAllocator >
|
||||
class TSparseArray;
|
||||
|
||||
template<typename InElementType, typename Allocator>
|
||||
class TSparseArray
|
||||
{
|
||||
public:
|
||||
typedef TSparseArrayElementOrListLink<ArrayType> FSparseArrayElement;
|
||||
using ElementType = InElementType;
|
||||
|
||||
TArray<FSparseArrayElement> Data;
|
||||
TBitArray AllocationFlags;
|
||||
public:
|
||||
typedef TSparseArrayElementOrFreeListLink<
|
||||
TAlignedBytes<sizeof(ElementType), alignof(ElementType)>
|
||||
> FElementOrFreeListLink;
|
||||
|
||||
typedef TArray<FElementOrFreeListLink/*, typename Allocator::ElementAllocator*/> DataType;
|
||||
DataType Data;
|
||||
|
||||
typedef TBitArray<typename Allocator::BitArrayAllocator> AllocationBitArrayType;
|
||||
AllocationBitArrayType AllocationFlags;
|
||||
|
||||
/** The index of an unallocated element in the array that currently contains the head of the linked list of free elements. */
|
||||
int32 FirstFreeIndex;
|
||||
|
||||
/** The number of elements in the free list. */
|
||||
int32 NumFreeIndices;
|
||||
|
||||
FORCEINLINE int32 Num() const
|
||||
{
|
||||
return Data.Num() - NumFreeIndices;
|
||||
}
|
||||
|
||||
class FBaseIterator
|
||||
template<bool bConst>
|
||||
class TBaseIterator
|
||||
{
|
||||
public:
|
||||
typedef TConstSetBitIterator<typename Allocator::BitArrayAllocator> BitArrayItType;
|
||||
|
||||
private:
|
||||
TSparseArray<ArrayType>& IteratedArray;
|
||||
TBitArray::FSetBitIterator BitArrayIt;
|
||||
typedef typename TChooseClass<bConst, const TSparseArray, TSparseArray>::Result ArrayType;
|
||||
typedef typename TChooseClass<bConst, const ElementType, ElementType>::Result ItElementType;
|
||||
|
||||
public:
|
||||
FORCEINLINE FBaseIterator(const TSparseArray<ArrayType>& Array, const TBitArray::FSetBitIterator BitIterator)
|
||||
: IteratedArray(const_cast<TSparseArray<ArrayType>&>(Array))
|
||||
, BitArrayIt(const_cast<TBitArray::FSetBitIterator&>(BitIterator))
|
||||
explicit TBaseIterator(ArrayType& InArray, const BitArrayItType& InBitArrayIt)
|
||||
: Array(InArray)
|
||||
, BitArrayIt(InBitArrayIt)
|
||||
{
|
||||
}
|
||||
|
||||
FORCEINLINE explicit operator bool() const
|
||||
{
|
||||
return (bool)BitArrayIt;
|
||||
}
|
||||
FORCEINLINE TSparseArray<ArrayType>::FBaseIterator& operator++()
|
||||
FORCEINLINE TBaseIterator& operator++()
|
||||
{
|
||||
// Iterate to the next set allocation flag.
|
||||
++BitArrayIt;
|
||||
return *this;
|
||||
}
|
||||
FORCEINLINE ArrayType& operator*()
|
||||
|
||||
FORCEINLINE int32 GetIndex() const { return BitArrayIt.GetIndex(); }
|
||||
|
||||
FORCEINLINE friend bool operator==(const TBaseIterator& Lhs, const TBaseIterator& Rhs) { return Lhs.BitArrayIt == Rhs.BitArrayIt && &Lhs.Array == &Rhs.Array; }
|
||||
FORCEINLINE friend bool operator!=(const TBaseIterator& Lhs, const TBaseIterator& Rhs) { return Lhs.BitArrayIt != Rhs.BitArrayIt || &Lhs.Array != &Rhs.Array; }
|
||||
|
||||
/** conversion to "bool" returning true if the iterator is valid. */
|
||||
FORCEINLINE explicit operator bool() const
|
||||
{
|
||||
return IteratedArray[BitArrayIt.GetIndex()].ElementData;
|
||||
}
|
||||
FORCEINLINE const ArrayType& operator*() const
|
||||
{
|
||||
return IteratedArray[BitArrayIt.GetIndex()].ElementData;
|
||||
}
|
||||
FORCEINLINE ArrayType* operator->()
|
||||
{
|
||||
return &IteratedArray[BitArrayIt.GetIndex()].ElementData;
|
||||
}
|
||||
FORCEINLINE const ArrayType* operator->() const
|
||||
{
|
||||
return &IteratedArray[BitArrayIt.GetIndex()].ElementData;
|
||||
}
|
||||
FORCEINLINE bool operator==(const TSparseArray<ArrayType>::FBaseIterator& Other) const
|
||||
{
|
||||
return BitArrayIt == Other.BitArrayIt;
|
||||
}
|
||||
FORCEINLINE bool operator!=(const TSparseArray<ArrayType>::FBaseIterator& Other) const
|
||||
{
|
||||
return BitArrayIt != Other.BitArrayIt;
|
||||
return !!BitArrayIt;
|
||||
}
|
||||
|
||||
FORCEINLINE int32 GetIndex() const
|
||||
/** inverse of the "bool" operator */
|
||||
FORCEINLINE bool operator !() const
|
||||
{
|
||||
return BitArrayIt.GetIndex();
|
||||
}
|
||||
FORCEINLINE bool IsElementValid() const
|
||||
{
|
||||
return *BitArrayIt;
|
||||
return !(bool)*this;
|
||||
}
|
||||
|
||||
FORCEINLINE ItElementType& operator*() const { return Array[GetIndex()]; }
|
||||
FORCEINLINE ItElementType* operator->() const { return &Array[GetIndex()]; }
|
||||
FORCEINLINE const FRelativeBitReference& GetRelativeBitReference() const { return BitArrayIt; }
|
||||
|
||||
protected:
|
||||
ArrayType& Array;
|
||||
BitArrayItType BitArrayIt;
|
||||
};
|
||||
|
||||
public:
|
||||
FORCEINLINE TSparseArray<ArrayType>::FBaseIterator begin()
|
||||
|
||||
/** Iterates over all allocated elements in a sparse array. */
|
||||
class TIterator : public TBaseIterator<false>
|
||||
{
|
||||
return TSparseArray<ArrayType>::FBaseIterator(*this, TBitArray::FSetBitIterator(AllocationFlags, 0));
|
||||
public:
|
||||
TIterator(TSparseArray& InArray)
|
||||
: TBaseIterator<false>(InArray, TConstSetBitIterator<typename Allocator::BitArrayAllocator>(InArray.AllocationFlags))
|
||||
{
|
||||
}
|
||||
|
||||
TIterator(TSparseArray& InArray, const typename TBaseIterator<false>::BitArrayItType& InBitArrayIt)
|
||||
: TBaseIterator<false>(InArray, InBitArrayIt)
|
||||
{
|
||||
}
|
||||
|
||||
/** Safely removes the current element from the array. */
|
||||
/*
|
||||
void RemoveCurrent()
|
||||
{
|
||||
this->Array.RemoveAt(this->GetIndex());
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
/** Iterates over all allocated elements in a const sparse array. */
|
||||
class TConstIterator : public TBaseIterator<true>
|
||||
{
|
||||
public:
|
||||
TConstIterator(const TSparseArray& InArray)
|
||||
: TBaseIterator<true>(InArray, TConstSetBitIterator<typename Allocator::BitArrayAllocator>(InArray.AllocationFlags))
|
||||
{
|
||||
}
|
||||
|
||||
TConstIterator(const TSparseArray& InArray, const typename TBaseIterator<true>::BitArrayItType& InBitArrayIt)
|
||||
: TBaseIterator<true>(InArray, InBitArrayIt)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#if TSPARSEARRAY_RANGED_FOR_CHECKS // T(R) Milxnor: Check this
|
||||
class TRangedForIterator : public TIterator
|
||||
{
|
||||
public:
|
||||
TRangedForIterator(TSparseArray& InArray, const typename TBaseIterator<false>::BitArrayItType& InBitArrayIt)
|
||||
: TIterator(InArray, InBitArrayIt)
|
||||
, InitialNum(InArray.Num())
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
int32 InitialNum;
|
||||
|
||||
friend FORCEINLINE bool operator!=(const TRangedForIterator& Lhs, const TRangedForIterator& Rhs)
|
||||
{
|
||||
// We only need to do the check in this operator, because no other operator will be
|
||||
// called until after this one returns.
|
||||
//
|
||||
// Also, we should only need to check one side of this comparison - if the other iterator isn't
|
||||
// even from the same array then the compiler has generated bad code.
|
||||
ensureMsgf(Lhs.Array.Num() == Lhs.InitialNum, TEXT("Container has changed during ranged-for iteration!"));
|
||||
return *(TIterator*)&Lhs != *(TIterator*)&Rhs;
|
||||
}
|
||||
};
|
||||
|
||||
class TRangedForConstIterator : public TConstIterator
|
||||
{
|
||||
public:
|
||||
TRangedForConstIterator(const TSparseArray& InArray, const typename TBaseIterator<true>::BitArrayItType& InBitArrayIt)
|
||||
: TConstIterator(InArray, InBitArrayIt)
|
||||
, InitialNum(InArray.Num())
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
int32 InitialNum;
|
||||
|
||||
friend FORCEINLINE bool operator!=(const TRangedForConstIterator& Lhs, const TRangedForConstIterator& Rhs)
|
||||
{
|
||||
// We only need to do the check in this operator, because no other operator will be
|
||||
// called until after this one returns.
|
||||
//
|
||||
// Also, we should only need to check one side of this comparison - if the other iterator isn't
|
||||
// even from the same array then the compiler has generated bad code.
|
||||
ensureMsgf(Lhs.Array.Num() == Lhs.InitialNum, TEXT("Container has changed during ranged-for iteration!"));
|
||||
return *(TIterator*)&Lhs != *(TIterator*)&Rhs;
|
||||
}
|
||||
};
|
||||
#else
|
||||
using TRangedForIterator = TIterator;
|
||||
using TRangedForConstIterator = TConstIterator;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
ElementType& operator[](int32 Index)
|
||||
{
|
||||
// checkSlow(Index >= 0 && Index < Data.Num() && Index < AllocationFlags.Num());
|
||||
//checkSlow(AllocationFlags[Index]); // Disabled to improve loading times -BZ
|
||||
return *(ElementType*)&GetData(Index).ElementData;
|
||||
}
|
||||
FORCEINLINE const TSparseArray<ArrayType>::FBaseIterator begin() const
|
||||
const ElementType& operator[](int32 Index) const
|
||||
{
|
||||
return TSparseArray<ArrayType>::FBaseIterator(*this, TBitArray::FSetBitIterator(AllocationFlags, 0));
|
||||
}
|
||||
FORCEINLINE TSparseArray<ArrayType>::FBaseIterator end()
|
||||
{
|
||||
return TSparseArray<ArrayType>::FBaseIterator(*this, TBitArray::FSetBitIterator(AllocationFlags));
|
||||
}
|
||||
FORCEINLINE const TSparseArray<ArrayType>::FBaseIterator end() const
|
||||
{
|
||||
return TSparseArray<ArrayType>::FBaseIterator(*this, TBitArray::FSetBitIterator(AllocationFlags));
|
||||
// checkSlow(Index >= 0 && Index < Data.Num() && Index < AllocationFlags.Num());
|
||||
//checkSlow(AllocationFlags[Index]); // Disabled to improve loading times -BZ
|
||||
return *(ElementType*)&GetData(Index).ElementData;
|
||||
}
|
||||
|
||||
FORCEINLINE FSparseArrayElement& operator[](uint32 Index)
|
||||
FElementOrFreeListLink& GetData(int32 Index)
|
||||
{
|
||||
return *(FSparseArrayElement*)&Data.at(Index).ElementData;
|
||||
}
|
||||
FORCEINLINE const FSparseArrayElement& operator[](uint32 Index) const
|
||||
{
|
||||
return *(const FSparseArrayElement*)&Data.at(Index).ElementData;
|
||||
}
|
||||
FORCEINLINE int32 GetNumFreeIndices() const
|
||||
{
|
||||
return NumFreeIndices;
|
||||
}
|
||||
FORCEINLINE int32 GetFirstFreeIndex() const
|
||||
{
|
||||
return FirstFreeIndex;
|
||||
}
|
||||
FORCEINLINE const TArray<FSparseArrayElement>& GetData() const
|
||||
{
|
||||
return Data;
|
||||
}
|
||||
FSparseArrayElement& GetData(int32 Index)
|
||||
{
|
||||
return *(FSparseArrayElement*)&Data.at(Index).ElementData;
|
||||
// return ((FSparseArrayElement*)Data.Data)[Index];
|
||||
return ((FElementOrFreeListLink*)Data.GetData())[Index];
|
||||
}
|
||||
|
||||
/** Accessor for the element or free list data. */
|
||||
const FSparseArrayElement& GetData(int32 Index) const
|
||||
const FElementOrFreeListLink& GetData(int32 Index) const
|
||||
{
|
||||
return *(const FSparseArrayElement*)&Data.at(Index).ElementData;
|
||||
// return ((FSparseArrayElement*)Data.Data)[Index];
|
||||
}
|
||||
FORCEINLINE const TBitArray& GetAllocationFlags() const
|
||||
{
|
||||
return AllocationFlags;
|
||||
}
|
||||
FORCEINLINE bool IsIndexValid(int32 IndexToCheck) const
|
||||
{
|
||||
return AllocationFlags.IsSet(IndexToCheck);
|
||||
return ((FElementOrFreeListLink*)Data.GetData())[Index];
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
} */
|
||||
FORCEINLINE friend TRangedForIterator begin(TSparseArray& Array) { return TRangedForIterator(Array, TConstSetBitIterator<typename Allocator::BitArrayAllocator>(Array.AllocationFlags)); }
|
||||
FORCEINLINE friend TRangedForConstIterator begin(const TSparseArray& Array) { return TRangedForConstIterator(Array, TConstSetBitIterator<typename Allocator::BitArrayAllocator>(Array.AllocationFlags)); }
|
||||
FORCEINLINE friend TRangedForIterator end(TSparseArray& Array) { return TRangedForIterator(Array, TConstSetBitIterator<typename Allocator::BitArrayAllocator>(Array.AllocationFlags, Array.AllocationFlags.Num())); }
|
||||
FORCEINLINE friend TRangedForConstIterator end(const TSparseArray& Array) { return TRangedForConstIterator(Array, TConstSetBitIterator<typename Allocator::BitArrayAllocator>(Array.AllocationFlags, Array.AllocationFlags.Num())); }
|
||||
|
||||
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.Set(Index, false);
|
||||
// AllocationFlags[Index] = false;
|
||||
|
||||
++Index;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
FORCEINLINE bool RemoveAt(const int32 IndexToRemove)
|
||||
{
|
||||
LOG_INFO(LogDev, "IndexToRemove: {}", IndexToRemove);
|
||||
LOG_INFO(LogDev, "AllocationFlags.IsSet(IndexToRemove): {}", AllocationFlags.IsSet(IndexToRemove));
|
||||
LOG_INFO(LogDev, "Data.Num(): {}", Data.Num());
|
||||
|
||||
if (IndexToRemove >= 0 && IndexToRemove < Data.Num() && AllocationFlags.IsSet(IndexToRemove))
|
||||
{
|
||||
int32 PreviousFreeIndex = -1;
|
||||
int32 NextFreeIndex = -1;
|
||||
|
||||
LOG_INFO(LogDev, "NumFreeIndices: {}", NumFreeIndices);
|
||||
|
||||
if (NumFreeIndices == 0)
|
||||
{
|
||||
FirstFreeIndex = IndexToRemove;
|
||||
Data.at(IndexToRemove) = { -1, -1 };
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto It = AllocationFlags.begin(); It != AllocationFlags.end(); ++It)
|
||||
{
|
||||
if (!It)
|
||||
{
|
||||
if (It.GetIndex() < IndexToRemove)
|
||||
{
|
||||
Data.at(IndexToRemove).PrevFreeIndex = It.GetIndex();
|
||||
}
|
||||
else if (It.GetIndex() > IndexToRemove)
|
||||
{
|
||||
Data.at(IndexToRemove).NextFreeIndex = It.GetIndex();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AllocationFlags.Set(IndexToRemove, false);
|
||||
NumFreeIndices++;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
};
|
||||
@@ -16,7 +16,7 @@ struct FTimerUnifiedDelegate
|
||||
TFunction<void(void)> FuncCallback;
|
||||
|
||||
FTimerUnifiedDelegate() {};
|
||||
FTimerUnifiedDelegate(FTimerDelegate const& D) : FuncDelegate(D) {};
|
||||
// FTimerUnifiedDelegate(FTimerDelegate const& D) : FuncDelegate(D) {}; // T(R)
|
||||
};
|
||||
|
||||
class FTimerManager // : public FNoncopyable
|
||||
@@ -27,6 +27,6 @@ public:
|
||||
static void (*InternalSetTimerOriginal)(__int64 TimerManager, FTimerHandle& InOutHandle, FTimerUnifiedDelegate&& InDelegate, float InRate, bool InbLoop, float InFirstDelay) =
|
||||
decltype(InternalSetTimerOriginal)(Addresses::SetTimer);
|
||||
|
||||
InternalSetTimerOriginal(__int64(this), InOutHandle, FTimerUnifiedDelegate(InDelegate), InRate, InbLoop, InFirstDelay);
|
||||
// InternalSetTimerOriginal(__int64(this), InOutHandle, FTimerUnifiedDelegate(InDelegate), InRate, InbLoop, InFirstDelay); // T(R)
|
||||
}
|
||||
};
|
||||
@@ -16,6 +16,93 @@ struct FMath : public FGenericPlatformMath
|
||||
return A * A;
|
||||
}
|
||||
|
||||
static float SRand() // T(REP)
|
||||
{
|
||||
return rand();
|
||||
}
|
||||
|
||||
static FORCEINLINE uint32 FloorLog2(uint32 Value)
|
||||
{
|
||||
/* // reference implementation
|
||||
// 1500ms on test data
|
||||
uint32 Bit = 32;
|
||||
for (; Bit > 0;)
|
||||
{
|
||||
Bit--;
|
||||
if (Value & (1<<Bit))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Bit;
|
||||
*/
|
||||
// same output as reference
|
||||
|
||||
// see http://codinggorilla.domemtech.com/?p=81 or http://en.wikipedia.org/wiki/Binary_logarithm but modified to return 0 for a input value of 0
|
||||
// 686ms on test data
|
||||
uint32 pos = 0;
|
||||
if (Value >= 1 << 16) { Value >>= 16; pos += 16; }
|
||||
if (Value >= 1 << 8) { Value >>= 8; pos += 8; }
|
||||
if (Value >= 1 << 4) { Value >>= 4; pos += 4; }
|
||||
if (Value >= 1 << 2) { Value >>= 2; pos += 2; }
|
||||
if (Value >= 1 << 1) { pos += 1; }
|
||||
return (Value == 0) ? 0 : pos;
|
||||
|
||||
// even faster would be method3 but it can introduce more cache misses and it would need to store the table somewhere
|
||||
// 304ms in test data
|
||||
/*int LogTable256[256];
|
||||
|
||||
void prep()
|
||||
{
|
||||
LogTable256[0] = LogTable256[1] = 0;
|
||||
for (int i = 2; i < 256; i++)
|
||||
{
|
||||
LogTable256[i] = 1 + LogTable256[i / 2];
|
||||
}
|
||||
LogTable256[0] = -1; // if you want log(0) to return -1
|
||||
}
|
||||
|
||||
int _forceinline method3(uint32 v)
|
||||
{
|
||||
int r; // r will be lg(v)
|
||||
uint32 tt; // temporaries
|
||||
|
||||
if ((tt = v >> 24) != 0)
|
||||
{
|
||||
r = (24 + LogTable256[tt]);
|
||||
}
|
||||
else if ((tt = v >> 16) != 0)
|
||||
{
|
||||
r = (16 + LogTable256[tt]);
|
||||
}
|
||||
else if ((tt = v >> 8 ) != 0)
|
||||
{
|
||||
r = (8 + LogTable256[tt]);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = LogTable256[v];
|
||||
}
|
||||
return r;
|
||||
}*/
|
||||
}
|
||||
|
||||
static FORCEINLINE uint32 CountLeadingZeros(uint32 Value)
|
||||
{
|
||||
if (Value == 0) return 32;
|
||||
return 31 - FloorLog2(Value);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static constexpr FORCEINLINE T DivideAndRoundUp(T Dividend, T Divisor)
|
||||
{
|
||||
return (Dividend + Divisor - 1) / Divisor;
|
||||
}
|
||||
|
||||
static FORCEINLINE int32 Rand() { return rand(); }
|
||||
|
||||
static FORCEINLINE float FRand() { return Rand() / (float)RAND_MAX; }
|
||||
|
||||
#define FASTASIN_HALF_PI (1.5707963050f)
|
||||
/**
|
||||
* Computes the ASin of a scalar value.
|
||||
|
||||
@@ -26,6 +26,14 @@ struct TCallTraitsParamTypeHelper<T*, true>
|
||||
typedef const T* ConstParamType;
|
||||
};
|
||||
|
||||
template<typename T> struct TContainerTraitsBase
|
||||
{
|
||||
// This should be overridden by every container that supports emptying its contents via a move operation.
|
||||
enum { MoveWillEmptyContainer = false };
|
||||
};
|
||||
|
||||
template<typename T> struct TContainerTraits : public TContainerTraitsBase<T> {};
|
||||
|
||||
template <typename T>
|
||||
struct TCallTraitsBase
|
||||
{
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
|
||||
#include "inc.h"
|
||||
|
||||
enum EForceInit
|
||||
{
|
||||
ForceInit,
|
||||
ForceInitToZero
|
||||
};
|
||||
|
||||
struct FVector
|
||||
{
|
||||
public:
|
||||
@@ -62,4 +68,10 @@ public:
|
||||
{
|
||||
*this = *this - A;
|
||||
}
|
||||
|
||||
explicit FORCEINLINE FVector(EForceInit)
|
||||
: X(0.0f), Y(0.0f), Z(0.0f)
|
||||
{
|
||||
// DiagnosticCheckNaN();
|
||||
}
|
||||
};
|
||||
@@ -13,6 +13,19 @@ public:
|
||||
return ChunkedObjects ? ChunkedObjects->GetObjectByIndex(ObjectIndex) : UnchunkedObjects ? UnchunkedObjects->GetObjectByIndex(ObjectIndex) : nullptr;
|
||||
}
|
||||
|
||||
FORCEINLINE bool operator==(const FWeakObjectPtr& Other) const
|
||||
{
|
||||
return
|
||||
(ObjectIndex == Other.ObjectIndex && ObjectSerialNumber == Other.ObjectSerialNumber)
|
||||
// || (!IsValid() && !Other.IsValid())
|
||||
;
|
||||
}
|
||||
|
||||
friend uint32 GetTypeHash(const FWeakObjectPtr& WeakObjectPtr)
|
||||
{
|
||||
return uint32(WeakObjectPtr.ObjectIndex ^ WeakObjectPtr.ObjectSerialNumber);
|
||||
}
|
||||
|
||||
bool operator==(const FWeakObjectPtr& other)
|
||||
{
|
||||
return ObjectIndex == other.ObjectIndex && ObjectSerialNumber == other.ObjectSerialNumber;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "WeakObjectPtr.h"
|
||||
#include "Object.h"
|
||||
#include "PointerIsConvertibleFromTo.h"
|
||||
|
||||
template<class T = UObject, class TWeakObjectPtrBase = FWeakObjectPtr>
|
||||
struct TWeakObjectPtr;
|
||||
@@ -14,8 +15,48 @@ struct TWeakObjectPtr : public TWeakObjectPtrBase
|
||||
return (T*)TWeakObjectPtrBase::Get();
|
||||
}
|
||||
|
||||
/*
|
||||
bool operator==(const TWeakObjectPtr& other)
|
||||
{
|
||||
return TWeakObjectPtrBase::operator==(other);
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
TWeakObjectPtr() {}
|
||||
};
|
||||
|
||||
template <typename LhsT, typename RhsT, typename OtherTWeakObjectPtrBase>
|
||||
FORCENOINLINE bool operator==(const TWeakObjectPtr<LhsT, OtherTWeakObjectPtrBase>& Lhs, const RhsT* Rhs)
|
||||
{
|
||||
// It's also possible that these static_asserts may fail for valid conversions because
|
||||
// one or both of the types have only been forward-declared.
|
||||
static_assert(TPointerIsConvertibleFromTo<RhsT, UObject>::Value, "TWeakObjectPtr can only be compared with UObject types");
|
||||
static_assert(TPointerIsConvertibleFromTo<LhsT, RhsT>::Value || TPointerIsConvertibleFromTo<RhsT, LhsT>::Value, "Unable to compare TWeakObjectPtr with raw pointer - types are incompatible");
|
||||
|
||||
// NOTE: this constructs a TWeakObjectPtrBase, which has some amount of overhead, so this may not be an efficient operation
|
||||
return (const OtherTWeakObjectPtrBase&)Lhs == OtherTWeakObjectPtrBase(Rhs);
|
||||
}
|
||||
|
||||
template <typename LhsT, typename RhsT, typename OtherTWeakObjectPtrBase>
|
||||
FORCENOINLINE bool operator==(const LhsT* Lhs, const TWeakObjectPtr<RhsT, OtherTWeakObjectPtrBase>& Rhs)
|
||||
{
|
||||
// It's also possible that these static_asserts may fail for valid conversions because
|
||||
// one or both of the types have only been forward-declared.
|
||||
static_assert(TPointerIsConvertibleFromTo<LhsT, UObject>::Value, "TWeakObjectPtr can only be compared with UObject types");
|
||||
static_assert(TPointerIsConvertibleFromTo<LhsT, RhsT>::Value || TPointerIsConvertibleFromTo<RhsT, LhsT>::Value, "Unable to compare TWeakObjectPtr with raw pointer - types are incompatible");
|
||||
|
||||
// NOTE: this constructs a TWeakObjectPtrBase, which has some amount of overhead, so this may not be an efficient operation
|
||||
return OtherTWeakObjectPtrBase(Lhs) == (const OtherTWeakObjectPtrBase&)Rhs;
|
||||
}
|
||||
|
||||
template <typename LhsT, typename OtherTWeakObjectPtrBase>
|
||||
FORCENOINLINE bool operator==(const TWeakObjectPtr<LhsT, OtherTWeakObjectPtrBase>& Lhs, TYPE_OF_NULLPTR)
|
||||
{
|
||||
return !Lhs.IsValid();
|
||||
}
|
||||
|
||||
template <typename RhsT, typename OtherTWeakObjectPtrBase>
|
||||
FORCENOINLINE bool operator==(TYPE_OF_NULLPTR, const TWeakObjectPtr<RhsT, OtherTWeakObjectPtrBase>& Rhs)
|
||||
{
|
||||
return !Rhs.IsValid();
|
||||
}
|
||||
@@ -6,17 +6,14 @@
|
||||
#include "Rotator.h"
|
||||
#include "Actor.h"
|
||||
#include "GameInstance.h"
|
||||
#include "WorldSettings.h"
|
||||
#include "GameplayStatics.h"
|
||||
|
||||
struct FNetworkNotify
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
class AWorldSettings : public AActor
|
||||
{
|
||||
public:
|
||||
};
|
||||
|
||||
struct FActorSpawnParameters
|
||||
{
|
||||
FName Name = FName(0);
|
||||
@@ -228,6 +225,11 @@ public:
|
||||
return this->Get<class UNetDriver*>(NetDriverOffset);
|
||||
}
|
||||
|
||||
float GetTimeSeconds() // T(REP)
|
||||
{
|
||||
return UGameplayStatics::GetTimeSeconds(this);
|
||||
}
|
||||
|
||||
UGameInstance* GetOwningGameInstance()
|
||||
{
|
||||
static auto OwningGameInstanceOffset = GetOffset("OwningGameInstance");
|
||||
|
||||
35
Project Reboot 3.0/WorldSettings.h
Normal file
35
Project Reboot 3.0/WorldSettings.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include "Actor.h"
|
||||
#include "NetConnection.h"
|
||||
#include "Array.h"
|
||||
|
||||
struct FNetViewer
|
||||
{
|
||||
UNetConnection* Connection;
|
||||
AActor* InViewer;
|
||||
AActor* ViewTarget;
|
||||
FVector ViewLocation;
|
||||
FVector ViewDir;
|
||||
|
||||
FNetViewer()
|
||||
: Connection(NULL)
|
||||
, InViewer(NULL)
|
||||
, ViewTarget(NULL)
|
||||
, ViewLocation(ForceInit)
|
||||
, ViewDir(ForceInit)
|
||||
{
|
||||
}
|
||||
|
||||
FNetViewer(UNetConnection* InConnection, float DeltaSeconds);
|
||||
};
|
||||
|
||||
class AWorldSettings : public AActor
|
||||
{
|
||||
public:
|
||||
TArray<struct FNetViewer>& GetReplicationViewers()
|
||||
{
|
||||
static auto ReplicationViewersOffset = GetOffset("ReplicationViewers");
|
||||
return Get<TArray<struct FNetViewer>>(ReplicationViewersOffset);
|
||||
}
|
||||
};
|
||||
@@ -553,6 +553,12 @@ void Addresses::Init()
|
||||
NavSystemCleanUpOriginal = decltype(NavSystemCleanUpOriginal)(Addresses::NavSystemCleanUp);
|
||||
LoadPlaysetOriginal = decltype(LoadPlaysetOriginal)(Addresses::LoadPlayset);
|
||||
AFortGameModeAthena::SetZoneToIndexOriginal = decltype(AFortGameModeAthena::SetZoneToIndexOriginal)(Addresses::SetZoneToIndex);
|
||||
AActor::originalCallPreReplication = decltype(AActor::originalCallPreReplication)(Addresses::CallPreReplication);
|
||||
APlayerController::originalSendClientAdjustment = decltype(APlayerController::originalSendClientAdjustment)(Addresses::SendClientAdjustment);
|
||||
UActorChannel::originalReplicateActor = decltype(UActorChannel::originalReplicateActor)(Addresses::ReplicateActor);
|
||||
UActorChannel::originalSetChannelActor = decltype(UActorChannel::originalSetChannelActor)(Addresses::SetChannelActor);
|
||||
UNetConnection::originalCreateChannel = decltype(UNetConnection::originalCreateChannel)(Addresses::CreateChannel);
|
||||
UNetConnection::originalCreateChannelByName = decltype(UNetConnection::originalCreateChannelByName)(Addresses::CreateChannel);
|
||||
|
||||
if (Engine_Version >= 421) ChunkedObjects = decltype(ChunkedObjects)(ObjectArray);
|
||||
else UnchunkedObjects = decltype(UnchunkedObjects)(ObjectArray);
|
||||
|
||||
@@ -110,11 +110,29 @@ static inline AFortAthenaMutator_Bots* SpawnBotMutator() //sets up all the class
|
||||
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
||||
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
|
||||
|
||||
auto MutatorBotsClass = FindObject<UClass>("/Script/FortniteGame.FortAthenaMutator_Bots");
|
||||
|
||||
if (!MutatorBotsClass)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static auto BGAClass = FindObject<UClass>(L"/Script/Engine.BlueprintGeneratedClass");
|
||||
static auto PhoebeMutatorClass = LoadObject<UClass>(L"/Game/Athena/AI/Phoebe/BP_Phoebe_Mutator.BP_Phoebe_Mutator_C", BGAClass);
|
||||
|
||||
if (!PhoebeMutatorClass)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto BotMutator = GetWorld()->SpawnActor<AFortAthenaMutator_Bots>(PhoebeMutatorClass);
|
||||
|
||||
if (!BotMutator)
|
||||
{
|
||||
LOG_WARN(LogAI, "Failed to spawn Bot Mutator!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static auto CachedGameModeOffset = BotMutator->GetOffset("CachedGameMode");
|
||||
BotMutator->Get(CachedGameModeOffset) = GameMode;
|
||||
|
||||
|
||||
@@ -5,6 +5,16 @@
|
||||
#include <format>
|
||||
#include <string>
|
||||
|
||||
/*
|
||||
|
||||
T(REP): Todo replication
|
||||
T(R): Todo random (every commented check, checkslow is automatically this)
|
||||
T(1-5): 1, being most important, 5 being least important to fix.
|
||||
|
||||
*/
|
||||
|
||||
decltype(nullptr) typedef TYPE_OF_NULLPTR;
|
||||
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned char uint8;
|
||||
typedef char int8;
|
||||
@@ -25,6 +35,8 @@ extern inline int Fortnite_CL = 0;
|
||||
|
||||
// #define ABOVE_S20
|
||||
|
||||
#define INDEX_NONE -1
|
||||
|
||||
struct PlaceholderBitfield
|
||||
{
|
||||
uint8_t First : 1;
|
||||
@@ -62,6 +74,15 @@ inline bool IsRestartingSupported()
|
||||
return Engine_Version >= 419 && Engine_Version < 424;
|
||||
}
|
||||
|
||||
enum ENetRole
|
||||
{
|
||||
ROLE_None,
|
||||
ROLE_SimulatedProxy,
|
||||
ROLE_AutonomousProxy,
|
||||
ROLE_Authority,
|
||||
ROLE_MAX,
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
enum class AllocatorType
|
||||
|
||||
@@ -80,15 +80,17 @@ static inline UEngine* GetEngine()
|
||||
return Engine;
|
||||
}
|
||||
|
||||
static inline class UWorld* GetWorld()
|
||||
{
|
||||
static UObject* Engine = GetEngine();
|
||||
static auto GameViewportOffset = Engine->GetOffset("GameViewport");
|
||||
auto GameViewport = Engine->Get<UObject*>(GameViewportOffset);
|
||||
namespace {
|
||||
static inline class UWorld* GetWorld()
|
||||
{
|
||||
static UObject* Engine = GetEngine();
|
||||
static auto GameViewportOffset = Engine->GetOffset("GameViewport");
|
||||
auto GameViewport = Engine->Get<UObject*>(GameViewportOffset);
|
||||
|
||||
static auto WorldOffset = GameViewport->GetOffset("World");
|
||||
static auto WorldOffset = GameViewport->GetOffset("World");
|
||||
|
||||
return GameViewport->Get<class UWorld*>(WorldOffset);
|
||||
return GameViewport->Get<class UWorld*>(WorldOffset);
|
||||
}
|
||||
}
|
||||
|
||||
static TArray<UObject*>& GetLocalPlayers()
|
||||
@@ -406,7 +408,8 @@ namespace MemberOffsets
|
||||
}
|
||||
}
|
||||
|
||||
static inline float GetMaxTickRateHook() { return 30.f; }
|
||||
inline float ServerTickRate = 30.f;
|
||||
static inline float GetMaxTickRateHook() { return ServerTickRate; }
|
||||
|
||||
#define VALIDATEOFFSET(offset) if (!offset) LOG_WARN(LogDev, "[{}] Invalid offset", __FUNCTIONNAME__);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user