summaryrefslogtreecommitdiff
path: root/tracker/AdminServer/PlayerPanel.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /tracker/AdminServer/PlayerPanel.cpp
downloadarchived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.tar.xz
archived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.zip
Diffstat (limited to 'tracker/AdminServer/PlayerPanel.cpp')
-rw-r--r--tracker/AdminServer/PlayerPanel.cpp401
1 files changed, 401 insertions, 0 deletions
diff --git a/tracker/AdminServer/PlayerPanel.cpp b/tracker/AdminServer/PlayerPanel.cpp
new file mode 100644
index 0000000..9a7eba0
--- /dev/null
+++ b/tracker/AdminServer/PlayerPanel.cpp
@@ -0,0 +1,401 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================
+
+#include <stdio.h>
+
+#include "PlayerPanel.h"
+#include "PlayerContextMenu.h"
+#include "PlayerListCompare.h"
+#include "DialogAddBan.h"
+
+#include <vgui/ISystem.h>
+#include <vgui/ISurface.h>
+#include <vgui/ILocalize.h>
+#include <vgui/IVGui.h>
+#include <vgui/KeyCode.h>
+#include <KeyValues.h>
+
+#include <vgui_controls/Button.h>
+#include <vgui_controls/ListPanel.h>
+#include <vgui_controls/QueryBox.h>
+
+using namespace vgui;
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CPlayerPanel::CPlayerPanel(vgui::Panel *parent, const char *name) : vgui::PropertyPage(parent, name)
+{
+ m_pPlayerListPanel = new vgui::ListPanel(this, "Players list");
+
+ m_pPlayerListPanel->AddColumnHeader(0, "name", "#Player_Panel_Name", 200, ListPanel::COLUMN_RESIZEWITHWINDOW );
+ m_pPlayerListPanel->AddColumnHeader(1, "authid", "#Player_Panel_ID", 100);
+ m_pPlayerListPanel->AddColumnHeader(2, "ping", "#Player_Panel_Ping", 50);
+ m_pPlayerListPanel->AddColumnHeader(3, "loss", "#Player_Panel_Loss", 50);
+ m_pPlayerListPanel->AddColumnHeader(4, "frags", "#Player_Panel_Frags", 50);
+ m_pPlayerListPanel->AddColumnHeader(5, "time", "#Player_Panel_Time", 75);
+
+/*
+ // TODO: update me!!
+ m_pPlayerListPanel->SetSortFunc(0, PlayerNameCompare);
+ m_pPlayerListPanel->SetSortFunc(1, PlayerAuthCompare);
+ m_pPlayerListPanel->SetSortFunc(2, PlayerPingCompare);
+ m_pPlayerListPanel->SetSortFunc(3, PlayerLossCompare);
+ m_pPlayerListPanel->SetSortFunc(4, PlayerFragsCompare);
+*/
+ m_pPlayerListPanel->SetSortFunc(5, PlayerTimeCompare);
+ m_pPlayerListPanel->SetEmptyListText("#Player_Panel_No_Players");
+ // Sort by ping time by default
+ m_pPlayerListPanel->SetSortColumn(0);
+
+ m_pKickButton = new Button(this, "Kick", "#Player_Panel_Kick");
+ m_pBanButton = new Button(this, "Ban", "#Player_Panel_Ban");
+
+ m_pPlayerContextMenu = new CPlayerContextMenu(this);
+ m_pPlayerContextMenu->SetVisible(false);
+
+ LoadControlSettings("Admin/PlayerPanel.res", "PLATFORM");
+
+ m_pKickButton->SetCommand(new KeyValues("KickPlayer"));
+ m_pBanButton->SetCommand(new KeyValues("BanPlayer"));
+
+ OnItemSelected(); // disable the buttons
+
+ m_flUpdateTime = 0.0f;
+ RemoteServer().AddServerMessageHandler(this, "UpdatePlayers");
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Destructor
+//-----------------------------------------------------------------------------
+CPlayerPanel::~CPlayerPanel()
+{
+ RemoteServer().RemoveServerDataResponseTarget(this);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Rebuilds player info
+//-----------------------------------------------------------------------------
+void CPlayerPanel::OnResetData()
+{
+ RemoteServer().RequestValue(this, "playerlist");
+
+ // update once every minute
+ m_flUpdateTime = (float)system()->GetFrameTime() + (60 * 1.0f);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Checks to see if we should update player info
+//-----------------------------------------------------------------------------
+void CPlayerPanel::OnThink()
+{
+ if (m_flUpdateTime < vgui::system()->GetFrameTime())
+ {
+ OnResetData();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Refreshes page if user hits F5
+//-----------------------------------------------------------------------------
+void CPlayerPanel::OnKeyCodeTyped(vgui::KeyCode code)
+{
+ if (code == KEY_F5)
+ {
+ OnResetData();
+ }
+ else
+ {
+ BaseClass::OnKeyCodeTyped(code);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns data on the player who is currently selected in the list
+//-----------------------------------------------------------------------------
+KeyValues *CPlayerPanel::GetSelected()
+{
+ return m_pPlayerListPanel->GetItem(m_pPlayerListPanel->GetSelectedItem(0));
+}
+
+static const char *FormatSeconds( int seconds )
+{
+ static char string[64];
+
+ int hours = 0;
+ int minutes = seconds / 60;
+
+ if ( minutes > 0 )
+ {
+ seconds -= (minutes * 60);
+ hours = minutes / 60;
+
+ if ( hours > 0 )
+ {
+ minutes -= (hours * 60);
+ }
+ }
+
+ if ( hours > 0 )
+ {
+ Q_snprintf( string, sizeof(string), "%2i:%02i:%02i", hours, minutes, seconds );
+ }
+ else
+ {
+ Q_snprintf( string, sizeof(string), "%02i:%02i", minutes, seconds );
+ }
+
+ return string;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: called when the server has returned a requested value
+//-----------------------------------------------------------------------------
+void CPlayerPanel::OnServerDataResponse(const char *value, const char *response)
+{
+ if (!stricmp(value, "UpdatePlayers"))
+ {
+ // server has indicated a change, force an update
+ m_flUpdateTime = 0.0f;
+ }
+ else if (!stricmp(value, "playerlist"))
+ {
+ // new list of players
+ m_pPlayerListPanel->DeleteAllItems();
+
+ // parse response
+ const char *parse = response;
+ while (parse && *parse)
+ {
+ // first should be the size of the player name
+ char name[64];
+ name[0] = '\0';
+ char authID[64];
+ authID[0] = '\0';
+ char netAdr[32];
+ netAdr[0] = '\0';
+ int ping = 0, packetLoss = 0, frags = 0, connectTime = 0;
+
+ ivgui()->DPrintf2("orig: %s\n", parse);
+
+ // parse out the name, which is quoted
+ Assert(*parse == '\"');
+ if (*parse != '\"')
+ break;
+ ++parse; // move past start quote
+ int pos = 0;
+ while (*parse && *parse != '\"')
+ {
+ name[pos++] = *parse;
+ parse++;
+ }
+ name[pos] = 0;
+ parse++; // move past end quote
+
+ if (6 != sscanf(parse, " %s %s %d %d %d %d\n", authID, netAdr, &ping, &packetLoss, &frags, &connectTime))
+ break;
+
+ const char *timeStr = FormatSeconds(connectTime);
+
+ ivgui()->DPrintf2("pars: \"%s\" %s %s %d %d %d %s\n", name, authID, netAdr, ping, packetLoss, frags, timeStr);
+
+ // add to list
+ KeyValues *player = new KeyValues("Player");
+ player->SetString("name", name);
+ player->SetString("authID", authID);
+ player->SetString("netAdr", netAdr);
+ player->SetInt("ping", ping);
+ player->SetInt("loss", packetLoss);
+ player->SetInt("frags", frags);
+ player->SetString("time", timeStr);
+ m_pPlayerListPanel->AddItem(player, 0, false, false);
+
+ // move to next line
+ parse = strchr(parse, '\n');
+ if (parse)
+ {
+ parse++;
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Buttom command handlers
+//-----------------------------------------------------------------------------
+void CPlayerPanel::OnCommand(const char *command)
+{
+ BaseClass::OnCommand(command);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles the UI for kicking a player from the server
+//-----------------------------------------------------------------------------
+void CPlayerPanel::OnKickButtonPressed()
+{
+ if (m_pPlayerListPanel->GetSelectedItemsCount() < 1)
+ return;
+
+ // open a message box to ask the user if they want to follow through on this
+ QueryBox *box;
+ if (m_pPlayerListPanel->GetSelectedItemsCount() > 1)
+ {
+ box = new QueryBox("#Kick_Multiple_Players_Title", "#Kick_Multiple_Players_Question");
+ }
+ else
+ {
+ // show the player name in the message box if only one player is being booted
+ KeyValues *kv = m_pPlayerListPanel->GetItem(m_pPlayerListPanel->GetSelectedItem(0));
+ Assert(kv != NULL);
+ if (!kv)
+ return;
+
+ wchar_t playerName[64];
+ g_pVGuiLocalize->ConvertANSIToUnicode( kv->GetString("name"), playerName, sizeof(playerName) );
+
+ wchar_t msg[512];
+ g_pVGuiLocalize->ConstructString( msg, sizeof(msg), g_pVGuiLocalize->Find("Kick_Single_Player_Question"), 1, playerName );
+ box = new QueryBox(g_pVGuiLocalize->Find("#Kick_Single_Player_Title"), msg);
+ }
+ box->AddActionSignalTarget(this);
+ box->SetOKCommand(new KeyValues("KickSelectedPlayers"));
+ box->ShowWindow();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Prompts a user to be banned
+//-----------------------------------------------------------------------------
+void CPlayerPanel::OnBanButtonPressed()
+{
+ if (m_pPlayerListPanel->GetSelectedItemsCount() != 1)
+ return;
+
+ // open a message box to ask the user if they want to follow through on this
+ KeyValues *kv = m_pPlayerListPanel->GetItem(m_pPlayerListPanel->GetSelectedItem(0));
+ Assert(kv != NULL);
+ if (!kv)
+ return;
+
+ const char *player = kv->GetString("name");
+ const char *authid = kv->GetString("authid");
+ const char *netAdr = kv->GetString("netAdr");
+
+ char buf[64];
+ if ( !strcmp( authid, "UNKNOWN" ) )
+ {
+ int s1, s2, s3, s4;
+ if (4 == sscanf(netAdr, "%d.%d.%d.%d", &s1, &s2, &s3, &s4))
+ {
+ Q_snprintf( buf, sizeof(buf), "%d.%d.%d.%d", s1, s2, s3, s4 );
+ authid = buf;
+ }
+ }
+
+ CDialogAddBan *box = new CDialogAddBan(this);
+ box->AddActionSignalTarget(this);
+ box->Activate("addban", player, authid);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Kicks all the players currently selected
+//-----------------------------------------------------------------------------
+void CPlayerPanel::KickSelectedPlayers()
+{
+ for (int i = 0; i < m_pPlayerListPanel->GetSelectedItemsCount(); i++)
+ {
+ // get the player info
+ int row = m_pPlayerListPanel->GetSelectedItem(i);
+ KeyValues *pl = m_pPlayerListPanel->GetItem(row);
+ if (!pl)
+ continue;
+
+ // kick 'em
+ char cmd[512];
+ _snprintf(cmd, sizeof(cmd), "kick \"%s\"", pl->GetString("name"));
+ RemoteServer().SendCommand(cmd);
+ }
+
+ m_pPlayerListPanel->ClearSelectedItems();
+ m_pKickButton->SetEnabled(false);
+ m_pBanButton->SetEnabled(false);
+ OnResetData();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Adds a new ban
+//-----------------------------------------------------------------------------
+void CPlayerPanel::AddBanByID(const char *id, const char *newtime)
+{
+ Assert(id && *id);
+ if (!id || !*id)
+ return;
+
+ // if the newtime string is not valid, then set it to 0 (permanent ban)
+ if (!newtime || atof(newtime) < 0.001)
+ {
+ newtime = "0";
+ }
+
+ const char *banCmd = "banid";
+ const char *saveCmd = "writeip";
+ int s1, s2, s3, s4;
+ if (4 == sscanf(id, "%d.%d.%d.%d", &s1, &s2, &s3, &s4))
+ {
+ banCmd = "addip";
+ saveCmd = "writeid";
+ }
+
+ // send down the ban command
+ char cmd[512];
+ _snprintf(cmd, sizeof(cmd) -1, "%s %s %s\n", banCmd, newtime, id);
+ RemoteServer().SendCommand(cmd);
+
+ // force the file to update
+ RemoteServer().SendCommand(saveCmd);
+
+ // refresh
+ OnResetData();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: opens context menu (user right clicked on a server)
+//-----------------------------------------------------------------------------
+void CPlayerPanel::OnOpenContextMenu(int itemID)
+{
+/* CODE DISABLED UNTIL VERIFIED AS WORKING
+ // show the player menus only if the cursor is over it
+ if (IsCursorOver() && m_pPlayerListPanel->GetNumSelectedRows())
+ {
+ // get the server
+ unsigned int playerID = m_pPlayerListPanel->GetDataItem(m_pPlayerListPanel->GetSelectedRow(0))->userData;
+
+ // activate context menu
+ m_pPlayerContextMenu->ShowMenu(this, playerID);
+ }
+*/
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: called when an item on the list panel is selected.
+//-----------------------------------------------------------------------------
+void CPlayerPanel::OnItemSelected()
+{
+ bool state = true;
+
+ if ( m_pPlayerListPanel->GetSelectedItemsCount() == 0 )
+ {
+ state = false;
+ }
+
+ m_pKickButton->SetEnabled(state);
+ m_pBanButton->SetEnabled(state);
+
+ if ( m_pPlayerListPanel->GetSelectedItemsCount() > 1 )
+ {
+ m_pBanButton->SetEnabled(false);
+ }
+}