Make the vpc actually build a project

libtcmalloc_minimal.so from cstrike linux
This commit is contained in:
2020-12-25 17:29:40 +01:00
parent 8d1c389b3c
commit 0acc2c38ae
134 changed files with 5 additions and 5 deletions

View File

@ -0,0 +1,197 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "AdminServer.h"
#include "IRunGameEngine.h"
#include "IGameServerData.h"
#include "GamePanelInfo.h"
#include "ivprofexport.h"
#include <vgui/ISystem.h>
#include <vgui/IPanel.h>
#include <vgui/IVGui.h>
#include <vgui/ILocalize.h>
#include <KeyValues.h>
#include "filesystem.h"
// expose the server browser interfaces
CAdminServer g_AdminServerSingleton;
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CAdminServer, IAdminServer, ADMINSERVER_INTERFACE_VERSION, g_AdminServerSingleton);
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CAdminServer, IVGuiModule, "VGuiModuleAdminServer001", g_AdminServerSingleton);
IGameServerData *g_pGameServerData = NULL;
IVProfExport *g_pVProfExport = NULL;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CAdminServer::CAdminServer()
{
// fill in the 0-based element of the manage servers list
OpenedManageDialog_t empty = { 0, NULL };
m_OpenedManageDialog.AddToTail(empty);
m_hParent=0;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CAdminServer::~CAdminServer()
{
}
//-----------------------------------------------------------------------------
// Purpose: links to vgui and engine interfaces
//-----------------------------------------------------------------------------
bool CAdminServer::Initialize(CreateInterfaceFn *factorylist, int factoryCount)
{
ConnectTier1Libraries( factorylist, factoryCount );
ConVar_Register();
ConnectTier2Libraries( factorylist, factoryCount );
ConnectTier3Libraries( factorylist, factoryCount );
// find our interfaces
for (int i = 0; i < factoryCount; i++)
{
// if we're running locally we can get this direct interface to the game engine
if (!g_pGameServerData)
{
g_pGameServerData = (IGameServerData *)(factorylist[i])(GAMESERVERDATA_INTERFACE_VERSION, NULL);
}
if ( !g_pVProfExport )
{
g_pVProfExport = (IVProfExport*)(factorylist[i])( VPROF_EXPORT_INTERFACE_VERSION, NULL );
}
}
RemoteServer().Initialize(); // now we have the game date interface, initialize the engine connection
if ( vgui::VGui_InitInterfacesList("AdminServer", factorylist, factoryCount) )
{
// load localization file
g_pVGuiLocalize->AddFile( "admin/admin_%language%.txt");
return true;
}
return false;
}
//-----------------------------------------------------------------------------
// Purpose: links to other modules interfaces (tracker)
//-----------------------------------------------------------------------------
bool CAdminServer::PostInitialize(CreateInterfaceFn *modules, int factoryCount)
{
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CAdminServer::IsValid()
{
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CAdminServer::Activate()
{
return true;
}
//-----------------------------------------------------------------------------
// Purpose: returns direct handle to main server browser dialog
//-----------------------------------------------------------------------------
vgui::VPANEL CAdminServer::GetPanel()
{
return NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Closes down the server browser for good
//-----------------------------------------------------------------------------
void CAdminServer::Shutdown()
{
DisconnectTier3Libraries();
DisconnectTier2Libraries();
ConVar_Unregister();
DisconnectTier1Libraries();
}
void CAdminServer::SetParent(vgui::VPANEL parent)
{
/* if (m_hServerPage.Get())
{
m_hServerPage->SetParent(parent);
}
*/
m_hParent = parent;
}
//-----------------------------------------------------------------------------
// Purpose: Called when the user enters the game
//-----------------------------------------------------------------------------
void CAdminServer::Deactivate()
{
}
//-----------------------------------------------------------------------------
// Purpose: Called when the user returns from the game to the outside UI
//-----------------------------------------------------------------------------
void CAdminServer::Reactivate()
{
}
//-----------------------------------------------------------------------------
// Purpose: opens a manage server dialog for a local server
//-----------------------------------------------------------------------------
ManageServerUIHandle_t CAdminServer::OpenManageServerDialog(const char *serverName, const char *gameDir)
{
CGamePanelInfo *tmp = new CGamePanelInfo(NULL, serverName, gameDir);
tmp->SetParent(m_hParent);
// add a new item into the list
int i = m_OpenedManageDialog.AddToTail();
m_OpenedManageDialog[i].handle = vgui::ivgui()->PanelToHandle(tmp->GetVPanel());
m_OpenedManageDialog[i].manageInterface = tmp;
return (ManageServerUIHandle_t)i;
}
//-----------------------------------------------------------------------------
// Purpose: opens a manage server dialog to a remote server
//-----------------------------------------------------------------------------
ManageServerUIHandle_t CAdminServer::OpenManageServerDialog(unsigned int gameIP, unsigned int gamePort, const char *password)
{
Assert(false);
return (ManageServerUIHandle_t)0;
}
//-----------------------------------------------------------------------------
// Purpose: forces the game info dialog closed
//-----------------------------------------------------------------------------
void CAdminServer::CloseManageServerDialog(ManageServerUIHandle_t gameDialog)
{
Assert(false);
}
//-----------------------------------------------------------------------------
// Purpose: Gets a handle to the management interface
//-----------------------------------------------------------------------------
IManageServer *CAdminServer::GetManageServerInterface(ManageServerUIHandle_t handle)
{
// make sure it's safe
if ((int)handle < 1 || (int)handle > m_OpenedManageDialog.Count())
return NULL;
vgui::VPANEL panel = vgui::ivgui()->HandleToPanel(m_OpenedManageDialog[handle].handle);
if (!panel)
return NULL;
return m_OpenedManageDialog[handle].manageInterface;
}

View File

@ -0,0 +1,69 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef ADMINSERVER_H
#define ADMINSERVER_H
#ifdef _WIN32
#pragma once
#endif
#include "IAdminServer.h"
#include "IVGuiModule.h"
#include <utlvector.h>
class CServerPage;
//-----------------------------------------------------------------------------
// Purpose: Handles the UI and pinging of a half-life game server list
//-----------------------------------------------------------------------------
class CAdminServer : public IAdminServer, public IVGuiModule
{
public:
CAdminServer();
~CAdminServer();
// IVGui module implementation
virtual bool Initialize(CreateInterfaceFn *factorylist, int numFactories);
virtual bool PostInitialize(CreateInterfaceFn *modules, int factoryCount);
virtual vgui::VPANEL GetPanel();
virtual bool Activate();
virtual bool IsValid();
virtual void Shutdown();
virtual void Deactivate();
virtual void Reactivate();
virtual void SetParent(vgui::VPANEL parent);
// IAdminServer implementation
// opens a manage server dialog for a local server
virtual ManageServerUIHandle_t OpenManageServerDialog(const char *serverName, const char *gameDir);
// opens a manage server dialog to a remote server
virtual ManageServerUIHandle_t OpenManageServerDialog(unsigned int gameIP, unsigned int gamePort, const char *password);
// forces the game info dialog closed
virtual void CloseManageServerDialog(ManageServerUIHandle_t gameDialog);
// Gets a handle to the interface
virtual IManageServer *GetManageServerInterface(ManageServerUIHandle_t handle);
private:
struct OpenedManageDialog_t
{
unsigned long handle;
IManageServer *manageInterface;
};
CUtlVector<OpenedManageDialog_t> m_OpenedManageDialog;
vgui::VPANEL m_hParent;
};
class IVProfExport;
extern IVProfExport *g_pVProfExport;
#endif // AdminServer_H

View File

@ -0,0 +1,117 @@
//-----------------------------------------------------------------------------
// ADMINSERVER.VPC
//
// Project Script
//-----------------------------------------------------------------------------
$Macro SRCDIR "..\.."
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
$Configuration
{
$Compiler
{
// $AdditionalIncludeDirectories "$BASE,.\,"
$PreprocessorDefinitions "$BASE;ADMINSERVER_EXPORTS;BUDGET_ADMIN_SERVER"
}
$Linker
{
$AdditionalDependencies "$BASE wsock32.lib"
}
}
$Project "AdminServer"
{
$Folder "Source Files"
{
$File "AdminServer.cpp"
$File "BanContextMenu.cpp"
$File "ConfigPanel.cpp"
$File "GamePanelInfo.cpp"
$File "MapCycleEditDialog.cpp"
$File "..\common\msgbuffer.cpp"
$File "PlayerContextMenu.cpp"
$File "PlayerListCompare.cpp"
$File "RemoteServer.cpp"
$File "VarEditDialog.cpp"
$File "VarListPropertyPage.cpp"
$File "$SRCDIR\common\vgui\vgui_basebudgetpanel.cpp"
$File "$SRCDIR\common\vgui\vgui_budgetbargraphpanel.cpp"
$File "$SRCDIR\common\vgui\vgui_budgethistorypanel.cpp"
$File "$SRCDIR\common\vgui\vgui_budgetpanelshared.cpp"
$File "$SRCDIR\public\vgui_controls\vgui_controls.cpp"
$Folder "Utils"
{
$File "TokenLine.cpp"
}
$Folder "Generic Dialogs"
{
$File "DialogAddBan.cpp"
$File "DialogCvarChange.cpp"
}
$Folder "Pages"
{
$File "BanPanel.cpp"
$File "BudgetPanelContainer.cpp"
$File "ChatPanel.cpp"
$File "GraphPanel.cpp"
$File "PlayerPanel.cpp"
$File "RawLogPanel.cpp"
$File "ServerConfigPanel.cpp"
$File "serverinfopanel.cpp"
}
}
$Folder "Header Files"
{
$File "AdminServer.h"
$File "BanContextMenu.h"
$File "BanPanel.h"
$File "BudgetPanelContainer.h"
$File "ChatPanel.h"
$File "ConfigPanel.h"
$File "DialogAddBan.h"
$File "DialogCvarChange.h"
$File "GamePanelInfo.h"
$File "GraphPanel.h"
$File "$SRCDIR\common\IGameServerData.h"
$File "IManageServer.h"
$File "$SRCDIR\public\tier1\interface.h"
$File "..\common\IServerRefreshResponse.h"
$File "$SRCDIR\common\ivprofexport.h"
$File "MapCycleEditDialog.h"
$File "..\common\msgbuffer.h"
$File "PlayerContextMenu.h"
$File "PlayerListCompare.h"
$File "PlayerPanel.h"
$File "RawLogPanel.h"
$File "RemoteServer.h"
$File "ServerConfigPanel.h"
$File "serverinfopanel.h"
$File "TokenLine.h"
$File "$SRCDIR\public\tier1\utlbuffer.h"
$File "$SRCDIR\public\tier1\utllinkedlist.h"
$File "$SRCDIR\public\tier1\utlsymbol.h"
$File "$SRCDIR\public\tier1\utlvector.h"
$File "VarEditDialog.h"
$File "VarListPropertyPage.h"
$File "$SRCDIR\common\vgui\vgui_basebudgetpanel.h"
$File "$SRCDIR\common\vgui\vgui_budgetbargraphpanel.h"
$File "$SRCDIR\common\vgui\vgui_budgethistorypanel.h"
$File "$SRCDIR\common\vgui\vgui_budgetpanelshared.h"
}
$Folder "Link Libraries"
{
$Lib tier2
$Lib tier3
$Lib vgui_controls
$Lib mathlib
}
}

View File

@ -0,0 +1,57 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "BanContextMenu.h"
#include <vgui/IInput.h>
#include <vgui/IPanel.h>
#include <vgui/ISurface.h>
#include <KeyValues.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CBanContextMenu::CBanContextMenu(Panel *parent) : Menu(parent, "BanContextMenu")
{
CBanContextMenu::parent=parent;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CBanContextMenu::~CBanContextMenu()
{
}
//-----------------------------------------------------------------------------
// Purpose: Activates the menu
//-----------------------------------------------------------------------------
void CBanContextMenu::ShowMenu(Panel *target, unsigned int banID)
{
DeleteAllItems();
if(banID==-1)
{
AddMenuItem("ban", "#Ban_Menu_Add", new KeyValues("addban", "banID", banID), CBanContextMenu::parent);
}
else
{
AddMenuItem("ban", "#Ban_Menu_Remove", new KeyValues("removeban", "banID", banID), CBanContextMenu::parent);
AddMenuItem("ban", "#Ban_Menu_Change", new KeyValues("changeban", "banID", banID), CBanContextMenu::parent);
}
MakePopup();
int x, y, gx, gy;
input()->GetCursorPos(x, y);
ipanel()->GetPos(surface()->GetEmbeddedPanel(), gx, gy);
SetPos(x - gx, y - gy);
MoveToFront();
RequestFocus();
SetVisible(true);
}

View File

@ -0,0 +1,32 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef BANCONTEXTMENU_H
#define BANCONTEXTMENU_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/Menu.h>
//-----------------------------------------------------------------------------
// Purpose: Basic right-click context menu for servers
//-----------------------------------------------------------------------------
class CBanContextMenu : public vgui::Menu
{
public:
CBanContextMenu(vgui::Panel *parent);
~CBanContextMenu();
// call this to activate the menu
void ShowMenu(vgui::Panel *target, unsigned int banID);
private:
vgui::Panel *parent; // so we can send it messages
};
#endif // BANCONTEXTMENU_H

View File

@ -0,0 +1,416 @@
//========= 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));
}

View File

@ -0,0 +1,78 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef BANPANEL_H
#define BANPANEL_H
#ifdef _WIN32
#pragma once
#endif
#include <KeyValues.h>
#include <vgui_controls/Frame.h>
#include <vgui_controls/PHandle.h>
#include <vgui_controls/ListPanel.h>
#include <vgui_controls/PropertyPage.h>
#include "utlvector.h"
#include "BanContextMenu.h"
#include "RemoteServer.h"
//-----------------------------------------------------------------------------
// Purpose: Dialog for displaying information about a game server
//-----------------------------------------------------------------------------
class CBanPanel : public vgui::PropertyPage, public IServerDataResponse
{
DECLARE_CLASS_SIMPLE( CBanPanel, vgui::PropertyPage );
public:
CBanPanel(vgui::Panel *parent, const char *name);
~CBanPanel();
virtual void OnResetData();
protected:
// property page handlers
virtual void OnPageShow();
virtual void OnThink();
// server response on user data
virtual void OnServerDataResponse(const char *value, const char *response);
virtual void OnKeyCodeTyped(vgui::KeyCode code);
private:
MESSAGE_FUNC( AddBan, "addban" );
MESSAGE_FUNC( RemoveBan, "removeban" );
MESSAGE_FUNC( ChangeBan, "changeban" );
MESSAGE_FUNC_CHARPTR( RemoveBanByID, "removebanbyid", id );
MESSAGE_FUNC_CHARPTR_CHARPTR( ChangeBanTimeByID, "AddBanValue", id, time );
MESSAGE_FUNC_PARAMS( OnCvarChangeValue, "CvarChangeValue", kv );
// returns true if the id string is an IP address, false if it's a WON or STEAM ID
bool IsIPAddress(const char *id);
// msg handlers
MESSAGE_FUNC_INT( OnOpenContextMenu, "OpenContextMenu", itemID );
void OnEffectPlayer(KeyValues *data);
MESSAGE_FUNC( OnItemSelected, "ItemSelected" );
MESSAGE_FUNC( ImportBanList, "importban" );
MESSAGE_FUNC_CHARPTR( OnFileSelected, "FileSelected", fullpath );
vgui::ListPanel *m_pBanListPanel;
vgui::Button *m_pAddButton;
vgui::Button *m_pRemoveButton;
vgui::Button *m_pChangeButton;
vgui::Button *m_pImportButton;
CBanContextMenu *m_pBanContextMenu;
float m_flUpdateTime;
bool m_bPageViewed;
};
#endif // BANPANEL_H

View File

@ -0,0 +1,247 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "BaseGamesPage.h"
#include "ServerListCompare.h"
#include "util.h"
#include "serverpage.h"
#include <VGUI_Controls.h>
#include <VGUI_CheckButton.h>
#include <VGUI_ComboBox.h>
#include <VGUI_ImagePanel.h>
#include <VGUI_IScheme.h>
#include <VGUI_IVGui.h>
#include <VGUI_ListPanel.h>
#include <VGUI_MenuButton.h>
#include <VGUI_Menu.h>
#include <VGUI_KeyValues.h>
#include <VGUI_MouseCode.h>
#include <stdio.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CBaseGamesPage::CBaseGamesPage(vgui::Panel *parent, const char *name) : Frame(parent, name), m_Servers(this)
{
ivgui()->AddTickSignal(GetVPanel());
//SetSize(500, 500);
//SetParent(parent); // doesn't have any effect....
m_pParent=parent;
// load the password icon
m_pPasswordIcon = new ImagePanel(NULL, NULL);
m_pPasswordIcon->SetImage(scheme()->GetImage(scheme()->GetDefaultScheme(), "server/icon_password"));
// Init UI
// m_pConnect = new Button(this, "ConnectButton", "Connect");
m_pRefresh = new Button(this, "RefreshButton", "Refresh");
m_pRefresh->SetCommand("refresh");
//m_pRefresh->AddActionSignalTarget(this);
m_pAddIP = new Button(this, "AddIPButton", "Add IP");
m_pManage = new Button(this, "ManageButton", "Manage");
m_pManage->SetCommand(new KeyValues("Manage"));
m_pManage->AddActionSignalTarget(this);
// m_pRefreshMenu = new Menu(this, "RefreshMenu");
// m_pRefreshMenu->MakePopup();
//m_pRefresh->SetMenu(m_pRefreshMenu);
//m_pRefresh->SetOpenDirection(MenuButton::UP);
//m_pRefreshMenu->AddMenuItem("Refresh", "Get new info for servers in current list ", "refresh", this);
//m_pRefreshMenu->AddMenuItem("GetNewList", "Get new server list ", "getnewlist", this);
//m_pRefreshMenu->AddMenuItem("StopRefresh", "Stop refreshing server list ", "stoprefresh", this);
m_pGameList = new OurListPanel(this, "gamelist");
// Add the column headers
m_pGameList->AddColumnHeader(0, "Password", util->GetString(""), 20, false, NOT_RESIZABLE, NOT_RESIZABLE );
m_pGameList->AddColumnHeader(1, "Name", util->GetString(" Servers"), 50, true, RESIZABLE, RESIZABLE);
m_pGameList->AddColumnHeader(2, "GameDesc", util->GetString(" Game"), 80, true, RESIZABLE, NOT_RESIZABLE);
m_pGameList->AddColumnHeader(3, "Players", util->GetString(" Players"), 55, true, RESIZABLE, NOT_RESIZABLE);
m_pGameList->AddColumnHeader(4, "Map", util->GetString(" Map" ), 90, true, RESIZABLE, NOT_RESIZABLE);
m_pGameList->AddColumnHeader(5, "Ping", util->GetString(" Latency" ), 55, true, RESIZABLE, NOT_RESIZABLE);
// setup fast sort functions
m_pGameList->SetSortFunc(0, PasswordCompare);
m_pGameList->SetSortFunc(1, ServerNameCompare);
m_pGameList->SetSortFunc(2, GameCompare);
m_pGameList->SetSortFunc(3, PlayersCompare);
m_pGameList->SetSortFunc(4, MapCompare);
m_pGameList->SetSortFunc(5, PingCompare);
// Sort by ping time by default
m_pGameList->SetSortColumn(5);
m_pGameList->AddActionSignalTarget(this);
// LoadControlSettings("Admin\\DialogAdminServerPage.res");
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CBaseGamesPage::~CBaseGamesPage()
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseGamesPage::PerformLayout()
{
BaseClass::PerformLayout();
/* // game list in middle
int x = 0, y = 0, wide, tall;
GetSize(wide, tall);
m_pGameList->SetBounds(10, 30, wide - 20, tall - 200);
Repaint();
*/
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseGamesPage::OnTick()
{
m_Servers.RunFrame();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseGamesPage::ApplySchemeSettings(vgui::IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
m_pGameList->SetFont(scheme()->GetFont(scheme()->GetDefaultScheme(), "DefaultSmall"));
}
//-----------------------------------------------------------------------------
// Purpose: gets information about specified server
//-----------------------------------------------------------------------------
serveritem_t &CBaseGamesPage::GetServer(unsigned int serverID)
{
return m_Servers.GetServer(serverID);
}
//-----------------------------------------------------------------------------
// Purpose: call to let the UI now whether the game list is currently refreshing
//-----------------------------------------------------------------------------
void CBaseGamesPage::SetRefreshing(bool state)
{
if(!CServerPage::GetInstance())
{
return;
}
if (state)
{
CServerPage::GetInstance()->UpdateStatusText("Refreshing server list...");
}
else
{
CServerPage::GetInstance()->UpdateStatusText("");
}
// m_pRefreshMenu->FindChildByName("Refresh")->SetVisible(!state);
//m_pRefreshMenu->FindChildByName("GetNewList")->SetVisible(!state);
// m_pRefreshMenu->FindChildByName("StopRefresh")->SetVisible(state);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseGamesPage::OnCommand(const char *command)
{
if (!stricmp(command, "Connect"))
{
OnBeginConnect();
}
else if (!stricmp(command, "stoprefresh"))
{
// cancel the existing refresh
StopRefresh();
}
else if (!stricmp(command, "refresh"))
{
// start a new refresh
StartRefresh();
}
else if (!stricmp(command, "GetNewList"))
{
GetNewServerList();
}
else if (!stricmp(command, "addip"))
{
PostMessage(this,new KeyValues("AddServerByName")); // CFavorites handles this message
}
else if (!stricmp(command, "config"))
{
CServerPage::GetInstance()->ConfigPanel();
}
else
{
BaseClass::OnCommand(command);
}
}
//-----------------------------------------------------------------------------
// Purpose: Called when the game dir combo box is changed
//-----------------------------------------------------------------------------
void CBaseGamesPage::OnTextChanged(Panel *panel, const char *text)
{
}
//-----------------------------------------------------------------------------
// Purpose: Handles filter dropdown being toggled
//-----------------------------------------------------------------------------
void CBaseGamesPage::OnButtonToggled(Panel *panel, int state)
{
// treat changing these buttons like any other filter has changed
OnTextChanged(panel, "");
}
void CBaseGamesPage::OnManage()
{
if (m_pGameList->GetNumSelectedRows())
{
// get the server
unsigned int serverID = m_pGameList->GetDataItem(m_pGameList->GetSelectedRow(0))->userData;
PostMessage(m_pParent->GetVPanel(), new KeyValues("Manage", "serverID", serverID));
}
}
void CBaseGamesPage::OurListPanel::OnMouseDoublePressed( vgui::MouseCode code )
{
PostMessage(m_pParent->GetVPanel(), new KeyValues("Manage"));
}
//-----------------------------------------------------------------------------
// Purpose: Message map
//-----------------------------------------------------------------------------
MessageMapItem_t CBaseGamesPage::m_MessageMap[] =
{
MAP_MESSAGE_PTR_INT( CBaseGamesPage, "ButtonToggled", OnButtonToggled, "panel", "state" ),
MAP_MESSAGE_PTR_CONSTCHARPTR( CBaseGamesPage, "TextChanged", OnTextChanged, "panel", "text" ),
MAP_MESSAGE( CBaseGamesPage , "Manage",OnManage ),
};
IMPLEMENT_PANELMAP(CBaseGamesPage, BaseClass);

View File

@ -0,0 +1,92 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef BASEGAMESPAGE_H
#define BASEGAMESPAGE_H
#ifdef _WIN32
#pragma once
#endif
#include <VGUI_Frame.h>
#include "ServerList.h"
#include "IServerRefreshResponse.h"
#include "server.h"
#include "IGameList.h"
namespace vgui
{
class ListPanel;
class ImagePanel;
class ComboBox;
class ToggleButton;
class CheckButton;
class TextEntry;
class MenuButton;
class Menu;
};
//-----------------------------------------------------------------------------
// Purpose: Base property page for all the games lists (internet/favorites/lan/etc.)
//-----------------------------------------------------------------------------
class CBaseGamesPage : public vgui2::Frame, public IServerRefreshResponse, public IGameList
{
public:
CBaseGamesPage(vgui::Panel *parent, const char *name);
~CBaseGamesPage();
virtual void PerformLayout();
virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
// gets information about specified server
virtual serveritem_t &GetServer(unsigned int serverID);
virtual void SetRefreshing(bool state);
protected:
virtual void OnTick();
virtual void OnCommand(const char *command);
// virtual void OnOnMouseDoublePressed(enum vgui::MouseCode code);
// an inner class
class OurListPanel: public vgui::ListPanel
{
public:
OurListPanel(vgui::Panel *parent, const char *panelName): vgui::ListPanel(parent,panelName) { m_pParent=parent;};
virtual void OnMouseDoublePressed( vgui::MouseCode code );
private:
vgui::Panel *m_pParent;
};
// a list panel we grab the double click event from :)
OurListPanel *m_pGameList;
CServerList m_Servers;
vgui::ImagePanel *m_pPasswordIcon; // password icon
private:
void OnButtonToggled(vgui::Panel *panel, int state);
void OnTextChanged(vgui::Panel *panel, const char *text);
void OnManage();
// command buttons
vgui::Button *m_pConnect;
vgui::Button *m_pRefresh;
vgui::Button *m_pManage;
vgui::Button *m_pAddIP;
vgui::Panel *m_pParent;
// vgui::Menu *m_pRefreshMenu;
typedef vgui::Frame BaseClass;
DECLARE_PANELMAP();
};
#endif // BASEGAMESPAGE_H

View File

@ -0,0 +1,175 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "BudgetPanelContainer.h"
#include "mathlib/mathlib.h"
#include "vgui/vgui_budgetpanelshared.h"
#include "AdminServer.h"
#include "ivprofexport.h"
#include "vgui/ilocalize.h"
#include "vgui/ISurface.h"
#include "vgui/vgui_BaseBudgetPanel.h"
// -------------------------------------------------------------------------------------------------------------------- //
// CBudgetPanelAdmin declaration.
// -------------------------------------------------------------------------------------------------------------------- //
class CBudgetPanelAdmin : public CBudgetPanelShared
{
typedef CBudgetPanelShared BaseClass;
public:
CBudgetPanelAdmin( vgui::Panel *pParent, const char *pElementName );
virtual void SetupCustomConfigData( CBudgetPanelConfigData &data );
virtual void PostChildPaint();
virtual void OnTick();
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
void DrawColoredText(
vgui::HFont font,
int x, int y,
int r, int g, int b, int a,
const char *pText,
... );
private:
Color m_budgetTextColor;
};
CBudgetPanelAdmin::CBudgetPanelAdmin( vgui::Panel *pParent, const char *pElementName ) :
BaseClass( pParent, pElementName, BUDGETFLAG_SERVER )
{
MarkAsDedicatedServer();
}
void CBudgetPanelAdmin::SetupCustomConfigData( CBudgetPanelConfigData &data )
{
GetBounds( data.m_xCoord, data.m_yCoord, data.m_Width, data.m_Height );
}
void CBudgetPanelAdmin::DrawColoredText(
vgui::HFont font,
int x, int y,
int r, int g, int b, int a,
const char *pText,
... )
{
char msg[4096];
va_list marker;
va_start( marker, pText );
_vsnprintf( msg, sizeof( msg ), pText, marker );
va_end( marker );
wchar_t unicodeStr[4096];
int nChars = g_pVGuiLocalize->ConvertANSIToUnicode( msg, unicodeStr, sizeof( unicodeStr ) );
vgui::surface()->DrawSetTextFont( font );
vgui::surface()->DrawSetTextColor( r, g, b, a );
vgui::surface()->DrawSetTextPos( x, y );
vgui::surface()->DrawPrintText( unicodeStr, nChars-1 );
}
void CBudgetPanelAdmin::ApplySchemeSettings( vgui::IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
m_budgetTextColor = pScheme->GetColor( "BrightControlText", Color( 0, 255, 0, 255 ) );
}
void CBudgetPanelAdmin::PostChildPaint()
{
DrawColoredText( m_hFont, 0, 0, m_budgetTextColor[0], m_budgetTextColor[1], m_budgetTextColor[2], m_budgetTextColor[3], "%i fps (showbudget 3D driver time included)", RoundFloatToInt(g_fFrameRate) );
DrawColoredText( m_hFont, 0, 16, m_budgetTextColor[0], m_budgetTextColor[1], m_budgetTextColor[2], m_budgetTextColor[3], "%.1f ms", g_fFrameTimeLessBudget*1000.0f );
BaseClass::PostChildPaint();
}
void CBudgetPanelAdmin::OnTick()
{
// Don't do all the work if we're not being drawn.
if ( IsVisible() )
{
SnapshotVProfHistory( 0 );
MarkForFullRepaint();
}
BaseClass::OnTick();
}
// ------------------------------------------------------------------------------------------------------------------------------------------------ //
// The budget panel container class. Just holds CBudgetPanelAdmin.
// ------------------------------------------------------------------------------------------------------------------------------------------------ //
CBudgetPanelContainer::CBudgetPanelContainer(vgui::Panel *parent, const char *name) : PropertyPage(parent, name)
{
LoadControlSettings("Admin/BudgetPanel.res", "PLATFORM");
m_pBudgetPanelAdmin = new CBudgetPanelAdmin( this, "AdminBudgetPanel" );
m_pBudgetPanelAdmin->SetVisible( false );
InvalidateLayout();
}
CBudgetPanelContainer::~CBudgetPanelContainer()
{
}
void CBudgetPanelContainer::OnServerDataResponse( const char *value, const char *response )
{
}
void CBudgetPanelContainer::Paint()
{
}
void CBudgetPanelContainer::PerformLayout()
{
BaseClass::PerformLayout();
int x, y, wide, tall;
GetBounds( x, y, wide, tall );
m_pBudgetPanelAdmin->SetBounds( 12, 12, wide - 24, tall - 24 );
m_pBudgetPanelAdmin->SendConfigDataToBase();
}
//-----------------------------------------------------------------------------
// Purpose: Activates the page
//-----------------------------------------------------------------------------
void CBudgetPanelContainer::OnPageShow()
{
if ( g_pVProfExport )
g_pVProfExport->AddListener();
m_pBudgetPanelAdmin->SetVisible( true );
BaseClass::OnPageShow();
}
//-----------------------------------------------------------------------------
// Purpose: Hides the page
//-----------------------------------------------------------------------------
void CBudgetPanelContainer::OnPageHide()
{
if ( g_pVProfExport )
g_pVProfExport->RemoveListener();
m_pBudgetPanelAdmin->SetVisible( false );
BaseClass::OnPageHide();
}

View File

@ -0,0 +1,60 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#ifndef BUDGETPANELCONTAINER_H
#define BUDGETPANELCONTAINER_H
#ifdef _WIN32
#pragma once
#endif
#include <KeyValues.h>
#include <vgui_controls/Frame.h>
#include <vgui_controls/PHandle.h>
#include <vgui_controls/ListPanel.h>
#include <vgui_controls/PropertyPage.h>
#include "utlvector.h"
#include "RemoteServer.h"
class CBudgetPanelAdmin;
//-----------------------------------------------------------------------------
// Purpose: Dialog for displaying information about a game server
//-----------------------------------------------------------------------------
class CBudgetPanelContainer : public vgui::PropertyPage, public IServerDataResponse
{
DECLARE_CLASS_SIMPLE( CBudgetPanelContainer, vgui::PropertyPage );
public:
CBudgetPanelContainer(vgui::Panel *parent, const char *name);
~CBudgetPanelContainer();
// Panel overrides.
public:
virtual void Paint();
virtual void PerformLayout();
// PropertyPage overrides.
public:
void OnPageShow();
void OnPageHide();
// IServerDataResponse overrides.
public:
virtual void OnServerDataResponse(const char *value, const char *response);
private:
CBudgetPanelAdmin *m_pBudgetPanelAdmin;
};
#endif // BUDGETPANELCONTAINER_H

View File

@ -0,0 +1,32 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef CHATCONTEXTMENU_H
#define CHATCONTEXTMENU_H
#ifdef _WIN32
#pragma once
#endif
#include <VGUI_Menu.h>
//-----------------------------------------------------------------------------
// Purpose: Basic right-click context menu for servers
//-----------------------------------------------------------------------------
class CChatContextMenu : public vgui::Menu
{
public:
CChatContextMenu(vgui::Panel *parent);
~CChatContextMenu();
// call this to activate the menu
void ShowMenu(vgui::Panel *target);
private:
vgui::Panel *parent; // so we can send it messages
};
#endif // CHATCONTEXTMENU_H

View File

@ -0,0 +1,87 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "ChatPanel.h"
#include "RemoteServer.h"
#include <vgui/IVGui.h>
#include <KeyValues.h>
#include <vgui_controls/TextEntry.h>
#include <vgui_controls/RichText.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/PHandle.h>
#include <stdio.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CChatPanel::CChatPanel(vgui::Panel *parent, const char *name) : PropertyPage(parent, name)
{
m_pServerChatPanel = new RichText(this, "ServerChatText");
m_pServerChatPanel->SetMaximumCharCount(8000);
m_pEnterChatPanel = new TextEntry(this,"ChatMessage");
m_pSendChatButton = new Button(this, "SendChat", "#Chat_Panel_Send");
m_pSendChatButton->SetCommand(new KeyValues("SendChat"));
m_pSendChatButton->SetAsDefaultButton(true);
LoadControlSettings("Admin/ChatPanel.res", "PLATFORM");
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CChatPanel::~CChatPanel()
{
}
//-----------------------------------------------------------------------------
// Purpose: Activates the page
//-----------------------------------------------------------------------------
void CChatPanel::OnPageShow()
{
BaseClass::OnPageShow();
}
//-----------------------------------------------------------------------------
// Purpose: Hides the page
//-----------------------------------------------------------------------------
void CChatPanel::OnPageHide()
{
BaseClass::OnPageHide();
}
//-----------------------------------------------------------------------------
// Purpose: inserts a new string into the main chat panel
//-----------------------------------------------------------------------------
void CChatPanel::DoInsertString(const char *str)
{
m_pServerChatPanel->InsertString(str);
}
//-----------------------------------------------------------------------------
// Purpose: run when the send button is pressed, send a rcon "say" to the server
//-----------------------------------------------------------------------------
void CChatPanel::OnSendChat()
{
// build a chat command and send it to the server
char chat_text[512];
strcpy(chat_text, "say ");
m_pEnterChatPanel->GetText(chat_text + 4, sizeof(chat_text) - 4);
if (strlen("say ") != strlen(chat_text))
{
RemoteServer().SendCommand(chat_text);
// the message is sent, zero the text
m_pEnterChatPanel->SetText("");
}
}

View File

@ -0,0 +1,44 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef CHATPANEL_H
#define CHATPANEL_H
#ifdef _WIN32
#pragma once
#endif
#include <KeyValues.h>
#include <vgui_controls/Frame.h>
#include <vgui_controls/PHandle.h>
#include <vgui_controls/ListPanel.h>
#include <vgui_controls/PropertyPage.h>
//-----------------------------------------------------------------------------
// Purpose: Dialog for displaying information about a game server
//-----------------------------------------------------------------------------
class CChatPanel : public vgui::PropertyPage
{
DECLARE_CLASS_SIMPLE( CChatPanel, vgui::PropertyPage );
public:
CChatPanel(vgui::Panel *parent, const char *name);
~CChatPanel();
// property page handlers
virtual void OnPageShow();
virtual void OnPageHide();
void DoInsertString(const char *str);
private:
MESSAGE_FUNC( OnSendChat, "SendChat" );
vgui::RichText *m_pServerChatPanel;
vgui::TextEntry *m_pEnterChatPanel;
vgui::Button *m_pSendChatButton;
};
#endif // CHATPANEL_H

View File

@ -0,0 +1,40 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "ClickableTabbedPanel.h"
#include <vgui/KeyValues.h>
using namespace vgui;
CClickableTabbedPanel::CClickableTabbedPanel(vgui2::Panel *parent, const char *panelName) : vgui2::PropertySheet(parent,panelName)
{
//PropertySheet::onTabPressed
}
CClickableTabbedPanel::~CClickableTabbedPanel()
{
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : code -
//-----------------------------------------------------------------------------
/*void CClickableTabbedPanel::onMousePressed(MouseCode code)
{
// check for context menu open
if (code == MOUSE_RIGHT)
{
postActionSignal(new KeyValues("OpenContextMenu", "itemID", -1));
}
}*/

View File

@ -0,0 +1,40 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef CLICKABLETABBEDPANEL_H
#define CLICKABLETABBEDPANEL_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui/MouseCode.h>
#include <vgui_controls/PropertySheet.h>
#include <vgui_controls/Frame.h>
#include <vgui_controls/Panel.h>
namespace vgui
{
class Panel;
};
class CClickableTabbedPanel: public vgui2::PropertySheet
{
public:
CClickableTabbedPanel(vgui2::Panel *parent, const char *panelName);
~CClickableTabbedPanel();
private:
// void onMousePressed(vgui2::MouseCode code);
};
#endif //CLICKABLETABBEDPANEL

View File

@ -0,0 +1,181 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "ConfigPanel.h"
//#include "Info.h"
#include <vgui/ISystem.h>
#include <vgui/ISurface.h>
#include <vgui/IVGui.h>
#include <KeyValues.h>
#include <vgui_controls/Label.h>
#include <vgui_controls/TextEntry.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/ToggleButton.h>
#include <vgui_controls/CheckButton.h>
#include <vgui_controls/MessageBox.h>
#include <vgui_controls/RadioButton.h>
#include <stdio.h>
using namespace vgui;
static const long RETRY_TIME = 10000; // refresh server every 10 seconds
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CConfigPanel::CConfigPanel(vgui::Panel *parent, bool autorefresh,bool savercon,int refreshtime,
bool graphs, int graphsrefreshtime,bool getlogs) : Frame(parent, "ConfigPanel")
{
196, 181, 80,
SetMinimumSize(400,240);
SetSizeable(false);
MakePopup();
m_pOkayButton = new Button(this, "Okay", "#Okay_Button");
m_pCloseButton = new Button(this, "Close", "#Close_Button");
m_pRefreshCheckButton = new CheckButton(this, "RefreshCheckButton", "");
m_pRconCheckButton = new CheckButton(this, "RconCheckButton", "");
m_pRefreshTextEntry= new TextEntry(this,"RefreshTextEntry");
m_pGraphsButton = new CheckButton(this, "GraphsButton", "");
m_pGraphsRefreshTimeTextEntry= new TextEntry(this,"GraphsRefreshTimeTextEntry");
m_pLogsButton = new CheckButton(this, "LogsButton", "");
SetTitle("My servers - Options",true);
LoadControlSettings("Admin\\ConfigPanel.res", "PLATFORM");
m_pRefreshCheckButton->SetSelected(autorefresh);
m_pRconCheckButton->SetSelected(savercon);
m_pGraphsButton->SetSelected(graphs);
m_pLogsButton->SetSelected(getlogs);
m_pRefreshTextEntry->SetEnabled(m_pRefreshCheckButton->IsSelected());
m_pRefreshTextEntry->SetEditable(m_pRefreshCheckButton->IsSelected());
m_pGraphsRefreshTimeTextEntry->SetEnabled(m_pGraphsButton->IsSelected());
m_pGraphsRefreshTimeTextEntry->SetEditable(m_pGraphsButton->IsSelected());
char refreshText[20];
_snprintf(refreshText,20,"%i",refreshtime);
m_pRefreshTextEntry->SetText(refreshText);
_snprintf(refreshText,20,"%i",graphsrefreshtime);
m_pGraphsRefreshTimeTextEntry->SetText(refreshText);
SetVisible(true);
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CConfigPanel::~CConfigPanel()
{
}
//-----------------------------------------------------------------------------
// Purpose: Activates the dialog
//-----------------------------------------------------------------------------
void CConfigPanel::Run()
{
RequestFocus();
}
//-----------------------------------------------------------------------------
// Purpose: Deletes the dialog when it's closed
//-----------------------------------------------------------------------------
void CConfigPanel::OnClose()
{
BaseClass::OnClose();
MarkForDeletion();
}
//-----------------------------------------------------------------------------
// Purpose: turn on and off components when check boxes are checked
//-----------------------------------------------------------------------------
void CConfigPanel::OnButtonToggled(Panel *panel)
{
if (panel == m_pRefreshCheckButton)
// you can only edit the refresh time if you allow auto refresh
{
m_pRefreshTextEntry->SetEnabled(m_pRefreshCheckButton->IsSelected());
m_pRefreshTextEntry->SetEditable(m_pRefreshCheckButton->IsSelected());
}
else if (panel == m_pGraphsButton)
// you can only edit the refresh time if you allow auto refresh
{
m_pGraphsRefreshTimeTextEntry->SetEnabled(m_pGraphsButton->IsSelected());
m_pGraphsRefreshTimeTextEntry->SetEditable(m_pGraphsButton->IsSelected());
}
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: Sets the text of a control by name
//-----------------------------------------------------------------------------
void CConfigPanel::SetControlText(const char *textEntryName, const char *text)
{
TextEntry *entry = dynamic_cast<TextEntry *>(FindChildByName(textEntryName));
if (entry)
{
entry->SetText(text);
}
}
//-----------------------------------------------------------------------------
// Purpose: Parse posted messages
//
//-----------------------------------------------------------------------------
void CConfigPanel::OnCommand(const char *command)
{
if(!stricmp(command,"okay"))
{ // save away the new settings
char timeText[20];
int time,timeGraphs;
m_pRefreshTextEntry->GetText(timeText,20);
sscanf(timeText,"%i",&time);
memset(timeText, 0x0, sizeof(timeText));
m_pGraphsRefreshTimeTextEntry->GetText(timeText, 20);
sscanf(timeText,"%i",&timeGraphs);
if(time>0 && time < 9999 && timeGraphs>0 && timeGraphs< 9999)
{
OnClose();
}
else
{
MessageBox *dlg = new MessageBox ("#Config_Panel", "#Config_Time_Error");
dlg->DoModal();
}
}
else if(!stricmp(command,"close") )
{
Close();
}
}

View File

@ -0,0 +1,54 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef CONFIGPANEL_H
#define CONFIGPANEL_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/Frame.h>
//-----------------------------------------------------------------------------
// Purpose: Dialog for displaying information about a game server
//-----------------------------------------------------------------------------
class CConfigPanel : public vgui::Frame
{
DECLARE_CLASS_SIMPLE( CConfigPanel, vgui::Frame );
public:
CConfigPanel(vgui::Panel *parent, bool autorefresh,bool savercon,int refreshtime,bool graphs, int graphsrefreshtime,bool getlogs);
~CConfigPanel();
void Run();
protected:
// message handlers
MESSAGE_FUNC_PTR( OnButtonToggled, "ButtonToggled", panel );
MESSAGE_FUNC_PTR( OnRadioButtonChecked, "RadioButtonChecked", panel )
{
OnButtonToggled( panel );
}
// vgui overrides
virtual void OnClose();
virtual void OnCommand(const char *command);
private:
void SetControlText(const char *textEntryName, const char *text);
vgui::Button *m_pOkayButton;
vgui::Button *m_pCloseButton;
vgui::CheckButton *m_pRconCheckButton;
vgui::CheckButton *m_pRefreshCheckButton;
vgui::TextEntry *m_pRefreshTextEntry;
vgui::CheckButton *m_pGraphsButton;
vgui::TextEntry *m_pGraphsRefreshTimeTextEntry;
vgui::CheckButton *m_pLogsButton;
};
#endif // CONFIGPANEL_H

View File

@ -0,0 +1,250 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include <stdio.h>
#include "DialogAddBan.h"
#include <vgui/ISurface.h>
#include <KeyValues.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/Label.h>
#include <vgui_controls/TextEntry.h>
#include <vgui_controls/CheckButton.h>
#include <vgui_controls/MessageBox.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CDialogAddBan::CDialogAddBan(vgui::Panel *parent) : Frame(parent, "DialogAddBan")
{
SetSize(320, 200);
SetTitle("#Game_Ban_Add_Title", false);
m_pIDTextEntry = new TextEntry(this, "IDTextEntry");
m_pOkayButton = new Button(this, "OkayButton", "#Okay_Button");
m_pPermBanRadio = new RadioButton(this, "PermBanRadio", "#Add_Ban_Time_Permanent");
m_pTempBanRadio = new RadioButton(this, "TempBanRadio", "#Add_Ban_Time_Temporary");
m_pPermBanRadio->SetSelected(true);
m_pTimeTextEntry = new TextEntry(this, "TimeTextEntry");
m_pTimeCombo = new ComboBox(this, "TimeCombo",3,false);
int defaultItem = m_pTimeCombo->AddItem("#Add_Ban_Period_Minutes", NULL);
m_pTimeCombo->AddItem("#Add_Ban_Period_Hours", NULL);
m_pTimeCombo->AddItem("#Add_Ban_Period_Days", NULL);
m_pTimeCombo->ActivateItem(defaultItem);
LoadControlSettings("Admin\\DialogAddBan.res", "PLATFORM");
SetTitle("#Add_Ban_Title", true);
SetSizeable(false);
// set our initial position in the middle of the workspace
MoveToCenterOfScreen();
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CDialogAddBan::~CDialogAddBan()
{
}
//-----------------------------------------------------------------------------
// Purpose: initializes the dialog and brings it to the foreground
//-----------------------------------------------------------------------------
void CDialogAddBan::Activate(const char *type,const char *player,const char *authid)
{
m_cType=type;
m_pOkayButton->SetAsDefaultButton(true);
MakePopup();
MoveToFront();
RequestFocus();
m_pIDTextEntry->RequestFocus();
SetVisible(true);
SetTextEntry("PlayerTextEntry",player);
SetTextEntry("IDTextEntry",authid);
BaseClass::Activate();
}
//-----------------------------------------------------------------------------
// Purpose: Sets the text of a labell by name
//-----------------------------------------------------------------------------
void CDialogAddBan::SetLabelText(const char *textEntryName, const char *text)
{
Label *entry = dynamic_cast<Label *>(FindChildByName(textEntryName));
if (entry)
{
entry->SetText(text);
}
}
//-----------------------------------------------------------------------------
// Purpose: Sets the text of a labell by name
//-----------------------------------------------------------------------------
void CDialogAddBan::SetTextEntry(const char *textEntryName, const char *text)
{
TextEntry *entry = dynamic_cast<TextEntry *>(FindChildByName(textEntryName));
if (entry)
{
entry->SetText(text);
}
}
bool CDialogAddBan::IsIPCheck()
{
char buf[64];
int dotCount=0;
m_pIDTextEntry->GetText(buf, sizeof(buf)-1);
for(unsigned int i=0;i<strlen(buf);i++)
{
if(buf[i]=='.')
{
dotCount++;
}
}
if(dotCount>0)
{
return true;
}
else
{
return false;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDialogAddBan::OnCommand(const char *command)
{
bool bClose = false;
if (!stricmp(command, "Okay"))
{
KeyValues *msg = new KeyValues("AddBanValue");
char buf[64],idbuf[64];
float time;
m_pIDTextEntry->GetText(idbuf, sizeof(idbuf));
m_pTimeTextEntry->GetText(buf, 64);
if(strlen(idbuf)<=0)
{
MessageBox *dlg = new MessageBox("#Add_Ban_Error", "#Add_Ban_ID_Invalid");
dlg->DoModal();
bClose=false;
}
else if(strlen(buf)<=0 && !m_pPermBanRadio->IsSelected())
{
MessageBox *dlg = new MessageBox("#Add_Ban_Error", "#Add_Ban_Time_Empty");
dlg->DoModal();
bClose=false;
}
else
{
if(m_pPermBanRadio->IsSelected())
{
time=0;
}
else
{
sscanf(buf,"%f",&time);
m_pTimeCombo->GetText(buf,64);
if(strstr(buf,"hour"))
{
time*=60;
}
else if(strstr(buf,"day"))
{
time*=(60*24);
}
if(time<0)
{
MessageBox *dlg = new MessageBox("#Add_Ban_Error", "#Add_Ban_Time_Invalid");
dlg->DoModal();
bClose=false;
}
}
if(time>=0)
{
msg->SetFloat("time", time);
msg->SetString("id", idbuf);
msg->SetString("type",m_cType);
msg->SetInt("ipcheck",IsIPCheck());
PostActionSignal(msg);
bClose = true;
}
}
}
else if (!stricmp(command, "Close"))
{
bClose = true;
}
else
{
BaseClass::OnCommand(command);
}
if (bClose)
{
Close();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDialogAddBan::PerformLayout()
{
BaseClass::PerformLayout();
}
//-----------------------------------------------------------------------------
// Purpose: deletes the dialog on close
//-----------------------------------------------------------------------------
void CDialogAddBan::OnClose()
{
BaseClass::OnClose();
MarkForDeletion();
}
//-----------------------------------------------------------------------------
// Purpose: called when the perm/temp ban time radio buttons are pressed
//-----------------------------------------------------------------------------
void CDialogAddBan::OnButtonToggled(Panel *panel)
{
if (panel == m_pPermBanRadio)
{
m_pTimeTextEntry->SetEnabled(false);
m_pTimeCombo->SetEnabled(false);
}
else
{
m_pTimeTextEntry->SetEnabled(true);
m_pTimeCombo->SetEnabled(true);
}
Repaint();
}

View File

@ -0,0 +1,67 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef DIALOGADDBAN_H
#define DIALOGADDBAN_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/Frame.h>
#include <vgui_controls/ComboBox.h>
#include <vgui_controls/TextEntry.h>
#include <vgui_controls/RadioButton.h>
//-----------------------------------------------------------------------------
// Purpose: Prompt for user to enter a password to be able to connect to the server
//-----------------------------------------------------------------------------
class CDialogAddBan : public vgui::Frame
{
DECLARE_CLASS_SIMPLE( CDialogAddBan, vgui::Frame );
public:
CDialogAddBan(vgui::Panel *parent);
~CDialogAddBan();
// initializes the dialog and brings it to the foreground
void Activate(const char *type,const char *player, const char *authid);
/* message returned:
"AddBanValue"
"id"
"time"
"type"
"ipcheck"
*/
// make the input stars, ala a password entry dialog
void MakePassword();
// set the text in a certain label name
void SetLabelText(const char *textEntryName, const char *text);
void SetTextEntry(const char *textEntryName, const char *text);
// returns if the IPCheck check button is checked
bool IsIPCheck();
private:
virtual void PerformLayout();
virtual void OnCommand(const char *command);
virtual void OnClose();
MESSAGE_FUNC_PTR( OnButtonToggled, "RadioButtonChecked", panel );
vgui::TextEntry *m_pTimeTextEntry;
vgui::TextEntry *m_pIDTextEntry;
vgui::Button *m_pOkayButton;
vgui::ComboBox *m_pTimeCombo;
vgui::RadioButton *m_pPermBanRadio;
vgui::RadioButton *m_pTempBanRadio;
const char *m_cType;
};
#endif // DIALOGADDBAN_H

View File

@ -0,0 +1,109 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "DialogAddServer.h"
#include "INetAPI.h"
#include "IGameList.h"
#include "Server.h"
#include <VGUI_MessageBox.h>
#include <VGUI_KeyValues.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
// Input : *gameList - game list to add specified server to
//-----------------------------------------------------------------------------
CDialogAddServer::CDialogAddServer(IGameList *gameList) : Frame(NULL, "DialogAddServer")
{
MakePopup();
m_pGameList = gameList;
SetTitle("Add Server - Servers", true);
LoadControlSettings("Admin\\DialogAddServer.res");
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CDialogAddServer::~CDialogAddServer()
{
}
//-----------------------------------------------------------------------------
// Purpose: Activates this dialog
//-----------------------------------------------------------------------------
void CDialogAddServer::Open()
{
MoveToFront();
RequestFocus();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *command -
//-----------------------------------------------------------------------------
void CDialogAddServer::OnCommand(const char *command)
{
if (!stricmp(command, "OK"))
{
OnOK();
}
else
{
BaseClass::OnCommand(command);
}
}
//-----------------------------------------------------------------------------
// Purpose: Handles the OK button being pressed; adds the server to the game list
//-----------------------------------------------------------------------------
void CDialogAddServer::OnOK()
{
// try and parse out IP address
const char *address = GetControlString("ServerNameText", "");
netadr_t netaddr;
if (net->StringToAdr(address, &netaddr))
{
// net address successfully parsed, add the server to the game list
serveritem_t server;
memset(&server, 0, sizeof(server));
for (int i = 0; i < 4; i++)
{
server.ip[i] = netaddr.ip[i];
}
server.port = (netaddr.port & 0xff) << 8 | (netaddr.port & 0xff00) >> 8;;
if (!server.port)
{
// use the default port since it was not entered
server.port = 27015;
}
m_pGameList->AddNewServer(server);
m_pGameList->StartRefresh();
}
else
{
// could not parse the ip address, popup an error
MessageBox *dlg = new MessageBox("Add Server - Error", "The server IP address you entered is invalid.");
dlg->DoModal();
}
// mark ourselves to be closed
PostMessage(this, new KeyValues("Close"));
}
//-----------------------------------------------------------------------------
// Purpose: Deletes dialog on close
//-----------------------------------------------------------------------------
void CDialogAddServer::OnClose()
{
BaseClass::OnClose();
MarkForDeletion();
}

View File

@ -0,0 +1,42 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef DIALOGADDSERVER_H
#define DIALOGADDSERVER_H
#ifdef _WIN32
#pragma once
#endif
#include <VGUI_Frame.h>
class IGameList;
//-----------------------------------------------------------------------------
// Purpose: Dialog which lets the user add a server by IP address
//-----------------------------------------------------------------------------
class CDialogAddServer : public vgui::Frame
{
public:
CDialogAddServer(IGameList *gameList);
~CDialogAddServer();
// activates this dialog
void Open();
private:
virtual void OnClose();
virtual void OnCommand(const char *command);
void OnOK();
IGameList *m_pGameList;
typedef vgui::Frame BaseClass;
};
#endif // DIALOGADDSERVER_H

View File

@ -0,0 +1,151 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include <stdio.h>
#include "DialogCvarChange.h"
#include <vgui/IInput.h>
#include <vgui/ISurface.h>
#include <KeyValues.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/Panel.h>
#include <vgui_controls/Label.h>
#include <vgui_controls/TextEntry.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CDialogCvarChange::CDialogCvarChange(vgui::Panel *parent) : Frame(parent, "DialogCvarChange")
{
SetSize(320, 200);
m_bAddCvarText = true;
m_pInfoLabel = new Label(this, "InfoLabel", "");
m_pCvarLabel = new Label(this, "CvarLabel", "");
m_pCvarEntry = new TextEntry(this, "CvarEntry");
m_pOkayButton = new Button(this, "OkayButton", "#Okay_Button");
LoadControlSettings("Admin/DialogCvarChange.res", "PLATFORM");
SetTitle("#Cvar_Title", true);
SetSizeable(false);
// set our initial position in the middle of the workspace
MoveToCenterOfScreen();
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CDialogCvarChange::~CDialogCvarChange()
{
}
//-----------------------------------------------------------------------------
// Purpose: Hides value text
//-----------------------------------------------------------------------------
void CDialogCvarChange::MakePassword()
{
m_pCvarEntry->SetTextHidden(true);
m_bAddCvarText = false; // this isn't asking about a cvar
}
//-----------------------------------------------------------------------------
// Purpose: initializes the dialog and brings it to the foreground
//-----------------------------------------------------------------------------
void CDialogCvarChange::Activate(const char *cvarName, const char *curValue, const char *type, const char *question)
{
m_pCvarLabel->SetText(cvarName);
if (!m_bAddCvarText)
{
m_pCvarLabel->SetVisible(false); // hide this
}
m_pInfoLabel->SetText(question);
m_cType=type;
m_pOkayButton->SetAsDefaultButton(true);
MakePopup();
MoveToFront();
m_pCvarEntry->SetText(curValue);
m_pCvarEntry->RequestFocus();
RequestFocus();
// make it modal
input()->SetAppModalSurface(GetVPanel());
SetVisible(true);
BaseClass::Activate();
}
//-----------------------------------------------------------------------------
// Purpose: Sets the text of a labell by name
//-----------------------------------------------------------------------------
void CDialogCvarChange::SetLabelText(const char *textEntryName, const char *text)
{
Label *entry = dynamic_cast<Label *>(FindChildByName(textEntryName));
if (entry)
{
entry->SetText(text);
}
}
//-----------------------------------------------------------------------------
// Purpose: Handles button presses
//-----------------------------------------------------------------------------
void CDialogCvarChange::OnCommand(const char *command)
{
bool bClose = false;
if (!stricmp(command, "Okay"))
{
KeyValues *msg = new KeyValues("CvarChangeValue");
char buf[64];
m_pCvarLabel->GetText(buf,64);
msg->SetString("player", buf );
m_pCvarEntry->GetText(buf, sizeof(buf)-1);
msg->SetString("value", buf);
msg->SetString("type",m_cType);
PostActionSignal(msg);
bClose = true;
}
else if (!stricmp(command, "Close"))
{
bClose = true;
}
else
{
BaseClass::OnCommand(command);
}
if (bClose)
{
Close();
}
}
//-----------------------------------------------------------------------------
// Purpose: deletes the dialog on close
//-----------------------------------------------------------------------------
void CDialogCvarChange::OnClose()
{
BaseClass::OnClose();
MarkForDeletion();
}

View File

@ -0,0 +1,58 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef DIALOGCVARCHANGE_H
#define DIALOGCVARCHANGE_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/Frame.h>
//-----------------------------------------------------------------------------
// Purpose: Prompt for user to enter a password to be able to connect to the server
//-----------------------------------------------------------------------------
class CDialogCvarChange : public vgui::Frame
{
public:
CDialogCvarChange(vgui::Panel *parent);
~CDialogCvarChange();
// initializes the dialog and brings it to the foreground
void Activate(const char *cvarName, const char *curValue, const char *type, const char *question);
/* message returned:
"CvarChangeValue"
"player"
"value"
"type"
*/
// make the input stars, ala a password entry dialog
void MakePassword();
// set the text in a certain label name
void SetLabelText(const char *textEntryName, const char *text);
private:
virtual void OnCommand(const char *command);
virtual void OnClose();
vgui::Label *m_pInfoLabel;
vgui::Label *m_pCvarLabel;
vgui::TextEntry *m_pCvarEntry;
vgui::Button *m_pOkayButton;
bool m_bAddCvarText; // if true puts the cvar name into the dialog
typedef vgui::Frame BaseClass;
const char *m_cType;
};
#endif // DIALOGCVARCHANGE_H

View File

@ -0,0 +1,532 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "DialogGameInfo.h"
#include "Info.h"
#include "IRunGameEngine.h"
#include "IGameList.h"
#include "TrackerProtocol.h"
#include "serverpage.h"
#include "ServerList.h"
#include "DialogServerPassword.h"
#include <VGUI_Controls.h>
#include <VGUI_ISystem.h>
#include <VGUI_ISurface.h>
#include <VGUI_IVGui.h>
#include <VGUI_KeyValues.h>
#include <VGUI_Label.h>
#include <VGUI_TextEntry.h>
#include <VGUI_Button.h>
#include <VGUI_ToggleButton.h>
#include <VGUI_RadioButton.h>
#include <stdio.h>
using namespace vgui;
static const long RETRY_TIME = 10000; // refresh server every 10 seconds
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CDialogGameInfo::CDialogGameInfo(IGameList *gameList, unsigned int serverID, int serverIP, int serverPort) : Frame(NULL, "DialogGameInfo"), m_Servers(this)
{
MakePopup();
SetBounds(0, 0, 512, 384);
m_bConnecting = false;
m_bServerFull = false;
m_bShowAutoRetryToggle = false;
m_bServerNotResponding = false;
m_bShowingExtendedOptions = false;
m_szPassword[0] = 0;
m_iServerID = serverID;
m_pConnectButton = new Button(this, "Connect", "&Join Game");
m_pCloseButton = new Button(this, "Close", "&Close");
m_pRefreshButton = new Button(this, "Refresh", "&Refresh");
m_pInfoLabel = new Label(this, "InfoLabel", "");
m_pAutoRetry = new ToggleButton(this, "AutoRetry", "&Auto-Retry");
m_pAutoRetry->AddActionSignalTarget(this);
m_pAutoRetryAlert = new RadioButton(this, "AutoRetryAlert", "A&lert me when a player slot is available on server.");
m_pAutoRetryJoin = new RadioButton(this, "AutoRetryJoin", "J&oin the server as soon as a player slot is available.");
m_pAutoRetryAlert->SetSelected(true);
m_pConnectButton->SetCommand(new KeyValues("Connect"));
m_pCloseButton->SetCommand(new KeyValues("Close"));
m_pRefreshButton->SetCommand(new KeyValues("Refresh"));
m_iRequestRetry = 0;
SetSizeable(false);
if (gameList)
{
// we already have the game info, fill it in
serveritem_t &server = gameList->GetServer(serverID);
m_iServerID = m_Servers.AddNewServer(server);
}
else
{
// create a new server to watch
serveritem_t server;
memset(&server, 0, sizeof(server));
*((int *)server.ip) = serverIP;
server.port = serverPort;
m_iServerID = m_Servers.AddNewServer(server);
}
// refresh immediately
RequestInfo();
// let us be ticked every frame
ivgui()->AddTickSignal(this->GetVPanel());
LoadControlSettings("Admin\\DialogGameInfo.res");
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CDialogGameInfo::~CDialogGameInfo()
{
}
//-----------------------------------------------------------------------------
// Purpose: Activates the dialog
//-----------------------------------------------------------------------------
void CDialogGameInfo::Run(const char *titleName)
{
char buf[512];
if (titleName)
{
sprintf(buf, "Game Info - %s", titleName);
}
else
{
strcpy(buf, "Game Info");
}
SetTitle(buf, true);
// get the info from the user
RequestInfo();
RequestFocus();
}
//-----------------------------------------------------------------------------
// Purpose: Changes which server to watch
//-----------------------------------------------------------------------------
void CDialogGameInfo::ChangeGame(int serverIP, int serverPort)
{
// check to see if it's the same game
serveritem_t &server = m_Servers.GetServer(m_iServerID);
if (*(int *)server.ip == serverIP && server.port == serverPort)
{
return;
}
// change the server
m_Servers.Clear();
// create a new server to watch
serveritem_t newServer;
memset(&newServer, 0, sizeof(newServer));
*((int *)newServer.ip) = serverIP;
newServer.port = serverPort;
m_iServerID = m_Servers.AddNewServer(newServer);
// start refresh immediately
RequestInfo();
}
//-----------------------------------------------------------------------------
// Purpose: Relayouts the data
//-----------------------------------------------------------------------------
void CDialogGameInfo::PerformLayout()
{
BaseClass::PerformLayout();
// get the server we're watching
serveritem_t &server = m_Servers.GetServer(m_iServerID);
SetControlText("ServerText", server.name);
SetControlText("GameText", server.gameDescription);
SetControlText("MapText", server.map);
char buf[128];
if (server.maxPlayers > 0)
{
sprintf(buf, "%d / %d", server.players, server.maxPlayers);
}
else
{
buf[0] = 0;
}
SetControlText("PlayersText", buf);
if (server.ip[0] && server.port)
{
char buf[64];
sprintf(buf, "%d.%d.%d.%d:%d", server.ip[0], server.ip[1], server.ip[2], server.ip[3], server.port);
SetControlText("ServerIPText", buf);
m_pConnectButton->SetEnabled(true);
}
else
{
SetControlText("ServerIPText", "");
m_pConnectButton->SetEnabled(false);
}
sprintf(buf, "%d", server.ping);
SetControlText("PingText", buf);
// set the info text
if (m_pAutoRetry->IsSelected())
{
if (server.players < server.maxPlayers)
{
m_pInfoLabel->SetText("Press 'Join Game' to connect to the server.");
}
else if (m_pAutoRetryJoin->IsSelected())
{
m_pInfoLabel->SetText("You will join the server as soon as a player slot is free.");
}
else
{
m_pInfoLabel->SetText("You will be alerted as soon player slot is free on the server.");
}
}
else if (m_bServerFull)
{
m_pInfoLabel->SetText("Could not connect - server is full.");
}
else if (m_bServerNotResponding)
{
char text[100];
_snprintf(text,100,"Server is not responding.%d.%d.%d.%d:%d", server.ip[0], server.ip[1], server.ip[2], server.ip[3], server.port);
m_pInfoLabel->SetText(text);
}
else
{
// clear the status
m_pInfoLabel->SetText("");
}
// auto-retry layout
m_pAutoRetry->SetVisible(m_bShowAutoRetryToggle);
if (m_pAutoRetry->IsSelected())
{
m_pAutoRetryAlert->SetVisible(true);
m_pAutoRetryJoin->SetVisible(true);
}
else
{
m_pAutoRetryAlert->SetVisible(false);
m_pAutoRetryJoin->SetVisible(false);
}
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: Sets up the current scheme colors
//-----------------------------------------------------------------------------
void CDialogGameInfo::ApplySchemeSettings(vgui::IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
// force the label to get it's scheme settings
m_pInfoLabel->InvalidateLayout(true);
// override them
m_pInfoLabel->SetFgColor(GetSchemeColor("BrightControlText"));
}
//-----------------------------------------------------------------------------
// Purpose: Forces the game info dialog to try and connect
//-----------------------------------------------------------------------------
void CDialogGameInfo::Connect()
{
OnConnect();
}
//-----------------------------------------------------------------------------
// Purpose: Connects the user to this game
//-----------------------------------------------------------------------------
void CDialogGameInfo::OnConnect()
{
// flag that we are attempting connection
m_bConnecting = true;
// reset state
m_bServerFull = false;
m_bServerNotResponding = false;
InvalidateLayout();
// need to refresh server before attempting to connect, to make sure there is enough room on the server
RequestInfo();
}
//-----------------------------------------------------------------------------
// Purpose: Handles Refresh button press, starts a re-ping of the server
//-----------------------------------------------------------------------------
void CDialogGameInfo::OnRefresh()
{
// re-ask the server for the game info
RequestInfo();
}
//-----------------------------------------------------------------------------
// Purpose: Deletes the dialog when it's closed
//-----------------------------------------------------------------------------
void CDialogGameInfo::OnClose()
{
BaseClass::OnClose();
MarkForDeletion();
}
//-----------------------------------------------------------------------------
// Purpose: Forces the whole dialog to redraw when the auto-retry button is toggled
//-----------------------------------------------------------------------------
void CDialogGameInfo::OnButtonToggled(Panel *panel)
{
if (panel == m_pAutoRetry)
{
ShowAutoRetryOptions(m_pAutoRetry->IsSelected());
}
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: Sets whether the extended auto-retry options are visible or not
// Input : state -
//-----------------------------------------------------------------------------
void CDialogGameInfo::ShowAutoRetryOptions(bool state)
{
// we need to extend the dialog
int growSize = 60;
if (!state)
{
growSize = -growSize;
}
// alter the dialog size accordingly
int wide, tall;
GetSize(wide, tall);
tall += growSize;
SetSize(wide, tall);
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: Sets the text of a control by name
//-----------------------------------------------------------------------------
void CDialogGameInfo::SetControlText(const char *textEntryName, const char *text)
{
TextEntry *entry = dynamic_cast<TextEntry *>(FindChildByName(textEntryName));
if (entry)
{
entry->SetText(text);
}
}
//-----------------------------------------------------------------------------
// Purpose: Requests the right info from the server
//-----------------------------------------------------------------------------
void CDialogGameInfo::RequestInfo()
{
// reset the time at which we auto-refresh
m_iRequestRetry = system()->GetTimeMillis() + RETRY_TIME;
if (!m_Servers.IsRefreshing())
{
m_Servers.AddServerToRefreshList(m_iServerID);
m_Servers.StartRefresh();
}
}
//-----------------------------------------------------------------------------
// Purpose: Called every frame, handles resending network messages
//-----------------------------------------------------------------------------
void CDialogGameInfo::OnTick()
{
// check to see if we should perform an auto-refresh
if (m_iRequestRetry && m_iRequestRetry < system()->GetTimeMillis())
{
// reask
RequestInfo();
}
m_Servers.RunFrame();
}
//-----------------------------------------------------------------------------
// Purpose: called when the server has successfully responded
//-----------------------------------------------------------------------------
void CDialogGameInfo::ServerResponded(serveritem_t &server)
{
if (m_bConnecting)
{
ConnectToServer();
}
else if (m_pAutoRetry->IsSelected())
{
// auto-retry is enabled, see if we can join
if (server.players < server.maxPlayers)
{
// there is a slot free, we can join
// make the sound
surface()->PlaySound("Servers\\game_ready.wav");
// flash this window
FlashWindow();
// if it's set, connect right away
if (m_pAutoRetryJoin->IsSelected())
{
ConnectToServer();
}
}
}
m_bServerNotResponding = false;
InvalidateLayout();
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: called when a server response has timed out
//-----------------------------------------------------------------------------
void CDialogGameInfo::ServerFailedToRespond(serveritem_t &server)
{
// the server didn't respond, mark that in the UI
// only mark if we haven't ever received a response
if (!server.hadSuccessfulResponse)
{
m_bServerNotResponding = true;
}
InvalidateLayout();
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: Connects to the server
//-----------------------------------------------------------------------------
void CDialogGameInfo::ConnectToServer()
{
m_bConnecting = false;
serveritem_t &server = m_Servers.GetServer(m_iServerID);
// check to see if we need a password
if (server.password && !m_szPassword[0])
{
CDialogServerPassword *box = new CDialogServerPassword();
box->AddActionSignalTarget(this);
box->Activate(server.name, server.serverID);
return;
}
// check the player count
if (server.players >= server.maxPlayers)
{
// mark why we cannot connect
m_bServerFull = true;
// give them access to auto-retry options
m_bShowAutoRetryToggle = true;
InvalidateLayout();
return;
}
// tell the engine to connect
char buf[64];
sprintf(buf, "%d.%d.%d.%d:%d", server.ip[0], server.ip[1], server.ip[2], server.ip[3], server.port);
const char *gameDir = server.gameDir;
if (g_pRunGameEngine->IsRunning())
{
char command[256];
// set the server password, if any
if (m_szPassword[0])
{
sprintf(command, "password \"%s\"\n", m_szPassword);
g_pRunGameEngine->AddTextCommand(command);
}
// send engine command to change servers
sprintf(command, "connect %s\n", buf);
g_pRunGameEngine->AddTextCommand(command);
}
else
{
char command[256];
// sprintf(command, " -game %s +connect %s", gameDir, buf);
sprintf(command, " +connect %s", buf);
if (m_szPassword[0])
{
strcat(command, " +password \"");
strcat(command, m_szPassword);
strcat(command, "\"");\
}
g_pRunGameEngine->RunEngine(gameDir, command);
}
// close this dialog
PostMessage(this, new KeyValues("Close"));
}
//-----------------------------------------------------------------------------
// Purpose: called when the current refresh list is complete
//-----------------------------------------------------------------------------
void CDialogGameInfo::RefreshComplete()
{
}
//-----------------------------------------------------------------------------
// Purpose: handles response from the get password dialog
//-----------------------------------------------------------------------------
void CDialogGameInfo::OnJoinServerWithPassword(const char *password)
{
// copy out the password
v_strncpy(m_szPassword, password, sizeof(m_szPassword));
// retry connecting to the server again
OnConnect();
}
//-----------------------------------------------------------------------------
// Purpose: Message map
//-----------------------------------------------------------------------------
MessageMapItem_t CDialogGameInfo::m_MessageMap[] =
{
MAP_MESSAGE( CDialogGameInfo, "Refresh", OnRefresh ),
MAP_MESSAGE( CDialogGameInfo, "Connect", OnConnect ),
MAP_MESSAGE_PTR( CDialogGameInfo, "ButtonToggled", OnButtonToggled, "panel" ),
MAP_MESSAGE_PTR( CDialogGameInfo, "RadioButtonChecked", OnButtonToggled, "panel" ),
MAP_MESSAGE_CONSTCHARPTR( CDialogGameInfo, "JoinServerWithPassword", OnJoinServerWithPassword, "password" ),
};
IMPLEMENT_PANELMAP( CDialogGameInfo, Frame );

View File

@ -0,0 +1,110 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef DIALOGGAMEINFO_H
#define DIALOGGAMEINFO_H
#ifdef _WIN32
#pragma once
#endif
#include <VGUI_Frame.h>
#include "ServerList.h"
#include "IServerRefreshResponse.h"
class KeyValues;
namespace vgui
{
class Button;
class ToggleButton;
class RadioButton;
class Label;
class TextEntry;
}
//-----------------------------------------------------------------------------
// Purpose: Dialog for displaying information about a game server
//-----------------------------------------------------------------------------
class CDialogGameInfo : public vgui::Frame, public IServerRefreshResponse
{
public:
CDialogGameInfo(class IGameList *gameList, unsigned int serverID, int serverIP = 0, int serverPort = 0);
~CDialogGameInfo();
void Run(const char *titleName);
void ChangeGame(int serverIP, int serverPort);
// forces the dialog to attempt to connect to the server
void Connect();
// implementation of IServerRefreshResponse interface
// called when the server has successfully responded
virtual void ServerResponded(serveritem_t &server);
// called when a server response has timed out
virtual void ServerFailedToRespond(serveritem_t &server);
// called when the current refresh list is complete
virtual void RefreshComplete();
protected:
// message handlers
void OnConnect();
void OnRefresh();
void OnButtonToggled(vgui::Panel *toggleButton);
// response from the get password dialog
void OnJoinServerWithPassword(const char *password);
DECLARE_PANELMAP();
// vgui overrides
void OnTick();
virtual void OnClose();
virtual void PerformLayout();
virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
private:
long m_iRequestRetry; // time at which to retry the request
// methods
void RequestInfo();
void ConnectToServer();
void ShowAutoRetryOptions(bool state);
void SetControlText(const char *textEntryName, const char *text);
vgui::Button *m_pConnectButton;
vgui::Button *m_pCloseButton;
vgui::Button *m_pRefreshButton;
vgui::Label *m_pInfoLabel;
vgui::ToggleButton *m_pAutoRetry;
vgui::RadioButton *m_pAutoRetryAlert;
vgui::RadioButton *m_pAutoRetryJoin;
// the ID of the server we're watching
unsigned int m_iServerID;
// server refreshing object
CServerList m_Servers;
// true if we should try connect to the server when it refreshes
bool m_bConnecting;
// password, if entered
char m_szPassword[64];
// state
bool m_bServerNotResponding;
bool m_bServerFull;
bool m_bShowAutoRetryToggle;
bool m_bShowingExtendedOptions;
typedef vgui::Frame BaseClass;
};
#endif // DIALOGGAMEINFO_H

View File

@ -0,0 +1,130 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include <stdio.h>
#include "DialogKickPlayer.h"
#include <VGUI_Button.h>
#include <VGUI_KeyValues.h>
#include <VGUI_Label.h>
#include <VGUI_TextEntry.h>
#include <VGUI_Controls.h>
#include <VGUI_ISurface.h>
using namespace vgui;
#define max(a,b) (((a) > (b)) ? (a) : (b))
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CDialogKickPlayer::CDialogKickPlayer() : Frame(NULL, "DialogKickPlayer")
{
SetSize(320, 200);
m_pInfoLabel = new Label(this, "InfoLabel", "Kick Player?");
m_pPlayerLabel = new Label(this, "PlayerLabel", "<player name>");
m_pOkayButton = new Button(this, "OkayButton", "&Okay");
LoadControlSettings("Admin\\DialogKickPlayer.res");
SetTitle("Kick/Ban/Status Player", true);
// set our initial position in the middle of the workspace
MoveToCenterOfScreen();
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CDialogKickPlayer::~CDialogKickPlayer()
{
}
//-----------------------------------------------------------------------------
// Purpose: initializes the dialog and brings it to the foreground
//-----------------------------------------------------------------------------
void CDialogKickPlayer::Activate(const char *playerName,const char *question,const char *type)
{
m_pPlayerLabel->SetText(playerName);
m_pInfoLabel->SetText(question);
m_pInfoLabel->SizeToContents();
// SetSize(
int wide,tall;
m_pInfoLabel->GetSize(wide,tall);
SetWide(max(wide+50,GetWide()));
m_cType=type;
m_pOkayButton->SetAsDefaultButton(true);
MakePopup();
MoveToFront();
RequestFocus();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *command -
//-----------------------------------------------------------------------------
void CDialogKickPlayer::OnCommand(const char *command)
{
bool bClose = false;
if (!stricmp(command, "Okay"))
{
KeyValues *msg = new KeyValues("KickPlayer");
char buf[64];
m_pPlayerLabel->GetText(buf,64);
msg->SetString("player", buf );
msg->SetString("type",m_cType);
PostActionSignal(msg);
bClose = true;
}
else if (!stricmp(command, "Close"))
{
bClose = true;
}
else
{
BaseClass::OnCommand(command);
}
if (bClose)
{
PostMessage(this, new KeyValues("Close"));
MarkForDeletion();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDialogKickPlayer::PerformLayout()
{
BaseClass::PerformLayout();
}
//-----------------------------------------------------------------------------
// Purpose: deletes the dialog on close
//-----------------------------------------------------------------------------
void CDialogKickPlayer::OnClose()
{
BaseClass::OnClose();
MarkForDeletion();
}

View File

@ -0,0 +1,57 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef DIALOGKICKPLAYER_H
#define DIALOGKICKPLAYER_H
#ifdef _WIN32
#pragma once
#endif
#include <VGUI_Frame.h>
namespace vgui
{
class TextEntry;
class Label;
class Button;
};
//-----------------------------------------------------------------------------
// Purpose: Prompt for user to enter a password to be able to connect to the server
//-----------------------------------------------------------------------------
class CDialogKickPlayer : public vgui::Frame
{
public:
CDialogKickPlayer();
~CDialogKickPlayer();
// initializes the dialog and brings it to the foreground
void Activate(const char *playerName, const char *question,const char *type);
/* message returned:
"KickPlayer"
"player"
"type"
*/
private:
virtual void PerformLayout();
virtual void OnCommand(const char *command);
virtual void OnClose();
vgui::Label *m_pInfoLabel;
vgui::Label *m_pPlayerLabel;
vgui::Button *m_pOkayButton;
typedef vgui::Frame BaseClass;
const char *m_cType;
};
#endif // DIALOGKICKPLAYER_H

View File

@ -0,0 +1,119 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "DialogServerPassword.h"
#include <VGUI_Button.h>
#include <VGUI_KeyValues.h>
#include <VGUI_Label.h>
#include <VGUI_TextEntry.h>
#include <VGUI_Controls.h>
#include <VGUI_ISurface.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CDialogServerPassword::CDialogServerPassword() : Frame(NULL, "DialogServerPassword")
{
m_iServerID = -1;
SetSize(320, 240);
m_pInfoLabel = new Label(this, "InfoLabel", "This server requires a password to join.");
m_pGameLabel = new Label(this, "GameLabel", "<game label>");
m_pPasswordEntry = new TextEntry(this, "PasswordEntry");
m_pConnectButton = new Button(this, "ConnectButton", "&Connect");
m_pPasswordEntry->SetTextHidden(true);
LoadControlSettings("Admin\\DialogServerPassword.res");
SetTitle("Server Requires Password - Servers", true);
// set our initial position in the middle of the workspace
MoveToCenterOfScreen();
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CDialogServerPassword::~CDialogServerPassword()
{
}
//-----------------------------------------------------------------------------
// Purpose: initializes the dialog and brings it to the foreground
//-----------------------------------------------------------------------------
void CDialogServerPassword::Activate(const char *serverName, unsigned int serverID)
{
m_pGameLabel->SetText(serverName);
m_iServerID = serverID;
m_pConnectButton->SetAsDefaultButton(true);
MakePopup();
MoveToFront();
m_pPasswordEntry->RequestFocus();
RequestFocus();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *command -
//-----------------------------------------------------------------------------
void CDialogServerPassword::OnCommand(const char *command)
{
bool bClose = false;
if (!stricmp(command, "Connect"))
{
KeyValues *msg = new KeyValues("JoinServerWithPassword");
char buf[64];
m_pPasswordEntry->GetText(0, buf, sizeof(buf)-1);
msg->SetString("password", buf);
msg->SetInt("serverID", m_iServerID);
PostActionSignal(msg);
bClose = true;
}
else if (!stricmp(command, "Close"))
{
bClose = true;
}
else
{
BaseClass::OnCommand(command);
}
if (bClose)
{
PostMessage(this, new KeyValues("Close"));
MarkForDeletion();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDialogServerPassword::PerformLayout()
{
BaseClass::PerformLayout();
}
//-----------------------------------------------------------------------------
// Purpose: deletes the dialog on close
//-----------------------------------------------------------------------------
void CDialogServerPassword::OnClose()
{
BaseClass::OnClose();
MarkForDeletion();
}

View File

@ -0,0 +1,58 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef DIALOGSERVERPASSWORD_H
#define DIALOGSERVERPASSWORD_H
#ifdef _WIN32
#pragma once
#endif
#include <VGUI_Frame.h>
namespace vgui
{
class TextEntry;
class Label;
class Button;
};
//-----------------------------------------------------------------------------
// Purpose: Prompt for user to enter a password to be able to connect to the server
//-----------------------------------------------------------------------------
class CDialogServerPassword : public vgui::Frame
{
public:
CDialogServerPassword();
~CDialogServerPassword();
// initializes the dialog and brings it to the foreground
void Activate(const char *serverName, unsigned int serverID);
/* message returned:
"JoinServerWithPassword"
"serverID"
"password"
*/
private:
virtual void PerformLayout();
virtual void OnCommand(const char *command);
virtual void OnClose();
vgui::Label *m_pInfoLabel;
vgui::Label *m_pGameLabel;
vgui::TextEntry *m_pPasswordEntry;
vgui::Button *m_pConnectButton;
typedef vgui::Frame BaseClass;
int m_iServerID;
};
#endif // DIALOGSERVERPASSWORD_H

View File

@ -0,0 +1,815 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "FavoriteGames.h"
#include "proto_oob.h"
#include "ServerContextMenu.h"
#include "ServerListCompare.h"
#include "Socket.h"
#include "util.h"
#include "serverpage.h"
#include "DialogAddServer.h"
#include "FavoriteGames.h"
#include "filesystem.h"
#include "tier1/utlbuffer.h"
#include <VGUI_Controls.h>
#include <VGUI_KeyValues.h>
#include <VGUI_ListPanel.h>
#include <VGUI_IScheme.h>
#include <VGUI_IVGui.h>
#include <VGUI_ImagePanel.h>
#include <VGUI_ISystem.h>
#include <VGUI_MessageBox.h>
#include <VGUI_Button.h>
using namespace vgui;
const int TIMEOUT = 99999;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CFavoriteGames::CFavoriteGames(vgui::Panel *parent) : CBaseGamesPage(parent, "FavoriteGames")
{
m_iServerRefreshCount = 0;
m_pImportFavoritesdlg = NULL;
m_bSaveRcon=false;
StartRefresh();
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CFavoriteGames::~CFavoriteGames()
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CFavoriteGames::LoadFavoritesList(KeyValues *favoritesData,bool loadrcon)
{
// load in favorites
for (KeyValues *dat = favoritesData->GetFirstSubKey(); dat != NULL; dat = dat->GetNextKey())
{
serveritem_t server;
memset(&server, 0, sizeof(server));
const char *addr = dat->GetString("address");
int ip1, ip2, ip3, ip4, port;
sscanf(addr, "%d.%d.%d.%d:%d", &ip1, &ip2, &ip3, &ip4, &port);
server.ip[0] = ip1;
server.ip[1] = ip2;
server.ip[2] = ip3;
server.ip[3] = ip4;
server.port = port;
server.players = 0;
v_strncpy(server.name, dat->GetString("name"), sizeof(server.name));
v_strncpy(server.map, dat->GetString("map"), sizeof(server.map));
v_strncpy(server.gameDir, dat->GetString("gamedir"), sizeof(server.gameDir));
server.players = dat->GetInt("players");
server.maxPlayers = dat->GetInt("maxplayers");
if(loadrcon)
{
v_strncpy(server.rconPassword,dat->GetString("rconpassword"),sizeof(server.rconPassword));
}
// add to main list
AddNewServer(server);
}
}
//-----------------------------------------------------------------------------
// Purpose: updates the Rconpassword for a server, and perhaps more later :)
//-----------------------------------------------------------------------------
void CFavoriteGames::UpdateServer(serveritem_t &serverIn)
{
for (int i = 0; i < m_Servers.ServerCount(); i++)
{
serveritem_t &serverOut = m_Servers.GetServer(i);
if( !memcmp(serverOut.ip,serverIn.ip,sizeof(serverIn.ip)) &&
serverOut.port==serverIn.port)
{
// we have a match!
v_strncpy(serverOut.rconPassword,serverIn.rconPassword,sizeof(serverOut.rconPassword));
}
}
}
//-----------------------------------------------------------------------------
// Purpose: saves the current list of servers to the favorites section of the data file
//-----------------------------------------------------------------------------
void CFavoriteGames::SaveFavoritesList(KeyValues *favoritesData,bool savercon)
{
favoritesData->Clear();
// loop through all the servers writing them into the doc
for (int i = 0; i < m_Servers.ServerCount(); i++)
{
serveritem_t &server = m_Servers.GetServer(i);
// always save away all the entries, even if they didn't respond this time
//if (server.doNotRefresh)
// continue;
KeyValues *dat = favoritesData->CreateNewKey();
dat->SetString("name", server.name);
dat->SetString("gamedir", server.gameDir);
dat->SetInt("players", server.players);
dat->SetInt("maxplayers", server.maxPlayers);
dat->SetString("map", server.map);
if(savercon)
{
dat->SetString("rconpassword",server.rconPassword);
}
char buf[64];
sprintf(buf, "%d.%d.%d.%d:%d", server.ip[0], server.ip[1], server.ip[2], server.ip[3], server.port);
dat->SetString("address", buf);
}
}
//-----------------------------------------------------------------------------
// Purpose: returns true if the game list supports the specified ui elements
// Input : item -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CFavoriteGames::SupportsItem(InterfaceItem_e item)
{
switch (item)
{
case GETNEWLIST:
case FILTERS:
default:
return false;
}
}
//-----------------------------------------------------------------------------
// Purpose: starts the servers refreshing
//-----------------------------------------------------------------------------
void CFavoriteGames::StartRefresh()
{
// stop current refresh
m_Servers.StopRefresh();
// build the refresh list from the server list
for (int i = 0; i < m_Servers.ServerCount(); i++)
{
// When managing servers it doesn't matter if they don't respond
//if (m_Servers.GetServer(i).doNotRefresh)
// continue;
m_Servers.AddServerToRefreshList(i);
}
m_Servers.StartRefresh();
SetRefreshing(IsRefreshing());
}
//-----------------------------------------------------------------------------
// Purpose: gets a new server list
//-----------------------------------------------------------------------------
void CFavoriteGames::GetNewServerList()
{
}
//-----------------------------------------------------------------------------
// Purpose: stops current refresh/GetNewServerList()
//-----------------------------------------------------------------------------
void CFavoriteGames::StopRefresh()
{
// stop the server list refreshing
m_Servers.StopRefresh();
// clear update states
m_iServerRefreshCount = 0;
// update UI
RefreshComplete();
}
//-----------------------------------------------------------------------------
// Purpose: returns true if the list is currently refreshing servers
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CFavoriteGames::IsRefreshing()
{
return m_Servers.IsRefreshing();
}
//-----------------------------------------------------------------------------
// Purpose: adds a new server to list
// Input : &server -
//-----------------------------------------------------------------------------
void CFavoriteGames::AddNewServer(serveritem_t &newServer)
{
// copy server into main server list
unsigned int index = m_Servers.AddNewServer(newServer);
// reget the server
serveritem_t &server = m_Servers.GetServer(index);
server.hadSuccessfulResponse = true;
server.doNotRefresh = false;
server.listEntry = NULL;
server.serverID = index;
}
//-----------------------------------------------------------------------------
// Purpose: Continues the refresh
// Input : moreAvailable -
// lastUnique -
//-----------------------------------------------------------------------------
void CFavoriteGames::ListReceived(bool moreAvailable, int lastUnique)
{
m_Servers.StartRefresh();
}
//-----------------------------------------------------------------------------
// Purpose: called when Connect button is pressed
//-----------------------------------------------------------------------------
void CFavoriteGames::OnBeginConnect()
{
if (!m_pGameList->GetNumSelectedRows())
return;
// get the server
int serverIndex = m_pGameList->GetDataItem(m_pGameList->GetSelectedRow(0))->userData;
// stop the current refresh
StopRefresh();
// join the game
CServerPage::GetInstance()->JoinGame(this, serverIndex);
}
//-----------------------------------------------------------------------------
// Purpose: Displays the current game info without connecting
//-----------------------------------------------------------------------------
void CFavoriteGames::OnViewGameInfo()
{
if (!m_pGameList->GetNumSelectedRows())
return;
// get the server
int serverIndex = m_pGameList->GetDataItem(m_pGameList->GetSelectedRow(0))->userData;
// stop the current refresh
StopRefresh();
// join the game
CServerPage::GetInstance()->OpenGameInfoDialog(this, serverIndex);
}
//-----------------------------------------------------------------------------
// Purpose: reapplies filters (does nothing with this)
//-----------------------------------------------------------------------------
void CFavoriteGames::ApplyFilters()
{
}
//-----------------------------------------------------------------------------
// Purpose: called when the server has successfully responded
// Input : &server -
//-----------------------------------------------------------------------------
void CFavoriteGames::ServerResponded(serveritem_t &server)
{
// update UI
KeyValues *kv;
if (server.listEntry)
{
// we're updating an existing entry
kv = server.listEntry->kv;
server.listEntry->userData = server.serverID;
}
else
{
// new entry
kv = new KeyValues("Server");
}
if (server.name[0] && server.maxPlayers)
{
kv->SetString("name", server.name);
kv->SetString("map", server.map);
kv->SetString("GameDir", server.gameDir);
kv->SetString("GameDesc", server.gameDescription);
kv->SetPtr("password", server.password ? m_pPasswordIcon : NULL);
char buf[256];
sprintf(buf, "%d / %d", server.players, server.maxPlayers);
kv->SetString("Players", buf);
}
if(server.ping==TIMEOUT)
{
kv->SetString("Ping", "timeout");
}
else
{
kv->SetInt("Ping", server.ping);
}
if (!server.listEntry)
{
// new server, add to list
int index = m_pGameList->AddItem(kv, server.serverID);
server.listEntry = m_pGameList->GetDataItem(index);
}
else
{
m_pGameList->ApplyItemChanges(server.listEntry->row);
}
m_iServerRefreshCount++;
if (m_pGameList->GetItemCount() > 1)
{
char buf[64];
sprintf(buf, " Servers (%d)", m_pGameList->GetItemCount());
m_pGameList->SetColumnHeaderText(1, buf);
}
else
{
m_pGameList->SetColumnHeaderText(1, " Servers");
}
m_pGameList->Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: called when a server response has timed out, treated just like a normal server
//-----------------------------------------------------------------------------
void CFavoriteGames::ServerFailedToRespond(serveritem_t &server)
{
server.ping=TIMEOUT;
ServerResponded(server);
}
//-----------------------------------------------------------------------------
// Purpose: called when the current refresh list is complete
//-----------------------------------------------------------------------------
void CFavoriteGames::RefreshComplete()
{
SetRefreshing(false);
m_pGameList->SortList();
m_iServerRefreshCount = 0;
}
//-----------------------------------------------------------------------------
// Purpose: opens context menu (user right clicked on a server)
//-----------------------------------------------------------------------------
void CFavoriteGames::OnOpenContextMenu(int row)
{
CServerContextMenu *menu = CServerPage::GetInstance()->GetContextMenu();
if (m_pGameList->GetNumSelectedRows())
{
// get the server
unsigned int serverID = m_pGameList->GetDataItem(m_pGameList->GetSelectedRow(0))->userData;
serveritem_t &server = m_Servers.GetServer(serverID);
// activate context menu
menu->ShowMenu(this, serverID, true, true, false,true);
menu->AddMenuItem("RemoveServer", "R&emove server from favorites", new KeyValues("RemoveFromFavorites"), this);
}
else
{
// no selected rows, so don't display default stuff in menu
menu->ShowMenu(this, -1, false, false, false,false);
}
menu->AddMenuItem("AddServerByName", "&Add server by IP address", new KeyValues("AddServerByName"), this);
}
//-----------------------------------------------------------------------------
// Purpose: refreshes a single server
//-----------------------------------------------------------------------------
void CFavoriteGames::OnRefreshServer(int serverID)
{
// walk the list of selected servers refreshing them
for (int i = 0; i < m_pGameList->GetNumSelectedRows(); i++)
{
int row = m_pGameList->GetSelectedRow(i);
ListPanel::DATAITEM *data = m_pGameList->GetDataItem(row);
if (data)
{
serverID = data->userData;
// refresh this server
m_Servers.AddServerToRefreshList(serverID);
}
}
m_Servers.StartRefresh();
SetRefreshing(IsRefreshing());
}
//-----------------------------------------------------------------------------
// Purpose: adds a server to the favorites
// Input : serverID -
//-----------------------------------------------------------------------------
void CFavoriteGames::OnRemoveFromFavorites()
{
// iterate the selection
while (m_pGameList->GetNumSelectedRows() > 0)
{
int row = m_pGameList->GetSelectedRow(0);
int serverID = m_pGameList->GetDataItem(row)->userData;
if (serverID >= m_Servers.ServerCount())
continue;
serveritem_t &server = m_Servers.GetServer(serverID);
// remove from favorites list
if (server.listEntry)
{
// find the row in the list and kill
m_pGameList->RemoveItem(server.listEntry->row);
server.listEntry = NULL;
}
server.doNotRefresh = true;
}
InvalidateLayout();
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: Adds a server by IP address
//-----------------------------------------------------------------------------
void CFavoriteGames::OnAddServerByName()
{
// open the add server dialog
CDialogAddServer *dlg = new CDialogAddServer(this);
dlg->Open();
}
//-----------------------------------------------------------------------------
// Purpose: Load a file into a CUtlBuffer class
//-----------------------------------------------------------------------------
int LoadFileIntoBuffer(CUtlBuffer &buf, char *pszFilename)
{
// Open the file
FileHandle_t fh = g_pFullFileSystem->Open( pszFilename, "rb" );
if (fh == 0)
{
MessageBox *dlg = new MessageBox ("Unable to open datafile.", false);
dlg->DoModal();
return 0; //file didn't load
}
int nFileSize = g_pFullFileSystem->Size(fh);
// Read the file in one gulp
buf.EnsureCapacity( nFileSize );
int result = g_pFullFileSystem->Read( buf.Base(), nFileSize, fh );
g_pFullFileSystem->Close( fh );
return nFileSize;
}
//-----------------------------------------------------------------------------
// Purpose: Import Favorite Servers from previous installations of
// Halflife
//-----------------------------------------------------------------------------
void CFavoriteGames::ImportFavorites()
{
// disabled for now due to filesystem not accepting non-relative paths
return;
char name[512];
// check if halflife is installed
if (vgui::system()->GetRegistryString("HKEY_LOCAL_MACHINE\\Software\\Valve\\Half-life\\InstallPath", name, sizeof(name)))
{
// attach name of favorites file
strcat(name, "\\favsvrs.dat");
}
// check if counterstrike is installed
else if (vgui::system()->GetRegistryString("HKEY_LOCAL_MACHINE\\Software\\Sierra OnLine\\Setup\\CSTRIKE\\Directory", name, sizeof(name)))
{
// attach name of favorites file
strcat(name, "\\favsvrs.dat");
}
else // no hl installation, no fav servers?
{
return;
}
// see if the favorite server list file exists.
FileHandle_t fh = g_pFullFileSystem->Open(name, "rb");
if ( !fh )
{
return;
}
g_pFullFileSystem->Close(fh);
// it exists! yay lets transfer the servers over into the server browser
// pop up a message about what we are doing
m_pImportFavoritesdlg = new MessageBox ("Updating Favorites", "Transferring your Favorites. This may take a minute...", this);
m_pImportFavoritesdlg->SetCommand("OnImportFavoritesFile");
m_pImportFavoritesdlg->AddActionSignalTarget(this);
// hide the ok button since they dont have to do anything
m_pImportFavoritesdlg->SetOkButtonVisible(false);
// don't let them close this window
m_pImportFavoritesdlg->DisableCloseButton(false);
// dont let them put this window on the menubar
m_pImportFavoritesdlg->SetMenuButtonVisible(false);
// Pop up the box
m_pImportFavoritesdlg->DoModal();
// execute the message box's command
KeyValues *command = new KeyValues("Command");
command->SetString("Command", "OnImportFavoritesFile");
// post the message with a delay so that the box will display before the command is executed
PostMessage(this, command, (float).1);
}
//-----------------------------------------------------------------------------
// Purpose: Parse posted messages
//
//-----------------------------------------------------------------------------
void CFavoriteGames::OnCommand(const char *command)
{
if (!strcmp(command, "OnImportFavoritesFile"))
{
OnImportFavoritesFile();
}
else
{
BaseClass::OnCommand(command);
}
}
//-----------------------------------------------------------------------------
// Purpose: Import Favorite Servers from previous installations of
// Halflife
//-----------------------------------------------------------------------------
void CFavoriteGames::OnImportFavoritesFile()
{
char name[512];
// check if they have halflife
if (vgui::system()->GetRegistryString("HKEY_LOCAL_MACHINE\\Software\\Valve\\Half-life\\InstallPath", name, sizeof(name)))
{
// add filename
strcat(name, "\\favsvrs.dat");
}
// check if they have counterstrike
else if (vgui::system()->GetRegistryString("HKEY_LOCAL_MACHINE\\Software\\Sierra OnLine\\Setup\\CSTRIKE\\Directory", name, sizeof(name)))
{
// add filename
strcat(name, "\\favsvrs.dat");
}
else // no hl installation, no fav servers? // should never hit this!
{
return;
}
// load the file in one gulp
CUtlBuffer buf ( 0, 1024, true);
int fileSize = LoadFileIntoBuffer(buf, name);
if ( fileSize == 0)
{
MessageBox *dlg = new MessageBox ("Unable to load favorites", "Error loading file.", this);
dlg->DoModal();
return; //file didn't load
}
// scan for the favorite servers
char data[255];
buf.GetString(data);
while (buf.TellGet() < fileSize)
{
// store the start of the server description so we can go back
// if its a favorite
int serverStart;
if ( strstr (data, "server") != NULL)
{
buf.GetString(data); // get the '{'
serverStart = buf.TellGet();
}
// check if server is a favorite
if ( strstr (data, "favorite") != NULL)
{
buf.GetString(data);
if ( strstr(data, "1") )// server is a favorite
{
// go back to the start and load the details
buf.SeekGet( CUtlBuffer::SEEK_HEAD, serverStart);
// try and add this server
if (!LoadAFavoriteServer (buf))
{
// file may be corrupt, had trouble parsing it
break;
};
}
}
buf.EatWhiteSpace();
buf.GetString(data);
}
// we are done. Hide the message box.
m_pImportFavoritesdlg->SetVisible(false);
}
//-----------------------------------------------------------------------------
// Purpose: Check to make sure we are reading what is expected
//
//-----------------------------------------------------------------------------
bool CFavoriteGames::CheckForCorruption(char *data, const char *checkString)
{
if (strcmp(data, checkString) != 0)
{
MessageBox *dlg = new MessageBox ("Unable to load favorites", "Error loading. File may be corrupt.");
dlg->DoModal();
return true;
}
return false;
}
//-----------------------------------------------------------------------------
// Purpose: Parse throught the details of a server and populate a serveritem_t structure
// Add it to the favorites list at the end.
//-----------------------------------------------------------------------------
bool CFavoriteGames::LoadAFavoriteServer (CUtlBuffer &buf)
{
serveritem_t fav;
char data[255];
buf.GetString(data);
if (CheckForCorruption(data, "\"address\""))
return false;;
buf.GetString(data);
int temp[4];
sscanf (data, "\"%d.%d.%d.%d\"\n", &temp[0], &temp[1], &temp[2], &temp[3]);
fav.ip[0] = temp[0];
fav.ip[1] = temp[1];
fav.ip[2] = temp[2];
fav.ip[3] = temp[3];
buf.EatWhiteSpace();
buf.Scanf ("\"port\" \"%d\"", &fav.port );
if (fav.port < 0)
fav.port += 65536;
buf.EatWhiteSpace();
buf.Scanf ("\"name\" \"%s\"", fav.name );
fav.name[strlen(fav.name)-1]='\0'; // remove trailing quote
buf.EatWhiteSpace();
buf.Scanf ("\"map\" \"%s\"", fav.map );
fav.map[strlen(fav.map)-1]='\0'; // remove trailing quote
buf.EatWhiteSpace();
buf.Scanf ("\"game\" \"%s\"", fav.gameDescription );
fav.gameDescription[strlen(fav.gameDescription)-1]='\0'; // remove trailing quote
buf.EatWhiteSpace();
buf.Scanf ("\"dir\" \"%s\"", fav.gameDir );
fav.gameDir[strlen(fav.gameDir)-1
]='\0'; // remove trailing quote
buf.GetString(data);
if (CheckForCorruption(data, "\"url\""))
return false;;
buf.GetString(data);
buf.GetString(data);
if (CheckForCorruption(data, "\"dl\""))
return false;;
buf.GetString(data);
buf.EatWhiteSpace();
buf.Scanf ("\"maxplayers\" \"%d\"", &fav.maxPlayers );
buf.EatWhiteSpace();
buf.Scanf ("\"currentplayers\" \"%d\"", &fav.players );
buf.GetString(data);
if (CheckForCorruption(data, "\"protocol\""))
return false;;
buf.GetString(data);
buf.GetString(data);
if (CheckForCorruption(data, "\"favorite\""))
return false;;
buf.GetString(data);
buf.GetString(data);
if (CheckForCorruption(data, "\"ipx\""))
return false;;
buf.GetString(data);
buf.GetString(data);
if (CheckForCorruption(data, "\"mod\""))
return false;;
buf.GetString(data);
buf.GetString(data);
if (CheckForCorruption(data, "\"version\""))
return false;;
buf.GetString(data);
buf.GetString(data);
if (CheckForCorruption(data, "\"size\""))
return false;;
buf.GetString(data);
buf.GetString(data);
if (CheckForCorruption(data, "\"svtype\""))
return false;;
buf.GetString(data);
buf.GetString(data);
if (CheckForCorruption(data, "\"svos\""))
return false;;
buf.GetString(data);
buf.EatWhiteSpace();
buf.Scanf ("\"password\" \"%d\"\n", &fav.password );
buf.GetString(data);
if (CheckForCorruption(data, "\"svside\""))
return false;;
buf.GetString(data);
buf.GetString(data);
if (CheckForCorruption(data, "\"cldll\""))
return false;;
buf.GetString(data);
buf.GetString(data);
if (CheckForCorruption(data, "\"lan\""))
return false;;
buf.GetString(data);
buf.GetString(data);
if (CheckForCorruption(data, "\"svping\""))
return false;;
buf.GetString(data);
buf.GetString(data);
if (CheckForCorruption(data, "\"noresponse\""))
return false;;
buf.GetString(data);
buf.GetString(data);
if (CheckForCorruption(data, "\"packetloss\""))
return false;;
buf.GetString(data);
buf.GetString(data);
if (CheckForCorruption(data, "\"status\""))
return false;;
buf.GetString(data);
buf.GetString(data);
if (CheckForCorruption(data, "\"filtered\""))
return false;;
buf.GetString(data);
buf.GetString(data);
if (CheckForCorruption(data, "\"fullmax\""))
return false;;
buf.GetString(data);
buf.GetString(data);
if (CheckForCorruption(data, "\"hlversion\""))
return false;;
buf.GetString(data);
AddNewServer(fav);
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Message map
//-----------------------------------------------------------------------------
MessageMapItem_t CFavoriteGames::m_MessageMap[] =
{
MAP_MESSAGE( CFavoriteGames, "ConnectToServer", OnBeginConnect ),
MAP_MESSAGE( CFavoriteGames, "ViewGameInfo", OnViewGameInfo ),
MAP_MESSAGE( CFavoriteGames, "RemoveFromFavorites", OnRemoveFromFavorites ),
MAP_MESSAGE( CFavoriteGames, "AddServerByName", OnAddServerByName ),
MAP_MESSAGE_INT( CFavoriteGames, "RefreshServer", OnRefreshServer, "serverID" ),
MAP_MESSAGE_INT( CFavoriteGames, "OpenContextMenu", OnOpenContextMenu, "row" ),
};
IMPLEMENT_PANELMAP(CFavoriteGames, BaseClass);

View File

@ -0,0 +1,121 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef FAVORITEGAMES_H
#define FAVORITEGAMES_H
#ifdef _WIN32
#pragma once
#endif
#include "BaseGamesPage.h"
#include "IGameList.h"
#include "IServerRefreshResponse.h"
#include "server.h"
class KeyValues;
namespace vgui
{
class ListPanel;
class MessageBox;
};
class CUtlBuffer;
//-----------------------------------------------------------------------------
// Purpose: Favorite games list
//-----------------------------------------------------------------------------
class CFavoriteGames : public CBaseGamesPage
{
public:
CFavoriteGames(vgui::Panel *parent);
~CFavoriteGames();
// favorites list, loads/saves into keyvalues
void LoadFavoritesList(vgui::KeyValues *favoritesData,bool loadrcon);
void SaveFavoritesList(vgui::KeyValues *favoritesData,bool savercon);
// property page handlers
// virtual void OnPageShow();
// virtual void OnPageHide();
// IGameList handlers
// returns true if the game list supports the specified ui elements
virtual bool SupportsItem(InterfaceItem_e item);
// starts the servers refreshing
virtual void StartRefresh();
// gets a new server list
virtual void GetNewServerList();
// stops current refresh/GetNewServerList()
virtual void StopRefresh();
// returns true if the list is currently refreshing servers
virtual bool IsRefreshing();
// gets information about specified server
// virtual serveritem_t &GetServer(unsigned int serverID);
// adds a new server to list
virtual void AddNewServer(serveritem_t &server);
// marks that server list has been fully received
virtual void ListReceived(bool moreAvailable, int lastUnique);
// called when Connect button is pressed
virtual void OnBeginConnect();
// called to look at game info
virtual void OnViewGameInfo();
// reapplies filters (does nothing with this)
virtual void ApplyFilters();
// IServerRefreshResponse handlers
// called when the server has successfully responded
virtual void ServerResponded(serveritem_t &server);
// called when a server response has timed out
virtual void ServerFailedToRespond(serveritem_t &server);
// called when the current refresh list is complete
virtual void RefreshComplete();
virtual void ImportFavorites();
virtual void OnImportFavoritesFile();
// updates the rconPassword field for this server
void UpdateServer(serveritem_t &serverIn);
private:
// context menu message handlers
void OnOpenContextMenu(int row);
void OnRefreshServer(int serverID);
void OnRemoveFromFavorites();
void OnAddServerByName();
void OnCommand(const char *command);
bool LoadAFavoriteServer (CUtlBuffer &buf);
bool CheckForCorruption(char *data, const char *checkString);
int m_iServerRefreshCount; // number of servers refreshed
bool m_bSaveRcon;
DECLARE_PANELMAP();
typedef CBaseGamesPage BaseClass;
// message that favorites are being imported
vgui::MessageBox *m_pImportFavoritesdlg;
};
#endif // FAVORITEGAMES_H

View File

@ -0,0 +1,341 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include <stdio.h>
#include "winsock.h" // this BUGGER defines PropertySheet to PropertySheetA ....
#undef PropertySheet
#include "tokenline.h"
#include "GamePanelInfo.h"
//#include "Info.h"
#include "IRunGameEngine.h"
#include "DialogCvarChange.h"
#include "DialogAddBan.h"
#include "BudgetPanelContainer.h"
#include <vgui/ISystem.h>
#include <vgui/ISurface.h>
#include <vgui/IVGui.h>
#include <KeyValues.h>
#include <vgui/Cursor.h>
#include <vgui/ILocalize.h>
#include <vgui_controls/Label.h>
#include <vgui_controls/TextEntry.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/PHandle.h>
#include <vgui_controls/MessageBox.h>
#include <vgui_controls/QueryBox.h>
#include <vgui_controls/Image.h>
#include <vgui_controls/ImagePanel.h>
#include "tier0/icommandline.h"
#include <proto_oob.h>
#include <netadr.h>
using namespace vgui;
static const long RETRY_TIME = 10000; // refresh server every 10 seconds
static const long MAP_CHANGE_TIME = 20000; // refresh 20 seconds after a map change
static const long RESTART_TIME = 60000; // refresh 60 seconds after a "_restart"
#include "IManageServer.h"
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CGamePanelInfo::CGamePanelInfo(vgui::Panel *parent, const char *name, const char *mod) : Frame(parent, name)
{
SetSize(560, 420);
SetMinimumSize(560, 420);
m_bRemoteServer = false;
m_bShuttingDown = false;
// Create an Animating Image Panel
m_pAnimImagePanel = new AnimatingImagePanel(this, "AnAnimatingImagePanel");
// Each image file is named ss1, ss2, ss3... ss20, one image for each frame of the animation.
// This loads the 20 images in to the Animation class.
m_pAnimImagePanel->LoadAnimation("resource\\steam\\g", 12);
//!! animation temporarily disabled until UI pass done
//m_pAnimImagePanel->StartAnimation();
m_pAnimImagePanel->SetVisible(false);
// the main container for the various sub panels
m_pDetailsSheet = new PropertySheet(this, "Panels");
// the sub panels
m_pPlayerListPanel = new CPlayerPanel(this, "Player List");
m_pBanListPanel = new CBanPanel(this, "Ban List");
m_pServerLogPanel = new CRawLogPanel(this, "ServerLog");
// chat panel disabled until we get the parsing done
// m_pServerChatPanel = new CChatPanel(this, "ChatPanel");
m_pServerConfigPanel = new CServerConfigPanel(this, "ServerConfigPanel", mod);
m_pGraphsPanel = new CGraphPanel(this,"GraphsPanel");
m_pServerInfoPanel = new CServerInfoPanel(this, "ServerInfo");
if ( CommandLine()->CheckParm( "-BudgetPanel" ) )
m_pBudgetPanel = new CBudgetPanelContainer( this, "BudgetPanel" );
else
m_pBudgetPanel = NULL;
m_pServerInfoPanel->AddActionSignalTarget(this);
m_pDetailsSheet->AddPage(m_pServerInfoPanel,"#Game_Main_Settings");
m_pDetailsSheet->AddPage(m_pServerConfigPanel,"#Game_Configure");
m_pDetailsSheet->AddPage(m_pGraphsPanel,"#Game_Server_Statistics");
m_pDetailsSheet->AddPage(m_pPlayerListPanel,"#Game_Current_Players");
m_pDetailsSheet->AddPage(m_pBanListPanel,"#Game_Bans");
if ( m_pBudgetPanel )
m_pDetailsSheet->AddPage(m_pBudgetPanel,"#Game_Budgets");
// chat panel disabled until we get the parsing done
// m_pDetailsSheet->AddPage(m_pServerChatPanel,"#Game_Chat");
m_pDetailsSheet->AddPage(m_pServerLogPanel,"#Game_Console");
// let us be ticked every frame
ivgui()->AddTickSignal(this->GetVPanel());
LoadControlSettingsAndUserConfig("Admin\\DialogGamePanelInfo.res");
SetNewTitle(false, name);
SetVisible(true);
MoveToCenterOfScreen();
RequestFocus();
MoveToFront();
//!! hack, force the server info panel to refresh fast
// because the info it receives while loading the server is wrong
PostMessage(m_pServerInfoPanel, new KeyValues("ResetData"), 0.1f);
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CGamePanelInfo::~CGamePanelInfo()
{
}
//-----------------------------------------------------------------------------
// Purpose: Sets the title of the dialog
//-----------------------------------------------------------------------------
void CGamePanelInfo::SetNewTitle(bool connectionFailed, const char *additional_text)
{
const char *localized_title = "#Game_RemoteTitle";
if (!m_bRemoteServer)
{
localized_title = "Game_LocalTitle";
}
else if (connectionFailed)
{
localized_title = "#Game_RemoteTitle_Failed";
}
wchar_t serverName[256];
g_pVGuiLocalize->ConvertANSIToUnicode(additional_text, serverName, sizeof(serverName));
wchar_t title[256];
g_pVGuiLocalize->ConstructString(title, sizeof(title), g_pVGuiLocalize->Find(localized_title), 1, serverName);
SetTitle(title, true);
}
//-----------------------------------------------------------------------------
// Purpose: Updates the title
//-----------------------------------------------------------------------------
void CGamePanelInfo::OnUpdateTitle()
{
SetNewTitle(false, m_pServerInfoPanel->GetHostname());
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: data accessor
//-----------------------------------------------------------------------------
void CGamePanelInfo::SetAsRemoteServer(bool remote)
{
m_bRemoteServer = remote;
}
//-----------------------------------------------------------------------------
// Purpose: Relayouts the data
//-----------------------------------------------------------------------------
void CGamePanelInfo::PerformLayout()
{
BaseClass::PerformLayout();
}
//-----------------------------------------------------------------------------
// Purpose: Called every frame, handles resending network messages
//-----------------------------------------------------------------------------
void CGamePanelInfo::OnTick()
{
// service the server I/O queue
RemoteServer().ProcessServerResponse();
}
//-----------------------------------------------------------------------------
// Purpose: handles button responses
//-----------------------------------------------------------------------------
void CGamePanelInfo::OnCommand(const char *command)
{
if (!stricmp(command, "stop2"))
{
RemoteServer().SendCommand("quit");
m_bShuttingDown = true;
Close();
}
else
{
BaseClass::OnCommand(command);
}
}
//-----------------------------------------------------------------------------
// Purpose: produces a dialog asking a player to enter a new ban
//-----------------------------------------------------------------------------
void CGamePanelInfo::OnStop()
{
QueryBox *box = new QueryBox("#Game_Stop_Server_Title", "#Game_Restart_Server");
box->AddActionSignalTarget(this);
box->SetOKButtonText("#Game_Stop_Server");
box->SetOKCommand(new KeyValues("Command", "command", "stop2"));
box->ShowWindow();
}
//-----------------------------------------------------------------------------
// Purpose: displays the help page
//-----------------------------------------------------------------------------
void CGamePanelInfo::OnHelp()
{
system()->ShellExecute("open", "Admin\\Admin.html");
}
//-----------------------------------------------------------------------------
// Purpose: Does any processing needed before closing the dialog
//-----------------------------------------------------------------------------
void CGamePanelInfo::OnClose()
{
if (m_bRemoteServer || m_bShuttingDown)
{
BaseClass::OnClose();
return;
}
// closing the window will kill the local server, notify user
OnStop();
}
//-----------------------------------------------------------------------------
// Purpose: allow the build mode editor to edit the current sub panel
//-----------------------------------------------------------------------------
void CGamePanelInfo::ActivateBuildMode()
{
// BaseClass::ActivateBuildMode();
// return;
// no subpanel, no build mode
EditablePanel *pg = dynamic_cast<EditablePanel *>(m_pDetailsSheet->GetActivePage());
if (pg)
{
pg->ActivateBuildMode();
}
}
//-----------------------------------------------------------------------------
// Purpose: Writes text to the console
//-----------------------------------------------------------------------------
void CGamePanelInfo::AddToConsole(const char *msg)
{
if (m_pServerLogPanel)
{
// hack, look for restart message
if (*msg == 3 && !strncmp(msg + 1, "MasterRequestRestart", strlen("MasterRequestRestart")))
{
OnMasterRequestRestart();
}
else if (*msg == 3 && !strncmp(msg + 1, "MasterOutOfDate", strlen("MasterOutOfDate")))
{
const char *details = strstr( msg, "MasterOutOfDate" );
if ( details )
{
OnMasterOutOfDate(details + strlen("MasterOutOfDate"));
}
}
else
{
// nothing special, just print
m_pServerLogPanel->DoInsertString(msg);
}
}
}
void CGamePanelInfo::OnMasterOutOfDate( const char *msg)
{
#if !defined(_DEBUG)
// open a dialog informing user that they need to restart the server
if (!m_hOutOfDateQueryBox.Get())
{
char *fullmsg = (char *) _alloca( strlen(msg) + strlen( "\n\nDo you wish to shutdown now?\n") + 1 );
_snprintf( fullmsg, strlen(msg) + strlen( "\n\nDo you wish to shutdown now?\n") + 1 , "%s\n\nDo you wish to shutdown now?\n", msg );
m_hOutOfDateQueryBox = new QueryBox("Server restart pending", fullmsg);
m_hOutOfDateQueryBox->AddActionSignalTarget(this);
m_hOutOfDateQueryBox->SetOKCommand(new KeyValues("RestartServer"));
m_hOutOfDateQueryBox->ShowWindow();
}
else
{
// reshow the existing window
m_hOutOfDateQueryBox->Activate();
}
#endif // !defined(_DEBUG)
}
//-----------------------------------------------------------------------------
// Purpose: Called when master server has requested the dedicated server restart
//-----------------------------------------------------------------------------
void CGamePanelInfo::OnMasterRequestRestart()
{
#if !defined(_DEBUG)
// open a dialog informing user that they need to restart the server
if (!m_hRestartQueryBox.Get())
{
m_hRestartQueryBox = new QueryBox("Server restart needed", "Your server is out of date, and will not be listed\non the master server until you restart.\n\nDo you wish to shutdown now?\n");
m_hRestartQueryBox->AddActionSignalTarget(this);
m_hRestartQueryBox->SetOKCommand(new KeyValues("RestartServer"));
m_hRestartQueryBox->ShowWindow();
}
else
{
// reshow the existing window
m_hRestartQueryBox->Activate();
}
#endif // !defined(_DEBUG)
}
//-----------------------------------------------------------------------------
// Purpose: Restarts the server
//-----------------------------------------------------------------------------
void CGamePanelInfo::OnRestartServer()
{
//!! mark us as needing restart
//!! this doesn't work yet, just shut us down
// shut us down
RemoteServer().SendCommand("quit");
m_bShuttingDown = true;
Close();
}

View File

@ -0,0 +1,105 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef GAMEPANELINFO_H
#define GAMEPANELINFO_H
#ifdef _WIN32
#pragma once
#endif
//#include <string.h>
#include <KeyValues.h>
#include <vgui_controls/Frame.h>
#include <vgui_controls/PHandle.h>
#include <vgui_controls/ListPanel.h>
#include <vgui_controls/AnimatingImagePanel.h>
#include <vgui_controls/Image.h>
#include <vgui_controls/PropertyPage.h>
#undef PropertySheet
#include <vgui_controls/PropertySheet.h>
#include "BanContextMenu.h"
#include "chatpanel.h"
#include "rawlogpanel.h"
#include "serverconfigpanel.h"
#include "playerpanel.h"
#include "banpanel.h"
#include "graphpanel.h"
#include "serverinfopanel.h"
#define PASSWORD_LEN 64
#define MOD_LEN 64
#include "imanageserver.h" // IManageServer interface
class CBudgetPanelContainer;
//-----------------------------------------------------------------------------
// Purpose: Dialog for displaying information about a game server
//-----------------------------------------------------------------------------
class CGamePanelInfo : public vgui::Frame, public IManageServer
{
DECLARE_CLASS_SIMPLE( CGamePanelInfo, vgui::Frame );
public:
CGamePanelInfo(vgui::Panel *parent, const char *name, const char *mod);
~CGamePanelInfo();
// IManageServer interface extras
void ShowPage() { Activate(); }
void AddToConsole(const char *msg);
void SetAsRemoteServer(bool remote);
protected:
// message handlers
void OnStop();
MESSAGE_FUNC( OnHelp, "Help" );
void OnMasterRequestRestart();
void OnMasterOutOfDate( const char *msg);
MESSAGE_FUNC( OnRestartServer, "RestartServer" );
MESSAGE_FUNC( OnUpdateTitle, "UpdateTitle" );
void SetNewTitle(bool connectionFailed, const char *additional_text); // sets the windows title
// vgui overrides
virtual void OnTick();
virtual void OnClose();
virtual void PerformLayout();
virtual void ActivateBuildMode();
virtual void OnCommand(const char *command);
private:
// methods
vgui::ComboBox *m_pViewCombo;
vgui::AnimatingImagePanel *m_pAnimImagePanel;
// GUI pabels
// main property sheet
vgui::PropertySheet *m_pDetailsSheet;
// panels in the sheet
CPlayerPanel *m_pPlayerListPanel;
CBanPanel *m_pBanListPanel;
CRawLogPanel *m_pServerLogPanel;
CChatPanel *m_pServerChatPanel;
CServerConfigPanel *m_pServerConfigPanel;
CGraphPanel *m_pGraphsPanel;
CServerInfoPanel *m_pServerInfoPanel;
CBudgetPanelContainer *m_pBudgetPanel;
// state
bool m_bRemoteServer;
bool m_bShuttingDown;
vgui::DHANDLE<vgui::QueryBox> m_hRestartQueryBox;
vgui::DHANDLE<vgui::QueryBox> m_hOutOfDateQueryBox;
};
#endif // GAMEPANELINFO_H

View File

@ -0,0 +1,731 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include <stdio.h>
#include "GraphPanel.h"
#include <vgui/ISystem.h>
#include <vgui/ISurface.h>
#include <vgui/IVGui.h>
#include <vgui/IScheme.h>
#include <vgui/ILocalize.h>
#include <KeyValues.h>
#include <vgui_controls/Label.h>
#include <vgui_controls/TextEntry.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/ToggleButton.h>
#include <vgui_controls/RadioButton.h>
#include <vgui_controls/ListPanel.h>
#include <vgui_controls/ComboBox.h>
#include <vgui_controls/PHandle.h>
#include <vgui_controls/PropertySheet.h>
#include <vgui_controls/CheckButton.h>
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define STATS_UPDATE_RATE 5.0f
// colors for the various graph lines+controls
Color CGraphPanel::CGraphsImage::CPUColor= Color(0,255,0,255); // green
Color CGraphPanel::CGraphsImage::FPSColor= Color(255,0,0,255); // red
Color CGraphPanel::CGraphsImage::NetInColor = Color(255,255,0,255); // yellow
Color CGraphPanel::CGraphsImage::NetOutColor = Color(0,255,255,255); // light blue
Color CGraphPanel::CGraphsImage::PlayersColor = Color(255,0,255,255); // purple
Color CGraphPanel::CGraphsImage::PingColor = Color(0,0,0,255); // black
//Color CGraphPanel::CGraphsImage::lineColor = Color(76,88,68,255);
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CGraphPanel::CGraphPanel(vgui::Panel *parent, const char *name) : PropertyPage(parent, name)
{
SetMinimumSize(300,200);
m_pGraphsPanel = new ImagePanel(this,"Graphs");
m_pGraphs = new CGraphsImage();
m_pGraphsPanel->SetImage(m_pGraphs);
m_pInButton = new CheckButton(this,"InCheck","#Graph_In");
m_pOutButton = new CheckButton(this,"OutCheck","#Graph_Out");
m_pFPSButton = new CheckButton(this,"FPSCheck","#Graph_FPS");
m_pCPUButton = new CheckButton(this,"CPUCheck","#Graph_CPU");
m_pPINGButton = new CheckButton(this,"PingCheck","#Graph_Ping");
m_pPlayerButton = new CheckButton(this,"PlayersCheck","#Graph_Players");
m_pTimeCombo = new ComboBox(this, "TimeCombo",3,false);
m_pTimeCombo->AddItem("#Graph_Minutes", NULL);
int defaultItem = m_pTimeCombo->AddItem("#Graph_Hours", NULL);
m_pTimeCombo->AddItem("#Graph_Day", NULL);
m_pTimeCombo->ActivateItem(defaultItem);
m_pVertCombo = new ComboBox(this, "VertCombo",6,false);
m_pVertCombo->AddItem("#Graph_In", NULL);
m_pVertCombo->AddItem("#Graph_Out", NULL);
m_pVertCombo->AddItem("#Graph_FPS", NULL);
defaultItem = m_pVertCombo->AddItem("#Graph_CPU", NULL);
m_pVertCombo->AddItem("#Graph_Ping", NULL);
m_pVertCombo->AddItem("#Graph_Players", NULL);
m_pVertCombo->ActivateItem(defaultItem);
// now setup defaults
m_pCPUButton->SetSelected(true);
m_pInButton->SetSelected(false);
m_pOutButton->SetSelected(false);
m_pFPSButton->SetSelected(false);
m_pPINGButton->SetSelected(false);
LoadControlSettings("Admin/GraphPanel.res", "PLATFORM");
int w,h;
m_pGraphsPanel->GetSize(w,h);
m_pGraphs->SaveSize(w,h);
m_pGraphs->SetDraw(m_pCPUButton->IsSelected(),m_pFPSButton->IsSelected(),
m_pInButton->IsSelected(),m_pOutButton->IsSelected(),m_pPINGButton->IsSelected(),m_pPlayerButton->IsSelected());
m_pPINGButton->SetFgColor(m_pGraphs->GetPingColor());
m_pCPUButton->SetFgColor(m_pGraphs->GetCPUColor());
m_pFPSButton->SetFgColor(m_pGraphs->GetFPSColor());
m_pInButton->SetFgColor(m_pGraphs->GetInColor());
m_pOutButton->SetFgColor(m_pGraphs->GetOutColor());
m_pPlayerButton->SetFgColor(m_pGraphs->GetPlayersColor());
ivgui()->AddTickSignal(GetVPanel());
m_flNextStatsUpdateTime = 0;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CGraphPanel::~CGraphPanel()
{
}
void CGraphPanel::ApplySchemeSettings( IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
m_pGraphsPanel->SetBorder( pScheme->GetBorder("ButtonDepressedBorder"));
m_pGraphs->SetBgColor(GetSchemeColor("WindowBG", pScheme));
m_pGraphs->SetAxisColor(Color(76,88,68,255));
}
//-----------------------------------------------------------------------------
// Purpose: Activates the page
//-----------------------------------------------------------------------------
void CGraphPanel::OnPageShow()
{
BaseClass::OnPageShow();
}
//-----------------------------------------------------------------------------
// Purpose: Hides the page
//-----------------------------------------------------------------------------
void CGraphPanel::OnPageHide()
{
BaseClass::OnPageHide();
}
//-----------------------------------------------------------------------------
// Purpose: called every frame to update stats page
//-----------------------------------------------------------------------------
void CGraphPanel::OnTick()
{
if (m_flNextStatsUpdateTime > system()->GetFrameTime())
return;
m_flNextStatsUpdateTime = (float)system()->GetFrameTime() + STATS_UPDATE_RATE;
RemoteServer().RequestValue(this, "stats");
}
//-----------------------------------------------------------------------------
// Purpose: tells the image about the new size
//-----------------------------------------------------------------------------
void CGraphPanel::PerformLayout()
{
BaseClass::PerformLayout();
int w,h,x,y;
m_pGraphsPanel->GetBounds(x,y,w,h);
m_pGraphs->SaveSize(w,h); // tell the image about the resize
// push the mid axis label to the middle of the image
Label *entry = dynamic_cast<Label *>(FindChildByName("AxisMid"));
if (entry)
{
int entry_x,entry_y;
entry->GetPos(entry_x,entry_y);
entry->SetPos(entry_x,y+(h/2)-8);
}
}
//-----------------------------------------------------------------------------
// Purpose: Handles stats command returns
//-----------------------------------------------------------------------------
void CGraphPanel::OnServerDataResponse(const char *value, const char *response)
{
if (!stricmp(value, "stats"))
{
// parse the stats out of the response
Points_t p;
float uptime, users;
sscanf(response, "%f %f %f %f %f %f %f", &p.cpu, &p.in, &p.out, &uptime, &users, &p.fps, &p.players);
p.cpu = p.cpu / 100; // its given as a value between 0<x<100, we want 0<x<1
p.ping = 0;
p.time = (float)system()->GetCurrentTime();
m_pGraphs->AddPoint(p);
// days:hours:minutes:seconds
char timeText[64];
_snprintf(timeText, sizeof(timeText), "%i", (int)p.players);
SetControlString("TotalUsersLabel", timeText);
// mark the vert combo has changed to force it to update graph ranges
m_pVertCombo->GetText(timeText, 64);
OnTextChanged(m_pVertCombo, timeText);
}
}
//-----------------------------------------------------------------------------
// Purpose: the paint routine for the graph image. Handles the layout and drawing of the graph image
//-----------------------------------------------------------------------------
void CGraphPanel::CGraphsImage::Paint()
{
int x,y;
float distPoints; // needs to be a float, rounding errors cause problems with lots of points
int bottom=5; // be 5 pixels above the bottom
int left=2;
int *pCpuX=NULL, *pCpuY=NULL;
int *pInX=NULL, *pInY=NULL;
int *pOutX=NULL, *pOutY=NULL;
int *pFPSX=NULL, *pFPSY=NULL;
int *pPingX=NULL, *pPingY=NULL;
int *pPlayersX=NULL, *pPlayersY=NULL;
GetSize(x,y);
SetColor(bgColor);
SetBkColor(bgColor);
DrawFilledRect(0,0,x,y);
y-=4; // borders
x-=4;
if(!cpu && !fps && !net_i && !net_o && !ping && !players) // no graphs selected
return;
if(points.Count()<2)
return; // not enough points yet...
if(x<=200 || y<=100)
return; // to small
distPoints= static_cast<float>(x)/static_cast<float>(points.Count()-1);
if(distPoints<=0)
{
distPoints=1;
}
SetColor(lineColor);
SetBkColor(lineColor);
//DrawLine(4,5,x,5);
DrawLine(4,y/2,x,y/2);
//DrawLine(4,y,x,y);
float RangePing=maxPing;
float RangeFPS=maxFPS;
float Range=0;
float RangePlayers=maxPlayers;
if(ping)
{
RangePing+=static_cast<float>(maxPing*0.1); // don't let the top of the range touch the top of the panel
if(RangePing<=1)
{ // don't let the zero be at the top of the screen
RangePing=1.0;
}
pPingX = new int[points.Count()];
pPingY = new int[points.Count()];
}
if(cpu)
{
pCpuX = new int[points.Count()];
pCpuY = new int[points.Count()];
}
if(fps)
{
RangeFPS+=static_cast<float>(maxFPS*0.1); // don't let the top of the range touch the top of the panel
if(RangeFPS<=1)
{ // don't let the zero be at the top of the screen
RangeFPS=1.0;
}
pFPSX = new int[points.Count()];
pFPSY = new int[points.Count()];
}
if(net_i)
{
// put them on a common scale, base it at zero
Range = max(maxIn,maxOut);
Range+=static_cast<float>(Range*0.1); // don't let the top of the range touch the top of the panel
if(Range<=1)
{ // don't let the zero be at the top of the screen
Range=1.0;
}
pInX = new int[points.Count()];
pInY = new int[points.Count()];
}
if(net_o)
{
// put them on a common scale, base it at zero
Range = max(maxIn,maxOut);
Range+=static_cast<float>(Range*0.1); // don't let the top of the range touch the top of the panel
if(Range<=1)
{ // don't let the zero be at the top of the screen
Range=1.0;
}
pOutX = new int[points.Count()];
pOutY = new int[points.Count()];
}
if(players)
{
RangePlayers+=static_cast<float>(maxPlayers*0.1); // don't let the top of the range touch the top of the panel
pPlayersX = new int[points.Count()];
pPlayersY = new int[points.Count()];
}
for(int i=0;i<points.Count();i++)
// draw the graphs, left to right
{
if(cpu)
{
pCpuX[i] = left+static_cast<int>(i*distPoints);
pCpuY[i] = static_cast<int>((1-points[i].cpu)*y);
}
if(net_i)
{
pInX[i] = left+static_cast<int>(i*distPoints);
pInY[i] = static_cast<int>(( (Range-points[i].in)/Range)*y-bottom);
}
if(net_o)
{
pOutX[i] = left+static_cast<int>(i*distPoints);
pOutY[i] = static_cast<int>(((Range-points[i].out)/Range)*y-bottom);
}
if(fps)
{
pFPSX[i] = left+static_cast<int>(i*distPoints);
pFPSY[i] = static_cast<int>(( (RangeFPS-points[i].fps)/RangeFPS)*y-bottom);
}
if(ping)
{
pPingX[i] = left+static_cast<int>(i*distPoints);
pPingY[i] = static_cast<int>(( (RangePing-points[i].ping)/RangePing)*y-bottom);
}
if(players)
{
pPlayersX[i] = left+static_cast<int>(i*distPoints);
pPlayersY[i] = static_cast<int>(( (RangePlayers-points[i].players)/RangePlayers)*y-bottom);
}
}
// we use DrawPolyLine, its much, much, much more efficient than calling lots of DrawLine()'s
if(cpu)
{
SetColor(CPUColor); // green
DrawPolyLine(pCpuX, pCpuY, points.Count());
delete [] pCpuX;
delete [] pCpuY;
}
if(net_i)
{
SetColor(NetInColor); // red
DrawPolyLine(pInX, pInY, points.Count());
delete [] pInX;
delete [] pInY;
}
if(net_o)
{
SetColor(NetOutColor); //yellow
DrawPolyLine(pOutX, pOutY, points.Count());
delete [] pOutX;
delete [] pOutY;
}
if(fps)
{
SetColor(FPSColor);
DrawPolyLine(pFPSX, pFPSY, points.Count());
delete [] pFPSX;
delete [] pFPSY;
}
if(ping)
{
SetColor(PingColor);
DrawPolyLine(pPingX, pPingY, points.Count());
delete [] pPingX;
delete [] pPingY;
}
if(players)
{
SetColor(PlayersColor);
DrawPolyLine(pPlayersX, pPlayersY, points.Count());
delete [] pPlayersX;
delete [] pPlayersY;
}
}
//-----------------------------------------------------------------------------
// Purpose: constructor for the graphs image
//-----------------------------------------------------------------------------
CGraphPanel::CGraphsImage::CGraphsImage(): vgui::Image(), points()
{
maxIn=maxOut=minIn=minOut=minFPS=maxFPS=minPing=maxPing=0;
net_i=net_o=fps=cpu=ping=players=false;
numAvgs=0;
memset(&avgPoint,0x0,sizeof(Points_t));
}
//-----------------------------------------------------------------------------
// Purpose: sets which graph to draw, true means draw it
//-----------------------------------------------------------------------------
void CGraphPanel::CGraphsImage::SetDraw(bool cpu_in,bool fps_in,bool net_in,bool net_out,bool ping_in,bool players_in)
{
cpu=cpu_in;
fps=fps_in;
net_i=net_in;
net_o=net_out;
ping=ping_in;
players=players_in;
}
//-----------------------------------------------------------------------------
// Purpose: used to average points over a period of time
//-----------------------------------------------------------------------------
void CGraphPanel::CGraphsImage::AvgPoint(Points_t p)
{
avgPoint.cpu += p.cpu;
avgPoint.fps += p.fps;
avgPoint.in += p.in;
avgPoint.out += p.out;
avgPoint.ping += p.ping;
avgPoint.players += p.players;
numAvgs++;
}
//-----------------------------------------------------------------------------
// Purpose: updates the current bounds of the points based on this new point
//-----------------------------------------------------------------------------
void CGraphPanel::CGraphsImage::CheckBounds(Points_t p)
{
if(p.in>maxIn)
{
maxIn=avgPoint.in;
}
if(p.out>maxOut)
{
maxOut=avgPoint.out;
}
if(p.in<minIn)
{
minIn=avgPoint.in;
}
if(p.out<minOut)
{
minOut=avgPoint.out;
}
if(p.fps>maxFPS)
{
maxFPS=avgPoint.fps;
}
if(p.fps<minFPS)
{
minFPS=avgPoint.fps;
}
if(p.ping>maxPing)
{
maxPing=avgPoint.ping;
}
if(p.ping<minPing)
{
minPing=avgPoint.ping;
}
if(p.players>maxPlayers)
{
maxPlayers=avgPoint.players;
}
if(p.players<minPlayers)
{
minPlayers=avgPoint.players;
}
}
//-----------------------------------------------------------------------------
// Purpose: adds a point to the graph image.
//-----------------------------------------------------------------------------
bool CGraphPanel::CGraphsImage::AddPoint(Points_t p)
{
int x,y;
bool recalcBounds=false;
GetSize(x,y);
if(avgPoint.cpu>1) // cpu is a percent !
{
return false;
}
if(timeBetween==SECONDS) // most recent minute
{
while(points.Count() && (p.time-points[0].time)>60)
{
points.Remove(0);
}
}
else if(timeBetween==HOURS) // most recent hour
{
while(points.Count() && (p.time-points[0].time)>60*60)
{
points.Remove(0);
}
}
else if ( timeBetween==MINUTES) // most recent day
{
while(points.Count() && (p.time-points[0].time)>60*60*24)
{
points.Remove(0);
}
}
AvgPoint(p);
// now work out the average of all the values
avgPoint.cpu /= numAvgs;
avgPoint.fps /= numAvgs;
avgPoint.in /= numAvgs;
avgPoint.out /= numAvgs;
avgPoint.ping /= numAvgs;
avgPoint.players /= numAvgs;
avgPoint.time = p.time;
numAvgs=0;
int k=0;
if(x!=0 && points.Count()> x/2)
// there are more points than pixels so thin them out
{
while(points.Count()> x/2)
{
// check that the bounds don't move
if(points[0].in==maxIn ||
points[0].out==maxOut ||
points[0].fps==maxFPS ||
points[0].ping==maxPing ||
points[0].players==maxPlayers)
{
recalcBounds=true;
}
points.Remove(k); // remove the head node
k+=2;
if(k>points.Count())
{
k=0;
}
}
}
if(recalcBounds)
{
for(int i=0;i<points.Count();i++)
{
CheckBounds(points[i]);
}
}
CheckBounds(avgPoint);
points.AddToTail(avgPoint);
memset(&avgPoint,0x0,sizeof(Points_t));
return true;
}
void CGraphPanel::CGraphsImage::SetScale(intervals time)
{
timeBetween=time;
// scale is reset so remove all the points
points.RemoveAll();
// and reset the maxes
maxIn=maxOut=minIn=minOut=minFPS=maxFPS=minPing=maxPing=maxPlayers=minPlayers=0;
}
//-----------------------------------------------------------------------------
// Purpose: clear button handler, clears the current points
//-----------------------------------------------------------------------------
void CGraphPanel::OnClearButton()
{
m_pGraphs->RemovePoints();
}
//-----------------------------------------------------------------------------
// Purpose: passes the state of the check buttons (for graph line display) through to the graph image
//-----------------------------------------------------------------------------
void CGraphPanel::OnCheckButton()
{
m_pGraphs->SetDraw(m_pCPUButton->IsSelected(), m_pFPSButton->IsSelected(), m_pInButton->IsSelected(), m_pOutButton->IsSelected(), m_pPINGButton->IsSelected(), m_pPlayerButton->IsSelected());
}
//-----------------------------------------------------------------------------
// Purpose:Handles the scale radio buttons, passes the scale to use through to the graph image
//-----------------------------------------------------------------------------
void CGraphPanel::OnTextChanged(Panel *panel, const char *text)
{
if (panel == m_pTimeCombo)
{
if (strstr(text, "Hour"))
{
m_pGraphs->SetScale(MINUTES);
}
else if (strstr(text, "Day"))
{
m_pGraphs->SetScale(HOURS);
}
else
{
m_pGraphs->SetScale(SECONDS);
}
}
else if (panel == m_pVertCombo)
{
float maxVal, minVal;
char minText[20], midText[20], maxText[20];
if (strstr(text, "CPU"))
{
SetAxisLabels(m_pGraphs->GetCPUColor(), "100%", "50%", "0%");
}
else if (strstr(text, "FPS"))
{
m_pGraphs->GetFPSLimits(maxVal, minVal);
sprintf(maxText,"%0.2f", maxVal);
sprintf(midText,"%0.2f", (maxVal - minVal) / 2);
sprintf(minText,"%0.2f", minVal);
SetAxisLabels(m_pGraphs->GetFPSColor(), maxText, midText, minText);
}
else if (strstr(text, "In"))
{
m_pGraphs->GetInLimits(maxVal, minVal);
sprintf(maxText,"%0.2f", maxVal);
sprintf(midText,"%0.2f", (maxVal - minVal) / 2);
sprintf(minText,"%0.2f", minVal);
SetAxisLabels(m_pGraphs->GetInColor(), maxText, midText, minText);
}
else if (strstr(text, "Out"))
{
m_pGraphs->GetOutLimits(maxVal, minVal);
sprintf(maxText,"%0.2f", maxVal);
sprintf(midText,"%0.2f", (maxVal - minVal) / 2);
sprintf(minText,"%0.2f", minVal);
SetAxisLabels(m_pGraphs->GetOutColor(), maxText, midText, minText);
}
else if (strstr(text, "Ping"))
{
m_pGraphs->GetPingLimits(maxVal, minVal);
sprintf(maxText,"%0.2f", maxVal);
sprintf(midText,"%0.2f", (maxVal - minVal) / 2);
sprintf(minText,"%0.2f", minVal);
SetAxisLabels(m_pGraphs->GetPingColor(), maxText, midText, minText);
}
else if (strstr(text, "Players"))
{
m_pGraphs->GetPlayerLimits(maxVal, minVal);
sprintf(maxText,"%0.2f", maxVal);
sprintf(midText,"%0.2f", (maxVal - minVal) / 2);
sprintf(minText,"%0.2f", minVal);
SetAxisLabels(m_pGraphs->GetPlayersColor(), maxText, midText, minText);
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CGraphPanel::SetAxisLabels(Color c, char *max, char *mid, char *min)
{
Label *lab;
lab= GetLabel("AxisMax");
if(lab)
{
lab->SetFgColor(c);
lab->SetText(max);
}
lab = GetLabel("AxisMid");
if(lab)
{
lab->SetFgColor(c);
lab->SetText(mid);
}
lab = GetLabel("AxisMin");
if(lab)
{
lab->SetFgColor(c);
lab->SetText(min);
}
}
Label *CGraphPanel::GetLabel(const char *name)
{
Label *lab = dynamic_cast<Label *>(FindChildByName(name));
return lab;
}

View File

@ -0,0 +1,154 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef GRAPHPANEL_H
#define GRAPHPANEL_H
#ifdef _WIN32
#pragma once
#endif
#include <KeyValues.h>
#include <vgui_controls/Frame.h>
#include <vgui_controls/PHandle.h>
#include <vgui_controls/ListPanel.h>
#include <vgui_controls/PropertyPage.h>
#include <vgui_controls/Image.h>
#include <vgui_controls/ImagePanel.h>
#include <vgui/IScheme.h>
#include "RemoteServer.h"
//-----------------------------------------------------------------------------
// Purpose: Dialog for displaying information about a game server
//-----------------------------------------------------------------------------
class CGraphPanel : public vgui::PropertyPage, public IServerDataResponse
{
DECLARE_CLASS_SIMPLE( CGraphPanel, vgui::PropertyPage );
public:
CGraphPanel(vgui::Panel *parent, const char *name);
~CGraphPanel();
// property page handlers
virtual void OnPageShow();
virtual void OnPageHide();
void PerformLayout();
protected:
// callback for receiving server data
virtual void OnServerDataResponse(const char *value, const char *response);
// called every frame to update stats page
virtual void OnTick();
private:
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
typedef enum { SECONDS, MINUTES, HOURS } intervals;
struct Points_t
{
float cpu; // the percent CPU usage
float in; // the ingoing bandwidth in kB/sec
float out; // the outgoing bandwidth in kB/sec
float time; // the time this was recorded
float fps; // the FPS of the server
float ping; // the ping of the server
float players; // the number of players currently on the server
};
// internal class for holding the graph picture
class CGraphsImage: public vgui::Image
{
public:
CGraphsImage();
using Image::DrawLine;
using Image::SetPos;
bool AddPoint(Points_t p);
void RemovePoints() { points.RemoveAll(); }
void SaveSize(int x1,int y1) { x=x1;y=y1; SetSize(x1,y1);}
void SetDraw(bool cpu_in,bool fps_in,bool net_in,bool net_out,bool ping_in,bool players_in);
void SetScale(intervals time);
void SetBgColor(Color col) { bgColor=col; }
void SetAxisColor(Color col) { lineColor=col; }
// return the pre-defined colors of each graph type
Color GetCPUColor() { return CPUColor; }
Color GetFPSColor() { return FPSColor; }
Color GetInColor() { return NetInColor; }
Color GetOutColor() { return NetOutColor; }
Color GetPlayersColor() { return PlayersColor; }
Color GetPingColor() { return PingColor; }
// return the limits of various graphs
void GetFPSLimits(float &max, float &min) { min=minFPS; max=maxFPS; }
void GetInLimits(float &max, float &min) { min=minIn; max=maxIn; }
void GetOutLimits(float &max, float &min) { min=minOut; max=maxOut; }
void GetPingLimits(float &max, float &min) { min=minPing; max=maxPing; }
void GetPlayerLimits(float &max, float &min) { min=minPlayers; max=maxPlayers; }
virtual void Paint();
private:
void AvgPoint(Points_t p);
void CheckBounds(Points_t p);
CUtlVector<Points_t> points;
int x,y; // the size
float maxIn,minIn,maxOut,minOut; // max and min bandwidths
float maxFPS,minFPS;
float minPing,maxPing;
float maxPlayers,minPlayers;
bool cpu,fps,net_i,ping,net_o,players;
intervals timeBetween;
Points_t avgPoint;
int numAvgs;
Color bgColor,lineColor;
// colors for the various graphs, set in graphpanel.cpp
static Color CPUColor;
static Color FPSColor;
static Color NetInColor;
static Color NetOutColor;
static Color PlayersColor;
static Color PingColor;
};
friend CGraphsImage; // so it can use the intervals enum
vgui::Label *GetLabel(const char *name);
void SetAxisLabels(Color c,char *max,char *mid,char *min);
// msg handlers
MESSAGE_FUNC( OnCheckButton, "CheckButtonChecked" );
MESSAGE_FUNC_PTR_CHARPTR( OnTextChanged, "TextChanged", panel, text );
MESSAGE_FUNC( OnClearButton, "clear" );
// GUI elements
CGraphsImage *m_pGraphs;
vgui::ImagePanel *m_pGraphsPanel;
vgui::Button *m_pClearButton;
vgui::CheckButton *m_pInButton;
vgui::CheckButton *m_pOutButton;
vgui::CheckButton *m_pFPSButton;
vgui::CheckButton *m_pCPUButton;
vgui::CheckButton *m_pPINGButton;
vgui::CheckButton *m_pPlayerButton;
vgui::ComboBox *m_pTimeCombo;
vgui::ComboBox *m_pVertCombo;
float m_flNextStatsUpdateTime;
};
#endif // GRAPHPANEL_H

View File

@ -0,0 +1,84 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include <stdio.h>
#include <VGUI_Controls.h>
#include "filesystem.h"
#include "HelpText.h"
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CHelpText::CHelpText(const char *mod)
{
char configName[200];
_snprintf(configName,200,"Admin\\HelpFile_%s.vdf",mod);
m_pHelpData = new KeyValues ("Help");
// always load the basic definiton
LoadHelpFile("Admin\\HelpFile.vdf");
// now load mod specific stuff
if( g_pFullFileSystem->FileExists(configName) )
{
LoadHelpFile(configName);
}
// and load an admin mod page if you can find it
if( g_pFullFileSystem->FileExists("Admin\\HelpFile_adminmod.vdf") )
{
LoadHelpFile("Admin\\HelpFile_adminmod.vdf");
}
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CHelpText::~CHelpText()
{
m_pHelpData->deleteThis();
}
void CHelpText::LoadHelpFile(const char *filename)
{
if (!m_pHelpData->LoadFromFile(g_pFullFileSystem, filename, true, "PLATFORM"))
{
// failed to load...
}
else
{
}
}
const char *CHelpText::GetHelp(const char *keyname)
{
KeyValues *help = m_pHelpData->FindKey(keyname, true);
if(help)
{
return help->GetString("text");
}
else
{
return NULL;
}
}

View File

@ -0,0 +1,35 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef HELPTEXT_H
#define HELPTEXT_H
#ifdef _WIN32
#pragma once
#endif
#include <VGUI_KeyValues.h>
//-----------------------------------------------------------------------------
// Purpose: parses in a text file and returns help strings about key words
//-----------------------------------------------------------------------------
class CHelpText
{
public:
CHelpText(const char *mod);
~CHelpText();
void LoadHelpFile(const char *filename);
const char *GetHelp(const char *keyname);
private:
vgui::KeyValues *m_pHelpData;
};
#endif // HELPTEXT_H

View File

@ -0,0 +1,35 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef IMANAGESERVER_H
#define IMANAGESERVER_H
#ifdef _WIN32
#pragma once
#endif
#include <interface.h>
//-----------------------------------------------------------------------------
// Purpose: basic callback interface for the manage server list, to update status text et al
//-----------------------------------------------------------------------------
class IManageServer : public IBaseInterface
{
public:
// activates the manage page
virtual void ShowPage() = 0;
// sets whether or not the server is remote
virtual void SetAsRemoteServer(bool remote) = 0;
// prints text to the console
virtual void AddToConsole(const char *msg) = 0;
};
#define IMANAGESERVER_INTERFACE_VERSION "IManageServer002"
#endif // IMANAGESERVER_H

View File

@ -0,0 +1,30 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef IRESPONSE_H
#define IRESPONSE_H
#ifdef _WIN32
#pragma once
#endif
//-----------------------------------------------------------------------------
// Purpose: Callback interface for server updates
//-----------------------------------------------------------------------------
class IResponse
{
public:
// called when the server has successfully responded
virtual void ServerResponded() = 0;
// called when a server response has timed out
virtual void ServerFailedToRespond() = 0;
};
#endif // IRESPONSE_H

View File

@ -0,0 +1,171 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include <stdio.h>
#include "MOTDPanel.h"
#include <VGUI_Controls.h>
#include <VGUI_ISystem.h>
#include <VGUI_ISurface.h>
#include <VGUI_IVGui.h>
#include <VGUI_KeyValues.h>
#include <VGUI_Label.h>
#include <VGUI_TextEntry.h>
#include <VGUI_Button.h>
#include <VGUI_ToggleButton.h>
#include <VGUI_RadioButton.h>
#include <VGUI_ListPanel.h>
#include <VGUI_ComboBox.h>
#include <VGUI_PHandle.h>
#include <VGUI_PropertySheet.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CMOTDPanel::CMOTDPanel(vgui::Panel *parent, const char *name) : PropertyPage(parent, name)
{
m_pRcon=NULL;
m_pMOTDPanel = new TextEntry(this, "ServerMOTDText");
m_pMOTDPanel->SetMultiline(true);
m_pMOTDPanel->SetEnabled(true);
m_pMOTDPanel->SetEditable(true);
m_pMOTDPanel->SetVerticalScrollbar(true);
m_pMOTDPanel->SetRichEdit(false);
m_pMOTDPanel->SetCatchEnterKey(true);
m_pMOTDPanel->setMaximumCharCount(1024);
m_pSendMOTDButton = new Button(this, "SendMOTD", "&Send");
m_pSendMOTDButton->SetCommand(new KeyValues("SendMOTD"));
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CMOTDPanel::~CMOTDPanel()
{
}
//-----------------------------------------------------------------------------
// Purpose: Activates the page
//-----------------------------------------------------------------------------
void CMOTDPanel::OnPageShow()
{
m_pMOTDPanel->RequestFocus();
}
//-----------------------------------------------------------------------------
// Purpose: Hides the page
//-----------------------------------------------------------------------------
void CMOTDPanel::OnPageHide()
{
}
//-----------------------------------------------------------------------------
// Purpose: Relayouts the data
//-----------------------------------------------------------------------------
void CMOTDPanel::PerformLayout()
{
BaseClass::PerformLayout();
// setup the layout of the panels
m_pMOTDPanel->SetBounds(5,5,GetWide()-10,GetTall()-35);
m_pSendMOTDButton->SetBounds(GetWide()-70,GetTall()-25,60,20);
}
//-----------------------------------------------------------------------------
// Purpose: inserts a new string into the main chat panel
//-----------------------------------------------------------------------------
void CMOTDPanel::DoInsertString(const char *str)
{
m_pMOTDPanel->SetText("");
if(strlen(str)>1024)
{
char *fix = const_cast<char *>(str);
fix[1024]='\0';
}
m_pMOTDPanel->DoInsertString(str);
}
//-----------------------------------------------------------------------------
// Purpose: passes the rcon class to use
//-----------------------------------------------------------------------------
void CMOTDPanel::SetRcon(CRcon *rcon)
{
m_pRcon=rcon;
}
//-----------------------------------------------------------------------------
// Purpose: run when the send button is pressed, send a rcon "say" to the server
//-----------------------------------------------------------------------------
void CMOTDPanel::OnSendMOTD()
{
if(m_pRcon)
{
char chat_text[2048];
_snprintf(chat_text,512,"motd_write ");
m_pMOTDPanel->GetText(0,chat_text+11,2048-11);
if(strlen("motd_write ")!=strlen(chat_text)) // check there is something in the text panel
{
unsigned int i=0;
while(i<strlen(chat_text) && i<2048)
{
if(chat_text[i]=='\n')
{
// shift everything up one
for(unsigned int k=strlen(chat_text)+1;k>i;k--)
{
chat_text[k+1]=chat_text[k];
}
// replace the newline with the string "\n"
chat_text[i]='\\';
chat_text[i+1]='n';
i++; // skip this insert
}
i++;
}
m_pRcon->SendRcon(chat_text);
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Called when the game dir combo box is changed
//-----------------------------------------------------------------------------
void CMOTDPanel::OnTextChanged(Panel *panel, const char *text)
{
// BUG - TextEntry NEVER lets the enter key through... This doesn't work
if( text[strlen(text)-1]=='\n') // the enter key was just pressed :)
{
OnSendMOTD();
}
}
//-----------------------------------------------------------------------------
// Purpose: Message map
//-----------------------------------------------------------------------------
MessageMapItem_t CMOTDPanel::m_MessageMap[] =
{
MAP_MESSAGE( CMOTDPanel, "SendMOTD", OnSendMOTD ),
MAP_MESSAGE( CMOTDPanel, "PageShow", OnPageShow ),
// MAP_MESSAGE_PTR_CONSTCHARPTR( CMOTDPanel, "TextChanged", OnTextChanged, "panel", "text" ),
};
IMPLEMENT_PANELMAP( CMOTDPanel, Frame );

View File

@ -0,0 +1,71 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef MOTDPANEL_H
#define MOTDPANEL_H
#ifdef _WIN32
#pragma once
#endif
#include <VGUI_Frame.h>
#include <VGUI_PHandle.h>
#include <VGUI_ListPanel.h>
#include <VGUI_KeyValues.h>
#include <VGUI_PropertyPage.h>
#include "rcon.h"
class KeyValues;
namespace vgui
{
class Button;
class ToggleButton;
class RadioButton;
class Label;
class TextEntry;
class ListPanel;
class MessageBox;
class ComboBox;
class Panel;
class PropertySheet;
};
//-----------------------------------------------------------------------------
// Purpose: Dialog for displaying information about a game server
//-----------------------------------------------------------------------------
class CMOTDPanel:public vgui::PropertyPage
{
public:
CMOTDPanel(vgui::Panel *parent, const char *name);
~CMOTDPanel();
// property page handlers
virtual void OnPageShow();
virtual void OnPageHide();
void DoInsertString(const char *str);
void SetRcon(CRcon *rcon);
virtual void PerformLayout();
private:
void OnSendMOTD();
void OnTextChanged(vgui::Panel *panel, const char *text);
vgui::TextEntry *m_pMOTDPanel;
vgui::Button *m_pSendMOTDButton;
CRcon *m_pRcon;
DECLARE_PANELMAP();
typedef vgui::PropertyPage BaseClass;
};
#endif // MOTDPANEL_H

View File

@ -0,0 +1,263 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "MapCycleEditDialog.h"
#include <vgui/KeyCode.h>
#include <KeyValues.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/ListPanel.h>
#include "RemoteServer.h"
#include "tier1/utlbuffer.h"
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CMapCycleEditDialog::CMapCycleEditDialog(vgui::Panel *parent, const char *name) : BaseClass(parent, name)
{
SetSize(480, 320);
SetSizeable(false);
m_pAvailableMapList = new ListPanel(this, "AvailableMapList");
m_pAvailableMapList->AddColumnHeader(0, "Map", "#Available_Maps", 128);
m_pAvailableMapList->SetColumnSortable(0, false);
m_pMapCycleList = new ListPanel(this, "MapCycleList");
m_pMapCycleList->AddColumnHeader(0, "Map", "#Map_Cycle", 128);
m_pMapCycleList->SetColumnSortable(0, false);
m_RightArrow = new Button(this, "RightButton", "");
m_LeftArrow = new Button(this, "LeftButton", "");
m_UpArrow = new Button(this, "UpButton", "");
m_DownArrow = new Button(this, "DownButton", "");
LoadControlSettings("Admin/MapCycleEditDialog.res", "PLATFORM");
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CMapCycleEditDialog::~CMapCycleEditDialog()
{
}
//-----------------------------------------------------------------------------
// Purpose: Shows the dialog, building the lists from the params
//-----------------------------------------------------------------------------
void CMapCycleEditDialog::Activate(vgui::Panel *updateTarget, CUtlVector<CUtlSymbol> &availableMaps, CUtlVector<CUtlSymbol> &mapCycle)
{
// set the action signal target
AddActionSignalTarget(updateTarget);
// clear lists
m_pAvailableMapList->DeleteAllItems();
m_pMapCycleList->DeleteAllItems();
// build lists
for (int i = 0; i < availableMaps.Count(); i++)
{
// only add to the available maps list if it's not in mapCycle
bool inMapCycle = false;
for (int j = 0; j < mapCycle.Count(); j++)
{
if (!stricmp(mapCycle[j].String(), availableMaps[i].String()))
{
inMapCycle = true;
break;
}
}
if (!inMapCycle)
{
m_pAvailableMapList->AddItem(new KeyValues("MapItem", "Map", availableMaps[i].String()), 0, false, false);
}
}
for (int i = 0; i < mapCycle.Count(); i++)
{
m_pMapCycleList->AddItem(new KeyValues("MapItem", "Map", mapCycle[i].String()), 0, false, false);
}
// show window
SetTitle("Change Map Cycle", false);
MoveToCenterOfScreen();
BaseClass::Activate();
}
//-----------------------------------------------------------------------------
// Purpose: Sets up button state
//-----------------------------------------------------------------------------
void CMapCycleEditDialog::PerformLayout()
{
m_LeftArrow->SetEnabled(false);
m_RightArrow->SetEnabled(false);
m_UpArrow->SetEnabled(false);
m_DownArrow->SetEnabled(false);
if (m_pMapCycleList->GetSelectedItemsCount() > 0)
{
m_LeftArrow->SetEnabled(true);
m_LeftArrow->SetAsDefaultButton(true);
if (m_pMapCycleList->GetSelectedItemsCount() == 1)
{
int row = m_pMapCycleList->GetSelectedItem(0);
if (row > 0)
{
m_UpArrow->SetEnabled(true);
}
if (row + 1 < m_pMapCycleList->GetItemCount())
{
m_DownArrow->SetEnabled(true);
}
}
}
else if (m_pAvailableMapList->GetSelectedItemsCount() > 0)
{
m_RightArrow->SetEnabled(true);
m_RightArrow->SetAsDefaultButton(true);
}
BaseClass::PerformLayout();
}
//-----------------------------------------------------------------------------
// Purpose: Updates UI based on which listpanel got selection
//-----------------------------------------------------------------------------
void CMapCycleEditDialog::OnItemSelected(vgui::Panel *panel)
{
if (panel == m_pAvailableMapList && m_pAvailableMapList->GetSelectedItemsCount() > 0)
{
m_pMapCycleList->ClearSelectedItems();
}
else if (panel == m_pMapCycleList && m_pMapCycleList->GetSelectedItemsCount() > 0)
{
m_pAvailableMapList->ClearSelectedItems();
}
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose: Button command handler
//-----------------------------------------------------------------------------
void CMapCycleEditDialog::OnCommand(const char *command)
{
if (!stricmp(command, "ArrowLeft"))
{
// move map from mapcycle to available list
while (m_pMapCycleList->GetSelectedItemsCount() > 0)
{
int itemID = m_pMapCycleList->GetSelectedItem(0);
KeyValues *data = m_pMapCycleList->GetItem(itemID);
if (!data)
return;
const char *map = data->GetString("Map");
m_pAvailableMapList->AddItem(new KeyValues("MapItem", "Map", map), 0, true, false);
m_pMapCycleList->RemoveItem(itemID);
}
}
else if (!stricmp(command, "ArrowRight"))
{
// move map from available list to mapcycle
while (m_pAvailableMapList->GetSelectedItemsCount() > 0)
{
int itemID = m_pAvailableMapList->GetSelectedItem(0);
KeyValues *data = m_pAvailableMapList->GetItem(itemID);
if (!data)
return;
const char *map = data->GetString("Map");
m_pMapCycleList->AddItem(new KeyValues("MapItem", "Map", map), 0, true, false);
m_pAvailableMapList->RemoveItem(itemID);
}
}
else if (!stricmp(command, "ArrowUp"))
{
int itemID = m_pMapCycleList->GetSelectedItem(0);
int row = m_pMapCycleList->GetItemCurrentRow(itemID);
int prevRow = row - 1;
if (prevRow < 0)
return;
int prevItemID = m_pMapCycleList->GetItemIDFromRow(prevRow);
// get the data
KeyValues *d1 = m_pMapCycleList->GetItem(itemID);
KeyValues *d2 = m_pMapCycleList->GetItem(prevItemID);
// swap the strings
CUtlSymbol tempString = d1->GetString("Map");
d1->SetString("Map", d2->GetString("Map"));
d2->SetString("Map", tempString.String());
// update the list
m_pMapCycleList->ApplyItemChanges(itemID);
m_pMapCycleList->ApplyItemChanges(prevItemID);
PostMessage(m_pMapCycleList, new KeyValues("KeyCodePressed", "code", KEY_UP));
}
else if (!stricmp(command, "ArrowDown"))
{
int itemID = m_pMapCycleList->GetSelectedItem(0);
int row = m_pMapCycleList->GetItemCurrentRow(itemID);
int nextRow = row + 1;
if (nextRow + 1 > m_pMapCycleList->GetItemCount())
return;
int nextItemID = m_pMapCycleList->GetItemIDFromRow(nextRow);
// get the data
KeyValues *d1 = m_pMapCycleList->GetItem(itemID);
KeyValues *d2 = m_pMapCycleList->GetItem(nextItemID);
// swap the strings
CUtlSymbol tempString = d1->GetString("Map");
d1->SetString("Map", d2->GetString("Map"));
d2->SetString("Map", tempString.String());
// update the list
m_pMapCycleList->ApplyItemChanges(itemID);
m_pMapCycleList->ApplyItemChanges(nextItemID);
PostMessage(m_pMapCycleList, new KeyValues("KeyCodePressed", "code", KEY_DOWN));
}
else if (!stricmp(command, "Cancel"))
{
Close();
}
else if (!stricmp(command, "OK"))
{
// write out the data
CUtlBuffer msg(0, 1024, CUtlBuffer::TEXT_BUFFER);
for (int i = 0; i < m_pMapCycleList->GetItemCount(); i++)
{
int itemID = m_pMapCycleList->GetItemIDFromRow(i);
KeyValues *kv = m_pMapCycleList->GetItem(itemID);
if ( kv )
{
msg.PutString(kv->GetString("Map"));
msg.PutChar('\n');
}
}
msg.PutChar(0);
RemoteServer().SetValue("mapcycle", (const char *)msg.Base());
// post message to tell varlist update
PostActionSignal(new KeyValues("VarChanged", "var", "mapcycle"));
// close
Close();
}
else
{
BaseClass::OnCommand(command);
}
}

View File

@ -0,0 +1,45 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef MAPCYCLEEDITDIALOG_H
#define MAPCYCLEEDITDIALOG_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/Frame.h>
#include "utlvector.h"
#include "utlsymbol.h"
//-----------------------------------------------------------------------------
// Purpose: Dialog for editing the game server map cycle list
//-----------------------------------------------------------------------------
class CMapCycleEditDialog : public vgui::Frame
{
DECLARE_CLASS_SIMPLE( CMapCycleEditDialog, vgui::Frame );
public:
CMapCycleEditDialog(vgui::Panel *parent, const char *name);
~CMapCycleEditDialog();
virtual void Activate(vgui::Panel *updateTarget, CUtlVector<CUtlSymbol> &availableMaps, CUtlVector<CUtlSymbol> &mapCycle);
protected:
virtual void OnCommand(const char *command);
virtual void PerformLayout();
private:
MESSAGE_FUNC_PTR( OnItemSelected, "ItemSelected", panel );
vgui::ListPanel *m_pAvailableMapList;
vgui::ListPanel *m_pMapCycleList;
vgui::Button *m_RightArrow;
vgui::Button *m_LeftArrow;
vgui::Button *m_UpArrow;
vgui::Button *m_DownArrow;
};
#endif // MAPCYCLEEDITDIALOG_H

View File

@ -0,0 +1,76 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "MasterMsgHandler.h"
#include "IGameList.h"
#include "serverpage.h"
#include <VGUI_Controls.h>
#include <VGUI_IVGui.h>
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CMasterMsgHandler::CMasterMsgHandler( IGameList *baseobject, HANDLERTYPE type, void *typeinfo /*= NULL*/ )
: CMsgHandler( type, typeinfo )
{
m_pGameList = baseobject;
}
//-----------------------------------------------------------------------------
// Purpose: Process cracked message
//-----------------------------------------------------------------------------
bool CMasterMsgHandler::Process( netadr_t *from, CMsgBuffer *msg )
{
// Skip the control character
msg->ReadByte();
// Skip the return character
msg->ReadByte();
// Get the batch ID
int unique = msg->ReadLong();
// Remainder of message length is 6 byte IP addresses
int nNumAddresses = msg->GetCurSize() - msg->GetReadCount();
assert( !( nNumAddresses % 6 ) );
// Each address is 6 bytes long
nNumAddresses /= 6;
while (nNumAddresses-- > 0)
{
serveritem_t server;
memset(&server, 0, sizeof(server));
for (int i = 0; i < 4; i++)
{
server.ip[i] = msg->ReadByte();
}
server.port = msg->ReadShort();
server.port = (server.port & 0xff) << 8 | (server.port & 0xff00) >> 8; // roll your own ntohs
server.received = 0;
server.listEntry = NULL;
server.doNotRefresh = false;
server.hadSuccessfulResponse = false;
server.map[0] = 0;
server.gameDir[0] = 0;
m_pGameList->AddNewServer(server);
}
if (!unique)
{
m_pGameList->ListReceived(false, 0);
}
else
{
// wait until we've refreshed the list before getting next batch of servers
m_pGameList->ListReceived(true, unique);
}
return true;
}

View File

@ -0,0 +1,33 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef PLAYER_H
#define PLAYER_H
#ifdef _WIN32
#pragma once
#endif
#include <VGUI_ListPanel.h>
//-----------------------------------------------------------------------------
// Purpose: Data describing a single player
//-----------------------------------------------------------------------------
typedef struct
{
char name[100];
int ping;
int userid;
char authid[20];
int loss;
int frags;
float time;
char addr[4];
} Players_t;
#endif // PLAYER_H

View File

@ -0,0 +1,51 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "PlayerContextMenu.h"
#include <vgui/IInput.h>
#include <vgui/IPanel.h>
#include <vgui/ISurface.h>
#include <KeyValues.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CPlayerContextMenu::CPlayerContextMenu(Panel *parent) : Menu(parent, "ServerContextMenu")
{
CPlayerContextMenu::parent=parent;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CPlayerContextMenu::~CPlayerContextMenu()
{
}
//-----------------------------------------------------------------------------
// Purpose: Activates the menu
//-----------------------------------------------------------------------------
void CPlayerContextMenu::ShowMenu(Panel *target, unsigned int playerID)
{
DeleteAllItems();
AddMenuItem("Kick", "#Player_Menu_Kick", new KeyValues("Kick", "playerID", playerID), CPlayerContextMenu::parent);
AddMenuItem("Ban", "#Player_Menu_Ban", new KeyValues("Ban", "playerID", playerID), CPlayerContextMenu::parent);
//addMenuItem("Status", "&Player Status", new KeyValues("Status", "playerID", playerID), CPlayerContextMenu::parent);
MakePopup();
int x, y, gx, gy;
input()->GetCursorPos(x, y);
ipanel()->GetPos(surface()->GetEmbeddedPanel(), gx, gy);
SetPos(x - gx, y - gy);
MoveToFront();
RequestFocus();
SetVisible(true);
}

View File

@ -0,0 +1,32 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef PLAYERCONTEXTMENU_H
#define PLAYERCONTEXTMENU_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/Menu.h>
//-----------------------------------------------------------------------------
// Purpose: Basic right-click context menu for servers
//-----------------------------------------------------------------------------
class CPlayerContextMenu : public vgui::Menu
{
public:
CPlayerContextMenu(vgui::Panel *parent);
~CPlayerContextMenu();
// call this to activate the menu
void ShowMenu(vgui::Panel *target, unsigned int serverID);
private:
vgui::Panel *parent; // so we can send it messages
};
#endif // PLAYERCONTEXTMENU_H

View File

@ -0,0 +1,191 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include <stdio.h>
#include <KeyValues.h>
#include <vgui_controls/ListPanel.h>
int __cdecl PlayerNameCompare(const KeyValues *elem1, const KeyValues *elem2 )
{
if ( !elem1 || !elem2 ) // No meaningful comparison
{
return 0;
}
/* const char *name1 = elem1->GetString("name");
const char *name2 = elem2->GetString("name");
return stricmp(name1,name2);
*/
return 0;
}
//-----------------------------------------------------------------------------
// Purpose: Ping comparison function
//-----------------------------------------------------------------------------
int __cdecl PlayerPingCompare(const KeyValues *elem1, const KeyValues *elem2 )
{
vgui::ListPanelItem *p1, *p2;
p1 = *(vgui::ListPanelItem **)elem1;
p2 = *(vgui::ListPanelItem **)elem2;
if ( !p1 || !p2 ) // No meaningful comparison
{
return 0;
}
int ping1 = p1->kv->GetInt("ping");
int ping2 = p2->kv->GetInt("ping");
if ( ping1 < ping2 )
return -1;
else if ( ping1 > ping2 )
return 1;
return 0;
}
//-----------------------------------------------------------------------------
// Purpose: Ping comparison function
//-----------------------------------------------------------------------------
int __cdecl PlayerAuthCompare(const void *elem1, const void *elem2 )
{
vgui::ListPanelItem *p1, *p2;
p1 = *(vgui::ListPanelItem **)elem1;
p2 = *(vgui::ListPanelItem **)elem2;
if ( !p1 || !p2 ) // No meaningful comparison
{
return 0;
}
const char *authid1 = p1->kv->GetString("authid");
const char *authid2 = p2->kv->GetString("authid");
return stricmp(authid1,authid2);
}
//-----------------------------------------------------------------------------
// Purpose: Loss comparison function
//-----------------------------------------------------------------------------
int __cdecl PlayerLossCompare(const void *elem1, const void *elem2 )
{
vgui::ListPanelItem *p1, *p2;
p1 = *(vgui::ListPanelItem **)elem1;
p2 = *(vgui::ListPanelItem **)elem2;
if ( !p1 || !p2 ) // No meaningful comparison
{
return 0;
}
int loss1 = p1->kv->GetInt("loss");
int loss2 = p2->kv->GetInt("loss");
if ( loss1 < loss2 )
return -1;
else if ( loss1 > loss2 )
return 1;
return 0;
}
//-----------------------------------------------------------------------------
// Purpose: Frags comparison function
//-----------------------------------------------------------------------------
int __cdecl PlayerFragsCompare(const void *elem1, const void *elem2 )
{
vgui::ListPanelItem *p1, *p2;
p1 = *(vgui::ListPanelItem **)elem1;
p2 = *(vgui::ListPanelItem **)elem2;
if ( !p1 || !p2 ) // No meaningful comparison
{
return 0;
}
int frags1 = p1->kv->GetInt("frags");
int frags2 = p2->kv->GetInt("frags");
if ( frags1 < frags2 )
return -1;
else if ( frags1 > frags2 )
return 1;
return 0;
}
//-----------------------------------------------------------------------------
// Purpose: Player connection time comparison function
//-----------------------------------------------------------------------------
int __cdecl PlayerTimeCompare( vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 )
{
int h1 = 0, h2 = 0, m1 = 0, m2 = 0, s1 = 0, s2 = 0;
float t1=0,t2=0;
const char *time1 = item1.kv->GetString("time");
const char *time2 = item2.kv->GetString("time");
int numFields1 = sscanf(time1,"%i:%i:%i",&h1,&m1,&s1);
int numFields2 = sscanf(time2,"%i:%i:%i",&h2,&m2,&s2);
switch ( numFields1 )
{
case 2:
s1 = m1;
m1 = h1;
h1 = 0;
break;
case 1:
s1 = h1;
m1 = 0;
h1 = 0;
break;
case 0:
s1 = 0;
m1 = 0;
h1 = 0;
}
switch ( numFields2 )
{
case 2:
s2 = m2;
m2 = h2;
h2 = 0;
break;
case 1:
s2 = h2;
m2 = 0;
h2 = 0;
break;
case 0:
s2 = 0;
m2 = 0;
h2 = 0;
}
t1=(float)(h1*3600+m1*60+s1);
t2=(float)(h2*3600+m2*60+s2);
if ( t1 < t2 )
return -1;
else if ( t1 > t2 )
return 1;
return 0;
}

View File

@ -0,0 +1,25 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef PLAYERLISTCOMPARE_H
#define PLAYERLISTCOMPARE_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/ListPanel.h>
// these functions are common to most server lists in sorts
int __cdecl PlayerNameCompare(const void *elem1, const void *elem2 );
int __cdecl PlayerAuthCompare(const void *elem1, const void *elem2 );
int __cdecl PlayerPingCompare(const void *elem1, const void *elem2 );
int __cdecl PlayerLossCompare(const void *elem1, const void *elem2 );
int __cdecl PlayerTimeCompare( vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 );
int __cdecl PlayerFragsCompare(const void *elem1, const void *elem2 );
#endif // PLAYERLISTCOMPARE_H

View File

@ -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);
}
}

View File

@ -0,0 +1,68 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef PLAYERPANEL_H
#define PLAYERPANEL_H
#ifdef _WIN32
#pragma once
#endif
#include <KeyValues.h>
#include <vgui_controls/Frame.h>
#include <vgui_controls/PHandle.h>
#include <vgui_controls/ListPanel.h>
#include <vgui_controls/PropertyPage.h>
#include "PlayerContextMenu.h"
#include "RemoteServer.h"
//-----------------------------------------------------------------------------
// Purpose: Dialog for displaying information about a game server
//-----------------------------------------------------------------------------
class CPlayerPanel : public vgui::PropertyPage, public IServerDataResponse
{
DECLARE_CLASS_SIMPLE( CPlayerPanel, vgui::PropertyPage );
public:
CPlayerPanel(vgui::Panel *parent, const char *name);
~CPlayerPanel();
// returns the keyvalues for the currently selected row
KeyValues *GetSelected();
protected:
// property page handlers
virtual void OnResetData();
virtual void OnThink();
virtual void OnKeyCodeTyped(vgui::KeyCode code);
// called when the server has returned a requested value
virtual void OnServerDataResponse(const char *value, const char *response);
private:
// vgui overrides
virtual void OnCommand(const char *command);
// msg handlers
MESSAGE_FUNC_INT( OnOpenContextMenu, "OpenContextMenu", itemID );
MESSAGE_FUNC( OnItemSelected, "ItemSelected" );
MESSAGE_FUNC( OnKickButtonPressed, "KickPlayer" );
MESSAGE_FUNC( OnBanButtonPressed, "BanPlayer" );
MESSAGE_FUNC( KickSelectedPlayers, "KickSelectedPlayers" );
MESSAGE_FUNC_CHARPTR_CHARPTR( AddBanByID, "AddBanValue", id, time );
vgui::ListPanel *m_pPlayerListPanel;
vgui::Button *m_pKickButton;
vgui::Button *m_pBanButton;
CPlayerContextMenu *m_pPlayerContextMenu;
float m_flUpdateTime;
};
#endif // PLAYERPANEL_H

View File

@ -0,0 +1,87 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include <stdio.h>
#include "RawLogPanel.h"
#include <vgui/ISystem.h>
#include <vgui/ISurface.h>
#include <vgui/IVGui.h>
#include <vgui/ILocalize.h>
#include <KeyValues.h>
#include <vgui_controls/Label.h>
#include <vgui_controls/TextEntry.h>
#include <vgui_controls/RichText.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/ToggleButton.h>
#include <vgui_controls/RadioButton.h>
#include <vgui_controls/ListPanel.h>
#include <vgui_controls/ComboBox.h>
#include <vgui_controls/PHandle.h>
#include <vgui_controls/PropertySheet.h>
#include "vgui_controls/ConsoleDialog.h"
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CRawLogPanel::CRawLogPanel(vgui::Panel *parent, const char *name) : vgui::PropertyPage(parent, name)
{
SetSize(200, 100);
m_pConsole = new CConsolePanel( this, "Console", false );
LoadControlSettings("Admin\\RawLogPanel.res", "PLATFORM");
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CRawLogPanel::~CRawLogPanel()
{
}
//-----------------------------------------------------------------------------
// Purpose: Activates the page
//-----------------------------------------------------------------------------
void CRawLogPanel::OnPageShow()
{
BaseClass::OnPageShow();
}
//-----------------------------------------------------------------------------
// Purpose: Hides the page
//-----------------------------------------------------------------------------
void CRawLogPanel::OnPageHide()
{
BaseClass::OnPageHide();
}
//-----------------------------------------------------------------------------
// Purpose: inserts a new string into the main chat panel
//-----------------------------------------------------------------------------
void CRawLogPanel::DoInsertString(const char *str)
{
if ( str )
{
m_pConsole->Print( str );
}
}
//-----------------------------------------------------------------------------
// Purpose: run when the send button is pressed, execs a command on the server
//-----------------------------------------------------------------------------
void CRawLogPanel::OnCommandSubmitted( char const *pchCommand )
{
if ( !pchCommand || !*pchCommand )
return;
// execute the typed command
RemoteServer().SendCommand( pchCommand );
}

View File

@ -0,0 +1,43 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef RAWLOGPANEL_H
#define RAWLOGPANEL_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/PropertyPage.h>
#include "RemoteServer.h"
namespace vgui
{
class CConsolePanel;
}
//-----------------------------------------------------------------------------
// Purpose: Dialog for displaying information about a game server
//-----------------------------------------------------------------------------
class CRawLogPanel : public vgui::PropertyPage
{
DECLARE_CLASS_SIMPLE( CRawLogPanel, vgui::PropertyPage );
public:
CRawLogPanel(vgui::Panel *parent, const char *name);
~CRawLogPanel();
// property page handlers
virtual void OnPageShow();
virtual void OnPageHide();
void DoInsertString(const char *str);
private:
MESSAGE_FUNC_CHARPTR( OnCommandSubmitted, "CommandSubmitted", command );
vgui::CConsolePanel *m_pConsole;
};
#endif // RAWLOGPANEL_H

View File

@ -0,0 +1,256 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "RemoteServer.h"
#include <assert.h>
#include <stdio.h>
#include "tier1/utlbuffer.h"
#include "IGameServerData.h"
extern IGameServerData *g_pGameServerData;
//-----------------------------------------------------------------------------
// Purpose: singleton accessor
//-----------------------------------------------------------------------------
CRemoteServer &RemoteServer()
{
static CRemoteServer s_RemoteServer;
return s_RemoteServer;
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CRemoteServer::CRemoteServer()
{
m_iCurrentRequestID = 0;
m_ListenerID = INVALID_LISTENER_ID;
m_bInitialized = false;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CRemoteServer::~CRemoteServer()
{
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
void CRemoteServer::Initialize()
{
m_bInitialized = true;
Assert( g_pGameServerData );
m_ListenerID = g_pGameServerData->GetNextListenerID( false ); // don't require auth on this connection
g_pGameServerData->RegisterAdminUIID( m_ListenerID );
}
//-----------------------------------------------------------------------------
// Purpose: connects to a remote game server
//-----------------------------------------------------------------------------
void CRemoteServer::ConnectRemoteGameServer(unsigned int ip, unsigned short port, const char *password)
{
assert(!("CRemoteServer::ConnectRemoteGameServer() not yet implemented"));
}
//-----------------------------------------------------------------------------
// Purpose: request a cvar/data from the server
//-----------------------------------------------------------------------------
void CRemoteServer::RequestValue(IServerDataResponse *requester, const char *variable)
{
Assert( m_bInitialized );
// add to the response handling table
int i = m_ResponseHandlers.AddToTail();
m_ResponseHandlers[i].requestID = m_iCurrentRequestID;
m_ResponseHandlers[i].handler = requester;
// build the command
char buf[512];
CUtlBuffer cmd(buf, sizeof(buf));
cmd.PutInt(m_iCurrentRequestID++);
cmd.PutInt(SERVERDATA_REQUESTVALUE);
cmd.PutString(variable);
cmd.PutString("");
// send to server
g_pGameServerData->WriteDataRequest(m_ListenerID, cmd.Base(), cmd.TellPut());
}
//-----------------------------------------------------------------------------
// Purpose: sets a value
//-----------------------------------------------------------------------------
void CRemoteServer::SetValue(const char *variable, const char *value)
{
Assert( m_bInitialized );
// build the command
char buf[512];
CUtlBuffer cmd(buf, sizeof(buf));
cmd.PutInt(m_iCurrentRequestID++);
cmd.PutInt(SERVERDATA_SETVALUE);
cmd.PutString(variable);
cmd.PutString(value);
// send to server
g_pGameServerData->WriteDataRequest(m_ListenerID, cmd.Base(), cmd.TellPut());
}
//-----------------------------------------------------------------------------
// Purpose: sends a custom command
//-----------------------------------------------------------------------------
void CRemoteServer::SendCommand(const char *commandString)
{
Assert( m_bInitialized );
// build the command
char buf[512];
CUtlBuffer cmd(buf, sizeof(buf));
cmd.PutInt(m_iCurrentRequestID++);
cmd.PutInt(SERVERDATA_EXECCOMMAND);
cmd.PutString(commandString);
cmd.PutString("");
g_pGameServerData->WriteDataRequest(m_ListenerID, cmd.Base(), cmd.TellPut());
}
//-----------------------------------------------------------------------------
// Purpose: changes the current password on the server
// responds with "PasswordChange" "true" or "PasswordChange" "false"
//-----------------------------------------------------------------------------
void CRemoteServer::ChangeAccessPassword(IServerDataResponse *requester, const char *newPassword)
{
}
//-----------------------------------------------------------------------------
// Purpose: process any return values, firing any IServerDataResponse items
// Output : returns true if any items were fired
//-----------------------------------------------------------------------------
bool CRemoteServer::ProcessServerResponse()
{
Assert(g_pGameServerData != NULL);
Assert( m_bInitialized );
char charbuf[4096];
bool bProcessedAnyPackets = false;
while (1)
{
// get packet from networking
int bytesRead = g_pGameServerData->ReadDataResponse(m_ListenerID, charbuf, sizeof(charbuf));
if (bytesRead < 1)
break;
bProcessedAnyPackets = true;
// parse response
CUtlBuffer buf(charbuf, bytesRead, CUtlBuffer::READ_ONLY);
int requestID = buf.GetInt();
int responseType = buf.GetInt();
char variable[64];
buf.GetString(variable);
switch (responseType)
{
case SERVERDATA_RESPONSE_VALUE:
{
int valueSize = buf.GetInt();
Assert(valueSize > 0);
CUtlBuffer value(0, valueSize);
if (valueSize > 0)
{
value.Put(buf.PeekGet(), valueSize);
}
else
{
// null terminate
value.PutChar(0);
}
// find callback (usually will be the first one in the list)
for (int i = m_ResponseHandlers.Head(); m_ResponseHandlers.IsValidIndex(i); i = m_ResponseHandlers.Next(i))
{
if (m_ResponseHandlers[i].requestID == requestID)
{
// found, call
m_ResponseHandlers[i].handler->OnServerDataResponse(variable, (const char *)value.Base());
// remove from list
m_ResponseHandlers.Remove(i);
// there is only ever one handler for a message
break;
}
}
}
break;
case SERVERDATA_UPDATE:
{
// find all the people watching for this message
for (int i = m_MessageHandlers.Head(); m_MessageHandlers.IsValidIndex(i); i = m_MessageHandlers.Next(i))
{
if (!stricmp(m_MessageHandlers[i].messageName, variable))
{
// found, call
m_MessageHandlers[i].handler->OnServerDataResponse(variable, "");
// keep looking, there can be more than one handler for a message
}
}
}
break;
default:
Assert(responseType == SERVERDATA_RESPONSE_VALUE || responseType == SERVERDATA_UPDATE);
break;
}
}
return bProcessedAnyPackets;
}
//-----------------------------------------------------------------------------
// Purpose: adds a constant watches for a particular message
//-----------------------------------------------------------------------------
void CRemoteServer::AddServerMessageHandler(IServerDataResponse *handler, const char *watch)
{
// add to the server message handling table
int i = m_MessageHandlers.AddToTail();
strncpy(m_MessageHandlers[i].messageName, watch, sizeof(m_MessageHandlers[i].messageName) - 1);
m_MessageHandlers[i].messageName[sizeof(m_MessageHandlers[i].messageName) - 1] = 0;
m_MessageHandlers[i].handler = handler;
}
//-----------------------------------------------------------------------------
// Purpose: removes a requester from the list to guarantee the pointer won't be used
//-----------------------------------------------------------------------------
void CRemoteServer::RemoveServerDataResponseTarget(IServerDataResponse *invalidRequester)
{
// iterate the responses
for (int i = 0; i < m_ResponseHandlers.MaxElementIndex(); i++)
{
if (m_ResponseHandlers.IsValidIndex(i))
{
if (m_ResponseHandlers[i].handler == invalidRequester)
{
// found invalid handler, remove from list
m_ResponseHandlers.Remove(i);
}
}
}
// iterate the message handlers
for (int i = 0; i < m_MessageHandlers.MaxElementIndex(); i++)
{
if (m_MessageHandlers.IsValidIndex(i))
{
if (m_MessageHandlers[i].handler == invalidRequester)
{
// found invalid handler, remove from list
m_MessageHandlers.Remove(i);
}
}
}
}

View File

@ -0,0 +1,95 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef REMOTESERVER_H
#define REMOTESERVER_H
#ifdef _WIN32
#pragma once
#endif
#include "UtlLinkedList.h"
#include "igameserverdata.h"
class IServerDataResponse;
//-----------------------------------------------------------------------------
// Purpose: Configures and installs the connection to the game server (remote or local)
//-----------------------------------------------------------------------------
class CRemoteServer
{
public:
CRemoteServer();
~CRemoteServer();
// setup this object
void Initialize();
// remote connection
void ConnectRemoteGameServer(unsigned int ip, unsigned short port, const char *password);
// request a cvar/data from the server
void RequestValue(IServerDataResponse *requester, const char *variable);
// sets a value
void SetValue(const char *variable, const char *value);
// sends a custom command
void SendCommand(const char *commandString);
// changes the current password on the server
// responds with "PasswordChange" "true" or "PasswordChange" "false"
void ChangeAccessPassword(IServerDataResponse *requester, const char *newPassword);
// process any return values, firing any IServerDataResponse items
// returns true if any items were fired
bool ProcessServerResponse();
// Adds a constant watches for a particular message. Used to handle
// information channels from the server->client (map changed, player joined, etc.)
void AddServerMessageHandler(IServerDataResponse *handler, const char *watch);
// removes a requester from the list to guarantee the pointer won't be used
void RemoveServerDataResponseTarget(IServerDataResponse *invalidRequester);
private:
int m_iCurrentRequestID;
ra_listener_id m_ListenerID;
bool m_bInitialized;
// list of all the currently waiting response handlers
struct ResponseHandler_t
{
int requestID;
IServerDataResponse *handler;
};
CUtlLinkedList<ResponseHandler_t, int> m_ResponseHandlers;
// list of constant response handlers
struct MessageHandler_t
{
char messageName[32];
IServerDataResponse *handler;
};
CUtlLinkedList<MessageHandler_t, int> m_MessageHandlers;
};
//-----------------------------------------------------------------------------
// Purpose: callback interface
//-----------------------------------------------------------------------------
class IServerDataResponse
{
public:
// called when the server has returned a requested value
virtual void OnServerDataResponse(const char *value, const char *response) = 0;
};
// singleton accessor
extern CRemoteServer &RemoteServer();
#endif // REMOTESERVER_H

View File

@ -0,0 +1,51 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "RulesContextMenu.h"
#include <VGUI_Controls.h>
#include <VGUI_IInput.h>
#include <VGUI_IPanel.h>
#include <VGUI_ISurface.h>
#include <VGUI_KeyValues.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CRulesContextMenu::CRulesContextMenu(Panel *parent) : Menu(parent, "RulesContextMenu")
{
CRulesContextMenu::parent=parent;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CRulesContextMenu::~CRulesContextMenu()
{
}
//-----------------------------------------------------------------------------
// Purpose: Activates the menu
//-----------------------------------------------------------------------------
void CRulesContextMenu::ShowMenu(Panel *target, unsigned int cvarID)
{
ClearMenu();
AddMenuItem("cvar", "&Change Value", new KeyValues("cvar", "cvarID", cvarID), CRulesContextMenu::parent);
MakePopup();
int x, y, gx, gy;
input()->GetCursorPos(x, y);
ipanel()->GetPos(surface()->GetEmbeddedPanel(), gx, gy);
SetPos(x - gx, y - gy);
MoveToFront();
RequestFocus();
SetVisible(true);
}

View File

@ -0,0 +1,32 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef RULESCONTEXTMENU_H
#define RULESCONTEXTMENU_H
#ifdef _WIN32
#pragma once
#endif
#include <VGUI_Menu.h>
//-----------------------------------------------------------------------------
// Purpose: Basic right-click context menu for servers
//-----------------------------------------------------------------------------
class CRulesContextMenu : public vgui::Menu
{
public:
CRulesContextMenu(vgui::Panel *parent);
~CRulesContextMenu();
// call this to activate the menu
void ShowMenu(vgui::Panel *target, unsigned int cvarID);
private:
vgui::Panel *parent; // so we can send it messages
};
#endif // RULESCONTEXTMENU_H

View File

@ -0,0 +1,61 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include <stdio.h>
#include "ServerConfigPanel.h"
#include <vgui/ISystem.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CServerConfigPanel::CServerConfigPanel(vgui::Panel *parent, const char *name, const char *mod) : CVarListPropertyPage(parent, name)
{
SetBounds(0, 0, 500, 170);
LoadControlSettings("Admin\\ServerConfigPanel.res", "PLATFORM");
// load our rules
if (!LoadVarList("scripts/GameServerConfig.vdf"))
{
//!! no local mod info, need to load from server
//!! always load from server if on a remote connection
}
m_flUpdateTime = 0.0f;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CServerConfigPanel::~CServerConfigPanel()
{
}
//-----------------------------------------------------------------------------
// Purpose: Reset data
//-----------------------------------------------------------------------------
void CServerConfigPanel::OnResetData()
{
RefreshVarList();
// update every minute
m_flUpdateTime = (float)system()->GetFrameTime() + (60 * 1.0f);
}
//-----------------------------------------------------------------------------
// Purpose: Checks to see if data needs to be refreshed
//-----------------------------------------------------------------------------
void CServerConfigPanel::OnThink()
{
if (m_flUpdateTime < system()->GetFrameTime())
{
OnResetData();
}
}

View File

@ -0,0 +1,35 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef SERVERCONFIGPANEL_H
#define SERVERCONFIGPANEL_H
#ifdef _WIN32
#pragma once
#endif
#include "VarListPropertyPage.h"
//-----------------------------------------------------------------------------
// Purpose: Displays and allows modification to variable specific to the game
//-----------------------------------------------------------------------------
class CServerConfigPanel : public CVarListPropertyPage
{
public:
CServerConfigPanel(vgui::Panel *parent, const char *name, const char *mod);
~CServerConfigPanel();
protected:
// variable updates
virtual void OnResetData();
virtual void OnThink();
private:
float m_flUpdateTime;
typedef CVarListPropertyPage BaseClass;
};
#endif // SERVERCONFIGPANEL_H

View File

@ -0,0 +1,104 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "ServerContextMenu.h"
#include <VGUI_Controls.h>
#include <VGUI_IInput.h>
#include <VGUI_IPanel.h>
#include <VGUI_ISurface.h>
#include <VGUI_KeyValues.h>
#include <VGUI_PropertySheet.h>
#include <stdio.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CServerContextMenu::CServerContextMenu(CServerPage *parent) : Menu(parent, "ServerContextMenu")
{
CServerContextMenu::parent=parent;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CServerContextMenu::~CServerContextMenu()
{
}
//-----------------------------------------------------------------------------
// Purpose: Activates the menu
//-----------------------------------------------------------------------------
void CServerContextMenu::ShowMenu(Panel *target, unsigned int serverID, bool showConnect, bool showRefresh, bool showAddToFavorites,bool manage)
{
ClearMenu();
// by default show the menu
bool displayed=false;
if(serverID==-1)
{
displayed=true; // no server selected, clicking on an empty area :)
}
if (showConnect)
{
displayed=true;
AddMenuItem("ConnectToServer", "&Connect to server", new KeyValues("ConnectToServer", "serverID", serverID), target);
AddMenuItem("ViewGameInfo", "&View server info", new KeyValues("ViewGameInfo", "serverID", serverID), target);
}
if (showRefresh)
{
displayed=true;
AddMenuItem("RefreshServer", "&Refresh server", new KeyValues("RefreshServer", "serverID", serverID), target);
}
if (showAddToFavorites)
{
displayed=true;
AddMenuItem("AddToFavorites", "&Add server to favorites", new KeyValues("AddToFavorites", "serverID", serverID), target);
}
if(manage)
{
displayed=true;
AddMenuItem("Manage", "&Manage Server", new KeyValues("Manage", "serverID", serverID), CServerContextMenu::parent);
}
/* if (parent->IsCursorOver() ) // if the cursor is over the tabs
{
displayed=false;
if((int) parent->GetTabPanel()->GetActivePageNum()!=0) // don't let the first tab be deleted, its our servers tab :)
{
char name[100];
displayed=true;
strncpy(name,"&Delete ",100);
parent->GetTabPanel()->GetActiveTabTitle(name+8,100-8);
AddMenuItem("Delete", name,new KeyValues("DeleteServer", "panelid",(int) parent->GetTabPanel()->GetActivePageNum()), CServerContextMenu::parent);
}
} */
if(displayed)
{
MakePopup();
int x, y, gx, gy;
input()->GetCursorPos(x, y);
ipanel()->GetPos(surface()->GetEmbeddedPanel(), gx, gy);
SetPos(x - gx, y - gy);
MoveToFront();
RequestFocus();
SetVisible(true);
}
}

View File

@ -0,0 +1,33 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef SERVERCONTEXTMENU_H
#define SERVERCONTEXTMENU_H
#ifdef _WIN32
#pragma once
#endif
#include <VGUI_Menu.h>
#include "serverpage.h"
//-----------------------------------------------------------------------------
// Purpose: Basic right-click context menu for servers
//-----------------------------------------------------------------------------
class CServerContextMenu : public vgui::Menu
{
public:
CServerContextMenu(CServerPage /*vgui::Panel*/ *parent);
~CServerContextMenu();
// call this to activate the menu
void ShowMenu(vgui::Panel *target, unsigned int serverID, bool showConnect, bool showRefresh, bool showAddToFavorites,bool manage);
private:
CServerPage /*vgui::Panel*/ *parent; // so we can send it messages
};
#endif // SERVERCONTEXTMENU_H

View File

@ -0,0 +1,446 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "IServerRefreshResponse.h"
#include "ServerList.h"
//#include "ServerMsgHandlerDetails.h"
#include "Socket.h"
#include "proto_oob.h"
// for debugging
#include <VGUI_Controls.h>
#include <VGUI_ISystem.h>
#include <VGUI_IVGui.h>
typedef enum
{
NONE = 0,
INFO_REQUESTED,
INFO_RECEIVED
} QUERYSTATUS;
extern void v_strncpy(char *dest, const char *src, int bufsize);
#define min(a,b) (((a) < (b)) ? (a) : (b))
//-----------------------------------------------------------------------------
// Purpose: Comparison function used in query redblack tree
//-----------------------------------------------------------------------------
bool QueryLessFunc( const query_t &item1, const query_t &item2 )
{
// compare port then ip
if (item1.addr.port < item2.addr.port)
return true;
else if (item1.addr.port > item2.addr.port)
return false;
int ip1 = *(int *)&item1.addr.ip;
int ip2 = *(int *)&item2.addr.ip;
return ip1 < ip2;
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CServerList::CServerList(IServerRefreshResponse *target) : m_Queries(0, MAX_QUERY_SOCKETS, QueryLessFunc)
{
m_pResponseTarget = target;
m_iUpdateSerialNumber = 1;
// calculate max sockets based on users' rate
char speedBuf[32];
int internetSpeed;
if (!vgui::system()->GetRegistryString("HKEY_CURRENT_USER\\Software\\Valve\\Tracker\\Rate", speedBuf, sizeof(speedBuf)-1))
{
// default to DSL speed if no reg key found (an unlikely occurance)
strcpy(speedBuf, "7500");
}
internetSpeed = atoi(speedBuf);
int maxSockets = (MAX_QUERY_SOCKETS * internetSpeed) / 10000;
if (internetSpeed < 6000)
{
// reduce the number of active queries again for slow internet speeds
maxSockets /= 2;
}
m_nMaxActive = maxSockets;
m_nRampUpSpeed = 1;
m_bQuerying = false;
m_nMaxRampUp = 1;
m_nInvalidServers = 0;
m_nRefreshedServers = 0;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CServerList::~CServerList()
{
// delete m_pQuery;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CServerList::RunFrame()
{
for(int i=0;i<m_Servers.Count();i++) {
m_Servers[i]->RunFrame();
}
QueryFrame();
}
//-----------------------------------------------------------------------------
// Purpose: gets a server from the list by id, range [0, ServerCount)
//-----------------------------------------------------------------------------
serveritem_t &CServerList::GetServer(unsigned int serverID)
{
if (m_Servers.IsValidIndex(serverID))
{
return m_Servers[serverID]->GetServer();
}
// return a dummy
static serveritem_t dummyServer;
memset(&dummyServer, 0, sizeof(dummyServer));
return dummyServer;
}
//-----------------------------------------------------------------------------
// Purpose: returns the number of servers
//-----------------------------------------------------------------------------
int CServerList::ServerCount()
{
return m_Servers.Count();
}
//-----------------------------------------------------------------------------
// Purpose: Returns the number of servers not yet pinged
//-----------------------------------------------------------------------------
int CServerList::RefreshListRemaining()
{
return m_RefreshList.Count();
}
//-----------------------------------------------------------------------------
// Purpose: returns true if the server list is still in the process of talking to servers
//-----------------------------------------------------------------------------
bool CServerList::IsRefreshing()
{
return m_bQuerying;
}
//-----------------------------------------------------------------------------
// Purpose: adds a new server to the list
//-----------------------------------------------------------------------------
unsigned int CServerList::AddNewServer(serveritem_t &server)
{
unsigned int serverID = m_Servers.AddToTail(new CServerInfo(this ,server));
m_Servers[serverID]->serverID = serverID;
return serverID;
}
//-----------------------------------------------------------------------------
// Purpose: Clears all servers from the list
//-----------------------------------------------------------------------------
void CServerList::Clear()
{
StopRefresh();
m_Servers.RemoveAll();
}
//-----------------------------------------------------------------------------
// Purpose: stops all refreshing
//-----------------------------------------------------------------------------
void CServerList::StopRefresh()
{
// Reset query context
m_Queries.RemoveAll();
// reset server received states
int count = ServerCount();
for (int i = 0; i < count; i++)
{
m_Servers[i]->received = 0;
}
m_RefreshList.RemoveAll();
// up the serial number so previous results don't interfere
m_iUpdateSerialNumber++;
m_nInvalidServers = 0;
m_nRefreshedServers = 0;
m_bQuerying = false;
m_nMaxRampUp = m_nRampUpSpeed;
}
//-----------------------------------------------------------------------------
// Purpose: marks a server to be refreshed
//-----------------------------------------------------------------------------
void CServerList::AddServerToRefreshList(unsigned int serverID)
{
if (!m_Servers.IsValidIndex(serverID))
return;
serveritem_t &server = m_Servers[serverID]->GetServer();
server.received = NONE;
m_RefreshList.AddToTail(serverID);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CServerList::StartRefresh()
{
if (m_RefreshList.Count() > 0)
{
m_bQuerying = true;
}
}
void CServerList::ServerResponded()
{
for(int i=0;i<m_Servers.Count();i++) {
if ( m_Servers[i]->Refreshed() ) {
serveritem_t &server = m_Servers[i]->GetServer();
// copy in data necessary for filters
// add to ping times list
server.pings[0] = server.pings[1];
server.pings[1] = server.pings[2];
server.pings[2] = server.ping;
// calculate ping
int ping = CalculateAveragePing(server);
// make sure the ping changes each time so the user can see the server has updated
if (server.ping == ping && ping>0)
{
ping--;
}
server.ping = ping;
server.received = INFO_RECEIVED;
netadr_t adr;
adr.ip[0] = server.ip[0];
adr.ip[1] = server.ip[1];
adr.ip[2] = server.ip[2];
adr.ip[3] = server.ip[3];
adr.port = (server.port & 0xff) << 8 | (server.port & 0xff00) >> 8;
adr.type = NA_IP;
query_t finder;
finder.addr = adr;
m_Queries.Remove(finder);
// notify the UI of the new server info
m_pResponseTarget->ServerResponded(server);
}
}
}
//-----------------------------------------------------------------------------
// Purpose: called when a server response has timed out
//-----------------------------------------------------------------------------
void CServerList::ServerFailedToRespond()
{
}
//-----------------------------------------------------------------------------
// Purpose: recalculates a servers ping, from the last few ping times
//-----------------------------------------------------------------------------
int CServerList::CalculateAveragePing(serveritem_t &server)
{
if (server.pings[0])
{
// three pings, throw away any the most extreme and average the other two
int middlePing = 0, lowPing = 1, highPing = 2;
if (server.pings[0] < server.pings[1])
{
if (server.pings[0] > server.pings[2])
{
lowPing = 2;
middlePing = 0;
highPing = 1;
}
else if (server.pings[1] < server.pings[2])
{
lowPing = 0;
middlePing = 1;
highPing = 2;
}
else
{
lowPing = 0;
middlePing = 2;
highPing = 1;
}
}
else
{
if (server.pings[1] > server.pings[2])
{
lowPing = 2;
middlePing = 1;
highPing = 0;
}
else if (server.pings[0] < server.pings[2])
{
lowPing = 1;
middlePing = 0;
highPing = 2;
}
else
{
lowPing = 1;
middlePing = 2;
highPing = 0;
}
}
// we have the middle ping, see which it's closest to
if ((server.pings[middlePing] - server.pings[lowPing]) < (server.pings[highPing] - server.pings[middlePing]))
{
return (server.pings[middlePing] + server.pings[lowPing]) / 2;
}
else
{
return (server.pings[middlePing] + server.pings[highPing]) / 2;
}
}
else if (server.pings[1])
{
// two pings received, average them
return (server.pings[1] + server.pings[2]) / 2;
}
else
{
// only one ping received so far, use that
return server.pings[2];
}
}
//-----------------------------------------------------------------------------
// Purpose: Called every frame to check queries
//-----------------------------------------------------------------------------
void CServerList::QueryFrame()
{
if (!m_bQuerying)
return;
float curtime = CSocket::GetClock();
// walk the query list, looking for any server timeouts
unsigned short idx = m_Queries.FirstInorder();
while (m_Queries.IsValidIndex(idx))
{
query_t &query = m_Queries[idx];
if ((curtime - query.sendTime) > 1.2f)
{
// server has timed out
serveritem_t &item = m_Servers[query.serverID]->GetServer();
// mark the server
item.pings[0] = item.pings[1];
item.pings[1] = item.pings[2];
item.pings[2] = 1200;
item.ping = CalculateAveragePing(item);
if (!item.hadSuccessfulResponse)
{
// remove the server if it has never responded before
item.doNotRefresh = true;
m_nInvalidServers++;
}
// respond to the game list notifying of the lack of response
m_pResponseTarget->ServerFailedToRespond(item);
item.received = false;
// get the next server now, since we're about to delete it from query list
unsigned short nextidx = m_Queries.NextInorder(idx);
// delete the query
m_Queries.RemoveAt(idx);
// move to next item
idx = nextidx;
}
else
{
// still waiting for server result
idx = m_Queries.NextInorder(idx);
}
}
// increment the number of sockets to use
m_nMaxRampUp = min(m_nMaxActive, m_nMaxRampUp + m_nRampUpSpeed);
// see if we should send more queries
while (m_RefreshList.Count() > 0 && (int)m_Queries.Count() < m_nMaxRampUp)
{
// get the first item from the list to refresh
int currentServer = m_RefreshList[0];
if (!m_Servers.IsValidIndex(currentServer))
break;
serveritem_t &item = m_Servers[currentServer]->GetServer();
item.time = curtime;
//QueryServer(m_pQuery, currentServer);
m_Servers[currentServer]->Query();
query_t query;
netadr_t adr;
adr.ip[0] = item.ip[0];
adr.ip[1] = item.ip[1];
adr.ip[2] = item.ip[2];
adr.ip[3] = item.ip[3];
adr.port = (item.port & 0xff) << 8 | (item.port & 0xff00) >> 8;
adr.type = NA_IP;
query.addr =adr;
query.sendTime=curtime;
query.serverID=item.serverID;
m_Queries.Insert(query);
// remove the server from the refresh list
m_RefreshList.Remove((int)0);
}
// Done querying?
if (m_Queries.Count() < 1)
{
m_bQuerying = false;
m_pResponseTarget->RefreshComplete();
// up the serial number, so that we ignore any late results
m_iUpdateSerialNumber++;
}
}

View File

@ -0,0 +1,112 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef SERVERLIST_H
#define SERVERLIST_H
#ifdef _WIN32
#pragma once
#endif
#include "server.h"
#include "netadr.h"
#include "serverinfo.h"
#include "iresponse.h"
#include "utlrbtree.h"
class CSocket;
class IServerRefreshResponse;
// holds a single query - definition needs to be public
struct query_t
{
netadr_t addr;
int serverID;
float sendTime;
};
//-----------------------------------------------------------------------------
// Purpose: Handles a list of servers, and can refresh them
//-----------------------------------------------------------------------------
class CServerList: public IResponse
{
public:
CServerList(IServerRefreshResponse *gameList);
~CServerList();
// Handles a frame of networking
void RunFrame();
// gets a server from the list by id, range [0, ServerCount)
serveritem_t &GetServer(unsigned int serverID);
// returns the number of servers
int ServerCount();
// adds a new server to the list, returning a handle to the server
unsigned int AddNewServer(serveritem_t &server);
// starts a refresh
void StartRefresh();
// stops all refreshing
void StopRefresh();
// clears all servers from the list
void Clear();
// marks a server to be refreshed
void AddServerToRefreshList(unsigned int serverID);
// returns true if servers are currently being refreshed
bool IsRefreshing();
// returns the number of servers not yet pinged
int RefreshListRemaining();
// implementation of IRconResponse interface
// called when the server has successfully responded to an info command
virtual void ServerResponded();
// called when a server response has timed out
virtual void ServerFailedToRespond();
private:
// Run query logic for this frame
void QueryFrame();
// recalculates a servers ping, from the last few ping times
int CalculateAveragePing(serveritem_t &server);
IServerRefreshResponse *m_pResponseTarget;
enum
{
MAX_QUERY_SOCKETS = 255,
};
// holds the list of all the currently active queries
CUtlRBTree<query_t, unsigned short> m_Queries;
// list of all known servers
CUtlVector<CServerInfo *> m_Servers;
// list of servers to be refreshed, in order... this would be more optimal as a queue
CUtlVector<int> m_RefreshList;
int m_iUpdateSerialNumber; // serial number of current update so we don't get results overlapping between different server list updates
bool m_bQuerying; // Is refreshing taking place?
int m_nMaxActive; // Max # of simultaneous sockets to use for querying
int m_nMaxRampUp; // increasing number of sockets to use
int m_nRampUpSpeed; // amount to ramp up each frame
int m_nInvalidServers; // number of servers marked as 'no not refresh'
int m_nRefreshedServers; // count of servers refreshed
};
#endif // SERVERLIST_H

View File

@ -0,0 +1,115 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "ServerListCompare.h"
#include "server.h"
#include "serverpage.h"
#include <VGUI_ListPanel.h>
#include <VGUI_KeyValues.h>
//-----------------------------------------------------------------------------
// Purpose: List password column sort function
//-----------------------------------------------------------------------------
int __cdecl PasswordCompare(vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 )
{
serveritem_t &s1 = CServerPage::GetInstance()->GetServer(item1.userData);
serveritem_t &s2 = CServerPage::GetInstance()->GetServer(item2.userData);
if (s1.password < s2.password)
return 1;
else if (s1.password > s2.password)
return -1;
return 0;
}
//-----------------------------------------------------------------------------
// Purpose: Ping comparison function
//-----------------------------------------------------------------------------
int __cdecl PingCompare(vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 )
{
serveritem_t &s1 = CServerPage::GetInstance()->GetServer(item1.userData);
serveritem_t &s2 = CServerPage::GetInstance()->GetServer(item2.userData);
int ping1 = s1.ping;
int ping2 = s2.ping;
if ( ping1 < ping2 )
return -1;
else if ( ping1 > ping2 )
return 1;
return 0;
}
//-----------------------------------------------------------------------------
// Purpose: Map comparison function
//-----------------------------------------------------------------------------
int __cdecl MapCompare(vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 )
{
serveritem_t &s1 = CServerPage::GetInstance()->GetServer(item1.userData);
serveritem_t &s2 = CServerPage::GetInstance()->GetServer(item2.userData);
return stricmp(s1.map, s2.map);
}
//-----------------------------------------------------------------------------
// Purpose: Game dir comparison function
//-----------------------------------------------------------------------------
int __cdecl GameCompare(vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 )
{
serveritem_t &s1 = CServerPage::GetInstance()->GetServer(item1.userData);
serveritem_t &s2 = CServerPage::GetInstance()->GetServer(item2.userData);
// make sure we haven't added the same server to the list twice
assert(p1->userData != p2->userData);
return stricmp(s1.gameDescription, s2.gameDescription);
}
//-----------------------------------------------------------------------------
// Purpose: Server name comparison function
//-----------------------------------------------------------------------------
int __cdecl ServerNameCompare(vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 )
{
serveritem_t &s1 = CServerPage::GetInstance()->GetServer(item1.userData);
serveritem_t &s2 = CServerPage::GetInstance()->GetServer(item2.userData);
return stricmp(s1.name, s2.name);
}
//-----------------------------------------------------------------------------
// Purpose: Player number comparison function
//-----------------------------------------------------------------------------
int __cdecl PlayersCompare(vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 )
{
serveritem_t &s1 = CServerPage::GetInstance()->GetServer(item1.userData);
serveritem_t &s2 = CServerPage::GetInstance()->GetServer(item2.userData);
int s1p = s1.players;
int s1m = s1.maxPlayers;
int s2p = s2.players;
int s2m = s2.maxPlayers;
// compare number of players
if (s1p > s2p)
return -1;
if (s1p < s2p)
return 1;
// compare max players if number of current players is equal
if (s1m > s2m)
return -1;
if (s1m < s2m)
return 1;
return 0;
}

View File

@ -0,0 +1,22 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef SERVERLISTCOMPARE_H
#define SERVERLISTCOMPARE_H
#ifdef _WIN32
#pragma once
#endif
// these functions are common to most server lists in sorts
int __cdecl PasswordCompare(vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 );
int __cdecl PingCompare(vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 );
int __cdecl PlayersCompare(vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 );
int __cdecl MapCompare(vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 );
int __cdecl GameCompare(vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 );
int __cdecl ServerNameCompare(vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 );
#endif // SERVERLISTCOMPARE_H

View File

@ -0,0 +1,150 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
/*
** The copyright to the contents herein is the property of Valve, L.L.C.
** The contents may be used and/or copied only with the written permission of
** Valve, L.L.C., or in accordance with the terms and conditions stipulated in
** the agreement/contract under which the contents have been supplied.
**
*******************************************************************************
**
** Contents:
**
** TokenLine.cpp: implementation of the TokenLine class.
**
******************************************************************************/
#include "TokenLine.h"
#include <string.h>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
TokenLine::~TokenLine()
{
}
bool TokenLine::SetLine(const char * newLine)
{
m_tokenNumber = 0;
if (!newLine || ( strlen(newLine) >= (MAX_LINE_CHARS-1) ) )
{
memset( m_fullLine, 0, MAX_LINE_CHARS );
memset( m_tokenBuffer, 0, MAX_LINE_CHARS );
return false;
}
strncpy( m_fullLine, newLine, MAX_LINE_CHARS-1 );
m_fullLine[ MAX_LINE_CHARS-1 ] = '\0';
strncpy( m_tokenBuffer, newLine, MAX_LINE_CHARS-1 );
m_tokenBuffer[ MAX_LINE_CHARS-1 ] = '\0';
// parse tokens
char * charPointer = m_tokenBuffer;
while (*charPointer && (m_tokenNumber < MAX_LINE_TOKENS))
{
while (*charPointer && ((*charPointer <= 32) || (*charPointer > 126)))
charPointer++;
if (*charPointer)
{
m_token[m_tokenNumber] = charPointer;
// special treatment for quotes
if (*charPointer == '\"')
{
charPointer++;
m_token[m_tokenNumber] = charPointer;
while (*charPointer && (*charPointer != '\"') )
charPointer++;
}
else
{
m_token[m_tokenNumber] = charPointer;
while (*charPointer && ((*charPointer > 32) && (*charPointer <= 126)))
charPointer++;
}
m_tokenNumber++;
if (*charPointer)
{
*charPointer=0;
charPointer++;
}
}
}
return (m_tokenNumber != MAX_LINE_TOKENS);
}
char * TokenLine::GetLine()
{
return m_fullLine;
}
char * TokenLine::GetToken(int i)
{
if (i >= m_tokenNumber)
return NULL;
return m_token[i];
}
// if the given parm is not present return NULL
// otherwise return the address of the following token, or an empty string
char* TokenLine::CheckToken(char * parm)
{
for (int i = 0 ; i < m_tokenNumber; i ++)
{
if (!m_token[i])
continue;
if ( !strcmp (parm,m_token[i]) )
{
char * ret = m_token[i+1];
// if this token doesn't exist, since index i was the last
// return an empty string
if ( (i+1) == m_tokenNumber ) ret = "";
return ret;
}
}
return NULL;
}
int TokenLine::CountToken()
{
int c = 0;
for (int i = 0 ; i < m_tokenNumber; i ++)
{
if (m_token[i])
c++;
}
return c;
}
char* TokenLine::GetRestOfLine(int i)
{
if (i >= m_tokenNumber)
return NULL;
return m_fullLine + (m_token[i] - m_tokenBuffer);
}
TokenLine::TokenLine(char * string)
{
SetLine(string);
}
TokenLine::TokenLine()
{
}

View File

@ -0,0 +1,36 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
// TokenLine.h: interface for the CommandLine class.
//
//////////////////////////////////////////////////////////////////////
#ifndef TOKENLINE_H
#define TOKENLINE_H
#pragma once
#define MAX_LINE_TOKENS 128
#define MAX_LINE_CHARS 2048
class TokenLine
{
public:
TokenLine();
TokenLine( char * string);
virtual ~TokenLine();
char * GetRestOfLine(int i); // returns all chars after token i
int CountToken(); // returns number of token
char * CheckToken(char * parm);// returns token after token parm or ""
char * GetToken(int i); // returns token i
char * GetLine(); // returns full line
bool SetLine (const char * newLine); // set new token line and parses it
char m_tokenBuffer[MAX_LINE_CHARS];
char m_fullLine[MAX_LINE_CHARS];
char * m_token[MAX_LINE_TOKENS];
int m_tokenNumber;
};
#endif // !defined TOKENLINE_H

View File

@ -0,0 +1,203 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "VarEditDialog.h"
#include "RemoteServer.h"
#include <stdio.h>
#include <vgui/IInput.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/ComboBox.h>
#include <vgui_controls/TextEntry.h>
#include <KeyValues.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CVarEditDialog::CVarEditDialog(vgui::Panel *parent, const char *name) : Frame(parent, name)
{
SetSize(280, 180);
SetSizeable(false);
m_pOKButton = new Button(this, "OKButton", "OK");
m_pCancelButton = new Button(this, "CancelButton", "Cancel");
m_pStringEdit = new TextEntry(this, "StringEdit");
m_pComboEdit = new ComboBox(this, "ComboEdit", 12, false);
m_pRules = NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CVarEditDialog::~CVarEditDialog()
{
// input()->ReleaseAppModalSurface();
if (m_pRules)
{
m_pRules->deleteThis();
}
}
//-----------------------------------------------------------------------------
// Purpose: Configures and shows the var edit dialog
//-----------------------------------------------------------------------------
void CVarEditDialog::Activate(vgui::Panel *actionSignalTarget, KeyValues *rules)
{
// configure
AddActionSignalTarget(actionSignalTarget);
m_pRules = rules->MakeCopy();
const char *type = m_pRules->GetString("type");
if (!stricmp(type, "enumeration"))
{
LoadControlSettings("Admin/VarEditDialog_ComboBox.res", "PLATFORM");
m_pStringEdit->SetVisible(false);
// fill in the combo box
for (KeyValues *kv = m_pRules->FindKey("list", true)->GetFirstSubKey(); kv != NULL; kv = kv->GetNextKey())
{
Assert( 0 );
// FIXME: This Assert doesn't compile
// Assert(index++ == atoi(kv->GetName()));
m_pComboEdit->AddItem(kv->GetString(), NULL);
}
// activate the current item
m_pComboEdit->ActivateItemByRow(m_pRules->GetInt("enum"));
}
else if (!stricmp(type, "customlist"))
{
LoadControlSettings("Admin/VarEditDialog_ComboBox.res", "PLATFORM");
m_pStringEdit->SetVisible(false);
// fill in the combo box
int index = 0;
const char *currentValue = m_pRules->GetString("value");
const char *parse = m_pRules->GetString("stringlist");
while (*parse)
{
// newline-seperated map list
if (*parse == '\n')
{
parse++;
continue;
}
// pull out the map name
const char *end = strstr(parse, "\n");
if (!end)
break;
char customString[64];
int nameSize = end - parse;
if (nameSize >= sizeof(customString))
{
nameSize = sizeof(customString) - 1;
}
// copy in the name
strncpy(customString, parse, nameSize);
customString[nameSize] = 0;
parse = end;
// add to dropdown
int itemID = m_pComboEdit->AddItem(customString, NULL);
index++;
// activate the current item
if (!stricmp(customString, currentValue))
{
m_pComboEdit->ActivateItem(itemID);
}
}
}
else
{
// normal string edit
LoadControlSettings("Admin/VarEditDialog_String.res", "PLATFORM");
m_pComboEdit->SetVisible(false);
m_pStringEdit->SelectAllOnFirstFocus(true);
m_pStringEdit->SetText(m_pRules->GetString("value"));
}
// set value
char title[256];
_snprintf(title, sizeof(title) - 1, "Change %s", m_pRules->GetString("name"));
SetTitle(title, false);
// bring to front
// input()->SetAppModalSurface(GetVPanel());
MoveToCenterOfScreen();
BaseClass::Activate();
}
//-----------------------------------------------------------------------------
// Purpose: button command handler
//-----------------------------------------------------------------------------
void CVarEditDialog::OnCommand(const char *command)
{
if (!stricmp(command, "OK"))
{
// change the value
ApplyChanges();
Close();
}
else if (!stricmp(command, "Cancel"))
{
Close();
}
else
{
BaseClass::OnCommand(command);
}
}
//-----------------------------------------------------------------------------
// Purpose: Applies changes
//-----------------------------------------------------------------------------
void CVarEditDialog::ApplyChanges()
{
const char *type = m_pRules->GetString("type");
if (!stricmp(type, "enumeration"))
{
// get the enumeration position from the combo box
int iVal = m_pComboEdit->GetActiveItem();
char value[32];
_snprintf(value, sizeof(value) - 1, "%d", iVal);
RemoteServer().SetValue(m_pRules->GetName(), value);
}
else if (!stricmp(type, "customlist"))
{
char value[512];
m_pComboEdit->GetText(value, sizeof(value));
RemoteServer().SetValue(m_pRules->GetName(), value);
}
else
{
// normal string
char value[512];
m_pStringEdit->GetText(value, sizeof(value));
RemoteServer().SetValue(m_pRules->GetName(), value);
}
// tell the caller the var changed
PostActionSignal(new KeyValues("VarChanged", "var", m_pRules->GetName()));
}
//-----------------------------------------------------------------------------
// Purpose: Deletes on close
//-----------------------------------------------------------------------------
void CVarEditDialog::OnClose()
{
BaseClass::OnClose();
MarkForDeletion();
}

View File

@ -0,0 +1,45 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef VAREDITDIALOG_H
#define VAREDITDIALOG_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/Frame.h>
//-----------------------------------------------------------------------------
// Purpose: Handles editing of cvars
//-----------------------------------------------------------------------------
class CVarEditDialog : public vgui::Frame
{
public:
CVarEditDialog(vgui::Panel *parent, const char *name);
~CVarEditDialog();
void Activate(vgui::Panel *actionSignalTarget, KeyValues *rules);
protected:
virtual void OnCommand(const char *command);
virtual void OnClose();
void ApplyChanges();
private:
vgui::Button *m_pOKButton;
vgui::Button *m_pCancelButton;
vgui::TextEntry *m_pStringEdit;
vgui::ComboBox *m_pComboEdit;
KeyValues *m_pRules;
typedef vgui::Frame BaseClass;
};
#endif // VAREDITDIALOG_H

View File

@ -0,0 +1,225 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "VarListPropertyPage.h"
#include "RemoteServer.h"
#include "VarEditDialog.h"
#include <KeyValues.h>
#include <vgui/KeyCode.h>
#include <vgui_controls/ListPanel.h>
#include <vgui_controls/Button.h>
#include "filesystem.h"
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CVarListPropertyPage::CVarListPropertyPage(vgui::Panel *parent, const char *name) : vgui::PropertyPage(parent, name)
{
m_pRulesList = new ListPanel(this, "RulesList");
m_pRulesList->AddColumnHeader(0, "name", "Variable", 256);
m_pRulesList->AddColumnHeader(1, "value", "Value", 256);
m_pEditButton = new Button(this, "EditButton", "Edit...");
m_pEditButton->SetCommand(new KeyValues("EditVariable"));
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CVarListPropertyPage::~CVarListPropertyPage()
{
// remove from callback list
RemoteServer().RemoveServerDataResponseTarget(this);
}
//-----------------------------------------------------------------------------
// Purpose: loads a list of variables from the file
//-----------------------------------------------------------------------------
bool CVarListPropertyPage::LoadVarList(const char *varfile)
{
bool bSuccess = false;
// clear the current list
m_pRulesList->DeleteAllItems();
// load list from file
KeyValues *dat = new KeyValues("VarList");
if (dat->LoadFromFile( g_pFullFileSystem, varfile, NULL))
{
// enter into list
for (KeyValues *rule = dat->GetFirstSubKey(); rule != NULL; rule = rule->GetNextKey())
{
m_pRulesList->AddItem(rule, 0, false, false);
}
bSuccess = true;
}
dat->deleteThis();
return bSuccess;
}
//-----------------------------------------------------------------------------
// Purpose: configures layout
//-----------------------------------------------------------------------------
void CVarListPropertyPage::PerformLayout()
{
BaseClass::PerformLayout();
OnItemSelected();
}
//-----------------------------------------------------------------------------
// Purpose: Handles edit button press
//-----------------------------------------------------------------------------
void CVarListPropertyPage::EditVariable()
{
// get rule from the list
int itemID = m_pRulesList->GetSelectedItem(0);
KeyValues *rule = m_pRulesList->GetItem(itemID);
if (!rule)
return;
OnEditVariable(rule);
}
//-----------------------------------------------------------------------------
// Purpose: Edits var
//-----------------------------------------------------------------------------
void CVarListPropertyPage::OnEditVariable(KeyValues *rule)
{
// open an edit box appropriate
CVarEditDialog *box = new CVarEditDialog(this, "VarEditDialog");
box->Activate(this, rule);
}
//-----------------------------------------------------------------------------
// Purpose: refreshes all the values of cvars in the list
//-----------------------------------------------------------------------------
void CVarListPropertyPage::RefreshVarList()
{
// iterate the vars
for (int i = 0; i < m_pRulesList->GetItemCount(); i++)
{
KeyValues *row = m_pRulesList->GetItem(i);
if (!row)
continue;
// request the info from the server on each one of them
RemoteServer().RequestValue(this, row->GetName());
}
RemoteServer().ProcessServerResponse();
}
//-----------------------------------------------------------------------------
// Purpose: sets the value of a variable in the list
//-----------------------------------------------------------------------------
void CVarListPropertyPage::SetVarString(const char *varName, const char *value)
{
// find the item by name
int itemID = m_pRulesList->GetItem(varName);
KeyValues *rule = m_pRulesList->GetItem(itemID);
if (!rule)
return;
// parse the rule
const char *type = rule->GetString("type");
if (!stricmp(type, "enumeration"))
{
// look up the value in the enumeration
int iValue = atoi(value);
const char *result = rule->FindKey("list", true)->GetString(value, "");
rule->SetString("value", result);
rule->SetInt("enum", iValue);
}
else
{
// no special type, treat it as a string
rule->SetString("value", value);
}
m_pRulesList->ApplyItemChanges(itemID);
}
//-----------------------------------------------------------------------------
// Purpose: Sets a custom string list
//-----------------------------------------------------------------------------
void CVarListPropertyPage::SetCustomStringList(const char *varName, const char *stringList)
{
// find the item by name
int itemID = m_pRulesList->GetItem(varName);
KeyValues *rule = m_pRulesList->GetItem(itemID);
if (!rule)
return;
rule->SetString("stringlist", stringList);
}
//-----------------------------------------------------------------------------
// Purpose: gets back the value of a variable
//-----------------------------------------------------------------------------
const char *CVarListPropertyPage::GetVarString(const char *varName)
{
int itemID = m_pRulesList->GetItem(varName);
KeyValues *rule = m_pRulesList->GetItem(itemID);
if (!rule)
return "";
return rule->GetString("value");
}
//-----------------------------------------------------------------------------
// Purpose: Causes values to refresh on the user hitting F5
//-----------------------------------------------------------------------------
void CVarListPropertyPage::OnKeyCodeTyped(KeyCode code)
{
if (code == KEY_F5)
{
OnResetData();
}
else
{
BaseClass::OnKeyCodeTyped(code);
}
}
//-----------------------------------------------------------------------------
// Purpose: Enables the edit button if any rows in the list are selected
//-----------------------------------------------------------------------------
void CVarListPropertyPage::OnItemSelected()
{
if (m_pRulesList->GetSelectedItemsCount() > 0)
{
m_pEditButton->SetEnabled(true);
}
else
{
m_pEditButton->SetEnabled(false);
}
}
//-----------------------------------------------------------------------------
// Purpose: Called when a var gets edited
//-----------------------------------------------------------------------------
void CVarListPropertyPage::OnVarChanged(const char *var)
{
// request new value from server
RemoteServer().RequestValue(this, var);
// process the queue immediately, since if we're running a local server there will already be a reply
RemoteServer().ProcessServerResponse();
}
//-----------------------------------------------------------------------------
// Purpose: handles responses from the server
//-----------------------------------------------------------------------------
void CVarListPropertyPage::OnServerDataResponse(const char *value, const char *response)
{
SetVarString(value, response);
}

View File

@ -0,0 +1,67 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef VARLISTPROPERTYPAGE_H
#define VARLISTPROPERTYPAGE_H
#ifdef _WIN32
#pragma once
#endif
#include <KeyValues.h>
#include <vgui_controls/PropertyPage.h>
#include "utlvector.h"
#include "RemoteServer.h"
//-----------------------------------------------------------------------------
// Purpose: Property page for use in the server admin tool
// holds a list of variables and manages the editing of them
//-----------------------------------------------------------------------------
class CVarListPropertyPage : public vgui::PropertyPage, public IServerDataResponse
{
DECLARE_CLASS_SIMPLE( CVarListPropertyPage, vgui::PropertyPage );
public:
CVarListPropertyPage(vgui::Panel *parent, const char *name);
~CVarListPropertyPage();
// loads the var list description from the specified file
bool LoadVarList(const char *varfile);
// sets the value of a variable
void SetVarString(const char *varName, const char *value);
// gets back the value of a variable
const char *GetVarString(const char *varName);
// refreshes all the values of cvars in the list
virtual void RefreshVarList();
// sets a custom string list for a combobox edit
// stringList is a newline-delimited set of strings
void SetCustomStringList(const char *varName, const char *stringList);
protected:
// override to change how a variable is edited
virtual void OnEditVariable(KeyValues *rule);
// handles responses from the server
virtual void OnServerDataResponse(const char *value, const char *response);
// vgui overrides
virtual void PerformLayout();
virtual void OnKeyCodeTyped(vgui::KeyCode code);
MESSAGE_FUNC_CHARPTR( OnVarChanged, "VarChanged", var );
private:
MESSAGE_FUNC( EditVariable, "EditVariable" );
MESSAGE_FUNC( OnItemSelected, "ItemSelected" );
vgui::ListPanel *m_pRulesList;
vgui::Button *m_pEditButton;
};
#endif // VARLISTPROPERTYPAGE_H

View File

@ -0,0 +1,28 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef BAN_H
#define BAN_H
#ifdef _WIN32
#pragma once
#endif
enum Bans { ID, WONID,AUTHID,IP };
//-----------------------------------------------------------------------------
// Purpose: Data describing a single player
//-----------------------------------------------------------------------------
typedef struct
{
char name[20]; // id of the band
float time;
Bans type;
} Bans_t;
#endif // BAN_H

View File

@ -0,0 +1,241 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: defines a RCon class used to send rcon commands to remote servers
//
// $NoKeywords: $
//=============================================================================
#include "banlist.h"
#include "Iresponse.h"
#include "PlayerMsgHandler.h"
#include "Socket.h"
#include "proto_oob.h"
#include "DialogGameInfo.h"
#include "inetapi.h"
#include "TokenLine.h"
#include "dialogkickplayer.h"
extern void v_strncpy(char *dest, const char *src, int bufsize);
typedef enum
{
NONE = 0,
INFO_REQUESTED,
INFO_RECEIVED
} RCONSTATUS;
CBanList::CBanList(IResponse *target,serveritem_t &server, const char *rconPassword) {
memcpy(&m_Server, &server,sizeof(serveritem_t));
m_pResponseTarget=target;
m_bIsRefreshing=false;
m_bNewBanList=false;
m_bRconFailed=false;
m_bGotIPs = false;
v_strncpy(m_szRconPassword,rconPassword,100);
m_pRcon = new CRcon(this , server,rconPassword);
m_BanList=NULL;
}
CBanList::~CBanList() {
delete m_pRcon;
}
//-----------------------------------------------------------------------------
// Purpose: sends a status query packet to a single server
//-----------------------------------------------------------------------------
void CBanList::SendQuery()
{
// now use "rcon status" to pull the list of bans
m_pRcon->SendRcon("listid");
m_bGotIPs=false;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBanList::RunFrame()
{
if(m_pRcon)
{
m_pRcon->RunFrame();
}
}
void CBanList::ServerResponded()
{
if(m_bGotIPs == false)
{
m_BanList.RemoveAll();
const char *rconResp = m_pRcon->RconResponse();
const char *cur = strstr(rconResp,"UserID filter list:")
+ strlen("UserID filter list:");
if( (unsigned int)cur == strlen("UserID filter list:"))
// if strstr returned NULL and we added a strlen to it...
{
cur=NULL;
}
// listid format:
// UserID filter list:
// 1 23434 : 20.000 min
// and on empty it produces:
// IP filter list: empty
while(cur!=NULL)
{
TokenLine banLine;
cur++; // dodge the newline
banLine.SetLine(cur); // need to add one here, to remove the "\n"
if(banLine.CountToken() >= 4 )
{
Bans_t ban;
memset(&ban,0x0,sizeof(Bans_t));
v_strncpy(ban.name,banLine.GetToken(1),20);
sscanf(banLine.GetToken(3),"%f",&ban.time);
ban.type= ID;
m_BanList.AddToTail(ban);
}
cur=strchr(cur,'\n');
}
m_bGotIPs=true;
// now find out the list of banned ips
m_pRcon->SendRcon("listip");
}
else
{
// listip format:
// IP filter list:
//192.168. 1. 66 : 20.000 min
const char *rconResp = m_pRcon->RconResponse();
const char *cur = strstr(rconResp,"IP filter list:")
+ strlen("IP filter list:");
if( (unsigned int)cur == strlen("IP filter list:"))
// if strstr returned NULL and we added a strlen to it...
{
cur=NULL;
}
while(cur!=NULL)
{
char tmpStr[512];
Bans_t ban;
cur++; // dodge past the newline
v_strncpy(tmpStr,cur,512);
memset(&ban,0x0,sizeof(Bans_t));
if( strchr(tmpStr,':') != NULL )
{
char *time;
time = strchr(tmpStr,':')+1;
tmpStr[strchr(tmpStr,':')-tmpStr]=0;
v_strncpy(ban.name,tmpStr,20);
unsigned int i=0;
while(i<strlen(ban.name)) // strip all the white space out...
{
if( ban.name[i]==' ')
{
strcpy(&ban.name[i],&ban.name[i+1]);
}
else
{
i++;
}
}
sscanf(time,"%f",&ban.time);
ban.type= IP;
m_BanList.AddToTail(ban);
}
cur=strchr(cur,'\n');
}
m_bNewBanList=true;
m_bIsRefreshing=false;
// notify the UI of the new server info
m_pResponseTarget->ServerResponded();
}
}
void CBanList::ServerFailedToRespond()
{
m_bNewBanList=true;
m_bIsRefreshing=false;
if(m_bRconFailed==false)
{
m_bRconFailed=true;
// CDialogKickPlayer *box = new CDialogKickPlayer();
//box->addActionSignalTarget(this);
// box->Activate("","Bad Rcon Password","badrcon");
}
// m_pResponseTarget->ServerFailedToRespond();
}
void CBanList::Refresh()
{
SendQuery();
}
bool CBanList::IsRefreshing()
{
return m_bIsRefreshing;
}
serveritem_t &CBanList::GetServer()
{
return m_Server;
}
bool CBanList::NewBanList()
{
return m_bNewBanList;
}
CUtlVector<Bans_t> *CBanList::GetBanList()
{
m_bNewBanList=false;
return &m_BanList;
}
void CBanList::SetPassword(const char *newPass)
{
m_pRcon->SetPassword(newPass);
m_bRconFailed=false;
}

View File

@ -0,0 +1,68 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef BANLIST_H
#define BANLIST_H
#ifdef _WIN32
#pragma once
#endif
#include "ban.h"
#include "netadr.h"
#include "utlvector.h"
#include "playermsghandler.h"
#include "Iresponse.h"
class CSocket;
class IResponse;
class CBanList: public IResponse
{
public:
CBanList(IResponse *target,serveritem_t &server, const char *rconPassword);
~CBanList();
// send an rcon command to a server
void SendQuery();
void Refresh();
bool IsRefreshing();
serveritem_t &GetServer();
void RunFrame();
CUtlVector<Bans_t> *GetBanList();
bool NewBanList();
void ServerResponded();
// called when a server response has timed out
void ServerFailedToRespond();
void SetPassword(const char *newPass);
private:
serveritem_t m_Server;
CUtlVector<Bans_t> m_BanList;
IResponse *m_pResponseTarget;
CRcon *m_pRcon;
bool m_bIsRefreshing;
bool m_bGotIPs;
bool m_bNewBanList;
bool m_bRconFailed;
char m_szRconPassword[100];
};
#endif // BANLIST_H

View File

@ -0,0 +1,177 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: queries server for the command list, and then use QueryCommand() to see
// if the server supports this command.
//
// $NoKeywords: $
//=============================================================================
#include <ctype.h> // isspace() define
#include <string.h>
#include "CMDList.h"
#include "Iresponse.h"
#include "Socket.h"
#include "proto_oob.h"
#include "DialogGameInfo.h"
#include "inetapi.h"
#include "TokenLine.h"
#include "dialogkickplayer.h"
extern void v_strncpy(char *dest, const char *src, int bufsize);
typedef enum
{
NONE = 0,
INFO_REQUESTED,
INFO_RECEIVED
} RCONSTATUS;
typedef enum
{
FS,
PAK
} MAP_TYPES;
CCMDList::CCMDList(IResponse *target,serveritem_t &server, const char *rconPassword) {
memcpy(&m_Server, &server,sizeof(serveritem_t));
m_bGotCommands = false;
m_pResponseTarget=target;
v_strncpy(m_szRconPassword,rconPassword,100);
m_pRcon = new CRcon(this , server,rconPassword);
m_pRcon->SendRcon("cmdlist");
m_CMDList.RemoveAll();
}
CCMDList::~CCMDList() {
delete m_pRcon;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CCMDList::RunFrame()
{
if(m_pRcon)
{
m_pRcon->RunFrame();
}
}
void CCMDList::ServerResponded()
{
char store[2048];
strcpy(store, m_pRcon->RconResponse());
char *cur=store;
char *next=NULL;
char *cmd=NULL;
bool cmd_end=false;
// response format:
//Command List
//--------------
//_unloadmodule
// ...
// writeip
//--------------
//125 Total Commands
//CmdList ? for syntax
while(cur!=NULL)
{
if(next!=NULL)
{
cur++;
}
next=strchr(cur,'\n');
if(next!=NULL)
{
*next='\0';
}
if( strncmp(cur,"Command List",12) && strncmp(cur,"-------------",13)
&& strncmp(cur,"Total Commands",14) && strncmp(cur,"CmdList ? for syntax",20) )
{
char *removeWhiteSpace=cur;
while(!isspace(*removeWhiteSpace) && removeWhiteSpace<next)
{
removeWhiteSpace++;
}
*removeWhiteSpace='\0';
cmd = new char[strlen(cur)];
if(cmd)
{
strcpy(cmd,cur);
m_CMDList.AddToTail(cmd);
}
}
else if ( ! strncmp(cur,"CmdList ? for syntax",20))
{
cmd_end=true;
}
cur=next;
}
if( cmd_end )
{
m_bGotCommands = true;
m_pResponseTarget->ServerResponded();
}
}
void CCMDList::ServerFailedToRespond()
{
//m_pResponseTarget->ServerFailedToRespond();
}
serveritem_t &CCMDList::GetServer()
{
return m_Server;
}
bool CCMDList::QueryCommand(char *cmd)
{
if(!m_bGotCommands)
return false;
for(int i=0;i<m_CMDList.Count();i++)
{
char *cmd_in = m_CMDList[i];
if(!stricmp(cmd,m_CMDList[i]))
break;
}
if(i!=m_CMDList.Count())
{
return true;
}
else
return false;
}
bool CCMDList::GotCommands()
{
return m_bGotCommands;
}
void CCMDList::SetPassword(const char *newPass)
{
m_pRcon->SetPassword(newPass);
m_bGotCommands = false;
m_CMDList.RemoveAll();
m_pRcon->SendRcon("cmdlist");
}

View File

@ -0,0 +1,56 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef CMDLIST_H
#define CMDLIST_H
#ifdef _WIN32
#pragma once
#endif
#include "server.h"
#include "netadr.h"
#include "maps.h"
#include "rcon.h"
#include "utlvector.h"
#include "Iresponse.h"
class CSocket;
class IResponse;
class CCMDList: public IResponse
{
public:
CCMDList(IResponse *target,serveritem_t &server, const char *rconPassword);
~CCMDList();
serveritem_t &GetServer();
void RunFrame();
bool QueryCommand(char *cmd);
bool GotCommands();
void SetPassword(const char *newPass);
virtual void ServerResponded();
virtual void ServerFailedToRespond();
private:
serveritem_t m_Server;
CUtlVector<char *> m_CMDList;
IResponse *m_pResponseTarget;
CRcon *m_pRcon;
bool m_bGotCommands;
char m_szRconPassword[100];
};
#endif // CMDLIST_H

View File

@ -0,0 +1,66 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "LogMsgHandler.h"
#include "info.h"
#include "proto_oob.h"
#include "inetapi.h"
#include "DialogGameInfo.h"
extern void v_strncpy(char *dest, const char *src, int bufsize);
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CLogMsgHandlerDetails::CLogMsgHandlerDetails(IResponse *baseobject, HANDLERTYPE type, void *typeinfo )
: CMsgHandler( type, typeinfo )
{
m_pLogList = baseobject;
m_bNewMessage=false;
}
CLogMsgHandlerDetails::~CLogMsgHandlerDetails()
{
}
//-------------------------------------------------------------------------
// Purpose: Process cracked message
//-----------------------------------------------------------------------------
bool CLogMsgHandlerDetails::Process( netadr_t *from, CMsgBuffer *msg )
{
m_bNewMessage=true;
v_strncpy(message,msg->ReadString(),512);
message[strlen(message)-1]='\n';
message[strlen(message)]='\0';
// now tell the UI we have this new message
m_pLogList->ServerResponded();
return true;
}
//-------------------------------------------------------------------------
// Purpose: returns if a new message is waiting
//-----------------------------------------------------------------------------
bool CLogMsgHandlerDetails::NewMessage()
{
bool val=m_bNewMessage;
m_bNewMessage=false;
return val;
}
//-------------------------------------------------------------------------
// Purpose: returns the text contained in the last message recieved
//-----------------------------------------------------------------------------
const char *CLogMsgHandlerDetails::GetBuf()
{
return message;
}

View File

@ -0,0 +1,45 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef LOGMSGHANDLER_H
#define LOGMSGHANDLER_H
#ifdef _WIN32
#pragma once
#endif
#include "Socket.h"
#include "utlvector.h"
#include "player.h"
#include "rcon.h"
//-----------------------------------------------------------------------------
// Purpose: Socket handler for pinging internet servers
//-----------------------------------------------------------------------------
class CLogMsgHandlerDetails : public CMsgHandler
{
public:
CLogMsgHandlerDetails(IResponse *baseobject, HANDLERTYPE type, void *typeinfo = NULL);
~CLogMsgHandlerDetails();
virtual bool Process(netadr_t *from, CMsgBuffer *msg);
// indicates if a new message has arrived
bool NewMessage();
// returns the text of the last message recieved
const char *GetBuf();
private:
IResponse *m_pLogList;
bool m_bNewMessage;
char message[512];
};
#endif // LOGMSGHANDLER_H

View File

@ -0,0 +1,26 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef MAPS_H
#define MAPS_H
#ifdef _WIN32
#pragma once
#endif
//-----------------------------------------------------------------------------
// Purpose: Data describing a single map
//-----------------------------------------------------------------------------
typedef struct
{
char name[100];
int type;
} Maps_t;
#endif // MAPS_H

View File

@ -0,0 +1,230 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: defines a RCon class used to send rcon commands to remote servers
//
// $NoKeywords: $
//=============================================================================
#include "mapslist.h"
#include "Iresponse.h"
#include "Socket.h"
#include "proto_oob.h"
#include "DialogGameInfo.h"
#include "inetapi.h"
#include "TokenLine.h"
#include "dialogkickplayer.h"
#include <string.h>
extern void v_strncpy(char *dest, const char *src, int bufsize);
typedef enum
{
NONE = 0,
INFO_REQUESTED,
INFO_RECEIVED
} RCONSTATUS;
typedef enum
{
FS,
PAK
} MAP_TYPES;
CMapsList::CMapsList(IResponse *target,serveritem_t &server, const char *rconPassword,const char *mod) {
memcpy(&m_Server, &server,sizeof(serveritem_t));
m_pResponseTarget=target;
if(strcmp(mod,"valve") )
{
v_strncpy(m_sMod,mod,64);
}
else
{
m_sMod[0]=0; // its the "valve" default mod, list all maps
}
m_bIsRefreshing=false;
m_bNewMapsList=false;
m_bRconFailed=false;
v_strncpy(m_szRconPassword,rconPassword,100);
m_pRcon = new CRcon(this , server,rconPassword);
}
CMapsList::~CMapsList() {
delete m_pRcon;
}
//-----------------------------------------------------------------------------
// Purpose: sends a status query packet to a single server
//-----------------------------------------------------------------------------
void CMapsList::SendQuery()
{
m_bIsRefreshing=true;
m_pRcon->SendRcon("maps *");
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMapsList::RunFrame()
{
if(m_pRcon)
{
m_pRcon->RunFrame();
}
}
void CMapsList::ServerResponded()
{
char store[2048];
strcpy(store, m_pRcon->RconResponse());
char *cur=store;
char *next=NULL;
int i=0,k=0;
bool checkDir=false;
// maps format:
// Dir: valve
//-------------
//(fs) rapidcore.bsp
//(fs) frenzy.bsp
//(fs) crossfire.bsp
//
//Dir: valve
//-------------
//(pak) boot_camp.bsp
//(pak) bounce.bsp
m_MapsList.RemoveAll();
char check[21];
_snprintf(check,21,"%s/",m_sMod);
if(strstr(store,check))
{ // if the name of the mod dir is in the return list its old style format
checkDir=true;
}
while(cur!=NULL)
{
cur++;
next=strchr(cur,'\n');
if(next!=NULL)
{
*next='\0';
}
if( strncmp(cur,"Dir:",4) && strncmp(cur,"-------------",13) )
{
TokenLine mapsLine;
mapsLine.SetLine(cur);
if(mapsLine.CountToken() >= 2 )
{
char tmpMap[100];
v_strncpy(tmpMap,mapsLine.GetToken(1),100); // type
char *end = strstr(tmpMap,".bsp"); // cull the .bsp
if(end != NULL)
{
*end='\0';
}
if(checkDir==true && strstr(tmpMap,m_sMod)==NULL )
// if the map name doesn't have the mod dir in it
// and its not running the "valve" mod continue
{
cur=next;
continue;
}
if ( strchr(tmpMap,'/') ) // remove the directory part of the map name
{
strcpy(tmpMap,strrchr(tmpMap,'/')+1);
}
for(k=0;k<m_MapsList.Count();k++) // now check it doesn't already exist inside the map list...
{
if(!strncmp(tmpMap,m_MapsList[k].name,strlen(tmpMap)) )
{
break;
}
}
if(k==m_MapsList.Count() // the map wasn't found
&& !(tmpMap[0]=='c' && (tmpMap[1]>='1' && tmpMap[1]<='5')) // a heuristic to remove single player maps
&& !(tmpMap[0]=='t' && tmpMap[1]=='0') ) // from the list
{
Maps_t map;
// this map wasn't found already
v_strncpy(map.name,tmpMap,strlen(tmpMap)+1);
if( !strcmp("(fs)",mapsLine.GetToken(0)) )
{ // name
map.type=FS;
}
else
{
map.type=PAK;
}
m_MapsList.AddToTail(map);
i++;
} // if k == Count
} // CountToken
} // if not a Dir: or "----------"
cur=next;
}
m_bNewMapsList=true;
m_bIsRefreshing=false;
// notify the UI of the new server info
m_pResponseTarget->ServerResponded();
}
void CMapsList::ServerFailedToRespond()
{
// rcon failed
//m_pResponseTarget->ServerFailedToRespond();
}
void CMapsList::Refresh()
{
SendQuery();
}
bool CMapsList::IsRefreshing()
{
return m_bIsRefreshing;
}
serveritem_t &CMapsList::GetServer()
{
return m_Server;
}
bool CMapsList::NewMapsList()
{
return m_bNewMapsList;
}
CUtlVector<Maps_t> *CMapsList::GetMapsList()
{
m_bNewMapsList=false;
return &m_MapsList;
}
void CMapsList::SetPassword(const char *newPass)
{
m_pRcon->SetPassword(newPass);
m_bRconFailed=false;
}

View File

@ -0,0 +1,70 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef MAPSLIST_H
#define MAPSLIST_H
#ifdef _WIN32
#pragma once
#endif
#include "server.h"
#include "netadr.h"
#include "maps.h"
#include "rcon.h"
#include "utlvector.h"
#include "Iresponse.h"
class CSocket;
class IResponse;
class CMapsList: public IResponse
{
public:
CMapsList(IResponse *target,serveritem_t &server, const char *rconPassword,const char *mod);
~CMapsList();
// send an rcon command to a server
void SendQuery();
void Refresh();
bool IsRefreshing();
serveritem_t &GetServer();
void RunFrame();
void UpdateServer();
CUtlVector<Maps_t> *GetMapsList();
bool NewMapsList();
void ServerResponded();
// called when a server response has timed out
void ServerFailedToRespond();
void SetPassword(const char *newPass);
private:
serveritem_t m_Server;
CUtlVector<Maps_t> m_MapsList;
IResponse *m_pResponseTarget;
CRcon *m_pRcon;
char m_sMod[64];
bool m_bIsRefreshing;
bool m_bNewMapsList;
bool m_bRconFailed;
char m_szRconPassword[100];
};
#endif // MAPSLIST_H

View File

@ -0,0 +1,227 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: defines a RCon class used to send rcon commands to remote servers
//
// $NoKeywords: $
//=============================================================================
#include "playerlist.h"
#include "Iresponse.h"
#include "PlayerMsgHandler.h"
#include "Socket.h"
#include "proto_oob.h"
#include "DialogGameInfo.h"
#include "inetapi.h"
#include "TokenLine.h"
#include "dialogkickplayer.h"
extern void v_strncpy(char *dest, const char *src, int bufsize);
typedef enum
{
NONE = 0,
INFO_REQUESTED,
INFO_RECEIVED
} RCONSTATUS;
CPlayerList::CPlayerList(IResponse *target,serveritem_t &server, const char *rconPassword) {
memcpy(&m_Server, &server,sizeof(serveritem_t));
m_pResponseTarget=target;
m_bIsRefreshing=false;
m_bNewPlayerList=false;
m_bRconFailed=false;
v_strncpy(m_szRconPassword,rconPassword,100);
m_pRcon = new CRcon(this , server,rconPassword);
m_PlayerList=NULL;
m_pPlayerInfoMsg=NULL;
m_pQuery = new CSocket("internet player query", -1);
}
CPlayerList::~CPlayerList() {
delete m_pQuery;
delete m_pRcon;
}
//-----------------------------------------------------------------------------
// Purpose: sends a status query packet to a single server
//-----------------------------------------------------------------------------
void CPlayerList::SendQuery()
{
CMsgBuffer *buffer = m_pQuery->GetSendBuffer();
assert( buffer );
if ( !buffer )
{
return;
}
int bytecode = S2A_PLAYER;
if ( m_pPlayerInfoMsg != NULL )
{
delete m_pPlayerInfoMsg;
}
m_pPlayerInfoMsg=new CPlayerMsgHandlerDetails(this, &m_PlayerList,CMsgHandler::MSGHANDLER_ALL, &bytecode);
m_pQuery->AddMessageHandler(m_pPlayerInfoMsg);
m_bIsRefreshing=true;
netadr_t adr;
adr.ip[0] = m_Server.ip[0];
adr.ip[1] = m_Server.ip[1];
adr.ip[2] = m_Server.ip[2];
adr.ip[3] = m_Server.ip[3];
adr.port = (m_Server.port & 0xff) << 8 | (m_Server.port & 0xff00) >> 8;
adr.type = NA_IP;
// Set state
m_Server.received = (int)INFO_REQUESTED;
// Create query message
buffer->Clear();
// Write control sequence
buffer->WriteLong(0xffffffff);
// Write query string
buffer->WriteString("players");
// Sendmessage
m_pQuery->SendMessage( &adr );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CPlayerList::RunFrame()
{
if (m_pQuery && m_bIsRefreshing)
{
m_pQuery->Frame();
}
if(m_pRcon)
{
m_pRcon->RunFrame();
}
}
void CPlayerList::ServerResponded()
{
const char *rconResp = m_pRcon->RconResponse();
const char *cur = strstr(rconResp,"name userid uniqueid frag time ping loss adr\n")
+ strlen("name userid uniqueid frag time ping loss adr\n");
// status format:
// # name userid uniqueid frag time ping loss adr
// # 1 "Player" 1 4294967295 0 30:56 22 0 192.168.3.64:27005
for(int i=0;i<m_PlayerList.Count();i++)
{
if(cur!=NULL)
{
TokenLine playerLine;
playerLine.SetLine(cur);
if(playerLine.CountToken() >= 9 )
{
// playerLine.GetToken(1); // count
// playerLine.GetToken(2); // player name
// char *player= playerLine.GetToken(2);
m_PlayerList[i].userid=atoi(playerLine.GetToken(3)); // userid
v_strncpy(m_PlayerList[i].authid,playerLine.GetToken(4),20); // authid
//playerLine.GetToken(5); // frag
// playerLine.GetToken(6); // time
m_PlayerList[i].ping=atoi(playerLine.GetToken(7)); //ping
m_PlayerList[i].loss=atoi(playerLine.GetToken(8)); // loss
// playerLine.GetToken(9); // adr
}
cur=strchr(cur,'\n')+1;
}
}
m_bNewPlayerList=true;
m_bIsRefreshing=false;
// notify the UI of the new server info
m_pResponseTarget->ServerResponded();
}
void CPlayerList::ServerFailedToRespond()
{
m_bNewPlayerList=true;
m_bIsRefreshing=false;
if(m_bRconFailed==false)
{
m_bRconFailed=true;
// CDialogKickPlayer *box = new CDialogKickPlayer();
//box->addActionSignalTarget(this);
// box->Activate("","Bad Rcon Password","badrcon");
}
// rcon failed BUT we still have some valid data :)
m_pResponseTarget->ServerResponded();
}
void CPlayerList::UpdateServer()
{
m_pQuery->RemoveMessageHandler(m_pPlayerInfoMsg);
// you CANNOT delete this handler because we are inside of it at the moment... (yes, this was an ugly bug)
// delete m_pPlayerInfoMsg;
// now use "rcon status" to pull extra info about the players
m_pRcon->SendRcon("status");
}
void CPlayerList::Refresh()
{
SendQuery();
}
bool CPlayerList::IsRefreshing()
{
return m_bIsRefreshing;
}
serveritem_t &CPlayerList::GetServer()
{
return m_Server;
}
bool CPlayerList::NewPlayerList()
{
return m_bNewPlayerList;
}
CUtlVector<Players_t> *CPlayerList::GetPlayerList()
{
m_bNewPlayerList=false;
return &m_PlayerList;
}
void CPlayerList::SetPassword(const char *newPass)
{
m_pRcon->SetPassword(newPass);
m_bRconFailed=false;
}

View File

@ -0,0 +1,70 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef PLAYERLIST_H
#define PLAYERLIST_H
#ifdef _WIN32
#pragma once
#endif
#include "server.h"
#include "netadr.h"
#include "utlvector.h"
#include "playermsghandler.h"
#include "Iresponse.h"
class CSocket;
class IResponse;
class CPlayerList: public IResponse
{
public:
CPlayerList(IResponse *target,serveritem_t &server, const char *rconPassword);
~CPlayerList();
// send an rcon command to a server
void SendQuery();
void Refresh();
bool IsRefreshing();
serveritem_t &GetServer();
void RunFrame();
void UpdateServer();
CUtlVector<Players_t> *GetPlayerList();
bool NewPlayerList();
void ServerResponded();
// called when a server response has timed out
void ServerFailedToRespond();
void SetPassword(const char *newPass);
private:
serveritem_t m_Server;
CSocket *m_pQuery; // Game server query socket
CUtlVector<Players_t> m_PlayerList;
IResponse *m_pResponseTarget;
CRcon *m_pRcon;
CPlayerMsgHandlerDetails *m_pPlayerInfoMsg;
bool m_bIsRefreshing;
bool m_bNewPlayerList;
bool m_bRconFailed;
char m_szRconPassword[100];
};
#endif // PLAYERLIST_H

View File

@ -0,0 +1,93 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "PlayerMsgHandler.h"
#include "playerlist.h"
#include "info.h"
#include "proto_oob.h"
#include "inetapi.h"
#include "DialogGameInfo.h"
extern void v_strncpy(char *dest, const char *src, int bufsize);
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CPlayerMsgHandlerDetails::CPlayerMsgHandlerDetails( CPlayerList *baseobject, CUtlVector<Players_t> *players,HANDLERTYPE type, void *typeinfo /*= NULL*/ )
: CMsgHandler( type, typeinfo )
{
m_pPlayerList = baseobject;
m_pPlayerNames=players;
}
CPlayerMsgHandlerDetails::~CPlayerMsgHandlerDetails()
{
// delete m_pPlayerNames;
}
//-------------------------------------------------------------------------
// Purpose: Process cracked message
//-----------------------------------------------------------------------------
bool CPlayerMsgHandlerDetails::Process( netadr_t *from, CMsgBuffer *msg )
{
m_pPlayerNames->RemoveAll();
m_pPlayerNames->Purge();
// Check type of data.
if (msg->ReadByte() != S2A_PLAYER)
return false;
int pNumber;
pNumber = msg->ReadByte();
if (pNumber <= 0 || pNumber > 32) // you still need to update the player vector if this happens, the server could be empty
{
m_pPlayerList->UpdateServer();
return false;
}
// Read the data
for (int i = 0; i < pNumber; i++)
{
Players_t player;
memset(&player,0x0,sizeof(Players_t));
player.userid = msg->ReadByte();
v_strncpy(player.name ,msg->ReadString(),100);
player.frags = msg->ReadLong();
player.time = msg->ReadFloat();
m_pPlayerNames->AddToTail(player);
}
/* serveritem_t server;
memset(&server, 0, sizeof(server));
netadr_t netaddr;
if (net->StringToAdr("192.168.1.66", &netaddr))
{
memcpy(server.ip,netaddr.ip,4);
}
server.port = 27015;
CDialogGameInfo *gameDialog = new CDialogGameInfo(NULL, 0,*((int *)server.ip),pNumber);
gameDialog->Run("Stuff");
*/
m_pPlayerList->UpdateServer();
return true;
}

View File

@ -0,0 +1,41 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef PLAYERMSGHANDLER_H
#define PLAYERMSGHANDLER_H
#ifdef _WIN32
#pragma once
#endif
#include "Socket.h"
#include "utlvector.h"
#include "player.h"
#include "rcon.h"
class CPlayerList;
//-----------------------------------------------------------------------------
// Purpose: Socket handler for pinging internet servers
//-----------------------------------------------------------------------------
class CPlayerMsgHandlerDetails : public CMsgHandler
{
public:
CPlayerMsgHandlerDetails(CPlayerList *baseobject, CUtlVector<Players_t> *players,HANDLERTYPE type, void *typeinfo = NULL);
~CPlayerMsgHandlerDetails();
virtual bool Process(netadr_t *from, CMsgBuffer *msg);
private:
// the parent class that we push info back to
CPlayerList *m_pPlayerList;
CUtlVector<Players_t> *m_pPlayerNames;
};
#endif // PLAYERMSGHANDLER_H

View File

@ -0,0 +1,29 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef POINT_H
#define POINT_H
#ifdef _WIN32
#pragma once
#endif
//-----------------------------------------------------------------------------
// Purpose: Data describing a point used on the graph, dervied from the "stats" rcon command
//-----------------------------------------------------------------------------
typedef struct {
float cpu; // the percent CPU usage
float in; // the ingoing bandwidth in kB/sec
float out; // the outgoing bandwidth in kB/sec
float time; // the time this was recorded
float fps; // the FPS of the server
float ping; // the ping of the server
} Points_t;
#endif // POINT_H

View File

@ -0,0 +1,343 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: defines a RCon class used to send rcon commands to remote servers
//
// $NoKeywords: $
//=============================================================================
#include "rcon.h"
#include "Iresponse.h"
#include "RconMsgHandler.h"
#include "Socket.h"
#include "proto_oob.h"
#include "DialogGameInfo.h"
#include "inetapi.h"
#include "dialogkickplayer.h"
extern void v_strncpy(char *dest, const char *src, int bufsize);
typedef enum
{
NONE = 0,
INFO_REQUESTED,
INFO_RECEIVED
} RCONSTATUS;
CRcon::CRcon(IResponse *target,serveritem_t &server,const char *password) {
memcpy(&m_Server, &server,sizeof(serveritem_t));
m_pResponseTarget=target;
m_bIsRefreshing = false;
m_bChallenge = false;
m_bNewRcon = false;
m_bPasswordFail = false;
m_bDisable = false;
m_bGotChallenge = false;
m_iChallenge = 0;
m_fQuerySendTime= 0;
v_strncpy(m_sPassword,password,100);
int bytecode = S2A_INFO_DETAILED;
m_pQuery = new CSocket("internet rcon query", -1);
m_pQuery->AddMessageHandler(new CRconMsgHandlerDetails(this, CMsgHandler::MSGHANDLER_ALL, &bytecode));
}
CRcon::~CRcon() {
delete m_pQuery;
}
//-----------------------------------------------------------------------------
// Purpose: resets the state of the rcon object back to startup conditions (i.e get challenge again)
//-----------------------------------------------------------------------------
void CRcon::Reset()
{
m_bIsRefreshing = false;
m_bChallenge = false;
m_bNewRcon = false;
m_bPasswordFail = false;
m_bDisable = false;
m_bGotChallenge = false;
m_iChallenge = 0;
m_fQuerySendTime= 0;
}
//-----------------------------------------------------------------------------
// Purpose: sends a challenge request to the server if we have yet to get one,
// else it sends the rcon itself
//-----------------------------------------------------------------------------
void CRcon::SendRcon(const char *command)
{
if(m_bDisable==true) // rcon is disabled because it has failed.
{
m_pResponseTarget->ServerFailedToRespond();
return;
}
if(m_bIsRefreshing)
{ // we are already processing a request, lets queue this
queue_requests_t queue;
strncpy(queue.queued,command,1024);
if(requests.Count()>10) // to many request already...
return;
requests.AddToTail(queue);
return;
}
m_bIsRefreshing=true;
m_bPasswordFail=false;
if(m_bGotChallenge==false) // haven't got the challenge id yet
{
GetChallenge();
v_strncpy(m_sCmd,command,1024); // store away the command for later :)
m_bChallenge=true; // note that we are requesting a challenge and need to still run this command
}
else
{
RconRequest(command,m_iChallenge);
}
}
//-----------------------------------------------------------------------------
// Purpose: runs a frame of the net handler
//-----------------------------------------------------------------------------
void CRcon::RunFrame()
{
// only the "ping" command has a timeout
/* float curtime = CSocket::GetClock();
if(m_fQuerySendTime!=0 && (curtime-m_fQuerySendTime)> 10.0f) // 10 seconds
{
m_fQuerySendTime= 0;
m_pResponseTarget->ServerFailedToRespond();
}
*/
if (m_pQuery)
{
m_pQuery->Frame();
}
}
//-----------------------------------------------------------------------------
// Purpose: emits a challenge request
//-----------------------------------------------------------------------------
void CRcon::GetChallenge()
{
CMsgBuffer *buffer = m_pQuery->GetSendBuffer();
assert( buffer );
if ( !buffer )
{
return;
}
netadr_t adr;
adr.ip[0] = m_Server.ip[0];
adr.ip[1] = m_Server.ip[1];
adr.ip[2] = m_Server.ip[2];
adr.ip[3] = m_Server.ip[3];
adr.port = (m_Server.port & 0xff) << 8 | (m_Server.port & 0xff00) >> 8;
adr.type = NA_IP;
// Set state
m_Server.received = (int)INFO_REQUESTED;
// Create query message
buffer->Clear();
// Write control sequence
buffer->WriteLong(0xffffffff);
// Write query string
buffer->WriteString("challenge rcon");
// Sendmessage
m_pQuery->SendMessage( &adr );
// set the clock for this send
m_fQuerySendTime = CSocket::GetClock();
}
//-----------------------------------------------------------------------------
// Purpose: emits a valid rcon request, the challenge id has already been found
//-----------------------------------------------------------------------------
void CRcon::RconRequest(const char *command, int challenge)
{
CMsgBuffer *buffer = m_pQuery->GetSendBuffer();
assert( buffer );
if ( !buffer )
{
return;
}
netadr_t adr;
adr.ip[0] = m_Server.ip[0];
adr.ip[1] = m_Server.ip[1];
adr.ip[2] = m_Server.ip[2];
adr.ip[3] = m_Server.ip[3];
adr.port = (m_Server.port & 0xff) << 8 | (m_Server.port & 0xff00) >> 8;
adr.type = NA_IP;
// Set state
m_Server.received = (int)INFO_REQUESTED;
// Create query message
buffer->Clear();
// Write control sequence
buffer->WriteLong(0xffffffff);
// Write query string
char rcon_cmd[600];
_snprintf(rcon_cmd,600,"rcon %u \"%s\" %s",challenge,m_sPassword,command);
buffer->WriteString(rcon_cmd);
// Sendmessage
m_pQuery->SendMessage( &adr );
// set the clock for this send
m_fQuerySendTime = CSocket::GetClock();
}
//-----------------------------------------------------------------------------
// Purpose: called when an rcon responds
//-----------------------------------------------------------------------------
void CRcon::UpdateServer(netadr_t *adr, int challenge, const char *resp)
{
m_fQuerySendTime= 0;
if(m_bChallenge==true) // now send the RCON request itself
{
m_bChallenge=false; // m_bChallenge is set to say we just requested the challenge value
m_iChallenge=challenge;
m_bGotChallenge=true;
RconRequest(m_sCmd,m_iChallenge);
}
else // this is the result of the RCON request
{
m_bNewRcon=true;
v_strncpy(m_sRconResponse,resp,2048);
m_bIsRefreshing=false;
// this must be before the SeverResponded() :)
if(requests.Count()>0)
{ // we have queued requests
SendRcon(requests[0].queued);
requests.Remove(0); // now delete this element
}
// notify the UI of the new server info
m_pResponseTarget->ServerResponded();
}
}
//-----------------------------------------------------------------------------
// Purpose: run when a refresh is asked for
//-----------------------------------------------------------------------------
void CRcon::Refresh()
{
}
//-----------------------------------------------------------------------------
// Purpose: returns if a rcon is currently being performed
//-----------------------------------------------------------------------------
bool CRcon::IsRefreshing()
{
return m_bIsRefreshing;
}
//-----------------------------------------------------------------------------
// Purpose: the server to which this rcon class is bound
//-----------------------------------------------------------------------------
serveritem_t &CRcon::GetServer()
{
return m_Server;
}
//-----------------------------------------------------------------------------
// Purpose: the challenge id used in rcons
//-----------------------------------------------------------------------------
bool CRcon::Challenge()
{
return m_bChallenge;
}
//-----------------------------------------------------------------------------
// Purpose: returns if a new rcon result is available
//-----------------------------------------------------------------------------
bool CRcon::NewRcon()
{
bool val = m_bNewRcon;
m_bNewRcon=false;
return val;
}
//-----------------------------------------------------------------------------
// Purpose: returns the response of the last rcon
//-----------------------------------------------------------------------------
const char *CRcon::RconResponse()
{
return (const char *)m_sRconResponse;
}
//-----------------------------------------------------------------------------
// Purpose: called when the wrong password is used, when a ServerFailed is called
//-----------------------------------------------------------------------------
bool CRcon::PasswordFail()
{
bool val=m_bPasswordFail;
m_bPasswordFail=false;
return val;
//m_pResponseTarget->ServerFailedToRespond();
}
//-----------------------------------------------------------------------------
// Purpose: called by the rcon message handler to denote a bad password
//-----------------------------------------------------------------------------
void CRcon::BadPassword(const char *info)
{
strncpy(m_sRconResponse,info,100);
m_bPasswordFail=true;
m_bDisable=true;
m_fQuerySendTime= 0;
m_bIsRefreshing=false;
/* // this must be before the ServerFailedToRespond() :)
if(requests.Count()>0)
{ // we have queued requests
SendRcon(requests[0].queued);
requests.Remove(0); // now delete this element
}
*/
m_pResponseTarget->ServerFailedToRespond();
}
//-----------------------------------------------------------------------------
// Purpose: return whether rcon has been disabled (due to bad passwords)
//-----------------------------------------------------------------------------
bool CRcon::Disabled()
{
return m_bDisable;
}
//-----------------------------------------------------------------------------
// Purpose: sets the password to use for rcons
//-----------------------------------------------------------------------------
void CRcon::SetPassword(const char *newPass)
{
strncpy(m_sPassword,newPass,100);
m_bDisable=false; // new password, so we can try again
}

View File

@ -0,0 +1,100 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: defines a RCon class used to send rcon commands to remote servers
//
// $NoKeywords: $
//=============================================================================
#ifndef RCON_H
#define RCON_H
#ifdef _WIN32
#pragma once
#endif
#include "server.h"
#include "netadr.h"
class CSocket;
class IResponse;
typedef struct
{
char queued[1024];
} queue_requests_t;
class CRcon
{
public:
CRcon(IResponse *target,serveritem_t &server, const char *password);
~CRcon();
// resets the state of the object, will cause it to get the challenge id again
void Reset();
// send an rcon command to a server
void SendRcon(const char *cmd);
// does nothing
void Refresh();
bool IsRefreshing();
serveritem_t &GetServer();
void RunFrame();
// return the response from the server
const char *RconResponse();
// called when the message handler gets a packet back
void UpdateServer(netadr_t *adr, int challenge,const char *resp);
// returns the challenge id
bool Challenge();
// returns if a new rcon result is waiting
bool NewRcon();
// returns if the password failed
bool PasswordFail();
// called when a bad password is used
void BadPassword(const char *info);
// returns whether this rcon is disabled (due to bad passwords)
bool Disabled();
//set the password to use in the rcon request
void SetPassword(const char *newPass);
private:
// sends the actual request
void RconRequest(const char *command, int challenge);
// requests a challenge value from the server
void GetChallenge();
serveritem_t m_Server;
CSocket *m_pQuery; // Game server query socket
IResponse *m_pResponseTarget;
bool m_bIsRefreshing; // whether we are currently performing an rcon command
bool m_bChallenge; // whether we are currently GETTING a challenge id
bool m_bNewRcon; // whether an rcon response is waiting to be picked up
bool m_bPasswordFail; // whether the password failed
bool m_bDisable; // whether rcon is disabled due to password failures
bool m_bGotChallenge; // whether we have a valid challenge id stored away
CUtlVector<queue_requests_t> requests;
char m_sPassword[100];
char m_sCmd[1024];
char m_sRconResponse[2048];
int m_iChallenge;
float m_fQuerySendTime;
};
#endif // RCON_H

View File

@ -0,0 +1,67 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "RconMsgHandler.h"
#include "rcon.h"
#include "info.h"
#include "DialogGameInfo.h"
#include "inetapi.h"
#include "proto_oob.h"
extern void v_strncpy(char *dest, const char *src, int bufsize);
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CRconMsgHandlerDetails::CRconMsgHandlerDetails( CRcon *baseobject, HANDLERTYPE type, void *typeinfo /*= NULL*/ )
: CMsgHandler( type, typeinfo )
{
m_pRcon = baseobject;
}
//-----------------------------------------------------------------------------
// Purpose: Process cracked message
//-----------------------------------------------------------------------------
bool CRconMsgHandlerDetails::Process( netadr_t *from, CMsgBuffer *msg )
{
// Skip the control character
//if (!m_pRcon->Challenge() && msg->ReadByte()!=A2C_PRINT)
// return false;
// get response name
const char *str = msg->ReadString();
if ( !str || !str[0] )
return false;
char info[ 2048 ];
v_strncpy( info, str, 2047 );
info[2047] = 0;
if(!_strnicmp(info,"lBad rcon_password",18) )
{
m_pRcon->BadPassword(info+1);
return true;
}
if(m_pRcon->Challenge() )
{ // if we know the challenge value pass it to UpdateServer
int challenge = atoi(info+strlen("challenge rcon"));
m_pRcon->UpdateServer(from, challenge, NULL);
}
else // else pass a default value
{
m_pRcon->UpdateServer(from, -1, info+1 );
}
return true;
}

View File

@ -0,0 +1,36 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef RCONMSGHANDLERDETAILS_H
#define RCONMSGHANDLERDETAILS_H
#ifdef _WIN32
#pragma once
#endif
#include "Socket.h"
class CRcon;
//-----------------------------------------------------------------------------
// Purpose: Socket handler for pinging internet servers
//-----------------------------------------------------------------------------
class CRconMsgHandlerDetails : public CMsgHandler
{
public:
CRconMsgHandlerDetails(CRcon *baseobject, HANDLERTYPE type, void *typeinfo = NULL);
virtual bool Process(netadr_t *from, CMsgBuffer *msg);
private:
// the parent class that we push info back to
CRcon *m_pRcon;
};
#endif // RCONMSGHANDLERDETAILS_H

View File

@ -0,0 +1,132 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: defines a RCon class used to send rcon commands to remote servers
//
// $NoKeywords: $
//=============================================================================
#include "rulesinfo.h"
#include "Iresponse.h"
#include "RulesInfoMsgHandler.h"
#include "Socket.h"
#include "proto_oob.h"
#include "DialogGameInfo.h"
extern void v_strncpy(char *dest, const char *src, int bufsize);
CRulesInfo::CRulesInfo(IResponse *target,serveritem_t &server) {
memcpy(&m_Server, &server,sizeof(serveritem_t));
m_pResponseTarget=target;
m_bIsRefreshing=false;
m_vRules=NULL;
int bytecode = S2A_RULES;
m_pQuery = new CSocket("internet rules query", -1);
m_pQuery->AddMessageHandler(new CRulesInfoMsgHandlerDetails(this, CMsgHandler::MSGHANDLER_ALL, &bytecode));
}
CRulesInfo::~CRulesInfo() {
delete m_pQuery;
}
//-----------------------------------------------------------------------------
// Purpose: sends a status query packet to a single server
//-----------------------------------------------------------------------------
void CRulesInfo::Query()
{
CMsgBuffer *buffer = m_pQuery->GetSendBuffer();
assert( buffer );
if ( !buffer )
{
return;
}
m_bIsRefreshing=true;
m_bRefreshed=false;
netadr_t adr;
adr.ip[0] = m_Server.ip[0];
adr.ip[1] = m_Server.ip[1];
adr.ip[2] = m_Server.ip[2];
adr.ip[3] = m_Server.ip[3];
adr.port = (m_Server.port & 0xff) << 8 | (m_Server.port & 0xff00) >> 8;
adr.type = NA_IP;
// Create query message
buffer->Clear();
// Write control sequence
buffer->WriteLong(0xffffffff);
// Write query string
buffer->WriteString("rules");
// Sendmessage
m_pQuery->SendMessage( &adr, buffer );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CRulesInfo::RunFrame()
{
if (m_pQuery)
{
m_pQuery->Frame();
}
}
void CRulesInfo::UpdateServer(netadr_t *adr, CUtlVector<vgui::KeyValues *> *Rules)
{
m_Server.hadSuccessfulResponse = true;
m_vRules=Rules;
m_bIsRefreshing=false;
m_bRefreshed=true;
// notify the UI of the new server info
m_pResponseTarget->ServerResponded();
}
void CRulesInfo::Refresh()
{
Query();
}
bool CRulesInfo::IsRefreshing()
{
return m_bIsRefreshing;
}
serveritem_t &CRulesInfo::GetServer()
{
return m_Server;
}
bool CRulesInfo::Refreshed()
{
bool val = m_bRefreshed;
m_bRefreshed=false;
return val;
}
CUtlVector<vgui::KeyValues *> *CRulesInfo::Rules()
{
return m_vRules;
}

View File

@ -0,0 +1,67 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: defines a RCon class used to send rcon commands to remote servers
//
// $NoKeywords: $
//=============================================================================
#ifndef RULESINFO_H
#define RULESINFO_H
#ifdef _WIN32
#pragma once
#endif
#include "server.h"
#include "netadr.h"
class CSocket;
class IResponse;
#include <VGUI_PropertyPage.h>
#include <VGUI_Frame.h>
#include <VGUI_ListPanel.h>
#include <VGUI_KeyValues.h>
class CRulesInfo
{
public:
CRulesInfo(IResponse *target,serveritem_t &server);
~CRulesInfo();
// send an rcon command to a server
void Query();
void Refresh();
bool IsRefreshing();
serveritem_t &GetServer();
void RunFrame();
bool Refreshed();
void UpdateServer(netadr_t *adr, CUtlVector<vgui::KeyValues *> *Rules);
CUtlVector<vgui::KeyValues *> *Rules();
int serverID;
int received;
private:
serveritem_t m_Server;
CSocket *m_pQuery; // Game server query socket
IResponse *m_pResponseTarget;
bool m_bIsRefreshing;
float m_fSendTime;
bool m_bRefreshed;
CUtlVector<vgui::KeyValues *> *m_vRules;
};
#endif // RULESINFO_H

View File

@ -0,0 +1,89 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "RulesInfoMsgHandler.h"
#include "rulesinfo.h"
#include "info.h"
#include "proto_oob.h"
#include "DialogGameInfo.h"
#include "inetapi.h"
extern void v_strncpy(char *dest, const char *src, int bufsize);
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CRulesInfoMsgHandlerDetails::CRulesInfoMsgHandlerDetails( CRulesInfo *baseobject, HANDLERTYPE type, void *typeinfo /*= NULL*/ )
: CMsgHandler( type, typeinfo )
{
m_pRulesInfo = baseobject;
m_vRules = new CUtlVector<vgui::KeyValues *>();
}
//-----------------------------------------------------------------------------
// Purpose: Process cracked message
//-----------------------------------------------------------------------------
bool CRulesInfoMsgHandlerDetails::Process( netadr_t *from, CMsgBuffer *msg )
{
m_vRules->RemoveAll();
m_vRules->Purge();
// Check type of data.
if (msg->ReadByte() != S2A_RULES)
return false;
int pNumber;
pNumber = msg->ReadByte();
// there is a null string at the start of the rules...
msg->ReadString();
// Read the data
for (int i = 0; i < pNumber; i++)
{
vgui::KeyValues *kv=new vgui::KeyValues("rules");
char *cvar,*value;
cvar = new char[50];
value = new char[50];
v_strncpy(cvar,msg->ReadString(),50);
v_strncpy(value,msg->ReadString(),50);
kv->SetString("cvar",cvar);
kv->SetString("value",value);
m_vRules->AddToTail(kv);
}
/* serveritem_t server;
memset(&server, 0, sizeof(server));
netadr_t netaddr;
if (net->StringToAdr("192.168.1.66", &netaddr))
{
memcpy(server.ip,netaddr.ip,4);
}
server.port = 27015;
CDialogGameInfo *gameDialog = new CDialogGameInfo(NULL, 0,*((int *)server.ip),pNumber);
gameDialog->Run("Stuff");
*/
m_pRulesInfo->UpdateServer(from, m_vRules);
return true;
}

View File

@ -0,0 +1,44 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef RULESINFOMSGHANDLERDETAILS_H
#define RULESINFOMSGHANDLERDETAILS_H
#ifdef _WIN32
#pragma once
#endif
#include "Socket.h"
#include "utlvector.h"
class CRulesInfo;
#include <VGUI_PropertyPage.h>
#include <VGUI_Frame.h>
#include <VGUI_ListPanel.h>
#include <VGUI_KeyValues.h>
//-----------------------------------------------------------------------------
// Purpose: Socket handler for pinging internet servers
//-----------------------------------------------------------------------------
class CRulesInfoMsgHandlerDetails : public CMsgHandler
{
public:
CRulesInfoMsgHandlerDetails(CRulesInfo *baseobject, HANDLERTYPE type, void *typeinfo = NULL);
virtual bool Process(netadr_t *from, CMsgBuffer *msg);
private:
// the parent class that we push info back to
CRulesInfo *m_pRulesInfo;
CUtlVector<vgui::KeyValues *> *m_vRules;
};
#endif // RULESINFOMSGHANDLERDETAILS_H

View File

@ -0,0 +1,187 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: defines a RCon class used to send rcon commands to remote servers
//
// $NoKeywords: $
//=============================================================================
#include "serverinfo.h"
#include "Iresponse.h"
#include "ServerInfoMsgHandler.h"
#include "Socket.h"
#include "proto_oob.h"
#include "DialogGameInfo.h"
extern void v_strncpy(char *dest, const char *src, int bufsize);
namespace
{
const float SERVER_TIMEOUT =5.0f; // timeout before failing
}
typedef enum
{
NONE = 0,
INFO_REQUESTED,
INFO_RECEIVED
} RCONSTATUS;
CServerInfo::CServerInfo(IResponse *target,serveritem_t &server) {
memcpy(&m_Server, &server,sizeof(serveritem_t));
m_pResponseTarget=target;
m_bIsRefreshing=false;
int bytecode = S2A_INFO_DETAILED;
m_pQuery = new CSocket("internet server query", -1);
m_pQuery->AddMessageHandler(new CServerInfoMsgHandlerDetails(this, CMsgHandler::MSGHANDLER_ALL, &bytecode));
m_fSendTime= 0;
}
CServerInfo::~CServerInfo() {
delete m_pQuery;
}
//-----------------------------------------------------------------------------
// Purpose: sends a status query packet to a single server
//-----------------------------------------------------------------------------
void CServerInfo::Query()
{
CMsgBuffer *buffer = m_pQuery->GetSendBuffer();
assert( buffer );
if ( !buffer )
{
return;
}
m_bIsRefreshing=true;
m_bRefreshed=false;
netadr_t adr;
adr.ip[0] = m_Server.ip[0];
adr.ip[1] = m_Server.ip[1];
adr.ip[2] = m_Server.ip[2];
adr.ip[3] = m_Server.ip[3];
adr.port = (m_Server.port & 0xff) << 8 | (m_Server.port & 0xff00) >> 8;
adr.type = NA_IP;
// Set state
m_Server.received = (int)INFO_REQUESTED;
// Create query message
buffer->Clear();
// Write control sequence
buffer->WriteLong(0xffffffff);
// Write query string
buffer->WriteString("infostring");
// Sendmessage
m_pQuery->SendMessage( &adr );
m_fSendTime = CSocket::GetClock();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CServerInfo::RunFrame()
{
float curtime = CSocket::GetClock();
if(m_fSendTime!=0 && (curtime-m_fSendTime)> 5.0f) // 10 seconds timeout
{
m_fSendTime = 0;
m_pResponseTarget->ServerFailedToRespond();
}
if (m_pQuery)
{
m_pQuery->Frame();
}
}
void CServerInfo::UpdateServer(netadr_t *adr, bool proxy, const char *serverName, const char *map,
const char *gamedir, const char *gameDescription, int players,
int maxPlayers, float recvTime, bool password)
{
m_Server.received = INFO_RECEIVED;
m_Server.hadSuccessfulResponse = true;
// copy in data necessary for filters
v_strncpy(m_Server.gameDir, gamedir, sizeof(m_Server.gameDir) - 1);
v_strncpy(m_Server.map, map, sizeof(m_Server.map) - 1);
v_strncpy(m_Server.name, serverName, sizeof(m_Server.name) - 1);
v_strncpy(m_Server.gameDescription, gameDescription, sizeof(m_Server.gameDescription) - 1);
m_Server.players = players;
m_Server.maxPlayers = maxPlayers;
m_Server.proxy = proxy;
m_Server.password = password;
int ping = (int)((recvTime - m_fSendTime) * 1000);
if (ping > 3000 || ping < 0)
{
// make sure ping is valid
ping = 1200;
}
// add to ping times list
// server.pings[0] = server.pings[1];
// server.pings[1] = server.pings[2];
// server.pings[2] = ping;
// calculate ping
// ping = CalculateAveragePing(server);
m_Server.ping = ping;
m_bIsRefreshing=false;
m_bRefreshed=true;
m_fSendTime = 0;
// notify the UI of the new server info
m_pResponseTarget->ServerResponded();
}
void CServerInfo::Refresh()
{
Query();
}
bool CServerInfo::IsRefreshing()
{
return m_bIsRefreshing;
}
serveritem_t &CServerInfo::GetServer()
{
return m_Server;
}
bool CServerInfo::Refreshed()
{
bool val = m_bRefreshed;
m_bRefreshed=false;
return val;
}

View File

@ -0,0 +1,60 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: defines a RCon class used to send rcon commands to remote servers
//
// $NoKeywords: $
//=============================================================================
#ifndef SERVERINFO_H
#define SERVERINFO_H
#ifdef _WIN32
#pragma once
#endif
#include "server.h"
#include "netadr.h"
class CSocket;
class IResponse;
class CServerInfo
{
public:
CServerInfo(IResponse *target,serveritem_t &server);
~CServerInfo();
// send an rcon command to a server
void Query();
void Refresh();
bool IsRefreshing();
serveritem_t &GetServer();
void RunFrame();
bool Refreshed();
void UpdateServer(netadr_t *adr, bool proxy, const char *serverName, const char *map,
const char *gamedir, const char *gameDescription, int players,
int maxPlayers, float recvTime, bool password);
int serverID;
int received;
private:
serveritem_t m_Server;
CSocket *m_pQuery; // Game server query socket
IResponse *m_pResponseTarget;
bool m_bIsRefreshing;
float m_fSendTime;
bool m_bRefreshed;
};
#endif // SERVERINFO_H

View File

@ -0,0 +1,74 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "ServerInfoMsgHandler.h"
#include "serverinfo.h"
#include "info.h"
extern void v_strncpy(char *dest, const char *src, int bufsize);
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CServerInfoMsgHandlerDetails::CServerInfoMsgHandlerDetails( CServerInfo *baseobject, HANDLERTYPE type, void *typeinfo /*= NULL*/ )
: CMsgHandler( type, typeinfo )
{
m_pServerInfo = baseobject;
}
//-----------------------------------------------------------------------------
// Purpose: Process cracked message
//-----------------------------------------------------------------------------
bool CServerInfoMsgHandlerDetails::Process( netadr_t *from, CMsgBuffer *msg )
{
// Skip the control character
msg->ReadByte();
// get response name
const char *str = msg->ReadString();
if ( !str || !str[0] )
return false;
// get infostring
str = msg->ReadString();
if ( !str || !str[0] )
return false;
char info[ 2048 ];
strncpy( info, str, 2047 );
info[2047] = 0;
char name[256], map[256], gamedir[256], desc[256];
v_strncpy(name, Info_ValueForKey(info, "hostname"), 255);
v_strncpy(map, Info_ValueForKey(info, "map"), 255);
v_strncpy(gamedir, Info_ValueForKey(info, "gamedir"), 255);
strlwr(gamedir);
v_strncpy(desc, Info_ValueForKey(info, "description"), 255);
int players = atoi(Info_ValueForKey(info, "players"));
int maxplayers = atoi(Info_ValueForKey(info, "max"));
char serverType = *Info_ValueForKey(info, "type");
bool password = atoi(Info_ValueForKey(info, "password"));
m_pServerInfo->UpdateServer(from, // index of server
(serverType == 'p'),
name,
map,
gamedir,
desc,
players,
maxplayers,
msg->GetTime(), // receive time
password
);
return true;
}

View File

@ -0,0 +1,36 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef SERVERINFOMSGHANDLERDETAILS_H
#define SERVERINFOMSGHANDLERDETAILS_H
#ifdef _WIN32
#pragma once
#endif
#include "Socket.h"
class CServerInfo;
//-----------------------------------------------------------------------------
// Purpose: Socket handler for pinging internet servers
//-----------------------------------------------------------------------------
class CServerInfoMsgHandlerDetails : public CMsgHandler
{
public:
CServerInfoMsgHandlerDetails(CServerInfo *baseobject, HANDLERTYPE type, void *typeinfo = NULL);
virtual bool Process(netadr_t *from, CMsgBuffer *msg);
private:
// the parent class that we push info back to
CServerInfo *m_pServerInfo;
};
#endif // SERVERINFOMSGHANDLERDETAILS_H

View File

@ -0,0 +1,285 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "ServerInfoPanel.h"
#include "MapCycleEditDialog.h"
#include <vgui/ISystem.h>
#include <ctype.h>
#include <stdio.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CServerInfoPanel::CServerInfoPanel(vgui::Panel *parent, const char *name) : CVarListPropertyPage(parent, name)
{
LoadControlSettings("Admin/GamePanelInfo.res", "PLATFORM");
LoadVarList("Admin/MainServerConfig.vdf");
m_iLastUptimeDisplayed = 0;
m_flUpdateTime = 0.0f;
m_bMapListRetrieved = false;
RemoteServer().AddServerMessageHandler(this, "UpdatePlayers");
RemoteServer().AddServerMessageHandler(this, "UpdateMap");
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CServerInfoPanel::~CServerInfoPanel()
{
RemoteServer().RemoveServerDataResponseTarget(this);
}
//-----------------------------------------------------------------------------
// Purpose: gets the current hostname
//-----------------------------------------------------------------------------
const char *CServerInfoPanel::GetHostname()
{
return GetVarString("hostname");
}
//-----------------------------------------------------------------------------
// Purpose: Refreshes page if necessary
//-----------------------------------------------------------------------------
void CServerInfoPanel::OnThink()
{
if (m_flUpdateTime < vgui::system()->GetFrameTime())
{
OnResetData();
}
// check uptime count
int time = m_iLastUptimeReceived + (int)(vgui::system()->GetFrameTime() - m_flLastUptimeReceiveTime);
if (time != m_iLastUptimeDisplayed)
{
m_iLastUptimeDisplayed = time;
char timeText[64];
_snprintf(timeText, sizeof(timeText), "%0.1i:%0.2i:%0.2i:%0.2i", (time / 3600) / 24, (time / 3600), (time / 60) % 60, time % 60);
SetControlString("UpTimeText", timeText);
}
}
//-----------------------------------------------------------------------------
// Purpose: Data is be reloaded from document into controls.
//-----------------------------------------------------------------------------
void CServerInfoPanel::OnResetData()
{
// only ask for maps list once
if (!m_bMapListRetrieved)
{
RemoteServer().RequestValue(this, "maplist");
m_bMapListRetrieved = true;
}
// refresh our vars
RefreshVarList();
// ask for the constant data
RemoteServer().RequestValue(this, "playercount");
RemoteServer().RequestValue(this, "maxplayers");
RemoteServer().RequestValue(this, "gamedescription");
RemoteServer().RequestValue(this, "uptime");
RemoteServer().RequestValue(this, "ipaddress");
// update once every minute
m_flUpdateTime = (float)system()->GetFrameTime() + (60 * 1.0f);
}
//-----------------------------------------------------------------------------
// Purpose: handles responses from the server
//-----------------------------------------------------------------------------
void CServerInfoPanel::OnServerDataResponse(const char *value, const char *response)
{
if (!stricmp(value, "playercount"))
{
m_iPlayerCount = atoi(response);
}
else if (!stricmp(value, "maxplayers"))
{
m_iMaxPlayers = atoi(response);
// update control
char buf[128];
buf[0] = 0;
if (m_iMaxPlayers > 0)
{
sprintf(buf, "%d / %d", m_iPlayerCount, m_iMaxPlayers);
}
SetControlString("PlayersText", buf);
}
else if (!stricmp(value, "gamedescription"))
{
SetControlString("GameText", response);
}
else if (!stricmp(value, "hostname"))
{
PostActionSignal(new KeyValues("UpdateTitle"));
}
else if (!stricmp(value, "UpdateMap") || !stricmp(value, "UpdatePlayers"))
{
// server has indicated a change, force an update
m_flUpdateTime = 0.0f;
}
else if (!stricmp(value, "maplist"))
{
SetCustomStringList("map", response);
// save off maplist for use in mapcycle editing
ParseIntoMapList(response, m_AvailableMaps);
// don't chain through, not in varlist
return;
}
else if (!stricmp(value, "uptime"))
{
// record uptime for extrapolation
m_iLastUptimeReceived = atoi(response);
m_flLastUptimeReceiveTime = (float)system()->GetFrameTime();
}
else if (!stricmp(value, "ipaddress"))
{
SetControlString("ServerIPText", response);
}
else if (!stricmp(value, "mapcycle"))
{
ParseIntoMapList(response, m_MapCycle);
UpdateMapCycleValue();
// don't chain through, we set the value ourself
return;
}
// always chain through, in case this variable is in the list as well
BaseClass::OnServerDataResponse(value, response);
// post update
if (!stricmp(value, "map"))
{
// map has changed, update map cycle view
UpdateMapCycleValue();
}
}
//-----------------------------------------------------------------------------
// Purpose: special editing of map cycle list
//-----------------------------------------------------------------------------
void CServerInfoPanel::OnEditVariable(KeyValues *rule)
{
if (!stricmp(rule->GetName(), "mapcycle"))
{
CMapCycleEditDialog *dlg = new CMapCycleEditDialog(this, "MapCycleEditDialog");
dlg->Activate(this, m_AvailableMaps, m_MapCycle);
}
else
{
BaseClass::OnEditVariable(rule);
}
}
//-----------------------------------------------------------------------------
// Purpose: Updates the value shown in the mapcycle field
//-----------------------------------------------------------------------------
void CServerInfoPanel::UpdateMapCycleValue()
{
// look at current map
CUtlSymbol currentMap = GetVarString("map");
if (!currentMap.IsValid())
return;
// find it in the map cycle list
int listPoint = -1;
for (int i = 0; i < m_MapCycle.Count(); i++)
{
if (!stricmp(m_MapCycle[i].String(), currentMap.String()))
{
listPoint = i;
}
}
// take out the next 2 maps and make them the value
char nextMaps[512];
nextMaps[0] = 0;
bool needComma = false;
for (int i = 0; i < 2; i++)
{
int point = listPoint + i + 1;
if (point >= m_MapCycle.Count())
{
point -= m_MapCycle.Count();
}
if (m_MapCycle.IsValidIndex(point))
{
if (needComma)
{
strcat(nextMaps, ", ");
}
strcat(nextMaps, m_MapCycle[point].String());
needComma = true;
}
}
// add some elipses to show there is more maps
if (needComma)
{
strcat(nextMaps, ", ");
}
strcat(nextMaps, "...");
// show in varlist
SetVarString("mapcycle", nextMaps);
}
//-----------------------------------------------------------------------------
// Purpose: Seperates out a newline-seperated map list into an array
//-----------------------------------------------------------------------------
void CServerInfoPanel::ParseIntoMapList(const char *maplist, CUtlVector<CUtlSymbol> &mapArray)
{
mapArray.RemoveAll();
const char *parse = maplist;
while (*parse)
{
// newline-seperated map list
//!! this should be done with a more standard tokenizer
if (isspace(*parse))
{
parse++;
continue;
}
// pull out the map name
const char *end = strstr(parse, "\n");
const char *end2 = strstr(parse, "\r");
if (end && end2 && end2 < end)
{
end = end2;
}
if (!end)
break;
char customString[64];
int nameSize = end - parse;
if (nameSize >= sizeof(customString))
{
nameSize = sizeof(customString) - 1;
}
// copy in the name
strncpy(customString, parse, nameSize);
customString[nameSize] = 0;
parse = end;
// add to the list string that aren't comments
if (nameSize > 0 && !(customString[0] == '/' && customString[1] == '/'))
{
int i = mapArray.AddToTail();
mapArray[i] = customString;
}
}
}

Some files were not shown because too many files have changed in this diff Show More