// Copyright 2017-2019 David Romanski (Socke). All Rights Reserved. #include "SocketClientBPLibrary.h" #include "SocketClient.h" USocketClientBPLibrary* USocketClientBPLibrary::socketClientBPLibrary; USocketClientBPLibrary::USocketClientBPLibrary(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { socketClientBPLibrary = this; if (socketClientCleanerThread == nullptr) socketClientCleanerThread = new FSocketClientCleanerThread(); } /*Delegate functions*/ void USocketClientBPLibrary::socketClientTCPConnectionEventDelegate(const bool success, const FString message, const FString clientConnectionIDP) {} void USocketClientBPLibrary::receiveTCPMessageEventDelegate(const FString message, const TArray& byteArray, const FString clientConnectionIDP) {} void USocketClientBPLibrary::socketClientUDPConnectionEventDelegate(const bool success, const FString message, const FString clientConnectionID) {} void USocketClientBPLibrary::receiveUDPMessageEventDelegate(const FString message, const TArray& byteArray, const FString IP, const int32 port,const FString clientConnectionID) {} void USocketClientBPLibrary::transferFileOverTCPProgressEventDelegate(const FString clientConnectionID, const FString filePath, const float percent, const float mbit, const int64 bytesSend, const int64 fileSize){} void USocketClientBPLibrary::fileTransferOverTCPInfoEventDelegate(const FString message, const FString clientConnectionID, const FString filePath, const bool success){} void USocketClientBPLibrary::readBytesFromFileInPartsEventDelegate(const int64 fileSize, const int64 position, const bool end, const TArray& byteArray){} USocketClientBPLibrary::~USocketClientBPLibrary() { } USocketClientBPLibrary* USocketClientBPLibrary::getSocketClientTarget() { return socketClientBPLibrary; } FString USocketClientBPLibrary::getLocalIP() { bool canBind = false; TSharedRef localIp = USocketClientBPLibrary::getSocketClientTarget()->getSocketSubSystem()->GetLocalHostAddr(*GLog, canBind); if (localIp->IsValid()) { FString localIP = localIp->ToString(false); if (localIP.Equals("127.0.0.1")) { UE_LOG(LogTemp, Error, TEXT("Could not detect the local IP.")); return "0.0.0.0"; } return localIp->ToString(false); } else { UE_LOG(LogTemp, Error, TEXT("Could not detect the local IP.")); } return "0.0.0.0"; } void USocketClientBPLibrary::connectSocketClientTCP(FString domainOrIP, ESocketClientIPType ipType, int32 port, EReceiveFilterClient receiveFilters, ESocketClientTCPSeparator messageSeparator, FString optionalCustomConnectionID, FString& connectionID, bool disableNaglesAlgorithm){ USocketClientBPLibrary::getSocketClientTarget()->connectSocketClientTCPNonStatic(domainOrIP, ipType, port, receiveFilters, messageSeparator,optionalCustomConnectionID, connectionID, nullptr,disableNaglesAlgorithm); } void USocketClientBPLibrary::connectSocketClientTCPNonStatic(FString domain, ESocketClientIPType ipType, int32 port, EReceiveFilterClient receiveFilter, ESocketClientTCPSeparator messageSeparator, FString optionalCustomConnectionID, FString& connectionID, UTCPConnectAsyncNode* tcpConnectAsyncNode, bool noPacketDelay) { USocketClientTCPClient* tcpClient = NewObject(USocketClientTCPClient::StaticClass()); if (optionalCustomConnectionID.IsEmpty()) { connectionID = FGuid::NewGuid().ToString(); } else { connectionID = optionalCustomConnectionID; if (tcpClients.Find(connectionID) != nullptr) { FString serverMessage = "An existing connection with this ID was found. Connection establishment was aborted"; UE_LOG(LogTemp, Warning, TEXT("An existing connection with this ID was found. Connection establishment was aborted. %s"), *connectionID); onsocketClientTCPConnectionEventDelegate.Broadcast(false, serverMessage, connectionID); tcpClient->onsocketClientTCPConnectionEventDelegate.Broadcast(false, serverMessage, connectionID); if (tcpConnectAsyncNode != nullptr) { tcpConnectAsyncNode->triggerConnectionEvent(false, connectionID, serverMessage); } return; } } tcpClients.Add(connectionID, tcpClient); tcpClient->connect(this, domain, ipType, port, receiveFilter, messageSeparator, connectionID,tcpConnectAsyncNode, noPacketDelay, false); } void USocketClientBPLibrary::socketClientSendTCP(FString connectionID, FString message, TArray byteArray, bool addLineBreak){ USocketClientBPLibrary::getSocketClientTarget()->socketClientSendTCPNonStatic(connectionID, message, byteArray, addLineBreak); } void USocketClientBPLibrary::socketClientSendTCPNonStatic(FString connectionID,FString message, TArray byteArray, bool addLineBreak) { if (connectionID.IsEmpty() || tcpClients.Find(connectionID) == nullptr) { //don't send to many error messages. one second = 10000000 ticks if (((FDateTime::Now().GetTicks()) - lastErrorMessageTime) >= 10000000) { UE_LOG(LogTemp, Error, TEXT("Connection not found (socketClientSendTCPMessage). %s"), *connectionID); lastErrorMessageTime = FDateTime::Now().GetTicks(); } return; } if (message.Len() > 0) { if (addLineBreak) { message.Append("\r\n"); } } USocketClientTCPClient* tcpClient = *tcpClients.Find(connectionID); tcpClient->sendMessage(message, byteArray); } void USocketClientBPLibrary::socketClientSendFileOverTCP(FString& connectionID, FString domainOrIP, ESocketClientIPType ipType, int32 port, EFileFunctionsSocketClientDirectoryType directoryType, FString filePath, FString token, FString Aes256bitKey){ USocketClientBPLibrary::getSocketClientTarget()->socketClientSendFileOverTCPNonStatic(connectionID, domainOrIP, ipType, port, directoryType, filePath, token, Aes256bitKey); } void USocketClientBPLibrary::socketClientSendFileOverTCPNonStatic(FString& connectionID, FString domainOrIP, ESocketClientIPType ipType, int32 port, EFileFunctionsSocketClientDirectoryType directoryType, FString filePath, FString token, FString Aes256bitKey){ USocketClientTCPClient* tcpClient = NewObject(USocketClientTCPClient::StaticClass()); connectionID = FGuid::NewGuid().ToString(); tcpClients.Add(connectionID, tcpClient); tcpClient->sendFile(this, connectionID, domainOrIP, ipType, port, directoryType, filePath, token, Aes256bitKey); } void USocketClientBPLibrary::socketClientRequestFileOverTCP(FString& connectionID, FString domainOrIP, ESocketClientIPType ipType, int32 port, EFileFunctionsSocketClientDirectoryType directoryType, FString downloadDirectory, bool resume, FString token, FString Aes256bitKey){ USocketClientBPLibrary::getSocketClientTarget()->socketClientRequestFileOverTCPNonStatic(connectionID, domainOrIP, ipType, port, directoryType, downloadDirectory, resume, token, Aes256bitKey); } void USocketClientBPLibrary::socketClientRequestFileOverTCPNonStatic(FString& connectionID, FString domainOrIP, ESocketClientIPType ipType, int32 port, EFileFunctionsSocketClientDirectoryType directoryType, FString downloadDirectory, bool resume, FString token, FString Aes256bitKey) { USocketClientTCPClient* tcpClient = NewObject(USocketClientTCPClient::StaticClass()); connectionID = FGuid::NewGuid().ToString(); tcpClients.Add(connectionID, tcpClient); tcpClient->requestFile(this, connectionID, domainOrIP, ipType, port, directoryType, downloadDirectory, resume,token, Aes256bitKey); } void USocketClientBPLibrary::closeSocketClientConnectionTCP(FString connectionID){ USocketClientBPLibrary::getSocketClientTarget()->closeSocketClientConnectionTCPNonStatic(connectionID); } void USocketClientBPLibrary::closeSocketClientConnectionTCPNonStatic(FString connectionID){ if (connectionID.IsEmpty()) { return; } if (tcpClients.Find(connectionID) == nullptr) { UE_LOG(LogTemp, Error, TEXT("Connection not found (closeSocketClientTCPConnection). %s"), *connectionID); return; } USocketClientTCPClient* tcpClient = *tcpClients.Find(connectionID); if (tcpClient != nullptr) { if (tcpClient->isRun()) { tcpClient->closeConnection(); } } tcpClients.Remove(connectionID); tcpClient = nullptr; } void USocketClientBPLibrary::closeAllSocketClientConnectionsTCP(){ USocketClientBPLibrary::getSocketClientTarget()->closeAllSocketClientConnectionsTCPNonStatic(); } void USocketClientBPLibrary::closeAllSocketClientConnectionsTCPNonStatic(){ TArray tmpArray; tcpClients.GetKeys(tmpArray); for (int32 i = 0; i < tmpArray.Num(); i++){ closeSocketClientConnectionTCPNonStatic(tmpArray[i]); } } void USocketClientBPLibrary::getTCPConnectionByConnectionID(FString connectionID, bool& found, USocketClientTCPClient*& connection){ USocketClientBPLibrary::getSocketClientTarget()->getTCPConnectionByConnectionIDNonStatic(connectionID, found, connection); } void USocketClientBPLibrary::getTCPConnectionByConnectionIDNonStatic(FString connectionID, bool& found, USocketClientTCPClient* &connection){ if (connectionID.IsEmpty() || tcpClients.Find(connectionID) == nullptr) { found = false; connection = nullptr; return; } found = true; connection = *tcpClients.Find(connectionID); } bool USocketClientBPLibrary::isTCPConnected(FString connectionID){ return USocketClientBPLibrary::getSocketClientTarget()->isTCPConnectedNonStatic(connectionID); } bool USocketClientBPLibrary::isTCPConnectedNonStatic(FString connectionID){ if (connectionID.IsEmpty() || tcpClients.Find(connectionID) == nullptr) { return false; } USocketClientTCPClient* tcpClient = *tcpClients.Find(connectionID); if (tcpClient->isRun() && tcpClient->isConnected()) { return true; } return false; } void USocketClientBPLibrary::socketClientInitUDPReceiver(FString& connectionID, FString domainOrIP, ESocketClientIPType ipType, int32 port, EReceiveFilterClient receiveFilter, int32 maxPacketSize){ USocketClientBPLibrary::getSocketClientTarget()->socketClientInitUDPReceiverNonStatic(connectionID,nullptr, domainOrIP, ipType, port, receiveFilter, maxPacketSize); } void USocketClientBPLibrary::socketClientInitUDPReceiverNonStatic(FString& connectionID, UUDPInitAsyncNode* udpInitAsyncNode, FString domain, ESocketClientIPType ipType, int32 port, EReceiveFilterClient receiveFilter, int32 maxPacketSize) { FString key = domain + FString::FromInt(port); if (udpClients.Find(key) != nullptr) { USocketClientUDP* udpClient = *udpClients.Find(key); connectionID = udpClient->getConnectionID(); FString info = "Connection already present:" + domain + ":" + FString::FromInt(port); onsocketClientUDPConnectionEventDelegate.Broadcast(true,info , connectionID); if (udpInitAsyncNode != nullptr) { udpInitAsyncNode->triggerInitEvent(true, connectionID, info); } return; } USocketClientUDP* udpClient = NewObject(USocketClientUDP::StaticClass()); connectionID = FGuid::NewGuid().ToString(); udpClients.Add(connectionID, udpClient); udpClients.Add(key, udpClient); udpClient->init(this, udpInitAsyncNode, domain, ipType, port, receiveFilter, connectionID, maxPacketSize); } void USocketClientBPLibrary::socketClientSendUDP(FString domainOrIP, ESocketClientIPType ipType, int32 port, FString message, TArray byteArray, bool addLineBreak, FString connectionID){ USocketClientBPLibrary::getSocketClientTarget()->socketClientSendUDPNonStatic(domainOrIP, ipType, port, message, byteArray, addLineBreak, connectionID); } void USocketClientBPLibrary::socketClientSendUDPNonStatic(FString domain, ESocketClientIPType ipType, int32 port, FString message, TArray byteArray, bool addLineBreak, FString clientConnectionIDP) { if (clientConnectionIDP.IsEmpty() || udpClients.Find(clientConnectionIDP) == nullptr) { //don't send to many error messages. one second = 10000000 ticks if (((FDateTime::Now().GetTicks()) - lastErrorMessageTime) >= 10000000) { UE_LOG(LogTemp, Error, TEXT("Connection not found (socketClientSendUDPMessage). %s"), *clientConnectionIDP); lastErrorMessageTime = FDateTime::Now().GetTicks(); } return; } if (message.Len() > 0 && addLineBreak) { message.Append("\r\n"); } USocketClientUDP* udpClient = *udpClients.Find(clientConnectionIDP); udpClient->sendUDPMessage(domain, ipType, port, message, byteArray); } void USocketClientBPLibrary::closeSocketClientConnectionUDP(FString connectionID){ USocketClientBPLibrary::getSocketClientTarget()->closeSocketClientConnectionUDPNonStatic(connectionID); } void USocketClientBPLibrary::closeSocketClientConnectionUDPNonStatic(FString connectionID) { if (connectionID.IsEmpty()) { return; } if (udpClients.Find(connectionID) == nullptr) { UE_LOG(LogTemp, Warning, TEXT("Connection not found (closeSocketClientUDPConnection). %s"), *connectionID); return; } USocketClientUDP* udpClient = *udpClients.Find(connectionID); udpClient->closeUDPConnection(); udpClients.Remove(connectionID); FString key = udpClient->getDomainOrIP() + FString::FromInt(udpClient->getPort()); udpClients.Remove(key); udpClient = nullptr; } void USocketClientBPLibrary::getUDPInitializationByConnectionID(FString connectionID, bool& found, USocketClientUDP*& connection){ USocketClientBPLibrary::getSocketClientTarget()->getUDPInitializationByConnectionIDNonStatic(connectionID, found, connection); } void USocketClientBPLibrary::getUDPInitializationByConnectionIDNonStatic(FString connectionID, bool& found, USocketClientUDP*& connection){ if (connectionID.IsEmpty() || udpClients.Find(connectionID) == nullptr) { found = false; connection = nullptr; return; } found = true; connection = *udpClients.Find(connectionID); } bool USocketClientBPLibrary::isUDPInitialized(FString connectionID){ return USocketClientBPLibrary::getSocketClientTarget()->isUDPInitializedNonStatic(connectionID); } bool USocketClientBPLibrary::isUDPInitializedNonStatic(FString connectionID){ if (connectionID.IsEmpty() || udpClients.Find(connectionID) == nullptr) { return false; } return (*udpClients.Find(connectionID))->isRun(); } void USocketClientBPLibrary::changeSocketPlatform(ESocketPlatformClient platform) { USocketClientBPLibrary::getSocketClientTarget()->systemSocketPlatform = platform; } FString USocketClientBPLibrary::resolveDomain(FString serverDomainP, ESocketClientIPType ipType) { FString* cachedDomainPointer = domainCache.Find(serverDomainP); if (cachedDomainPointer != nullptr) { return *cachedDomainPointer; } //is IPv4? if (ipType == ESocketClientIPType::E_ipv4) { TArray ipNumbers; int32 lineCount = serverDomainP.ParseIntoArray(ipNumbers, TEXT("."), true); if (lineCount == 4 && serverDomainP.Len() <= 15 && serverDomainP.Len() >= 7) { domainCache.Add(serverDomainP, serverDomainP); return serverDomainP; } } //is IPv6? Just a simple check if (ipType == ESocketClientIPType::E_ipv6) { TArray ipNumbers; int32 lineCount = serverDomainP.ParseIntoArray(ipNumbers, TEXT(":"), true); if (lineCount >= 2) { domainCache.Add(serverDomainP, serverDomainP); return serverDomainP; } } //resolve Domain ISocketSubsystem* sSS = USocketClientBPLibrary::getSocketSubSystem(); FResolveInfo* ResolveInfo = sSS->GetHostByName(TCHAR_TO_ANSI(*serverDomainP)); while (!ResolveInfo->IsComplete()); int32 errorCode = ResolveInfo->GetErrorCode(); if (errorCode == 0) { const FInternetAddr* Addr = &ResolveInfo->GetResolvedAddress(); uint32 OutIP = 0; FString adr = Addr->ToString(false); domainCache.Add(serverDomainP, adr); return adr; } else { if (dnsClient == nullptr) dnsClient = NewObject(UDNSClientSocketClient::StaticClass()); dnsClient->resolveDomain(sSS, serverDomainP); int32 timeout = 1000; while (dnsClient->isResloving() && timeout > 0) { timeout -= 10; FPlatformProcess::Sleep(0.01); } FString adr = dnsClient->getIP(); domainCache.Add(serverDomainP, adr); return adr; } return serverDomainP; } void USocketClientBPLibrary::cleanConnection(FSocketClientPluginSession& session){ socketClientCleanerThread->addSession(session); } void USocketClientBPLibrary::changeCleanerThreadSettingsOnClient(bool showLogs, int32 minLiveTimeInSeconds){ if (USocketClientBPLibrary::getSocketClientTarget()->socketClientCleanerThread != nullptr) { USocketClientBPLibrary::getSocketClientTarget()->socketClientCleanerThread->changeSettings(showLogs, minLiveTimeInSeconds); } } void USocketClientBPLibrary::getSystemType(ESocketClientSystem& system) { #if PLATFORM_ANDROID system = ESocketClientSystem::Android; return; #endif #if PLATFORM_IOS system = ESocketClientSystem::IOS; return; #endif #if PLATFORM_WINDOWS system = ESocketClientSystem::Windows; return; #endif #if PLATFORM_LINUX system = ESocketClientSystem::Linux; return; #endif #if PLATFORM_MAC system = ESocketClientSystem::Mac; return; #endif } TArray USocketClientBPLibrary::parseHexToBytes(FString hex) { TArray bytes; if (hex.Contains(" ")) { hex = hex.Replace(TEXT(" "), TEXT("")); } if (hex.Len() % 2 != 0) { UE_LOG(LogTemp, Error, TEXT("This is not a valid hex string: %s"), *hex); return bytes; } TArray charArray = hex.GetCharArray(); for (int32 i = 0; i < (charArray.Num() - 1); i++) { if (CheckTCharIsHex(charArray[i]) == false) { UE_LOG(LogTemp, Error, TEXT("This is not a valid hex string: %s"), *hex); return bytes; } } bytes.AddZeroed(hex.Len() / 2); HexToBytes(hex, bytes.GetData()); return bytes; } FString USocketClientBPLibrary::parseHexToString(FString hex) { TArray bytes = parseHexToBytes(hex); bytes.Add(0x00);// null-terminator char* Data = (char*)bytes.GetData(); return FString(UTF8_TO_TCHAR(Data)); } FString USocketClientBPLibrary::parseBytesToHex(TArray bytes) { FString hex; hex = BytesToHex(bytes.GetData(), bytes.Num()); return hex; } TArray USocketClientBPLibrary::parseHexToBytesPure(FString hex) { return parseHexToBytes(hex); } FString USocketClientBPLibrary::parseHexToStringPure(FString hex) { return parseHexToString(hex); } FString USocketClientBPLibrary::parseBytesToHexPure(TArray bytes) { return parseBytesToHex(bytes); } void USocketClientBPLibrary::parseBytesToFloat(TArray bytes, float& value) { if (bytes.Num() != 4) { UE_LOG(LogTemp, Error, TEXT("ParseBytesToFloat: Cannot convert bytes to float. Array must contain 4 bytes but has %i bytes."), bytes.Num()); return; } FMemory::Memcpy(&value, bytes.GetData(), 4); } void USocketClientBPLibrary::parseBytesToInteger(TArray bytes, int32& value) { if (bytes.Num() != 4) { UE_LOG(LogTemp, Error, TEXT("ParseBytesToInteger: Cannot convert bytes to integer. Array must contain 4 bytes but has %i bytes."), bytes.Num()); return; } FMemory::Memcpy(&value, bytes.GetData(), 4); } void USocketClientBPLibrary::parseBytesToInteger64(TArray bytes, int64& value) { if (bytes.Num() != 8) { UE_LOG(LogTemp, Error, TEXT("ParseBytesToInteger64: Cannot convert bytes to integer. Array must contain 8 bytes but has %i bytes."), bytes.Num()); return; } FMemory::Memcpy(&value, bytes.GetData(), 8); } void USocketClientBPLibrary::parseBytesToFloatPure(TArray bytes, float& value){ parseBytesToFloat(bytes, value); } void USocketClientBPLibrary::parseBytesToIntegerPure(TArray bytes, int32& value){ parseBytesToInteger(bytes, value); } void USocketClientBPLibrary::parseBytesToInteger64Pure(TArray bytes, int64& value){ parseBytesToInteger64(bytes, value); } void USocketClientBPLibrary::parseBytesToFloatEndian(TArray bytes, float& littleEndian, float& bigEndian) { littleEndian = 0.f; bigEndian = 0.f; if (bytes.Num() != 4) { UE_LOG(LogTemp, Error, TEXT("ParseBytesToFloat: Cannot convert bytes to float. Array must contain 4 bytes but has %i bytes."), bytes.Num()); return; } uint8 littleEndianChar[] = { bytes[0], bytes[1], bytes[2], bytes[3] }; FMemory::Memcpy(&littleEndian, &littleEndianChar, sizeof(littleEndian)); uint8 bigEndianChar[] = { bytes[3], bytes[2], bytes[1], bytes[0] }; FMemory::Memcpy(&bigEndian, &bigEndianChar, sizeof(bigEndian)); } void USocketClientBPLibrary::parseBytesToIntegerEndian(TArray bytes, int32& littleEndian, int32& bigEndian){ littleEndian = 0; bigEndian = 0; if (bytes.Num() != 4){ UE_LOG(LogTemp, Error, TEXT("ParseBytesToInteger: Cannot convert bytes to integer. Array must contain 4 bytes but has %i bytes."), bytes.Num()); return; } uint8 littleEndianChar[] = { bytes[0], bytes[1], bytes[2], bytes[3] }; FMemory::Memcpy(&littleEndian, &littleEndianChar, sizeof(littleEndian)); uint8 bigEndianChar[] = { bytes[3], bytes[2], bytes[1], bytes[0] }; FMemory::Memcpy(&bigEndian, &bigEndianChar, sizeof(bigEndian)); } void USocketClientBPLibrary::parseBytesToInteger64Endian(TArray bytes, int64& littleEndian, int64& bigEndian) { littleEndian = 0; bigEndian = 0; if (bytes.Num() != 8) { UE_LOG(LogTemp, Error, TEXT("ParseBytesToInteger64: Cannot convert bytes to integer. Array must contain 8 bytes but has %i bytes."), bytes.Num()); return; }return; uint8 littleEndianChar[] = { bytes[0], bytes[1], bytes[2], bytes[3],bytes[4], bytes[5], bytes[6], bytes[7] }; FMemory::Memcpy(&littleEndian, &littleEndianChar, sizeof(littleEndian)); uint8 bigEndianChar[] = { bytes[7], bytes[6], bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0] }; FMemory::Memcpy(&bigEndian, &bigEndianChar, sizeof(bigEndian)); } void USocketClientBPLibrary::parseFloatToBytes(TArray& byteArray, float value, bool switchByteOrder){ union { float tmpVal; uint8 tmpArray[4]; } u; u.tmpVal = value; byteArray.AddUninitialized(4); FMemory::Memcpy(byteArray.GetData(), u.tmpArray, 4); if (switchByteOrder) { byteArray.SwapMemory(3, 0); byteArray.SwapMemory(2, 1); } } void USocketClientBPLibrary::parseIntegerToBytes(TArray& byteArray, int32 value, bool switchByteOrder){ union { int32 tmpVal; uint8 tmpArray[4]; } u; u.tmpVal = value; byteArray.AddUninitialized(4); FMemory::Memcpy(byteArray.GetData(), u.tmpArray, 4); if (switchByteOrder) { byteArray.SwapMemory(3, 0); byteArray.SwapMemory(2, 1); } } void USocketClientBPLibrary::parseInteger64ToBytes(TArray& byteArray, int64 value, bool switchByteOrder){ union { int64 tmpVal; uint8 tmpArray[8]; } u; u.tmpVal = value; byteArray.AddUninitialized(8); FMemory::Memcpy(byteArray.GetData(), u.tmpArray, 8); if (switchByteOrder) { byteArray.SwapMemory(7, 0); byteArray.SwapMemory(6, 1); byteArray.SwapMemory(5, 2); byteArray.SwapMemory(4, 3); } } void USocketClientBPLibrary::parseFloatToBytesPure(TArray& byteArray, float value, bool switchByteOrder){ parseFloatToBytes(byteArray, value, switchByteOrder); } void USocketClientBPLibrary::parseIntegerToBytesPure(TArray& byteArray, int32 value, bool switchByteOrder){ parseIntegerToBytes(byteArray, value, switchByteOrder); } void USocketClientBPLibrary::parseInteger64ToBytesPure(TArray& byteArray, int64 value, bool switchByteOrder){ parseInteger64ToBytes(byteArray, value, switchByteOrder); } void USocketClientBPLibrary::parseBytesToFloatArrayPure(TArray& value, TArray bytes) { if (bytes.Num() == 0 && bytes.Num() % 4 != 0) return; value.Empty(); value.AddUninitialized(bytes.Num() / 4); FMemory::Memcpy(value.GetData(), bytes.GetData(), bytes.Num()); } void USocketClientBPLibrary::parseBytesToIntegerArrayPure(TArray& value, TArray bytes) { if (bytes.Num() == 0 && bytes.Num() % 4 != 0) return; value.Empty(); value.AddUninitialized(bytes.Num() / 4); FMemory::Memcpy(value.GetData(), bytes.GetData(), bytes.Num()); } void USocketClientBPLibrary::parseBytesToInteger64ArrayPure(TArray& value, TArray bytes) { if (bytes.Num() == 0 && bytes.Num() % 8 != 0) return; value.Empty(); value.AddUninitialized(bytes.Num() / 8); FMemory::Memcpy(value.GetData(), bytes.GetData(), bytes.Num()); } void USocketClientBPLibrary::parseFloatArrayToBytesPure(TArray& byteArray, TArray value) { byteArray.Empty(); byteArray.AddUninitialized(value.Num() * 4); FMemory::Memcpy(byteArray.GetData(), value.GetData(), value.Num() * 4); } void USocketClientBPLibrary::parseIntegerArrayToBytesPure(TArray& byteArray, TArray value) { byteArray.Empty(); byteArray.AddUninitialized(value.Num() * 4); FMemory::Memcpy(byteArray.GetData(), value.GetData(), value.Num() * 4); } void USocketClientBPLibrary::parseInteger64ArrayToBytesPure(TArray& byteArray, TArray value) { byteArray.Empty(); byteArray.AddUninitialized(value.Num() * 8); FMemory::Memcpy(byteArray.GetData(), value.GetData(), value.Num() * 8); } void USocketClientBPLibrary::changeTCPSeparatorStringOnClient(FString separator) { USocketClientBPLibrary::getSocketClientTarget()->changeTCPSeparatorStringOnClientNonStatic(separator); } void USocketClientBPLibrary::changeTCPSeparatorStringOnClientNonStatic(FString separator) { tcpStringSeparator = separator; } void USocketClientBPLibrary::changeTCPSeparatorByteOnClient(uint8 separator) { USocketClientBPLibrary::getSocketClientTarget()->changeTCPSeparatorByteOnClientNonStatic(separator); } void USocketClientBPLibrary::changeTCPSeparatorByteOnClientNonStatic(uint8 separator) { tcpByteSeparator = separator; } int32 USocketClientBPLibrary::getUniquePlayerID(APlayerController* playerController) { if (playerController == nullptr || playerController->GetLocalPlayer() == nullptr) return 0; return playerController->GetLocalPlayer()->GetUniqueID(); } FString USocketClientBPLibrary::getRandomID(){ return FGuid::NewGuid().ToString(); } void USocketClientBPLibrary::getTcpSeparator(uint8& byteSeparator, FString& stringSeparator){ stringSeparator = tcpStringSeparator; byteSeparator = tcpByteSeparator; } ISocketSubsystem* USocketClientBPLibrary::getSocketSubSystem() { switch (USocketClientBPLibrary::getSocketClientTarget()->systemSocketPlatform) { case ESocketPlatformClient::E_SSC_SYSTEM: return ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM); case ESocketPlatformClient::E_SSC_WINDOWS: return ISocketSubsystem::Get(FName(TEXT("WINDOWS"))); case ESocketPlatformClient::E_SSC_MAC: return ISocketSubsystem::Get(FName(TEXT("MAC"))); case ESocketPlatformClient::E_SSC_IOS: return ISocketSubsystem::Get(FName(TEXT("IOS"))); case ESocketPlatformClient::E_SSC_UNIX: return ISocketSubsystem::Get(FName(TEXT("UNIX"))); case ESocketPlatformClient::E_SSC_ANDROID: return ISocketSubsystem::Get(FName(TEXT("ANDROID"))); case ESocketPlatformClient::E_SSC_PS4: return ISocketSubsystem::Get(FName(TEXT("PS4"))); case ESocketPlatformClient::E_SSC_XBOXONE: return ISocketSubsystem::Get(FName(TEXT("XBOXONE"))); case ESocketPlatformClient::E_SSC_HTML5: return ISocketSubsystem::Get(FName(TEXT("HTML5"))); case ESocketPlatformClient::E_SSC_SWITCH: return ISocketSubsystem::Get(FName(TEXT("SWITCH"))); case ESocketPlatformClient::E_SSC_DEFAULT: return ISocketSubsystem::Get(); default: return ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM); } }