1
0
mirror of https://github.com/ncblakely/GiantsTools synced 2024-11-04 22:35:37 +01:00
GiantsTools/ServerConsoleExample/ServerDialog.cpp

249 lines
6.3 KiB
C++
Raw Normal View History

#include "pch.h"
#include "ServerConsoleApp.h"
#include "ServerDialog.h"
IMPLEMENT_DYNAMIC(ServerDialog, CDialogEx)
ServerDialog::ServerDialog(IComponentContainer* container, CWnd* parent)
: ComponentBase(container),
CDialogEx(IDD_SERVER, parent)
{
const auto& pGameServer = m_pContainer->Get<IGameServer>();
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<IGameServer>();
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());
2020-12-21 09:38:20 +01:00
ShowWindow(SW_HIDE);
DestroyWindow();
2020-12-21 09:38:20 +01:00
KillTimer((UINT_PTR)this);
m_pParentWnd->SendMessage(WM_CLOSE, 0, 0);
}
void ServerDialog::RefreshPlayers()
{
if (!m_hWnd)
{
return;
}
AFX_MANAGE_STATE(AfxGetStaticModuleState());
const int savedSelection = PlayersListCtrl.GetSelectionMark();
PlayersListCtrl.DeleteAllItems();
const auto& pTextLookupService = m_pContainer->Get<ITextLookupService>();
const auto& pGameServer = m_pContainer->Get<IGameServer>();
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<IGameServer>();
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<IGameServer>();
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<IGameServer>();
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;
}