CSGO Webinterface

T

tx_g

Gast
Hallo, ich bin gerade dabei mir ein kleines Webinterface für meinen CSGO Server zu bauen. Allerdings funktioniert das alles nicht so wie ich es mir gedacht habe.
Hier ist erst einmal der Code:
index.php
PHP:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="css.css">
</head>
<body>
<center>
<div class="box">
<div id="h1">CSGO SERVER</div>
<form action="#" method="post">
<?php include 'start.php';?>
<p>
</label>
	<label>Gamemode
    <select name="gm" size="1">
	  <option>-</option>
	<optgroup label="Classic Casual">
      <option>+game_type 0 +game_mode 0 </option>
	</optgroup>
	<optgroup label="Classic Competitive">
	  <option>+game_type 0 +game_mode 1 </option>
	</optgroup>
	<optgroup label="Deathmatch">
      <option>+game_type 1 +game_mode 2 </option>
	</optgroup>
	<optgroup label="Arms Race">
	  <option>+game_type 1 +game_mode 0 </option>
	</optgroup>
	<optgroup label="Demolition">
      <option>+game_type 1 +game_mode 1 </option>
	</optgroup>
    </select>
  </label>
</p>
<p>
	<label>Map
    <select name="map" size="1">
	<option>-</option>
	<optgroup label="de_Map">
      <option>de_dust</option>
      <option>de_dust2</option>
      <option>de_cache</option>
      <option>de_cbble</option>
      <option>de_shortdust</option>
	  <option>de_canals</option>
      <option>de_nuke</option>
      <option>de_vertigo</option>
      <option>de_train</option>
      <option>de_overpass</option>
	  <option>de_mirage</option>
	  <option>de_atztec</option>
	  <option>de_savehouse</option>
	  <option>de_stmarc</option>
	  <option>de_atztec</option>
	  </optgroup>
	  <optgroup label="ar_Map">
	  <option>ar_baggage</option>
      <option>ar_dizzy</option>
      <option>ar_shots</option>
      <option>ar_monastery</option>
	  </optgroup>
	  <optgroup label="cr_Map">
	  <option>cs_italy</option>
      <option>cs_assault</option>
      <option>cs_insertion</option>
      <option>cs_office</option>
	  </optgroup>
    </select>
</p>
<p>
</label>
	<label>Tickrate
    <select name="tr" size="1">
	  <option>-</option>
	  <option>64<option>
	  <option>128</option>
    </select>
  </label>
</p>
<p>
</label>
	<label>Max_Player
    <select name="player" size="1">
	  <option>-</option>
	  <option>2<option>
	  <option>4</option>
	  <option>8<option>
	  <option>16</option>
	  <option>32<option>
	  <option>64</option>
    </select>
  </label>
</p>
  <input type="submit" value="START" name="submit" id="button"></input>
</form>
</div>
</div>
</body>

start.php
PHP:
<?php
session_start();
if (isset($_POST['submit'])) {
	$gamemode = $_POST['gm'];
	$map = $_POST['map'];
	$tr = $_POST['tr'];
	$player = $_POST['players'];
	input($gamemode, $map, $tr, $player);
}
function input ($gamemode, $map, $tr, $player){
	if($gamemode=='-'){die("<div id='errormsg'>Bitte kontrolliere deine Eingabe.</div>");}
	if($map=='-'){die("<div id='errormsg'>Bitte kontrolliere deine Eingabe.</div>");}
	if($tr=='-'){die("<div id='errormsg'>Bitte kontrolliere deine Eingabe.</div>");}
	if($player=='-'){die("<div id='errormsg'>Bitte kontrolliere deine Eingabe.</div>");}
	start ($gamemode, $map, $tr, $player);
}
function start ($gamemode, $map, $tr, $player){
	$account = "SteamAccountCode";
	$command = "./srcds_run -game csgo -console -usercon $gamemode -maxplayers_override $player +exec server.cfg +map $map -tickrate $tr +sv_setsteamaccount $account";
	shell_exec ("/home/steam/server/$command");
	die("<div id='msg'>Server gestartet.</div>");
}
?>

Nachdem man alles Ausgewählt hat startet der Server. Allerdings hängt die Seite dann bei "warten auf Antwort " o.Ä. fest, da shell_exec nicht abgeschlossen wird, da der Server ja mit ihm startet. Das sollte so nicht sein. Er soll den Befehl ausführen also den Server starten und dann einfach weiter machen.
Das zweite Problem das ich habe ist, wenn der Server läuft, wie bekomme ich ihn wieder aus? Dafür habe ich noch keine Lösung gefunden.
Evtl könnt ihr mir da helfen.
 
Aus der Doku von exec (trifft auch für shell_exec zu):
Falls Sie diese Funktion benutzen, um ein Programm zu starten und im Hintergrund weiterlaufen lassen möchten, müssen Sie sicherstellen, dass die Ausgabe des Programms in eine Datei oder einen anderen Ausgabestream umgeleitet wird. Anderenfalls wird PHP solange hängen, bis das Programm zu Ende ausgeführt wurde.

Die Einfachste Lösung wäre es also, die Ausgaben des Prozesses nach /dev/null umzuleiten, falls sie Dich nicht interessiert.

Also den Aufruf etwas erweitern ...
Code:
shell_exec( $your_command . "> /dev/null 2>/dev/null &" );
 
Also müsste das ganze mit
PHP:
shell_exec(sprintf("%s > %s 2>&1 & echo $! >> %s", $command . "> /dev/null 2>/dev/null &", $outputfile, $pidfile));
file_put_contents("pid.txt", $pidfile);
...

und somit stoppen mit
PHP:
$pidid = file_get_contents('pid.txt');
proc_terminate ( $pidid ,$signal = 15);
unlink(pid.txt);
funktionieren, oder liege ich damit falsch?
 
Der Befehl shell_exec unterstützt nur einen Parameter, wenn Du die PID zurück haben willst, dann musst Du wie in dem verlinkten Beispiel exec verwenden. Außerdem musst Du Dich zwischen der Umleitung nach /dev/null und dem Outputfile entscheiden.
 
Andreas_ schrieb:
Der Befehl shell_exec unterstützt nur einen Parameter, wenn Du die PID zurück haben willst, dann musst Du wie in dem verlinkten Beispiel exec verwenden. Außerdem musst Du Dich zwischen der Umleitung nach /dev/null und dem Outputfile entscheiden.

Also müsste es so aussehen:
PHP:
$command = "./srcds_run -game csgo -console -usercon $gamemode -maxplayers_override $player +exec server.cfg +map $map -tickrate $tr +sv_setsteamaccount $account";
	exec(sprintf("%s > %s 2>&1 & echo $! >> %s", $command, $outputfile, $pidfile));
	file_put_contents("pid.txt", $pidfile);
Irgendwie startet es nun nicht mehr :/
 
Zuletzt bearbeitet von einem Moderator:
Schau Dir am besten die Doku zu exec an, da gibt es Beispiele, wie man den Aufruf in eine eigene Klasse kapselt. Das zweite Beispiel wäre da empfehlenswert.

/edit: Link auf deutsche Version korrigiert.
 
Zuletzt bearbeitet:
Horstexplorer schrieb:
Ich sehe nicht was ich falsch machen würde
$outputfile und $pidfile vor dem Aufruf deklariert?

Ansonsten ist das zweite Beispiel aus der Doku für Dich gut geeignet. Das definiert eine Klasse Process mit den Methoden start(), stop() und status(). Also alles was Du brauchst.
 
Ok, ich hoffe ich habe das richtig umgesetzt:
(Liegt jetzt beides in einem Doc)
index.php
PHP:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="css.css">
</head>
<body>
<center>
<div class="box">
<div id="h1">CSGO SERVER</div>
<form action="#" method="post">
<?php include 'server.php';?>
<p>
</label>
	<label>Gamemode
    <select name="gm" size="1">
	  <option>-</option>
	<optgroup label="Classic Casual">
      <option>+game_type 0 +game_mode 0 </option>
	</optgroup>
	<optgroup label="Classic Competitive">
	  <option>+game_type 0 +game_mode 1 </option>
	</optgroup>
	<optgroup label="Deathmatch">
      <option>+game_type 1 +game_mode 2 </option>
	</optgroup>
	<optgroup label="Arms Race">
	  <option>+game_type 1 +game_mode 0 </option>
	</optgroup>
	<optgroup label="Demolition">
      <option>+game_type 1 +game_mode 1 </option>
	</optgroup>
    </select>
  </label>
</p>
<p>
	<label>Map
    <select name="map" size="1">
	<option>-</option>
	<optgroup label="de_Map">
      <option>de_dust</option>
      <option>de_dust2</option>
      <option>de_cache</option>
      <option>de_cbble</option>
      <option>de_shortdust</option>
	  <option>de_canals</option>
      <option>de_nuke</option>
      <option>de_vertigo</option>
      <option>de_train</option>
      <option>de_overpass</option>
	  <option>de_mirage</option>
	  <option>de_atztec</option>
	  <option>de_savehouse</option>
	  <option>de_stmarc</option>
	  <option>de_atztec</option>
	  </optgroup>
	  <optgroup label="ar_Map">
	  <option>ar_baggage</option>
      <option>ar_dizzy</option>
      <option>ar_shots</option>
      <option>ar_monastery</option>
	  </optgroup>
	  <optgroup label="cr_Map">
	  <option>cs_italy</option>
      <option>cs_assault</option>
      <option>cs_insertion</option>
      <option>cs_office</option>
	  </optgroup>
    </select>
</p>
<p>
</label>
	<label>Tickrate
    <select name="tr" size="1">
	  <option>-</option>
	  <option>64</option>
	  <option>128</option>
    </select>
  </label>
</p>
<p>
</label>
	<label>Max_Player
    <select name="player" size="1">
	  <option>-</option>
	  <option>2</option>
	  <option>4</option>
	  <option>8</option>
	  <option>16</option>
	  <option>32</option>
	  <option>64</option>
    </select>
  </label>
</p>
  <input type="submit" value="START" name="submit" id="button"></input>
  <input type="submit" value="STOP" name="submit2" id="sbutton"></input>
</form>
</div>
</div>
</body>

server.php
PHP:
<?php
//START
if (isset($_POST['submit'])) {
	$gamemode = $_POST['gm'];
	$map = $_POST['map'];
	$tr = $_POST['tr'];
	$player = $_POST['players'];
	input($gamemode, $map, $tr, $player);
}
function input ($gamemode, $map, $tr, $player){
	if($gamemode=='-'){die("<div id='errormsg'>Bitte kontrolliere deine Eingabe.</div>");}
	if($map=='-'){die("<div id='errormsg'>Bitte kontrolliere deine Eingabe.</div>");}
	if($tr=='-'){die("<div id='errormsg'>Bitte kontrolliere deine Eingabe.</div>");}
	if($player=='-'){die("<div id='errormsg'>Bitte kontrolliere deine Eingabe.</div>");}
	start ($gamemode, $map, $tr, $player);
}
function start ($gamemode, $map, $tr, $player){
	$account = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
	$command = "/home/steam/server/./srcds_run -game csgo -console -usercon $gamemode -maxplayers_override $player +exec server.cfg +map $map -tickrate $tr +sv_setsteamaccount $account";
	$process = new Process($command);
	$process.setPid(27015);
	$process.start();
	header('location: index.php');
}
//STOP
if (isset($_POST['submit2'])) {
	$process = new Process();
	$process.setPid(27015);
	$process.stop();
	header('location: index.php');
}
 
Der Befehl setPid() funktioniert nicht so, wie Du es vermutest. Du kannst damit nicht die PID eines neuen oder laufenden Prozesses ändern. Sinn macht es nur mit setPid() eine Prozess zu identifizieren, dessen Status Du abfragen oder den Du beenden willst.

PHP:
function start ($gamemode, $map, $tr, $player){
	$account = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
	$command = "/home/steam/server/./srcds_run -game csgo -console -usercon $gamemode -maxplayers_override $player +exec server.cfg +map $map -tickrate $tr +sv_setsteamaccount $account";
	$process = new Process($command);
        // die pid für spätere Verwendung abspeichern
        file_put_contents("pid.txt", $process.getPid());
	header('location: index.php');
}
//STOP
if (isset($_POST['submit2'])) {
	$process = new Process();
        // die gespeicherte pid laden
        $pid = file_get_contents("pid.txt");
        $process.setPid($pid);
	$process.stop();
	header('location: index.php');
}
 
Wenn das Interface auf einem öffentlich zugänglichen Server laufen soll musst du die Parameter aus dem Formular mit escapeshellarg erst "entschärfen", sonst führt der erste der die Debug-Tools des Browsers kennt beliebige Befehle auf dem Server aus..

Beispiel:

PHP:
$command="/home/steam/server/./srcds_run -game csgo -console -usercon " . escapeshellarg($gamemode) . " -maxplayers_override " . escapeshellarg($player) . " +exec server.cfg +map " . escapeshellarg($map) . " -tickrate " . escapeshellarg($tr) . " +sv_setsteamaccount $account";
 
Zuletzt bearbeitet:
Ok, vielen Dank für die Hilfe bis jetzt. Allerdings startet das ganze immer noch nicht :/
index.php
PHP:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="css.css">
</head>
<body>
<center>
<div class="box">
<div id="h1">CSGO SERVER</div>
<form action="#" method="post">
<?php include 'server.php';?>
<p>
</label>
	<label>Gamemode
    <select name="gm" size="1">
	  <option>-</option>
	<optgroup label="Classic Casual">
      <option>+game_type 0 +game_mode 0 </option>
	</optgroup>
	<optgroup label="Classic Competitive">
	  <option>+game_type 0 +game_mode 1 </option>
	</optgroup>
	<optgroup label="Deathmatch">
      <option>+game_type 1 +game_mode 2 </option>
	</optgroup>
	<optgroup label="Arms Race">
	  <option>+game_type 1 +game_mode 0 </option>
	</optgroup>
	<optgroup label="Demolition">
      <option>+game_type 1 +game_mode 1 </option>
	</optgroup>
    </select>
  </label>
</p>
<p>
	<label>Map
    <select name="map" size="1">
	<option>-</option>
	<optgroup label="de_Map">
      <option>de_dust</option>
      <option>de_dust2</option>
      <option>de_cache</option>
      <option>de_cbble</option>
      <option>de_shortdust</option>
	  <option>de_canals</option>
      <option>de_nuke</option>
      <option>de_vertigo</option>
      <option>de_train</option>
      <option>de_overpass</option>
	  <option>de_mirage</option>
	  <option>de_atztec</option>
	  <option>de_savehouse</option>
	  <option>de_stmarc</option>
	  <option>de_atztec</option>
	  </optgroup>
	  <optgroup label="ar_Map">
	  <option>ar_baggage</option>
      <option>ar_dizzy</option>
      <option>ar_shots</option>
      <option>ar_monastery</option>
	  </optgroup>
	  <optgroup label="cr_Map">
	  <option>cs_italy</option>
      <option>cs_assault</option>
      <option>cs_insertion</option>
      <option>cs_office</option>
	  </optgroup>
    </select>
</p>
<p>
</label>
	<label>Tickrate
    <select name="tr" size="1">
	  <option>-</option>
	  <option>64</option>
	  <option>128</option>
    </select>
  </label>
</p>
<p>
</label>
	<label>Max_Player
    <select name="player" size="1">
	  <option>-</option>
	  <option>2</option>
	  <option>4</option>
	  <option>8</option>
	  <option>16</option>
	  <option>32</option>
	  <option>64</option>
    </select>
  </label>
</p>
  <input type="submit" value="START" name="submit" id="button"></input>
  <input type="submit" value="STOP" name="submit2" id="sbutton"></input>
</form>
</div>
</div>
</body>
server.php
PHP:
<?php
//START
if (isset($_POST['submit'])) {
	$gamemode = $_POST['gm'];
	$map = $_POST['map'];
	$tr = $_POST['tr'];
	$player = $_POST['player'];
	input($gamemode, $map, $tr, $player);
}
function input ($gamemode, $map, $tr, $player){
	if($gamemode=='-'){die("<div id='errormsg'>Bitte kontrolliere deine Eingabe.</div>");}
	if($map=='-'){die("<div id='errormsg'>Bitte kontrolliere deine Eingabe.</div>");}
	if($tr=='-'){die("<div id='errormsg'>Bitte kontrolliere deine Eingabe.</div>");}
	if($player=='-'){die("<div id='errormsg'>Bitte kontrolliere deine Eingabe.</div>");}
	start ($gamemode, $map, $tr, $player);
}
function start ($gamemode, $map, $tr, $player){
	$account = "xxxxxxxxxxxxxxxxxxxxxxxxxx";
	$command="/home/steam/server/./srcds_run -game csgo -console -usercon " . escapeshellarg($gamemode) . " -maxplayers_override " . escapeshellarg($player) . " +exec server.cfg +map " . escapeshellarg($map) . " -tickrate " . escapeshellarg($tr) . " +sv_setsteamaccount $account";
	$process = new Process($command);
        // die pid für spätere Verwendung abspeichern
        file_put_contents("pid.txt", $process.getPid());
	header('location: index.php');
}
//STOP
if (isset($_POST['submit2'])) {
	$process = new Process();
        // die gespeicherte pid laden
        $pid = file_get_contents("pid.txt");
        $process.setPid($pid);
	$process.stop();
	header('location: index.php');
}
 
Zuletzt bearbeitet von einem Moderator:
Hast Du den von Dir zusammengebauten Command-String mal direkt von der Shell aus probiert? Der Account unter dem der Webserver läuft hat alle benötigten Rechte?
 
Der Commandstring funktioniert. www-data ownt auch alle Dateien in dem Verzeichnis.
 
Dann würde ich versuchsweise die Ausgabe nicht nach /dev/null umleiten sondern in eine Textdatei.

Dazu musst Du nur eine Zeile der Klasse anpassen
PHP:
$command = 'nohup '.$this->command.' > /dev/null 2>&1 & echo $!';

zum Beispiel:
PHP:
// zum Ueberpruefen das uebergebene Commando sichern
file_put_contents("/home/steam/server/command.txt", $this->command);
// Umleitung der Ausgabe in eine Text-Datei
$command = 'nohup '.$this->command.' > /home/steam/server/output.txt 2>&1 & echo $!';
Eventuell noch die Verzeichnisse anpassen. Mitunter ist am Inhalt der Textdateien erkennbar, warum der Aufruf nicht funktioniert ...
 
Ich habe die Verzeichnisse auf /var/www/html gelegt, allerdings werden diese Dateien dort nicht erstellt.
 
Horstexplorer schrieb:
Ich habe die Verzeichnisse auf /var/www/html gelegt, allerdings werden diese Dateien dort nicht erstellt.
Wenn keine der Textdateien erstellt wurde, dann dürfte ein Rechteproblem vorliegen.
 
Zurück
Oben