新建3d客户端

This commit is contained in:
liuyunhui
2025-09-15 17:17:30 +08:00
parent 1fe5a72ca4
commit fded7b9a51
38 changed files with 5874 additions and 0 deletions
@@ -0,0 +1,36 @@
// Copyright 2017-2020 David Romanski (Socke). All Rights Reserved.
#pragma once
#include "SocketServer.h"
#include "SocketServerBPLibrary.h"
#include "DNSClientSocketServer.generated.h"
UCLASS()
class SOCKETSERVER_API UDNSClientSocketServer : public UObject
{
GENERATED_UCLASS_BODY()
public:
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FresolveDomainEventDelegate, FString, IP);
UFUNCTION()
void resolveDomainEventDelegate(const FString IP);
UPROPERTY(BlueprintAssignable, Category = "SocketServer|Events|ResolveDomain")
FresolveDomainEventDelegate onresolveDomainEventDelegate;
void resolveDomain(ISocketSubsystem * socketSubSystem, FString domain, bool useDNSCache = true, FString dnsIP = FString("8.8.8.8"));
void UDPReceiver(const FArrayReaderPtr& ArrayReaderPtr, const FIPv4Endpoint& EndPt);
FSocket* socket = nullptr;
bool isResloving();
FString getIP();
private:
bool resolving;
FString ip;
FString domain;
TMap<FString, FString> dnsCache;
};
@@ -0,0 +1,24 @@
// Copyright 2018-2020 David Romanski (Socke). All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "EventBean.generated.h"
UCLASS(Blueprintable, BlueprintType)
class UEventBean : public UObject
{
GENERATED_UCLASS_BODY()
public:
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FregisteredEventDelegate, const FString, message, const TArray<uint8>&, byteArray);
UFUNCTION()
void registeredEventDelegate(const FString message, const TArray<uint8>& byteArray);
UPROPERTY(BlueprintAssignable, Category = "SocketServer|Register|Events")
FregisteredEventDelegate onregisteredEventDelegate;
private:
};
@@ -0,0 +1,243 @@
// Copyright 2017-2020 David Romanski (Socke). All Rights Reserved.
#pragma once
#include "SocketServer.h"
#include "SocketServerBPLibrary.h"
#include "FileFunctionsSocketServer.generated.h"
class FReadFileInPartsSocketServerThread;
UCLASS(Blueprintable, BlueprintType)
class SOCKETSERVER_API UFileFunctionsSocketServer : public UObject
{
GENERATED_UCLASS_BODY()
public:
UFUNCTION()
static UFileFunctionsSocketServer* getFileFunctionsSocketServerTarget();
static UFileFunctionsSocketServer* fileFunctionsSocketServer;
static FString getCleanDirectory(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static void writeBytesToFile(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath, TArray<uint8> bytes, bool& success);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static void addBytesToFileAndCloseIt(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath, TArray<uint8> bytes, bool& success);
//UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
// static void splittFile(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath, int32 parts, bool& success);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static TArray<uint8> readBytesFromFile(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath, bool& success);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static void readStringFromFile(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath, bool& success, FString& data);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static void writeStringToFile(EFileFunctionsSocketServerDirectoryType directoryType, FString data, FString filePath, EFileFunctionsSocketServerEncodingOptions fileEncoding, bool& success);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static void getMD5FromFile(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath, bool& success, FString& MD5);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static void getMD5FromFileAbsolutePath(FString filePath, bool& success, FString& MD5);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static void stringToBase64String(FString string, FString& base64String);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static void base64StringToString(FString& string, FString base64String);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static void bytesToBase64String(TArray<uint8> bytes, FString& base64String);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static TArray<uint8> base64StringToBytes(FString base64String, bool& success);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static void fileToBase64String(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath, bool& success, FString& base64String, FString& fileName);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static bool fileExists(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static bool fileExistsAbsolutePath(FString filePath);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static bool directoryExists(EFileFunctionsSocketServerDirectoryType directoryType, FString path);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static int64 fileSize(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static int64 fileSizeAbsolutePath(FString filePath);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static bool deleteFile(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static bool deleteFileAbsolutePath(FString filePath);
/** Delete a directory and return true if the directory was deleted or otherwise does not exist. **/
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static bool deleteDirectory(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath);
/** Return true if the file is read only. **/
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static bool isReadOnly(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath);
/** Attempt to move a file. Return true if successful. Will not overwrite existing files. **/
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static bool moveFile(EFileFunctionsSocketServerDirectoryType directoryTypeTo, FString filePathTo, EFileFunctionsSocketServerDirectoryType directoryTypeFrom, FString filePathFrom);
/** Attempt to change the read only status of a file. Return true if successful. **/
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static bool setReadOnly(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath, bool bNewReadOnlyValue);
/** Return the modification time of a file. Returns FDateTime::MinValue() on failure **/
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static FDateTime getTimeStamp(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath);
/** Sets the modification time of a file **/
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static void setTimeStamp(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath, FDateTime DateTime);
/** Return the last access time of a file. Returns FDateTime::MinValue() on failure **/
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static FDateTime getAccessTimeStamp(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath);
/** For case insensitive filesystems, returns the full path of the file with the same case as in the filesystem */
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static FString getFilenameOnDisk(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath);
/** Create a directory and return true if the directory was created or already existed. **/
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static bool createDirectory(EFileFunctionsSocketServerDirectoryType directoryType, FString path);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static void getAllFilesFromDirectory(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath, int32& count, TArray<FString>& files, TArray<FString>& filePaths, FString fileType = "*.*");
//AES
/**
* Encrypts a string with AES in 256bit and returns the encrypted string as Base64 string.
* @param message The string to be encrypted
* @param keyIn256Bit The key must be a string with 32 characters. Please use ASCII characters only!
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|AES")
static FString encryptMessageWithAES(FString message, FString keyIn256Bit);
/**
* Decrypts a Base64 string that has been encrypted in AES with 256bit and returns the string.
* @param message The string to be decrypted
* @param keyIn256Bit The key must be a string with 32 characters. Please use ASCII characters only!
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|AES")
static FString decryptMessageWithAES(FString encryptedBase64Message, FString keyIn256Bit);
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "SocketServer|SpecialFunctions|String")
static FString int64ToString(int64 num);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static struct FFileFunctionsSocketServerOpenFile openFile(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static int64 addBytesToFile(struct FFileFunctionsSocketServerOpenFile openFile, TArray<uint8>bytes);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static void closeFile(struct FFileFunctionsSocketServerOpenFile openFile);
/**
* With this function you can read a file piece by piece. This reduces the RAM consumption to almost zero and files can be read in infinite size.
*@param bufferSize In bytes. This is the size of the file pieces that are being read.
*@param delayBetweenReadsInSeconds Specified in seconds. The higher the value, the slower the file is read (0.0001 minimum). When sending data over the network/internet, please make sure not to send data too fast. SSDs can read data much faster than you can send it over a network. This means that the data ends up in some buffers (RAM) and can also cause them to overflow.
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File", meta = (AdvancedDisplay = 2))
static void readBytesFromFileInPartsAsync(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath, int32 bufferSize = 65536, float delayBetweenReadsInSeconds = 0.01f);
void readBytesFromFileInPartsAsyncInternal(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath, int32 bufferSize = 65536, float delayBetweenReadsInSeconds = 0.01f);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|File")
static void cancelReadBytesFromFileInParts(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath);
void cancelReadBytesFromFileInPartsInternal(EFileFunctionsSocketServerDirectoryType directoryType, FString filePath);
void cleanReadBytesFromFileInParts(FString cleanDir);
TMap<FString, FReadFileInPartsSocketServerThread*> readFileInPartsThreads;
private:
static TArray<uint8> FStringToByteArray(FString s);
};
/* asynchronous Thread*/
class SOCKETSERVER_API FReadFileInPartsSocketServerThread : public FRunnable {
public:
FReadFileInPartsSocketServerThread(FString cleanDirP, int32 bufferSizeP, float delayBetweenReadsInSecondsP) :
cleanDir(cleanDirP),
bufferSize(bufferSizeP),
delayBetweenReadsInSeconds(delayBetweenReadsInSecondsP)
{
FString threadName = "FReadFileInPartsSocketServerThread" + FGuid::NewGuid().ToString();
thread = FRunnableThread::Create(this, *threadName, 0, EThreadPriority::TPri_Normal);
}
virtual uint32 Run() override {
FArchive* reader = IFileManager::Get().CreateFileReader(*cleanDir);
if (reader == nullptr || reader->TotalSize() == 0) {
AsyncTask(ENamedThreads::GameThread, []() {
USocketServerBPLibrary::getSocketServerTarget()->onreadBytesFromFileInPartsEventDelegate.Broadcast(0, 0, true, TArray<uint8>());
});
if (reader != nullptr) {
reader->Close();
}
delete reader;
return 0;
}
if (delayBetweenReadsInSeconds <= 0) {
delayBetweenReadsInSeconds = 0.0001f;
}
int64 fileSize = reader->TotalSize();
int64 readSize = 0;
int64 lastPosition = 0;
TArray<uint8> buffer;
if (bufferSize > fileSize) {
bufferSize = fileSize;
}
while (run && lastPosition < fileSize) {
if ((lastPosition + bufferSize) > fileSize) {
bufferSize = fileSize - lastPosition;
}
//buffer.Reset(bufferSize);
buffer.Empty();
buffer.AddUninitialized(bufferSize);
reader->Serialize(buffer.GetData(), buffer.Num());
lastPosition += buffer.Num();
//UE_LOG(LogTemp, Warning, TEXT("xxxxx READ: %i"), buffer.Num());
AsyncTask(ENamedThreads::GameThread, [fileSize, lastPosition, buffer]() {
USocketServerBPLibrary::getSocketServerTarget()->onreadBytesFromFileInPartsEventDelegate.Broadcast(fileSize, lastPosition, false, buffer);
});
FPlatformProcess::Sleep(delayBetweenReadsInSeconds);
}
AsyncTask(ENamedThreads::GameThread, [fileSize, lastPosition]() {
USocketServerBPLibrary::getSocketServerTarget()->onreadBytesFromFileInPartsEventDelegate.Broadcast(fileSize, lastPosition, true, TArray<uint8>());
});
UFileFunctionsSocketServer::getFileFunctionsSocketServerTarget()->cleanReadBytesFromFileInParts(cleanDir);
//buffer.Empty();
if (reader != nullptr) {
reader->Close();
}
delete reader;
thread = nullptr;
return 0;
}
void stopThread() {
run = false;
}
void setDelayBetweenReadsInSeconds(float d) {
delayBetweenReadsInSeconds = d;
if (delayBetweenReadsInSeconds <= 0) {
delayBetweenReadsInSeconds = 0.001f;
}
}
protected:
bool run = true;
FString cleanDir;
int32 bufferSize;
float delayBetweenReadsInSeconds;
//USocketServerBPLibrary* mainLib = USocketServerBPLibrary::getSocketServerTarget();
FRunnableThread* thread = nullptr;
};
@@ -0,0 +1,32 @@
// Copyright 2017-2020 David Romanski (Socke). All Rights Reserved.
#pragma once
#include "SocketServer.h"
#include "RCONServer.generated.h"
UCLASS(Blueprintable, BlueprintType)
class SOCKETSERVER_API URCONServer : public UObject
{
GENERATED_UCLASS_BODY()
public:
UFUNCTION()
void receiveTCPMessageEvent(const FString sessionID, const FString message, const TArray<uint8>& byteArray, const FString serverID);
void startRCONServer(FString serverID, ERCONPasswordType passwordType, FString passwordOrFile,
bool& success, FString& errorMessage);
bool sendResponse(FString sessionID, FString serverID, int32 id, int32 type, FString body);
private:
FString passwordOrFile = FString();
ERCONPasswordType passwordType = ERCONPasswordType::E_parameter;
TArray<FString> commandList;
void authResponse(FString sessionID, FString serverID, FString password, int32 rconID);
};
@@ -0,0 +1,267 @@
// Copyright 2017-2022 David Romanski (Socke). All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "EngineGlobals.h"
#include "Engine/Engine.h"
#include "EventBean.h"
#include "Sockets.h"
#include "SocketSubsystem.h"
#include "Interfaces/IPv4/IPv4Endpoint.h"
#include "Common/UdpSocketReceiver.h"
#include "Common/UdpSocketBuilder.h"
#include "Async/Async.h"
#include "Containers/Queue.h"
#include "Misc/DateTime.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "Misc/FileHelper.h"
#include "Misc/Paths.h"
#include "HAL/PlatformFileManager.h"
#include "HAL/FileManager.h"
#include "Misc/Base64.h"
#include "Misc/SecureHash.h"
#include "Misc/AES.h"
#include "Modules/ModuleManager.h"
#include "SocketServer.generated.h"
class FSocketServerTCPClientSendDataThread;
class FSocketServerTCPClientReceiveDataThread;
class FSocketServerTCPFileHandlerThread;
class FUdpSocketReceiver;
class FSocketServerUDPThread;
class FSocketServerUDPClientSendDataThread;
UENUM(BlueprintType)
enum class EFileFunctionsSocketServerEncodingOptions : uint8
{
E_AutoDetect UMETA(DisplayName = "AutoDetect"),
E_ForceAnsi UMETA(DisplayName = "ForceAnsi"),
E_ForceUnicode UMETA(DisplayName = "ForceUnicode"),
E_ForceUTF8 UMETA(DisplayName = "ForceUTF8"),
E_ForceUTF8WithoutBOM UMETA(DisplayName = "ForceUTF8WithoutBOM")
};
UENUM(BlueprintType)
enum class EFileFunctionsSocketServerDirectoryType : uint8
{
E_gd UMETA(DisplayName = "Game directory"),
E_ad UMETA(DisplayName = "Absolute directory")
};
UENUM(BlueprintType)
enum class EServerSocketConnectionEventType : uint8
{
E_Server UMETA(DisplayName = "Server"),
E_Client UMETA(DisplayName = "Client")
};
UENUM(BlueprintType)
enum class EServerSocketConnectionProtocol : uint8
{
E_NotSet UMETA(DisplayName = "NotSet"),
E_TCP UMETA(DisplayName = "TCP"),
E_UDP UMETA(DisplayName = "UDP")
};
UENUM(BlueprintType)
enum class EServerSocketConnectionCheckPortType : uint8
{
E_TCP UMETA(DisplayName = "TCP"),
E_UDP UMETA(DisplayName = "UDP")
};
UENUM(BlueprintType)
enum class EReceiveFilterServer : uint8
{
E_SAB UMETA(DisplayName = "Message And Bytes"),
E_S UMETA(DisplayName = "Message"),
E_B UMETA(DisplayName = "Bytes")
};
UENUM(BlueprintType)
enum class ESocketPlatformServer : uint8
{
E_SSS_SYSTEM UMETA(DisplayName = "System"),
E_SSS_DEFAULT UMETA(DisplayName = "Auto"),
E_SSS_WINDOWS UMETA(DisplayName = "WINDOWS"),
E_SSS_MAC UMETA(DisplayName = "MAC"),
E_SSS_IOS UMETA(DisplayName = "IOS"),
E_SSS_UNIX UMETA(DisplayName = "UNIX"),
E_SSS_ANDROID UMETA(DisplayName = "ANDROID"),
E_SSS_PS4 UMETA(DisplayName = "PS4"),
E_SSS_XBOXONE UMETA(DisplayName = "XBOXONE"),
E_SSS_HTML5 UMETA(DisplayName = "HTML5"),
E_SSS_SWITCH UMETA(DisplayName = "SWITCH")
};
UENUM(BlueprintType)
enum class ESocketServerUDPSocketType : uint8
{
E_SSS_SERVER UMETA(DisplayName = "Use Server Socket"),
E_SSS_CLIENT UMETA(DisplayName = "Use Client Socket")
};
UENUM(BlueprintType)
enum class ESocketServerTCPSeparator : uint8
{
E_None UMETA(DisplayName = "None"),
E_ByteSeparator UMETA(DisplayName = "Separate via one Byte"),
E_StringSeparator UMETA(DisplayName = "Separate via String"),
E_LengthSeparator UMETA(DisplayName = "Separate by Length")
};
UENUM(BlueprintType)
enum class ERCONPasswordType : uint8
{
E_parameter UMETA(DisplayName = "As String Parameter"),
E_gd UMETA(DisplayName = "As File in Game directory"),
E_ad UMETA(DisplayName = "As File in Absolute directory")
};
USTRUCT()
struct FSendUDPMessageStruct {
GENERATED_USTRUCT_BODY()
FString ip;
int32 port;
FString message;
TArray<uint8> bytes;
FSocket* socketUDP = nullptr;
};
USTRUCT(BlueprintType)
struct FFileFunctionsSocketServerOpenFile
{
GENERATED_USTRUCT_BODY()
FArchive* writer = nullptr;
};
USTRUCT()
struct FIPandPortStruct {
GENERATED_USTRUCT_BODY()
bool success = false;
FString ip = FString();
FString errorMessage = FString();
int32 port = 0;
};
USTRUCT(BlueprintType)
struct FSocketServerPluginSession
{
GENERATED_USTRUCT_BODY()
FString ip = FString();
int32 port = 0;
int64 addToCleanerTime = 0;
FString sessionID = FString();
FString serverID = FString();
FSocket* socket = nullptr;
FSocketServerTCPClientSendDataThread* tcpSendThread = nullptr;
FSocketServerTCPClientReceiveDataThread* tcpRecieverThread = nullptr;
FSocketServerTCPFileHandlerThread* tcpFileHandlerThread = nullptr;
FUdpSocketReceiver* udpSocketReceiver = nullptr;
FSocketServerUDPThread* udpServerThread = nullptr;
FSocketServerUDPClientSendDataThread* udpSendThread = nullptr;
EServerSocketConnectionProtocol protocol;
};
USTRUCT(BlueprintType)
struct FSocketServerDownloadFileInfo
{
GENERATED_USTRUCT_BODY()
float size;
float megaBytesReceived;
float megaBytesLeft;
float percentDownload;
float megaBit;
FString fileName;
FString serverID;
};
//USTRUCT(BlueprintType)
//struct FSocketServerUploadFileInfo
//{
// GENERATED_USTRUCT_BODY()
//
// float size;
// float megaBytesSend;
// float megaBytesLeft;
// float percentUpload;
// float megaBit;
// FString fileName;
// FString serverID;
//};
USTRUCT(BlueprintType)
struct FSocketServerToken
{
GENERATED_USTRUCT_BODY()
FString token = FString();
bool deleteAfterUse = false;
EFileFunctionsSocketServerDirectoryType directoryType;
FString fileDirectory = FString();
};
#ifndef __FileFunctionsSocketServer
#define __FileFunctionsSocketServer
#include "FileFunctionsSocketServer.h"
#endif
#ifndef __RCONServer
#define __RCONServer
#include "RCONServer.h"
#endif
#ifndef __SocketServerCleanerThread
#define __SocketServerCleanerThread
#include "SocketServerCleanerThread.h"
#endif
#ifndef __SocketServerBPLibrary
#define __SocketServerBPLibrary
#include "SocketServerBPLibrary.h"
#endif
#ifndef __SocketServerUDP
#define __SocketServerUDP
#include "SocketServerUDP.h"
#endif
#ifndef __SocketServerTCP
#define __SocketServerTCP
#include "SocketServerTCP.h"
#endif
class FSocketServerModule : public IModuleInterface
{
public:
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
};
@@ -0,0 +1,499 @@
// Copyright 2017-2020 David Romanski (Socke). All Rights Reserved.
#pragma once
#include "SocketServer.h"
#include "SocketServerBPLibrary.generated.h"
class FSocketServerCleanerThread;
class USocketServerUDP;
class USocketServerTCP;
class URCONServer;
UCLASS()
class SOCKETSERVER_API USocketServerBPLibrary : public UObject
{
GENERATED_UCLASS_BODY()
public:
static USocketServerBPLibrary *socketServerBPLibrary;
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "SocketServer")
static USocketServerBPLibrary* getSocketServerTarget();
//Delegates
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FiveParams(FsocketServerConnectionEventDelegate, EServerSocketConnectionEventType, type, bool, success, FString, message, FString, sessionID, FString, serverID);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FourParams(FserverReceiveTCPMessageEventDelegate, FString, sessionID, FString, message, const TArray<uint8>&, byteArray, FString, serverID);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FourParams(FreadBytesFromFileInPartsEventDelegate, int64, fileSize, int64, position, bool, end, const TArray<uint8>&, byteArray);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FsocketServerUDPConnectionEventDelegate, bool, success, FString, message, FString, serverID);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FourParams(FserverReceiveUDPMessageEventDelegate, FString, sessionID, FString, message, const TArray<uint8>&, byteArray,FString, serverID);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_SixParams(FfileTransferOverTCPProgressEventDelegate, FString, sessionID, FString, filePath, float, percent, float, mbit, int64, bytesTransferred, int64, fileSize);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FourParams(FfileTransferOverTCPInfoEventDelegate, FString, message, FString, sessionID, FString, filePath, bool, success);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FourParams(FreceiveRCONRequestEventDelegate, FString, sessionID, FString, serverID, int32, requestID, FString, request);
UFUNCTION()
void socketServerConnectionEventDelegate(const EServerSocketConnectionEventType type, const bool success, const FString message, const FString sessionID, const FString serverID);
UPROPERTY(BlueprintAssignable, Category = "SocketServer|TCP|Events|ConnectionInfo")
FsocketServerConnectionEventDelegate onsocketServerConnectionEventDelegate;
UFUNCTION()
void serverReceiveTCPMessageEventDelegate(const FString sessionID, const FString message, const TArray<uint8>& byteArray, const FString serverID);
UPROPERTY(BlueprintAssignable, Category = "SocketServer|TCP|Events|ReceiveMessage")
FserverReceiveTCPMessageEventDelegate onserverReceiveTCPMessageEventDelegate;
UFUNCTION()
void socketServerUDPConnectionEventDelegate(const bool success, const FString message, const FString serverID);
UPROPERTY(BlueprintAssignable, Category = "SocketServer|UDP|Events|ConnectionInfo")
FsocketServerUDPConnectionEventDelegate onsocketServerUDPConnectionEventDelegate;
UFUNCTION()
void serverReceiveUDPMessageEventDelegate(const FString sessionID, const FString message, const TArray<uint8>& byteArray, const FString serverID);
UPROPERTY(BlueprintAssignable, Category = "SocketServer|UDP|Events|ReceiveMessage")
FserverReceiveUDPMessageEventDelegate onserverReceiveUDPMessageEventDelegate;
UFUNCTION()
void fileTransferOverTCPProgressEventDelegate(const FString sessionID, const FString filePath, const float percent, const float mbit, const int64 bytesTransferred, const int64 fileSize);
UPROPERTY(BlueprintAssignable, Category = "SocketServer|TCP|Events|File|FileTransferOverTCPProgress")
FfileTransferOverTCPProgressEventDelegate onfileTransferOverTCPProgressEventDelegate;
UFUNCTION()
void fileTransferOverTCPInfoEventDelegate(const FString message, const FString sessionID, const FString filePath, const bool success);
UPROPERTY(BlueprintAssignable, Category = "SocketServer|TCP|Events|File|FileTransferOverTCPInfo")
FfileTransferOverTCPInfoEventDelegate onfileTransferOverTCPInfoEventDelegate;
UFUNCTION()
void readBytesFromFileInPartsEventDelegate(const int64 fileSize, const int64 position, const bool end, const TArray<uint8>& byteArray);
UPROPERTY(BlueprintAssignable, Category = "SocketServer|SpecialFunctions|File|Events|ReadBytesFromFileInPartsAsync")
FreadBytesFromFileInPartsEventDelegate onreadBytesFromFileInPartsEventDelegate;
UFUNCTION()
void receiveRCONRequestEventDelegate(const FString sessionID, const FString serverID, const int32 requestID, const FString request);
UPROPERTY(BlueprintAssignable, Category = "SocketServer|TCP|Events|RCON|ReceiveRCONRequest")
FreceiveRCONRequestEventDelegate onreceiveRCONRequestEventDelegate;
/**
*Get all Session IDs
*@param optionalServerID With one server the field can remain empty. If there are several servers, the ServerID should be entered here or the newest server is automatically taken.
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer")
static void serverPluginGetSocketSessionIds(const FString optionalServerID, TArray<FString>& sessionIDs);
void serverPluginGetSocketSessionIdsNonStatic(const FString optionalServerID, TArray<FString>& sessionIDs);
UFUNCTION(BlueprintCallable, Category = "SocketServer")
static void serverPluginGetSocketSessionInfo(const FString sessionID, bool &sessionFound, FString &IP, int32 &port, EServerSocketConnectionProtocol &connectionProtocol, FString& serverID);
void serverPluginGetSocketSessionInfoNonStatic(const FString sessionID, bool& sessionFound, FString& IP, int32& port, EServerSocketConnectionProtocol& connectionProtocol, FString& serverID);
UFUNCTION(BlueprintCallable, Category = "SocketServer")
static void serverPluginGetSocketSessionInfoByServerID(const FString serverID, const FString sessionID, bool& sessionFound, FString& IP, int32& port, EServerSocketConnectionProtocol& connectionProtocol);
void serverPluginGetSocketSessionInfoByServerIDNonStatic(const FString serverID, const FString sessionID, bool& sessionFound, FString& IP, int32& port, EServerSocketConnectionProtocol& connectionProtocol);
/**
*Close a connection and remove the session
*@param optionalServerID With one server the field can remain empty. If there are several servers, the ServerID should be entered here or the newest server is automatically taken.
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer")
static void removeSessionAndCloseConnection(FString sessionId, FString optionalServerID);
void removeSessionAndCloseConnectionNonStatic(FString sessionId, FString optionalServerID);
//UDP
/**
*Start UDP Server
*@param domainOrIP IP or Domain to listen
*@param port port to listen
*@param multicast This allows several servers to be started on different computers in the LAN with the same IP.
*@param receiveFilter This allows you to decide which data type you want to receive. If you receive files it makes no sense to convert them into a string.
*@param customServerID Optionally you can assign your own ServerID like "myAuthentificationServer" or "fileServer"
*@param maxPacketSize sets the maximum UDP packet size. More than 65507 is not possible.
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer|UDP", meta = (AdvancedDisplay = 7))
static void startUDPServer(FString& serverID, FString IP = FString("0.0.0.0"), int32 port = 8888, bool multicast = false, EReceiveFilterServer receiveFilter = EReceiveFilterServer::E_SAB, FString customServerID = FString(""), int32 maxPacketSize = 65507);
void startUDPServerNonStatic(FString& serverID, FString IP = FString("0.0.0.0"), int32 port = 8888, bool multicast = false, EReceiveFilterServer receiveFilter = EReceiveFilterServer::E_SAB, FString customServerID = FString(""), int32 maxPacketSize = 65507);
/**
*Stop UDP Server
*@param optionalServerID With one server the field can remain empty. If there are several servers, the ServerID should be entered here or the newest server is automatically taken.
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer|UDP")
static void stopUDPServer(FString optionalServerID);
void stopUDPServerNonStatic(FString optionalServerID);
UFUNCTION(BlueprintCallable, Category = "SocketServer|UDP")
static void stopAllUDPServers();
void stopAllUDPServersNonStatic();
/**
*Sends data back to a client.
*@param clientSessionIDs
*@param message
*@param byteArray
*@param addLineBreak
*@param socketType Some Thirdparty software expects the data to be sent back over the same socket, others expects a new socket.
*@param optionalServerID With one server the field can remain empty. If there are several servers, the ServerID should be entered here or the newest server is automatically taken.
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer|UDP", meta = (AutoCreateRefTerm = "byteArray"))
static void socketServerSendUDPMessage(TArray<FString> clientSessionIDs, FString message, TArray<uint8> byteArray, bool addLineBreak, bool asynchronous, ESocketServerUDPSocketType socketType, FString optionalServerID);
void socketServerSendUDPMessageNonStatic(TArray<FString> clientSessionIDs, FString message, TArray<uint8> byteArray, bool addLineBreak, bool asynchronous, ESocketServerUDPSocketType socketType, FString optionalServerID);
/**
*Sends data back to a client.
*@param clientSessionIDs
*@param message
*@param byteArray
*@param addLineBreak
*@param socketType Some Thirdparty software expects the data to be sent back over the same socket, others expects a new socket.
*@param optionalServerID With one server the field can remain empty. If there are several servers, the ServerID should be entered here or the newest server is automatically taken.
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer|UDP", meta = (AutoCreateRefTerm = "byteArray"))
static void socketServerSendUDPMessageToClient(FString clientSessionID, FString message, TArray<uint8> byteArray, bool addLineBreak, bool asynchronous, ESocketServerUDPSocketType socketType, FString optionalServerID);
void socketServerSendUDPMessageToClientNonStatic(FString clientSessionID, FString message, TArray<uint8> byteArray, bool addLineBreak, bool asynchronous, ESocketServerUDPSocketType socketType, FString optionalServerID);
/**
*If you want to send data directly to a specific destination without getting data back.
*@param ip
*@param port
*@param message
*@param byteArray
*@param addLineBreak
*@param optionalServerID With one server the field can remain empty. If there are several servers, the ServerID should be entered here or the newest server is automatically taken.
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer|UDP", meta = (AutoCreateRefTerm = "byteArray"))
static void socketServerSendUDPMessageTo(FString ip, int32 port, FString message, TArray<uint8> byteArray, bool addLineBreak, bool asynchronous, FString optionalServerID);
void socketServerSendUDPMessageToNonStatic(FString ip, int32 port, FString message, TArray<uint8> byteArray, bool addLineBreak, bool asynchronous, FString optionalServerID);
//TCP
/**
* Start TCP Server
* @param domainOrIP IP or Domain to listen
* @param port port to listen
* @param receiveFilter This allows you to decide which data type you want to receive. If you receive files it makes no sense to convert them into a string.
* @param messageSeparator It may be that data packets are split or merged when transmitted over TCP in order to optimize the transmission. For example, if you send "Hello" two times in a row very quickly, it can happen that "HelloHa" and "llo" arrive. To counteract this circumstance there are options to separate the data packets.
* @param customServerID Optionally you can assign your own ServerID like "myAuthentificationServer" or "fileServer"
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer|TCP")
static void startTCPServer(FString& serverID, FString IP = FString("0.0.0.0"), int32 port = 8888, EReceiveFilterServer receiveFilter = EReceiveFilterServer::E_SAB,
ESocketServerTCPSeparator messageSeparator = ESocketServerTCPSeparator::E_None, FString customServerID = FString(""));
void startTCPServerNontStatic(FString& serverID, FString IP, int32 port, EReceiveFilterServer receiveFilter, ESocketServerTCPSeparator messageSeparator,
FString customServerID, bool isFileServer, FString Aes256bitKey, bool resumeFiles, bool writeHandShakeToLogEditorOnly);
/**
* Starts a file server that can receive and send files in response to requests from clients. The files are streamed and do not consume RAM. To determine what can be uploaded or downloaded and how, the tokens are used.
* @param domainOrIP IP or Domain to listen
* @param port port to listen
* @param receiveFilter This allows you to decide which data type you want to receive. If you receive files it makes no sense to convert them into a string.
* @param customServerID Optionally you can assign your own ServerID like "myAuthentificationServer" or "fileServer"
* @param Aes256bitKey The AES key must consist of 32 ASCII characters. The communication between client and server is encrypted via AES in 256bit. Therefore a key must be entered.
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer|TCP")
static void startTCPFileServer(FString& serverID, FString IP = FString("0.0.0.0"), int32 port = 8899, FString customServerID = FString(""), FString Aes256bitKey = FString(""), bool resumeFiles = false, bool writeHandShakeToLogEditorOnly = false);
/**
* Tokens are used to determine what can be uploaded or downloaded and how. It can be used to specify a directory in which a file is stored or to specify a file that can be sent to a client.
* @param deleteTokenAfterUse If true, the token will be deleted after one use.
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer|TCP")
static void addFileToken(FString token, bool deleteTokenAfterUse, EFileFunctionsSocketServerDirectoryType directoryType, FString filePathOrDirectory);
/**
* Tokens are used to determine what can be uploaded or downloaded and how. It can be used to specify a directory in which a file is stored or to specify a file that can be sent to a client.
* @param fileTokens Key= token, value = file path or directory
* @param deleteTokenAfterUse If true, the token will be deleted after one use.
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer|TCP")
static void addFileTokens(TMap<FString, FString> fileTokens, bool deleteAfterUse, EFileFunctionsSocketServerDirectoryType directoryType);
UFUNCTION(BlueprintCallable, Category = "SocketServer|TCP")
static void removeFileToken(FString token);
/**
*Stop TCP Server
*@param optionalServerID With one server the field can remain empty. If there are several servers, the ServerID should be entered here or the newest server is automatically taken.
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer|TCP")
static void stopTCPServer(FString optionalServerID);
void stopTCPServerNonSTatic(FString optionalServerID);
UFUNCTION(BlueprintCallable, Category = "SocketServer|TCP")
static void stopAllTCPServers();
void stopAllTCPServersNonStatic();
//UFUNCTION(BlueprintCallable, Category = "SocketServer|TCP", meta = (AutoCreateRefTerm = "userIdsToDirectoriesMap"))
// void startTCPFileserver(FString& serverID, TMap<FString, FString> userIdsToDirectoriesMap, FString IP = FString("0.0.0.0"), int32 port = 9999, FString downloadDirectory = FString("Content/"), EFileFunctionsSocketServerDirectoryType directoryType = EFileFunctionsSocketServerDirectoryType::E_gd, EHTTPSocketServerFileDownloadResumeType ifFileExistThen = EHTTPSocketServerFileDownloadResumeType::E_RESUME, FString customServerID = FString(""), bool onlyWithToken = true);
//UFUNCTION(BlueprintCallable, Category = "SocketServer|TCP")
// void addFileserverToken(FString token, int32 lifeTimeSeconds,bool reusable);
//UFUNCTION(BlueprintCallable, Category = "SocketServer|TCP")
// void removeFileserverToken(FString token);
/**
*Send data to clients
*@param clientSessionIDs array with client sessionIDs
*@param message data as string
*@param byteArray data as bytes
*@param addLineBreak add linebreak to message
*@param serverID Id of the server you want to send data from
*@param optionalServerID With one server the field can remain empty. If there are several servers, the ServerID should be entered here or the newest server is automatically taken.
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer|TCP", meta = (AutoCreateRefTerm = "byteArray"))
static void socketServerSendTCPMessage(TArray<FString> clientSessionIDs, FString message, TArray<uint8> byteArray, bool addLineBreak = true, FString optionalServerID = FString(""));
void socketServerSendTCPMessageNonStatic(TArray<FString> clientSessionIDs, FString message, TArray<uint8> byteArray, bool addLineBreak = true, FString optionalServerID = FString(""));
/**
*Send data to client
*@param clientSessionID array with client sessionIDs
*@param message data as string
*@param byteArray data as bytes
*@param addLineBreak add linebreak to message
*@param serverID Id of the server you want to send data from
*@param optionalServerID With one server the field can remain empty. If there are several servers, the ServerID should be entered here or the newest server is automatically taken.
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer|TCP", meta = (AutoCreateRefTerm = "byteArray"))
static void socketServerSendTCPMessageToClient(FString clientSessionID, FString message, TArray<uint8> byteArray, bool addLineBreak = true, FString optionalServerID = FString(""));
void socketServerSendTCPMessageToClientNonStatic(FString clientSessionID, FString message, TArray<uint8> byteArray, bool addLineBreak = true, FString optionalServerID = FString(""));
UFUNCTION(BlueprintCallable, Category = "SocketServer|TCP")
static void changeTCPSeparatorStringOnServer(FString separator = "(~{");
void changeTCPSeparatorStringOnServerNonStatic(FString separator);
UFUNCTION(BlueprintCallable, Category = "SocketServer|TCP")
static void changeTCPSeparatorByteOnServer(uint8 separator = 0x00);
void changeTCPSeparatorByteOnServerNonStatic(uint8 separator);
/**
*Send file to client
*@param clientSessionID client sessionID
*@param directoryWithFileName
*@param directoryType
*@param serverID Id of the server you want to send file from
*/
/*UFUNCTION(BlueprintCallable, Category = "SocketServer|TCP", meta = (AutoCreateRefTerm = "byteArray"))
void socketServerSendTCPFile(FString clientSessionID, FString directoryWithFileName = FString("Content/image.png"), EFileFunctionsSocketServerDirectoryType directoryType = EFileFunctionsSocketServerDirectoryType::E_gd, int64 resumeFileSize =0,FString serverID = FString(""));*/
/**
*Creates a unique ID
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer")
static FString generateUniqueID();
/**
*Resolve Domain. Only Domains. Hostnames do not work.
*@param domain
*@param useDNSCache Domain and IP are stored in RAM. Starting from the second time the IP is taken from the RAM.
*@param dnsIP
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer")
static UDNSClientSocketServer* resolveDomain(FString domain, bool useDNSCache = true, FString dnsIP = FString("8.8.8.8"));
UDNSClientSocketServer* resolveDomainNonStatic(FString domain, bool useDNSCache = true, FString dnsIP = FString("8.8.8.8"));
/**
*UE4 uses different socket connections. When Steam is active, Steam Sockets are used for all connections. This leads to problems if you want to use Steam but not Steam Sockets. Therefore you can change the sockets.
*@param platform Auto = UE4 decides. Thirdparty platforms (Steam, Playstore etc.) will be used if configured. System = UE4 determines the OS and selects a socket type accordingly.
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer")
static void changeSocketPlatform(ESocketPlatformServer platform);
/**
* Checks if a server can listen on IP x and port y.
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer")
static bool checkPort(EServerSocketConnectionCheckPortType type, FString ip = FString("0.0.0.0"), int32 port = 8888);
bool checkPortNonStatic(EServerSocketConnectionCheckPortType type, FString ip = FString("0.0.0.0"), int32 port = 8888);
/**
* Returns a random port on which the server can listen.
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer")
static int32 getRandomPort(EServerSocketConnectionCheckPortType type, FString ip = FString("0.0.0.0"));
int32 getRandomPortNonStatic(EServerSocketConnectionCheckPortType type, FString ip = FString("0.0.0.0"));
UFUNCTION(BlueprintCallable, Category = "SocketServer|Register")
static void registerClientEvent(FString sessionID, UEventBean*& event);
void registerClientEventNonStatic(FString sessionID, UEventBean*& event);
UFUNCTION(BlueprintCallable, Category = "SocketServer|Register")
static void unregisterClientEvent(FString sessionID);
void unregisterClientEventNonStatic(FString sessionID);
UEventBean* getResiteredClientEvent(FString sessionID);
//RCON
/**
* Turns a TCP server into an RCON server.
* @param passwordType If the type "As String Parameter" has been selected, the password can simply be entered as a parameter. Otherwise please select a directory incl. file.
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer|TCP|RCON")
static void registerRCONServer(FString serverID, ERCONPasswordType passwordType, FString passwordOrFile, bool& success, FString& errorMessage);
UFUNCTION(BlueprintCallable, Category = "SocketServer|TCP|RCON")
static void unregiserRCONServer(FString serverID);
/**
* Sends an RCON response to an RCON client. sessionID, serverID and requestID must be specified.
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer|TCP|RCON")
static void sendRCONResponse(FString sessionID, FString serverID, int32 requestID, FString response);
/**
*The cleaner thread is a thread that runs endlessly and deletes data remnants from closed/broken connections from RAM.
*@param showLogs Writes to the logs when data remnants are deleted.
*@param minLiveTimeInSeconds When a connection is closed it is passed to the cleaner thread. The thread ignores the connection for "minLiveTimeInSeconds" until it clears the data. This is necessary because sometimes connections need some time to be closed completely.
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions")
static void changeCleanerThreadSettingsOnServer(bool showLogs, int32 minLiveTimeInSeconds = 10);
//number stuff
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|Number")
static void parseBytesToFloat(TArray<uint8> bytes, float& value);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|Number")
static void parseBytesToInteger(TArray<uint8> bytes, int32& value);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|Number")
static void parseBytesToInteger64(TArray<uint8> bytes, int64& value);
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "SocketServer|SpecialFunctions|Number")
static void parseBytesToFloatPure(TArray<uint8> bytes, float& value);
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "SocketServer|SpecialFunctions|Number")
static void parseBytesToIntegerPure(TArray<uint8> bytes, int32& value);
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "SocketServer|SpecialFunctions|Number")
static void parseBytesToInteger64Pure(TArray<uint8> bytes, int64& value);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|Number")
static void parseBytesToFloatEndian(TArray<uint8> bytes, float& littleEndian, float& bigEndian);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|Number")
static void parseBytesToIntegerEndian(TArray<uint8> bytes, int32& littleEndian, int32& bigEndian);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|Number")
static void parseBytesToInteger64Endian(TArray<uint8> bytes, int64& littleEndian, int64& bigEndian);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|Number", meta = (AutoCreateRefTerm = "byteArray"))
static void parseFloatToBytes(TArray<uint8>& byteArray, float value, bool switchByteOrder = false);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|Number", meta = (AutoCreateRefTerm = "byteArray"))
static void parseIntegerToBytes(TArray<uint8>& byteArray, int32 value, bool switchByteOrder = false);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|Number", meta = (AutoCreateRefTerm = "byteArray"))
static void parseInteger64ToBytes(TArray<uint8>& byteArray, int64 value, bool switchByteOrder = false);
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "SocketServer|SpecialFunctions|Number", meta = (AutoCreateRefTerm = "byteArray"))
static void parseFloatToBytesPure(TArray<uint8>& byteArray, float value, bool switchByteOrder = false);
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "SocketServer|SpecialFunctions|Number", meta = (AutoCreateRefTerm = "byteArray"))
static void parseIntegerToBytesPure(TArray<uint8>& byteArray, int32 value, bool switchByteOrder = false);
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "SocketServer|SpecialFunctions|Number", meta = (AutoCreateRefTerm = "byteArray"))
static void parseInteger64ToBytesPure(TArray<uint8>& byteArray, int64 value, bool switchByteOrder = false);
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "SocketServer|SpecialFunctions|Number", meta = (AutoCreateRefTerm = "value"))
static void parseBytesToFloatArrayPure(TArray<float>& value, TArray<uint8> bytes);
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "SocketServer|SpecialFunctions|Number", meta = (AutoCreateRefTerm = "value"))
static void parseBytesToIntegerArrayPure(TArray<int32>& value, TArray<uint8> bytes);
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "SocketServer|SpecialFunctions|Number", meta = (AutoCreateRefTerm = "value"))
static void parseBytesToInteger64ArrayPure(TArray<int64>& value, TArray<uint8> bytes);
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "SocketServer|SpecialFunctions|Number", meta = (AutoCreateRefTerm = "byteArray"))
static void parseFloatArrayToBytesPure(TArray<uint8>& byteArray, TArray<float> value);
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "SocketServer|SpecialFunctions|Number", meta = (AutoCreateRefTerm = "byteArray"))
static void parseIntegerArrayToBytesPure(TArray<uint8>& byteArray, TArray<int32> value);
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "SocketServer|SpecialFunctions|Number", meta = (AutoCreateRefTerm = "byteArray"))
static void parseInteger64ArrayToBytesPure(TArray<uint8>& byteArray, TArray<int64> value);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|Hex")
static TArray<uint8> parseHexToBytes(FString hex);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|Hex")
static FString parseHexToString(FString hex);
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|Hex")
static FString parseBytesToHex(TArray<uint8> bytes);
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "SocketServer|SpecialFunctions|Hex")
static TArray<uint8> parseHexToBytesPure(FString hex);
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "SocketServer|SpecialFunctions|Hex")
static FString parseHexToStringPure(FString hex);
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "SocketServer|SpecialFunctions|Hex")
static FString parseBytesToHexPure(TArray<uint8> bytes);
/**
*With this function you can start a UE game server at runtime. To close the server, you can simply start the server again on the same port. However, the default map will then be loaded.
*@param Protocol i.e. "unreal" or "http"
*@param Host Optional hostname, i.e. "204.157.115.40" or "unreal.epicgames.com", blank if local.
*@param Port Optional host port
*@param Map
* @param name, i.e. "SkyCity", default is "Entry".
* @param RedirectURL Optional place to download Map if client does not possess it
* @param Portal Portal to enter through, default is ""
*/
UFUNCTION(BlueprintCallable, Category = "SocketServer|SpecialFunctions|Multiplayer", meta = (WorldContext = worldContextObject, AutoCreateRefTerm = "Options"))
static bool startUEGameHost(UObject* worldContextObject, FString Protocol, FString Host, FString Map, FString RedirectURL, TArray<FString> Options, FString Portal, int32 Port = 7777);
static ISocketSubsystem* getSocketSubSystem();
//void addClientSession(FString key, FClientSocketSession& session);
//void removeClientSession(FString key);
//TMap<FString, FClientSocketSession> getClientSessions();
//void startTCPClientHandler(FClientSocketSession& session, EReceiveFilterServer receiveFilter);
//bool isTCPServerRun();
//void setTCPServerRun(bool run);
void getTcpSeparator(uint8& byteSeparator, FString& stringSeparator);
void cleanConnection(FSocketServerPluginSession& session);
TMap<FString, USocketServerTCP*> getTcpServerMap();
TMap<FString, FSocketServerToken> fileTokenMap;
FSocketServerCleanerThread* socketServerPluginCleanerThread = nullptr;
private:
ESocketPlatformServer systemSocketPlatform;
TMap<FString, UEventBean*> messageEvents;
TMap<FString, USocketServerUDP*> udpServers;
TMap<FString, USocketServerTCP*> tcpServers;
TMap<FString, URCONServer*> rconServers;
FString lastUDPServerID;
FString lastTCPServerID;
FString tcpStringSeparator = "(~{";
uint8 tcpByteSeparator = 0x00;
FIPandPortStruct checkIpAndPort(FString IP, int32 port);
};
@@ -0,0 +1,25 @@
// Copyright 2022 David Romanski (Socke). All Rights Reserved.
#pragma once
#include "SocketServer.h"
class SOCKETSERVER_API FSocketServerCleanerThread : public FRunnable {
public:
FSocketServerCleanerThread();
virtual uint32 Run() override;
void addSession(FSocketServerPluginSession& session);
void changeSettings(bool showLogs, int32 minLiveTimeInSeconds);
private:
bool showLogs = false;
int32 minLiveTimeInSeconds = 10;
FRunnableThread* thread = nullptr;
TQueue<FSocketServerPluginSession> sessionQueue;
};
@@ -0,0 +1,80 @@
// Copyright 2017-2020 David Romanski (Socke). All Rights Reserved.
#pragma once
#include "SocketServer.h"
#include "SocketServerTCPThread.h"
#include "SocketServerTCPClientSendDataThread.h"
#include "SocketServerTCPClientReceiveDataThread.h"
#include "SocketServerTCPFileHandlerThread.h"
#include "SocketServerTCP.generated.h"
class USocketServerBPLibrary;
UCLASS(Blueprintable, BlueprintType)
class SOCKETSERVER_API USocketServerTCP : public UObject
{
GENERATED_UCLASS_BODY()
public:
void startTCPServer(FIPandPortStruct ipStructP,FString IP, int32 port, EReceiveFilterServer receiveFilter, ESocketServerTCPSeparator messageWrapping,
FString serverID, bool isFileServer, FString Aes256bitKey, bool resumeFiles, bool writeHandShakeToLogEditorOnly);
void stopTCPServer();
void sendTCPMessage(TArray<FString> clientSessionIDs, FString message, TArray<uint8> byteArray, bool addLineBreak);
void sendTCPMessageToClient(FString clientSessionID, FString message, TArray<uint8> byteArray, bool addLineBreak);
FIPandPortStruct getServerIpAndPortStruct();
FString getIP();
int32 getPort();
FString getServerID();
bool hasResume();
void initTCPClientThreads(FSocketServerPluginSession& session, EReceiveFilterServer receiveFilter);
void addClientSession(FSocketServerPluginSession& session);
FSocketServerPluginSession getClientSession(FString key);
void removeClientSession(FString key);
TMap<FString, FSocketServerPluginSession> getClientSessions();
//EHTTPSocketServerFileDownloadResumeType getifFileExistThen();
FString encryptMessage(FString message);
FString decryptMessage(FString message);
struct FSocketServerToken getTokenStruct(FString token);
void removeTokenFromStruct(FString token);
FString getCleanDir(EFileFunctionsSocketServerDirectoryType directoryType, FString fileDirectory);
void getMD5FromFile(FString filePathP, bool& success, FString& MD5);
void deleteFile(FString filePathP);
int64 fileSize(FString filePathP);
FString int64ToString(int64 num);
void getTcpSeparator(FString& stringSeparator, uint8& byteSeparator, ESocketServerTCPSeparator& messageWrapping);
bool isRun();
void readDataLength(TArray<uint8>& byteDataArray, int32& byteLenght);
TMap<FString, FSocketServerPluginSession> clientSessions;
private:
FSocketServerTCPThread* socketServerTCPThread = nullptr;
FSocketServerTCPFileHandlerThread* tcpFileHandlerThread = nullptr;
bool run = true;
FString serverID = FString();
FIPandPortStruct ipAndPortStruct;
FString serverIP = FString();
int32 serverPort = -1;
EReceiveFilterServer receiveFilter;
bool fileServer = false;
FString aesKey = FString();
bool resumeFiles = false;
bool writeHandShakeToLogEditorOnly = false;
//FString downloadDir;
ESocketServerTCPSeparator messageWrapping;
FString tcpStringSeparator = "(~{";
uint8 tcpByteSeparator = 0x00;
};
@@ -0,0 +1,29 @@
// Copyright 2022 David Romanski (Socke). All Rights Reserved.
#pragma once
#include "SocketServer.h"
class SOCKETSERVER_API FSocketServerTCPClientReceiveDataThread : public FRunnable {
public:
FSocketServerTCPClientReceiveDataThread(USocketServerTCP* tcpServerP,
FSocketServerPluginSession& sessionP,
EReceiveFilterServer receiveFilterP);
~FSocketServerTCPClientReceiveDataThread();
virtual uint32 Run() override;
void triggerMessageEvent(TArray<uint8>& byteDataArray, FString& sessionID, FString& serverID, bool addNullTerminator = true);
void stopThread();
private:
USocketServerTCP* tcpServer = nullptr;
FSocketServerPluginSession session;
EReceiveFilterServer receiveFilter;
FRunnableThread* thread = nullptr;
bool run = true;
bool deathConnection = false;
};
@@ -0,0 +1,34 @@
// Copyright 2022 David Romanski (Socke). All Rights Reserved.
#pragma once
#include "SocketServer.h"
class SOCKETSERVER_API FSocketServerTCPClientSendDataThread : public FRunnable {
public:
FSocketServerTCPClientSendDataThread(USocketServerTCP* tcpServerP, FSocketServerPluginSession& sessionP);
~FSocketServerTCPClientSendDataThread();
virtual uint32 Run() override;
FRunnableThread* getThread();
void setThread(FRunnableThread* threadP);
void stopThread();
bool isRun();
void setMessage(FString messageP, TArray<uint8> byteArrayP);
void sendMessage(FString messageP, TArray<uint8> byteArrayP);
void pauseThread(bool pause);
private:
USocketServerTCP* tcpServer = nullptr;
FSocketServerPluginSession session;
FRunnableThread* thread = nullptr;
FSocket* socket = nullptr;
bool run = true;
bool paused;
bool waitForInit = true;
TQueue<FString> messageQueue;
TQueue<TArray<uint8>> byteArrayQueue;
};
@@ -0,0 +1,48 @@
// Copyright 2022 David Romanski (Socke). All Rights Reserved.
#pragma once
#include "SocketServer.h"
//#include "SocketServerTCPFileHandlerThread.generated.h"
class SOCKETSERVER_API FSocketServerTCPFileHandlerThread : public FRunnable {
public:
FSocketServerTCPFileHandlerThread(USocketServerTCP* tcpServerP, FSocketServerPluginSession& sessionP);
~FSocketServerTCPFileHandlerThread();
virtual uint32 Run() override;
void doRequestFileFromServer(FSocketServerToken tokenStruct);
void doSendFileToClient(FString message);
void triggerFileOverTCPProgress(FString sessionIDP, FString filePathP, float percentP, float mbitP, int64 bytesReceivedP, int64 fileSizeP);
void triggerFileTransferOverTCPInfoEvent(FString messageP, FString sessionIDP, FString filePathP, bool successP);
void sendEndMessage(FString fullFilePathP, FString tokenP, FString md5ClientP);
FString readMessageFromClient();
void sendMessageToClient(FString message);
void stopThread();
private:
USocketServerTCP* tcpServer = nullptr;
FSocketServerPluginSession session;
bool fileServer = false;
FRunnableThread* thread = nullptr;
bool run = true;
//int32 commandProgress = 0;
int64 fileSize = 0;
double WaitForRead = 30;
//FSocketServerTCPClientSendFileToThread* sendFileThread = nullptr;
};
//UCLASS(Blueprintable, BlueprintType)
//class USocketServerTCPFileHandler : public UObject
//{
// GENERATED_UCLASS_BODY()
//
// UFUNCTION()
// void receiveData(const FString sessionID, const FString message, const TArray<uint8>& byteArray, const FString serverID);
//};
@@ -0,0 +1,23 @@
// Copyright 2022 David Romanski (Socke). All Rights Reserved.
#pragma once
#include "SocketServer.h"
class SOCKETSERVER_API FSocketServerTCPThread : public FRunnable {
public:
FSocketServerTCPThread(USocketServerTCP* tcpServerP, EReceiveFilterServer receiveFilterP, bool& runP);
~FSocketServerTCPThread();
virtual uint32 Run() override;
void stopThread();
private:
USocketServerTCP* tcpServer;
EReceiveFilterServer receiveFilter;
bool& run;
FRunnableThread* thread = nullptr;
};
@@ -0,0 +1,59 @@
// Copyright 2017 David Romanski (Socke). All Rights Reserved.
#pragma once
#include "SocketServer.h"
#include "SocketServerUDPThread.h"
#include "SocketServerUDPClientSendDataThread.h"
#include "SocketServerUDP.generated.h"
class USocketServerBPLibrary;
class FSocketServerUDPThread;
class FSocketServerUDPClientSendDataThread;
UCLASS(Blueprintable, BlueprintType)
class SOCKETSERVER_API USocketServerUDP : public UObject
{
GENERATED_UCLASS_BODY()
public:
void startUDPServer(FIPandPortStruct ipStruct,FString IP, int32 port, bool multicast, EReceiveFilterServer receiveFilter, FString serverID, int32 maxPacketSize);
void stopUDPServer();
void sendUDPMessage(TArray<FString> clientSessionIDs, FString message, TArray<uint8> byteArray, bool asynchronous, ESocketServerUDPSocketType socketType);
void sendUDPMessageToClient(FString clientSessionID, FString message, TArray<uint8> byteArray, bool asynchronous, ESocketServerUDPSocketType socketType);
void sendUDPMessageTo(FString ip, int32 port, FString message, TArray<uint8> byteArray, bool asynchronous);
//do not work with ipv6
//void UDPReceiver(const FArrayReaderPtr& ArrayReaderPtr, const FIPv4Endpoint& EndPt);
void UDPReceiverSocketServerPlugin(FArrayReaderPtr& ArrayReaderPtr, TSharedRef<FInternetAddr> remoteAddress);
FIPandPortStruct getServerIpAndPortStruct();
FString getIP();
int32 getPort();
void setSocketReceiver(FUdpSocketReceiver* socketReceiverP, FSocket* socket);
FUdpSocketReceiver* getSocketReceiver();
FSocket* getSocket();
FString getServerID();
void addClientSession(FSocketServerPluginSession& session);
FSocketServerPluginSession* getClientSession(FString key);
void removeClientSession(FString key);
TMap<FString, FSocketServerPluginSession> getClientSessions();
void sendBytes(FSocket*& socket, TArray<uint8>& bytes, int32& sent, TSharedRef<FInternetAddr>& addr);
private:
FString serverID;
FIPandPortStruct ipAndPortStruct;
FString serverIP;
int32 serverPort = -1;
int32 maxPacketSize = 65507;
FSocket* socket= nullptr;
FUdpSocketReceiver* socketReceiver = nullptr;
EReceiveFilterServer receiveFilter;
FSocketServerUDPThread* serverThread = nullptr;
FSocketServerUDPClientSendDataThread* sendThread = nullptr;
TMap<FString, FSocketServerPluginSession> clientSessions;
};
@@ -0,0 +1,30 @@
// Copyright 2022 David Romanski (Socke). All Rights Reserved.
#pragma once
#include "SocketServer.h"
class SOCKETSERVER_API FSocketServerUDPClientSendDataThread : public FRunnable {
public:
FSocketServerUDPClientSendDataThread(USocketServerUDP* udpServerP);
~FSocketServerUDPClientSendDataThread();
virtual uint32 Run() override;
FRunnableThread* getThread();
void setThread(FRunnableThread* threadP);
void stopThread();
bool isRun();
void sendMessage(FString ip, int32 port, FString message, TArray<uint8> bytes, FSocket* socketUDP);
void pauseThread(bool pause);
private:
USocketServerUDP* udpServer;
FRunnableThread* thread = nullptr;
bool run = true;
bool paused;
TQueue<FSendUDPMessageStruct> messageQueue;
};
@@ -0,0 +1,28 @@
// Copyright 2022 David Romanski (Socke). All Rights Reserved.
#pragma once
#include "SocketServer.h"
class SOCKETSERVER_API FSocketServerUDPThread : public FRunnable {
public:
FSocketServerUDPThread(USocketServerUDP* udpServerP, bool multicastP);
~FSocketServerUDPThread();
virtual uint32 Run() override;
void stopThread();
private:
FString message;
USocketServerUDP* udpServer;
bool multicast;
FRunnableThread* thread = nullptr;
bool run = true;
};