diff --git a/ServerConsoleExample/CodeAnalysis.ruleset b/ServerConsoleExample/CodeAnalysis.ruleset
new file mode 100644
index 0000000..845c4a8
--- /dev/null
+++ b/ServerConsoleExample/CodeAnalysis.ruleset
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ServerConsoleExample/ServerConsole.def b/ServerConsoleExample/ServerConsole.def
new file mode 100644
index 0000000..58e9b42
--- /dev/null
+++ b/ServerConsoleExample/ServerConsole.def
@@ -0,0 +1,4 @@
+LIBRARY
+
+EXPORTS
+ ; Explicit exports can go here
diff --git a/ServerConsoleExample/ServerConsole.filters b/ServerConsoleExample/ServerConsole.filters
new file mode 100644
index 0000000..76165d4
--- /dev/null
+++ b/ServerConsoleExample/ServerConsole.filters
@@ -0,0 +1,61 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Resource Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Resource Files
+
+
+
\ No newline at end of file
diff --git a/ServerConsoleExample/ServerConsole.rc b/ServerConsoleExample/ServerConsole.rc
new file mode 100644
index 0000000..3ea1469
Binary files /dev/null and b/ServerConsoleExample/ServerConsole.rc differ
diff --git a/ServerConsoleExample/ServerConsole.vcxproj b/ServerConsoleExample/ServerConsole.vcxproj
new file mode 100644
index 0000000..dc0c63e
--- /dev/null
+++ b/ServerConsoleExample/ServerConsole.vcxproj
@@ -0,0 +1,237 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ {8AEE9CFF-0E24-498F-B60A-627A7F4A727D}
+ MFCDLLProj
+ ServerInterface
+ 10.0
+ ServerConsole
+
+
+
+ DynamicLibrary
+ true
+ v142
+ MultiByte
+ Dynamic
+
+
+ DynamicLibrary
+ false
+ v142
+ true
+ MultiByte
+ Dynamic
+
+
+ DynamicLibrary
+ true
+ v142
+ Unicode
+ Static
+
+
+ DynamicLibrary
+ false
+ v142
+ true
+ Unicode
+ Static
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ true
+ CodeAnalysis.ruleset
+
+
+ true
+
+
+ false
+ true
+ CodeAnalysis.ruleset
+
+
+ false
+
+
+
+
+
+ Use
+ Level3
+ true
+ WIN32;_WINDOWS;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_DEBUG;_USRDLL;%(PreprocessorDefinitions)
+ pch.h
+ ..\..\Sdk\Include
+ true
+ stdcpplatest
+ MultiThreadedDebugDLL
+
+
+ Windows
+ .\ServerConsole.def
+ Rpcrt4.lib
+
+
+ false
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+ 0x0409
+ _DEBUG;%(PreprocessorDefinitions)
+ $(IntDir);%(AdditionalIncludeDirectories)
+
+
+ xcopy /DY "$(TargetPath)" "$(GIANTS_PATH)\$(TargetFileName)*"
+
+
+
+
+ Use
+ Level3
+ true
+ _WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)
+ pch.h
+
+
+ Windows
+ .\ServerInterface.def
+
+
+ false
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+ 0x0409
+ _DEBUG;%(PreprocessorDefinitions)
+ $(IntDir);%(AdditionalIncludeDirectories)
+
+
+
+
+ Use
+ Level3
+ true
+ true
+ true
+ WIN32;_WINDOWS;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;NDEBUG;_USRDLL;%(PreprocessorDefinitions)
+ pch.h
+ ..\..\Sdk\Include
+ true
+ stdcpplatest
+ MultiThreadedDLL
+
+
+ Windows
+ true
+ true
+ .\ServerConsole.def
+
+
+ false
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+ 0x0409
+ NDEBUG;%(PreprocessorDefinitions)
+ $(IntDir);%(AdditionalIncludeDirectories)
+
+
+ xcopy /DY "$(TargetPath)" "$(GIANTS_PATH)\$(TargetFileName)*"
+
+
+
+
+ Use
+ Level3
+ true
+ true
+ true
+ _WINDOWS;NDEBUG;_USRDLL;%(PreprocessorDefinitions)
+ pch.h
+
+
+ Windows
+ true
+ true
+ .\ServerInterface.def
+
+
+ false
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+ 0x0409
+ NDEBUG;%(PreprocessorDefinitions)
+ $(IntDir);%(AdditionalIncludeDirectories)
+
+
+
+
+ Create
+ Create
+ Create
+ Create
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ServerConsoleExample/ServerConsoleApp.cpp b/ServerConsoleExample/ServerConsoleApp.cpp
new file mode 100644
index 0000000..3df4ec7
--- /dev/null
+++ b/ServerConsoleExample/ServerConsoleApp.cpp
@@ -0,0 +1,56 @@
+#include "pch.h"
+#include
+#include "ServerConsoleApp.h"
+#include "ServerDialog.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+BEGIN_MESSAGE_MAP(ServerConsoleApp, CWinApp)
+END_MESSAGE_MAP()
+
+ServerConsoleApp ConsoleApp;
+BOOL ServerConsoleApp::InitInstance()
+{
+ INITCOMMONCONTROLSEX InitCtrls;
+ InitCtrls.dwSize = sizeof(InitCtrls);
+ InitCtrls.dwICC = ICC_WIN95_CLASSES;
+ InitCommonControlsEx(&InitCtrls);
+
+ CWinApp::InitInstance();
+
+ return TRUE;
+}
+
+ServerConsoleApp::~ServerConsoleApp()
+{
+}
+
+BOOL ServerConsoleApp::ExitInstance()
+{
+ return CWinApp::ExitInstance();
+}
+
+IGameServerConsole* ServerConsoleApp::InitializeDialog(IComponentContainer* container)
+{
+ // Create the server console window.
+ // As this is also a Component, Giants will clean up this object automatically once
+ // it is no longer needed (i.e, there is no need to call delete).
+ auto* dialog = new ServerDialog(container);
+ m_pMainWnd = dialog;
+ return dialog;
+}
+
+__declspec(dllexport) void CreateServerConsole(
+ int apiVersion,
+ IComponentContainer* container)
+{
+ if (apiVersion > 1)
+ {
+ throw std::invalid_argument(fmt::format("Unsupported API version {0}", apiVersion).c_str());
+ }
+
+ AFX_MANAGE_STATE(AfxGetStaticModuleState());
+ ConsoleApp.InitializeDialog(container);
+}
\ No newline at end of file
diff --git a/ServerConsoleExample/ServerConsoleApp.h b/ServerConsoleExample/ServerConsoleApp.h
new file mode 100644
index 0000000..1386dc1
--- /dev/null
+++ b/ServerConsoleExample/ServerConsoleApp.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#ifndef __AFXWIN_H__
+ #error "include 'pch.h' before including this file for PCH"
+#endif
+
+#include "resource.h" // main symbols
+#include "ServerDialog.h"
+#include
+#include
+
+class ServerConsoleApp : public CWinApp
+{
+public:
+ ~ServerConsoleApp();
+
+// MFC methods
+ BOOL InitInstance() override;
+ BOOL ExitInstance() override;
+
+ IGameServerConsole* InitializeDialog(IComponentContainer* container);
+
+ DECLARE_MESSAGE_MAP()
+};
diff --git a/ServerConsoleExample/ServerDialog.cpp b/ServerConsoleExample/ServerDialog.cpp
new file mode 100644
index 0000000..c6a78d0
--- /dev/null
+++ b/ServerConsoleExample/ServerDialog.cpp
@@ -0,0 +1,248 @@
+#include "pch.h"
+
+#include "ServerConsoleApp.h"
+#include "ServerDialog.h"
+#include "Utils.h"
+
+IMPLEMENT_DYNAMIC(ServerDialog, CDialogEx)
+
+ServerDialog::ServerDialog(IComponentContainer* container, CWnd* parent)
+ : ComponentBase(container),
+ CDialogEx(IDD_SERVER, parent)
+{
+ const auto& pGameServer = m_pContainer->Get();
+
+ using namespace std::placeholders;
+ m_playerConnectedEventHandle = pGameServer->Listen(GameServerEventType::PlayerConnected, std::bind(&ServerDialog::HandlePlayerConnected, this, _1));
+ m_playerDisconnectedEventHandle = pGameServer->Listen(GameServerEventType::PlayerDisconnected, std::bind(&ServerDialog::HandlePlayerDisconnected, this, _1));
+ m_playerChatMessageHandle = pGameServer->Listen(GameServerEventType::ChatMessage, std::bind(&ServerDialog::HandleChatMessage, this, _1));
+ m_worldLoadedHandle = pGameServer->Listen(GameServerEventType::WorldLoaded, std::bind(&ServerDialog::HandleWorldLoaded, this, _1));
+}
+
+ServerDialog::~ServerDialog()
+{
+ try
+ {
+ const auto& pGameServer = m_pContainer->Get();
+
+ pGameServer->Unlisten(GameServerEventType::PlayerConnected, m_playerConnectedEventHandle);
+ pGameServer->Unlisten(GameServerEventType::PlayerDisconnected, m_playerDisconnectedEventHandle);
+ pGameServer->Unlisten(GameServerEventType::ChatMessage, m_playerChatMessageHandle);
+ }
+ catch (...)
+ {
+
+ }
+}
+
+void ServerDialog::DoDataExchange(CDataExchange* pDX)
+{
+ CDialogEx::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_CONSOLE, ConsoleEditBox);
+ DDX_Control(pDX, IDC_PLAYERS, PlayersListCtrl);
+ DDX_Control(pDX, IDC_BAN, ButtonBan);
+ DDX_Control(pDX, IDC_KICK, ButtonKick);
+}
+
+void __stdcall ServerDialog::TimerCallback(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
+{
+ ((ServerDialog*)idEvent)->RefreshPlayers();
+}
+
+void ServerDialog::CloseDialog()
+{
+ OnCancel();
+}
+
+void ServerDialog::ShowDialog()
+{
+ AFX_MANAGE_STATE(AfxGetStaticModuleState());
+
+ Create(IDD_SERVER);
+ ShowWindow(SW_SHOW);
+}
+
+BOOL ServerDialog::OnInitDialog()
+{
+ AFX_MANAGE_STATE(AfxGetStaticModuleState());
+ CDialog::OnInitDialog();
+
+ CreateColumns();
+
+ using namespace std::placeholders;
+ SetTimer((UINT_PTR)this, 1000, TimerCallback);
+
+ return TRUE;
+}
+
+void ServerDialog::CreateColumns()
+{
+ AFX_MANAGE_STATE(AfxGetStaticModuleState());
+ PlayersListCtrl.InsertColumn(0, _T("Name"), LVCFMT_LEFT, 40);
+ PlayersListCtrl.InsertColumn(1, _T("Status"), LVCFMT_LEFT, 80);
+ PlayersListCtrl.InsertColumn(2, _T("Ping"), LVCFMT_LEFT, 40);
+ PlayersListCtrl.InsertColumn(3, _T("Score"), LVCFMT_LEFT, 80);
+ PlayersListCtrl.InsertColumn(4, _T("Team"), LVCFMT_LEFT, 80);
+
+ for (int i = 0; i < NumColumns; i++)
+ {
+ PlayersListCtrl.SetColumnWidth(i, LVSCW_AUTOSIZE_USEHEADER);
+ }
+}
+
+void ServerDialog::PostNcDestroy()
+{
+ AFX_MANAGE_STATE(AfxGetStaticModuleState());
+
+ CDialog::PostNcDestroy();
+}
+
+void ServerDialog::OnOK()
+{
+ AFX_MANAGE_STATE(AfxGetStaticModuleState());
+
+ if (!UpdateData(TRUE))
+ return;
+ DestroyWindow();
+}
+
+void ServerDialog::OnCancel()
+{
+ AFX_MANAGE_STATE(AfxGetStaticModuleState());
+
+ KillTimer((UINT_PTR)this);
+ ShowWindow(SW_HIDE);
+ DestroyWindow();
+}
+
+void ServerDialog::RefreshPlayers()
+{
+ if (!m_hWnd)
+ {
+ return;
+ }
+
+ AFX_MANAGE_STATE(AfxGetStaticModuleState());
+
+ const int savedSelection = PlayersListCtrl.GetSelectionMark();
+ PlayersListCtrl.DeleteAllItems();
+
+
+ const auto& pTextLookupService = m_pContainer->Get();
+ const auto& pGameServer = m_pContainer->Get();
+ for (const auto& player : pGameServer->GetPlayers())
+ {
+ if (player.host)
+ {
+ continue; // Skip host player
+ }
+
+ LVITEM item{};
+ item.cColumns = NumColumns;
+ item.mask = LVIF_COLUMNS | LVIF_PARAM;
+ 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.SetSelectionMark(savedSelection);
+}
+
+void ServerDialog::HandlePlayerConnected(const GameServerEvent& event)
+{
+ RefreshPlayers();
+}
+
+void ServerDialog::HandlePlayerDisconnected(const GameServerEvent& event)
+{
+ RefreshPlayers();
+}
+
+void ServerDialog::HandleChatMessage(const GameServerEvent& event)
+{
+ AFX_MANAGE_STATE(AfxGetStaticModuleState());
+
+ const auto& chatMessageEvent = (const ChatMessageEvent&)event;
+
+ ConsoleEditBox.SetSel(-1, 0);
+ ConsoleEditBox.ReplaceSel(chatMessageEvent.message.data());
+ ConsoleEditBox.SetSel(-1, 0);
+ ConsoleEditBox.ReplaceSel("\n");
+}
+
+void ServerDialog::HandleWorldLoaded(const GameServerEvent& event)
+{
+ AFX_MANAGE_STATE(AfxGetStaticModuleState());
+
+ const auto& pGameServer = m_pContainer->Get();
+
+ NetGameDetails details = pGameServer->GetGameDetails();
+
+ // TODO: Connect to world state controls
+}
+
+BEGIN_MESSAGE_MAP(ServerDialog, CDialogEx)
+ ON_BN_CLICKED(IDC_BAN, &ServerDialog::OnBnClickedBan)
+ ON_NOTIFY(LVN_ITEMCHANGED, IDC_PLAYERS, &ServerDialog::OnItemChanged)
+ ON_BN_CLICKED(IDC_KICK, &ServerDialog::OnBnClickedKick)
+END_MESSAGE_MAP()
+
+
+// ServerDialog message handlers
+
+void ServerDialog::OnBnClickedBan()
+{
+ const int selection = PlayersListCtrl.GetSelectionMark();
+ if (selection == -1)
+ {
+ return;
+ }
+
+ const PlayerIndex playerIndex = (PlayerIndex)PlayersListCtrl.GetItemData(selection);
+ if (playerIndex > 0)
+ {
+ const auto& pGameServer = m_pContainer->Get();
+ pGameServer->BanPlayer(playerIndex);
+ }
+}
+
+void ServerDialog::OnBnClickedKick()
+{
+ const int selection = PlayersListCtrl.GetSelectionMark();
+ if (selection == -1)
+ {
+ return;
+ }
+
+ const PlayerIndex playerIndex = (PlayerIndex)PlayersListCtrl.GetItemData(selection);
+ if (playerIndex > 0)
+ {
+ const auto& pGameServer = m_pContainer->Get();
+ pGameServer->KickPlayer(playerIndex, KickReason::Removed);
+ }
+}
+
+void ServerDialog::OnItemChanged(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ const LPNMLISTVIEW pNMListView = (const LPNMLISTVIEW)(pNMHDR);
+
+ if (!(pNMListView->uChanged & LVIF_STATE))
+ {
+ return;
+ }
+
+ if ((pNMListView->uOldState & LVIS_SELECTED) == (pNMListView->uNewState & LVIS_SELECTED))
+ {
+ return;
+ }
+
+ ButtonKick.EnableWindow(TRUE);
+ ButtonBan.EnableWindow(TRUE);
+
+ *pResult = 0;
+}
diff --git a/ServerConsoleExample/ServerDialog.h b/ServerConsoleExample/ServerDialog.h
new file mode 100644
index 0000000..2e992c6
--- /dev/null
+++ b/ServerConsoleExample/ServerDialog.h
@@ -0,0 +1,62 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+
+// ServerDialog dialog
+
+class ServerDialog : public CDialogEx, public ComponentBase
+{
+ DECLARE_DYNAMIC(ServerDialog)
+
+public:
+ ~ServerDialog();
+ ServerDialog(IComponentContainer* container, CWnd* parent = nullptr);
+
+ void CreateColumns();
+ void RefreshPlayers();
+
+ static void STDMETHODCALLTYPE TimerCallback(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime);
+ void STDMETHODCALLTYPE CloseDialog() override;
+ void STDMETHODCALLTYPE ShowDialog() override;
+
+ void HandlePlayerConnected(const GameServerEvent& event);
+ void HandlePlayerDisconnected(const GameServerEvent& event);
+ void HandleChatMessage(const GameServerEvent& event);
+ void HandleWorldLoaded(const GameServerEvent& event);
+
+ // MFC methods
+ BOOL OnInitDialog() override;
+ void PostNcDestroy() override;
+ void OnOK() override;
+ void OnCancel() override;
+
+// Dialog Data
+#ifdef AFX_DESIGN_TIME
+ enum { IDD = IDD_SERVER };
+#endif
+
+private:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+
+ DECLARE_MESSAGE_MAP()
+
+ CEdit ConsoleEditBox;
+ CListCtrl PlayersListCtrl;
+ CButton ButtonBan;
+ CButton ButtonKick;
+
+ afx_msg void OnBnClickedKick();
+ afx_msg void OnBnClickedBan();
+ afx_msg void OnItemChanged(NMHDR* pNMHDR, LRESULT* pResult);
+
+ UUID m_playerConnectedEventHandle{};
+ UUID m_playerDisconnectedEventHandle{};
+ UUID m_playerChatMessageHandle{};
+ UUID m_worldLoadedHandle{};
+
+ const int NumColumns = 5;
+};
diff --git a/ServerConsoleExample/Utils.cpp b/ServerConsoleExample/Utils.cpp
new file mode 100644
index 0000000..471bbea
--- /dev/null
+++ b/ServerConsoleExample/Utils.cpp
@@ -0,0 +1,12 @@
+#include "pch.h"
+
+#include
+
+#include "Utils.h"
+
+std::wstring to_wstring(const std::string_view& sourceString)
+{
+ std::wstring_convert> converter;
+
+ return converter.from_bytes(sourceString.data());
+}
\ No newline at end of file
diff --git a/ServerConsoleExample/Utils.h b/ServerConsoleExample/Utils.h
new file mode 100644
index 0000000..cb59597
--- /dev/null
+++ b/ServerConsoleExample/Utils.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#include
+
+std::wstring to_wstring(const std::string_view& sourceString);
diff --git a/ServerConsoleExample/framework.h b/ServerConsoleExample/framework.h
new file mode 100644
index 0000000..5175c5a
--- /dev/null
+++ b/ServerConsoleExample/framework.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+#endif
+
+#include "targetver.h"
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
+
+#include // MFC core and standard components
+#include // MFC extensions
+
+#ifndef _AFX_NO_OLE_SUPPORT
+#include // MFC OLE classes
+#include // MFC OLE dialog classes
+#include // MFC Automation classes
+#endif // _AFX_NO_OLE_SUPPORT
+
+#ifndef _AFX_NO_DB_SUPPORT
+#include // MFC ODBC database classes
+#endif // _AFX_NO_DB_SUPPORT
+
+#ifndef _AFX_NO_DAO_SUPPORT
+#include // MFC DAO database classes
+#endif // _AFX_NO_DAO_SUPPORT
+
+#ifndef _AFX_NO_OLE_SUPPORT
+#include // MFC support for Internet Explorer 4 Common Controls
+#endif
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include // MFC support for Windows Common Controls
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+
diff --git a/ServerConsoleExample/pch.cpp b/ServerConsoleExample/pch.cpp
new file mode 100644
index 0000000..64b7eef
--- /dev/null
+++ b/ServerConsoleExample/pch.cpp
@@ -0,0 +1,5 @@
+// pch.cpp: source file corresponding to the pre-compiled header
+
+#include "pch.h"
+
+// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
diff --git a/ServerConsoleExample/pch.h b/ServerConsoleExample/pch.h
new file mode 100644
index 0000000..add9e33
--- /dev/null
+++ b/ServerConsoleExample/pch.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include
+
+// AFX includes:
+#include "framework.h"
+#include "afxdialogex.h"
+
+// STL includes:
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+// Third party:
+#pragma warning(push, 1)
+#pragma warning (disable : ALL_CODE_ANALYSIS_WARNINGS)
+#include
+#pragma warning(pop)
\ No newline at end of file
diff --git a/ServerConsoleExample/res/ServerConsole.rc2 b/ServerConsoleExample/res/ServerConsole.rc2
new file mode 100644
index 0000000..4c16fbb
Binary files /dev/null and b/ServerConsoleExample/res/ServerConsole.rc2 differ
diff --git a/ServerConsoleExample/resource.h b/ServerConsoleExample/resource.h
new file mode 100644
index 0000000..5e4de71
--- /dev/null
+++ b/ServerConsoleExample/resource.h
@@ -0,0 +1,27 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by ServerConsole.rc
+//
+#define IDD_SERVER 132
+#define IDC_GAMETYPE 133
+#define IDC_TEAMS 134
+#define IDC_WORLD 135
+#define IDC_PLAYERS 136
+#define IDC_ROTATIONS 137
+#define IDC_ROTATION 138
+#define IDC_TIMEREMAINING 139
+#define IDC_BAN 140
+#define IDC_KICK 141
+#define IDC_INPUT 142
+#define IDC_CONSOLE 143
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 1000
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 1000
+#endif
+#endif
diff --git a/ServerConsoleExample/targetver.h b/ServerConsoleExample/targetver.h
new file mode 100644
index 0000000..87c0086
--- /dev/null
+++ b/ServerConsoleExample/targetver.h
@@ -0,0 +1,8 @@
+#pragma once
+
+// Including SDKDDKVer.h defines the highest available Windows platform.
+
+// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
+// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
+
+#include