initial
This commit is contained in:
876
dedicated/vgui/CreateMultiplayerGameServerPage.cpp
Normal file
876
dedicated/vgui/CreateMultiplayerGameServerPage.cpp
Normal file
@@ -0,0 +1,876 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <stdio.h>
|
||||
#include "steam.h"
|
||||
|
||||
#include "CreateMultiplayerGameServerPage.h"
|
||||
#include <Winsock2.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
#include <vgui_controls/Controls.h>
|
||||
#include <keyvalues.h>
|
||||
#include <vgui_controls/ListPanel.h>
|
||||
#include <vgui_controls/ComboBox.h>
|
||||
#include <vgui_controls/MessageBox.h>
|
||||
#include <vgui_controls/CheckButton.h>
|
||||
#include <vgui/IVGui.h>
|
||||
|
||||
#include <OfflineMode.h>
|
||||
|
||||
#include "filesystem.h"
|
||||
#include "mainpanel.h"
|
||||
#include "tier0/icommandline.h"
|
||||
#include "netapi.h"
|
||||
// for SRC
|
||||
#include <vstdlib/random.h>
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
//#define ALLOW_OLD_ENGINE_GAMES
|
||||
|
||||
|
||||
// filesystem_steam.cpp implements this useful function - mount all the caches for a given app ID.
|
||||
extern void MountDependencies( int iAppId, CUtlVector<unsigned int> &depList );
|
||||
|
||||
|
||||
bool IsEp1EraAppID( int iSteamAppId )
|
||||
{
|
||||
return iSteamAppId == 211 || iSteamAppId == 215;
|
||||
}
|
||||
|
||||
// Checks the liblist.gam file for a "fallback_dir"
|
||||
const char *GetLiblistFallbackDir( const char *pszGameDir )
|
||||
{
|
||||
static char szFallback[512];
|
||||
char szTemp[512];
|
||||
|
||||
szFallback[0] = 0;
|
||||
|
||||
_snprintf( szTemp, sizeof(szTemp) - 1, "%s\\liblist.gam", pszGameDir );
|
||||
g_pFullFileSystem->GetLocalCopy( szTemp );
|
||||
|
||||
FileHandle_t hFile = g_pFullFileSystem->Open( szTemp, "rt" );
|
||||
|
||||
if ( hFile )
|
||||
{
|
||||
char szLine[512];
|
||||
|
||||
// look for the line starting with 'fallback_dir'
|
||||
while ( !g_pFullFileSystem->EndOfFile( hFile ) )
|
||||
{
|
||||
// get a single line
|
||||
szLine[0] = 0;
|
||||
g_pFullFileSystem->ReadLine( szLine, sizeof(szLine) - 1, hFile );
|
||||
szLine[sizeof(szLine) - 1] = 0;
|
||||
|
||||
if ( !strnicmp( szLine, "fallback_dir", 12 ) )
|
||||
{
|
||||
// we got the line, get the value between the quotes
|
||||
char *start = strchr( szLine, '\"' );
|
||||
|
||||
if ( !start )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
char *end = strchr( start + 1, '\"' );
|
||||
if ( !end )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// copy out between start and end
|
||||
int bytesToCopy = end - start - 1;
|
||||
if ( bytesToCopy >= sizeof(szFallback) - 1 )
|
||||
{
|
||||
bytesToCopy = sizeof(szFallback) - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( bytesToCopy > 0 )
|
||||
{
|
||||
strncpy( szFallback, start + 1, bytesToCopy );
|
||||
szFallback[bytesToCopy] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_pFullFileSystem->Close( hFile );
|
||||
}
|
||||
|
||||
return szFallback;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CCreateMultiplayerGameServerPage::CCreateMultiplayerGameServerPage(vgui::Panel *parent, const char *name) : Frame(parent, name)
|
||||
{
|
||||
memset(&m_iServer,0x0,sizeof(serveritem_t));
|
||||
|
||||
m_MainPanel = parent; // as we are a popup frame we need to store this seperately
|
||||
m_pSavedData = NULL;
|
||||
m_pGameInfo = NULL;
|
||||
|
||||
SetMinimumSize(310, 350);
|
||||
SetSize(310, 350);
|
||||
SetSizeable(false);
|
||||
|
||||
|
||||
SetTitle("#Start_Server_Title",true);
|
||||
|
||||
m_pMapList = new ComboBox(this, "MapList",10,false);
|
||||
m_pMapList->SetEnabled(false); // a mod needs to be chosen first to populate the map list
|
||||
m_pMapList->SetEditable(false);
|
||||
|
||||
m_pNetworkCombo = new ComboBox(this, "NetworkCombo",10,false);
|
||||
int defaultItem = m_pNetworkCombo->AddItem("#Internet", NULL);
|
||||
int lanItem = m_pNetworkCombo->AddItem("#LAN", NULL);
|
||||
if ( CommandLine()->CheckParm("-steam") && IsSteamInOfflineMode() )
|
||||
{
|
||||
defaultItem = lanItem;
|
||||
}
|
||||
m_pNetworkCombo->ActivateItem(defaultItem);
|
||||
|
||||
m_pNumPlayers = new ComboBox(this, "NumPlayers",10,false);
|
||||
char num[3];
|
||||
int i;
|
||||
for( i = 1 ; i <= MAX_PLAYERS ; i++ )
|
||||
{
|
||||
_snprintf(num, 3, "%i", i);
|
||||
m_pNumPlayers->AddItem(num, NULL);
|
||||
}
|
||||
m_pNumPlayers->ActivateItemByRow(23); // 24 players by default
|
||||
|
||||
m_pGameCombo = new ComboBox(this,"MODCombo", 10, false);
|
||||
|
||||
m_pStartServerButton = new Button(this, "StartButton", "#Start_Server_Button");
|
||||
m_pStartServerButton->SetCommand("start");
|
||||
|
||||
m_pCancelButton = new Button(this, "CancelButton", "#Start_Server_Cancel");
|
||||
m_pCancelButton->SetCommand("cancel");
|
||||
|
||||
m_pSecureCheck = new CheckButton(this, "SecureCheck", "#Start_Server_Secure");
|
||||
m_pSecureCheck->SetSelected(true);
|
||||
|
||||
LoadControlSettingsAndUserConfig("Admin/CreateMultiplayerGameServerPage.res");
|
||||
|
||||
// load some defaults into the controls
|
||||
SetControlString("ServerNameEdit", "Half-Life dedicated server");
|
||||
Q_strncpy(m_szGameName, "Half-Life", sizeof(m_szGameName));
|
||||
|
||||
LoadMODList();
|
||||
|
||||
m_pGameCombo->RequestFocus();
|
||||
|
||||
// get default port from commandline if possible
|
||||
m_iPort = 27015;
|
||||
const char *portVal = NULL;
|
||||
if (CommandLine()->CheckParm("-port", &portVal) && portVal && atoi(portVal) > 0)
|
||||
{
|
||||
m_iPort = atoi(portVal);
|
||||
}
|
||||
SetControlInt("PortEdit", m_iPort);
|
||||
|
||||
LoadConfig();
|
||||
|
||||
m_szMapName[0] = 0;
|
||||
m_szHostName[0] = 0;
|
||||
m_szPassword[0] = 0;
|
||||
m_iMaxPlayers = 24;
|
||||
|
||||
if ( CommandLine()->CheckParm("-steam") && IsSteamInOfflineMode() )
|
||||
{
|
||||
m_pNetworkCombo->SetEnabled( false );
|
||||
}
|
||||
|
||||
SetVisible(true);
|
||||
|
||||
if ( CommandLine()->CheckParm("-steam") && IsSteamInOfflineMode() )
|
||||
{
|
||||
MessageBox *box = new vgui::MessageBox( "#Start_Server_Offline_Title", "#Start_Server_Offline_Warning" );
|
||||
box->DoModal();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CCreateMultiplayerGameServerPage::~CCreateMultiplayerGameServerPage()
|
||||
{
|
||||
SaveConfig();
|
||||
if (m_pSavedData)
|
||||
{
|
||||
m_pSavedData->deleteThis();
|
||||
m_pSavedData = NULL;
|
||||
}
|
||||
if ( m_pGameInfo )
|
||||
{
|
||||
m_pGameInfo->deleteThis();
|
||||
m_pGameInfo = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCreateMultiplayerGameServerPage::OnResetData()
|
||||
{
|
||||
m_pGameCombo->SetEnabled(true);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: loads settings from a config file
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCreateMultiplayerGameServerPage::LoadConfig()
|
||||
{
|
||||
// free any old filters
|
||||
if (m_pSavedData)
|
||||
{
|
||||
m_pSavedData->deleteThis();
|
||||
}
|
||||
m_pSavedData = new KeyValues ("Server");
|
||||
|
||||
if (!m_pSavedData->LoadFromFile(g_pFullFileSystem, "Server.vdf", "CONFIG"))
|
||||
{
|
||||
// file not successfully loaded
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_pSavedData->FindKey("RconPassword", false))
|
||||
{
|
||||
const char *password = m_pSavedData->GetString("RconPassword", "");
|
||||
if (strlen(password)>0)
|
||||
{
|
||||
SetControlString("RCONPasswordEdit", password);
|
||||
}
|
||||
}
|
||||
if (m_pSavedData->FindKey("MaxPlayers", false))
|
||||
{
|
||||
int maxPlayers = m_pSavedData->GetInt("MaxPlayers", -1);
|
||||
if (maxPlayers > 0 && maxPlayers <= 32)
|
||||
{
|
||||
m_pNumPlayers->ActivateItemByRow(maxPlayers - 1);
|
||||
}
|
||||
}
|
||||
if (m_pSavedData->FindKey("MOD", false))
|
||||
{
|
||||
const char *mod = m_pSavedData->GetString("MOD", "");
|
||||
if (strlen(mod) > 0)
|
||||
{
|
||||
// look for the item in the dropdown
|
||||
m_szMod[0] = 0;
|
||||
for (int i = 0; i < m_pGameCombo->GetItemCount(); i++)
|
||||
{
|
||||
if (!m_pGameCombo->IsItemIDValid(i))
|
||||
continue;
|
||||
|
||||
if (!stricmp(m_pGameCombo->GetItemUserData(i)->GetString("gamedir"), mod))
|
||||
{
|
||||
// item found in list, activate
|
||||
m_pGameCombo->ActivateItem(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_pSavedData->FindKey("Map", false))
|
||||
{
|
||||
const char *map = m_pSavedData->GetString("Map", "");
|
||||
if (strlen(map) > 0)
|
||||
{
|
||||
SetControlString("MapList", map);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pSavedData->FindKey("Network", false))
|
||||
{
|
||||
int nwIndex = m_pSavedData->GetInt("Network");
|
||||
if (nwIndex > 0 && nwIndex < 2)
|
||||
{
|
||||
m_pNetworkCombo->ActivateItemByRow(nwIndex);
|
||||
}
|
||||
}
|
||||
if (m_pSavedData->FindKey("Secure", false))
|
||||
{
|
||||
bool secure = m_pSavedData->GetBool("Secure");
|
||||
m_pSecureCheck->SetSelected(secure);
|
||||
}
|
||||
if (m_pSavedData->FindKey("ServerName", false))
|
||||
{
|
||||
const char *serverName = m_pSavedData->GetString("ServerName","");
|
||||
if (strlen(serverName) > 0)
|
||||
{
|
||||
SetControlString("ServerNameEdit", serverName);
|
||||
}
|
||||
}
|
||||
m_iPort = m_pSavedData->GetInt("Port", m_iPort);
|
||||
SetControlInt("PortEdit", m_iPort);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCreateMultiplayerGameServerPage::SetConfig(const char *serverName, const char *rconPassword, int maxPlayers, const char *mod, const char *map, int network, int secure, int port)
|
||||
{
|
||||
m_pSavedData->SetInt("MaxPlayers", maxPlayers);
|
||||
m_pSavedData->SetString("RconPassword", rconPassword);
|
||||
m_pSavedData->SetString("ServerName", serverName);
|
||||
m_pSavedData->SetString("MOD", mod);
|
||||
m_pSavedData->SetString("Map", map);
|
||||
m_pSavedData->SetInt("Secure", secure);
|
||||
m_pSavedData->SetInt("Network", network);
|
||||
m_pSavedData->SetInt("Port", port);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCreateMultiplayerGameServerPage::SaveConfig()
|
||||
{
|
||||
m_pSavedData->SaveToFile(g_pFullFileSystem, "Server.vdf", "CONFIG");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns true if one of the characters in the string is not a valid alpha numeric character
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CCreateMultiplayerGameServerPage::BadRconChars(const char *pass)
|
||||
{
|
||||
bool bad = false;
|
||||
|
||||
for(unsigned int i=0;i<strlen(pass);i++)
|
||||
{
|
||||
bad |= !( V_isalnum(pass[i]) ? true : false );
|
||||
}
|
||||
return bad;
|
||||
}
|
||||
|
||||
const char *ToString( int val )
|
||||
{
|
||||
static char text[256];
|
||||
Q_snprintf( text, sizeof(text), "%i", val );
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called to get the info from the dialog
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCreateMultiplayerGameServerPage::OnCommand(const char *cmd)
|
||||
{
|
||||
char cvars[1024];
|
||||
int secure = GetControlInt("SecureCheck", 1);
|
||||
m_pNumPlayers->GetText(cvars, 1024);
|
||||
m_iMaxPlayers = atoi(cvars);
|
||||
V_strcpy_safe(m_szHostName, GetControlString("ServerNameEdit", ""));
|
||||
V_strcpy_safe(m_szPassword, GetControlString("RCONPasswordEdit", ""));
|
||||
m_iPort = GetControlInt("PortEdit", 27015);
|
||||
|
||||
if (!stricmp(cmd, "cancel"))
|
||||
{
|
||||
vgui::ivgui()->PostMessage( m_MainPanel->GetVPanel(), new KeyValues("Quit"), NULL);
|
||||
Close();
|
||||
}
|
||||
else if (!stricmp(cmd, "start"))
|
||||
{
|
||||
// save our current settings
|
||||
SetConfig(m_szHostName, m_szPassword, m_iMaxPlayers, m_szMod, GetMapName(), m_pNetworkCombo->GetActiveItem() != 0, secure, m_iPort);
|
||||
SaveConfig();
|
||||
|
||||
// create the command to execute
|
||||
bool isLanOnly = (m_pNetworkCombo->GetActiveItem() != 0);
|
||||
CommandLine()->AppendParm("-game", m_szMod);
|
||||
CommandLine()->AppendParm("-maxplayers", ToString(m_iMaxPlayers));
|
||||
CommandLine()->AppendParm("+sv_lan", ToString(isLanOnly));
|
||||
CommandLine()->AppendParm("+map", GetMapName());
|
||||
CommandLine()->AppendParm("-port", ToString(m_iPort));
|
||||
if (!secure) // if they don't want it secure...
|
||||
{
|
||||
CommandLine()->AppendParm("-insecure", "");
|
||||
}
|
||||
|
||||
|
||||
// strncpy(m_szPassword, GetControlString("RCONPasswordEdit", ""), DATA_STR_LENGTH);
|
||||
if (strlen(m_szPassword) < 3 || BadRconChars(m_szPassword))
|
||||
{
|
||||
MessageBox *dlg = new MessageBox("#Start_Server_RCON_Error_Title", "#Start_Server_RCON_Error");
|
||||
dlg->DoModal();
|
||||
}
|
||||
else
|
||||
{
|
||||
_snprintf(cvars, 1024, "rcon_password \"%s\"\nsetmaster enable\nhostname \"%s\"\n", m_szPassword, m_szHostName);
|
||||
|
||||
m_pGameCombo->SetEnabled(false);
|
||||
m_pNumPlayers->SetEnabled(false);
|
||||
|
||||
netadr_t local;
|
||||
net->GetLocalIP(&local);
|
||||
local.port = ::htons(m_iPort);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_iServer.ip[i] = local.ip[i];
|
||||
}
|
||||
m_iServer.port = (local.port & 0xff) << 8 | (local.port & 0xff00) >> 8;;
|
||||
|
||||
V_strcpy_safe(m_iServer.name, m_szHostName);
|
||||
V_strcpy_safe(m_iServer.map, GetMapName());
|
||||
V_strcpy_safe(m_iServer.gameDir, m_szMod);
|
||||
m_iServer.maxPlayers = m_iMaxPlayers;
|
||||
|
||||
SetVisible(false);
|
||||
|
||||
// mount the caches
|
||||
KeyValues *gameData = m_pGameCombo->GetActiveItemUserData();
|
||||
if (CommandLine()->CheckParm("-steam"))
|
||||
{
|
||||
if (gameData)
|
||||
{
|
||||
KeyValues *pFileSystem = gameData->FindKey( "FileSystem" );
|
||||
if ( !pFileSystem )
|
||||
Error( "Game %s missing FileSystem key.", gameData->GetString( "game" ) );
|
||||
|
||||
// Mods just specify their app ID (CS, HL2, HL2MP, etc), and it mounts all the necessary caches.
|
||||
int iAppId = pFileSystem->GetInt( "SteamAppId" );
|
||||
if ( iAppId )
|
||||
{
|
||||
CUtlVector<unsigned int> depList;
|
||||
MountDependencies( iAppId, depList );
|
||||
|
||||
char gameinfoFilename[MAX_PATH];
|
||||
Q_snprintf( gameinfoFilename, sizeof( gameinfoFilename ), "%s\\gameinfo.txt", m_iServer.gameDir );
|
||||
g_pFullFileSystem->GetLocalCopy( gameinfoFilename );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Launch the old dedicated server if necessary.
|
||||
if ( LaunchOldDedicatedServer( gameData ) )
|
||||
{
|
||||
vgui::ivgui()->PostMessage( m_MainPanel->GetVPanel(), new KeyValues("Quit"), NULL);
|
||||
Close();
|
||||
}
|
||||
|
||||
CMainPanel::GetInstance()->StartServer(cvars);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CCreateMultiplayerGameServerPage::LaunchOldDedicatedServer( KeyValues *pGameInfo )
|
||||
{
|
||||
#if defined( ALLOW_OLD_ENGINE_GAMES )
|
||||
// Validate the gameinfo.txt format..
|
||||
KeyValues *pSub = pGameInfo->FindKey( "FileSystem" );
|
||||
if ( pSub )
|
||||
{
|
||||
int iSteamAppId = pSub->GetInt( "SteamAppId", -1 );
|
||||
if ( iSteamAppId != -1 )
|
||||
{
|
||||
if ( IsEp1EraAppID( iSteamAppId ) )
|
||||
{
|
||||
// Old-skool app. Launch the old dedicated server.
|
||||
char steamDir[MAX_PATH];
|
||||
if ( !system()->GetRegistryString( "HKEY_CURRENT_USER\\Software\\Valve\\Steam\\SteamPath", steamDir, sizeof( steamDir ) ) )
|
||||
Error( "LaunchOldDedicatedServer: can't get SteamPath." );
|
||||
|
||||
V_FixSlashes( steamDir );
|
||||
V_AppendSlash( steamDir, sizeof( steamDir ) );
|
||||
|
||||
char commandLine[1024 * 4];
|
||||
commandLine[0] = 0;
|
||||
V_snprintf( commandLine, sizeof( commandLine ), "\"%ssteam.exe\" -applaunch 205 -HiddenLaunch", steamDir );
|
||||
|
||||
// Feed it all the parameters chosen in the UI so it doesn't redisplay the UI.
|
||||
STARTUPINFO si;
|
||||
memset( &si, 0, sizeof( si ) );
|
||||
si.cb = sizeof( si );
|
||||
|
||||
PROCESS_INFORMATION pi;
|
||||
if ( !CreateProcess( NULL, commandLine, NULL, NULL, false, 0, NULL, steamDir, &si, &pi ) )
|
||||
{
|
||||
Error( "LaunchOldDedicatedServer: Unable to launch old srcds." );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: loads the list of available maps into the map list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCreateMultiplayerGameServerPage::LoadMODList()
|
||||
{
|
||||
m_pGameCombo->DeleteAllItems();
|
||||
|
||||
// add steam games
|
||||
if (CommandLine()->CheckParm("-steam"))
|
||||
{
|
||||
const char *pSteamGamesFilename = "hlds_steamgames.vdf";
|
||||
|
||||
KeyValues *gamesFile = new KeyValues( pSteamGamesFilename );
|
||||
|
||||
if ( gamesFile->LoadFromFile( g_pFullFileSystem, pSteamGamesFilename, NULL ) )
|
||||
{
|
||||
for ( KeyValues *kv = gamesFile->GetFirstSubKey(); kv != NULL; kv = kv->GetNextKey() )
|
||||
{
|
||||
const char *pGameDir = kv->GetString( "gamedir", NULL );
|
||||
if ( !pGameDir )
|
||||
Error( "Mod %s in %s missing 'gamedir'.", kv->GetName(), pSteamGamesFilename );
|
||||
|
||||
AddMod( pGameDir, pSteamGamesFilename, kv );
|
||||
}
|
||||
}
|
||||
gamesFile->deleteThis();
|
||||
gamesFile = NULL;
|
||||
}
|
||||
|
||||
|
||||
// For backward compatibility, check inside the dedicated server's own directory for mods.
|
||||
LoadModListInDirectory( "." );
|
||||
|
||||
// Also, check in SourceMods.
|
||||
char sourceModsDir[MAX_PATH];
|
||||
if ( system()->GetRegistryString( "HKEY_CURRENT_USER\\Software\\Valve\\Steam\\SourceModInstallPath", sourceModsDir, sizeof( sourceModsDir ) ) )
|
||||
LoadModListInDirectory( sourceModsDir );
|
||||
|
||||
m_pGameCombo->ActivateItem(0);
|
||||
}
|
||||
|
||||
|
||||
void CCreateMultiplayerGameServerPage::LoadModListInDirectory( const char *pDirectoryName )
|
||||
{
|
||||
char searchString[MAX_PATH*2];
|
||||
Q_strncpy( searchString, pDirectoryName, sizeof( searchString ) );
|
||||
Q_AppendSlash( searchString, sizeof( searchString ) );
|
||||
Q_strncat( searchString, "*.*", sizeof( searchString ), COPY_ALL_CHARACTERS );
|
||||
|
||||
FileFindHandle_t findHandle = NULL;
|
||||
const char *filename = g_pFullFileSystem->FindFirst( searchString, &findHandle );
|
||||
while ( filename )
|
||||
{
|
||||
// add to the mod list
|
||||
if (filename[0] != '.' && g_pFullFileSystem->FindIsDirectory(findHandle))
|
||||
{
|
||||
char fullFilename[MAX_PATH];
|
||||
if ( Q_stricmp( pDirectoryName, "." ) == 0 )
|
||||
{
|
||||
// If we don't do this, then the games in hlds_steamgames.vdf will get listed twice
|
||||
// since their gamedir is listed as "cstrike" and "hl2mp", not ".\cstrike" or ".\hl2mp".
|
||||
Q_strncpy( fullFilename, filename, sizeof( fullFilename ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_strncpy( fullFilename, pDirectoryName, sizeof( fullFilename ) );
|
||||
Q_AppendSlash( fullFilename, sizeof( fullFilename ) );
|
||||
Q_strncat( fullFilename, filename, sizeof( fullFilename ), COPY_ALL_CHARACTERS );
|
||||
}
|
||||
|
||||
LoadPossibleMod( fullFilename );
|
||||
}
|
||||
|
||||
filename = g_pFullFileSystem->FindNext(findHandle);
|
||||
}
|
||||
g_pFullFileSystem->FindClose(findHandle);
|
||||
}
|
||||
|
||||
|
||||
void CCreateMultiplayerGameServerPage::LoadPossibleMod( const char *pGameDirName )
|
||||
{
|
||||
char gameInfoFilename[1024];
|
||||
Q_snprintf(gameInfoFilename, sizeof(gameInfoFilename) - 1, "%s\\gameinfo.txt", pGameDirName);
|
||||
if ( !g_pFullFileSystem->FileExists(gameInfoFilename) )
|
||||
return;
|
||||
|
||||
// don't want to add single player games to the list
|
||||
KeyValues *pGameInfo = new KeyValues( "GameInfo" );
|
||||
bool loadedFile = pGameInfo->LoadFromFile( g_pFullFileSystem, gameInfoFilename );
|
||||
if ( !loadedFile )
|
||||
return;
|
||||
|
||||
AddMod( pGameDirName, gameInfoFilename, pGameInfo );
|
||||
|
||||
pGameInfo->deleteThis();
|
||||
pGameInfo = NULL;
|
||||
}
|
||||
|
||||
|
||||
void CCreateMultiplayerGameServerPage::AddMod( const char *pGameDirName, const char *pGameInfoFilename, KeyValues *pGameInfo )
|
||||
{
|
||||
// Don't re-add something with the same gamedir name (this can happen with games listed in hlds_steamgames.vdf,
|
||||
// since after the first time a game is run, it'll also have a gameinfo.txt that will be found).
|
||||
for ( int i=0; i < m_pGameCombo->GetItemCount(); i++ )
|
||||
{
|
||||
if ( !m_pGameCombo->IsItemIDValid(i) )
|
||||
continue;
|
||||
|
||||
if ( Q_stricmp( m_pGameCombo->GetItemUserData(i)->GetString("gamedir"), pGameDirName ) == 0 )
|
||||
return;
|
||||
}
|
||||
|
||||
// If this mod supports multiplayer, then we'll add it.
|
||||
const char *gameType = pGameInfo->GetString( "type", "singleplayer_only" );
|
||||
if ( Q_stricmp(gameType, "singleplayer_only") != 0 )
|
||||
{
|
||||
// Validate the gameinfo.txt format..
|
||||
KeyValues *pSub = pGameInfo->FindKey( "FileSystem" );
|
||||
if ( !pSub )
|
||||
Error( "%s missing FileSystem key.", pGameInfoFilename );
|
||||
|
||||
int iSteamAppId = pSub->GetInt( "SteamAppId", -1 );
|
||||
if ( iSteamAppId == -1 )
|
||||
Error( "%s missing FileSystem\\SteamAppId key.", pGameInfoFilename );
|
||||
|
||||
#if !defined( ALLOW_OLD_ENGINE_GAMES )
|
||||
// If we're not supporting old games in here and its appid is old, forget about it.
|
||||
if ( IsEp1EraAppID( iSteamAppId ) )
|
||||
return;
|
||||
#endif
|
||||
|
||||
const char *gameName = pGameInfo->GetString( "game", NULL );
|
||||
if ( !gameName )
|
||||
Error( "%s missing 'game' key.", pGameInfoFilename );
|
||||
|
||||
|
||||
// add to drop-down combo and mod list
|
||||
KeyValues *kv = pGameInfo->MakeCopy();
|
||||
kv->SetString( "gamedir", pGameDirName );
|
||||
|
||||
m_pGameCombo->AddItem( gameName, kv );
|
||||
|
||||
kv->deleteThis();
|
||||
kv = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: loads the list of available maps for the given path into the map list
|
||||
// Returns: number of maps loaded into the list
|
||||
//-----------------------------------------------------------------------------
|
||||
int CCreateMultiplayerGameServerPage::LoadMaps( const char *pszMod )
|
||||
{
|
||||
// iterate the filesystem getting the list of all the files
|
||||
// UNDONE: steam wants this done in a special way, need to support that
|
||||
FileFindHandle_t findHandle = NULL;
|
||||
char szSearch[256];
|
||||
sprintf( szSearch, "%s/maps/*.bsp", pszMod );
|
||||
|
||||
int iMapsFound = 0;
|
||||
|
||||
const char *pszFilename = g_pFullFileSystem->FindFirst( szSearch, &findHandle );
|
||||
|
||||
KeyValues *hiddenMaps = NULL;
|
||||
if ( m_pGameInfo )
|
||||
{
|
||||
hiddenMaps = m_pGameInfo->FindKey( "hidden_maps" );
|
||||
}
|
||||
|
||||
while ( pszFilename )
|
||||
{
|
||||
// remove the text 'maps/' and '.bsp' from the file name to get the map name
|
||||
char mapname[256];
|
||||
const char *str = strstr( pszFilename, "maps" );
|
||||
if ( str )
|
||||
{
|
||||
V_strcpy_safe( mapname, str + 5 ); // maps + \\ = 5
|
||||
}
|
||||
else
|
||||
{
|
||||
V_strcpy_safe( mapname, pszFilename );
|
||||
}
|
||||
|
||||
char *ext = strstr( mapname, ".bsp" );
|
||||
if ( ext )
|
||||
{
|
||||
*ext = 0;
|
||||
}
|
||||
|
||||
//!! hack: strip out single player HL maps
|
||||
// this needs to be specified in a seperate file
|
||||
if ( ( mapname[0] == 'c' || mapname[0] == 't' ) && mapname[2] == 'a' && mapname[1] >= '0' && mapname[1] <= '5' )
|
||||
{
|
||||
goto nextFile;
|
||||
}
|
||||
|
||||
// strip out maps that shouldn't be displayed
|
||||
if ( hiddenMaps )
|
||||
{
|
||||
if ( hiddenMaps->GetInt( mapname, 0 ) )
|
||||
{
|
||||
goto nextFile;
|
||||
}
|
||||
}
|
||||
|
||||
iMapsFound++;
|
||||
|
||||
// add to the map list
|
||||
m_pMapList->AddItem( mapname, NULL );
|
||||
|
||||
// get the next file
|
||||
nextFile:
|
||||
pszFilename = g_pFullFileSystem->FindNext( findHandle );
|
||||
}
|
||||
|
||||
g_pFullFileSystem->FindClose( findHandle );
|
||||
|
||||
return iMapsFound;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: loads the list of available maps into the map list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCreateMultiplayerGameServerPage::LoadMapList()
|
||||
{
|
||||
int iMapsFound = 0;
|
||||
|
||||
// clear the current list (if any)
|
||||
m_pMapList->DeleteAllItems();
|
||||
|
||||
Assert( strlen(m_szMod ) > 0);
|
||||
if ( strlen( m_szMod ) < 1)
|
||||
{
|
||||
m_pMapList->SetEnabled( false );
|
||||
return;
|
||||
}
|
||||
|
||||
m_pMapList->SetEnabled( true );
|
||||
m_pStartServerButton->SetEnabled( true );
|
||||
|
||||
if ( CommandLine()->CheckParm( "-steam" ) )
|
||||
{
|
||||
KeyValues *userData = m_pGameCombo->GetActiveItemUserData();
|
||||
if ( userData && userData->GetString( "DedicatedServerStartMap", NULL ) )
|
||||
{
|
||||
// set only
|
||||
m_pMapList->AddItem( userData->GetString( "DedicatedServerStartMap" ), NULL );
|
||||
m_pMapList->ActivateItemByRow( 0 );
|
||||
m_pMapList->SetEnabled( false );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Load the maps for the GameDir
|
||||
iMapsFound += LoadMaps( m_szMod );
|
||||
|
||||
// If we're using a "fallback_dir" in liblist.gam then include those maps...
|
||||
const char *pszFallback = GetLiblistFallbackDir( m_szMod );
|
||||
if ( pszFallback[0] )
|
||||
{
|
||||
iMapsFound += LoadMaps( pszFallback );
|
||||
}
|
||||
|
||||
if ( iMapsFound < 1 )
|
||||
{
|
||||
m_pMapList->SetEnabled( false );
|
||||
}
|
||||
|
||||
// set the first item to be selected
|
||||
m_pMapList->ActivateItemByRow( 0 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the name of the map selected from the map combo
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CCreateMultiplayerGameServerPage::GetMapName()
|
||||
{
|
||||
m_pMapList->GetText(m_szMapName, DATA_STR_LENGTH);
|
||||
return m_szMapName;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CCreateMultiplayerGameServerPage::GetRconPassword()
|
||||
{
|
||||
return m_szPassword;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: updates "s" with the details of the chosen server to run
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCreateMultiplayerGameServerPage::GetServer(serveritem_t &s)
|
||||
{
|
||||
s=m_iServer;
|
||||
strcpy(s.name,m_iServer.name);
|
||||
strcpy(s.rconPassword,m_iServer.rconPassword);
|
||||
memcpy(s.ip,m_iServer.ip,sizeof(m_iServer.ip));
|
||||
memcpy(s.pings,m_iServer.pings,3*sizeof(int));
|
||||
strcpy(s.gameDir,m_iServer.gameDir);
|
||||
strcpy(s.map,m_iServer.map);
|
||||
strcpy(s.gameDescription,m_iServer.gameDescription);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handles changes to combo boxes
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCreateMultiplayerGameServerPage::OnTextChanged(Panel *panel)
|
||||
{
|
||||
if (panel == m_pGameCombo)
|
||||
{
|
||||
// see if we should update the game name
|
||||
bool updateHostname = false;
|
||||
char hostname[256];
|
||||
GetControlString("ServerNameEdit", m_szHostName, sizeof(m_szHostName));
|
||||
_snprintf(hostname, sizeof(hostname) - 1, "%s dedicated server", m_szGameName);
|
||||
if (!stricmp(m_szHostName, hostname))
|
||||
{
|
||||
updateHostname = true;
|
||||
}
|
||||
|
||||
// update the game name
|
||||
m_pGameCombo->GetText( m_szGameName, sizeof(m_szGameName) );
|
||||
|
||||
|
||||
// Copy the gamedir into m_szMod.
|
||||
KeyValues *gameData = m_pGameCombo->GetActiveItemUserData();
|
||||
if ( !gameData )
|
||||
Error( "Missing gameData for active item." );
|
||||
|
||||
const char *pGameDir = gameData->GetString( "gamedir", NULL );
|
||||
if ( !pGameDir )
|
||||
Error( "Game %s missing 'gamedir' key.", m_szGameName );
|
||||
|
||||
Q_strncpy( m_szMod, pGameDir, sizeof( m_szMod ) );
|
||||
|
||||
|
||||
// re-load the GameInfo KeyValues
|
||||
if ( m_pGameInfo )
|
||||
{
|
||||
m_pGameInfo->deleteThis();
|
||||
}
|
||||
char liblist[1024];
|
||||
Q_snprintf(liblist, sizeof(liblist) - 1, "%s\\gameinfo.txt", m_szMod);
|
||||
m_pGameInfo = new KeyValues( "GameInfo" );
|
||||
m_pGameInfo->LoadFromFile( g_pFullFileSystem, liblist );
|
||||
|
||||
// redo the hostname with the new game name
|
||||
if (updateHostname)
|
||||
{
|
||||
_snprintf(hostname, sizeof(hostname) - 1, "%s dedicated server", m_szGameName);
|
||||
SetControlString("ServerNameEdit", hostname);
|
||||
}
|
||||
|
||||
// reload the list of maps we display
|
||||
LoadMapList();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
126
dedicated/vgui/CreateMultiplayerGameServerPage.h
Normal file
126
dedicated/vgui/CreateMultiplayerGameServerPage.h
Normal file
@@ -0,0 +1,126 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef CREATEMULTIPLAYERGAMESERVERPAGE_H
|
||||
#define CREATEMULTIPLAYERGAMESERVERPAGE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <vgui_controls/Frame.h>
|
||||
#include <vgui_controls/Button.h>
|
||||
#include <vgui_controls/ComboBox.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Data describing a single server
|
||||
//-----------------------------------------------------------------------------
|
||||
struct serveritem_t
|
||||
{
|
||||
serveritem_t()
|
||||
{
|
||||
pings[0] = 0;
|
||||
pings[1] = 0;
|
||||
pings[2] = 0;
|
||||
}
|
||||
|
||||
unsigned char ip[4];
|
||||
int port;
|
||||
int received;
|
||||
float time;
|
||||
int ping; // current ping time, derived from pings[]
|
||||
int pings[3]; // last 3 ping times
|
||||
bool hadSuccessfulResponse; // server has responded successfully in the past
|
||||
bool doNotRefresh; // server is marked as not responding and should no longer be refreshed
|
||||
char gameDir[32]; // current game directory
|
||||
char map[32]; // current map
|
||||
char gameDescription[64]; // game description
|
||||
char name[64]; // server name
|
||||
int players;
|
||||
int maxPlayers;
|
||||
int botPlayers;
|
||||
bool proxy;
|
||||
bool password;
|
||||
bool secure;
|
||||
bool loadedFromFile; // true if this entry was loaded from file rather than comming from the master
|
||||
unsigned int serverID;
|
||||
int listEntryID;
|
||||
char rconPassword[64]; // the rcon password for this server
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: server options page of the create game server dialog
|
||||
//-----------------------------------------------------------------------------
|
||||
class CCreateMultiplayerGameServerPage : public vgui::Frame
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CCreateMultiplayerGameServerPage, vgui::Frame );
|
||||
public:
|
||||
CCreateMultiplayerGameServerPage(vgui::Panel *parent, const char *name);
|
||||
~CCreateMultiplayerGameServerPage();
|
||||
|
||||
// returns currently entered information about the server
|
||||
int GetMaxPlayers() { return m_iMaxPlayers; }
|
||||
const char *GetPassword() { return m_szPassword; }
|
||||
const char *GetHostName() { return m_szHostName; }
|
||||
const char *GetMapName();
|
||||
const char *GetModName() { return m_szMod; }
|
||||
const char *GetGameName() { return m_szGameName; }
|
||||
void LoadMapList();
|
||||
int LoadMaps( const char *pszMod );
|
||||
|
||||
virtual void OnCommand(const char *cmd);
|
||||
|
||||
virtual void OnResetData();
|
||||
|
||||
void GetServer(serveritem_t &s);
|
||||
const char *GetRconPassword();
|
||||
|
||||
private:
|
||||
enum { MAX_PLAYERS = 32 };
|
||||
enum { DATA_STR_LENGTH = 64 };
|
||||
|
||||
void LoadConfig();
|
||||
void SaveConfig();
|
||||
void SetConfig(const char *serverName, const char *rconPassword, int maxPlayers, const char *map, const char *mod, int network, int secure, int port);
|
||||
|
||||
bool LaunchOldDedicatedServer( KeyValues *pGameInfo );
|
||||
|
||||
//void OnCommand(const char *text);
|
||||
void LoadMODList();
|
||||
void LoadModListInDirectory( const char *pDirectoryName );
|
||||
void LoadPossibleMod( const char *pGameDirName );
|
||||
void AddMod( const char *pGameDirName, const char *pGameInfoFilename, KeyValues *pGameInfo );
|
||||
|
||||
bool BadRconChars(const char *pass);
|
||||
|
||||
vgui::ComboBox *m_pGameCombo;
|
||||
vgui::ComboBox *m_pMapList;
|
||||
vgui::ComboBox *m_pNumPlayers;
|
||||
vgui::ComboBox *m_pNetworkCombo;
|
||||
vgui::Button *m_pStartServerButton;
|
||||
vgui::Button *m_pCancelButton;
|
||||
vgui::CheckButton *m_pSecureCheck;
|
||||
|
||||
MESSAGE_FUNC_PTR( OnTextChanged, "TextChanged", panel );
|
||||
|
||||
serveritem_t m_iServer;
|
||||
|
||||
char m_szHostName[DATA_STR_LENGTH];
|
||||
char m_szPassword[DATA_STR_LENGTH];
|
||||
char m_szMapName[DATA_STR_LENGTH];
|
||||
char m_szMod[DATA_STR_LENGTH];
|
||||
char m_szGameName[DATA_STR_LENGTH];
|
||||
char m_szExtra[DATA_STR_LENGTH*2];
|
||||
int m_iMaxPlayers;
|
||||
int m_iPort;
|
||||
|
||||
vgui::Panel *m_MainPanel;
|
||||
KeyValues *m_pSavedData; // data to save away
|
||||
KeyValues *m_pGameInfo;
|
||||
};
|
||||
|
||||
|
||||
#endif // CREATEMULTIPLAYERGAMESERVERPAGE_H
|
||||
274
dedicated/vgui/MainPanel.cpp
Normal file
274
dedicated/vgui/MainPanel.cpp
Normal file
@@ -0,0 +1,274 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifdef _WIN32
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <windows.h>
|
||||
// base vgui interfaces
|
||||
#include <vgui/vgui.h>
|
||||
#include <vgui_controls/Panel.h>
|
||||
#include <vgui/IVGui.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include <vgui/Cursor.h>
|
||||
#include <vgui_controls/ProgressBox.h>
|
||||
|
||||
#include "filesystem.h"
|
||||
#include "IAdminServer.h"
|
||||
|
||||
#include "MainPanel.h"
|
||||
#include <imanageserver.h>
|
||||
#include "ivguimodule.h"
|
||||
#include <vgui/IVGui.h>
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
static CMainPanel *s_InternetDlg = NULL;
|
||||
CSysModule *g_hAdminServerModule = NULL;
|
||||
extern IAdminServer *g_pAdminServer;
|
||||
char *gpszCvars = NULL;
|
||||
|
||||
|
||||
void Sys_Sleep_Old( int msec );
|
||||
|
||||
extern BOOL gbAppHasBeenTerminated; // used to signal the server thread
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CMainPanel::CMainPanel( ) : Panel(NULL, "CMainPanel")
|
||||
{
|
||||
SetPaintBackgroundEnabled( false );
|
||||
SetFgColor( Color( 0,0,0,0 ) );
|
||||
m_bStarting = false;
|
||||
m_flPreviousSteamProgress = 0.0f;
|
||||
m_pGameServer= NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CMainPanel::~CMainPanel()
|
||||
{
|
||||
if (gpszCvars)
|
||||
{
|
||||
free(gpszCvars);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called once to set up
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMainPanel::Initialize( )
|
||||
{
|
||||
s_InternetDlg = this;
|
||||
m_pGameServer = NULL;
|
||||
|
||||
m_bStarted = false;
|
||||
m_bIsInConfig = true;
|
||||
m_bClosing = false;
|
||||
m_pProgressBox = NULL;
|
||||
m_hShutdown = NULL;
|
||||
|
||||
MoveToFront();
|
||||
|
||||
m_pConfigPage = new CCreateMultiplayerGameServerPage(this, "Config");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMainPanel::Open( void )
|
||||
{
|
||||
m_pConfigPage->SetVisible(true);
|
||||
m_pConfigPage->MoveToFront();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMainPanel::OnClose()
|
||||
{
|
||||
DoStop();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns a pointer to a static instance of this dialog
|
||||
//-----------------------------------------------------------------------------
|
||||
CMainPanel *CMainPanel::GetInstance()
|
||||
{
|
||||
return s_InternetDlg;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Changes to the console page and starts up the actual server
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMainPanel::StartServer(const char *cvars)
|
||||
{
|
||||
surface()->SetCursor(dc_hourglass);
|
||||
m_pConfigPage->GetServer(s1);
|
||||
|
||||
// hide the config page and close it
|
||||
m_pConfigPage->SetVisible(false);
|
||||
m_pConfigPage->Close();
|
||||
|
||||
gpszCvars = strdup(cvars);
|
||||
|
||||
// show the basic progress box immediately
|
||||
m_pProgressBox = new ProgressBox("#Start_Server_Loading_Title", "#Server_UpdatingSteamResources", "Starting dedicated server...");
|
||||
m_pProgressBox->SetCancelButtonVisible(true);
|
||||
m_pProgressBox->ShowWindow();
|
||||
|
||||
// make sure we have all the steam content for this mod
|
||||
char reslist[_MAX_PATH];
|
||||
_snprintf(reslist, sizeof(reslist), "reslists/%s/preload.lst", m_pConfigPage->GetGameName());
|
||||
m_hResourceWaitHandle = g_pFullFileSystem->WaitForResources(reslist);
|
||||
if (!m_hResourceWaitHandle)
|
||||
{
|
||||
Assert( 0 );
|
||||
}
|
||||
|
||||
m_pProgressBox->SetCancelButtonEnabled(false);
|
||||
|
||||
m_hShutdown = CreateEvent( NULL, TRUE, FALSE, NULL );
|
||||
ivgui()->AddTickSignal(GetVPanel());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: lets us delay the loading of the management screen until the server has started
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMainPanel::OnTick()
|
||||
{
|
||||
if (m_hResourceWaitHandle)
|
||||
{
|
||||
// see if we've been cancelled
|
||||
if (!m_pProgressBox.Get() || !m_pProgressBox->IsVisible())
|
||||
{
|
||||
// cancel out
|
||||
g_pFullFileSystem->CancelWaitForResources(m_hResourceWaitHandle);
|
||||
m_hResourceWaitHandle = NULL;
|
||||
DoStop();
|
||||
return;
|
||||
}
|
||||
|
||||
// update resource waiting
|
||||
bool complete;
|
||||
float progress;
|
||||
if (g_pFullFileSystem->GetWaitForResourcesProgress(m_hResourceWaitHandle, &progress, &complete))
|
||||
{
|
||||
vgui::ivgui()->DPrintf2( "progress %.2f %s\n", progress, complete ? "not complete" : "complete" );
|
||||
|
||||
// don't set the progress if we've jumped straight from 0 to 100% complete
|
||||
if (!(progress == 1.0f && m_flPreviousSteamProgress == 0.0f))
|
||||
{
|
||||
m_pProgressBox->SetProgress(progress);
|
||||
m_flPreviousSteamProgress = progress;
|
||||
}
|
||||
}
|
||||
|
||||
// This is here because without it, the dedicated server will consume a lot of CPU and it will slow Steam down
|
||||
// so much that it'll download at 64k instead of 6M.
|
||||
Sleep( 200 );
|
||||
|
||||
// see if we're done
|
||||
if (complete)
|
||||
{
|
||||
m_hResourceWaitHandle = NULL;
|
||||
m_bStarting = true;
|
||||
m_bIsInConfig = false;
|
||||
// at this stage in the process the user can no longer cancel
|
||||
m_pProgressBox->SetCancelButtonEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_bStarting) // if we are actively launching the app
|
||||
{
|
||||
static int count = 0;
|
||||
if (WAIT_OBJECT_0 == WaitForSingleObject(m_hShutdown, 10) || count > 5000)
|
||||
{
|
||||
if (!m_bStarted)
|
||||
{
|
||||
serveritem_t server;
|
||||
m_pConfigPage->GetServer(server);
|
||||
ManageServerUIHandle_t managePage = g_pAdminServer->OpenManageServerDialog(server.name, server.gameDir);
|
||||
m_pGameServer = g_pAdminServer->GetManageServerInterface(managePage);
|
||||
m_bStarted = true;
|
||||
|
||||
if (m_pProgressBox)
|
||||
{
|
||||
m_pProgressBox->Close();
|
||||
m_pProgressBox = NULL;
|
||||
}
|
||||
}
|
||||
else // must be stopping the server
|
||||
{
|
||||
DoStop();
|
||||
}
|
||||
|
||||
surface()->SetCursor(dc_user);
|
||||
m_bStarting = false;
|
||||
ResetEvent(m_hShutdown);
|
||||
}
|
||||
else
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: stops VGUI and kills any progress dialog we may have been displaying
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMainPanel::DoStop()
|
||||
{
|
||||
surface()->SetCursor(dc_user);
|
||||
|
||||
m_bStarted = false;
|
||||
m_bClosing = true;
|
||||
|
||||
if (m_pProgressBox)
|
||||
{
|
||||
m_pProgressBox->Close();
|
||||
m_pProgressBox = NULL;
|
||||
}
|
||||
|
||||
ivgui()->Stop();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Pushes text into the console
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMainPanel::AddConsoleText(const char *msg)
|
||||
{
|
||||
if (m_pGameServer)
|
||||
{
|
||||
m_pGameServer->AddToConsole(msg);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Message map
|
||||
//-----------------------------------------------------------------------------
|
||||
MessageMapItem_t CMainPanel::m_MessageMap[] =
|
||||
{
|
||||
MAP_MESSAGE( CMainPanel, "Quit", OnClose ),
|
||||
};
|
||||
|
||||
IMPLEMENT_PANELMAP(CMainPanel, BaseClass);
|
||||
|
||||
#endif // _WIN32
|
||||
89
dedicated/vgui/MainPanel.h
Normal file
89
dedicated/vgui/MainPanel.h
Normal file
@@ -0,0 +1,89 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
#ifndef CMAINPANEL_H
|
||||
#define CMAINPANEL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <vgui_controls/Frame.h>
|
||||
#include <vgui_controls/Panel.h>
|
||||
#include <vgui_controls/ListPanel.h>
|
||||
#include <vgui_controls/PHandle.h>
|
||||
#include "utlvector.h"
|
||||
|
||||
//#include <GamePanelInfo.h>
|
||||
|
||||
#include "imanageserver.h"
|
||||
//#include "gameserver.h"
|
||||
#include "CreateMultiplayerGameServerPage.h"
|
||||
|
||||
class IAdminServer;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Root panel for dedicated server GUI
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMainPanel : public vgui::Panel
|
||||
{
|
||||
public:
|
||||
// Construction/destruction
|
||||
CMainPanel( );
|
||||
virtual ~CMainPanel();
|
||||
|
||||
virtual void Initialize( );
|
||||
|
||||
// displays the dialog, moves it into focus, updates if it has to
|
||||
virtual void Open( void );
|
||||
|
||||
// returns a pointer to a static instance of this dialog
|
||||
// valid for use only in sort functions
|
||||
static CMainPanel *GetInstance();
|
||||
virtual void StartServer(const char *cvars);
|
||||
|
||||
void ActivateBuildMode();
|
||||
|
||||
void *GetShutdownHandle() { return m_hShutdown; }
|
||||
|
||||
void AddConsoleText(const char *msg);
|
||||
|
||||
bool Stopping() { return m_bClosing; }
|
||||
|
||||
bool IsInConfig() { return m_bIsInConfig; }
|
||||
|
||||
private:
|
||||
|
||||
// called when dialog is shut down
|
||||
virtual void OnClose();
|
||||
virtual void OnTick();
|
||||
void DoStop();
|
||||
|
||||
// GUI elements
|
||||
IManageServer *m_pGameServer;
|
||||
|
||||
// the popup menu
|
||||
vgui::DHANDLE<vgui::ProgressBox> m_pProgressBox;
|
||||
CCreateMultiplayerGameServerPage *m_pConfigPage;
|
||||
|
||||
// Event that lets the thread tell the main window it shutdown
|
||||
void *m_hShutdown;
|
||||
|
||||
bool m_bStarting; // whether the server is currently starting
|
||||
bool m_bStarted; // whether the server has been started or not
|
||||
bool m_bClosing; // whether we are shutting down
|
||||
bool m_bIsInConfig;
|
||||
serveritem_t s1;
|
||||
int m_hResourceWaitHandle;
|
||||
float m_flPreviousSteamProgress;
|
||||
|
||||
typedef vgui::Panel BaseClass;
|
||||
DECLARE_PANELMAP();
|
||||
|
||||
};
|
||||
|
||||
#endif // CMAINPANEL_H
|
||||
187
dedicated/vgui/vguihelpers.cpp
Normal file
187
dedicated/vgui/vguihelpers.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <direct.h>
|
||||
|
||||
// includes for the VGUI version
|
||||
#include <vgui_controls/Panel.h>
|
||||
#include <vgui_controls/Controls.h>
|
||||
#include <vgui/ISystem.h>
|
||||
#include <vgui/IVGui.h>
|
||||
#include <vgui/IPanel.h>
|
||||
#include "filesystem.h"
|
||||
#include <vgui/ILocalize.h>
|
||||
#include <vgui/IScheme.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include <IVGuiModule.h>
|
||||
|
||||
#include "vgui/MainPanel.h"
|
||||
#include "IAdminServer.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
static CMainPanel *g_pMainPanel = NULL; // the main panel to show
|
||||
static CSysModule *g_hAdminServerModule;
|
||||
IAdminServer *g_pAdminServer = NULL;
|
||||
static IVGuiModule *g_pAdminVGuiModule = NULL;
|
||||
|
||||
void* DedicatedFactory(const char *pName, int *pReturnCode);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Starts up the VGUI system and loads the base panel
|
||||
//-----------------------------------------------------------------------------
|
||||
int StartVGUI( CreateInterfaceFn dedicatedFactory )
|
||||
{
|
||||
// the "base dir" so we can scan mod name
|
||||
g_pFullFileSystem->AddSearchPath(".", "MAIN");
|
||||
// the main platform dir
|
||||
g_pFullFileSystem->AddSearchPath( "platform", "PLATFORM", PATH_ADD_TO_HEAD);
|
||||
|
||||
vgui::ivgui()->SetSleep(false);
|
||||
|
||||
// find our configuration directory
|
||||
char szConfigDir[512];
|
||||
const char *steamPath = getenv("SteamInstallPath");
|
||||
if (steamPath)
|
||||
{
|
||||
// put the config dir directly under steam
|
||||
Q_snprintf(szConfigDir, sizeof(szConfigDir), "%s/config", steamPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we're not running steam, so just put the config dir under the platform
|
||||
Q_strncpy( szConfigDir, "platform/config", sizeof(szConfigDir));
|
||||
}
|
||||
g_pFullFileSystem->CreateDirHierarchy("config", "PLATFORM");
|
||||
g_pFullFileSystem->AddSearchPath(szConfigDir, "CONFIG", PATH_ADD_TO_HEAD);
|
||||
|
||||
// initialize the user configuration file
|
||||
vgui::system()->SetUserConfigFile("DedicatedServerDialogConfig.vdf", "CONFIG");
|
||||
|
||||
// Init the surface
|
||||
g_pMainPanel = new CMainPanel( );
|
||||
g_pMainPanel->SetVisible(true);
|
||||
|
||||
vgui::surface()->SetEmbeddedPanel(g_pMainPanel->GetVPanel());
|
||||
|
||||
// load the scheme
|
||||
vgui::scheme()->LoadSchemeFromFile("Resource/SourceScheme.res", "SourceScheme");
|
||||
|
||||
// localization
|
||||
g_pVGuiLocalize->AddFile( "Resource/platform_%language%.txt" );
|
||||
g_pVGuiLocalize->AddFile( "Resource/vgui_%language%.txt" );
|
||||
g_pVGuiLocalize->AddFile( "Admin/server_%language%.txt" );
|
||||
|
||||
// Start vgui
|
||||
vgui::ivgui()->Start();
|
||||
|
||||
// load the module
|
||||
g_pFullFileSystem->GetLocalCopy("bin/AdminServer.dll");
|
||||
g_hAdminServerModule = g_pFullFileSystem->LoadModule("AdminServer");
|
||||
Assert(g_hAdminServerModule != NULL);
|
||||
CreateInterfaceFn adminFactory = NULL;
|
||||
|
||||
if (!g_hAdminServerModule)
|
||||
{
|
||||
vgui::ivgui()->DPrintf2("Admin Error: module version (Admin/AdminServer.dll, %s) invalid, not loading\n", IMANAGESERVER_INTERFACE_VERSION );
|
||||
}
|
||||
else
|
||||
{
|
||||
// make sure we get the right version
|
||||
adminFactory = Sys_GetFactory(g_hAdminServerModule);
|
||||
g_pAdminServer = (IAdminServer *)adminFactory(ADMINSERVER_INTERFACE_VERSION, NULL);
|
||||
g_pAdminVGuiModule = (IVGuiModule *)adminFactory("VGuiModuleAdminServer001", NULL);
|
||||
Assert(g_pAdminServer != NULL);
|
||||
Assert(g_pAdminVGuiModule != NULL);
|
||||
if (!g_pAdminServer || !g_pAdminVGuiModule)
|
||||
{
|
||||
vgui::ivgui()->DPrintf2("Admin Error: module version (Admin/AdminServer.dll, %s) invalid, not loading\n", IMANAGESERVER_INTERFACE_VERSION );
|
||||
}
|
||||
}
|
||||
|
||||
// finish initializing admin module
|
||||
g_pAdminVGuiModule->Initialize( &dedicatedFactory, 1 );
|
||||
g_pAdminVGuiModule->PostInitialize(&adminFactory, 1);
|
||||
g_pAdminVGuiModule->SetParent( g_pMainPanel->GetVPanel() );
|
||||
|
||||
// finish setting up main panel
|
||||
g_pMainPanel->Initialize( );
|
||||
g_pMainPanel->Open();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Shuts down the VGUI system
|
||||
//-----------------------------------------------------------------------------
|
||||
void StopVGUI()
|
||||
{
|
||||
SetEvent(g_pMainPanel->GetShutdownHandle());
|
||||
|
||||
delete g_pMainPanel;
|
||||
g_pMainPanel = NULL;
|
||||
|
||||
if (g_hAdminServerModule)
|
||||
{
|
||||
g_pAdminVGuiModule->Shutdown( );
|
||||
Sys_UnloadModule(g_hAdminServerModule);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Run a single VGUI frame
|
||||
//-----------------------------------------------------------------------------
|
||||
void RunVGUIFrame()
|
||||
{
|
||||
vgui::ivgui()->RunFrame();
|
||||
}
|
||||
|
||||
|
||||
bool VGUIIsStopping()
|
||||
{
|
||||
return g_pMainPanel->Stopping();
|
||||
}
|
||||
|
||||
|
||||
bool VGUIIsRunning()
|
||||
{
|
||||
return vgui::ivgui()->IsRunning();
|
||||
}
|
||||
|
||||
bool VGUIIsInConfig()
|
||||
{
|
||||
return g_pMainPanel->IsInConfig();
|
||||
}
|
||||
|
||||
void VGUIFinishedConfig()
|
||||
{
|
||||
Assert( g_pMainPanel );
|
||||
if(g_pMainPanel) // engine is loaded, pass the message on
|
||||
{
|
||||
SetEvent(g_pMainPanel->GetShutdownHandle());
|
||||
}
|
||||
}
|
||||
|
||||
void VGUIPrintf( const char *msg )
|
||||
{
|
||||
if ( !g_pMainPanel || VGUIIsInConfig() || VGUIIsStopping() )
|
||||
{
|
||||
::MessageBox( NULL, msg, "Dedicated Server Message", MB_OK | MB_TOPMOST );
|
||||
}
|
||||
else if ( g_pMainPanel )
|
||||
{
|
||||
g_pMainPanel->AddConsoleText( msg );
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
26
dedicated/vgui/vguihelpers.h
Normal file
26
dedicated/vgui/vguihelpers.h
Normal file
@@ -0,0 +1,26 @@
|
||||
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef VGUIHELPERS_H
|
||||
#define VGUIHELPERS_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier1/interface.h"
|
||||
|
||||
int StartVGUI( CreateInterfaceFn dedicatedFactory );
|
||||
void StopVGUI();
|
||||
void RunVGUIFrame();
|
||||
bool VGUIIsRunning();
|
||||
bool VGUIIsStopping();
|
||||
bool VGUIIsInConfig();
|
||||
void VGUIFinishedConfig();
|
||||
void VGUIPrintf( const char *msg );
|
||||
|
||||
#endif // VGUIHELPERS_H
|
||||
|
||||
39
dedicated/vgui/vguihelpers_linux.cpp
Normal file
39
dedicated/vgui/vguihelpers_linux.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "interface.h"
|
||||
|
||||
bool InitializeVGui(CreateInterfaceFn *factorylist, int factorycount)
|
||||
{
|
||||
}
|
||||
|
||||
int StartVGUI()
|
||||
{
|
||||
}
|
||||
|
||||
void StopVGUI()
|
||||
{
|
||||
}
|
||||
|
||||
void RunVGUIFrame()
|
||||
{
|
||||
}
|
||||
|
||||
bool VGUIIsRunning()
|
||||
{
|
||||
}
|
||||
|
||||
bool VGUIIsStopping()
|
||||
{
|
||||
}
|
||||
|
||||
bool VGUIIsInConfig()
|
||||
{
|
||||
}
|
||||
|
||||
void VGUIFinishedConfig()
|
||||
{
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user