mirror of
https://github.com/mordentral/AdvancedSessionsPlugin.git
synced 2025-10-22 16:04:18 +00:00
Merge
This commit is contained in:
@@ -1,233 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "OnlineSubSystemHeader.h"
|
|
||||||
#include "NetworkPackageLibrary.generated.h"
|
|
||||||
|
|
||||||
|
|
||||||
//General Advanced Sessions Log
|
|
||||||
DECLARE_LOG_CATEGORY_EXTERN(NetworkPackageLibraryLog, Log, All);
|
|
||||||
|
|
||||||
// A struct to contain information about a chunk send over network
|
|
||||||
USTRUCT()
|
|
||||||
struct FNetworkPackage
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
public:
|
|
||||||
UPROPERTY()
|
|
||||||
uint8 ThisPackageNumber;
|
|
||||||
UPROPERTY()
|
|
||||||
uint8 TotalExpectedPackages;
|
|
||||||
UPROPERTY()
|
|
||||||
TArray<uint64> ChunkData;
|
|
||||||
UPROPERTY()
|
|
||||||
uint32 PackageID;
|
|
||||||
UPROPERTY()
|
|
||||||
uint32 StartLocation;
|
|
||||||
UPROPERTY()
|
|
||||||
uint32 PackageSize;
|
|
||||||
UPROPERTY()
|
|
||||||
uint32 TotalDataSize;
|
|
||||||
UPROPERTY()
|
|
||||||
uint8 PackageType;
|
|
||||||
|
|
||||||
FNetworkPackage()
|
|
||||||
{
|
|
||||||
ThisPackageNumber = 0;
|
|
||||||
TotalExpectedPackages = 0;
|
|
||||||
PackageID = 0;
|
|
||||||
PackageType = 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
USTRUCT()
|
|
||||||
struct FNetworkPackageBin
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
public:
|
|
||||||
TArray<uint8> RemainingPackageNumbers;
|
|
||||||
//TArray<FNetworkPackage> ChunkDataBin;
|
|
||||||
uint8 TotalExpectedPackages;
|
|
||||||
TArray<uint8> ChunkData;
|
|
||||||
int32 PackageID;
|
|
||||||
uint8 PackageType;
|
|
||||||
uint32 TotalDataSize;
|
|
||||||
|
|
||||||
bool bFinishedReceiving;
|
|
||||||
|
|
||||||
FNetworkPackageBin()
|
|
||||||
{
|
|
||||||
TotalExpectedPackages = 0;
|
|
||||||
bFinishedReceiving = false;
|
|
||||||
PackageID = 0;
|
|
||||||
TotalDataSize = 0;
|
|
||||||
PackageType = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
FNetworkPackageBin(const FNetworkPackage & Package)
|
|
||||||
{
|
|
||||||
bFinishedReceiving = false;
|
|
||||||
TotalExpectedPackages = 0;
|
|
||||||
InitializeFromPackage(Package);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitializeFromPackage(const FNetworkPackage & Package)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < Package.TotalExpectedPackages; ++i)
|
|
||||||
RemainingPackageNumbers.Add(i + 1);
|
|
||||||
|
|
||||||
ChunkData.AddUninitialized(Package.TotalDataSize);
|
|
||||||
|
|
||||||
FMemory::Memcpy(ChunkData.GetData() + Package.StartLocation, Package.ChunkData.GetData(), Package.PackageSize);
|
|
||||||
|
|
||||||
TotalDataSize = Package.TotalDataSize;
|
|
||||||
PackageType = Package.PackageType;
|
|
||||||
|
|
||||||
TotalExpectedPackages = Package.TotalExpectedPackages;
|
|
||||||
PackageID = Package.PackageID;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns true if this was the last package it was waiting on
|
|
||||||
bool AddPackage(const FNetworkPackage & Package)
|
|
||||||
{
|
|
||||||
if (Package.ThisPackageNumber <= TotalExpectedPackages && RemainingPackageNumbers.Find(Package.ThisPackageNumber) == INDEX_NONE)
|
|
||||||
{
|
|
||||||
RemainingPackageNumbers.Remove(Package.ThisPackageNumber);
|
|
||||||
|
|
||||||
FMemory::Memcpy(ChunkData.GetData() + Package.StartLocation, Package.ChunkData.GetData(), Package.PackageSize);
|
|
||||||
|
|
||||||
if (!RemainingPackageNumbers.Num())
|
|
||||||
{
|
|
||||||
bFinishedReceiving = true;
|
|
||||||
UncompressData();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false; // Already received this package, something is wrong
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UncompressData()
|
|
||||||
{
|
|
||||||
FBufferArchive DecompressedBinaryArray;
|
|
||||||
FArchiveLoadCompressedProxy Decompressor = FArchiveLoadCompressedProxy(ChunkData, ECompressionFlags::COMPRESS_ZLIB);
|
|
||||||
|
|
||||||
if (Decompressor.GetError())
|
|
||||||
{
|
|
||||||
// File was not compressed
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Decompressor << DecompressedBinaryArray;
|
|
||||||
Decompressor.FlushCache();
|
|
||||||
Decompressor.Close();
|
|
||||||
|
|
||||||
ChunkData.Empty();
|
|
||||||
DecompressedBinaryArray << ChunkData;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// An actor component meant to handle sending large data array's across the network
|
|
||||||
UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent))
|
|
||||||
class UNetworkPackageLibraryComponent : public UActorComponent
|
|
||||||
{
|
|
||||||
GENERATED_UCLASS_BODY()
|
|
||||||
~UNetworkPackageLibraryComponent();
|
|
||||||
|
|
||||||
public:
|
|
||||||
#pragma region NETWORKING Networking Region
|
|
||||||
|
|
||||||
// NETWORKING FUNCTIONS
|
|
||||||
//UPROPERTY(Replicated, BlueprintReadOnly)
|
|
||||||
int32 IncrementalPackageID;
|
|
||||||
|
|
||||||
int32 GetPackageID() { return IncrementalPackageID++; }
|
|
||||||
|
|
||||||
TArray<FNetworkPackageBin> NetworkPackageQueue;
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "NetworkPackageLibrary")
|
|
||||||
bool DeleteQueuedDataPackage(int32 NetworkPackageID)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < NetworkPackageQueue.Num(); ++i)
|
|
||||||
{
|
|
||||||
if (NetworkPackageQueue[i].PackageID == NetworkPackageID)
|
|
||||||
{
|
|
||||||
NetworkPackageQueue.RemoveAt(i);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintImplementableEvent, Category = "NetworkPackageLibrary")
|
|
||||||
void BPEventNotifyPackageReady(int32 PackageID, uint8 PackageType);
|
|
||||||
|
|
||||||
UFUNCTION(Server, Reliable, WithValidation)
|
|
||||||
virtual void ReceiveChunkDataPackage(FNetworkPackage Package);
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "NetworkPackageLibrary")
|
|
||||||
virtual void NetworkReplicateChunkData_ToServer(TArray<uint8> ChunkData, uint8 PackageType)
|
|
||||||
{
|
|
||||||
// I can up this to 32 byte structures instead of the 8 bytes structure to get up to 64 KB per packet, right now it is 16kb per packet max with the 64bit size
|
|
||||||
int MAX_ARRAY_SIZE = 2048;
|
|
||||||
|
|
||||||
FNetworkPackage newPackage;
|
|
||||||
newPackage.PackageID = GetPackageID();
|
|
||||||
|
|
||||||
FBufferArchive ToBinary;
|
|
||||||
ToBinary << ChunkData;
|
|
||||||
|
|
||||||
// Compress File
|
|
||||||
TArray<uint8> CompressedData;
|
|
||||||
FArchiveSaveCompressedProxy Compressor = FArchiveSaveCompressedProxy(CompressedData, ECompressionFlags::COMPRESS_ZLIB);
|
|
||||||
|
|
||||||
//Send entire binary array/archive to compressor
|
|
||||||
Compressor << ToBinary;
|
|
||||||
|
|
||||||
//send archive serialized data to binary array
|
|
||||||
Compressor.Flush();
|
|
||||||
Compressor.FlushCache();
|
|
||||||
Compressor.Close();
|
|
||||||
|
|
||||||
uint32 numPackages = FMath::CeilToInt(CompressedData.Num() / MAX_ARRAY_SIZE);
|
|
||||||
if ((CompressedData.Num() % MAX_ARRAY_SIZE) > 0)
|
|
||||||
numPackages++;
|
|
||||||
|
|
||||||
newPackage.TotalDataSize = CompressedData.Num();
|
|
||||||
newPackage.TotalExpectedPackages = numPackages;
|
|
||||||
newPackage.PackageType = PackageType;
|
|
||||||
|
|
||||||
uint32 curLoc = 0;
|
|
||||||
|
|
||||||
for (uint32 i = 0; i < numPackages; ++i)
|
|
||||||
{
|
|
||||||
if (curLoc >= (uint32)CompressedData.Num())
|
|
||||||
return; // End here, no more to send
|
|
||||||
|
|
||||||
FNetworkPackage pack = newPackage;
|
|
||||||
pack.ThisPackageNumber = i;
|
|
||||||
pack.StartLocation = curLoc;
|
|
||||||
|
|
||||||
uint32 thisCount = FMath::Clamp<uint32>((uint32)(newPackage.TotalDataSize - curLoc), 0, MAX_ARRAY_SIZE);
|
|
||||||
pack.ChunkData.AddUninitialized(FMath::CeilToInt(thisCount / sizeof(uint64)));
|
|
||||||
pack.PackageSize = thisCount;
|
|
||||||
FMemory::Memcpy(pack.ChunkData.GetData(), CompressedData.GetData() + curLoc, thisCount);
|
|
||||||
|
|
||||||
// Send it up the pipeline
|
|
||||||
ReceiveChunkDataPackage(pack);
|
|
||||||
//TargetController->ReceiveChunkDataPackage(this, pack);
|
|
||||||
curLoc += MAX_ARRAY_SIZE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// END NETWORKING FUNCTIONS
|
|
||||||
|
|
||||||
#pragma endregion End of networking Region
|
|
||||||
|
|
||||||
};
|
|
@@ -1,44 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
#include "OnlineSubSystemHeader.h"
|
|
||||||
#include "NetworkPackageLibrary.h"
|
|
||||||
|
|
||||||
//General Log
|
|
||||||
DEFINE_LOG_CATEGORY(NetworkPackageLibraryLog);
|
|
||||||
|
|
||||||
UNetworkPackageLibraryComponent::UNetworkPackageLibraryComponent(const FObjectInitializer& ObjectInitializer)
|
|
||||||
: Super(ObjectInitializer)
|
|
||||||
{
|
|
||||||
PrimaryComponentTick.bCanEverTick = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
UNetworkPackageLibraryComponent::~UNetworkPackageLibraryComponent()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UNetworkPackageLibraryComponent::ReceiveChunkDataPackage_Validate(FNetworkPackage Package)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UNetworkPackageLibraryComponent::ReceiveChunkDataPackage_Implementation(FNetworkPackage Package)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < NetworkPackageQueue.Num(); ++i)
|
|
||||||
{
|
|
||||||
if (NetworkPackageQueue[i].PackageID == Package.PackageID)
|
|
||||||
{
|
|
||||||
if (NetworkPackageQueue[i].AddPackage(Package))
|
|
||||||
{
|
|
||||||
if (NetworkPackageQueue[i].bFinishedReceiving)
|
|
||||||
BPEventNotifyPackageReady(i, NetworkPackageQueue[i].PackageType);
|
|
||||||
//else
|
|
||||||
// NOTIFY BAD SEND
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Else need to add a new package
|
|
||||||
FNetworkPackageBin newBin(Package);
|
|
||||||
NetworkPackageQueue.Add(Package);
|
|
||||||
}
|
|
Reference in New Issue
Block a user