High Level API - Fully Functional
This commit is contained in:
154
HLAPI/HLAPI/HLAPI.vcxproj
Normal file
154
HLAPI/HLAPI/HLAPI.vcxproj
Normal file
@ -0,0 +1,154 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\include\HLAPI\BitConverter.hpp" />
|
||||
<ClInclude Include="..\..\include\HLAPI\DataReceivedEvent.hpp" />
|
||||
<ClInclude Include="..\..\include\HLAPI\DisconnectedEvent.hpp" />
|
||||
<ClInclude Include="..\..\include\HLAPI\InternalTags.hpp" />
|
||||
<ClInclude Include="..\..\include\HLAPI\MessageQueue.hpp" />
|
||||
<ClInclude Include="..\..\include\HLAPI\NetworkHeader.hpp" />
|
||||
<ClInclude Include="..\..\include\HLAPI\NetworkMessage.hpp" />
|
||||
<ClInclude Include="..\..\include\HLAPI\NewConnectionEvent.hpp" />
|
||||
<ClInclude Include="..\..\include\HLAPI\Server.hpp" />
|
||||
<ClInclude Include="..\..\include\HLAPI\TcpConnection.hpp" />
|
||||
<ClInclude Include="..\..\include\HLAPI\TcpConnectionHandler.hpp" />
|
||||
<ClInclude Include="..\..\include\HLAPI\TcpServer.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\HLAPI\main.cpp" />
|
||||
<ClCompile Include="..\..\src\HLAPI\MessageQueue.cpp" />
|
||||
<ClCompile Include="..\..\src\HLAPI\NetworkMessage.cpp" />
|
||||
<ClCompile Include="..\..\src\HLAPI\Server.cpp" />
|
||||
<ClCompile Include="..\..\src\HLAPI\TcpConnection.cpp" />
|
||||
<ClCompile Include="..\..\src\HLAPI\TcpConnectionHandler.cpp" />
|
||||
<ClCompile Include="..\..\src\HLAPI\TcpServer.cpp" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{989D0F55-C4B9-44D2-AD2B-DD7E1AAABFC1}</ProjectGuid>
|
||||
<RootNamespace>HLAPI</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>D:\VoidNet\include\HLAPI;D:\VoidNet\include</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalDependencies>D:\VoidNet\VoidNetVS\x64\Debug\VoidNetVS.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
72
HLAPI/HLAPI/HLAPI.vcxproj.filters
Normal file
72
HLAPI/HLAPI/HLAPI.vcxproj.filters
Normal file
@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="include">
|
||||
<UniqueIdentifier>{a941a71f-2121-4d2f-87f9-58bcadbeb98b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="src">
|
||||
<UniqueIdentifier>{1c087ed8-3cca-4254-836f-10fb70fda154}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\include\HLAPI\BitConverter.hpp">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\HLAPI\DataReceivedEvent.hpp">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\HLAPI\DisconnectedEvent.hpp">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\HLAPI\InternalTags.hpp">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\HLAPI\MessageQueue.hpp">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\HLAPI\NetworkHeader.hpp">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\HLAPI\NetworkMessage.hpp">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\HLAPI\NewConnectionEvent.hpp">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\HLAPI\Server.hpp">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\HLAPI\TcpConnection.hpp">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\HLAPI\TcpConnectionHandler.hpp">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\HLAPI\TcpServer.hpp">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\HLAPI\main.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\HLAPI\MessageQueue.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\HLAPI\NetworkMessage.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\HLAPI\Server.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\HLAPI\TcpConnection.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\HLAPI\TcpConnectionHandler.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\HLAPI\TcpServer.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -1,4 +1,4 @@
|
||||
#include "Utility.hpp"
|
||||
#include "Util.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25123.0
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29326.143
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VoidNetVS", "VoidNetVS\VoidNetVS.vcxproj", "{5172321E-CCB0-4A77-9F3D-FAAF0084F434}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tests", "..\TestsVS\Tests\Tests.vcxproj", "{41663B22-3949-4570-9AB5-309363EAD56F}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HLAPI", "..\HLAPI\HLAPI\HLAPI.vcxproj", "{989D0F55-C4B9-44D2-AD2B-DD7E1AAABFC1}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
@ -31,8 +33,19 @@ Global
|
||||
{41663B22-3949-4570-9AB5-309363EAD56F}.Release|x64.Build.0 = Release|x64
|
||||
{41663B22-3949-4570-9AB5-309363EAD56F}.Release|x86.ActiveCfg = Release|Win32
|
||||
{41663B22-3949-4570-9AB5-309363EAD56F}.Release|x86.Build.0 = Release|Win32
|
||||
{989D0F55-C4B9-44D2-AD2B-DD7E1AAABFC1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{989D0F55-C4B9-44D2-AD2B-DD7E1AAABFC1}.Debug|x64.Build.0 = Debug|x64
|
||||
{989D0F55-C4B9-44D2-AD2B-DD7E1AAABFC1}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{989D0F55-C4B9-44D2-AD2B-DD7E1AAABFC1}.Debug|x86.Build.0 = Debug|Win32
|
||||
{989D0F55-C4B9-44D2-AD2B-DD7E1AAABFC1}.Release|x64.ActiveCfg = Release|x64
|
||||
{989D0F55-C4B9-44D2-AD2B-DD7E1AAABFC1}.Release|x64.Build.0 = Release|x64
|
||||
{989D0F55-C4B9-44D2-AD2B-DD7E1AAABFC1}.Release|x86.ActiveCfg = Release|Win32
|
||||
{989D0F55-C4B9-44D2-AD2B-DD7E1AAABFC1}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {30B0A8A0-814A-40F1-99DB-799D6ABB368C}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@ -124,7 +124,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<PreprocessorDefinitions>_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
33
include/HLAPI/BitConverter.hpp
Normal file
33
include/HLAPI/BitConverter.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
// i want to use bitshifting but i red in stackoverflow that casting doesnt generate overhead
|
||||
// now ive hit a wall
|
||||
// casting vs bitshifting
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
namespace std
|
||||
{
|
||||
class BitConverter
|
||||
{
|
||||
public:
|
||||
template<typename T>
|
||||
inline static uint8_t *ToBytes(T value)
|
||||
{
|
||||
uint8_t *data = new uint8_t[sizeof(T)]();
|
||||
memcpy(data, &value, sizeof(T));
|
||||
return data;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline static T FromBytes(uint8_t *data)
|
||||
{
|
||||
if (!data)
|
||||
throw std::invalid_argument("cant have null parameter -> BitConverter::FromBytes");
|
||||
T value;
|
||||
memcpy(&value, data, sizeof(T));
|
||||
return value;
|
||||
}
|
||||
};
|
||||
}
|
||||
27
include/HLAPI/DataReceivedEvent.hpp
Normal file
27
include/HLAPI/DataReceivedEvent.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include "NetworkMessage.hpp"
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
class DataReceivedEvent
|
||||
{
|
||||
public:
|
||||
inline DataReceivedEvent(const NetworkMessage &msg)
|
||||
{
|
||||
SenderID = msg.GetSenderID();
|
||||
DistributionMode = msg.GetDistributionMode();
|
||||
DestinationID = msg.GetDestinationID();
|
||||
Tag = msg.GetTag();
|
||||
Data = msg.GetData<void>();
|
||||
}
|
||||
|
||||
public:
|
||||
uint32_t SenderID;
|
||||
DistributionMode DistributionMode;
|
||||
uint32_t DestinationID;
|
||||
uint32_t Tag;
|
||||
|
||||
void *Data;
|
||||
};
|
||||
}
|
||||
36
include/HLAPI/DisconnectedEvent.hpp
Normal file
36
include/HLAPI/DisconnectedEvent.hpp
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
class DisconnectedEvent // can be processed by client and server
|
||||
{
|
||||
private:
|
||||
DisconnectedEvent();
|
||||
|
||||
public:
|
||||
inline DisconnectedEvent(uint32_t id, char *reason, int32_t reason_id)
|
||||
: m_reason(reason)
|
||||
, m_clientID(id)
|
||||
, m_reasonID(reason_id)
|
||||
{
|
||||
}
|
||||
|
||||
inline DisconnectedEvent(uint32_t id, const std::string &reason, int32_t reason_id)
|
||||
: m_reason(reason)
|
||||
, m_clientID(id)
|
||||
, m_reasonID(reason_id)
|
||||
{
|
||||
}
|
||||
|
||||
inline const std::string &GetReason() const { return m_reason; }
|
||||
inline int32_t GetReasonID() const { return m_reasonID; }
|
||||
inline uint32_t GetID() const { return m_clientID; }
|
||||
|
||||
private:
|
||||
std::string m_reason;
|
||||
int32_t m_reasonID;
|
||||
uint32_t m_clientID;
|
||||
};
|
||||
}
|
||||
10
include/HLAPI/InternalTags.hpp
Normal file
10
include/HLAPI/InternalTags.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum class InternalTags : uint32_t
|
||||
{
|
||||
Disconnect = 0xFFFFFFFF,
|
||||
Connect = 0xFFFFFFFE,
|
||||
AssignID = 0xFFFFFFFD
|
||||
};
|
||||
43
include/HLAPI/MessageQueue.hpp
Normal file
43
include/HLAPI/MessageQueue.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <queue>
|
||||
#include <mutex>
|
||||
|
||||
#include "NetworkMessage.hpp"
|
||||
|
||||
#include "NewConnectionEvent.hpp"
|
||||
#include "DisconnectedEvent.hpp"
|
||||
#include "DataReceivedEvent.hpp"
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
class MessageQueue
|
||||
{
|
||||
public:
|
||||
MessageQueue()
|
||||
{
|
||||
}
|
||||
|
||||
void EnqueueMessageToSend(const NetworkMessage &msg);
|
||||
|
||||
void EnqueueMessageReceived(const NetworkMessage &msg);
|
||||
void EnqueueDisconnection(const NetworkMessage &msg);
|
||||
void EnqueueConnection(const NetworkMessage &msg);
|
||||
|
||||
NetworkMessage DequeueMessageToSend();
|
||||
|
||||
uint32_t SendSize();
|
||||
|
||||
private:
|
||||
std::deque<NetworkMessage> m_messagesToSend;
|
||||
|
||||
std::deque<NewConnectionEvent> m_connectionEvents;
|
||||
std::deque<DisconnectedEvent> m_disconnectedEvents;
|
||||
std::deque<DataReceivedEvent> m_dataReceivedEvents;
|
||||
|
||||
std::mutex m_sendMutex;
|
||||
std::mutex m_receivedMutex;
|
||||
std::mutex m_disconnectMutex;
|
||||
std::mutex m_connectionMutex;
|
||||
};
|
||||
}
|
||||
12
include/HLAPI/NetworkHeader.hpp
Normal file
12
include/HLAPI/NetworkHeader.hpp
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
class NetworkHeader
|
||||
{
|
||||
public:
|
||||
uint32_t Size;
|
||||
};
|
||||
}
|
||||
95
include/HLAPI/NetworkMessage.hpp
Normal file
95
include/HLAPI/NetworkMessage.hpp
Normal file
@ -0,0 +1,95 @@
|
||||
#pragma once
|
||||
|
||||
#include "NetworkHeader.hpp"
|
||||
#include "BitConverter.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
enum class DistributionMode : uint8_t
|
||||
{
|
||||
ID,
|
||||
Others,
|
||||
OthersAndServer,
|
||||
All,
|
||||
AllAndMe,
|
||||
Server
|
||||
};
|
||||
|
||||
class NetworkMessage
|
||||
{
|
||||
public:
|
||||
NetworkMessage()
|
||||
{
|
||||
}
|
||||
|
||||
NetworkMessage(uint32_t sender, DistributionMode mode, uint32_t destinationId, uint32_t tag, void *data, uint32_t dataSize)
|
||||
: m_senderID(sender)
|
||||
, m_distributionMode(mode)
|
||||
, m_destinationID(destinationId)
|
||||
, m_tag(tag)
|
||||
, m_data(data)
|
||||
, m_dataSize(dataSize)
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t GetSenderID() const;
|
||||
DistributionMode GetDistributionMode() const;
|
||||
uint32_t GetDestinationID() const;
|
||||
uint32_t GetTag() const;
|
||||
|
||||
private:
|
||||
uint32_t m_senderID = 0;
|
||||
DistributionMode m_distributionMode = DistributionMode::All;
|
||||
uint32_t m_destinationID = 0;
|
||||
uint32_t m_tag = 0;
|
||||
|
||||
void *m_data = 0;
|
||||
uint32_t m_dataSize = 0;
|
||||
|
||||
public:
|
||||
template<typename T>
|
||||
void SetData(T *data)
|
||||
{
|
||||
m_data = data;
|
||||
m_dataSize = sizeof(T);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
uint8_t * SerializeData(uint32_t &size)
|
||||
{
|
||||
int32_t sizeOfNetHeader = sizeof(NetworkHeader);
|
||||
|
||||
NetworkHeader header;
|
||||
header.Size = 13 + sizeOfNetHeader + sizeof(T);
|
||||
|
||||
uint8_t *bytes = new uint8_t[header.Size];
|
||||
memcpy(bytes, &header, sizeOfNetHeader);
|
||||
|
||||
uint8_t *sender = BitConverter::ToBytes<uint32_t>(m_senderID); // 4
|
||||
uint8_t *destination = BitConverter::ToBytes<uint32_t>(m_destinationID); // 4
|
||||
uint8_t *tag = BitConverter::ToBytes<uint32_t>(m_tag); // 4
|
||||
|
||||
memcpy(bytes + sizeOfNetHeader, sender, 4);
|
||||
bytes[sizeOfNetHeader + 4] = (uint8_t)m_distributionMode;
|
||||
memcpy(bytes + sizeOfNetHeader + 5, destination, 4);
|
||||
memcpy(bytes + sizeOfNetHeader + 9, tag, 4);
|
||||
|
||||
memcpy(bytes + 13 + sizeOfNetHeader, m_data, sizeof(T));
|
||||
|
||||
size = header.Size;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
uint8_t *SerializeData(uint32_t &size);
|
||||
void Deserialize(uint8_t *data, uint32_t size);
|
||||
|
||||
template<typename T>
|
||||
T *GetData() const
|
||||
{
|
||||
return (T*)m_data;
|
||||
}
|
||||
};
|
||||
}
|
||||
18
include/HLAPI/NewConnectionEvent.hpp
Normal file
18
include/HLAPI/NewConnectionEvent.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
class NewConnectionEvent
|
||||
{
|
||||
public:
|
||||
inline NewConnectionEvent(uint32_t id, void *data)
|
||||
: m_id(id)
|
||||
, m_data(data)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t m_id;
|
||||
void *m_data;
|
||||
};
|
||||
}
|
||||
26
include/HLAPI/Server.hpp
Normal file
26
include/HLAPI/Server.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <Net.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
class TcpServer;
|
||||
|
||||
class MessageQueue;
|
||||
|
||||
class Server
|
||||
{
|
||||
public:
|
||||
Server(uint32_t max_connections = 20, uint16_t port = DEFAULT_SERVER_PORT);
|
||||
|
||||
void Start();
|
||||
void Stop();
|
||||
|
||||
private:
|
||||
std::shared_ptr<std::net::TcpServer> m_tcpServer;
|
||||
|
||||
std::shared_ptr<MessageQueue> m_queue;
|
||||
};
|
||||
}
|
||||
40
include/HLAPI/TcpConnection.hpp
Normal file
40
include/HLAPI/TcpConnection.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "TcpClient.hpp"
|
||||
|
||||
#include "NetworkMessage.hpp"
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
class TcpConnection
|
||||
{
|
||||
public:
|
||||
friend class TcpConnectionHandler;
|
||||
|
||||
TcpConnection(TcpClient *client);
|
||||
|
||||
std::shared_ptr<TcpClient> GetClient();
|
||||
uint32_t GetID();
|
||||
void SetID(uint32_t id);
|
||||
|
||||
template<typename T>
|
||||
void SendMessage(DistributionMode mode, uint32_t destinationId, uint32_t tag, void *data)
|
||||
{
|
||||
NetworkMessage msg(m_id, mode, destinationId, tag, data, sizeof(T));
|
||||
}
|
||||
|
||||
void ReceiveData();
|
||||
|
||||
std::function<void(uint32_t, DistributionMode, uint32_t, uint32_t, void*)> DataReceivedEvent;
|
||||
std::function<void(uint32_t, std::string, int32_t)> DisconnectedEvent;
|
||||
std::function<void(uint32_t, void*)> NewConnectionEvent;
|
||||
|
||||
private:
|
||||
bool sendMessage(NetworkMessage &msg);
|
||||
|
||||
std::shared_ptr<TcpClient> m_client;
|
||||
uint32_t m_id;
|
||||
};
|
||||
}
|
||||
63
include/HLAPI/TcpConnectionHandler.hpp
Normal file
63
include/HLAPI/TcpConnectionHandler.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include <queue>
|
||||
|
||||
#include <TcpListener.hpp>
|
||||
#include <TcpConnection.hpp>
|
||||
|
||||
//#include <BaseLibrary/SpinMutex.hpp>
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
class MessageQueue;
|
||||
class TcpConnection;
|
||||
class Server;
|
||||
|
||||
namespace sockets
|
||||
{
|
||||
class TcpListener;
|
||||
}
|
||||
}
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
class TcpConnectionHandler
|
||||
{
|
||||
friend class std::net::Server;
|
||||
|
||||
public:
|
||||
TcpConnectionHandler(std::shared_ptr<TcpListener> listener_ptr);
|
||||
~TcpConnectionHandler();
|
||||
|
||||
void Start();
|
||||
void Stop();
|
||||
void AddClient(std::shared_ptr<TcpConnection> &c);
|
||||
void SetMaxConnections(uint32_t max_connections);
|
||||
|
||||
uint32_t GetAvailableID();
|
||||
|
||||
private:
|
||||
void HandleReceiveMsgAndConns();
|
||||
void HandleSend();
|
||||
|
||||
void HandleReceiveMsgAndConnsThreaded();
|
||||
void HandleSendThreaded();
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<TcpConnection>> m_list;
|
||||
std::mutex m_listMutex;
|
||||
|
||||
uint32_t m_maxConnections;
|
||||
|
||||
std::thread m_receiveThread;
|
||||
std::thread m_sendThread;
|
||||
|
||||
std::atomic_bool m_run;
|
||||
|
||||
std::shared_ptr<MessageQueue> m_queue;
|
||||
|
||||
std::shared_ptr<TcpListener> m_listenerPtr;
|
||||
};
|
||||
}
|
||||
31
include/HLAPI/TcpServer.hpp
Normal file
31
include/HLAPI/TcpServer.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "TcpListener.hpp"
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
class Server;
|
||||
class TcpConnectionHandler;
|
||||
|
||||
class TcpServer
|
||||
{
|
||||
friend class std::net::Server;
|
||||
|
||||
public:
|
||||
TcpServer(uint32_t max_connections, uint16_t port = DEFAULT_SERVER_PORT);
|
||||
|
||||
void Start();
|
||||
void Stop();
|
||||
|
||||
private:
|
||||
std::shared_ptr<TcpListener> listener;
|
||||
uint32_t m_maxConnections;
|
||||
uint16_t m_port;
|
||||
|
||||
std::atomic_bool m_run;
|
||||
|
||||
std::shared_ptr<std::net::TcpConnectionHandler> m_connectionHandler;
|
||||
};
|
||||
}
|
||||
52
src/HLAPI/MessageQueue.cpp
Normal file
52
src/HLAPI/MessageQueue.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
#include "MessageQueue.hpp"
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
void MessageQueue::EnqueueMessageToSend(const NetworkMessage & msg)
|
||||
{
|
||||
m_sendMutex.lock();
|
||||
m_messagesToSend.emplace_back(msg);
|
||||
m_sendMutex.unlock();
|
||||
}
|
||||
|
||||
void MessageQueue::EnqueueMessageReceived(const NetworkMessage & msg)
|
||||
{
|
||||
m_receivedMutex.lock();
|
||||
DataReceivedEvent ev(msg);
|
||||
m_dataReceivedEvents.push_back(ev);
|
||||
m_receivedMutex.unlock();
|
||||
}
|
||||
|
||||
void MessageQueue::EnqueueDisconnection(const NetworkMessage & msg)
|
||||
{
|
||||
m_disconnectMutex.lock();
|
||||
//std::unique_ptr<DisconnectedEvent> ev(((NetworkMessage)msg).GetData<DisconnectedEvent>());
|
||||
//m_disconnectedEvents.push_back(*(ev.get()));
|
||||
m_disconnectMutex.unlock();
|
||||
}
|
||||
|
||||
void MessageQueue::EnqueueConnection(const NetworkMessage & msg)
|
||||
{
|
||||
m_connectionMutex.lock();
|
||||
NewConnectionEvent ev(msg.GetSenderID(), msg.GetData<void>());
|
||||
m_connectionEvents.push_back(ev);
|
||||
m_connectionMutex.unlock();
|
||||
}
|
||||
|
||||
NetworkMessage MessageQueue::DequeueMessageToSend()
|
||||
{
|
||||
m_sendMutex.lock();
|
||||
NetworkMessage msg = m_messagesToSend.front();
|
||||
m_messagesToSend.erase(m_messagesToSend.begin() + 1);
|
||||
m_sendMutex.unlock();
|
||||
return msg;
|
||||
}
|
||||
|
||||
uint32_t MessageQueue::SendSize()
|
||||
{
|
||||
m_sendMutex.lock();
|
||||
uint32_t size = m_messagesToSend.size();
|
||||
m_sendMutex.unlock();
|
||||
return size;
|
||||
}
|
||||
}
|
||||
63
src/HLAPI/NetworkMessage.cpp
Normal file
63
src/HLAPI/NetworkMessage.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
#include "NetworkMessage.hpp"
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
uint32_t NetworkMessage::GetSenderID() const
|
||||
{
|
||||
return m_senderID;
|
||||
}
|
||||
|
||||
DistributionMode NetworkMessage::GetDistributionMode() const
|
||||
{
|
||||
return m_distributionMode;
|
||||
}
|
||||
|
||||
uint32_t NetworkMessage::GetDestinationID() const
|
||||
{
|
||||
return m_destinationID;
|
||||
}
|
||||
|
||||
uint32_t NetworkMessage::GetTag() const
|
||||
{
|
||||
return m_tag;
|
||||
}
|
||||
|
||||
uint8_t *NetworkMessage::SerializeData(uint32_t &size)
|
||||
{
|
||||
int32_t sizeOfNetHeader = sizeof(NetworkHeader);
|
||||
|
||||
NetworkHeader header;
|
||||
header.Size = 13 + sizeOfNetHeader + m_dataSize;
|
||||
|
||||
uint8_t *bytes = new uint8_t[header.Size];
|
||||
memcpy(bytes, &header, sizeOfNetHeader);
|
||||
|
||||
uint8_t *sender = BitConverter::ToBytes<uint32_t>(m_senderID); // 4
|
||||
uint8_t *destination = BitConverter::ToBytes<uint32_t>(m_destinationID); // 4
|
||||
uint8_t *tag = BitConverter::ToBytes<uint32_t>(m_tag); // 4
|
||||
|
||||
memcpy(bytes + sizeOfNetHeader, sender, 4);
|
||||
bytes[sizeOfNetHeader + 4] = (uint8_t)m_distributionMode;
|
||||
memcpy(bytes + sizeOfNetHeader + 5, destination, 4);
|
||||
memcpy(bytes + sizeOfNetHeader + 9, tag, 4);
|
||||
|
||||
memcpy(bytes + 13 + sizeOfNetHeader, m_data, m_dataSize);
|
||||
|
||||
size = header.Size;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void NetworkMessage::Deserialize(uint8_t *data, uint32_t size)
|
||||
{
|
||||
NetworkHeader buffer;
|
||||
uint32_t sizeOfNetHeader = sizeof(NetworkHeader);
|
||||
memcpy(&(buffer), data, sizeOfNetHeader);
|
||||
|
||||
memcpy(&(m_senderID), data + 4 + sizeOfNetHeader, 4);
|
||||
m_distributionMode = (DistributionMode)data[8 + sizeOfNetHeader];
|
||||
memcpy(&(m_destinationID), data + 5 + sizeOfNetHeader, 4);
|
||||
memcpy(&(m_tag), data + 9 + sizeOfNetHeader, 4);
|
||||
|
||||
m_data = data + 13 + sizeOfNetHeader;
|
||||
}
|
||||
}
|
||||
25
src/HLAPI/Server.cpp
Normal file
25
src/HLAPI/Server.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
#include "Server.hpp"
|
||||
|
||||
#include "MessageQueue.hpp"
|
||||
#include "TcpServer.hpp"
|
||||
//#include "UdpServer.hpp
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
Server::Server(uint32_t max_connections, uint16_t port)
|
||||
{
|
||||
m_tcpServer = std::make_shared<std::net::TcpServer>(max_connections, port);
|
||||
m_queue = std::make_shared<MessageQueue>();
|
||||
//m_tcpServer->m_connectionHandler->m_queue = m_queue;
|
||||
}
|
||||
|
||||
void Server::Start()
|
||||
{
|
||||
m_tcpServer->Start();
|
||||
}
|
||||
|
||||
void Server::Stop()
|
||||
{
|
||||
m_tcpServer->Stop();
|
||||
}
|
||||
}
|
||||
72
src/HLAPI/TcpConnection.cpp
Normal file
72
src/HLAPI/TcpConnection.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
#include "TcpConnection.hpp"
|
||||
|
||||
#include "InternalTags.hpp"
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
TcpConnection::TcpConnection(TcpClient * client)
|
||||
: m_client(client)
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<TcpClient> TcpConnection::GetClient()
|
||||
{
|
||||
return m_client;
|
||||
}
|
||||
|
||||
uint32_t TcpConnection::GetID()
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
void TcpConnection::SetID(uint32_t id)
|
||||
{
|
||||
m_id = id;
|
||||
}
|
||||
|
||||
bool TcpConnection::sendMessage(NetworkMessage & msg)
|
||||
{
|
||||
uint32_t size;
|
||||
uint8_t *data = msg.SerializeData(size);
|
||||
int32_t sent;
|
||||
return m_client->Send(data, size, sent);
|
||||
}
|
||||
|
||||
void TcpConnection::ReceiveData()
|
||||
{
|
||||
std::unique_ptr<uint8_t> header(new uint8_t[sizeof(NetworkHeader*)]());
|
||||
|
||||
int32_t read;
|
||||
if (!m_client->Recv(header.get(), sizeof(NetworkHeader*), read))
|
||||
return;
|
||||
|
||||
if (read == sizeof(NetworkHeader*))
|
||||
{
|
||||
std::unique_ptr<NetworkHeader> net_header((NetworkHeader*)header.get());
|
||||
|
||||
std::unique_ptr<uint8_t> buffer(new uint8_t[net_header->Size]());
|
||||
int32_t read;
|
||||
if (!m_client->Recv(buffer.get(), net_header->Size, read))
|
||||
{
|
||||
if (read != net_header->Size)
|
||||
return; // wrong message?
|
||||
|
||||
NetworkMessage msg;
|
||||
msg.Deserialize(buffer.get(), net_header->Size);
|
||||
|
||||
if (msg.GetTag() == (uint32_t)InternalTags::Disconnect)
|
||||
{
|
||||
//DisconnectedEvent(msg.m_senderID, );
|
||||
}
|
||||
else if (msg.GetTag() == (uint32_t)InternalTags::Connect)
|
||||
NewConnectionEvent(msg.GetSenderID(), msg.GetData<void>());
|
||||
else
|
||||
DataReceivedEvent(msg.GetSenderID(), msg.GetDistributionMode(), msg.GetDestinationID(), msg.GetTag(), msg.GetData<void>());
|
||||
}
|
||||
}
|
||||
else // wrong message
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
306
src/HLAPI/TcpConnectionHandler.cpp
Normal file
306
src/HLAPI/TcpConnectionHandler.cpp
Normal file
@ -0,0 +1,306 @@
|
||||
#include "TcpConnectionHandler.hpp"
|
||||
|
||||
#include "DisconnectedEvent.hpp"
|
||||
#include "NewConnectionEvent.hpp"
|
||||
#include "InternalTags.hpp"
|
||||
|
||||
#include "NetworkMessage.hpp"
|
||||
#include "MessageQueue.hpp"
|
||||
#include "TcpConnection.hpp"
|
||||
#include "TcpListener.hpp"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
TcpConnectionHandler::TcpConnectionHandler(std::shared_ptr<TcpListener> listener_ptr)
|
||||
: m_run(false)
|
||||
, m_listenerPtr(listener_ptr)
|
||||
, m_queue(new MessageQueue())
|
||||
{
|
||||
}
|
||||
|
||||
TcpConnectionHandler::~TcpConnectionHandler()
|
||||
{
|
||||
m_run.exchange(false);
|
||||
}
|
||||
|
||||
void TcpConnectionHandler::Start()
|
||||
{
|
||||
m_run.exchange(true);
|
||||
std::thread receive_thread(&TcpConnectionHandler::HandleReceiveMsgAndConnsThreaded, this);
|
||||
m_receiveThread.swap(receive_thread);
|
||||
|
||||
//std::thread send_thread(&TcpConnectionHandler::HandleSendThreaded, this);
|
||||
//m_sendThread.swap(send_thread);
|
||||
}
|
||||
|
||||
void TcpConnectionHandler::Stop()
|
||||
{
|
||||
m_run.exchange(false);
|
||||
}
|
||||
|
||||
void TcpConnectionHandler::AddClient(std::shared_ptr<TcpConnection> &c)
|
||||
{
|
||||
uint32_t id = GetAvailableID();
|
||||
if (id == -1)
|
||||
{
|
||||
// this can be handled just by the server
|
||||
// what if the server owner wants to know if a user wanted to join but couldnt
|
||||
DisconnectedEvent disconnected_event(id, "Server Full", -1);
|
||||
std::shared_ptr<TcpClient> client = c->GetClient();
|
||||
/*int32_t size = 0;
|
||||
uint8_t *buffer = disconnected_event.Serialize(size);
|
||||
int32_t sent = 0;
|
||||
client->Send(buffer, size, sent);*/
|
||||
client->Close();
|
||||
}
|
||||
|
||||
c->SetID(id);
|
||||
|
||||
uint32_t *id_ptr = &id;
|
||||
|
||||
NetworkMessage msg(0, DistributionMode::ID, id, (uint32_t)InternalTags::AssignID, id_ptr, sizeof(id_ptr));
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
|
||||
uint32_t serialized_size;
|
||||
uint8_t *serialized_data = msg.SerializeData<uint32_t>(serialized_size);
|
||||
int32_t sent;
|
||||
if (!c->GetClient()->Send(serialized_data, serialized_size, sent))
|
||||
{
|
||||
//couldnt send
|
||||
return;
|
||||
}
|
||||
|
||||
m_listMutex.lock();
|
||||
m_list.push_back(c);
|
||||
m_listMutex.unlock();
|
||||
|
||||
m_queue->EnqueueConnection(msg);
|
||||
}
|
||||
|
||||
uint32_t TcpConnectionHandler::GetAvailableID()
|
||||
{
|
||||
for (int i = 1; i <= m_maxConnections; i++)
|
||||
{
|
||||
bool flag = true;
|
||||
m_listMutex.lock();
|
||||
for (int k = 0; k < m_list.size(); k++)
|
||||
{
|
||||
if (m_list.at(k)->GetID() == i)
|
||||
flag = false;
|
||||
}
|
||||
m_listMutex.unlock();
|
||||
|
||||
if (flag)
|
||||
return i;
|
||||
}
|
||||
|
||||
//throw OutOfRangeException("Out of IDs to allocate - clients = max connections", "NewConnectionEventPool");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void TcpConnectionHandler::SetMaxConnections(uint32_t max_connections)
|
||||
{
|
||||
m_maxConnections = max_connections;
|
||||
}
|
||||
|
||||
void TcpConnectionHandler::HandleReceiveMsgAndConns()
|
||||
{
|
||||
// https://www.ibm.com/support/knowledgecenter/en/ssw_i5_54/rzab6/poll.htm
|
||||
std::vector<pollfd> poll_fds;
|
||||
pollfd master_fd;
|
||||
master_fd.fd = m_listenerPtr->m_socket->GetNativeSocket();
|
||||
master_fd.events = POLLRDNORM;
|
||||
poll_fds.emplace_back(master_fd);
|
||||
|
||||
for (size_t i = 0; i < m_list.size(); i++)
|
||||
{
|
||||
pollfd client_fd;
|
||||
client_fd.fd = m_list.at(i)->m_client->m_socket->GetNativeSocket();
|
||||
client_fd.events = POLLRDNORM;
|
||||
poll_fds.emplace_back(client_fd);
|
||||
}
|
||||
|
||||
int res = poll(poll_fds.data(), poll_fds.size(), -1);
|
||||
|
||||
if (res < 0)
|
||||
{
|
||||
//poll error
|
||||
}
|
||||
|
||||
//should never timeout because its infinite (negative)
|
||||
//if (res == 0)
|
||||
//{
|
||||
//timeout
|
||||
//}
|
||||
|
||||
for (int i = 0; i < poll_fds.size(); i++)
|
||||
{
|
||||
if (poll_fds.at(i).revents == 0)
|
||||
continue;
|
||||
|
||||
if (poll_fds[i].revents != POLLRDNORM)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (poll_fds.at(i).fd == m_listenerPtr->m_socket->GetNativeSocket())
|
||||
{
|
||||
TcpClient *c = m_listenerPtr->AcceptClient();
|
||||
if (c)
|
||||
{
|
||||
std::shared_ptr<TcpConnection> connection = std::make_shared<TcpConnection>(c);
|
||||
AddClient(connection);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // not the listening socket
|
||||
{
|
||||
SOCKET c = poll_fds.at(i).fd;
|
||||
std::unique_ptr<uint8_t> header(new uint8_t[sizeof(NetworkHeader*)]());
|
||||
|
||||
int32_t read;
|
||||
if ((read = recv(c, (char*)header.get(), sizeof(NetworkHeader*), 0)) != sizeof(NetworkHeader*))
|
||||
continue;
|
||||
|
||||
std::unique_ptr<NetworkHeader> net_header((NetworkHeader*)header.get());
|
||||
std::unique_ptr<uint8_t> buffer(new uint8_t[net_header->Size]());
|
||||
|
||||
if ((read = recv(c, (char*)buffer.get(), net_header->Size, 0)) == net_header->Size)
|
||||
{
|
||||
NetworkMessage msg;
|
||||
msg.Deserialize(buffer.get(), net_header->Size);
|
||||
|
||||
if (msg.GetTag() == (uint32_t)InternalTags::Disconnect)
|
||||
m_queue->EnqueueDisconnection(msg);
|
||||
else if (msg.GetTag() == (uint32_t)InternalTags::Connect)
|
||||
m_queue->EnqueueConnection(msg);
|
||||
else
|
||||
m_queue->EnqueueMessageReceived(msg);
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TcpConnectionHandler::HandleSend()
|
||||
{
|
||||
if (m_queue->SendSize() > 0)
|
||||
{
|
||||
NetworkMessage msg = m_queue->DequeueMessageToSend();
|
||||
|
||||
uint32_t size;
|
||||
std::unique_ptr<uint8_t> data(msg.SerializeData(size));
|
||||
|
||||
if (msg.GetDistributionMode() == DistributionMode::Others)
|
||||
{
|
||||
m_listMutex.lock();
|
||||
for (int i = 0; i < m_list.size(); i++)
|
||||
{
|
||||
std::shared_ptr<TcpConnection> c = m_list.at(i);
|
||||
if (c->GetID() != msg.GetSenderID())
|
||||
{
|
||||
int32_t sent;
|
||||
if (!c->GetClient()->Send(data.get(), size, sent))
|
||||
{
|
||||
// it failed - retry? or just disconnect right in the first try
|
||||
}
|
||||
}
|
||||
}
|
||||
m_listMutex.unlock();
|
||||
}
|
||||
else if (msg.GetDistributionMode() == DistributionMode::OthersAndServer)
|
||||
{
|
||||
m_listMutex.lock();
|
||||
for (int i = 0; i < m_list.size(); i++)
|
||||
{
|
||||
std::shared_ptr<TcpConnection> c = m_list.at(i);
|
||||
if (c->GetID() != msg.GetSenderID())
|
||||
{
|
||||
int32_t sent;
|
||||
if (!c->GetClient()->Send(data.get(), size, sent))
|
||||
{
|
||||
// it failed - retry? or just disconnect right in the first try
|
||||
}
|
||||
}
|
||||
}
|
||||
m_listMutex.unlock();
|
||||
|
||||
//handle to plugins too
|
||||
}
|
||||
else if (msg.GetDistributionMode() == DistributionMode::ID)
|
||||
{
|
||||
m_listMutex.lock();
|
||||
for (int i = 0; i < m_list.size(); i++)
|
||||
{
|
||||
std::shared_ptr<TcpConnection> c = m_list.at(i);
|
||||
if (c->GetID() == msg.GetSenderID())
|
||||
{
|
||||
int32_t sent;
|
||||
if (!c->GetClient()->Send(data.get(), size, sent))
|
||||
{
|
||||
// it failed - retry? or just disconnect right in the first try
|
||||
}
|
||||
}
|
||||
}
|
||||
m_listMutex.unlock();
|
||||
}
|
||||
else if (msg.GetDistributionMode() == DistributionMode::All)
|
||||
{
|
||||
m_listMutex.lock();
|
||||
for (int i = 0; i < m_list.size(); i++)
|
||||
{
|
||||
std::shared_ptr<TcpConnection> c = m_list.at(i);
|
||||
|
||||
int32_t sent;
|
||||
if (!c->GetClient()->Send(data.get(), size, sent))
|
||||
{
|
||||
// it failed - retry? or just disconnect right in the first try
|
||||
}
|
||||
}
|
||||
m_listMutex.unlock();
|
||||
}
|
||||
else if (msg.GetDistributionMode() == DistributionMode::AllAndMe)
|
||||
{
|
||||
m_listMutex.lock();
|
||||
for (int i = 0; i < m_list.size(); i++)
|
||||
{
|
||||
std::shared_ptr<TcpConnection> c = m_list.at(i);
|
||||
|
||||
int32_t sent;
|
||||
if (!c->GetClient()->Send(data.get(), size, sent))
|
||||
{
|
||||
// it failed - retry? or just disconnect right in the first try
|
||||
}
|
||||
}
|
||||
m_listMutex.unlock();
|
||||
|
||||
//handle to plugins too
|
||||
}
|
||||
else if (msg.GetDistributionMode() == DistributionMode::Server)
|
||||
{
|
||||
//handle just in plugins
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TcpConnectionHandler::HandleReceiveMsgAndConnsThreaded()
|
||||
{
|
||||
while (m_run.load())
|
||||
{
|
||||
HandleReceiveMsgAndConns();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||
}
|
||||
}
|
||||
|
||||
void TcpConnectionHandler::HandleSendThreaded()
|
||||
{
|
||||
while (m_run.load())
|
||||
{
|
||||
HandleSend();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||
}
|
||||
}
|
||||
}
|
||||
33
src/HLAPI/TcpServer.cpp
Normal file
33
src/HLAPI/TcpServer.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
#include "TcpServer.hpp"
|
||||
|
||||
#include "TcpConnection.hpp"
|
||||
#include "TcpSocketBuilder.hpp"
|
||||
#include "TcpClient.hpp"
|
||||
#include "TcpConnectionHandler.hpp"
|
||||
|
||||
namespace std::net
|
||||
{
|
||||
TcpServer::TcpServer(uint32_t max_connections, uint16_t port)
|
||||
: m_maxConnections(max_connections)
|
||||
, m_port(port)
|
||||
, m_run(false)
|
||||
{
|
||||
if (max_connections == 0 || port == 0)
|
||||
throw std::invalid_argument("TcpServer::TcpServer()");
|
||||
|
||||
listener = std::shared_ptr<TcpListener>(TcpSocketBuilder().AsReusable().Bind(IPAddress(0, 0, 0, 0, port)).Listening().BuildListener().release());
|
||||
m_connectionHandler = std::make_shared<std::net::TcpConnectionHandler>(listener);
|
||||
m_connectionHandler->SetMaxConnections(max_connections);
|
||||
}
|
||||
|
||||
void TcpServer::Start()
|
||||
{
|
||||
m_run = true;
|
||||
m_connectionHandler->Start();
|
||||
}
|
||||
|
||||
void TcpServer::Stop()
|
||||
{
|
||||
m_run.exchange(false);
|
||||
}
|
||||
}
|
||||
58
src/HLAPI/main.cpp
Normal file
58
src/HLAPI/main.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include "Init.hpp"
|
||||
#include "Server.hpp"
|
||||
#include "BitConverter.hpp"
|
||||
#include "TcpClient.hpp"
|
||||
#include "InternalTags.hpp"
|
||||
#include "NetworkMessage.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::net::Initialize();
|
||||
std::net::Server server(100);
|
||||
server.Start();
|
||||
|
||||
std::net::TcpClient client;
|
||||
std::net::IPAddress ip("127.0.0.1");
|
||||
client.Connect(ip);
|
||||
|
||||
std::net::TcpClient client2;
|
||||
client2.Connect(ip);
|
||||
|
||||
while (true)
|
||||
{
|
||||
uint32_t data_size;
|
||||
while (client.HasPendingData(data_size))
|
||||
{
|
||||
std::net::NetworkMessage message;
|
||||
|
||||
uint8_t *bytes = new uint8_t[data_size]();
|
||||
|
||||
int32_t read;
|
||||
client.Recv(bytes, data_size, read);
|
||||
|
||||
message.Deserialize(bytes, data_size);
|
||||
|
||||
uint32_t id = std::BitConverter::FromBytes<uint32_t>((uint8_t*)(message.GetData<void>()));
|
||||
if (message.GetTag() == (uint32_t)InternalTags::AssignID)
|
||||
std::cout << id << std::endl;
|
||||
}
|
||||
|
||||
while (client2.HasPendingData(data_size))
|
||||
{
|
||||
std::net::NetworkMessage message2;
|
||||
|
||||
uint8_t* bytes2 = new uint8_t[data_size]();
|
||||
|
||||
int32_t read2;
|
||||
client2.Recv(bytes2, data_size, read2);
|
||||
|
||||
message2.Deserialize(bytes2, data_size);
|
||||
|
||||
uint32_t id2 = std::BitConverter::FromBytes<uint32_t>((uint8_t*)(message2.GetData<void>()));
|
||||
if (message2.GetTag() == (uint32_t)InternalTags::AssignID)
|
||||
std::cout << id2 << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user