diff --git a/Sdk/Include/ConfigConstants.h b/Sdk/Include/ConfigConstants.h
new file mode 100644
index 0000000..1176b61
--- /dev/null
+++ b/Sdk/Include/ConfigConstants.h
@@ -0,0 +1,13 @@
+#pragma once
+
+namespace ConfigSections
+{
+ const char* const Network = "network";
+};
+
+namespace ConfigKeys
+{
+ // Network
+ const char* const MasterServerHostName = "masterServerHostName";
+ const char* const BannedPlayers = "bannedPlayers";
+}
\ No newline at end of file
diff --git a/Sdk/Include/ConfigEvents.h b/Sdk/Include/ConfigEvents.h
new file mode 100644
index 0000000..9aa23d6
--- /dev/null
+++ b/Sdk/Include/ConfigEvents.h
@@ -0,0 +1,44 @@
+#pragma once
+
+///
+/// Event types for .
+///
+enum class ConfigEventType
+{
+ None = 0,
+
+ ConfigLoaded,
+ ConfigSaving
+};
+
+struct ConfigEvent
+{
+public:
+ virtual ~ConfigEvent() = default;
+ ConfigEvent(ConfigEventType type) noexcept { this->type = type; }
+
+private:
+ ConfigEventType type;
+};
+
+struct ConfigLoadedEvent : ConfigEvent
+{
+ ConfigLoadedEvent(struct IConfig& config) noexcept
+ : ConfigEvent(ConfigEventType::ConfigLoaded),
+ config(config)
+ {
+ }
+
+ struct IConfig& config;
+};
+
+struct ConfigSavingEvent : ConfigEvent
+{
+ ConfigSavingEvent(struct IConfig& config) noexcept
+ : ConfigEvent(ConfigEventType::ConfigSaving),
+ config(config)
+ {
+ }
+
+ struct IConfig& config;
+};
diff --git a/Sdk/Include/IComponent.h b/Sdk/Include/IComponent.h
index e1b9009..bde23d8 100644
--- a/Sdk/Include/IComponent.h
+++ b/Sdk/Include/IComponent.h
@@ -3,7 +3,7 @@
#include
// {779CF758-3E3F-4FEE-9513-60106522686A}
-DEFINE_GUID(IID_IComponent, 0x779cf758, 0x3e3f, 0x4fee, 0x95, 0x13, 0x60, 0x10, 0x65, 0x22, 0x68, 0x6a);
+inline const GUID IID_IComponent = { 0x779cf758, 0x3e3f, 0x4fee, 0x95, 0x13, 0x60, 0x10, 0x65, 0x22, 0x68, 0x6a };
///
/// Base interface for a game COM component.
diff --git a/Sdk/Include/IComponentContainer.h b/Sdk/Include/IComponentContainer.h
index 480157e..7e616b0 100644
--- a/Sdk/Include/IComponentContainer.h
+++ b/Sdk/Include/IComponentContainer.h
@@ -7,8 +7,7 @@ template
using ComPtr = Microsoft::WRL::ComPtr;
// {C942AA9B-C576-4D3F-A54F-B135B500E611}
-DEFINE_GUID(IID_IComponentContainer,
- 0xc942aa9b, 0xc576, 0x4d3f, 0xa5, 0x4f, 0xb1, 0x35, 0xb5, 0x0, 0xe6, 0x11);
+inline const GUID IID_IComponentContainer = { 0xc942aa9b, 0xc576, 0x4d3f, 0xa5, 0x4f, 0xb1, 0x35, 0xb5, 0x0, 0xe6, 0x11 };
template
struct TypedGet
@@ -18,19 +17,24 @@ struct TypedGet
{
ComPtr temp;
ComPtr pComponent = ((T*)this)->Get(__uuidof(TGet));
- HRESULT hr = pComponent.As(&temp);
- if (FAILED(hr))
+ if (pComponent)
{
- if (hr == E_NOINTERFACE)
+ HRESULT hr = pComponent.As(&temp);
+ if (FAILED(hr))
{
- throw std::invalid_argument("The interface is not supported.");
+ if (hr == E_NOINTERFACE)
+ {
+ throw std::invalid_argument("The interface is not supported.");
+ }
+
+ throw std::invalid_argument(fmt::format("Unknown exception {0:x} querying interface.", hr));
}
- throw std::invalid_argument(fmt::format("Unknown exception {0:x} querying interface.", hr));
+ pComponent.Detach();
+ return temp;
}
- pComponent.Detach();
- return temp;
+ return ComPtr(); // Null
}
};
diff --git a/Sdk/Include/IConfig.h b/Sdk/Include/IConfig.h
new file mode 100644
index 0000000..e5d05e6
--- /dev/null
+++ b/Sdk/Include/IConfig.h
@@ -0,0 +1,44 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+
+// {599E6624-694C-41B6-B354-62EEA1132041}
+inline const GUID IID_IConfig = { 0x599e6624, 0x694c, 0x41b6, 0xb3, 0x54, 0x62, 0xee, 0xa1, 0x13, 0x20, 0x41 };
+
+struct IConfig : IComponent, IEventSource
+{
+ virtual ~IConfig() = default;
+
+ virtual void STDMETHODCALLTYPE Read() = 0;
+
+ virtual void STDMETHODCALLTYPE Save() = 0;
+
+ virtual float STDMETHODCALLTYPE GetFloat(const tstring_view& section, const tstring_view& setting) const = 0;
+
+ virtual std::vector STDMETHODCALLTYPE GetFloatArray(const tstring_view& section, const tstring_view& setting) const = 0;
+
+ virtual int STDMETHODCALLTYPE GetInteger(const tstring_view& section, const tstring_view& setting) const = 0;
+
+ virtual std::vector STDMETHODCALLTYPE GetIntegerArray(const tstring_view& section, const tstring_view& setting) const = 0;
+
+ virtual tstring STDMETHODCALLTYPE GetString(const tstring_view& section, const tstring_view& setting) const = 0;
+
+ virtual std::vector STDMETHODCALLTYPE GetStringArray(const tstring_view& section, const tstring_view& setting) const = 0;
+
+ virtual void STDMETHODCALLTYPE SetFloat(const tstring_view& section, const tstring_view& setting, float value) = 0;
+
+ virtual void STDMETHODCALLTYPE SetFloatArray(const tstring_view& section, const tstring_view& setting, std::vector&& values) = 0;
+
+ virtual void STDMETHODCALLTYPE SetInteger(const tstring_view& section, const tstring_view& setting, int value) = 0;
+
+ virtual void STDMETHODCALLTYPE SetIntegerArray(const tstring_view& section, const tstring_view& setting, std::vector&& values) = 0;
+
+ virtual void STDMETHODCALLTYPE SetString(const tstring_view& section, const tstring_view& setting, tstring_view value) = 0;
+
+ virtual void STDMETHODCALLTYPE SetStringArray(const tstring_view& section, const tstring_view& setting, std::vector&& values) = 0;
+};
+
+struct DECLSPEC_UUID("{599E6624-694C-41B6-B354-62EEA1132041}") IConfig;
\ No newline at end of file
diff --git a/Sdk/Include/IEventSource.h b/Sdk/Include/IEventSource.h
new file mode 100644
index 0000000..5951663
--- /dev/null
+++ b/Sdk/Include/IEventSource.h
@@ -0,0 +1,10 @@
+#pragma once
+
+template
+struct IEventSource
+{
+ virtual ~IEventSource() = default;
+
+ virtual UUID STDMETHODCALLTYPE Listen(TEventType event, std::function function) noexcept = 0;
+ virtual void STDMETHODCALLTYPE Unlisten(TEventType event, UUID uuid) noexcept = 0;
+};
\ No newline at end of file
diff --git a/Sdk/Include/IExceptionHandler.h b/Sdk/Include/IExceptionHandler.h
new file mode 100644
index 0000000..0d7de6e
--- /dev/null
+++ b/Sdk/Include/IExceptionHandler.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include
+
+// {9C4C8F9C-D4C1-4749-A073-D710548D3154}
+inline const GUID IID_IExceptionHandler = { 0x9c4c8f9c, 0xd4c1, 0x4749, 0xa0, 0x73, 0xd7, 0x10, 0x54, 0x8d, 0x31, 0x54 };
+struct IExceptionHandler : IComponent
+{
+ virtual ~IExceptionHandler() = default;
+
+ virtual void STDMETHODCALLTYPE AttachToCurrentThread() = 0;
+ virtual void STDMETHODCALLTYPE DetachFromCurrentThread() = 0;
+ virtual void STDMETHODCALLTYPE Initialize() = 0;
+ virtual void STDMETHODCALLTYPE PostLoad() = 0;
+ virtual void STDMETHODCALLTYPE Shutdown() = 0;
+};
+
+struct DECLSPEC_UUID("{9C4C8F9C-D4C1-4749-A073-D710548D3154}") IExceptionHandler;
\ No newline at end of file
diff --git a/Sdk/Include/IGameServer.h b/Sdk/Include/IGameServer.h
index 6fed479..2514417 100644
--- a/Sdk/Include/IGameServer.h
+++ b/Sdk/Include/IGameServer.h
@@ -4,18 +4,18 @@
#include
#include
#include
+#include
#include "GameServerEvents.h"
#include "NetCommon.h"
// {B2D67EE7-8063-488F-B3B9-E7DA675CB752}
-DEFINE_GUID(IID_IGameServer,
- 0xb2d67ee7, 0x8063, 0x488f, 0xb3, 0xb9, 0xe7, 0xda, 0x67, 0x5c, 0xb7, 0x52);
+inline const GUID IID_IGameServer = { 0xb2d67ee7, 0x8063, 0x488f, 0xb3, 0xb9, 0xe7, 0xda, 0x67, 0x5c, 0xb7, 0x52 };
///
/// Defines an API for communicating with the game server.
///
-struct IGameServer : IComponent
+struct IGameServer : IComponent, IEventSource
{
virtual ~IGameServer() = default;
@@ -32,10 +32,6 @@ struct IGameServer : IComponent
virtual void STDMETHODCALLTYPE ChangeGameOption(GameOption option) = 0;
virtual NetGameDetails STDMETHODCALLTYPE GetGameDetails() = 0;
-
- virtual UUID STDMETHODCALLTYPE Listen(GameServerEventType event, std::function function) noexcept = 0;
-
- virtual void STDMETHODCALLTYPE Unlisten(GameServerEventType event, UUID uuid) noexcept = 0;
};
struct DECLSPEC_UUID("{B2D67EE7-8063-488F-B3B9-E7DA675CB752}") IGameServer;
\ No newline at end of file
diff --git a/Sdk/Include/IGameServerConsole.h b/Sdk/Include/IGameServerConsole.h
index afe59c0..be2f128 100644
--- a/Sdk/Include/IGameServerConsole.h
+++ b/Sdk/Include/IGameServerConsole.h
@@ -5,8 +5,7 @@
#include
// {3B2D43AC-2557-4C28-991D-A456B59D76CB}
-DEFINE_GUID(IID_IGameServerConsole,
- 0x3b2d43ac, 0x2557, 0x4c28, 0x99, 0x1d, 0xa4, 0x56, 0xb5, 0x9d, 0x76, 0xcb);
+inline const GUID IID_IGameServerConsole = { 0x3b2d43ac, 0x2557, 0x4c28, 0x99, 0x1d, 0xa4, 0x56, 0xb5, 0x9d, 0x76, 0xcb };
///
/// Interface for dedicated server consoles.
diff --git a/Sdk/Include/ITextLookupService.h b/Sdk/Include/ITextLookupService.h
index 5280460..97416e2 100644
--- a/Sdk/Include/ITextLookupService.h
+++ b/Sdk/Include/ITextLookupService.h
@@ -7,8 +7,7 @@ enum class NetPlayerState;
enum class GameTeam;
// {770DEBD3-165D-4340-829D-5262F473FBE3}
-DEFINE_GUID(IID_ITextLookupService,
- 0x770debd3, 0x165d, 0x4340, 0x82, 0x9d, 0x52, 0x62, 0xf4, 0x73, 0xfb, 0xe3);
+inline const GUID IID_ITextLookupService = { 0x770debd3, 0x165d, 0x4340, 0x82, 0x9d, 0x52, 0x62, 0xf4, 0x73, 0xfb, 0xe3 };
///
/// Service providing localization of text placeholders and friendly-name mappings of common enums.
diff --git a/Sdk/Include/MasterServer/IGiantsApiClient.h b/Sdk/Include/MasterServer/IGiantsApiClient.h
new file mode 100644
index 0000000..071c5d3
--- /dev/null
+++ b/Sdk/Include/MasterServer/IGiantsApiClient.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include
+
+#include
+#include
+
+using njson = nlohmann::json;
+
+typedef std::future> ServerInfoFuture;
+
+// {EE129A81-0A86-49C4-8D23-A771A7350952}
+inline const GUID IID_IGiantsApiClient = { 0xee129a81, 0xa86, 0x49c4, 0x8d, 0x23, 0xa7, 0x71, 0xa7, 0x35, 0x9, 0x52 };
+
+struct IGiantsApiClient : IComponent
+{
+ virtual ~IGiantsApiClient() = default;
+
+ virtual void STDMETHODCALLTYPE DeleteServerInformationAsync() = 0;
+ virtual ServerInfoFuture STDMETHODCALLTYPE GetServerInformationAsync() = 0;
+ virtual void STDMETHODCALLTYPE PostServerInformationAsync(const njson& requestBody) = 0;
+};
+
+struct DECLSPEC_UUID("{EE129A81-0A86-49C4-8D23-A771A7350952}") IGiantsApiClient;
\ No newline at end of file
diff --git a/Sdk/Include/MasterServer/PlayerInfoResponse.h b/Sdk/Include/MasterServer/PlayerInfoResponse.h
new file mode 100644
index 0000000..530f292
--- /dev/null
+++ b/Sdk/Include/MasterServer/PlayerInfoResponse.h
@@ -0,0 +1,21 @@
+#pragma once
+
+using njson = nlohmann::json;
+
+struct PlayerInfoResponse
+{
+ explicit PlayerInfoResponse(const njson& playerInfoResponse)
+ {
+ index = playerInfoResponse["index"];
+ name = playerInfoResponse["name"];
+ frags = playerInfoResponse["frags"];
+ deaths = playerInfoResponse["deaths"];
+ teamName = playerInfoResponse["teamName"];
+ }
+
+ int index;
+ std::string name;
+ int frags;
+ int deaths;
+ std::string teamName;
+};
diff --git a/Sdk/Include/MasterServer/ServerInfoResponse.h b/Sdk/Include/MasterServer/ServerInfoResponse.h
new file mode 100644
index 0000000..6ed9302
--- /dev/null
+++ b/Sdk/Include/MasterServer/ServerInfoResponse.h
@@ -0,0 +1,51 @@
+#pragma once
+
+#include
+
+using njson = nlohmann::json;
+
+struct ServerInfoResponse
+{
+ explicit ServerInfoResponse(const njson& serverInfoResponse)
+ {
+ hostIp = serverInfoResponse["hostIpAddress"];
+ gameName = serverInfoResponse["gameName"];
+
+ njson versionJson = serverInfoResponse["version"];
+ version.build = versionJson["build"];
+ version.major = versionJson["major"];
+ version.minor = versionJson["minor"];
+ version.revision = versionJson["revision"];
+
+ sessionName = serverInfoResponse["sessionName"];
+ port = serverInfoResponse["port"];
+ mapName = serverInfoResponse["mapName"];
+ gameType = serverInfoResponse["gameType"];
+ numPlayers = serverInfoResponse["numPlayers"];
+ gameState = serverInfoResponse["gameState"];
+ timeLimit = serverInfoResponse["timeLimit"];
+ fragLimit = serverInfoResponse["fragLimit"];
+ teamFragLimit = serverInfoResponse["teamFragLimit"];
+ firstBaseComplete = serverInfoResponse["firstBaseComplete"];
+
+ for (const auto& playerInfoResponse : serverInfoResponse["playerInfo"])
+ {
+ playerInfo.emplace_back(PlayerInfoResponse(playerInfoResponse));
+ }
+ }
+
+ std::string hostIp;
+ std::string gameName;
+ Version version;
+ std::string sessionName;
+ int port = 0;
+ std::string mapName;
+ std::string gameType;
+ int numPlayers = 0;
+ std::string gameState;
+ int timeLimit = 0;
+ int fragLimit = 0;
+ int teamFragLimit = 0;
+ bool firstBaseComplete = false;
+ std::vector playerInfo;
+};
diff --git a/Sdk/Include/Version.h b/Sdk/Include/Version.h
new file mode 100644
index 0000000..cad8c6a
--- /dev/null
+++ b/Sdk/Include/Version.h
@@ -0,0 +1,9 @@
+#pragma once
+
+struct Version
+{
+ int major;
+ int minor;
+ int build;
+ int revision;
+};