diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /tracker/AdminServer/PlayerPanel.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'tracker/AdminServer/PlayerPanel.cpp')
| -rw-r--r-- | tracker/AdminServer/PlayerPanel.cpp | 401 |
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); + } +} |