mirror of
https://github.com/ncblakely/GiantsTools
synced 2024-12-24 16:27:23 +01:00
Minor SDK fixes to ensure proper memory deallocation.
This commit is contained in:
parent
ac7a8eb4ba
commit
382d67f7b1
@ -25,6 +25,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plugins", "Plugins", "{0801
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "imp_gbs", "Plugins\imp_gbs\imp_gbs.vcxproj", "{448F061E-AE05-4E06-84A1-C95660FD048C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Giants.Services.Tests", "Giants.Services.Tests\Giants.Services.Tests.csproj", "{2AFB71CA-8313-472E-B242-0517343764B4}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ServerConsole", "ServerConsoleExample\ServerConsole.vcxproj", "{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -277,6 +281,52 @@ Global
|
||||
{448F061E-AE05-4E06-84A1-C95660FD048C}.ReleaseBeta|x64.Build.0 = Release|x64
|
||||
{448F061E-AE05-4E06-84A1-C95660FD048C}.ReleaseBeta|x86.ActiveCfg = Release|Win32
|
||||
{448F061E-AE05-4E06-84A1-C95660FD048C}.ReleaseBeta|x86.Build.0 = Release|Win32
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.DebugBeta|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.DebugBeta|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.DebugBeta|x64.ActiveCfg = Debug|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.DebugBeta|x64.Build.0 = Debug|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.DebugBeta|x86.ActiveCfg = Debug|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.DebugBeta|x86.Build.0 = Debug|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.Release|x64.Build.0 = Release|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.Release|x86.Build.0 = Release|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.ReleaseBeta|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.ReleaseBeta|Any CPU.Build.0 = Release|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.ReleaseBeta|x64.ActiveCfg = Release|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.ReleaseBeta|x64.Build.0 = Release|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.ReleaseBeta|x86.ActiveCfg = Release|Any CPU
|
||||
{2AFB71CA-8313-472E-B242-0517343764B4}.ReleaseBeta|x86.Build.0 = Release|Any CPU
|
||||
{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}.Debug|x64.Build.0 = Debug|x64
|
||||
{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}.Debug|x86.Build.0 = Debug|Win32
|
||||
{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}.DebugBeta|Any CPU.ActiveCfg = Debug|Win32
|
||||
{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}.DebugBeta|Any CPU.Build.0 = Debug|Win32
|
||||
{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}.DebugBeta|x64.ActiveCfg = Debug|x64
|
||||
{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}.DebugBeta|x64.Build.0 = Debug|x64
|
||||
{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}.DebugBeta|x86.ActiveCfg = Debug|Win32
|
||||
{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}.DebugBeta|x86.Build.0 = Debug|Win32
|
||||
{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}.Release|x64.ActiveCfg = Release|x64
|
||||
{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}.Release|x64.Build.0 = Release|x64
|
||||
{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}.Release|x86.ActiveCfg = Release|Win32
|
||||
{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}.Release|x86.Build.0 = Release|Win32
|
||||
{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}.ReleaseBeta|Any CPU.ActiveCfg = Debug|Win32
|
||||
{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}.ReleaseBeta|Any CPU.Build.0 = Debug|Win32
|
||||
{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}.ReleaseBeta|x64.ActiveCfg = Release|x64
|
||||
{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}.ReleaseBeta|x64.Build.0 = Release|x64
|
||||
{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}.ReleaseBeta|x86.ActiveCfg = Release|Win32
|
||||
{8AEE9CFF-0E24-498F-B60A-627A7F4A727D}.ReleaseBeta|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
165
Sdk/Include/DataTypes.h
Normal file
165
Sdk/Include/DataTypes.h
Normal file
@ -0,0 +1,165 @@
|
||||
#pragma once
|
||||
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Basic game data types and macros
|
||||
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned char UBYTE;
|
||||
typedef signed char SBYTE;
|
||||
typedef unsigned short UWORD;
|
||||
typedef int BOOL;
|
||||
typedef unsigned long ULONG;
|
||||
typedef unsigned long DWORD;
|
||||
typedef std::int64_t int64;
|
||||
typedef std::uint64_t uint64;
|
||||
#ifdef UNICODE
|
||||
typedef std::wstring tstring;
|
||||
typedef std::wstring_view tstring_view;
|
||||
#else
|
||||
typedef std::string tstring;
|
||||
typedef std::string_view tstring_view;
|
||||
#endif
|
||||
|
||||
#define countof(array) (sizeof((array)) / sizeof((array)[0]))
|
||||
|
||||
#define FlagSet(b, f) ((b) |= (f))
|
||||
#define FlagClear(b, f) ((b) &= ~(f))
|
||||
#define FlagIsClear(b, f) (!FlagIsSet(b, f))
|
||||
#define FlagFlip(b, f) ((b) ^= (f))
|
||||
#define FlagIsSet(b, f) (((b) & (f)) != 0)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Vectors
|
||||
|
||||
struct P3D
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
|
||||
inline const P3D& operator -= (const P3D& rhs)
|
||||
{
|
||||
x -= rhs.x;
|
||||
y -= rhs.y;
|
||||
z -= rhs.z;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const P3D& operator += (const P3D& rhs)
|
||||
{
|
||||
x += rhs.x;
|
||||
y += rhs.y;
|
||||
z += rhs.z;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline P3D operator - (const P3D& rhs)
|
||||
{
|
||||
P3D result;
|
||||
|
||||
result.x = x - rhs.x;
|
||||
result.y = y - rhs.y;
|
||||
result.z = z - rhs.z;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline P3D Cross(const P3D& v2)
|
||||
{
|
||||
P3D result;
|
||||
|
||||
result.x = y * v2.z - z * v2.y;
|
||||
result.y = z * v2.x - x * v2.z;
|
||||
result.z = x * v2.y - y * v2.x;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline float Dot(const P3D& v2)
|
||||
{
|
||||
return x * v2.x + y * v2.y + z * v2.z;
|
||||
}
|
||||
|
||||
inline float Length()
|
||||
{
|
||||
return (float)(sqrt(x * x + y * y + z * z));
|
||||
}
|
||||
|
||||
inline P3D Scale(float scale)
|
||||
{
|
||||
x *= scale;
|
||||
y *= scale;
|
||||
z *= scale;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline P3D Normalize()
|
||||
{
|
||||
const float length = Length();
|
||||
P3D normalized = *this;
|
||||
|
||||
float factor = 0.0f;
|
||||
if (length)
|
||||
{
|
||||
factor = 1 / length;
|
||||
}
|
||||
else
|
||||
{
|
||||
factor = 1.0f;
|
||||
}
|
||||
|
||||
normalized.x *= factor;
|
||||
normalized.y *= factor;
|
||||
normalized.z *= factor;
|
||||
|
||||
return normalized;
|
||||
}
|
||||
|
||||
bool IsNaN() const
|
||||
{
|
||||
return (_isnan(x) || _isnan(y) || _isnan(z));
|
||||
}
|
||||
|
||||
bool Finite() const
|
||||
{
|
||||
return (_finite(x) && _finite(y) && _finite(z));
|
||||
}
|
||||
};
|
||||
|
||||
#pragma pack (push, 1)
|
||||
// Optimized 3D vector for network packets.
|
||||
struct NetP3D
|
||||
{
|
||||
short x, y, z;
|
||||
};
|
||||
#pragma pack (pop)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct RGBFloat
|
||||
{
|
||||
float r{};
|
||||
float g{};
|
||||
float b{};
|
||||
};
|
||||
|
||||
struct VertRGB
|
||||
{
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
};
|
||||
|
||||
struct UV
|
||||
{
|
||||
float u, v;
|
||||
};
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <DataTypes.h>
|
||||
|
||||
#include "NetCommon.h"
|
||||
|
||||
/// <summary>
|
||||
@ -29,21 +31,22 @@ struct PlayerConnectedEvent : GameServerEvent
|
||||
{
|
||||
PlayerConnectedEvent() noexcept : GameServerEvent(GameServerEventType::PlayerConnected) { }
|
||||
|
||||
std::unique_ptr<PlayerInfo> info;
|
||||
std::shared_ptr<PlayerInfo> info;
|
||||
};
|
||||
|
||||
struct PlayerDisconnectedEvent : GameServerEvent
|
||||
{
|
||||
PlayerDisconnectedEvent() noexcept : GameServerEvent(GameServerEventType::PlayerDisconnected) { }
|
||||
|
||||
std::unique_ptr<PlayerInfo> info;
|
||||
std::shared_ptr<PlayerInfo> info;
|
||||
};
|
||||
|
||||
struct ChatMessageEvent : GameServerEvent
|
||||
{
|
||||
ChatMessageEvent() noexcept : GameServerEvent(GameServerEventType::ChatMessage) { }
|
||||
|
||||
std::string_view message;
|
||||
tstring_view message{};
|
||||
PlayerIndex senderIndex{};
|
||||
};
|
||||
|
||||
struct WorldLoadedEvent : GameServerEvent
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <DataTypes.h>
|
||||
#include <IComponent.h>
|
||||
#include <IEventSource.h>
|
||||
|
||||
@ -19,19 +21,60 @@ struct IGameServer : IComponent, IEventSource<GameServerEventType, GameServerEve
|
||||
{
|
||||
virtual ~IGameServer() = default;
|
||||
|
||||
virtual void STDMETHODCALLTYPE SendChatMessage(const std::string_view& message, ChatColor color, int flags, PlayerIndex indexTo) = 0;
|
||||
/// <summary>
|
||||
/// Sends a chat message to all players or to a specified player.
|
||||
/// </summary>
|
||||
/// <param name="message">The chat message.</param>
|
||||
/// <param name="color">Text color.</param>
|
||||
/// <param name="flags">Flags for the message.</param>
|
||||
/// <param name="indexTo">The index to send the message to. If 0, it will be sent to all players.</param>
|
||||
virtual void STDMETHODCALLTYPE SendChatMessage(const tstring_view& message, ChatColor color, int flags, PlayerIndex indexTo) = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Bans the player at the specified index.
|
||||
/// </summary>
|
||||
/// <param name="index">The player index.</param>
|
||||
/// <returns></returns>
|
||||
virtual void STDMETHODCALLTYPE BanPlayer(int index) = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Kicks the player at the specified index.
|
||||
/// </summary>
|
||||
/// <param name="index">The player index.</param>
|
||||
/// <param name="reason">The reason for kicking the player.</param>
|
||||
/// <returns></returns>
|
||||
virtual void STDMETHODCALLTYPE KickPlayer(int index, KickReason reason) = 0;
|
||||
|
||||
virtual PlayerInfo STDMETHODCALLTYPE GetPlayer(int index) = 0;
|
||||
/// <summary>
|
||||
/// Gets player data for the specified index.
|
||||
/// </summary>
|
||||
/// <param name="index">The zero-based player index.</param>
|
||||
/// <throws>std::out_of_range</throws>
|
||||
virtual const std::shared_ptr<PlayerInfo> STDMETHODCALLTYPE GetPlayer(int index) const = 0;
|
||||
|
||||
virtual std::vector<PlayerInfo> STDMETHODCALLTYPE GetPlayers() = 0;
|
||||
/// <summary>
|
||||
/// Gets data for all players in the current game.
|
||||
/// </summary>
|
||||
virtual std::vector<std::shared_ptr<PlayerInfo>> STDMETHODCALLTYPE GetPlayers() const = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Toggles or increments the specified game option.
|
||||
/// Note: the behavior of this method is the same as changing an option from the F1 in-game menu.
|
||||
/// </summary>
|
||||
/// <param name="option"></param>
|
||||
/// <returns></returns>
|
||||
virtual void STDMETHODCALLTYPE ChangeGameOption(GameOption option) = 0;
|
||||
|
||||
virtual NetGameDetails STDMETHODCALLTYPE GetGameDetails() = 0;
|
||||
/// <summary>
|
||||
/// Gets details for the current game.
|
||||
/// </summary>
|
||||
virtual const std::shared_ptr<NetGameDetails> STDMETHODCALLTYPE GetGameDetails() const = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Modifies the settings for the current game.
|
||||
/// </summary>
|
||||
/// <param name="gameDetails">The game details.</param>
|
||||
virtual void STDMETHODCALLTYPE ChangeGameDetails(const NetGameDetails& gameDetails) = 0;
|
||||
};
|
||||
|
||||
struct DECLSPEC_UUID("{B2D67EE7-8063-488F-B3B9-E7DA675CB752}") IGameServer;
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <DataTypes.h>
|
||||
#include <IComponent.h>
|
||||
#include <string>
|
||||
|
||||
@ -14,7 +15,7 @@ inline const GUID IID_ITextLookupService = { 0x770debd3, 0x165d, 0x4340, 0x82, 0
|
||||
/// </summary>
|
||||
struct ITextLookupService : public IComponent
|
||||
{
|
||||
virtual std::string STDMETHODCALLTYPE GetLocalized(std::string_view lookup) = 0;
|
||||
virtual std::string STDMETHODCALLTYPE GetLocalized(tstring_view lookup) = 0;
|
||||
|
||||
virtual std::string STDMETHODCALLTYPE GetNetPlayerStateName(enum class NetPlayerState state) = 0;
|
||||
|
||||
|
@ -93,6 +93,9 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||
<PropertyGroup Label="Vcpkg">
|
||||
<VcpkgEnableManifest>true</VcpkgEnableManifest>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
@ -100,7 +103,7 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>..\..\Sdk\Include</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\Sdk\Include</AdditionalIncludeDirectories>
|
||||
<EnablePREfast>true</EnablePREfast>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
@ -154,7 +157,7 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;NDEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>..\..\Sdk\Include</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\Sdk\Include</AdditionalIncludeDirectories>
|
||||
<EnablePREfast>true</EnablePREfast>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
|
@ -132,7 +132,7 @@ void ServerDialog::RefreshPlayers()
|
||||
const auto& pGameServer = m_pContainer->Get<IGameServer>();
|
||||
for (const auto& player : pGameServer->GetPlayers())
|
||||
{
|
||||
if (player.host)
|
||||
if (player->host)
|
||||
{
|
||||
continue; // Skip host player
|
||||
}
|
||||
@ -140,14 +140,14 @@ void ServerDialog::RefreshPlayers()
|
||||
LVITEM item{};
|
||||
item.cColumns = NumColumns;
|
||||
item.mask = LVIF_COLUMNS | LVIF_PARAM;
|
||||
item.lParam = player.index;
|
||||
item.lParam = player->index;
|
||||
|
||||
const int index = PlayersListCtrl.InsertItem(&item);
|
||||
PlayersListCtrl.SetItemText(index, 0, player.name.c_str());
|
||||
PlayersListCtrl.SetItemText(index, 1, pTextLookupService->GetNetPlayerStateName(player.state).c_str());
|
||||
PlayersListCtrl.SetItemText(index, 2, fmt::format(_T("{0}"), player.ping).c_str());
|
||||
PlayersListCtrl.SetItemText(index, 3, fmt::format(_T("{0}"), player.score).c_str());
|
||||
PlayersListCtrl.SetItemText(index, 4, pTextLookupService->GetPlayerTeamName(player.team).c_str());
|
||||
PlayersListCtrl.SetItemText(index, 0, player->name.c_str());
|
||||
PlayersListCtrl.SetItemText(index, 1, pTextLookupService->GetNetPlayerStateName(player->state).c_str());
|
||||
PlayersListCtrl.SetItemText(index, 2, fmt::format(_T("{0}"), player->ping).c_str());
|
||||
PlayersListCtrl.SetItemText(index, 3, fmt::format(_T("{0}"), player->score).c_str());
|
||||
PlayersListCtrl.SetItemText(index, 4, pTextLookupService->GetPlayerTeamName(player->team).c_str());
|
||||
}
|
||||
|
||||
PlayersListCtrl.SetSelectionMark(savedSelection);
|
||||
@ -181,7 +181,7 @@ void ServerDialog::HandleWorldLoaded(const GameServerEvent& event)
|
||||
|
||||
const auto& pGameServer = m_pContainer->Get<IGameServer>();
|
||||
|
||||
NetGameDetails details = pGameServer->GetGameDetails();
|
||||
auto details = pGameServer->GetGameDetails();
|
||||
|
||||
// TODO: Connect to world state controls
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user