mirror of
https://github.com/easy-wi/developer.git
synced 2025-02-20 11:23:28 +08:00
2612 lines
130 KiB
PHP
2612 lines
130 KiB
PHP
<?php
|
||
|
||
/**
|
||
* File: class_app.php.
|
||
* Author: Ulrich Block
|
||
* Date: 26.10.14
|
||
* Contact: <ulrich.block@easy-wi.com>
|
||
*
|
||
* This file is part of Easy-WI.
|
||
*
|
||
* Easy-WI is free software: you can redistribute it and/or modify
|
||
* it under the terms of the GNU General Public License as published by
|
||
* the Free Software Foundation, either version 3 of the License, or
|
||
* (at your option) any later version.
|
||
*
|
||
* Easy-WI is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
* GNU General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU General Public License
|
||
* along with Easy-WI. If not, see <http://www.gnu.org/licenses/>.
|
||
*
|
||
* Diese Datei ist Teil von Easy-WI.
|
||
*
|
||
* Easy-WI ist Freie Software: Sie koennen es unter den Bedingungen
|
||
* der GNU General Public License, wie von der Free Software Foundation,
|
||
* Version 3 der Lizenz oder (nach Ihrer Wahl) jeder spaeteren
|
||
* veroeffentlichten Version, weiterverbreiten und/oder modifizieren.
|
||
*
|
||
* Easy-WI wird in der Hoffnung, dass es nuetzlich sein wird, aber
|
||
* OHNE JEDE GEWAEHELEISTUNG, bereitgestellt; sogar ohne die implizite
|
||
* Gewaehrleistung der MARKTFAEHIGKEIT oder EIGNUNG FUER EINEN BESTIMMTEN ZWECK.
|
||
* Siehe die GNU General Public License fuer weitere Details.
|
||
*
|
||
* Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
|
||
* Programm erhalten haben. Wenn nicht, siehe <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
// Include PHPSeclib if not already included
|
||
if (!class_exists('SSH2')) {
|
||
include(EASYWIDIR . '/third_party/phpseclib/autoloader.php');
|
||
}
|
||
|
||
// Include EasyWi FTP if not already included
|
||
if (!class_exists('EasyWiFTP')) {
|
||
include(EASYWIDIR . '/stuff/methods/class_ftp.php');
|
||
}
|
||
|
||
if (!class_exists('Yaml')) {
|
||
include(EASYWIDIR . '/third_party/Symfony/autoloader_yaml.php');
|
||
}
|
||
|
||
use Symfony\Component\Yaml\Yaml;
|
||
|
||
class AppServer {
|
||
|
||
private $uniqueHex, $winCmds = array(), $shellScriptHeader, $shellScripts = array('user' => '', 'server' => array()), $commandReturns = array(), $undefinedRequiredVars = array();
|
||
|
||
public $appMasterServerDetails = array(), $appServerDetails = false;
|
||
|
||
// The constructor gathers the root data
|
||
function __construct($id) {
|
||
|
||
global $sql, $aeskey;
|
||
|
||
$this->uniqueHex = dechex(mt_rand());
|
||
|
||
$query = $sql->prepare("SELECT *,AES_DECRYPT(`port`,:aeskey) AS `decryptedport`,AES_DECRYPT(`user`,:aeskey) AS `decrypteduser`,AES_DECRYPT(`pass`,:aeskey) AS `decryptedpass`,AES_DECRYPT(`steamAccount`,:aeskey) AS `decryptedsteamAccount`,AES_DECRYPT(`steamPassword`,:aeskey) AS `decryptedsteamPassword` FROM `rserverdata` WHERE `id`=:serverID LIMIT 1");
|
||
$query->execute(array(':serverID' => $id, ':aeskey' => $aeskey));
|
||
|
||
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
|
||
|
||
$this->appMasterServerDetails['id'] = (int) $id;
|
||
$this->appMasterServerDetails['notified'] = (int) $row['notified'];
|
||
$this->appMasterServerDetails['ssh2IP'] = (string) $row['ip'];
|
||
$this->appMasterServerDetails['ssh2Port'] = (int) $row['decryptedport'];
|
||
$this->appMasterServerDetails['ssh2User'] = (string) $row['decrypteduser'];
|
||
$this->appMasterServerDetails['ssh2Publickey'] = (string) $row['publickey'];
|
||
$this->appMasterServerDetails['ssh2DecryptedPass'] = (string) $row['decryptedpass'];
|
||
$this->appMasterServerDetails['ssh2KeyName'] = (string) $row['keyname'];
|
||
$this->appMasterServerDetails['ftpPort'] = (string) $row['ftpport'];
|
||
$this->appMasterServerDetails['os'] = (string) $row['os'];
|
||
$this->appMasterServerDetails['iniVars'] = @parse_ini_string($row['install_paths'], true);
|
||
|
||
# https://github.com/easy-wi/developer/issues/70
|
||
$this->appMasterServerDetails['privateKey'] = EASYWIDIR . '/keys/' . removePub($this->appMasterServerDetails['ssh2KeyName']);
|
||
|
||
$this->appMasterServerDetails['quotaActive'] = $row['quota_active'];
|
||
$this->appMasterServerDetails['quotaCmd'] = $row['quota_cmd'];
|
||
$this->appMasterServerDetails['repquotaCmd'] = $row['repquota_cmd'];
|
||
$this->appMasterServerDetails['blocksize'] = $row['blocksize'];
|
||
$this->appMasterServerDetails['inodeBlockRatio'] = $row['inode_block_ratio'];
|
||
|
||
$this->appMasterServerDetails['configBadFiles'] = preg_split('/,/', $row['config_bad_files'], -1, PREG_SPLIT_NO_EMPTY);
|
||
$this->appMasterServerDetails['configBadTime'] = (int) $row['config_bad_time'];
|
||
$this->appMasterServerDetails['configBinaries'] = preg_split('/,/', $row['config_binaries'], -1, PREG_SPLIT_NO_EMPTY);
|
||
$this->appMasterServerDetails['configDemoTime'] = (int) $row['config_demo_time'];
|
||
$this->appMasterServerDetails['configFiles'] = preg_split('/,/', $row['config_files'], -1, PREG_SPLIT_NO_EMPTY);
|
||
$this->appMasterServerDetails['configIonice'] = (string) $row['config_ionice'];
|
||
$this->appMasterServerDetails['configLogTime'] = (int) $row['config_log_time'];
|
||
$this->appMasterServerDetails['configUserID'] = ($row['config_user_id'] > 0) ? (int) $row['config_user_id'] : 1000;
|
||
$this->appMasterServerDetails['configZtmpTime'] = (int) $row['config_ztmp_time'];
|
||
|
||
if ($this->appMasterServerDetails['os'] == 'L') {
|
||
$this->shellScriptHeader = "#!/bin/bash\n";
|
||
$this->shellScriptHeader .= "if ionice -c3 true 2>/dev/null; then IONICE='ionice -n 7 '; fi\n";
|
||
$this->shellScripts['user'] = $this->shellScriptHeader . 'rm -f /home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/userCud-' . $this->uniqueHex . '.sh' . "\n";
|
||
}
|
||
}
|
||
|
||
return ($query->rowCount() > 0) ? true : false;
|
||
}
|
||
|
||
// Function that gathers the details of the currently active app
|
||
public function getAppServerDetails($id) {
|
||
|
||
// Those three variables are always defined, when this class is used
|
||
global $sql, $aeskey, $resellerLockupID;
|
||
|
||
$query = $sql->prepare("SELECT g.*,AES_DECRYPT(g.`ppassword`,:aeskey) AS `decryptedppass`,AES_DECRYPT(g.`ftppassword`,:aeskey) AS `decryptedftppass`,u.`cname` FROM `gsswitch` AS g INNER JOIN `userdata` AS u ON u.`id`=g.`userid` WHERE g.`id`=:id AND g.`resellerid`=:resellerID LIMIT 1");
|
||
$query->execute(array(':id' => $id, ':aeskey' => $aeskey, ':resellerID' => $resellerLockupID));
|
||
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
|
||
|
||
// If app details can not be found return false
|
||
if (!$this->getAppDetails($row['serverid'], $id)) {
|
||
|
||
$query2 = $sql->prepare("SELECT `id` FROM `serverlist` WHERE `switchID`=? LIMIT 1");
|
||
$query2->execute(array($id));
|
||
$row['serverid'] = $query2->fetchColumn();
|
||
|
||
if ($row['serverid'] > 0) {
|
||
$query2 = $sql->prepare("UPDATE `gsswitch` SET `serverid`=? WHERE `id`=? LIMIT 1");
|
||
$query2->execute(array($row['serverid'], $id));
|
||
}
|
||
|
||
if (!$this->getAppDetails($row['serverid'], $id)) {
|
||
|
||
$this->appServerDetails = false;
|
||
|
||
return false;
|
||
}
|
||
}
|
||
|
||
$this->appServerDetails['app']['id'] = $row['serverid'];
|
||
|
||
$this->appServerDetails['id'] = (int) $row['id'];
|
||
$this->appServerDetails['userid'] = (int) $row['userid'];
|
||
$this->appServerDetails['type'] = (string) $row['type'];
|
||
$this->appServerDetails['lendServer'] = (string) $row['lendserver'];
|
||
$this->appServerDetails['protectionModeAllowed'] = ($this->appServerDetails['template']['protectedApp'] == 'Y') ? (string) $row['pallowed'] : 'N';
|
||
$this->appServerDetails['protectionModeStarted'] = ($this->appServerDetails['protectionModeAllowed'] == 'Y') ? (string) $row['protected'] : 'N';
|
||
$this->appServerDetails['eacAllowed'] = (string) $row['eacallowed'];
|
||
$this->appServerDetails['tvAllowed'] = (string) $row['tvenable'];
|
||
$this->appServerDetails['serverIP'] = (string) $row['serverip'];
|
||
$this->appServerDetails['port'] = (int) $row['port'];
|
||
$this->appServerDetails['port2'] = (int) $row['port2'];
|
||
$this->appServerDetails['port3'] = (int) $row['port3'];
|
||
$this->appServerDetails['port4'] = (int) $row['port4'];
|
||
$this->appServerDetails['port5'] = (int) $row['port5'];
|
||
$this->appServerDetails['minram'] = ($row['minram'] > 0) ? (int) $row['minram'] : 512;
|
||
$this->appServerDetails['maxram'] = ($row['maxram'] > 0) ? (int) $row['maxram'] : 1024;
|
||
$this->appServerDetails['slots'] = (int) $row['slots'];
|
||
$this->appServerDetails['userMasterFastDownload'] = (string) $row['masterfdl'];
|
||
$this->appServerDetails['specificFastDownLoadData'] = (string) $row['mfdldata'];
|
||
$this->appServerDetails['useTaskSet'] = (string) $row['taskset'];
|
||
$this->appServerDetails['cores'] = (string) $row['cores'];
|
||
$this->appServerDetails['maxCores'] = count(preg_split("/\,/", $this->appServerDetails['cores'], -1, PREG_SPLIT_NO_EMPTY));
|
||
$this->appServerDetails['maxCores'] = ($this->appServerDetails['maxCores'] == 0) ? 1 : $this->appServerDetails['maxCores'];
|
||
$this->appServerDetails['userName'] = ($row['newlayout'] == 'Y') ? (string) $row['cname'] . '-' . $id : (string) $row['cname'];
|
||
$this->appServerDetails['userNameExecute'] = ($this->appServerDetails['protectionModeStarted'] == 'Y') ? (string) $this->appServerDetails['userName'] . '-p' : (string) $this->appServerDetails['userName'];
|
||
$this->appServerDetails['hdd'] = (int) $row['hdd'];
|
||
$this->appServerDetails['homeLabel'] = (string) $row['homeLabel'];
|
||
|
||
// Password value is only used for setting. In case a server is inactive we need to generate a random one, so the customer can no longer log in.
|
||
$this->appServerDetails['ftpPassword'] = ($row['active'] == 'Y') ? (string) $row['decryptedftppass'] : passwordgenerate(10);
|
||
$this->appServerDetails['ftpPasswordProtected'] = ($row['active'] == 'Y') ? (string) $row['decryptedppass'] : passwordgenerate(10);
|
||
|
||
// This password will be used, when a FTP connection needs to be setup
|
||
$this->appServerDetails['ftpPasswordExecute'] = ($this->appServerDetails['protectionModeStarted'] == 'Y') ? (string) $row['decryptedppass'] : (string) $row['decryptedftppass'];
|
||
|
||
// As the data loading is sequential, required parameters for the ternary operator will not be available within getAppDetails() function
|
||
$this->appServerDetails['app']['templateChoosen'] = ($this->appServerDetails['app']['servertemplate'] == 1 or $this->appServerDetails['protectionModeStarted'] == 'Y') ? $this->appServerDetails['template']['shorten'] : $this->appServerDetails['template']['shorten'] . '-' . $this->appServerDetails['app']['servertemplate'];
|
||
$this->appServerDetails['app']['uploadDir'] = ($this->appServerDetails['tvAllowed'] == 'Y') ? $this->appServerDetails['app']['uploadDir'] : false;
|
||
|
||
$this->appServerDetails['homeDir'] = ($this->appMasterServerDetails['iniVars'] and isset($this->appMasterServerDetails['iniVars'][$row['homeLabel']]['path'])) ? (string) $this->appMasterServerDetails['iniVars'][$row['homeLabel']]['path'] : '/home';
|
||
|
||
$serverTemplateDir = $this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName'];
|
||
$serverTemplateDir .= ($this->appServerDetails['protectionModeStarted'] == 'Y') ? '/pserver/' : '/server/';
|
||
$this->appServerDetails['absolutePath'] = $this->removeSlashes($serverTemplateDir . '/' . $this->appServerDetails['app']['templateChoosen'] . '/');
|
||
$this->appServerDetails['absoluteTemplatePath'] = $this->removeSlashes($serverTemplateDir);
|
||
|
||
// For protected users the pserver/ directory is the home folder
|
||
// We deliberately let admins that failed to setup a chrooted FTP environment run into errors
|
||
$absoluteFTPPath = ($this->appServerDetails['protectionModeStarted'] == 'Y') ? '/' : '/server/';
|
||
$absoluteFTPPath .= $this->appServerDetails['app']['templateChoosen'];
|
||
|
||
if ($this->getGameType() == 'hl2') {
|
||
$absoluteFTPPath .= '/' . $this->appServerDetails['template']['binarydir'];
|
||
}
|
||
|
||
$absoluteFTPPath .= '/' . $this->appServerDetails['template']['modfolder'] . '/';
|
||
|
||
$this->appServerDetails['absoluteFTPPath'] = $this->removeSlashes($absoluteFTPPath);
|
||
$this->appServerDetails['absoluteFTPPathNoChroot'] = $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName'] . $this->appServerDetails['absoluteFTPPath']);
|
||
}
|
||
|
||
return ($query->rowCount() > 0) ? true : false;
|
||
}
|
||
|
||
// Function that gathers the details of the currently active app
|
||
private function getAppDetails($id, $appServerID) {
|
||
|
||
global $sql, $aeskey;
|
||
|
||
$query = $sql->prepare("SELECT t.`id` AS `template_id`,t.`steamgame`,t.`gameq`,t.`shorten`,t.`protected`,t.`protectedSaveCFGs`,t.`gamebinary`,t.`gamebinaryWin`,t.`binarydir`,t.`modfolder`,t.`copyStartBinary`,t.`cmd` AS `template_cmd`,t.`modcmds` AS `template_modcmds`,t.`steamGameserverToken`,`configedit`,s.*,AES_DECRYPT(s.`uploaddir`,:aeskey) AS `d_uploaddir`,AES_DECRYPT(s.`webapiAuthkey`,:aeskey) AS `d_webapiauthkey`,AES_DECRYPT(s.`steamServerToken`,:aeskey) AS `d_steamServerToken` FROM `serverlist` AS s INNER JOIN `servertypes` AS t ON t.`id`=s.`servertype` WHERE s.`id`=:id AND s.`switchID`=:appServerID LIMIT 1");
|
||
$query->execute(array(':aeskey' => $aeskey, ':id' => $id, ':appServerID' => $appServerID));
|
||
|
||
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
|
||
|
||
// First block will be global app template settings
|
||
$this->appServerDetails['template']['id'] = (string) $row['template_id'];
|
||
$this->appServerDetails['template']['gameq'] = (string) $row['gameq'];
|
||
$this->appServerDetails['template']['shorten'] = (string) $row['shorten'];
|
||
$this->appServerDetails['template']['protectedApp'] = (string) $row['protected'];
|
||
$this->appServerDetails['template']['protectedSaveCFGs'] = $row['protectedSaveCFGs'];
|
||
$this->appServerDetails['template']['gameBinary'] = ($this->appMasterServerDetails['os'] == 'L') ? (string) $row['gamebinary'] : (string) $row['gamebinaryWin'];
|
||
$this->appServerDetails['template']['binarydir'] = (string) $row['binarydir'];
|
||
$this->appServerDetails['template']['modfolder'] = (string) $row['modfolder'];
|
||
$this->appServerDetails['template']['modcmds'] = (string) $row['template_modcmds'];
|
||
$this->appServerDetails['template']['steamgame'] = (string) $row['steamgame'];
|
||
$this->appServerDetails['template']['steamGameserverToken'] = (string) $row['steamGameserverToken'];
|
||
$this->appServerDetails['template']['configedit'] = $row['configedit'];
|
||
$this->appServerDetails['template']['copyStartBinary'] = $row['copyStartBinary'];
|
||
|
||
// second block will be specific app settings
|
||
$this->appServerDetails['app']['anticheat'] = (int) $row['anticheat'];
|
||
$this->appServerDetails['app']['fps'] = (int) $row['fps'];
|
||
$this->appServerDetails['app']['tic'] = (int) $row['tic'];
|
||
$this->appServerDetails['app']['servertemplate'] = (int) $row['servertemplate'];
|
||
$this->appServerDetails['app']['map'] = (string) $row['map'];
|
||
$this->appServerDetails['app']['workShop'] = (string) $row['workShop'];
|
||
$this->appServerDetails['app']['mapGroup'] = (string) $row['mapGroup'];
|
||
$this->appServerDetails['app']['steamServerToken'] = (string) $row['d_steamServerToken'];
|
||
$this->appServerDetails['app']['workshopCollection'] = (int) $row['workshopCollection'];
|
||
$this->appServerDetails['app']['webApiAuthKey'] = (string) $row['d_webapiauthkey'];
|
||
|
||
$this->appServerDetails['app']['upload'] = (int) $row['upload'];
|
||
$this->appServerDetails['app']['uploadDir'] = (strlen($row['d_uploaddir']) > 0) ? (string) $row['d_uploaddir'] : false;
|
||
|
||
$this->appServerDetails['app']['modcmd'] = (string) $row['modcmd'];
|
||
$this->appServerDetails['app']['gamemod'] = (string) $row['gamemod'];
|
||
$this->appServerDetails['app']['gamemod2'] = (string) $row['gamemod2'];
|
||
|
||
// Third will be app settings which might get overwritten by global settings
|
||
$this->appServerDetails['app']['cmd'] = ($row['owncmd'] == 'Y') ? (string) $row['cmd'] : (string) $row['template_cmd'];
|
||
}
|
||
|
||
return ($query->rowCount() > 0) ? true : false;
|
||
}
|
||
|
||
private function getReplacements() {
|
||
|
||
if ($this->appServerDetails['lendServer'] == 'Y') {
|
||
$lendDetails = $this->getLendDetails();
|
||
}
|
||
|
||
if (!isset($lendDetails) or !is_array($lendDetails)) {
|
||
$lendDetails = array('rcon' => '', 'password' => '', 'slots' => $this->appServerDetails['slots']);
|
||
}
|
||
|
||
$placeholder = array('%binary%', '%tickrate%', '%tic%', '%ip%', '%port%', '%tvport%', '%port2%', '%port3%', '%port4%', '%port5%', '%slots%', '%map%', '%mapgroup%', '%fps%', '%minram%', '%maxram%', '%maxcores%', '%folder%', '%user%', '%absolutepath%');
|
||
|
||
$replacePlaceholderWith = array(
|
||
$this->appServerDetails['template']['gameBinary'],
|
||
$this->appServerDetails['app']['tic'],
|
||
$this->appServerDetails['app']['tic'],
|
||
$this->appServerDetails['serverIP'],
|
||
$this->appServerDetails['port'],
|
||
$this->appServerDetails['port2'],
|
||
$this->appServerDetails['port2'],
|
||
$this->appServerDetails['port3'],
|
||
$this->appServerDetails['port4'],
|
||
$this->appServerDetails['port5'],
|
||
($this->appServerDetails['lendServer'] == 'Y') ? $lendDetails['slots'] : $this->appServerDetails['slots'],
|
||
$this->appServerDetails['app']['map'],
|
||
$this->appServerDetails['app']['mapGroup'],
|
||
$this->appServerDetails['app']['fps'],
|
||
$this->appServerDetails['minram'],
|
||
$this->appServerDetails['maxram'],
|
||
$this->appServerDetails['maxCores'],
|
||
$this->appServerDetails['app']['templateChoosen'],
|
||
$this->appServerDetails['userName'],
|
||
$this->appServerDetails['absolutePath']
|
||
);
|
||
|
||
return array('placeholder' => $placeholder, 'replacePlaceholderWith' => $replacePlaceholderWith);
|
||
}
|
||
|
||
// function that gathers the details for all installed addons
|
||
public function getAddonDetails () {
|
||
|
||
global $sql;
|
||
|
||
$this->appServerDetails['extensions']['addons'] = array();
|
||
$this->appServerDetails['extensions']['addonSettings'] = array();
|
||
$this->appServerDetails['extensions']['maps'] = array();
|
||
$this->appServerDetails['extensions']['cmds'] = array();
|
||
$this->appServerDetails['extensions']['rmcmd'] = array();
|
||
|
||
$query = $sql->prepare("SELECT a.`id`,a.`cmd`,a.`rmcmd`,a.`addon`,a.`type`,a.`paddon`,a.`depending`,a.`folder` FROM `addons_installed` AS i INNER JOIN `addons` AS a ON a.`id`=i.`addonid` WHERE i.`serverid`=? AND i.`paddon`=? AND i.`servertemplate`=?");
|
||
$query->execute(array($this->appServerDetails['app']['id'], $this->appServerDetails['protectionModeStarted'], $this->appServerDetails['app']['servertemplate']));
|
||
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
|
||
|
||
if ($row['type'] == 'tool') {
|
||
$this->appServerDetails['extensions']['addons'][$row['id']] = $row['addon'];
|
||
} else {
|
||
$this->appServerDetails['extensions']['maps'][$row['id']] = $row['addon'];
|
||
}
|
||
|
||
$this->appServerDetails['extensions']['addonSettings'][$row['id']] = array('protectedAllowed' => $row['paddon'], 'folder' => $row['folder']);
|
||
|
||
// Maps are allowed with protection mode in any case. Addons can be limited. We need to filter addons which should not be running when protection mode is active
|
||
if ($row['type'] == 'map' or $this->appServerDetails['protectionModeStarted'] == 'N' or ($this->appServerDetails['protectionModeStarted'] == 'Y' and $row['paddon'] == 'Y')) {
|
||
if (strlen($row['cmd']) > 0) {
|
||
$this->appServerDetails['extensions']['cmds'][] = (substr($row['cmd'], 0, 12) == '[no_padding]') ? trim(substr($row['cmd'], 12)) : ' ' . $row['cmd'];
|
||
}
|
||
|
||
if (strlen($row['rmcmd']) > 0) {
|
||
foreach (preg_split("/\r\n/", $row['rmcmd'], -1, PREG_SPLIT_NO_EMPTY) as $removeCommand) {
|
||
if (strlen($removeCommand) > 0) {
|
||
$this->appServerDetails['extensions']['removeCmds'][] = $removeCommand;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Function that checks if the game server is landed and if yes with which details
|
||
private function getLendDetails () {
|
||
|
||
global $sql, $aeskey;
|
||
|
||
$cmd = '';
|
||
|
||
$query = $sql->prepare("SELECT `rcon`,`password`,`slots`,AES_DECRYPT(`ftpuploadpath`,?) AS `decyptedftpuploadpath` FROM `lendedserver` WHERE `serverid`=? LIMIT 1");
|
||
$query->execute(array($aeskey, $this->appServerDetails['app']['id']));
|
||
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
|
||
|
||
$this->appServerDetails['slots'] = (int) $row['slots'];
|
||
|
||
if (strlen($row['decyptedftpuploadpath']) > 0 and $row['decyptedftpuploadpath'] != 'ftp://username:password@1.1.1.1/demos') {
|
||
$this->appServerDetails['app']['uploadDir'] = $row['decyptedftpuploadpath'];
|
||
}
|
||
|
||
$gameType = $this->getGameType();
|
||
|
||
if ($gameType == 'hl2') {
|
||
$cmd .= ' +rcon_password ' .$row['rcon'] . ' +sv_password ' . $row['password']. ' +tv_enable 1 +tv_autorecord 1';
|
||
} else if ($gameType == 'hl1') {
|
||
$cmd .= ' +rcon_password ' . $row['rcon'] . ' +sv_password ' . $row['password'];
|
||
} else if ($gameType == 'cod') {
|
||
$cmd .= ' +set rcon_password ' . $row['rcon'] . ' +set g_password ' . $row['password'];
|
||
} else {
|
||
$cmd = array('rcon' => $row['rcon'], 'password' => $row['password'], 'slots' => $row['slots']);
|
||
}
|
||
}
|
||
|
||
return $cmd;
|
||
}
|
||
|
||
/*
|
||
* Abstract helper functions
|
||
*/
|
||
private function addLogline ($logName, $logLine) {
|
||
$this->shellScripts['user'] .= 'echo "`date`: ' . $logLine . '" >> "/home/' . $this->appMasterServerDetails['ssh2User'] . '/logs/' . $logName . '"' . "\n";
|
||
}
|
||
|
||
private function removeSlashes ($string) {
|
||
|
||
while (strpos($string, '//') !== false) {
|
||
$string = str_replace('//', '/', $string);
|
||
}
|
||
|
||
return $string;
|
||
}
|
||
|
||
// Often we need to proceed depending on game engine type
|
||
private function getGameType () {
|
||
|
||
// First do a check against the binary
|
||
if (in_array($this->appServerDetails['template']['gameBinary'], array('srcds_run', 'srcds.exe'))) {
|
||
return 'hl2';
|
||
}
|
||
|
||
if (in_array($this->appServerDetails['template']['gameBinary'], array('hlds_run', 'hlds.exe'))) {
|
||
return 'hl1';
|
||
}
|
||
|
||
if (in_array($this->appServerDetails['template']['gameBinary'], array('cod4_lnxded', 'codwaw_lnxded', 'iw3mp.exe', 'CoDWaWmp.exe'))) {
|
||
return 'cod';
|
||
}
|
||
|
||
// The admin might have configured a shell script instead of the native binary or script
|
||
// We also need to check against the gameQ setting to be on the safe side
|
||
if (in_array($this->appServerDetails['template']['gameq'], array('minecraft', 'minequery'))) {
|
||
return 'mc';
|
||
}
|
||
|
||
if (in_array($this->appServerDetails['template']['gameq'], array('aoc', 'csgo', 'css', 'dods', 'hl2dm', 'l4d', 'l4d2', 'ns2', 'tf2', 'zps'))) {
|
||
return 'hl2';
|
||
}
|
||
|
||
if (in_array($this->appServerDetails['template']['gameq'], array('cs16', 'cscz', 'dod', 'insurgency', 'ns', 'tfc'))) {
|
||
return 'hl1';
|
||
}
|
||
|
||
if (substr($this->appServerDetails['template']['gameq'], 0, 3) == 'cod') {
|
||
return 'cod';
|
||
}
|
||
|
||
return $this->appServerDetails['template']['gameq'];
|
||
}
|
||
|
||
/*
|
||
* Following code contains the user management related funtions
|
||
*/
|
||
|
||
private function linuxAddModUserGenerate ($userName, $password, $protected = false, $deactivate = false) {
|
||
|
||
$password = ($deactivate == false) ? $password : passwordgenerate(10);
|
||
$userNameHome = ($protected == false) ? $this->appServerDetails['userName'] : $this->appServerDetails['userName'] . '/pserver';
|
||
|
||
// Check if the user can be found. If not, add it, if yes, edit
|
||
$this->shellScripts['user'] .= 'if [ "`id ' . $userName . ' 2>/dev/null`" == "" ]; then' . "\n";
|
||
|
||
$this->shellScripts['user'] .= 'CONFIGUSERID=' . $this->appMasterServerDetails['configUserID'] . "\n";
|
||
$this->shellScripts['user'] .= 'USER=`ls -la /var/run/screen | grep S-' . $userName . ' | head -n 1 | awk \'{print $3}\'`' . "\n";
|
||
$this->shellScripts['user'] .= 'if [ "$USER" != "" -a $USER -eq $USER 2> /dev/null ]; then CONFIGUSERID=$USER; fi' . "\n";
|
||
$this->shellScripts['user'] .= 'USERID=`getent passwd | cut -f3 -d: | sort -un | awk \'BEGIN { id=\'${CONFIGUSERID}\' } $1 == id { id++ } $1 > id { print id; exit }\'`' . "\n";
|
||
$this->shellScripts['user'] .= 'if [ "`ls -la /var/run/screen | awk \'{print $3}\' | grep $USERID`" == "" -a "`grep \"x:$USERID:\" /etc/passwd`" == "" ]; then' . "\n";
|
||
$this->shellScripts['user'] .= 'if [ "`lsb_release -i 2> /dev/null | grep \'Distributor\' | awk \'{print tolower($3)}\'`" == "centos" ] || [ "`grep \'\bNAME=\b\' /etc/os-release | sed -n \'s/^.*NAME=//p\' | sed -e \'s/\(.*\)/\L\1/\'`" == "slackware" ]; then' . "\n";
|
||
$this->shellScripts['user'] .= 'sudo /usr/sbin/useradd -m -p `perl -e \'print crypt("\'' . $password . '\'","Sa")\'` -d ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $userNameHome) . ' -g ' . $this->appMasterServerDetails['ssh2User'] . ' -s /bin/false $USERID ' . $userName . ' 2>/dev/null' . "\n";
|
||
$this->shellScripts['user'] .= 'else' . "\n";
|
||
$this->shellScripts['user'] .= 'sudo /usr/sbin/useradd -m -p `perl -e \'print crypt("\'' . $password . '\'","Sa")\'` -d ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $userNameHome) . ' -g ' . $this->appMasterServerDetails['ssh2User'] . ' -s /bin/false -u $USERID ' . $userName . ' 2>/dev/null' . "\n";
|
||
$this->shellScripts['user'] .= 'fi' . "\n";
|
||
$this->shellScripts['user'] .= 'else' . "\n";
|
||
$this->shellScripts['user'] .= 'while [ "`ls -la /var/run/screen | awk \'{print $3}\' | grep $USERID`" != "" -o "`grep \"x:$USERID:\" /etc/passwd`" != "" ]; do' . "\n";
|
||
$this->shellScripts['user'] .= 'USERID=$[USERID+1]' . "\n";
|
||
$this->shellScripts['user'] .= 'if [ "`ls -la /var/run/screen | awk \'{print $3}\' | grep $USERID`" == "" -a "`grep \"x:$USERID:\" /etc/passwd`" == "" ]; then' . "\n";
|
||
$this->shellScripts['user'] .= 'if [ "`lsb_release -i 2> /dev/null | grep \'Distributor\' | awk \'{print tolower($3)}\'`" == "centos" ] || [ "`grep \'\bNAME=\b\' /etc/os-release | sed -n \'s/^.*NAME=//p\' | sed -e \'s/\(.*\)/\L\1/\'`" == "slackware" ]; then' . "\n";
|
||
$this->shellScripts['user'] .= 'sudo /usr/sbin/useradd -m -p `perl -e \'print crypt("\'' . $password . '\'","Sa")\'` -m -d ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $userNameHome) . ' -g ' . $this->appMasterServerDetails['ssh2User'] . ' -s /bin/false $USERID ' . $userName . ' 2>/dev/null' . "\n";
|
||
$this->shellScripts['user'] .= 'else' . "\n";
|
||
$this->shellScripts['user'] .= 'sudo /usr/sbin/useradd -m -p `perl -e \'print crypt("\'' . $password . '\'","Sa")\'` -m -d ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $userNameHome) . ' -g ' . $this->appMasterServerDetails['ssh2User'] . ' -s /bin/false -u $USERID ' . $userName . ' 2>/dev/null' . "\n";
|
||
$this->shellScripts['user'] .= 'fi' . "\n";
|
||
$this->shellScripts['user'] .= 'fi' . "\n";
|
||
$this->shellScripts['user'] .= 'done' . "\n";
|
||
$this->shellScripts['user'] .= 'fi' . "\n";
|
||
$this->addLogline('user.log', 'User ' . $userName . ' added');
|
||
$this->shellScripts['user'] .= 'else' . "\n";
|
||
$this->shellScripts['user'] .= 'sudo /usr/sbin/usermod -p `perl -e \'print crypt("\'' . $password . '\'","Sa")\'` -m -d ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $userNameHome) . ' ' . $userName . "\n";
|
||
$this->addLogline('user.log', 'User ' . $userName . ' edited');
|
||
$this->shellScripts['user'] .= 'fi' . "\n";
|
||
|
||
}
|
||
|
||
private function linuxAddModUser ($deactivate) {
|
||
|
||
$this->linuxAddModUserGenerate ($this->appServerDetails['userName'], $this->appServerDetails['ftpPassword'], false, $deactivate);
|
||
|
||
if ($this->appServerDetails['protectionModeAllowed']) {
|
||
$this->linuxAddModUserGenerate ($this->appServerDetails['userName'] . '-p', $this->appServerDetails['ftpPasswordProtected'], true, $deactivate);
|
||
}
|
||
}
|
||
|
||
private function windowsAddModUser () {
|
||
|
||
}
|
||
|
||
private function linuxDeleteUserGenerate ($userName) {
|
||
$this->shellScripts['user'] .= 'sudo pkill -u ' . $userName . "\n";
|
||
$this->shellScripts['user'] .= 'if [ "`id ' . $userName . ' 2>/dev/null`" != "" ]; then' . "\n";
|
||
$this->shellScripts['user'] .= '${IONICE}nice -n +19 sudo /usr/sbin/userdel -fr ' . $userName . ' > /dev/null 2>&1 ' . "\n";
|
||
$this->addLogline('user.log', 'User ' . $userName . ' deleted');
|
||
$this->shellScripts['user'] .= 'fi' . "\n";
|
||
|
||
}
|
||
|
||
private function linuxDelUser ($type) {
|
||
|
||
$this->linuxDeleteUserGenerate($this->appServerDetails['userName'] . '-p');
|
||
|
||
if ($type == 'both') {
|
||
$this->linuxDeleteUserGenerate($this->appServerDetails['userName']);
|
||
}
|
||
}
|
||
|
||
private function windowsDeluser ($type) {
|
||
|
||
}
|
||
|
||
public function userCud ($action, $type = false, $deactivate = false) {
|
||
|
||
if ($this->appServerDetails and isset($this->appMasterServerDetails['os'])) {
|
||
|
||
if ($action == 'del') {
|
||
if ($this->appMasterServerDetails['os'] == 'L') {
|
||
$this->linuxDelUser($type);
|
||
} else {
|
||
$this->windowsDeluser($type);
|
||
}
|
||
} else {
|
||
if ($this->appMasterServerDetails['os'] == 'L') {
|
||
$this->linuxAddModUser($deactivate);
|
||
} else {
|
||
$this->windowsAddModUser($deactivate);
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
// Quotas are a Linux technique to define the diskspace a user is allowed to use.
|
||
public function setQuota () {
|
||
if ($this->appServerDetails and $this->appMasterServerDetails['os'] == 'L' and $this->appMasterServerDetails['quotaActive'] == 'Y' and strlen($this->appMasterServerDetails['quotaCmd']) > 0 and $this->appServerDetails['hdd'] > 0) {
|
||
|
||
// setquota works with KibiByte and Inodes; Stored is Megabyte
|
||
$sizeInKibiByte = $this->appServerDetails['hdd'] * 1024;
|
||
$sizeInByte = $this->appServerDetails['hdd'] * 1048576;
|
||
$blockAmount = round(($sizeInByte /$this->appMasterServerDetails['blocksize']));
|
||
$inodeAmount = round($blockAmount / $this->appMasterServerDetails['inodeBlockRatio']);
|
||
$mountPoint = (isset($this->appMasterServerDetails['iniVars'][$this->appServerDetails['homeLabel']]['mountpoint'])) ? $this->appMasterServerDetails['iniVars'][$this->appServerDetails['homeLabel']]['mountpoint'] : $this->appServerDetails['homeDir'];
|
||
|
||
$this->shellScripts['user'] .= str_replace('%cmd%', ' -u ' . $this->appServerDetails['userName'] . ' ' . $sizeInKibiByte . ' ' . $sizeInKibiByte . ' ' . $inodeAmount . ' ' . $inodeAmount . ' ' . $mountPoint, $this->appMasterServerDetails['quotaCmd']) . "\n";
|
||
|
||
$this->addLogline('user.log', 'Userquota set for ' . $this->appServerDetails['userName']);
|
||
}
|
||
}
|
||
|
||
/*
|
||
* The next section contains private and public functions.
|
||
* When the root is Linux, they will generate the self deleting temporary shell scripts in ram, write them to the root and execute.
|
||
* When the root is Windows, they will generate the to be executed commands in ram and start them all at once at the end.
|
||
*/
|
||
|
||
// Generic function that add a user´s script to the to be generated and executed list
|
||
// The execution of scripts as a user will be sequential and blocking
|
||
// That way we can ensure that a server is installed before it gets started
|
||
private function addLinuxScript ($scriptName, $script, $userName = false, $doNotexecute = false) {
|
||
|
||
$userName = ($userName == false) ? $this->appServerDetails['userNameExecute'] : $userName;
|
||
|
||
if ($doNotexecute == false) {
|
||
$this->shellScripts['user'] .= 'chmod 770 ' . $scriptName . "\n";
|
||
$this->shellScripts['user'] .= 'sudo -u ' . $userName . ' ' . $scriptName . "\n";
|
||
}
|
||
|
||
$this->shellScripts['server']["{$scriptName}"] = $script;
|
||
}
|
||
|
||
private function copyStartFile($sourcePath, $targetPath) {
|
||
|
||
$targetPath = $this->removeSlashes($targetPath . $this->appServerDetails['template']['binarydir']);
|
||
$sourceFile = $this->removeSlashes($sourcePath . $this->appServerDetails['template']['binarydir'] . '/' . $this->appServerDetails['template']['gameBinary']);
|
||
$targetFile = $this->removeSlashes($targetPath . '/' . $this->appServerDetails['template']['gameBinary']);
|
||
|
||
$script = 'if [ -f "' . $sourceFile . '" ]; then' . "\n";
|
||
$script .= 'if [ ! -d "' . $targetPath . '" ]; then mkdir -p "' . $targetPath . '"; fi' . "\n";
|
||
$script .= 'if [ -f "' . $targetFile . '" ]; then' . "\n";
|
||
$script .= 'chmod 700 "' . $targetFile . '"' . "\n";
|
||
$script .= 'rm -f "' . $targetFile . '"' . "\n";
|
||
$script .= 'fi' . "\n";
|
||
$script .= 'cp -f "' . $sourceFile . '" "' . $targetFile . '"'. "\n";
|
||
$script .= 'chmod 700 "' . $targetFile . '"' . "\n";
|
||
$script .= 'fi' . "\n";
|
||
|
||
return $script;
|
||
}
|
||
|
||
// Function that generated the script for adding an app
|
||
private function linuxAddApp ($templates, $standalone = true) {
|
||
|
||
if ($standalone) {
|
||
$scriptName = $this->removeSlashes('/home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/add-' . $this->appServerDetails['userNameExecute'] . '-' . $this->appServerDetails['serverIP'] . '-' . $this->appServerDetails['port'] . '-apps.sh');
|
||
}
|
||
|
||
$serverDir = ($this->appServerDetails['protectionModeStarted'] == 'Y') ? 'pserver/' : 'server/';
|
||
$absolutePath = $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName'] . '/' . $serverDir);
|
||
|
||
$copyFileExtensions = array('xml', 'vdf', 'cfg', 'con', 'conf', 'config', 'ini', 'gam', 'txt', 'log', 'smx', 'sp', 'db', 'lang', 'lua', 'props', 'properties', 'json', 'example', 'html', 'yml', 'yaml', 'csv', 'eco');
|
||
|
||
if ($standalone and isset($scriptName)) {
|
||
$script = $this->shellScriptHeader;
|
||
$script .= 'rm -f ' . $scriptName . "\n";
|
||
} else {
|
||
$script = '';
|
||
}
|
||
|
||
$script .= "PATTERN='(/valve|/overviews/|/scripts/|/media/|/particles/|/sound/|/hl2/|/overviews/|/resource/|/sprites/|gameinfo.txt|steam.inf|steam_appid.txt)'" . "\n";
|
||
|
||
// Migrate old folder structure with ip_port as sub folder to structure without
|
||
$script .= 'if [ -d ' . $absolutePath . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . ' ]; then' . "\n";
|
||
$script .= 'mv ' . $absolutePath . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . '/* ' . $absolutePath . "\n";
|
||
$script .= '${IONICE}nice -n +19 rm -rf ' . $absolutePath . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . "\n";
|
||
$script .= 'fi' . "\n";
|
||
|
||
foreach ($templates as $template) {
|
||
|
||
$absoluteTargetTemplatePath = $this->removeSlashes($absolutePath . $template . '/');
|
||
$sourceTemplate = (substr($template, -2) == '-2' or substr($template, -2) == '-3') ? substr($template, 0, (strlen($template) -2)) : $template;
|
||
$absoluteSourceTemplatePath = $this->removeSlashes('/home/' . $this->appMasterServerDetails['ssh2User'] . '/masterserver/' . $sourceTemplate . '/');
|
||
|
||
$script .= 'if [ ! -d "' . $absoluteTargetTemplatePath . '" ]; then mkdir -p "' . $absoluteTargetTemplatePath . '"; fi' . "\n";
|
||
$script .= 'cd ' . $absoluteSourceTemplatePath . "\n";
|
||
|
||
if ($this->appServerDetails['template']['copyStartBinary'] == 'Y') {
|
||
$script .= $this->copyStartFile($absoluteSourceTemplatePath, $absoluteTargetTemplatePath);
|
||
}
|
||
|
||
$script .= 'FILEFOUND=(`find -mindepth 1 -type f \( -iname "*.' . implode('" -or -iname "*.', $copyFileExtensions) . '" \) | grep -v -E "$PATTERN"`)' . "\n";
|
||
$script .= 'for FILTEREDFILES in ${FILEFOUND[@]}; do' . "\n";
|
||
$script .= 'FOLDERNAME=`dirname "$FILTEREDFILES"`' . "\n";
|
||
$script .= 'if ([[ `find "$FOLDERNAME" -maxdepth 0 -type d` ]] && [[ ! -d "' . $absoluteTargetTemplatePath . '$FOLDERNAME" ]]); then mkdir -p "' . $absoluteTargetTemplatePath . '$FOLDERNAME"; fi' . "\n";
|
||
$script .= 'if [ -f "' . $absoluteTargetTemplatePath . '$FILTEREDFILES" ]; then find "' . $absoluteTargetTemplatePath . '$FILTEREDFILES" -maxdepth 1 -type l -delete; fi' . "\n";
|
||
$script .= 'if [ ! -f "' . $absoluteTargetTemplatePath . '$FILTEREDFILES" ]; then ${IONICE}cp "' . $absoluteSourceTemplatePath . '$FILTEREDFILES" "' . $absoluteTargetTemplatePath . '$FILTEREDFILES"; fi' . "\n";
|
||
$script .= 'done' . "\n";
|
||
$script .= 'cp -sr ' . $absoluteSourceTemplatePath . '* ' . $absoluteTargetTemplatePath . ' > /dev/null 2>&1' . "\n";
|
||
|
||
$this->addLogline('app_server.log', 'Server template ' . $absoluteTargetTemplatePath . ' owned by user ' . $this->appServerDetails['userNameExecute'] . ' added/synced');
|
||
|
||
}
|
||
|
||
$dirChmod = 700;
|
||
$fileChmod = 600;
|
||
|
||
if ($this->appServerDetails['protectionModeStarted'] == 'Y') {
|
||
$dirChmod = 750;
|
||
$fileChmod = 640;
|
||
}
|
||
$script .= '${IONICE}nice -n +19 find ' . $absolutePath . ' -type d -print0 | xargs -0 chmod ' . $dirChmod . "\n";
|
||
|
||
if ($this->appServerDetails['template']['copyStartBinary'] == 'Y' and strlen($this->appServerDetails['template']['gameBinary']) > 0) {
|
||
$script .= '${IONICE}nice -n +19 find ' . $absolutePath . ' -type f ! -name "' . $this->appServerDetails['template']['gameBinary'] . '" -print0 | xargs -0 chmod ' . $fileChmod . "\n";
|
||
} else {
|
||
$script .= '${IONICE}nice -n +19 find ' . $absolutePath . ' -type f -print0 | xargs -0 chmod ' . $fileChmod . "\n";
|
||
}
|
||
|
||
$script .= '${IONICE}nice -n +19 find -L ' . $absolutePath . ' -type l -delete' . "\n";
|
||
|
||
try {
|
||
if (substr($sourceTemplate, -3) === "cs2") {
|
||
$baseDir64 = $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName']) . "/.steam/sdk64";
|
||
$baseDir32 = $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName']) . "/.steam/sdk32";
|
||
|
||
$link64 = "$baseDir64/steamclient.so";
|
||
$link32 = "$baseDir32/steamclient.so";
|
||
|
||
// Befehle zur Erstellung der Verzeichnisse hinzufügen
|
||
$script .= '${IONICE}nice -n +19 mkdir -p ' . $baseDir64 . "\n";
|
||
$script .= '${IONICE}nice -n +19 mkdir -p ' . $baseDir32 . "\n";
|
||
|
||
// Befehle zur Erstellung der symbolischen Verknüpfungen hinzufügen
|
||
$script .= '${IONICE}nice -n +19 ln -s /home/' . $this->appMasterServerDetails['ssh2User'] . '/masterserver/steamCMD/linux64/steamclient.so ' . $link64 . "\n";
|
||
$script .= '${IONICE}nice -n +19 ln -s /home/' . $this->appMasterServerDetails['ssh2User'] . '/masterserver/steamCMD/linux32/steamclient.so ' . $link32 . "\n";
|
||
}
|
||
} catch (Exception $e) {
|
||
// Fehlerprotokollierung
|
||
error_log("Ein Fehler ist im Symbolverknüpfungs-Skript aufgetreten: " . $e->getMessage());
|
||
// Optional: Benutzerbenachrichtigung oder weitere Fehlerbehandlung
|
||
}
|
||
if ($standalone and isset($scriptName)) {
|
||
$this->addLinuxScript($scriptName, $script);
|
||
}
|
||
|
||
return $script;
|
||
|
||
}
|
||
|
||
private function getAllAllowedGames($names = false) {
|
||
|
||
global $sql;
|
||
|
||
$returnArray = array();
|
||
|
||
if ($this->appServerDetails) {
|
||
|
||
if ($names) {
|
||
$query = $sql->prepare("SELECT DISTINCT(t.`shorten`) AS `name` FROM `serverlist` AS s INNER JOIN `servertypes` AS t ON t.`id`=s.`servertype` WHERE s.`switchID`=?");
|
||
} else {
|
||
$query = $sql->prepare("SELECT DISTINCT(t.`description `) AS `name` FROM `serverlist` AS s INNER JOIN `servertypes` AS t ON t.`id`=s.`servertype` WHERE s.`switchID`=?");
|
||
}
|
||
|
||
$query->execute(array($this->appServerDetails['id']));
|
||
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
|
||
$returnArray[] = $row['name'];
|
||
}
|
||
}
|
||
|
||
return $returnArray;
|
||
}
|
||
|
||
public function addApp ($templates = array(), $sendMail = false) {
|
||
|
||
if (count($templates) == 0) {
|
||
$templates = array($this->appServerDetails['app']['templateChoosen']);
|
||
}
|
||
|
||
if ($sendMail === true) {
|
||
|
||
$mailConnectInfo = array(
|
||
'ip' => $this->appServerDetails['serverIP'],
|
||
'port' => $this->appServerDetails['port']
|
||
);
|
||
|
||
for ($i = 2; $i < 6; $i++) {
|
||
if ($this->appServerDetails["port{$i}"] > 0) {
|
||
$mailConnectInfo["port{$i}"] = $this->appServerDetails["port{$i}"];
|
||
}
|
||
}
|
||
|
||
sendmail('emailserverinstall', $this->appServerDetails['userid'], $this->appServerDetails['serverIP'] . ':' . $this->appServerDetails['port'], implode(', ', $this->getAllAllowedGames(true)), $mailConnectInfo);
|
||
}
|
||
|
||
if ($this->appServerDetails) {
|
||
if ($this->appMasterServerDetails['os'] == 'L') {
|
||
$this->linuxAddApp($templates);
|
||
} else if ($this->appMasterServerDetails['os'] == 'W') {
|
||
}
|
||
}
|
||
}
|
||
|
||
private function backUpSpareFiles($template, $spareFiles) {
|
||
|
||
if (count($spareFiles) == 0) {
|
||
return '';
|
||
}
|
||
|
||
$script = 'cd ' . $template . "\n";
|
||
|
||
foreach ($spareFiles as $spareFile) {
|
||
|
||
$script .= 'TARGET_FOLDER="`dirname ' . $spareFile . '`"' . "\n";
|
||
|
||
$script .= 'if [ ! -d "../sparefiles/${TARGET_FOLDER}" ]; then mkdir -p "../sparefiles/${TARGET_FOLDER}"' . "\n";
|
||
|
||
$script .= 'cp "' . $spareFile . '" "../sparefiles/' . $spareFile . '"' . "\n";
|
||
}
|
||
|
||
$script .= 'cd ..' . "\n";
|
||
|
||
return $script;
|
||
}
|
||
|
||
private function restoreSpareFiles($template) {
|
||
|
||
$script = 'if [ -d "sparefiles" ]; then' . "\n";
|
||
$script .= 'if [ !-d "' . $template . '" ]; then mkdir -p "' . $template . '"' . "\n";
|
||
$script .= 'mv "sparefiles/*" "' . $template . '/"' . "\n";
|
||
$script .= 'rm -rf "sparefiles"' . "\n";
|
||
$script .= 'fi' . "\n";
|
||
|
||
return $script;
|
||
}
|
||
|
||
private function linuxRemoveApp($templates, $spareFiles) {
|
||
|
||
$scriptName = $this->removeSlashes('/home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/del-' . $this->appServerDetails['userNameExecute'] . '-' . $this->appServerDetails['serverIP'] . '-' . $this->appServerDetails['port'] . '-templates.sh');
|
||
$serverDir = ($this->appServerDetails['protectionModeStarted'] == 'Y') ? 'pserver/' : 'server/';
|
||
|
||
$script = $this->shellScriptHeader;
|
||
$script .= 'rm -f ' . $scriptName . "\n";
|
||
$script .= 'cd ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName'] . '/' . $serverDir) . "\n";
|
||
|
||
foreach ($templates as $template) {
|
||
|
||
$script .= $this->backUpSpareFiles($template, $spareFiles);
|
||
|
||
$script .= 'if [ -d "' . $template . '" ]; then ${IONICE}rm -rf "' . $template . '"; fi' . "\n";
|
||
$this->addLogline('app_server.log', 'Server template ' . $serverDir . $template . ' owned by user ' . $this->appServerDetails['userNameExecute'] . ' deleted');
|
||
|
||
$script .= $this->restoreSpareFiles($template);
|
||
}
|
||
|
||
$this->addLinuxScript($scriptName, $script);
|
||
}
|
||
|
||
public function removeApp($templates, $spareFiles = array()) {
|
||
|
||
if ($this->appServerDetails) {
|
||
|
||
$this->easyAntiCheatSettings('stop');
|
||
|
||
if (count($templates) > 0) {
|
||
if ($this->appMasterServerDetails['os'] == 'L') {
|
||
$this->linuxRemoveApp($templates, $spareFiles);
|
||
} else if ($this->appMasterServerDetails['os'] == 'W') {
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private function linuxMcWorldSave($standalone = true) {
|
||
|
||
$screenName = $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'];
|
||
$scriptName = $this->removeSlashes('/home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/worldsave-' . $this->appServerDetails['userNameExecute'] . '-' . $this->appServerDetails['serverIP'] . '-' . $this->appServerDetails['port'] . '.sh');
|
||
|
||
if ($standalone === true) {
|
||
|
||
$script = $this->shellScriptHeader;
|
||
$script .= 'rm -f ' . $scriptName . "\n";
|
||
|
||
} else {
|
||
$script = '';
|
||
}
|
||
|
||
$script .= 'if [ "`screen -ls | grep ' . $screenName . ' | awk \'{print $1}\'`" != "" ]; then' . "\n";
|
||
$script .= 'screen -p 0 -S ' . $screenName . ' -X stuff $\'\n\'' . "\n";
|
||
$script .= 'screen -p 0 -S ' . $screenName . ' -X stuff "say SERVER WILL SAVE THE WORLD NOW"' . "\n";
|
||
$script .= 'screen -p 0 -S ' . $screenName . ' -X stuff $\'\n\'' . "\n";
|
||
$script .= 'screen -p 0 -S ' . $screenName . ' -X stuff $\'\n\'' . "\n";
|
||
$script .= 'screen -p 0 -S ' . $screenName . ' -X stuff "save-all"' . "\n";
|
||
$script .= 'screen -p 0 -S ' . $screenName . ' -X stuff $\'\n\'' . "\n";
|
||
$script .= 'sleep 10' . "\n";
|
||
$script .= 'fi' . "\n";
|
||
|
||
if ($standalone === true) {
|
||
|
||
$this->addLinuxScript($scriptName, $script);
|
||
|
||
$this->addLogline('app_server.log', 'Minecraft worldsave ' . $screenName . ' owned by user ' . $this->appServerDetails['userNameExecute']);
|
||
}
|
||
|
||
return $script;
|
||
}
|
||
|
||
public function mcWorldSave () {
|
||
if ($this->appServerDetails and $this->getGameType() == 'mc') {
|
||
if ($this->appMasterServerDetails['os'] == 'L') {
|
||
} else if ($this->appMasterServerDetails['os'] == 'W') {
|
||
}
|
||
}
|
||
}
|
||
|
||
private function linuxStopApp ($standalone = true, $scriptName = '') {
|
||
|
||
$screenName = $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'];
|
||
|
||
if ($standalone === true or $scriptName == '') {
|
||
|
||
$scriptName = $this->removeSlashes('/home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/stop-' . $this->appServerDetails['userNameExecute'] . '-' . $this->appServerDetails['serverIP'] . '-' . $this->appServerDetails['port'] . '.sh');
|
||
|
||
$script = $this->shellScriptHeader;
|
||
$script .= 'rm -f ' . $scriptName . "\n";
|
||
|
||
} else {
|
||
$script = '';
|
||
}
|
||
|
||
$script .= 'screen -wipe > /dev/null 2>&1' . "\n";
|
||
$script .= 'if [[ `screen -ls | grep ' . $screenName . '` ]]; then' . "\n";
|
||
|
||
if ($this->appServerDetails['template']['gameq'] == 'minecraft') {
|
||
$script .= $this->linuxMcWorldSave(false);
|
||
}
|
||
|
||
$gameType = $this->getGameType();
|
||
|
||
if ($gameType == 'hl2' and $this->appServerDetails['tvAllowed'] == 'Y') {
|
||
$script .= 'screen -p 0 -S ' . $screenName . ' -X stuff $\'\n\'' . "\n";
|
||
$script .= 'screen -p 0 -S ' . $screenName . ' -X stuff "tv_stoprecord"' . "\n";
|
||
$script .= 'screen -p 0 -S ' . $screenName . ' -X stuff $\'\n\'' . "\n";
|
||
}
|
||
|
||
$script .= 'if [ "`screen -ls | grep ' . $screenName . ' | wc -l`" == "1" ]; then screen -r ' . $screenName . ' -X quit; fi' . "\n";
|
||
|
||
$script .= 'fi' . "\n";
|
||
|
||
$script .= 'ps x | grep ' . $screenName . ' | grep -v ' . $scriptName . ' | grep -v grep | awk \'{print $1}\' | while read PID; do' . "\n";
|
||
$script .= 'kill $PID > /dev/null 2>&1' . "\n";
|
||
$script .= 'kill -9 $PID > /dev/null 2>&1' . "\n";
|
||
$script .= 'done' . "\n";
|
||
|
||
$script .= 'ps x | grep -v ' . $scriptName . ' | grep Ssl | grep java | grep -v grep | awk \'{print $1}\' | while read PID; do' . "\n";
|
||
$script .= 'kill $PID > /dev/null 2>&1' . "\n";
|
||
$script .= 'kill -9 $PID > /dev/null 2>&1' . "\n";
|
||
$script .= 'done' . "\n";
|
||
|
||
$script .= 'ps x | grep -v ' . $scriptName . ' | grep Ssl+ | grep java | grep -v grep | awk \'{print $1}\' | while read PID; do' . "\n";
|
||
$script .= 'kill $PID > /dev/null 2>&1' . "\n";
|
||
$script .= 'kill -9 $PID > /dev/null 2>&1' . "\n";
|
||
$script .= 'done' . "\n";
|
||
|
||
if ($gameType == 'hl2' and $this->appServerDetails['tvAllowed'] == 'Y' and in_array($this->appServerDetails['app']['upload'], array(2, 3)) and $this->appServerDetails['app']['uploadDir']) {
|
||
$script .= $this->linuxDemoUpload(false);
|
||
}
|
||
|
||
$script .= $this->arkCheckSleep();
|
||
|
||
if ($standalone === true) {
|
||
$this->addLinuxScript($scriptName, $script);
|
||
$this->addLogline('app_server.log', 'App ' . $screenName . ' owned by user ' . $this->appServerDetails['userNameExecute'] . ' stopped');
|
||
}
|
||
|
||
return $script;
|
||
}
|
||
|
||
public function stopApp () {
|
||
|
||
global $sql;
|
||
|
||
if ($this->appServerDetails) {
|
||
|
||
$this->easyAntiCheatSettings('stop');
|
||
|
||
if ($this->appMasterServerDetails['os'] == 'L') {
|
||
$this->linuxStopApp();
|
||
} else if ($this->appMasterServerDetails['os'] == 'W') {
|
||
}
|
||
|
||
$query = $sql->prepare("UPDATE `gsswitch` SET `stopped`='Y' WHERE `id`=? LIMIT 1");
|
||
$query->execute(array($this->appServerDetails['id']));
|
||
}
|
||
}
|
||
|
||
private function linuxHardStop ($userName) {
|
||
|
||
$scriptName = $this->removeSlashes('/home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/hardstop-' . $userName . '.sh');
|
||
|
||
$script = $this->shellScriptHeader;
|
||
$script .= 'rm -f ' . $scriptName . "\n";
|
||
|
||
$script .= 'crontab -r' . "\n";
|
||
$script .= 'screen -wipe > /dev/null 2>&1' . "\n";
|
||
//$script .= 'pkill -u `whoami`' . "\n";
|
||
|
||
$this->addLinuxScript($scriptName, $script, $userName);
|
||
$this->addLogline('app_server.log', 'Hard stop for user ' . $userName);
|
||
}
|
||
|
||
public function stopAppHard () {
|
||
if ($this->appServerDetails and $this->appMasterServerDetails['os'] == 'L') {
|
||
|
||
$this->linuxHardStop($this->appServerDetails['userName']);
|
||
|
||
if ($this->appServerDetails['protectionModeAllowed'] == 'Y') {
|
||
$this->linuxHardStop($this->appServerDetails['userNameExecute']);
|
||
}
|
||
|
||
} else if ($this->appServerDetails and $this->appMasterServerDetails['os'] == 'W') {
|
||
}
|
||
}
|
||
|
||
private function replaceValue($customColumns, $replaceSettings, $value) {
|
||
|
||
if (is_string($value) and strpos($value, '%') !== false) {
|
||
$value = str_replace($replaceSettings['placeholder'], $replaceSettings['replacePlaceholderWith'], $value);
|
||
}
|
||
|
||
foreach ($customColumns as $customColumn) {
|
||
$value = str_replace('%' . $customColumn['name'] . '%', $customColumn['value'], $value);
|
||
}
|
||
|
||
// Check if it is a numeric value but a string and convert
|
||
if (is_numeric($value) and gettype($value) == "string") {
|
||
$value = (int) $value;
|
||
}
|
||
|
||
return $value;
|
||
}
|
||
|
||
private function protectedYaml($replaceSettings, $parsedConfig) {
|
||
|
||
$customColumns = customColumns('G', $this->appServerDetails['id']);
|
||
|
||
foreach ($parsedConfig as $key => $value) {
|
||
|
||
if (is_array($value) or is_object($value)) {
|
||
$parsedConfig[$key] = $this->protectedYaml($replaceSettings, $value);
|
||
} else {
|
||
$parsedConfig[$key] = $this->replaceValue($customColumns, $replaceSettings, $value);
|
||
}
|
||
}
|
||
|
||
return $parsedConfig;
|
||
}
|
||
|
||
private function protectedXML($replaceSettings, $parsedConfig) {
|
||
|
||
$customColumns = customColumns('G', $this->appServerDetails['id']);
|
||
|
||
foreach ($parsedConfig as $key => $value) {
|
||
|
||
if (is_object($value)) {
|
||
|
||
foreach ($value->attributes() as $k => $v) {
|
||
$value->attributes()->$k = $this->replaceValue($customColumns, $replaceSettings, (string) $v);
|
||
}
|
||
|
||
} else if (is_array($value)) {
|
||
|
||
$parsedConfig[$key] = $this->protectedXML($replaceSettings, $value);
|
||
|
||
} else {
|
||
$parsedConfig[$key] = $this->replaceValue($customColumns, $replaceSettings, $value);
|
||
}
|
||
}
|
||
|
||
return $parsedConfig;
|
||
}
|
||
|
||
private function xmlStringToObject($xml) {
|
||
|
||
try {
|
||
|
||
if (strpos($xml, '<?xml') === false) {
|
||
$xml = '<?xml version="1.0"?><xml>' . $xml . '</xml>';
|
||
}
|
||
|
||
return new SimpleXMLElement($xml);
|
||
|
||
} catch (Exception $e) {
|
||
return new stdClass;
|
||
}
|
||
}
|
||
|
||
private function parseYML($string) {
|
||
try {
|
||
return Yaml::parse($string);
|
||
} catch (Exception $e) {
|
||
return new stdClass;
|
||
}
|
||
}
|
||
|
||
private function protectedSettingsToArray() {
|
||
|
||
$protectedString = '';
|
||
$cvarProtectArray = array();
|
||
$lendServerReplaceMents = array();
|
||
$debugger = array();
|
||
|
||
$replaceSettings = $this->getReplacements();
|
||
@parse_ini_string($this->appServerDetails['template']['configedit'], true, INI_SCANNER_RAW);
|
||
|
||
foreach (explode("\n", $this->appServerDetails['template']['configedit']) as $line) {
|
||
|
||
$line = str_replace(array("\r"), '', $line);
|
||
|
||
if (preg_match('/^(\[[\w\/\.\-\_]{1,}\]|\[[\w\/\.\-\_]{1,}\] (xml|ini|cfg|lua|json|ddot|yml|Yaml|yaml))$/', $line)) {
|
||
|
||
if (strlen($protectedString) > 0 and isset($configPathAndFile) and !isset($cvarProtectArray[$configPathAndFile]['cvars'])) {
|
||
if (in_array($cvarProtectArray[$configPathAndFile]['type'], array('yml', 'yaml', 'Yaml'))) {
|
||
$cvarProtectArray[$configPathAndFile]['cvars'] = $this->protectedYaml($replaceSettings, $this->parseYML($protectedString));
|
||
} else if ($cvarProtectArray[$configPathAndFile]['type'] == 'xml') {
|
||
$cvarProtectArray[$configPathAndFile]['cvars'] = $this->protectedXML($replaceSettings, $this->xmlStringToObject($protectedString));
|
||
}
|
||
}
|
||
|
||
$exploded = preg_split("/\s+/", $line, -1, PREG_SPLIT_NO_EMPTY);
|
||
|
||
$cvarType = (isset($exploded[1])) ? $exploded[1] : 'cfg';
|
||
|
||
$configPathAndFile = substr($exploded[0], 1, strlen($exploded[0]) - 2);
|
||
|
||
$cvarProtectArray[$configPathAndFile]['type'] = $cvarType;
|
||
|
||
$protectedString = '';
|
||
|
||
} else if (isset($configPathAndFile) and isset($cvarProtectArray[$configPathAndFile]['type'])) {
|
||
|
||
unset($splitLine);
|
||
|
||
if ($cvarProtectArray[$configPathAndFile]['type'] == 'cfg') {
|
||
|
||
$splitLine = preg_split("/\s+/", $line, -1, PREG_SPLIT_NO_EMPTY);
|
||
//TODO
|
||
} else if (in_array($cvarProtectArray[$configPathAndFile]['type'], array('yml','yaml','Yaml'/*,'xml'*/))) {
|
||
|
||
$protectedString .= $line . "\r\n";
|
||
|
||
} else if (in_array($cvarProtectArray[$configPathAndFile]['type'], array('ini','lua'))) {
|
||
|
||
$splitLine = preg_split("/\=/", $line, -1, PREG_SPLIT_NO_EMPTY);
|
||
|
||
} else if (in_array($cvarProtectArray[$configPathAndFile]['type'], array('json','ddot'))) {
|
||
|
||
$splitLine = preg_split("/:/", $line, -1, PREG_SPLIT_NO_EMPTY);
|
||
|
||
//TODO
|
||
// In case of XML configs the splitting is more complicated
|
||
} else if ($cvarProtectArray[$configPathAndFile]['type'] == 'xml') {
|
||
|
||
$exploded = explode('>', $line);
|
||
|
||
if (isset($exploded[1])) {
|
||
|
||
$key = str_replace('<', '', $exploded[0]);
|
||
|
||
@list($value) = explode('<', $exploded[1]);
|
||
|
||
$splitLine = array($key, $value);
|
||
}
|
||
} else {
|
||
$debugger[] = 'Type not known yet: '. $line;
|
||
}
|
||
|
||
if (isset($splitLine[1])) {
|
||
|
||
$replacedLine = str_replace($replaceSettings['placeholder'], $replaceSettings['replacePlaceholderWith'], $splitLine[1]);
|
||
|
||
foreach (customColumns('G', $this->appServerDetails['id']) as $customColumn) {
|
||
$replacedLine = str_replace('%' . $customColumn['name'] . '%', $customColumn['value'], $replacedLine);
|
||
}
|
||
|
||
$cvarProtectArray[$configPathAndFile]['cvars'][$splitLine[0]] = $replacedLine;
|
||
|
||
} else if (isset($splitLine[0])) {
|
||
$debugger[] = 'no second part for ' . $splitLine[0];
|
||
} else {
|
||
$debugger[] = '$splitLine not defined';
|
||
}
|
||
|
||
} else {
|
||
$debugger[] = 'The sorry rest: ' . $line;
|
||
}
|
||
}
|
||
|
||
if (strlen($protectedString) > 0 and isset($configPathAndFile) and !isset($cvarProtectArray[$configPathAndFile]['cvars'])) {
|
||
if (in_array($cvarProtectArray[$configPathAndFile]['type'], array('yml', 'yaml', 'Yaml'))) {
|
||
|
||
$cvarProtectArray[$configPathAndFile]['cvars'] = $this->protectedYaml($replaceSettings, $this->parseYML($protectedString));
|
||
|
||
//TODO
|
||
}/* else if ($cvarProtectArray[$configPathAndFile]['type'] == 'xml') {
|
||
$cvarProtectArray[$configPathAndFile]['cvars'] = $this->protectedXML($replaceSettings, $this->xmlStringToObject($protectedString));
|
||
}*/
|
||
}
|
||
|
||
if ($this->appServerDetails['lendServer'] == 'Y') {
|
||
|
||
if ($this->appServerDetails['lendServer'] == 'Y') {
|
||
$lendDetails = $this->getLendDetails();
|
||
}
|
||
|
||
if (!isset($lendDetails) or !is_array($lendDetails)) {
|
||
$lendDetails = array('rcon' => '', 'password' => '', 'slots' => $this->appServerDetails['slots']);
|
||
}
|
||
|
||
$gameType = $this->getGameType();
|
||
|
||
if ($gameType == 'mc') {
|
||
$lendServerReplaceMents = array('enable-rcon' => 'true', 'rcon.password' => $lendDetails['rcon']);
|
||
} else if ($gameType == 'hl2' or $gameType == 'hl1') {
|
||
$lendServerReplaceMents = array('sv_password' => $lendDetails['password'], 'rcon' => $lendDetails['rcon']);
|
||
} else if ($gameType == 'cod') {
|
||
$lendServerReplaceMents = array('g_password' => $lendDetails['password'], 'rcon_password' => $lendDetails['rcon']);
|
||
} else if ($gameType == 'teeworlds') {
|
||
$lendServerReplaceMents = array('sv_password' => $lendDetails['password'], 'sv_rcon_password' => $lendDetails['rcon']);
|
||
} else if ($gameType == 'samp') {
|
||
$lendServerReplaceMents = array('password' => $lendDetails['password'], 'rcon' => 1, 'rcon_password' => $lendDetails['rcon']);
|
||
}
|
||
}
|
||
|
||
// Remove configs that do not contain any overwrite settings
|
||
// Removing will prevent unnecessary FTP connections
|
||
foreach ($cvarProtectArray as $config => $values) {
|
||
|
||
if ($this->appServerDetails['lendServer'] == 'Y') {
|
||
|
||
foreach ($lendServerReplaceMents as $cvar => $value) {
|
||
$cvarProtectArray[$config]['cvars'][$cvar] = $value;
|
||
}
|
||
}
|
||
|
||
if (!isset($values['cvars']) or count($values['cvars']) == 0) {
|
||
unset($cvarProtectArray[$config]);
|
||
}
|
||
}
|
||
|
||
return $cvarProtectArray;
|
||
}
|
||
|
||
private function getFileAndPathName($fileWithPath) {
|
||
|
||
$splitConfigPath = preg_split('/\//', $this->removeSlashes($fileWithPath), -1, PREG_SPLIT_NO_EMPTY);
|
||
$folderFileCount = count($splitConfigPath) - 1;
|
||
|
||
$i = 0;
|
||
|
||
$path = '';
|
||
|
||
while ($i < $folderFileCount) {
|
||
$path .= '/' . $splitConfigPath[$i];
|
||
$i++;
|
||
}
|
||
|
||
return array('path' => $path, 'file' => $splitConfigPath[$i]);
|
||
}
|
||
|
||
private function isAssociative($array) {
|
||
return array_keys($array) !== range(0, count($array) - 1);
|
||
}
|
||
|
||
private function replaceArrayValues($givenArray, $replacements) {
|
||
|
||
foreach(array_keys($givenArray) as $key) {
|
||
|
||
if (is_array($givenArray[$key])) {
|
||
|
||
$givenArray[$key] = $this->replaceArrayValues($givenArray[$key], ((is_array($replacements) or is_object($replacements)) and isset($replacements[$key])) ? $replacements[$key] : $replacements);
|
||
|
||
} else {
|
||
|
||
if (isset($this->undefinedRequiredVars[$key])) {
|
||
unset($this->undefinedRequiredVars[$key]);
|
||
}
|
||
|
||
if (isset($replacements[$key])) {
|
||
$givenArray[$key] = $replacements[$key];
|
||
}
|
||
|
||
// Check if it is a numeric value but a string and convert
|
||
if (is_numeric($givenArray[$key]) and gettype($givenArray[$key]) == "string") {
|
||
$givenArray[$key] = (int) $givenArray[$key];
|
||
}
|
||
}
|
||
}
|
||
|
||
return $givenArray;
|
||
}
|
||
|
||
private function booleanOrValue($value) {
|
||
|
||
if (is_bool($value)) {
|
||
return ($value) ? "true" : "false";
|
||
}
|
||
|
||
return $value;
|
||
}
|
||
|
||
private function generateIniString($array) {
|
||
|
||
$iniString = '';
|
||
|
||
foreach($array as $key => $value) {
|
||
|
||
if (is_array($value)) {
|
||
|
||
foreach($value as $arrayValue) {
|
||
$iniString .= $key . '=' . $this->booleanOrValue($arrayValue) . PHP_EOL;
|
||
}
|
||
|
||
} else {
|
||
$iniString .= $key . '=' . $this->booleanOrValue($value) . PHP_EOL;
|
||
}
|
||
}
|
||
|
||
return $iniString;
|
||
}
|
||
|
||
private function replaceIni($stored, $replacements) {
|
||
|
||
if (!$stored) {
|
||
$stored = array();
|
||
}
|
||
|
||
$iniString = "";
|
||
$arrayKeys = array_keys($stored);
|
||
|
||
if (count($arrayKeys) !== 0) {
|
||
|
||
if (is_array($stored[$arrayKeys[0]]) and $this->isAssociative($stored[$arrayKeys[0]])) {
|
||
|
||
foreach($stored as $iniGroup => $values) {
|
||
$iniString .= '[' . $iniGroup . ']' . PHP_EOL;
|
||
$iniString .= $this->generateIniString($this->replaceArrayValues($values, $replacements));
|
||
}
|
||
|
||
} else {
|
||
$iniString = $this->generateIniString($this->replaceArrayValues($stored, $replacements));
|
||
}
|
||
}
|
||
|
||
$iniString .= $this->generateIniString($this->undefinedRequiredVars);
|
||
|
||
return $iniString;
|
||
}
|
||
|
||
private function addNotFoundVars($replacedArray, $key, $value) {
|
||
|
||
if (!isset($replacedArray[$key]) or (!is_array($replacedArray[$key]) and !is_object($replacedArray[$key]))) {
|
||
|
||
$replacedArray[$key] = $value;
|
||
|
||
} else {
|
||
|
||
foreach ($replacedArray[$key] as $k => $v) {
|
||
$replacedArray[$key] = $this->addNotFoundVars($replacedArray[$key], $k, $v);
|
||
}
|
||
}
|
||
|
||
return $replacedArray;
|
||
}
|
||
|
||
private function replaceArray($stored, $replacements) {
|
||
|
||
if (!$stored) {
|
||
$stored = array();
|
||
}
|
||
|
||
$replacedArray = $this->replaceArrayValues($stored, $replacements);
|
||
|
||
foreach ($this->undefinedRequiredVars as $key => $value) {
|
||
$replacedArray = $this->addNotFoundVars($replacedArray, $key, $value);
|
||
}
|
||
|
||
return $replacedArray;
|
||
}
|
||
|
||
private function replaceYaml($stored, $replacements) {
|
||
return Yaml::dump($this->replaceArray($stored, $replacements), 2, 4);
|
||
}
|
||
|
||
//TODO: Replace XML objects
|
||
private function replaceXML($stored, $replacements) {
|
||
|
||
if (!$stored) {
|
||
$stored = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?>');
|
||
}
|
||
|
||
return $stored->asXML();
|
||
}
|
||
|
||
private function replaceJSON($stored, $replacements) {
|
||
return json_encode($this->replaceArray($stored, $replacements), JSON_PRETTY_PRINT);
|
||
}
|
||
|
||
private function replaceLua($stored, $replacements) {
|
||
return Lua::arrayToLua($this->replaceArray($stored, $replacements));
|
||
}
|
||
|
||
private function correctProtectedFiles () {
|
||
|
||
$protectedConfigs = $this->protectedSettingsToArray();
|
||
|
||
if (count($protectedConfigs) > 0) {
|
||
|
||
$ftpObect = new EasyWiFTP($this->appMasterServerDetails['ssh2IP'], $this->appMasterServerDetails['ftpPort'], $this->appServerDetails['userNameExecute'], $this->appServerDetails['ftpPasswordExecute']);
|
||
|
||
if ($ftpObect->loggedIn === true) {
|
||
|
||
foreach ($protectedConfigs as $config => $values) {
|
||
|
||
$fileWithPath = $this->appServerDetails['absoluteFTPPath'] . '/' . $config;
|
||
$fileAndPath = $this->getFileAndPathName($fileWithPath);
|
||
|
||
if (!$ftpObect->downloadToTemp($fileWithPath)) {
|
||
|
||
$noChrootfileWithPath = $this->appServerDetails['absoluteFTPPathNoChroot'] . '/' . $config;
|
||
$noChrootfileAndPath = $this->getFileAndPathName($noChrootfileWithPath);
|
||
|
||
if ($ftpObect->downloadToTemp($noChrootfileAndPath)) {
|
||
$fileAndPath = $noChrootfileAndPath;
|
||
}
|
||
}
|
||
|
||
$path = $fileAndPath['path'];
|
||
$fileName = $fileAndPath['file'];
|
||
|
||
$configFileContent = $ftpObect->getTempFileContent();
|
||
|
||
// We have one temp handle for all files to reduce the amount of needed ram
|
||
$ftpObect->tempHandle = null;
|
||
$this->undefinedRequiredVars = $values['cvars'];
|
||
|
||
//TODO handle each type of file with specific parser
|
||
if ($values['type'] === 'ini') {
|
||
|
||
$ftpObect->writeContentToTemp($this->replaceIni(@parse_ini_string($configFileContent, false, INI_SCANNER_RAW), $values['cvars']));
|
||
|
||
} else if ($values['type'] === 'yml' or $values['type'] === 'Yaml' or $values['type'] === 'yaml') {
|
||
|
||
$ftpObect->writeContentToTemp($this->replaceYaml($this->parseYML($configFileContent), $values['cvars']));
|
||
//TODO
|
||
/* } else if ($values['type'] === 'xml') {
|
||
|
||
$ftpObect->writeContentToTemp($this->replaceXML(new SimpleXMLElement($configFileContent), $values['cvars']));
|
||
*/
|
||
} else if ($values['type'] == 'json') {
|
||
|
||
$ftpObect->writeContentToTemp($this->replaceJSON(@parse_ini_string(@json_decode($configFileContent), false, INI_SCANNER_RAW), $values['cvars']));
|
||
|
||
} else if ($values['type'] == 'lua') {
|
||
|
||
if (!class_exists('Lua')) {
|
||
include(EASYWIDIR . '/stuff/methods/class_lua.php');
|
||
}
|
||
|
||
$ftpObect->writeContentToTemp($this->replaceLua(Lua::luaToArray($configFileContent), $values['cvars']));
|
||
|
||
} else {
|
||
|
||
$cvarsNotFound = $values['cvars'];
|
||
|
||
// Depending how the file was uploaded and written, there might be lots of not needed characters in the file
|
||
// A clean up will make the file handling lot easier
|
||
$configFileContent = str_replace(array("\0","\b","\r","\Z"),"", $configFileContent);
|
||
|
||
$lines = explode("\n", $configFileContent);
|
||
$lineCount = count($lines) - 1;
|
||
$i = 0;
|
||
|
||
// iterate over all lines
|
||
foreach ($lines as $singeLine) {
|
||
|
||
// Set to false on each iteration to be able to detect config overwrites
|
||
$edited = false;
|
||
|
||
// For easier comparison make a string to lower
|
||
$loweredSingleLine = strtolower($singeLine);
|
||
|
||
foreach ($values['cvars'] as $cvar => $value) {
|
||
|
||
if ($values['type'] == 'cfg' and preg_match('/^[\s\/]{0,}' . strtolower($cvar) . '\s+(.*)$/', $loweredSingleLine)) {
|
||
|
||
$edited = true;
|
||
|
||
unset($cvarsNotFound[$cvar]);
|
||
|
||
$splitLine = preg_split('/' . $cvar . '/', $singeLine, -1, PREG_SPLIT_NO_EMPTY);
|
||
|
||
$ftpObect->writeContentToTemp((isset($splitLine[1])) ? $splitLine[0] . $cvar . ' ' . $value : $cvar . ' ' . $value);
|
||
|
||
} else if ($values['type'] == 'ddot' and preg_match('/^[\s\/]{0,}' . strtolower($cvar) . '[\s+]{0,}\:[\s+]{0,}(.*)$/', $loweredSingleLine)) {
|
||
|
||
$edited = true;
|
||
|
||
unset($cvarsNotFound[$cvar]);
|
||
|
||
$ftpObect->writeContentToTemp($cvar . ':' . $value);
|
||
|
||
} else if ($values['type'] == 'xml' and @preg_match("/^(.*)\<" . strtolower($cvar) . "\>(.*)\<\/" . strtolower($cvar) . "\>(.*)$/", $loweredSingleLine)) {
|
||
|
||
$edited = true;
|
||
|
||
unset($cvarsNotFound[$cvar]);
|
||
|
||
$splitLine = preg_split('/\<' . $cvar . '/', $singeLine, -1, PREG_SPLIT_NO_EMPTY);
|
||
|
||
$ftpObect->writeContentToTemp((isset($splitLine[1])) ? $splitLine[0] . '<' .$cvar . '>' . $value . '</' . $cvar . '>' : '<' . $cvar . '> ' . $value . '</' . $cvar . '>');
|
||
}
|
||
}
|
||
|
||
// Write untouched content
|
||
if ($edited == false) {
|
||
$ftpObect->writeContentToTemp($singeLine);
|
||
}
|
||
|
||
// If we do not count, we would add a newline at the end every time, a file is edited
|
||
if ($i < $lineCount) {
|
||
$ftpObect->writeContentToTemp("\r\n");
|
||
}
|
||
|
||
$i++;
|
||
}
|
||
|
||
$debug = array();
|
||
|
||
// In case of ini or CFG files we can add entries, which are missing from the file and should be protected
|
||
foreach ($cvarsNotFound as $cvar => $value) {
|
||
|
||
if ($values['type'] == 'cfg') {
|
||
|
||
$ftpObect->writeContentToTemp($cvar . ' ' . $value . "\r\n");
|
||
|
||
} else if ($values['type'] == 'ddot') {
|
||
|
||
$ftpObect->writeContentToTemp($cvar . ':' . $value . "\r\n");
|
||
|
||
} else {
|
||
$debug[] = 'Type is: ' . $values['type'] . ' and key value: ' . $cvar . '=>' . $value;
|
||
}
|
||
}
|
||
}
|
||
|
||
$ftpObect->uploadFileFromTemp($path, $fileName, false);
|
||
}
|
||
}
|
||
|
||
$ftpObect->logOut();
|
||
}
|
||
}
|
||
|
||
// If EAC is available and active the server.cfg needs to be retrieved and EAC setup
|
||
private function easyAntiCheatSettings ($action = 'start') {
|
||
|
||
global $resellerLockupID;
|
||
|
||
if ($this->appServerDetails['eacAllowed'] == 'Y') {
|
||
|
||
$gameType = $this->getGameType();
|
||
|
||
// On app start we only run commands for supported games
|
||
if ($action == 'start' and in_array($this->appServerDetails['app']['anticheat'], array(3, 4, 5, 6)) and ($gameType == 'hl1' or $gameType == 'hl2')) {
|
||
|
||
if ($gameType == 'hl2') {
|
||
$config = 'cfg/server.cfg';
|
||
} else if ($gameType == 'hl1') {
|
||
$config = 'server.cfg';
|
||
} else {
|
||
$config = 'main/server.cfg';
|
||
}
|
||
|
||
$ftpObect = new EasyWiFTP($this->appMasterServerDetails['ssh2IP'], $this->appMasterServerDetails['ftpPort'], $this->appServerDetails['userNameExecute'], $this->appServerDetails['ftpPasswordExecute']);
|
||
|
||
if ($ftpObect->loggedIn === true) {
|
||
|
||
if (!$ftpObect->downloadToTemp($this->appServerDetails['absoluteFTPPath'] . $config)) {
|
||
$ftpObect->downloadToTemp($this->appServerDetails['absoluteFTPPathNoChroot'] . $config);
|
||
}
|
||
|
||
$configFile = $ftpObect->getTempFileContent();
|
||
|
||
$configFile = str_replace(array("\0","\b","\r","\Z"), '', $configFile);
|
||
$configFile = preg_replace('/\s+/', ' ', $configFile);
|
||
|
||
$lines = explode("\n", $configFile);
|
||
|
||
foreach ($lines as $singeLine) {
|
||
|
||
// Do a rough check if the line is a comment
|
||
if (preg_match("/\w/", substr($singeLine, 0, 1))) {
|
||
|
||
if (preg_match("/\"/", $singeLine)) {
|
||
|
||
$exploded = explode('"', $singeLine);
|
||
$cvar = str_replace(' ', '', $exploded[0]);
|
||
|
||
} else {
|
||
|
||
$exploded = explode(' ', $singeLine);
|
||
$cvar = $exploded[0];
|
||
}
|
||
|
||
if ($cvar == 'rcon_password' and isset($exploded[1])) {
|
||
$rconPassword = $exploded[1];
|
||
}
|
||
}
|
||
}
|
||
|
||
if (isset($rconPassword)) {
|
||
eacchange('change', $this->appServerDetails['template']['id'], $rconPassword, $resellerLockupID);
|
||
}
|
||
}
|
||
|
||
// On app stop we run commands in any case to ensure we remove left overs
|
||
} else if ($action == 'stop') {
|
||
eacchange('remove', $this->appServerDetails['template']['id'], '', $resellerLockupID);
|
||
}
|
||
}
|
||
}
|
||
|
||
private function generateStartCommand () {
|
||
|
||
$gameType = $this->getGameType();
|
||
|
||
// https://github.com/easy-wi/developer/issues/205
|
||
// In case Workshop is on we need to remove mapgroup
|
||
$startCommand = ($this->appServerDetails['app']['workShop'] == 'Y') ? str_replace(array('%mapgroup%', ' +mapgroup'), '', $this->appServerDetails['app']['cmd']) : $this->appServerDetails['app']['cmd'];
|
||
|
||
// In case of hl2 based servers and no TV allowed, turn off the source tv capabilities
|
||
if ($gameType == 'hl2' and $this->appServerDetails['tvAllowed'] == 'N') {
|
||
$startCommand .= ' -nohltv -tvdisable';
|
||
}
|
||
|
||
// If the user decided to use EAC instead of VAC, or turned VAC off on porpuse
|
||
if (($gameType == 'hl1' or $gameType == 'hl2') and ($this->appServerDetails['app']['anticheat'] == 2 or ($this->appServerDetails['app']['anticheat'] > 2 and $this->appServerDetails['eacAllowed'] == 'Y'))) {
|
||
$startCommand .= ' -insecure';
|
||
}
|
||
|
||
// Mod commands are typically used at CS:GO, COD and so and load build in modifications like arms race
|
||
$modCommand = $this->appServerDetails['app']['modcmd'];
|
||
|
||
foreach (explode("\r\n", $this->appServerDetails['template']['modcmds']) as $line) {
|
||
if (preg_match('/^(\[[\w\/\.\-\_\= ]{1,}\])$/', $line)) {
|
||
|
||
$exploded = preg_split("/\=/", trim($line,'[]'), -1, PREG_SPLIT_NO_EMPTY);
|
||
$name = trim($exploded[0]);
|
||
|
||
// This construction appears redundant, but is required as a fallback in case there was an issue in the DB and at least one mod command is required
|
||
if (isset($exploded[1]) and trim($exploded[1]) == 'default' and ($modCommand === null or $modCommand == '')) {
|
||
$modCommand = trim($exploded[0]);
|
||
}
|
||
|
||
if (!isset($modsCmds[$name])) {
|
||
$modsCmds[$name] = array();
|
||
}
|
||
|
||
} else if (isset($name) and isset ($modsCmds[$name]) and $line != '') {
|
||
$modsCmds[$name][] = $line;
|
||
}
|
||
}
|
||
|
||
if (isset($modsCmds[$modCommand]) and is_array($modsCmds[$modCommand])) {
|
||
foreach ($modsCmds[$modCommand] as $singleModADD) {
|
||
$startCommand .= ' ' . $singleModADD;
|
||
}
|
||
}
|
||
|
||
// Steam Workshop support
|
||
if ($this->appServerDetails['app']['workShop'] == 'Y' and strlen($this->appServerDetails['app']['webApiAuthKey']) > 0 and strlen($this->appServerDetails['app']['workshopCollection']) > 0) {
|
||
if (in_array($this->appServerDetails['template']['shorten'], array('gmod', 'garrysmod'))) {
|
||
$startCommand .= ' -nodefaultmap +host_workshop_collection ' . $this->appServerDetails['app']['workshopCollection'] . ' -authkey ' . $this->appServerDetails['app']['webApiAuthKey'];
|
||
} else {
|
||
$startCommand .= ' -nodefaultmap +host_workshop_collection ' . $this->appServerDetails['app']['workshopCollection'] . ' +workshop_start_map ' . $this->appServerDetails['app']['map'] . ' -authkey ' . $this->appServerDetails['app']['webApiAuthKey'];
|
||
$startCommand = preg_replace('/[\s\s+]{1,}\+map[\s\s+]{1,}[\w-_!%]{1,}/', '', $startCommand);
|
||
}
|
||
}
|
||
|
||
// Steam Server Token Support
|
||
if ($this->appServerDetails['template']['steamGameserverToken'] == 'Y' and strlen($this->appServerDetails['app']['steamServerToken']) > 0) {
|
||
$startCommand .= ' +sv_setsteamaccount ' . $this->appServerDetails['app']['steamServerToken'];
|
||
}
|
||
|
||
if ($this->appServerDetails['lendServer'] == 'Y') {
|
||
|
||
$lendDetails = $this->getLendDetails();
|
||
|
||
if (!is_array($lendDetails)) {
|
||
$startCommand .= $this->getLendDetails();
|
||
}
|
||
}
|
||
|
||
// Add addon commands
|
||
if (isset($this->appServerDetails['extensions']['cmds']) and count($this->appServerDetails['extensions']['cmds']) > 0) {
|
||
$startCommand .= implode('', $this->appServerDetails['extensions']['cmds']);
|
||
}
|
||
|
||
// Remove what needs to be removed according to installed addons
|
||
if (isset($this->appServerDetails['extensions']['removeCmds']) and count($this->appServerDetails['extensions']['removeCmds']) > 0) {
|
||
foreach ($this->appServerDetails['extensions']['removeCmds'] as $removeCommand) {
|
||
$startCommand = str_replace($removeCommand, '', $startCommand);
|
||
}
|
||
}
|
||
|
||
$replaceSettings = $this->getReplacements();
|
||
|
||
$startCommand = str_replace($replaceSettings['placeholder'], $replaceSettings['replacePlaceholderWith'], $startCommand);
|
||
|
||
foreach (customColumns('G', $this->appServerDetails['id']) as $customColumn) {
|
||
$startCommand = str_replace("%${customColumn['name']}%", $customColumn['value'], $startCommand);
|
||
}
|
||
|
||
//If a template is set up for both OS, we might need to alter the start of the command
|
||
if ($this->appMasterServerDetails['os'] == 'W') {
|
||
|
||
if (substr($startCommand, 0, 2) == './') {
|
||
$startCommand = substr($startCommand, 3);
|
||
}
|
||
|
||
if (substr($startCommand, 0, 1) == '.') {
|
||
$startCommand = substr($startCommand, 2);
|
||
}
|
||
|
||
$shellCommand = '';
|
||
|
||
} else {
|
||
$shellCommand = 'if [ "`screen -v | awk \'{split($3, a, "."); print a[2]}\'`" == "05" ]; then' . "\n";
|
||
$shellCommand .= 'SCREENLOG="screenlog.0"' . "\n";
|
||
$shellCommand .= 'fi' . "\n";
|
||
$shellCommand .= ($this->appServerDetails['useTaskSet'] == 'Y' and strlen($this->appServerDetails['cores']) > 0) ? 'taskset -c ' . $this->appServerDetails['cores'] . ' ' : '';
|
||
$shellCommand .= 'screen -A -m -d -L $SCREENLOG -S ' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . ' ' . $startCommand . "\n";
|
||
}
|
||
|
||
return $shellCommand;
|
||
}
|
||
|
||
private function arkCheckSleep () {
|
||
|
||
// Loop used for ARK only. Ensures enough time has elapsed for worl save
|
||
if ($this->appServerDetails['template']['gameBinary'] == 'ShooterGameServer') {
|
||
|
||
// For 30 seconds check every half second if the world save is done and a restart can be performed
|
||
$script = 'I=0' . "\n";
|
||
$script .= 'while [ "`ps fx | grep \'./ShooterGameServer\' | grep -v grep | head -n 1`" != "" -a $I -lt 60 ]; do' . "\n";
|
||
$script .= 'sleep 0.5' . "\n";
|
||
$script .= 'let I=I+1' . "\n";
|
||
$script .= 'done' . "\n";
|
||
|
||
// If a process is still running, kill it hard
|
||
$script .= 'ps fx | grep \'./ShooterGameServer\' | grep -v grep | awk \'{print $1}\' | while read PID; do' . "\n";
|
||
$script .= 'kill $PID' . "\n";
|
||
$script .= 'done' . "\n";
|
||
|
||
return $script;
|
||
}
|
||
|
||
return '';
|
||
}
|
||
|
||
private function linuxStartApp () {
|
||
|
||
$scriptName = $this->removeSlashes('/home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/start-' . $this->appServerDetails['userNameExecute'] . '-' . $this->appServerDetails['serverIP'] . '-' . $this->appServerDetails['port'] . '.sh');
|
||
|
||
$serverDir = $this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName'];
|
||
$serverDir .= ($this->appServerDetails['protectionModeStarted'] == 'Y') ? '/pserver/' : '/server/';
|
||
$serverDir = $this->removeSlashes($serverDir);
|
||
$serverTemplateDir = $this->removeSlashes($serverDir . '/');
|
||
|
||
$script = $this->shellScriptHeader;
|
||
$script .= 'rm -f ' . $scriptName . "\n";
|
||
|
||
$script .= $this->linuxStopApp(false, $scriptName);
|
||
|
||
$script .= '${IONICE}find -L ' . $serverDir . ' -type l -delete' . "\n";
|
||
|
||
if ($this->appServerDetails['protectionModeStarted'] == 'Y') {
|
||
|
||
$script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type d -print0 | xargs -0 chmod 750' . "\n";
|
||
|
||
if ($this->appServerDetails['template']['copyStartBinary'] == 'Y' and strlen($this->appServerDetails['template']['gameBinary']) > 0) {
|
||
$script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "' . $this->appServerDetails['template']['gameBinary'] . '" -print0 | xargs -0 chmod 750' . "\n";
|
||
} else {
|
||
$script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "ShooterGameServer" -print0 | xargs -0 chmod 640' . "\n";
|
||
}
|
||
|
||
} else {
|
||
|
||
$script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type d -print0 | xargs -0 chmod 700' . "\n";
|
||
|
||
if ($this->appServerDetails['template']['copyStartBinary'] == 'Y' and strlen($this->appServerDetails['template']['gameBinary']) > 0) {
|
||
$script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "' . $this->appServerDetails['template']['gameBinary'] . '" -print0 | xargs -0 chmod 700' . "\n";
|
||
} else {
|
||
$script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -type f ! -name "ShooterGameServer" -print0 | xargs -0 chmod 600' . "\n";
|
||
}
|
||
|
||
// Remove files where they do not belong
|
||
$script .= '${IONICE}nice -n +19 find ' . $serverDir . ' -mindepth 1 -maxdepth 1 \( -type f -or -type l \) -delete' . "\n";
|
||
$script .= '${IONICE}nice -n +19 find ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName']) . ' -mindepth 1 -maxdepth 1 \( -type f -or -type l \)';
|
||
$script .= ' ! -name ".profile" ! -name ".bashrc" ! -name ".bash_logout" -delete' . "\n";
|
||
|
||
// Remove folders where they do not belong
|
||
$script .= '${IONICE}nice -n +19 find ' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName']) . ' -mindepth 1 -maxdepth 1 -type d';
|
||
$script .= ' ! -name ".steam" ! -name "pserver" ! -name "backup" ! -name "fdl_data" ! -name "server" -print0 | xargs -0 rm -rf' . "\n";
|
||
|
||
$script .= '${IONICE}nice -n +19 find /home/' . $this->appMasterServerDetails['ssh2User'] . '/fdl_data -type f -user `whoami` ! -name "*.bz2" -delete' . "\n";
|
||
}
|
||
|
||
if ($this->appServerDetails['template']['steamgame'] == 'S') {
|
||
$script .= 'if [ ! -f "' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName'] . '/.steam/sdk32/steamclient.so') . '" ]; then' . "\n";
|
||
$script .= ' mkdir -p "' . $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName'] . '/.steam/sdk32/') . '"' . "\n";
|
||
$script .= ' ln -s "' . $this->removeSlashes('/home/' . $this->appMasterServerDetails['ssh2User'] . '/masterserver//steamCMD/linux32/steamclient.so') . '" "';
|
||
$script .= $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName'] . '/.steam/sdk32/steamclient.so') . '"' . "\n";
|
||
$script .= 'fi' . "\n";
|
||
}
|
||
|
||
if (count($this->appMasterServerDetails['configBinaries']) > 0 or count($this->appMasterServerDetails['configFiles']) > 0 ) {
|
||
|
||
$script .= 'FILESFOUND=(`find ' . $serverDir . ' -type f ';
|
||
|
||
if (count($this->appMasterServerDetails['configBinaries']) > 0) {
|
||
$script .= '\( -iname "*.' . implode('" -or -iname "*.', $this->appMasterServerDetails['configBinaries']) . '" \)';
|
||
}
|
||
|
||
if (count($this->appMasterServerDetails['configFiles']) > 0) {
|
||
$script .= ' -wholename "' . implode('" -o -wholename "', $this->appMasterServerDetails['configFiles']) . '"';
|
||
}
|
||
|
||
$script .= '`)' . "\n";
|
||
|
||
$script .= 'for BADFILE in ${FILESFOUND[@]}; do' . "\n";
|
||
$script .= 'chmod 666 $BADFILE > /dev/null 2>&1' . "\n";
|
||
$script .= 'rm -f $BADFILE > /dev/null 2>&1' . "\n";
|
||
$script .= 'if [ -f $BADFILE ]; then exit 0; fi' . "\n";
|
||
$script .= 'done' . "\n";
|
||
}
|
||
|
||
if ($this->appMasterServerDetails['configBadTime'] > 0 and count($this->appMasterServerDetails['configBadFiles']) > 0) {
|
||
$script .= '${IONICE}find ' . $serverDir . ' -type f \( -iname "*.' . implode('" -or -iname "*.', $this->appMasterServerDetails['configBadFiles']) . '" \) -mtime +' . $this->appMasterServerDetails['configBadTime'] . ' -delete' . "\n";
|
||
}
|
||
|
||
if ($this->appMasterServerDetails['configDemoTime'] > 0) {
|
||
$script .= '${IONICE}find ' . $serverTemplateDir . ' -type f -name "*.dem" -mtime +' . $this->appMasterServerDetails['configDemoTime'] . ' -delete' . "\n";
|
||
}
|
||
|
||
if ($this->appMasterServerDetails['configLogTime'] > 0) {
|
||
$script .= '${IONICE}find ' . $serverTemplateDir . ' -type f -name "*.log" -mtime +' . $this->appMasterServerDetails['configLogTime'] . ' -delete' . "\n";
|
||
}
|
||
|
||
if ($this->appMasterServerDetails['configZtmpTime'] > 0) {
|
||
$script .= '${IONICE}find ' . $serverTemplateDir . ' -type f -name "*.ztmp" -mtime +' . $this->appMasterServerDetails['configZtmpTime'] . ' -delete' . "\n";
|
||
}
|
||
|
||
$script .= 'cd ' . $this->appServerDetails['absolutePath'] . "\n";
|
||
|
||
if (strlen($this->appServerDetails['template']['binarydir']) > 0) {
|
||
$script .= 'BINARY_DIR=`find "' . $this->appServerDetails['template']['binarydir'] . '" -type d | head -n 1`' . "\n";
|
||
$script .= 'if [ "$BINARY_DIR" != "" ]; then cd "$BINARY_DIR"; fi' . "\n";
|
||
}
|
||
|
||
// Loop used for ARK only. Ensures enough time has elapsed for world save
|
||
if ($this->appServerDetails['template']['gameBinary'] == 'ShooterGameServer') {
|
||
|
||
// For 30 seconds check every half second if the world save is done and a restart can be performed
|
||
$script .= 'I=0' . "\n";
|
||
$script .= 'while [ "`ps fx | grep \'./ShooterGameServer\' | grep -v grep | head -n 1 | awk \'{print $5}\' | sed \'s/.\///g\'`" != "ShooterGameServer" -a $I -lt 60 ]; do' . "\n";
|
||
$script .= 'sleep 0.5' . "\n";
|
||
$script .= 'let I=I+1' . "\n";
|
||
$script .= 'done' . "\n";
|
||
|
||
// If a process is still running, kill it hard
|
||
$script .= 'ps fx | grep \'./ShooterGameServer\' | grep -v grep | awk \'{print $1}\' | while read PID; do' . "\n";
|
||
$script .= 'kill $PID' . "\n";
|
||
$script .= 'done' . "\n";
|
||
//
|
||
}
|
||
|
||
$script .= $this->arkCheckSleep();
|
||
|
||
$script .= 'if [ -f screenlog.0 ]; then rm -f screenlog.0; fi' . "\n";
|
||
$script .= $this->generateStartCommand() . "\n";
|
||
|
||
if ($this->getGameType() == 'hl2' and $this->appServerDetails['tvAllowed'] == 'Y' and in_array($this->appServerDetails['app']['upload'], array(4, 5)) and $this->appServerDetails['app']['uploadDir']) {
|
||
$script .= $this->linuxDemoUpload(false);
|
||
}
|
||
|
||
$this->addLinuxScript($scriptName, $script);
|
||
$this->addLogline('app_server.log', 'App ' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . ' owned by user ' . $this->appServerDetails['userNameExecute'] . ' started');
|
||
}
|
||
|
||
public function startApp () {
|
||
|
||
global $sql;
|
||
|
||
if ($this->appServerDetails) {
|
||
|
||
$this->getAddonDetails();
|
||
|
||
$this->correctProtectedFiles();
|
||
|
||
$this->easyAntiCheatSettings();
|
||
|
||
if ($this->appMasterServerDetails['os'] == 'L') {
|
||
|
||
if ($this->appServerDetails['protectionModeStarted'] == 'Y') {
|
||
$this->linuxHardStop($this->appServerDetails['userName']);
|
||
} else if ($this->appServerDetails['protectionModeAllowed'] == 'Y' and $this->appServerDetails['protectionModeStarted'] == 'N') {
|
||
$this->linuxHardStop($this->appServerDetails['userName'] . '-p');
|
||
}
|
||
|
||
$this->linuxAddApp(array($this->appServerDetails['app']['templateChoosen']));
|
||
$this->linuxAddAddons();
|
||
|
||
$this->linuxStartApp();
|
||
|
||
} else if ($this->appMasterServerDetails['os'] == 'W') {
|
||
}
|
||
|
||
$query = $sql->prepare("UPDATE `gsswitch` SET `stopped`='N' WHERE `id`=? LIMIT 1");
|
||
$query->execute(array($this->appServerDetails['id']));
|
||
}
|
||
}
|
||
|
||
private function linuxDemoUpload ($standalone = true) {
|
||
|
||
$scriptName = $this->removeSlashes('/home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/demo-' . $this->appServerDetails['userNameExecute'] . '-' . $this->appServerDetails['serverIP'] . '-' . $this->appServerDetails['port'] . '.sh');
|
||
|
||
if ($standalone == true) {
|
||
$script = $this->shellScriptHeader;
|
||
$script .= 'rm -f ' . $scriptName . "\n";
|
||
} else {
|
||
$script = '';
|
||
}
|
||
|
||
if (in_array($this->appServerDetails['app']['upload'], array(3, 5))) {
|
||
$script .= 'KEEP="-k"' . "\n";
|
||
}
|
||
|
||
// This if cases have to be run on the root as the PHP script does not know what is installed there
|
||
$script .= 'LSOF=`which lsof`' . "\n";
|
||
$script .= 'if [ "$LSOF" == "" ]; then KEEP="-k"; fi' . "\n";
|
||
$script .= 'cd ' . $this->appServerDetails['absolutePath'] . "\n";
|
||
|
||
$uploadScript = 'if [[ `which zip` ]]; then' . "\n";
|
||
$uploadScript .= 'if [ "$KEEP" == "" ]; then KEEP="-m"; fi' . "\n";
|
||
$uploadScript .= '${IONICE}nice -n +19 zip -q $KEEP $DEMOPATH/$DEMO.zip $DEMOPATH/$DEMO' . "\n";
|
||
$uploadScript .= 'ZIP="zip"' . "\n";
|
||
$uploadScript .= 'elif [[ `which bzip2` ]]; then' . "\n";
|
||
$uploadScript .= '${IONICE}nice -n +19 bzip2 -s -q -9 $KEEP $DEMOPATH/$DEMO' . "\n";
|
||
$uploadScript .= 'ZIP="bz2"' . "\n";
|
||
$uploadScript .= 'fi' . "\n";
|
||
$uploadScript .= 'DEMOANDPATH="$DEMOPATH/$DEMO.$ZIP"' . "\n";
|
||
$uploadScript .= 'wput -q --limit-rate=1024K --remove-source-files --tries 3 --basename="${DEMOPATH/\/\///}" "${DEMOANDPATH/\/\///}" "' . $this->appServerDetails['app']['uploadDir'] . '"' . "\n";
|
||
|
||
// 2 and 3 are one time run (manuel mode)
|
||
if (in_array($this->appServerDetails['app']['upload'], array(2, 3))) {
|
||
$script .= 'cd `find -mindepth 1 -maxdepth 3 -type d -name "' . $this->appServerDetails['template']['modfolder'] . '" | head -n1`' . "\n";
|
||
$script .= 'find . -maxdepth 2 -type f -name "*.dem" | while read LINE; do' . "\n";
|
||
$script .= 'DEMOPATH="`dirname $LINE`/"' . "\n";
|
||
$script .= 'DEMO="`basename $LINE`"' . "\n";
|
||
$script .= 'if [ "$LSOF" != "" ]; then ' . "\n";
|
||
$script .= 'if [[ ! `lsof $LINE` ]]; then' . "\n";
|
||
$script .= $uploadScript;
|
||
$script .= 'fi' . "\n";
|
||
$script .= 'else' . "\n";
|
||
$script .= $uploadScript;
|
||
$script .= 'fi' . "\n";
|
||
$script .= 'done' . "\n";
|
||
|
||
// 4 and 5 is continuous run with a tail of the screenlog
|
||
} else if (in_array($this->appServerDetails['app']['upload'], array(4, 5))) {
|
||
|
||
$script .= 'DEMOPATH=`find -mindepth 1 -maxdepth 3 -type d -name "' . $this->appServerDetails['template']['modfolder'] . '" | head -n1`' . "\n";
|
||
$script .= 'SCREENLOG="`find ' . $this->appServerDetails['absolutePath'] . ' -name "screenlog.0" | head -n1`"' . "\n";
|
||
$script .= 'if [ "$SCREENLOG" != "" ]; then' . "\n";
|
||
$script .= 'cd `dirname $SCREENLOG`' . "\n";
|
||
$script .= 'tail -f screenlog.0 | while read LINE; do' . "\n";
|
||
|
||
$script .= 'if [[ `echo $LINE | grep -E "Completed (SourceTV|GOTV)"` ]]; then' . "\n";
|
||
$script .= 'DEMO=`echo -n "$LINE" | awk \'{print $4}\' | tr -d \'"\' | tr -d \',\'`' . "\n";
|
||
|
||
$script .= 'if [ "$LSOF" != "" ]; then ' . "\n";
|
||
$script .= 'if [[ ! `lsof $DEMOPATH/$DEMO` ]]; then' . "\n";
|
||
$script .= $uploadScript;
|
||
$script .= 'fi' . "\n";
|
||
$script .= 'else' . "\n";
|
||
$script .= $uploadScript;
|
||
$script .= 'fi' . "\n";
|
||
$script .= 'fi' . "\n";
|
||
$script .= 'done' . "\n";
|
||
$script .= 'fi' . "\n";
|
||
}
|
||
|
||
if (in_array($this->appServerDetails['app']['upload'], array(2, 3, 4, 5))) {
|
||
|
||
// The demo listener needs to be started in a separate screen
|
||
if (in_array($this->appServerDetails['app']['upload'], array(4, 5))) {
|
||
|
||
$this->addLinuxScript($scriptName, $script, $this->appServerDetails['userNameExecute'], true);
|
||
|
||
$screenScriptName = $this->removeSlashes('/home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/demo-start-' . $this->appServerDetails['userNameExecute'] . '-' . $this->appServerDetails['serverIP'] . '-' . $this->appServerDetails['port'] . '.sh');
|
||
|
||
$script = $this->shellScriptHeader;
|
||
$script .= 'rm -f ' . $screenScriptName . "\n";
|
||
|
||
// Kill any screen that is running with the same name
|
||
$script .= 'ps fx | grep \'SCREEN\' | grep \'demo_' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . '\' | grep -v grep | awk \'{print $1}\' | while read PID; do' . "\n";
|
||
$script .= 'kill $PID > /dev/null 2>&1' . "\n";
|
||
$script .= 'kill -9 $PID > /dev/null 2>&1' . "\n";
|
||
$script .= 'done' . "\n";
|
||
|
||
$script .= 'screen -d -m -S demo_' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . ' ' . $scriptName . "\n";
|
||
|
||
// Rename for the function return
|
||
$scriptName = $screenScriptName;
|
||
}
|
||
|
||
$this->addLogline('app_server.log', 'Demo upload started for ' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . ' owned by user ' . $this->appServerDetails['userNameExecute']);
|
||
|
||
if ($standalone == true) {
|
||
$this->addLinuxScript($scriptName, $script);
|
||
}
|
||
|
||
return $script;
|
||
}
|
||
|
||
return '';
|
||
}
|
||
|
||
public function demoUpload () {
|
||
if ($this->appServerDetails and $this->appServerDetails['app']['uploadDir'] and $this->appMasterServerDetails['os'] == 'L') {
|
||
$this->linuxDemoUpload();
|
||
} else if ($this->appServerDetails and $this->appMasterServerDetails['os'] == 'W') {
|
||
}
|
||
}
|
||
|
||
private function linuxAddonShellGeneric ($type, $name, $action, $folders = '') {
|
||
|
||
$masterAddonFolder = '/home/' . $this->appMasterServerDetails['ssh2User'] . '/';
|
||
$masterAddonFolder .= ($type == 'addon') ? 'masteraddons/' : 'mastermaps/';
|
||
$masterAddonFolder .= $name . '/';
|
||
|
||
if (strlen($this->appServerDetails['template']['modfolder']) == 0) {
|
||
$script = 'GAMEDIR="' . $this->appServerDetails['absolutePath'] . '"' . "\n";
|
||
} else {
|
||
$script = 'if [ "`find ' . $this->appServerDetails['absolutePath'] . ' -mindepth 1 -maxdepth 3 -type d -name ' . $this->appServerDetails['template']['modfolder'] . ' | wc -l`" == "1" ]; then' . "\n";
|
||
$script .= 'GAMEDIR=`find ' . $this->appServerDetails['absolutePath'] . ' -mindepth 1 -maxdepth 3 -type d -name "' . $this->appServerDetails['template']['modfolder'] . '" | head -n 1`' . "\n";
|
||
$script .= 'else' . "\n";
|
||
$script .= 'GAMEDIR=`find ' . $this->appServerDetails['absolutePath'] . ' -mindepth 1 -maxdepth 1 -type d -name "' . $this->appServerDetails['template']['modfolder'] . '" | head -n 1`' . "\n";
|
||
$script .= 'fi' . "\n";
|
||
}
|
||
|
||
$script .= 'if [ -d "' . $masterAddonFolder . '" -a "$GAMEDIR" != "" ]; then' . "\n";
|
||
|
||
$script .= 'cd ' . $masterAddonFolder . "\n";
|
||
|
||
if ($action == 'add') {
|
||
$script .= $this->linuxAddAddonShellCommands($type, $masterAddonFolder);
|
||
} else {
|
||
$script .= $this->linuxRemoveAddonShellCommands($folders);
|
||
}
|
||
|
||
$script .= 'fi' . "\n";
|
||
|
||
return $script;
|
||
}
|
||
|
||
private function linuxAddAddonShellCommands ($type, $masterAddonFolder) {
|
||
|
||
$script = '';
|
||
|
||
$script .= 'cp -sr ' . $masterAddonFolder . '* $GAMEDIR/ > /dev/null 2>&1' . "\n";
|
||
|
||
if ($type == 'addon') {
|
||
$script .= 'find -type f | grep -i -E -w \'(xml|cfg|con|conf|config|gam|ini|txt|vdf|smx|sp|ext|sma|amxx|lang|lua|json|yml)$\' | sed \'s/\.\///g\' | while read FILE; do' . "\n";
|
||
$script .= 'FOLDER=`dirname $FILE`' . "\n";
|
||
$script .= 'FILENAME=`basename $FILE`' . "\n";
|
||
$script .= 'if [ ! -d $GAMEDIR/$FOLDER ]; then mkdir -p $GAMEDIR/$FOLDER/; fi' . "\n";
|
||
$script .= 'find $GAMEDIR/$FILE -type l -delete > /dev/null 2>&1' . "\n";
|
||
$script .= 'if [ "$FILENAME" == "liblist.gam" ]; then' . "\n";
|
||
$script .= 'mv $GAMEDIR/$FILE $GAMEDIR/$FILE.old' . "\n";
|
||
$script .= 'cp ' . $masterAddonFolder . '$FILE $GAMEDIR/$FILE' . "\n";
|
||
$script .= 'elif [ "$FILENAME" == "plugins.ini" ]; then' . "\n";
|
||
$script .= 'if [ -f $GAMEDIR/$FILE ]; then' . "\n";
|
||
$script .= 'cat ' . $masterAddonFolder . '$FILE | while read $LINE; do' . "\n";
|
||
$script .= 'if [ `grep "$LINE" $GAMEDIR/$FILE` == "" ]; then echo $LINE >> $GAMEDIR/$FILE; fi' . "\n";
|
||
$script .= 'done' . "\n";
|
||
$script .= 'else' . "\n";
|
||
$script .= 'cp ' . $masterAddonFolder . '$FILE $GAMEDIR/$FILE' . "\n";
|
||
$script .= 'fi' . "\n";
|
||
$script .= 'elif [ "$FILENAME" == "gametypes.txt" ]; then' . "\n";
|
||
$script .= 'if [ "$FOLDER" != "cfg/mani_admin_plugin" ]; then cp ' . $masterAddonFolder . '$FILE $GAMEDIR/$FILE; fi' . "\n";
|
||
$script .= 'elif [ ! -f $GAMEDIR/$FILE -a ! -f "$GAMEDIR/$FOLDER/disabled/$FILENAME" ]; then' . "\n";
|
||
$script .= 'cp ' . $masterAddonFolder . '$FILE $GAMEDIR/$FILE' . "\n";
|
||
$script .= 'fi' . "\n";
|
||
$script .= 'done' . "\n";
|
||
}
|
||
|
||
return $script;
|
||
}
|
||
|
||
private function linuxAddAddons ($id = false) {
|
||
|
||
$scriptName = $this->removeSlashes('/home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/addons-add-' . $this->appServerDetails['userNameExecute'] . '-' . $this->appServerDetails['serverIP'] . '-' . $this->appServerDetails['port'] . '.sh');
|
||
|
||
$script = $this->shellScriptHeader;
|
||
$script .= 'rm -f ' . $scriptName . "\n";
|
||
|
||
if ($id === false) {
|
||
|
||
$logLine = '';
|
||
|
||
if (isset($this->appServerDetails['extensions']['addons']) and count($this->appServerDetails['extensions']['addons']) > 0) {
|
||
|
||
foreach ($this->appServerDetails['extensions']['addons'] as $id => $addon) {
|
||
|
||
// A possible scenario is that the addon has been installed while unprotected and the mode switched later on
|
||
// In such a case we need to ensure that the addon is not installed on restart
|
||
if ($this->appServerDetails['protectionModeStarted'] == 'N' or ($this->appServerDetails['protectionModeStarted'] == 'Y' and $this->appServerDetails['extensions']['addonSettings'][$id]['protectedAllowed'] == 'Y')) {
|
||
$script .= $this->linuxAddonShellGeneric('addon', $addon, 'add');
|
||
}
|
||
}
|
||
|
||
$logLine .= 'added addon(s) ' . implode(',', $this->appServerDetails['extensions']['addons']);
|
||
}
|
||
|
||
if (isset($this->appServerDetails['extensions']['maps']) and count($this->appServerDetails['extensions']['maps']) > 0) {
|
||
|
||
foreach ($this->appServerDetails['extensions']['maps'] as $addon) {
|
||
$script .= $this->linuxAddonShellGeneric('map', $addon, 'add');
|
||
}
|
||
|
||
$logLine .= ' added map(s) ' . implode(',', $this->appServerDetails['extensions']['maps']);
|
||
}
|
||
|
||
|
||
} else if (isset($this->appServerDetails['extensions']['addons'][$id])) {
|
||
|
||
$script .= $this->linuxAddonShellGeneric('addon', $this->appServerDetails['extensions']['addons'][$id], 'add');
|
||
|
||
$logLine = 'Added addon ' . $this->appServerDetails['extensions']['addons'][$id];
|
||
|
||
} else if (isset($this->appServerDetails['extensions']['maps'][$id])) {
|
||
|
||
$script .= $this->linuxAddonShellGeneric('map', $this->appServerDetails['extensions']['maps'][$id], 'add');
|
||
|
||
$logLine = 'Added map ' . $this->appServerDetails['extensions']['maps'][$id];
|
||
|
||
}
|
||
|
||
if (isset($logLine) and strlen($logLine) > 0) {
|
||
$this->addLinuxScript($scriptName, $script);
|
||
$this->addLogline('app_server.log', $logLine . ' to app ' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . ' owned by user ' . $this->appServerDetails['userNameExecute']);
|
||
}
|
||
}
|
||
|
||
public function addAddon ($id = false) {
|
||
if ($this->appServerDetails and $this->appMasterServerDetails['os'] == 'L') {
|
||
$this->linuxAddAddons($id);
|
||
} else if ($this->appServerDetails and $this->appMasterServerDetails['os'] == 'W') {
|
||
}
|
||
}
|
||
|
||
private function getDependentAddonsQuery($id) {
|
||
|
||
global $sql;
|
||
|
||
$array = array();
|
||
|
||
$query = $sql->prepare("SELECT a.`id`,a.`addon` FROM `addons` AS a INNER JOIN `addons_installed` AS i ON i.`addonid`=a.`id` AND i.`serverid`=? AND i.`servertemplate`=? WHERE a.`depending`=?");
|
||
$query->execute(array($this->appServerDetails['app']['id'], $this->appServerDetails['app']['servertemplate'], $id));
|
||
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
|
||
$array[] = $row['id'];
|
||
}
|
||
|
||
return $array;
|
||
}
|
||
|
||
private function getDependentAddons ($id) {
|
||
|
||
$addonIDs = $this->getDependentAddonsQuery($id);
|
||
|
||
if (count($addonIDs) > 0) {
|
||
|
||
foreach ($addonIDs as $addonID) {
|
||
foreach($this->getDependentAddons($addonID) as $dependentAddonID) {
|
||
$addonIDs[] = $dependentAddonID;
|
||
}
|
||
}
|
||
}
|
||
|
||
return $addonIDs;
|
||
}
|
||
|
||
private function linuxRemoveAddonShellCommands ($folders) {
|
||
|
||
$script = 'find -mindepth 1 -type f | sed \'s/\.\///g\' | while read FILES; do' . "\n";
|
||
$script .= 'if [ "`basename $FILES`" == "liblist.gam" ]; then' . "\n";
|
||
$script .= 'mv $GAMEDIR/$FILES.old $GAMEDIR/$FILES' . "\n";
|
||
$script .= 'elif [ "`basename $FILES`" == "plugins.ini" ]; then' . "\n";
|
||
|
||
$script .= 'if [ -f /home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/$USER.pluginlist.temp ]; then rm -f /home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/$USER.pluginlist.temp; fi' . "\n";
|
||
|
||
$script .= 'cat $GAMEDIR/$FILES | while read LINE; do' . "\n";
|
||
$script .= 'if [[ `grep "$LINE" $FILES` == "" ]]; then echo "$LINE" >> /home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/$USER.pluginlist.temp; fi' . "\n";
|
||
$script .= 'done' . "\n";
|
||
$script .= 'cp /home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/$USER.pluginlist.temp $GAMEDIR/$FILES' . "\n";
|
||
$script .= 'rm -f /home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/$USER.pluginlist.temp' . "\n";
|
||
$script .= 'else' . "\n";
|
||
$script .= 'rm -rf "$GAMEDIR/$FILES" > /dev/null 2>&1' . "\n";
|
||
$script .= 'if [ "$FILES" == "liblist.gam" ]; then mv $GAMEDIR/$FILES.old $GAMEDIR/$FILES > /dev/null 2>&1; fi' . "\n";
|
||
$script .= 'fi' . "\n";
|
||
$script .= 'done' . "\n";
|
||
$script .= 'cd $GAMEDIR' . "\n";
|
||
$script .= 'find -mindepth 1 -type d -empty -delete' . "\n";
|
||
|
||
// Check for to be removed folders
|
||
if (count($folders) > 0) {
|
||
$script .= 'find -mindepth 1 \( -iname "' . implode('" -or -iname "', $folders) . '"\) -print0 | xargs -0 rm -rf' . "\n";
|
||
}
|
||
|
||
return $script;
|
||
}
|
||
|
||
private function linuxRemoveAddons ($ids) {
|
||
|
||
$names = array();
|
||
|
||
$scriptName = $this->removeSlashes('/home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/addons-del-' . $this->appServerDetails['userNameExecute'] . '-' . $this->appServerDetails['serverIP'] . '-' . $this->appServerDetails['port'] . '.sh');
|
||
|
||
$script = $this->shellScriptHeader;
|
||
$script .= 'rm -f ' . $scriptName . "\n";
|
||
$script .= 'USER=`id -un`' . "\n";
|
||
|
||
foreach ($ids as $id) {
|
||
|
||
$folders = (isset($this->appServerDetails['extensions']['addonSettings'][$id]['folder'])) ? preg_split('/(\s+|,)/', $this->appServerDetails['extensions']['addonSettings'][$id]['folder'], -1, PREG_SPLIT_NO_EMPTY) : array();
|
||
|
||
if (isset($this->appServerDetails['extensions']['addons'][$id])) {
|
||
|
||
$names[] = $this->appServerDetails['extensions']['addons'][$id];
|
||
|
||
$script .= $this->linuxAddonShellGeneric('addon', $this->appServerDetails['extensions']['addons'][$id], 'del', $folders);
|
||
|
||
} else if (isset($this->appServerDetails['extensions']['maps'][$id])) {
|
||
|
||
$names[] = $this->appServerDetails['extensions']['maps'][$id];
|
||
|
||
$script .= $this->linuxAddonShellGeneric('map', $this->appServerDetails['extensions']['maps'][$id], 'del', $folders);
|
||
}
|
||
}
|
||
|
||
if (count($names) > 0) {
|
||
$this->addLinuxScript($scriptName, $script);
|
||
$this->addLogline('app_server.log', 'Removed addon(s)/map(s) ' . implode(',', $names) . ' from app ' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . ' owned by user ' . $this->appServerDetails['userNameExecute']);
|
||
}
|
||
}
|
||
|
||
public function removeAddon ($id) {
|
||
|
||
global $sql;
|
||
|
||
if ($this->appServerDetails) {
|
||
|
||
$toBeRemovedAddonIDs = array($id);
|
||
|
||
foreach ($this->getDependentAddons($id) as $addonID) {
|
||
$toBeRemovedAddonIDs[] = $addonID;
|
||
}
|
||
|
||
if ($this->appMasterServerDetails['os'] == 'L') {
|
||
$this->linuxRemoveAddons($toBeRemovedAddonIDs);
|
||
} else if ($this->appMasterServerDetails['os'] == 'W') {
|
||
}
|
||
|
||
$query = $sql->prepare("DELETE FROM `addons_installed` WHERE `addonid`=? AND `serverid`=? AND `servertemplate`=? LIMIT 1");
|
||
foreach ($toBeRemovedAddonIDs as $addonID) {
|
||
$query->execute(array($addonID, $this->appServerDetails['app']['id'], $this->appServerDetails['app']['servertemplate']));
|
||
}
|
||
}
|
||
}
|
||
|
||
private function linuxMigrateServer ($sourceFTP, $targetTemplate, $modFolder) {
|
||
|
||
$serverDir = $this->removeSlashes($this->appServerDetails['homeDir'] . '/' . $this->appServerDetails['userName'] . '/server/' . '/' . $targetTemplate . '/');
|
||
|
||
$scriptName = $this->removeSlashes('/home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/migrate-' . $this->appServerDetails['userName'] . '-' . $this->appServerDetails['serverIP'] . '-' . $this->appServerDetails['port'] . '.sh');
|
||
|
||
$script = $this->shellScriptHeader;
|
||
$script .= 'rm -f ' . $scriptName . "\n";
|
||
$script .= 'if [ -d "' . $serverDir . '" ]; then ${IONICE}rm -rf "' . $serverDir . '"; fi' . "\n";
|
||
|
||
$script .= $this->linuxAddApp(array($targetTemplate), false);
|
||
|
||
$script .= 'if [ ! -d "' . $serverDir . '" ]; then mkdir -p "' . $serverDir . '"; fi' . "\n";
|
||
$script .= 'cd ' . $serverDir . "\n";
|
||
|
||
if (strlen($modFolder) > 0) {
|
||
$script .= 'MODFOLDER=`find -mindepth 1 -maxdepth 3 -type d -name "' . $modFolder . '" | head -n 1`' . "\n";
|
||
$script .= 'if [ "$MODFOLDER" != "" ]; then cd $MODFOLDER; fi' . "\n";
|
||
}
|
||
|
||
$cutDirs = count(preg_split('/\//', $sourceFTP['path'], -1, PREG_SPLIT_NO_EMPTY));
|
||
|
||
if ($cutDirs < 0) {
|
||
$cutDirs = 0;
|
||
}
|
||
|
||
$script .= 'find -type f -print0 | xargs -0 rm -f' . "\n";
|
||
$script .= 'wget -q -r -l inf -nc -nH --limit-rate=4096K --retr-symlinks --no-check-certificate --ftp-user=' . $sourceFTP['user'] . ' --ftp-password=' . $sourceFTP['password'] . ' --cut-dirs=' . $cutDirs . ' ' . $sourceFTP['connectString'] . "\n";
|
||
|
||
$script .= $this->linuxAddApp(array($targetTemplate), false);
|
||
|
||
$this->addLinuxScript($scriptName, $script);
|
||
$this->addLogline('app_server.log', 'Migrated server to ' . $targetTemplate . ' belonging to app ' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . ' owned by user ' . $this->appServerDetails['userName']);
|
||
}
|
||
|
||
public function migrateToEasyWi ($sourceFTP, $targetTemplate, $modFolder) {
|
||
if ($this->appServerDetails and $this->appMasterServerDetails['os'] == 'L') {
|
||
$this->linuxMigrateServer($sourceFTP, $targetTemplate, $modFolder);
|
||
} else if ($this->appServerDetails and $this->appMasterServerDetails['os'] == 'W') {
|
||
}
|
||
}
|
||
|
||
private function linuxFastDLSync ($fdlConnectString) {
|
||
|
||
$gameType = $this->getGameType();
|
||
|
||
if (in_array($gameType, array('hl1', 'hl2', 'cod'))) {
|
||
|
||
$fdlFileList = $this->removeSlashes('/home/' . $this->appMasterServerDetails['ssh2User'] . '/conf/fdl-' . $this->appServerDetails['template']['shorten'] . '.list');
|
||
|
||
$scriptName = $this->removeSlashes('/home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/fdl-sync-' . $this->appServerDetails['userName'] . '-' . $this->appServerDetails['serverIP'] . '-' . $this->appServerDetails['port'] . '.sh');
|
||
|
||
$script = $this->shellScriptHeader;
|
||
$script .= 'rm -f ' . $scriptName . "\n";
|
||
$script .= 'USERNAME=`id -un`' . "\n";
|
||
|
||
$script .= 'if [ -f "' . $fdlFileList . '" ]; then' . "\n";
|
||
$script .= 'cd ' . $this->appServerDetails['absolutePath'] . "\n";
|
||
|
||
$excludePattern = '\.log\|\.txt\|\.cfg\|\.vdf\|\.db\|\.dat\|\.ztmp\|\.blib\|log\/\|logs\/\|downloads\/\|DownloadLists\/\|metamod\/\|amxmodx\/\|hl\/\|hl2\/\|cfg\/\|addons\/\|bin\/\|classes/';
|
||
|
||
if ($gameType == 'hl2') {
|
||
|
||
$fdlMasterFolder = $this->removeSlashes('/home/' . $this->appMasterServerDetails['ssh2User'] . '/fdl_data/hl2/' . $this->appServerDetails['template']['shorten'] . '/');
|
||
|
||
$script .= 'if [ ! -d "' . $fdlMasterFolder . '" ]; then mkdir -p "' . $fdlMasterFolder . '"; fi' . "\n";
|
||
$script .= 'find "' . $fdlMasterFolder . '" -maxdepth 1 -type d -user `whoami` -exec chmod 770 {} \;' . "\n";
|
||
|
||
$logFile = $this->removeSlashes('/home/' . $this->appMasterServerDetails['ssh2User'] . '/logs/fdl-hl2.log');
|
||
|
||
if (strlen($this->appServerDetails['template']['binarydir']) > 0) {
|
||
$script .= 'cd ' . $this->appServerDetails['template']['binarydir'] . "\n";
|
||
}
|
||
|
||
if ($this->appServerDetails['template']['gameq'] == 'l4d2') {
|
||
$script .= 'cd left4dead2/left4dead2/' . "\n";
|
||
} else if (strlen($this->appServerDetails['template']['modfolder']) > 0) {
|
||
$script .= 'cd ' . $this->appServerDetails['template']['modfolder'] . '/' . "\n";
|
||
}
|
||
|
||
$script .= 'ABSOLUTEGAMEPATH=`readlink -f .`' . "\n";
|
||
|
||
$script .= 'find particles/ maps/ materials/ resource/ models/ sound/ -type l -or -type f 2> /dev/null | grep -v "' . $excludePattern . '" | while read FOUNDFILE; do' . "\n";
|
||
|
||
} else if ($gameType == 'hl1') {
|
||
|
||
$logFile = $this->removeSlashes('/home/' . $this->appMasterServerDetails['ssh2User'] . '/logs/fdl-hl1.log');
|
||
|
||
$script .= 'cd ' . $this->appServerDetails['template']['modfolder'] . '/' . "\n";
|
||
|
||
$script .= 'find . -type l -or -type f 2> /dev/null | grep -v "' . $excludePattern . '" | while read FOUNDFILE; do' . "\n";
|
||
|
||
} else {
|
||
|
||
$logFile = $this->removeSlashes('/home/' . $this->appMasterServerDetails['ssh2User'] . '/logs/fdl-cod.log');
|
||
|
||
$script .= 'find usermaps/ mods/ -type l -or -type f \( -iname "*.ff" -or -iname "*.iwd" \) 2> /dev/null | grep -v "' . $excludePattern . '" | while read FOUNDFILE; do' . "\n";
|
||
}
|
||
|
||
$script .= 'FILTEREDFILE=${FOUNDFILE//\.\//}' . "\n";
|
||
$script .= 'if [[ ! `grep "$FILTEREDFILE" "' . $fdlFileList . '"` ]]; then' . "\n";
|
||
$script .= 'FILENAME=`basename $FILTEREDFILE`' . "\n";
|
||
|
||
if ($gameType == 'hl2' and isset($fdlMasterFolder)) {
|
||
|
||
$script .= 'cd ' . $fdlMasterFolder . "\n";
|
||
$script .= 'ABSOLUTEFILTEREDFILE="$ABSOLUTEGAMEPATH/$FILTEREDFILE"' . "\n";
|
||
$script .= 'FDLDATADIR=' . $fdlMasterFolder . '`dirname "$FILTEREDFILE"`' . "\n";
|
||
$script .= 'if [ ! -d $FDLDATADIR ]; then mkdir -p $FDLDATADIR; chmod 770 $FDLDATADIR; fi' . "\n";
|
||
$script .= 'FDLDATAFILENAME="$FDLDATADIR/$FILENAME"' . "\n";
|
||
$script .= 'CHECKSUMNEW=`${IONICE}nice -n +19 md5sum "$ABSOLUTEFILTEREDFILE" | awk \'{print $1}\'`' . "\n";
|
||
$script .= 'if [ -f "$FDLDATAFILENAME.stat" -a -f "$FDLDATAFILENAME.bz2" ]; then' . "\n";
|
||
$script .= 'CHECKSUMOLD=`head -n 1 "$FDLDATAFILENAME.stat" 2> /dev/null`' . "\n";
|
||
$script .= 'else' . "\n";
|
||
$script .= 'CHECKSUMOLD=""' . "\n";
|
||
$script .= 'fi' . "\n";
|
||
$script .= 'if [ "$CHECKSUMOLD" != "$CHECKSUMNEW" ]; then' . "\n";
|
||
$script .= '${IONICE}nice -n +19 bzip2 -k -s -q -9 -f -c "$ABSOLUTEFILTEREDFILE" > "$FDLDATAFILENAME.bz2"' . "\n";
|
||
$script .= 'echo $CHECKSUMNEW > "$FDLDATAFILENAME.stat"' . "\n";
|
||
$script .= 'chmod 660 "$FDLDATAFILENAME.stat" "$FDLDATAFILENAME.bz2"' . "\n";
|
||
$script .= 'fi' . "\n";
|
||
$script .= 'if [ "$CHECKSUMOLD" != "$CHECKSUMNEW" -a "$CHECKSUMOLD" != "" ]; then' . "\n";
|
||
$script .= 'wput -q --reupload --limit-rate=1024K "$FILTEREDFILE.bz2" ' . $fdlConnectString . "\n";
|
||
$script .= 'echo "`date`: $USERNAME: ' . $this->appServerDetails['app']['templateChoosen'] . ' file $FILENAME compressed and uploaded" >> ' . $logFile . "\n";
|
||
$script .= 'else' . "\n";
|
||
$script .= 'wput -q --dont-continue --limit-rate=1024K "$FILTEREDFILE.bz2" ' . $fdlConnectString . "\n";
|
||
$script .= 'echo "`date`: $USERNAME: ' . $this->appServerDetails['app']['templateChoosen'] . ' file $FILENAME uploaded" >> ' . $logFile . "\n";
|
||
$script .= 'fi' . "\n";
|
||
|
||
} else {
|
||
$script .= 'if [ "`wput -q -nv --limit-rate=1024K "$FILTEREDFILE" ' . $fdlConnectString . ' | grep \"Skipping file\"`" != "" ]; then' . "\n";
|
||
$script .= 'wput -qN --limit-rate=1024K "$FILTEREDFILE" ' . $fdlConnectString . "\n";
|
||
$script .= 'echo "`date`: $USERNAME: ' . $this->appServerDetails['app']['templateChoosen'] . ' file $FILENAME checked" >> ' . $logFile . "\n";
|
||
$script .= 'else' . "\n";
|
||
$script .= 'echo "`date`: $USERNAME: ' . $this->appServerDetails['app']['templateChoosen'] . ' file $FILENAME uploaded" >> ' . $logFile . "\n";
|
||
$script .= 'fi' . "\n";
|
||
}
|
||
|
||
$script .= 'fi' . "\n";
|
||
$script .= 'done' . "\n";
|
||
|
||
if ($gameType == 'hl2' and isset($fdlMasterFolder)) {
|
||
$script .= 'find "' . $fdlMasterFolder . '" -type d -user $USERNAME -exec chmod 770 {} \;' . "\n";
|
||
$script .= 'find "' . $fdlMasterFolder . '" -type f -user $USERNAME -exec chmod 660 {} \;' . "\n";
|
||
}
|
||
|
||
$script .= 'fi' . "\n";
|
||
|
||
$this->addLinuxScript($scriptName, $script);
|
||
$this->addLogline('fdl.log', 'FDL sync started for app on server ' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . ' owned by user ' . $this->appServerDetails['userName']);
|
||
}
|
||
}
|
||
|
||
public function fastDLSync ($fdlConnectString) {
|
||
|
||
if (strlen($fdlConnectString) > 0) {
|
||
|
||
if (substr($fdlConnectString, -1, 1) != '/') {
|
||
$fdlConnectString .= '/';
|
||
}
|
||
|
||
$fdlConnectString .= $this->appServerDetails['template']['shorten'] . '/';
|
||
|
||
if ($this->appServerDetails and $this->appMasterServerDetails['os'] == 'L') {
|
||
$this->linuxFastDLSync($fdlConnectString);
|
||
} else if ($this->appServerDetails and $this->appMasterServerDetails['os'] == 'W') {
|
||
}
|
||
}
|
||
}
|
||
|
||
private function linuxBackupCreate ($ftpUploadString) {
|
||
|
||
global $resellerLockupID;
|
||
|
||
$backupDir = $this->removeSlashes($this->appServerDetails['homeDir'] .'/' . $this->appServerDetails['userName'] . '/backup/');
|
||
$backUpFile = $this->removeSlashes($backupDir . '/' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . '-$GAMETEMPLATE.tar.bz2');
|
||
$serverDir = $this->removeSlashes($this->appServerDetails['homeDir'] .'/' . $this->appServerDetails['userName'] . '/server/');
|
||
|
||
$scriptName = $this->removeSlashes('/home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/backup-create-' . $this->appServerDetails['userName'] . '-' . $this->appServerDetails['serverIP'] . '-' . $this->appServerDetails['port'] . '.sh');
|
||
|
||
$script = $this->shellScriptHeader;
|
||
$script .= 'rm -f ' . $scriptName . "\n";
|
||
|
||
$script .= 'if [ ! -d "' . $backupDir . '" ]; then mkdir -p "' . $backupDir . '"; fi' . "\n";
|
||
$script .= 'find "' . $serverDir . '" -mindepth 1 -maxdepth 1 -type d | while read FOLDER; do' . "\n";
|
||
$script .= 'GAMETEMPLATE=`basename $FOLDER`' . "\n";
|
||
$script .= 'if [[ `lsof -f -- "' . $backUpFile . '" 2>/dev/null` ]]; then continue; fi' . "\n";
|
||
$script .= 'if [ -f "' . $backUpFile . '" ]; then rm -f "' . $backUpFile . '"; fi' . "\n";
|
||
$script .= 'cd "' . $serverDir . '/$GAMETEMPLATE"' . "\n";
|
||
$script .= '${IONICE}nice -n +19 tar cfj "' . $backUpFile . '" .' . "\n";
|
||
|
||
if (strlen($ftpUploadString) > 0) {
|
||
$script .= 'wput -q --limit-rate=4098 --basename="' . $backupDir . '" "' . $backUpFile . '" "' . $ftpUploadString . '"' . "\n";
|
||
}
|
||
|
||
$script .= 'done' . "\n";
|
||
$script .= 'wget -q --timeout=60 --no-check-certificate -O - ' . webhostdomain($resellerLockupID) . '/get_password.php?w=bu\\&shorten=`id -un`\\id=' . $this->appServerDetails['port'] . '\\&ip=' . $this->appServerDetails['serverIP'] . "\n";
|
||
|
||
$this->addLinuxScript($scriptName, $script);
|
||
$this->addLogline('app_server.log', 'Created backup for apps on server ' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . ' owned by user ' . $this->appServerDetails['userName']);
|
||
}
|
||
|
||
public function backupCreate ($ftpUploadString) {
|
||
if ($this->appServerDetails and $this->appMasterServerDetails['os'] == 'L') {
|
||
$this->linuxBackupCreate($ftpUploadString);
|
||
} else if ($this->appServerDetails and $this->appMasterServerDetails['os'] == 'W') {
|
||
}
|
||
}
|
||
|
||
private function linuxBackupDeploy ($template, $ftpDownloadString) {
|
||
|
||
global $resellerLockupID;
|
||
|
||
$backupDir = $this->removeSlashes($this->appServerDetails['homeDir'] . $this->appServerDetails['userName'] . '/backup/');
|
||
$serverDir = $this->removeSlashes($this->appServerDetails['homeDir'] . $this->appServerDetails['userName'] . '/server/');
|
||
|
||
$scriptName = $this->removeSlashes('/home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/backup-deploy-' . $this->appServerDetails['userName'] . '-' . $this->appServerDetails['serverIP'] . '-' . $this->appServerDetails['port'] . '.sh');
|
||
|
||
$script = $this->shellScriptHeader;
|
||
$script .= 'rm -f ' . $scriptName . "\n";
|
||
|
||
if (strlen($ftpDownloadString) > 0) {
|
||
$script .= 'if [ ! -d "' . $backupDir . '" ]; then mkdir -p "' . $backupDir . '"; fi' . "\n";
|
||
$script .= 'cd ' . $backupDir . "\n";
|
||
$script .= 'mv "' . $this->removeSlashes($backupDir . '/' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . '-' . $template . '.tar.bz2') . '" "' . $this->removeSlashes($backupDir . '/' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . '-' . $template . '_old.tar.bz2"') . "\n";
|
||
$script .= 'wget -q --timeout=10 --no-check-certificate ' . $ftpDownloadString . '/' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . '-' . $template . '.tar.bz2' . "\n";
|
||
$script .= 'if [ -f "' . $this->removeSlashes($backupDir . '/' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . '-' . $template . '.tar.bz2') . '" ]; then' . "\n";
|
||
$script .= 'rm -f "' . $this->removeSlashes($backupDir . '/' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . '-' . $template . '_old.tar.bz2"') . "\n";
|
||
$script .= 'else' . "\n";
|
||
$script .= 'mv "' . $this->removeSlashes($backupDir . '/' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . '-' . $template . '_old.tar.bz2') . '" "' . $this->removeSlashes($backupDir . '/' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . '-' . $template . '.tar.bz2"') . "\n";
|
||
$script .= 'fi' . "\n";
|
||
}
|
||
|
||
$script .= 'if [ -f "' . $this->removeSlashes($backupDir . '/' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . '-' . $template . '.tar.bz2') . '" ]; then' . "\n";
|
||
$script .= 'rm -rf ' . $this->removeSlashes($serverDir . '/' . $template . '/*') . "\n";
|
||
|
||
$script .= 'fi' . "\n";
|
||
|
||
$script .= 'if [ ! -d "' . $this->removeSlashes($serverDir . '/' . $template) . '" ]; then mkdir -p "' . $this->removeSlashes($serverDir . '/' . $template) . '"; fi' . "\n";
|
||
|
||
$script .= '${IONICE}nice -n +19 tar -C "' . $this->removeSlashes($serverDir . '/' . $template) . '" -xjf "' . $this->removeSlashes($backupDir . '/' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . '-' . $template . '.tar.bz2"') . "\n";
|
||
$script .= 'wget -q --no-check-certificate -O - ' . webhostdomain($resellerLockupID) . '/get_password.php?w=rb\\&shorten=`id -un`\\id=' . $this->appServerDetails['port'] . '\\&ip=' . $this->appServerDetails['serverIP'] . "\n";
|
||
|
||
$this->addLinuxScript($scriptName, $script);
|
||
$this->addLogline('app_server.log', 'Deployed backup for app template ' . $template . ' on server ' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . ' owned by user ' . $this->appServerDetails['userName']);
|
||
}
|
||
|
||
public function backupDeploy ($template, $ftpDownloadString) {
|
||
if ($this->appServerDetails and $this->appMasterServerDetails['os'] == 'L') {
|
||
$this->linuxBackupDeploy($template, $ftpDownloadString);
|
||
} else if ($this->appServerDetails and $this->appMasterServerDetails['os'] == 'W') {
|
||
}
|
||
}
|
||
|
||
private function shellCommandLinux($command) {
|
||
|
||
$scriptName = $this->removeSlashes('/home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/execute-cmd-' . $this->appServerDetails['userNameExecute'] . '-' . $this->appServerDetails['serverIP'] . '-' . $this->appServerDetails['port'] . '.sh');
|
||
$screenName = $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'];
|
||
|
||
$script = $this->shellScriptHeader;
|
||
$script .= 'rm -f ' . $scriptName . "\n";
|
||
|
||
$script .= 'screen -S ' . $screenName . ' -X stuff $\'' . $command . '\n\'';
|
||
|
||
$this->addLinuxScript($scriptName, $script);
|
||
|
||
$this->addLogline('app_server.log', 'App console command' . $this->appServerDetails['serverIP'] . '_' . $this->appServerDetails['port'] . ' owned by user ' . $this->appServerDetails['userNameExecute'] . ' executed');
|
||
|
||
return true;
|
||
}
|
||
|
||
public function shellCommand($command) {
|
||
|
||
// Linux and Windows deamon are reached via SSH2.
|
||
|
||
if ($this->appMasterServerDetails['os'] == 'L') {
|
||
return $this->shellCommandLinux($command);
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
private function getKeyAndOrPassword () {
|
||
|
||
if ($this->appMasterServerDetails['ssh2Publickey'] != 'N' and file_exists($this->appMasterServerDetails['privateKey'])) {
|
||
|
||
$ssh2Pass = new phpseclib\Crypt\RSA();
|
||
|
||
if ($this->appMasterServerDetails['ssh2Publickey'] == 'B') {
|
||
$ssh2Pass->setPassword($this->appMasterServerDetails['ssh2DecryptedPass']);
|
||
}
|
||
|
||
$ssh2Pass->loadKey(file_get_contents($this->appMasterServerDetails['privateKey']));
|
||
|
||
} else {
|
||
$ssh2Pass = $this->appMasterServerDetails['ssh2DecryptedPass'];
|
||
}
|
||
|
||
return $ssh2Pass;
|
||
}
|
||
|
||
private function handleFailedConnectAttemps () {
|
||
|
||
global $sql, $resellerLockupID, $rSA;
|
||
|
||
$query = $sql->prepare("UPDATE `rserverdata` SET `notified`=`notified`+1 WHERE `id`=? LIMIT 1");
|
||
$query->execute(array($this->appMasterServerDetails['id']));
|
||
|
||
// While we keep on counting up, the mail is send only once to prevent spam
|
||
if (($this->appMasterServerDetails['notified'] + 1) == $rSA['down_checks']) {
|
||
$query = ($resellerLockupID == 0) ? $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE `resellerid`=0 AND `accounttype`='a'") : $sql->prepare("SELECT `id`,`mail_serverdown` FROM `userdata` WHERE (`id`=${$resellerLockupID} AND `id`=`resellerid`) OR `resellerid`=0 AND `accounttype`='a'");
|
||
$query->execute();
|
||
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
|
||
if ($row['mail_serverdown'] == 'Y') {
|
||
sendmail('emaildown', $row['id'], $this->appMasterServerDetails['ssh2IP'], '');
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private function executeLinux () {
|
||
|
||
if (strlen($this->shellScripts['user']) > 0 or count($this->shellScripts['server']) > 0) {
|
||
|
||
$sftpObject = new phpseclib\Net\SFTP($this->appMasterServerDetails['ssh2IP'], $this->appMasterServerDetails['ssh2Port']);
|
||
|
||
$ssh2Pass = $this->getKeyAndOrPassword();
|
||
|
||
$loginReturn = $sftpObject->login($this->appMasterServerDetails['ssh2User'], $ssh2Pass);
|
||
|
||
if ($loginReturn) {
|
||
|
||
$this->commandReturns[] = $sftpObject->put('/home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/userCud-' . $this->uniqueHex . '.sh', $this->shellScripts['user']);
|
||
$this->commandReturns[] = $sftpObject->chmod(0700, '/home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/userCud-' . $this->uniqueHex . '.sh');
|
||
|
||
foreach($this->shellScripts['server'] as $fileName => $scriptContent) {
|
||
$this->commandReturns[] = 'script added: ' . $fileName;
|
||
$this->commandReturns[] = $sftpObject->put($fileName, $scriptContent);
|
||
}
|
||
|
||
// Files have been created, now login with SSH2 and execute the gobal script
|
||
$sshObject = new phpseclib\Net\SSH2($this->appMasterServerDetails['ssh2IP'], $this->appMasterServerDetails['ssh2Port']);
|
||
|
||
if ($sshObject->login($this->appMasterServerDetails['ssh2User'], $ssh2Pass)) {
|
||
$this->commandReturns[] = $sshObject->exec('/home/' . $this->appMasterServerDetails['ssh2User'] . '/temp/userCud-' . $this->uniqueHex . '.sh & ');
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
$this->handleFailedConnectAttemps();
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
public function execute () {
|
||
|
||
// Linux and Windows deamon are reached via SSH2.
|
||
|
||
if ($this->appMasterServerDetails['os'] == 'L') {
|
||
return $this->executeLinux();
|
||
// create the script in server array
|
||
// run the user script which than will execute the other scripts
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
public function debug() {
|
||
|
||
if ($this->appMasterServerDetails['os'] == 'L') {
|
||
return array($this->shellScripts['user'], implode("\r\n", $this->shellScripts['server']), implode("\r\n", $this->commandReturns));
|
||
}
|
||
|
||
if ($this->appMasterServerDetails['os'] == 'W') {
|
||
return array(implode("\r\n", $this->winCmds), implode("\r\n", $this->commandReturns));
|
||
}
|
||
|
||
return array();
|
||
}
|
||
|
||
function __destruct() {
|
||
|
||
}
|
||
}
|