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