You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
417 lines
12 KiB
417 lines
12 KiB
5 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
// $NoKeywords: $
|
||
|
//=============================================================================
|
||
|
|
||
|
#include <stdio.h>
|
||
|
|
||
|
#include "BanPanel.h"
|
||
|
#include "PlayerContextMenu.h"
|
||
|
#include "DialogAddBan.h"
|
||
|
|
||
|
#include <vgui/Cursor.h>
|
||
|
#include <vgui/ISystem.h>
|
||
|
#include <vgui/ISurface.h>
|
||
|
#include <vgui/ILocalize.h>
|
||
|
#include <vgui/IVGui.h>
|
||
|
#include <KeyValues.h>
|
||
|
|
||
|
#include <vgui_controls/Label.h>
|
||
|
#include <vgui_controls/Button.h>
|
||
|
#include <vgui_controls/QueryBox.h>
|
||
|
#include <vgui_controls/ListPanel.h>
|
||
|
#include <vgui_controls/FileOpenDialog.h>
|
||
|
|
||
|
#include "filesystem.h"
|
||
|
|
||
|
#include "DialogCvarChange.h"
|
||
|
#include "tokenline.h"
|
||
|
|
||
|
using namespace vgui;
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Constructor
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CBanPanel::CBanPanel(vgui::Panel *parent, const char *name) : PropertyPage(parent, name)
|
||
|
{
|
||
|
m_pBanListPanel = new ListPanel(this, "BanList");
|
||
|
m_pBanListPanel->AddColumnHeader(0, "type", "#Ban_List_Type", 150 );
|
||
|
m_pBanListPanel->AddColumnHeader(1, "id", "#Ban_List_ID", 200 );
|
||
|
m_pBanListPanel->AddColumnHeader(2, "time", "#Ban_List_Time", 200 );
|
||
|
m_pBanListPanel->SetSortColumn(2);
|
||
|
m_pBanListPanel->SetEmptyListText("#Ban_List_Empty");
|
||
|
|
||
|
m_pAddButton = new Button(this, "Add", "#Ban_List_Add");
|
||
|
m_pRemoveButton = new Button(this, "Remove", "#Ban_List_Remove");
|
||
|
m_pChangeButton = new Button(this, "Change", "#Ban_List_Edit");
|
||
|
m_pImportButton = new Button(this, "Import", "#Ban_List_Import");
|
||
|
|
||
|
m_pAddButton->SetCommand(new KeyValues("addban"));
|
||
|
m_pRemoveButton->SetCommand(new KeyValues("removeban"));
|
||
|
m_pChangeButton->SetCommand(new KeyValues("changeban"));
|
||
|
m_pImportButton->SetCommand(new KeyValues("importban"));
|
||
|
|
||
|
m_pBanContextMenu = new CBanContextMenu(this);
|
||
|
m_pBanContextMenu->SetVisible(false);
|
||
|
|
||
|
m_flUpdateTime = 0.0f;
|
||
|
m_bPageViewed = false;
|
||
|
|
||
|
LoadControlSettings("Admin/BanPanel.res", "PLATFORM");
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Destructor
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CBanPanel::~CBanPanel()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Activates the page
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBanPanel::OnPageShow()
|
||
|
{
|
||
|
BaseClass::OnPageShow();
|
||
|
OnItemSelected();
|
||
|
if (!m_bPageViewed)
|
||
|
{
|
||
|
m_bPageViewed = true;
|
||
|
// force update on first page view
|
||
|
m_flUpdateTime = 0.0f;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Requests new data set from server
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBanPanel::OnResetData()
|
||
|
{
|
||
|
RemoteServer().RequestValue(this, "banlist");
|
||
|
// update once every 5 minutes
|
||
|
m_flUpdateTime = (float)system()->GetFrameTime() + (60 * 5.0f);
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Checks to see if the page data should be refreshed
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBanPanel::OnThink()
|
||
|
{
|
||
|
if (m_flUpdateTime < system()->GetFrameTime())
|
||
|
{
|
||
|
OnResetData();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Wrap g_pVGuiLocalize->Find() and not return NULL
|
||
|
//-----------------------------------------------------------------------------
|
||
|
static const wchar_t * LocalizeFind( const char *identifier, const wchar_t *defaultText )
|
||
|
{
|
||
|
const wchar_t *str = g_pVGuiLocalize->Find(identifier);
|
||
|
if ( !str )
|
||
|
str = defaultText;
|
||
|
return str;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Received response from server containing data
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBanPanel::OnServerDataResponse(const char *value, const char *response)
|
||
|
{
|
||
|
// build the list
|
||
|
if (!stricmp(value, "banlist"))
|
||
|
{
|
||
|
// clear current list
|
||
|
m_pBanListPanel->DeleteAllItems();
|
||
|
|
||
|
// scan through response for all items
|
||
|
int item = 0;
|
||
|
float banTime = 0.0f;
|
||
|
char id[64] = { 0 };
|
||
|
while (3 == sscanf(response, "%i %s : %f min\n", &item, id, &banTime))
|
||
|
{
|
||
|
KeyValues *ban = new KeyValues("ban");
|
||
|
|
||
|
// determine type
|
||
|
if (IsIPAddress(id))
|
||
|
{
|
||
|
// ip address
|
||
|
ban->SetWString("type", LocalizeFind("#Ban_IP", L"IP Address"));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// must be a userID
|
||
|
ban->SetWString("type", LocalizeFind("#Ban_Auth_ID", L"AuthID"));
|
||
|
}
|
||
|
ban->SetString("id", id);
|
||
|
|
||
|
if (banTime > 0.0f)
|
||
|
{
|
||
|
ban->SetFloat("time", banTime);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ban->SetWString("time", LocalizeFind("#Ban_Permanent", L"permanent"));
|
||
|
}
|
||
|
|
||
|
// add to list
|
||
|
m_pBanListPanel->AddItem(ban, 0, false, false);
|
||
|
|
||
|
// move to the next item
|
||
|
response = (const char *)strchr(response, '\n');
|
||
|
if (!response)
|
||
|
break;
|
||
|
response++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Refreshes the list on the user hitting F5
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBanPanel::OnKeyCodeTyped(vgui::KeyCode code)
|
||
|
{
|
||
|
if (code == KEY_F5)
|
||
|
{
|
||
|
OnResetData();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
BaseClass::OnKeyCodeTyped(code);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: opens context menu (user right clicked on a server)
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBanPanel::OnOpenContextMenu(int row)
|
||
|
{
|
||
|
/* CONTEXT MENU CODE TEMPORARILY DISABLED UNTIL VERIFIED AS WORKING
|
||
|
if (m_pBanListPanel->IsVisible() && m_pBanListPanel->IsCursorOver()
|
||
|
&& m_pBanListPanel->GetNumSelectedRows())
|
||
|
// show the ban changing menu IF its the visible panel and the cursor is
|
||
|
// over it
|
||
|
{
|
||
|
|
||
|
unsigned int banID =m_pBanListPanel->GetSelectedRow(0);
|
||
|
|
||
|
// activate context menu
|
||
|
m_pBanContextMenu->ShowMenu(this, banID);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_pBanContextMenu->ShowMenu(this, -1);
|
||
|
}
|
||
|
*/
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Manually adds a new ban
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBanPanel::AddBan()
|
||
|
{
|
||
|
CDialogAddBan *box = new CDialogAddBan(this);
|
||
|
box->AddActionSignalTarget(this);
|
||
|
box->Activate("addban", "", "");
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: prompts the user to remove an existing ban
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBanPanel::RemoveBan()
|
||
|
{
|
||
|
int itemID = m_pBanListPanel->GetSelectedItem(0);
|
||
|
if ( itemID == -1 )
|
||
|
return;
|
||
|
|
||
|
// ask the user whether or not they want to remove the ban
|
||
|
KeyValues *kv = m_pBanListPanel->GetItem(itemID);
|
||
|
if (kv != NULL)
|
||
|
{
|
||
|
// build the message
|
||
|
wchar_t id[256];
|
||
|
g_pVGuiLocalize->ConvertANSIToUnicode(kv->GetString("id"), id, sizeof(id));
|
||
|
wchar_t message[256];
|
||
|
g_pVGuiLocalize->ConstructString(message, sizeof(message), g_pVGuiLocalize->Find("#Ban_Remove_Msg"), 1, id);
|
||
|
|
||
|
// activate the confirmation dialog
|
||
|
QueryBox *box = new QueryBox(g_pVGuiLocalize->Find("#Ban_Title_Remove"), message);
|
||
|
box->SetOKCommand(new KeyValues("removebanbyid", "id", kv->GetString("id")));
|
||
|
box->AddActionSignalTarget(this);
|
||
|
box->DoModal();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: change the time length of a ban
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBanPanel::ChangeBan()
|
||
|
{
|
||
|
int itemID = m_pBanListPanel->GetSelectedItem(0);
|
||
|
if (itemID == -1)
|
||
|
return;
|
||
|
|
||
|
KeyValues *kv = m_pBanListPanel->GetItem(itemID);
|
||
|
if (kv != NULL)
|
||
|
{
|
||
|
char timeText[20];
|
||
|
float time = kv->GetFloat("time");
|
||
|
_snprintf(timeText, sizeof(timeText), "%0.2f", time);
|
||
|
|
||
|
// open a dialog asking them what time to change the ban lenght to
|
||
|
CDialogCvarChange *box = new CDialogCvarChange(this);
|
||
|
box->AddActionSignalTarget(this);
|
||
|
box->SetTitle("#Ban_Title_Change", true);
|
||
|
box->Activate(kv->GetString("id"), timeText, "changeban", "#Ban_Change_Time");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Removes the specified ban
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBanPanel::RemoveBanByID(const char *id)
|
||
|
{
|
||
|
Assert(id && *id);
|
||
|
if (!id || !*id)
|
||
|
return;
|
||
|
|
||
|
// send down the command
|
||
|
char cmd[512];
|
||
|
_snprintf(cmd, sizeof(cmd) -1, "%s %s\n", IsIPAddress(id) ? "removeip" : "removeid", id);
|
||
|
RemoteServer().SendCommand(cmd);
|
||
|
|
||
|
// force the file to be written
|
||
|
if (IsIPAddress(id))
|
||
|
{
|
||
|
RemoteServer().SendCommand("writeip");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
RemoteServer().SendCommand("writeid");
|
||
|
}
|
||
|
|
||
|
// refresh
|
||
|
OnResetData();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Changes a ban
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBanPanel::ChangeBanTimeByID(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";
|
||
|
}
|
||
|
|
||
|
// send down the command
|
||
|
char cmd[512];
|
||
|
_snprintf(cmd, sizeof(cmd) -1, "%s %s %s\n", IsIPAddress(id) ? "addip" : "banid", newtime, id);
|
||
|
RemoteServer().SendCommand(cmd);
|
||
|
if (IsIPAddress(id))
|
||
|
{
|
||
|
RemoteServer().SendCommand("writeip");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
RemoteServer().SendCommand("writeid");
|
||
|
}
|
||
|
|
||
|
// refresh
|
||
|
OnResetData();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Changes a ban
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBanPanel::OnCvarChangeValue( KeyValues *kv )
|
||
|
{
|
||
|
const char *idText = kv->GetString( "player", "" );
|
||
|
const char *durationText = kv->GetString( "value", "0" );
|
||
|
|
||
|
ChangeBanTimeByID( idText, durationText );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: called when a row on the list panel is selected.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBanPanel::OnItemSelected()
|
||
|
{
|
||
|
int itemID = m_pBanListPanel->GetSelectedItem(0);
|
||
|
if (itemID == -1)
|
||
|
{
|
||
|
m_pRemoveButton->SetEnabled(false);
|
||
|
m_pChangeButton->SetEnabled(false);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_pRemoveButton->SetEnabled(true);
|
||
|
m_pChangeButton->SetEnabled(true);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Asks the user for the ban file to import
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBanPanel::ImportBanList()
|
||
|
{
|
||
|
// Pop up the dialog
|
||
|
FileOpenDialog *pFileDialog = new FileOpenDialog(this, "#Ban_Find_Ban_File", true);
|
||
|
pFileDialog->AddFilter( "*.cfg", "#Config_files", true );
|
||
|
pFileDialog->AddFilter( "*.*", "#All_files", false );
|
||
|
pFileDialog->DoModal(true);
|
||
|
pFileDialog->Activate();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: When a file is selected print out its full path in the debugger
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBanPanel::OnFileSelected(const char *fullpath)
|
||
|
{
|
||
|
char line[255];
|
||
|
TokenLine tok;
|
||
|
|
||
|
// this can take a while, put up a waiting cursor
|
||
|
surface()->SetCursor(dc_hourglass);
|
||
|
|
||
|
// we don't use filesystem() here becuase we want to let the user pick
|
||
|
// a file from anywhere on their filesystem... so we use stdio
|
||
|
FILE *f = fopen(fullpath,"rb");
|
||
|
while (!feof(f) && fgets(line, 255, f))
|
||
|
{
|
||
|
// parse each line of the config file adding the ban
|
||
|
tok.SetLine(line);
|
||
|
if (tok.CountToken() == 3)
|
||
|
{
|
||
|
// add the ban
|
||
|
const char *id = tok.GetToken(2);
|
||
|
ChangeBanTimeByID(id, "0");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// change the cursor back to normal and shutdown file
|
||
|
surface()->SetCursor(dc_user);
|
||
|
if (f)
|
||
|
{
|
||
|
fclose(f);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: returns true if the id string is an IP address, false if it's a WON or STEAM ID
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CBanPanel::IsIPAddress(const char *id)
|
||
|
{
|
||
|
int s1, s2, s3, s4;
|
||
|
return (4 == sscanf(id, "%d.%d.%d.%d", &s1, &s2, &s3, &s4));
|
||
|
}
|