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.
416 lines
12 KiB
416 lines
12 KiB
//========= 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)); |
|
}
|
|
|