DieFeM 8 anni fa
parent
commit
e19b6e073b
5 ha cambiato i file con 2078 aggiunte e 270 eliminazioni
  1. 355 0
      includes/api_functions.php
  2. 50 0
      includes/database_mysqli.php
  3. 1 0
      modules/user_admin/edit_user.php
  4. 1616 270
      ogp_api.php
  5. 56 0
      test_api.php

+ 355 - 0
includes/api_functions.php

@@ -0,0 +1,355 @@
+<?php
+function get_function_args($main_request)
+{
+	//______________ Token
+	$functions["token/test"] = array("token" => true);
+	$functions["token/create"] = array("user" => true, "password" => true);
+	
+	//______________ Remote Servers
+	$functions["server/list"] = array("token" => true);
+	$functions["server/status"] = array("token" => true, "remote_server_id" => true);
+	$functions["server/restart"] = array("token" => true, "remote_server_id" => true);
+	$functions["server/create"] = array("token" => true, "agent_name" => true, "agent_ip" => true, "agent_port" => true, "agent_user" => true, "encryption_key" => true, "ftp_ip" => true, "ftp_port" => true, "timeout" => true, "use_nat" => true, "display_public_ip" => true);
+	$functions["server/remove"] = array("token" => true, "remote_server_id" => true);
+	$functions["server/add_ip"] = array("token" => true, "remote_server_id" => true, "ip" => true);
+	$functions["server/remove_ip"] = array("token" => true, "remote_server_id" => true, "ip" => true);
+	$functions["server/list_ips"] = array("token" => true, "remote_server_id" => true);
+	$functions["server/edit_ip"] = array("token" => true, "remote_server_id" => true, "old_ip" => true, "new_ip" => true);
+
+	//______________ Game Servers
+	$functions["user_games/list_games"] = array("token" => true,"system" => true,"architecture" => true);
+	$functions["user_games/list_servers"] = array("token" => true);
+	$functions["user_games/create"] = array("token" => true, "remote_server_id" => true, "server_name" => true, "home_cfg_id" => true, "mod_cfg_id" => true, "ip" => true, "port" => true, "control_password" => true, "enable_ftp" => true, "ftp_password" => true, "slots" => true, "affinity" => true, "nice" => true);
+	$functions["user_games/clone"] = array("token" => true, "origin_home_id" => true, "new_server_name" => true, "new_ip" => true, "new_port" => true, "control_password" => true, "enable_ftp" => true, "ftp_password" => true, "slots" => true, "affinity" => true, "nice" => true);
+	$functions["user_games/set_expiration"] = array("token" => true, "home_id" => true, "timestamp" => true);
+
+	//______________ Users
+	$functions["user_admin/list"] = array("token" => true);
+	$functions["user_admin/get"] = array("token" => true, "email" => true);
+	$functions["user_admin/create"] = array("token" => true, "name" => true, "password" => true, "email" => true);
+	$functions["user_admin/remove"] = array("token" => true, "email" => true);
+	$functions["user_admin/set_expiration"] = array("token" => true, "email" => true, "timestamp" => true);
+	$functions["user_admin/list_assigned"] = array("token" => true, "email" => true);
+	$functions["user_admin/assign"] = array("token" => true, "home_id" => true, "email" => true, "timestamp" => true);
+	$functions["user_admin/remove_assign"] = array("token" => true, "home_id" => true, "email" => true);
+
+	//______________ Game Manager
+	$functions["gamemanager/start"] = array("token" => true, "ip" => true, "port" => true, "mod_key" => false);
+	$functions["gamemanager/stop"] = array("token" => true, "ip" => true, "port" => true, "mod_key" => false);
+	$functions["gamemanager/restart"] = array("token" => true, "ip" => true, "port" => true, "mod_key" => false);
+	$functions["gamemanager/rcon"] = array("token" => true, "ip" => true, "port" => true, "mod_key" => false, "command" => true);
+	$functions["gamemanager/update"] = array("token" => true, "ip" => true, "port" => true, "mod_key" => false, "type" => true, "manual_url" => false);
+
+	//______________ Lite File Manager
+	$functions["litefm/list"] = array("token" => true, "ip" => true, "port" => true, "relative_path" => true);
+	$functions["litefm/get"] = array("token" => true, "ip" => true, "port" => true, "relative_path" => true);
+	$functions["litefm/save"] = array("token" => true, "ip" => true, "port" => true, "relative_path" => true, "contents" => true);
+	$functions["litefm/remove"] = array("token" => true, "ip" => true, "port" => true, "relative_path" => true);
+
+	//______________ Addons Manager
+	$functions["addonsmanager/list"] = array("token" => true, "ip" => true, "port" => true);
+	$functions["addonsmanager/install"] = array("token" => true, "ip" => true, "port" => true, "addon_id" => true);
+
+	//______________ Steam Workshop
+	$functions["steam_workshop/install"] = array("token" => true, "ip" => true, "port" => true, "mod_key" => false, "mods_list" => true);
+	if($main_request == "all")
+		return $functions;
+	return isset($functions["$main_request"])?$functions["$main_request"]:false;
+}
+
+function get_query_port($server_xml, $server_port)
+{
+	if( $server_xml->query_port and $server_xml->query_port['type'] == "add" )
+		return $server_port + $server_xml->query_port;
+	return $server_port;
+}
+
+function get_start_cmd($user_info,$remote,$server_xml,$home_info,$mod_id,$ip,$port,$db)
+{	
+	$last_param = json_decode($home_info['last_param'], True);
+	
+	$os = $remote->what_os();
+	
+	$isAdmin = false;
+	if(hasValue($user_info) && hasValue($user_info['user_id'])){
+		$isAdmin = $db->isAdmin($user_info['user_id']);
+	}
+	
+	$cli_param_data['GAME_TYPE'] = $home_info['mods'][$mod_id]['mod_key'];
+	$cli_param_data['IP'] = $ip;
+	$cli_param_data['PORT'] = $port;
+	$cli_param_data['HOSTNAME'] = $home_info['home_name'];
+	$cli_param_data['PID_FILE'] = "ogp_game_startup.pid";
+	
+	// Linux
+	if( preg_match("/Linux/", $os) )
+	{
+		if(preg_match("/_win(32|64)?$/", $home_info['game_key']))
+		{
+			$home_path_wine = $remote->exec("winepath -w ".$home_info['home_path']);
+			$home_path_wine = str_replace("\\","\\\\", $home_path_wine);
+			$home_path_wine = trim($home_path_wine);
+			$cli_param_data['BASE_PATH'] = $home_path_wine;
+			$cli_param_data['HOME_PATH'] = $home_path_wine;
+			$cli_param_data['SAVE_PATH'] = $home_path_wine;
+			$cli_param_data['OUTPUT_PATH'] = $home_path_wine;
+			$cli_param_data['USER_PATH'] = $home_path_wine;
+		}
+		else
+		{
+			$cli_param_data['BASE_PATH'] = $home_info['home_path'];
+			$cli_param_data['HOME_PATH'] = $home_info['home_path'];
+			$cli_param_data['SAVE_PATH'] = $home_info['home_path'];
+			$cli_param_data['OUTPUT_PATH'] = $home_info['home_path'];
+			$cli_param_data['USER_PATH'] = $home_info['home_path'];
+		}
+	}
+	// Windows
+	elseif( preg_match("/CYGWIN/", $os) )
+	{
+		$home_path_win = $remote->exec("cygpath -w ".$home_info['home_path']);
+		$home_path_win = str_replace("\\","\\\\", $home_path_win);
+		$home_path_win = trim($home_path_win);
+		$cli_param_data['BASE_PATH'] = $home_path_win;
+		$cli_param_data['HOME_PATH'] = $home_path_win;
+		$cli_param_data['SAVE_PATH'] = $home_path_win;
+		$cli_param_data['OUTPUT_PATH'] = $home_path_win;
+		$cli_param_data['USER_PATH'] = $home_path_win;
+	}
+	
+	if ($server_xml->protocol == "gameq")
+	{
+		$cli_param_data['QUERY_PORT'] = get_query_port($server_xml, $port);
+	}
+	elseif ($server_xml->protocol == "lgsl")
+	{
+		require('protocol/lgsl/lgsl_protocol.php');
+		$get_ports = lgsl_port_conversion((string)$server_xml->lgsl_query_name, $port, "", "");
+		$cli_param_data['QUERY_PORT'] = $get_ports['1'];
+	}
+	elseif ($server_xml->protocol == "teamspeak3")
+	{
+		$cli_param_data['QUERY_PORT'] = $port + 24;
+	}
+	
+	$cli_param_data['MAP'] = ($last_param === NULL or !isset($last_param['map'])) ?  "" : $last_param['map'];
+	$cli_param_data['PLAYERS'] = ($last_param === NULL or !isset($last_param['players'])) ? 
+								 isset($home_info['mods'][$mod_id]['max_players']) ? 
+								 $home_info['mods'][$mod_id]['max_players'] : "1" : $last_param['players'];
+	$cli_param_data['CONTROL_PASSWORD'] = $home_info['control_password'];
+	
+	$start_cmd = "";
+	// If the template is empty then these are not needed.
+	if ( $server_xml->cli_template )
+	{
+		$start_cmd = $server_xml->cli_template;
+		if ( $server_xml->cli_params )
+		{
+			foreach ( $server_xml->cli_params->cli_param as $cli )
+			{
+				// If s is found the param is seperated with space
+				$add_space = preg_match( "/s/", $cli['options'] ) > 0 ? " " : "";
+				$cli_value = $cli_param_data[(string) $cli['id'] ];
+				// If q is found we add quotes around the value.
+				if ( preg_match( "/q/", $cli['options'] ) > 0 )
+				{
+					$cli_value = "\"".$cli_value."\"";
+				}
+				$start_cmd = preg_replace( "/%".$cli['id']."%/",
+					$cli['cli_string'].$add_space.$cli_value, $start_cmd );
+			}
+		}
+		
+		if ( $server_xml->reserve_ports )
+		{
+			foreach ( $server_xml->reserve_ports->port as $reserve_port )
+			{
+				// If s is found the param is seperated with space
+				$add_space = preg_match( "/s/", $reserve_port['options'] ) > 0 ? " " : "";
+				$cli_value = $reserve_port['type'] == "add" ? $port + (string) $reserve_port:
+															  $port - (string) $reserve_port;
+				// If q is found we add quotes around the value.
+				if ( preg_match( "/q/", $reserve_port['options'] ) > 0 )
+				{
+					$cli_value = "\"".$cli_value."\"";
+				}
+				$start_cmd = preg_replace( "/%".$reserve_port['id']."%/",
+					$reserve_port['cli_string'].$add_space.$cli_value, $start_cmd );
+			}
+		}
+	}
+
+	if ( $isAdmin )
+	{
+		$home_info['access_rights'] = "ufpet";
+	}
+						
+	$param_access_enabled = preg_match("/p/",$home_info['access_rights']) > 0 ? TRUE : FALSE; 
+	
+	if ($param_access_enabled && $last_param !== NULL and isset($server_xml->server_params->param) )
+	{
+		foreach($server_xml->server_params->param as $param)
+		{						
+			foreach ($last_param as $paramKey => $paramValue)
+			{
+				if (!isset($paramValue))
+					$paramValue = (string)$param->default;
+				
+				if ($param['key'] == $paramKey)
+				{	
+					if (0 == strlen($paramValue))
+						continue;
+					if ($param['key'] == $paramValue) // it's a checkbox
+						$new_param = $paramKey;
+					elseif($param->option == "ns" or $param->options == "ns")
+						$new_param = $paramKey.clean_server_param_value($paramValue, $server_xml->cli_allow_chars);
+					elseif($param->option == "q" or $param->options == "q")
+						$new_param = $paramKey . '"' . clean_server_param_value($paramValue, $server_xml->cli_allow_chars) . '"';
+					elseif($param->option == "s" or $param->options == "s")
+						$new_param = $paramKey . ' ' . clean_server_param_value($paramValue, $server_xml->cli_allow_chars);
+					else
+						$new_param = $paramKey . ' "' . clean_server_param_value($paramValue, $server_xml->cli_allow_chars) . '"';
+				  
+					if ($param['id'] == NULL || $param['id'] == "")
+						$start_cmd .= ' '.$new_param;
+					else
+						$start_cmd = preg_replace( "/%".$param['id']."%/", $new_param, $start_cmd );
+				}			  
+			}
+			
+			if ($param['id'] != NULL && $param['id'] != ""){
+				$start_cmd = preg_replace( "/%".$param['id']."%/", '', $start_cmd );
+			}
+		} 
+	}
+	
+	$extra_param_access_enabled = preg_match("/e/",$home_info['access_rights']) > 0 ? TRUE:FALSE;
+			
+	if ( array_key_exists('extra', $last_param) && $extra_param_access_enabled )
+		$extra_default = $last_param['extra'];
+	else
+		$extra_default = $home_info['mods'][$mod_id]['extra_params'];
+		
+	$start_cmd .= " ".str_replace("\\\\", "\\", clean_server_param_value($extra_default, $server_xml->cli_allow_chars));
+
+	return $start_cmd;
+}
+
+function send_rcon_command($command, $remote, $server_xml, $home_info, $home_id, $ip, $port)
+{
+	if( $server_xml->gameq_query_name and $server_xml->gameq_query_name == "minecraft" )
+	{
+		require_once("modules/gamemanager/MinecraftRcon.class.php");
+		$server_properties_file = clean_path($home_info['home_path']."/server.properties");
+		$retval = $remote->remote_readfile($server_properties_file, $data);
+		if($retval == 1 and strpos($data, 'rcon.port') !== FALSE)
+		{
+			$server_properties = parse_ini_string($data);
+			$rcon_port = $server_properties['rcon.port'];
+		}
+		else
+		{
+			$rcon_port = $port+10;
+		}
+		$rcon = new MinecraftRcon;
+		if( $rcon->Connect($ip, $rcon_port, $home_info['control_password']) )
+		{
+			$return = $rcon->Command($command);
+			if($return)
+				return $return;
+			else
+				return FALSE;
+			$rcon->Disconnect();
+		}
+		else
+			return FALSE;
+	}
+	elseif( $server_xml->lgsl_query_name and  $server_xml->lgsl_query_name == "7dtd" )
+	{
+		$query_port = $port + 1;
+		$return = $remote->exec('exec 3<>/dev/tcp/'.$ip.'/'. $query_port .' && echo -en "'.$command.'\\nexit\\n" >&3 && cat <&3');
+		if(preg_match("/Connected with 7DTD server/",$return))	
+			return $return;
+		else
+			return FALSE;
+	}
+	else
+	{
+		$remote_retval = $remote->remote_send_rcon_command( $home_id, $ip, $port, $server_xml->control_protocol, $home_info['control_password'],$server_xml->control_protocol_type,$command,$return);
+		if ( $remote_retval === 1 )
+			return $return;
+		elseif ( $remote_retval === -10 )
+			return FALSE;
+		else
+			return FALSE;
+	}
+}
+
+function test_rsync_response($address)
+{
+	$starttime = microtime(true);
+	$fp = fsockopen($address, 873, $errno, $errstr, 3);
+	$stoptime  = microtime(true);
+	if (!$fp) {
+		return FALSE;
+	}
+	else
+	{
+		$out = "Connection: Close\r\n\r\n";
+		fwrite($fp, $out);
+		$response = "";
+		while (!feof($fp)) {
+			$response .= fgets($fp, 128);
+		}
+		fclose($fp);
+		if(strstr($response,"@RSYNCD"))
+		{
+			$response_time = ($stoptime - $starttime);
+			return $response_time;
+		}
+		else
+			return FALSE;
+	}
+}
+
+function get_faster_rsync($rsync_sites)
+{
+	$faster = "NONE";
+	foreach($rsync_sites as $site)
+	{
+		list($url,$name) = explode('|', $site);
+		$current_time = test_rsync_response($url);
+		if($response_time !== FALSE)
+		{
+			if(!isset($previous_time))
+				$faster = $url;
+			if($previous_time > $current_time)
+				$faster = $url;
+			$previous_time = $current_time;
+		}
+	}
+	
+	if($faster == "NONE")
+		$faster = "rsync.opengamepanel.org";
+	return $faster;
+}
+
+function get_download_filename($url)
+{
+	if(empty($url) or !filter_var($url, FILTER_VALIDATE_URL))
+		return FALSE;
+	$headers = get_headers($url, 1);
+	if($headers['Server'] == 'cloudflare')
+		return basename($url);
+	if(isset($headers[0]) and preg_match('/200|302/', $headers[0]))
+	{
+		if(isset($headers['Content-Disposition']))
+		{
+			list($type, $filename) = explode('filename=',$headers['Content-Disposition']);
+		}
+	}
+	else
+		$filename = basename($url);
+	return trim($filename);
+}
+?>

+ 50 - 0
includes/database_mysqli.php

@@ -3729,6 +3729,56 @@ class OGPDatabaseMySQL extends OGPDatabase
 		$tmp = mysqli_fetch_row($result);
 		$tmp = mysqli_fetch_row($result);
 		return $tmp[0];
 		return $tmp[0];
 	}
 	}
+	
+	public function getApiToken($user_id)
+	{
+		if (is_numeric($user_id) === false)
+			return false;
+		$this->checkApiTable();
+		
+		$user_id = (int)$this->realEscapeSingle($user_id);
+		
+		$query = 'SELECT `token` FROM `%sapi_tokens` WHERE `user_id` = %2$d;';
+		$query = sprintf($query, $this->table_prefix, $user_id);
+		
+		$result = mysqli_query($this->link, $query);
+		++$this->queries_;
+		$tmp = mysqli_fetch_row($result);
+		++$this->queries_;
+		if(empty($tmp))
+		{
+			$token = bin2hex(openssl_random_pseudo_bytes(32));
+			$query ='INSERT INTO %sapi_tokens'.
+					' (user_id, token)'.
+					' VALUES'.
+					' (\'%2$d\', \'%3$s\')'.
+					' ON DUPLICATE KEY UPDATE'.
+					' user_id = VALUES(user_id),'.
+					' token = VALUES(token);';
+			$query = sprintf($query, $this->table_prefix, $user_id, $token);
+			if(!$this->query($query))
+				return false;
+		}
+		else
+		{
+			$token = $tmp[0];
+		}
+		
+		return $token;
+	}
+	
+	public function checkApiTable()
+	{
+		if(!$this->query('SELECT 1 FROM '.$this->table_prefix.'api_tokens LIMIT 1'))
+		{
+			$this->query(	"CREATE TABLE IF NOT EXISTS `".$this->table_prefix.'api_tokens'."` (".
+							"`user_id` int(11) NOT NULL,".
+							"`token` varchar(64) NOT NULL,".
+							"PRIMARY KEY  (`user_id`),".
+							"UNIQUE KEY user_id (user_id)".
+							") ENGINE=MyISAM DEFAULT CHARSET=latin1;");
+		}
+	}
 }
 }
 
 
 ?>
 ?>

+ 1 - 0
modules/user_admin/edit_user.php

@@ -229,6 +229,7 @@ function exec_ogp_module() {
 	$ft->add_field('string','city',$userInfo['users_city']);
 	$ft->add_field('string','city',$userInfo['users_city']);
 	$ft->add_field('string','province',$userInfo['users_province']);
 	$ft->add_field('string','province',$userInfo['users_province']);
 	$ft->add_field('string','country',$userInfo['users_country']);
 	$ft->add_field('string','country',$userInfo['users_country']);
+	$ft->add_field('string','api_token',$db->getApiToken($_SESSION['user_id']), 64, "readonly");
 	if ( $isAdmin && $userInfo['users_role'] != "subuser" ) {
 	if ( $isAdmin && $userInfo['users_role'] != "subuser" ) {
 		$ft->add_custom_field('user_role',
 		$ft->add_custom_field('user_role',
 			create_drop_box_from_array(array('user', 'admin'),"newrole", $userInfo['users_role']));
 			create_drop_box_from_array(array('user', 'admin'),"newrole", $userInfo['users_role']));

+ 1616 - 270
ogp_api.php

@@ -1,319 +1,1665 @@
 <?php
 <?php
 /*
 /*
- *
- * OGP - Open Game Panel
- * Copyright (C) 2008 - 2018 The OGP Development Team
- *
- * http://www.opengamepanel.org/
- *
- * This program 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 2
- * of the License, or any later version.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- */
+______________ Token Management
+api.php?token/create/{panel_user}/{panel_password}
+api.php?token/test/{token}
 
 
-/******************
- * Functions      *
- * ***************/
- 
-function outPutJSON($result){
-	global $action, $db;
-		
-	// Send JSON ouput
+______________ Remote Servers
+api.php?server/list						(POST/GET {token})
+api.php?server/status					(POST/GET {token}{remote_server_id})
+api.php?server/restart					(POST/GET {token}{remote_server_id})
+api.php?server/create 					(POST/GET {token}{agent_name}{agent_ip}{agent_port}{agent_user}{encryption_key}{ftp_ip}{ftp_port}{timeout}{use_nat}{display_public_ip})
+api.php?server/remove 					(POST/GET {token}{remote_server_id})
+api.php?server/add_ip					(POST/GET {token}{remote_server_id}{ip})
+api.php?server/remove_ip				(POST/GET {token}{remote_server_id}{ip})
+api.php?server/list_ips					(POST/GET {token}{remote_server_id})
+api.php?server/edit_ip					(POST/GET {token}{remote_server_id}{old_ip}{new_ip})
+
+______________ Game Servers
+api.php?user_games/list_games			(POST/GET {token}{system(windows|linux)}{architecture(32|64)})
+api.php?user_games/list_servers			(POST/GET {token})
+api.php?user_games/create 				(POST/GET {token}{remote_server_id}{server_name}{home_cfg_id}{mod_cfg_id}{ip}{port}{control_password}{enable_ftp}{ftp_password}{slots}{affinity}{nice})
+api.php?user_games/clone 				(POST/GET {token}{origin_home_id}{new_server_name}{new_ip}{new_port}{control_password}{enable_ftp}{ftp_password}{slots}{affinity}{nice})
+api.php?user_games/set_expiration 		(POST/GET {token}{home_id}{timestamp})
+
+______________ Users
+api.php?user_admin/list 				(POST/GET {token})
+api.php?user_admin/get		 			(POST/GET {token}{email})
+api.php?user_admin/create 				(POST/GET {token}{email}{name}{password})
+api.php?user_admin/remove 				(POST/GET {token}{email})
+api.php?user_admin/set_expiration 		(POST/GET {token}{email}{timestamp})
+api.php?user_admin/list_assigned		(POST/GET {token}{email})
+api.php?user_admin/assign 				(POST/GET {token}{email}{home_id}{timestamp})
+api.php?user_admin/remove_assign 		(POST/GET {token}{email}{home_id})
+
+______________ Game Manager
+api.php?gamemanager/start 				(POST/GET {token}{ip}{port}{mod_key})
+api.php?gamemanager/stop 				(POST/GET {token}{ip}{port}{mod_key})
+api.php?gamemanager/restart 			(POST/GET {token}{ip}{port}{mod_key})
+api.php?gamemanager/rcon 				(POST/GET {token}{ip}{port}{mod_key}{command})
+api.php?gamemanager/update 				(POST/GET {token}{ip}{port}{mod_key}{type}{manual_url})
+
+______________ Lite File Manager
+api.php?litefm/list 					(POST/GET {token}{ip}{port}{relative_path})
+api.php?litefm/get 						(POST/GET {token}{ip}{port}{relative_path})
+api.php?litefm/save 					(POST/GET {token}{ip}{port}{relative_path}{contents})
+api.php?litefm/remove 					(POST/GET {token}{ip}{port}{relative_path})
+
+______________ Addons Manager
+api.php?addonsmanager/list				(POST/GET {token})
+api.php?addonsmanager/install			(POST/GET {token}{ip}{port}{mod_key}{addon_id})
+
+______________ Steam Workshop
+api.php?steam_workshop/install 			(POST/GET {token}{ip}{port}{mods_list})
+
+*/
+$main_request = key($_GET);
+$request = explode('/', $main_request);
+unset($_GET["$main_request"]);
+if(!empty($_GET))
+	$_POST = array_merge($_POST,$_GET);
+//Retirieve the function name
+$function = 'api_'.$request[0];
+//Remove the main function from the request
+array_splice($request, 0, 1);
+
+if(function_exists($function))
+{
+	// Report only critical PHP errors
+	error_reporting(E_ERROR);
+	
+	// Path definitions
+	define("INCLUDES", "includes/");
+	define("MODULES", "modules/");
+	
+	// require needed functions
+	require_once INCLUDES.'functions.php';
+	require_once INCLUDES.'helpers.php';
+	require_once INCLUDES.'html_functions.php';
+	require_once INCLUDES.'lib_remote.php';
+	require_once INCLUDES.'config.inc.php';
+	require_once MODULES.'config_games/server_config_parser.php';
+	require_once INCLUDES.'api_functions.php';
+	
+	// API tokens table
+	define("API_TABLE", $table_prefix."api_tokens");
+	// Connect to the database server and select database.
+	$db = createDatabaseConnection($db_type, $db_host, $db_user, $db_pass, $db_name, $table_prefix);
+	$settings = $db->getSettings();
+	$db->checkApiTable();
+	$logged_in = false;
+	
+	if($function != 'api_token')
+	{
+		if(isset($_POST['token']))
+		{
+			$token = $_POST['token'];
+			$query = "SELECT user_id FROM ".API_TABLE." WHERE `token` = '".$token."';";
+			$result = $db->resultQuery($query);
+			if(isset($result[0]['user_id']))
+			{
+				$user_info = $db->getUserById($result[0]['user_id']);
+				if(isset($user_info['users_login']))
+					$logged_in = true;
+			}
+		}
+		else
+		{
+			outputJSON(array("status" => "300", "message" => "No token supplied"));
+		}
+	}
+	
+	if($logged_in or $function == 'api_token')
+	{
+		//call the function and output the returned data as json
+		$func_req = str_replace('api_','',$function)."/".$request[0];
+		if($main_request == "all")
+			outputJSON(array("status" => "400", "message" => "BAD REQUEST"));
+		else
+			$function_args = get_function_args("$func_req");
+		
+		if(!$function_args)
+			outputJSON(array("status" => "400", "message" => "BAD REQUEST"));
+		elseif(!(($func_req == "token/test" and isset($request[1])) OR ($func_req == "token/create" and isset($request[1]) and isset($request[2]))))
+		{
+			foreach($function_args as $arg => $mandatory)
+			{
+				if($mandatory and !isset($_POST["$arg"]))
+				{
+					outputJSON(array("status" => "400", "message" => "BAD REQUEST", "fields_supplied" => $_POST, "fields_required" => $function_args));
+					break;
+				}
+			}
+		}
+		outputJSON($function());
+	}
+	else
+	{
+		outputJSON(array("status" => "301", "message" => "Invalid Token"));
+	}
+}
+else
+{
+	outputJSON(array("status" => "400", "message" => "BAD REQUEST"));
+}
+
+function outputJSON($result){	
+	// Send JSON output
 	header('Content-Type: application/json');
 	header('Content-Type: application/json');
 	echo json_encode($result);
 	echo json_encode($result);
 	exit();
 	exit();
 }
 }
 
 
-function runRemoteAction($action){
-	global $settings, $db, $remote, $server_xml, $mod_xml, $server_home, $mod_key, $mod_id, $appId, $home_ip_ports, $homeId, $resultOp;
-	
-	// Load XML and server options
-	$installer_name = isset($mod_xml->installer_name) ? $mod_xml->installer_name : $mod_key;
-
-	$modname = $installer_name == '90' ? $mod_key : '';
-	$betaname = isset($mod_xml->betaname) ? $mod_xml->betaname : '';
-	$betapwd = isset($mod_xml->betapwd) ? $mod_xml->betapwd : '';
-	$login = $mod_xml->installer_login ? $mod_xml->installer_login : $settings['steam_user'];
-	$pass = $mod_xml->installer_login ? '' : $settings['steam_pass'];
-	$arch = isset($mod_xml->steam_bitness) ? $mod_xml->steam_bitness : '';
-	$exec_folder_path = $server_xml->exe_location;
-	$exec_path = $server_xml->server_exec_name;
-
-	$precmd = $server_home['mods'][$mod_id]['precmd'] == "" ? ($server_home['mods'][$mod_id]['def_precmd'] == "" ? $server_xml->pre_install : $server_home['mods'][$mod_id]['def_precmd'] ) : $server_home['mods'][$mod_id]['precmd'];
-	$postcmd = $server_home['mods'][$mod_id]['postcmd'] == "" ? ($server_home['mods'][$mod_id]['def_postcmd'] == "" ? $server_xml->post_install : $server_home['mods'][$mod_id]['def_precmd'] ) : $server_home['mods'][$mod_id]['postcmd'];
-	$cfg_os = preg_match('/win32|win64/', $server_xml->game_key) ? 'windows' : 'linux';
-	$lockFiles = !empty($server_xml->lock_files) ? trim($server_xml->lock_files) : '';
-	$preStart = !empty($server_xml->pre_start) ? trim($server_xml->pre_start) : '';
-	$envVars = !empty($server_xml->environment_variables) ? trim($server_xml->environment_variables) : '';
-	$startup_cmd = get_start_cmd($remote, $server_xml, $server_home, $mod_id, $home_ip_ports['ip'], $home_ip_ports['port'], $db);
-	
-	switch($action){
-		case "steam_auto_update":
-	
-			// Make the update call
-			$remoteResult = $remote->automatic_steam_update(
-				//generic
-				$homeId, $server_home['home_path'], $home_ip_ports['ip'], $home_ip_ports['port'], $exec_path, $exec_folder_path,
-									 
-				//stop
-				$server_xml->control_protocol, $server_home['control_password'], $server_xml->control_type,
+function isValidTimeStamp($timestamp)//https://stackoverflow.com/questions/2524680/check-whether-the-string-is-a-unix-timestamp
+{
+    if(is_numeric($timestamp) and strtotime(date('d-m-Y H:i:s',$timestamp)) === (int)$timestamp)
+        return true;
+	return false;
+}
 
 
-				//update
-				$appId, $modname, $betaname, $betapwd, $login, $pass, $settings['steam_guard'], $precmd, $postcmd, $cfg_os, $lockFiles,
-									  
-				//start
-				$startup_cmd, $server_home['mods'][$mod_id]['cpu_affinity'], $server_home['mods'][$mod_id]['nice'], $preStart, $envVars, $server_xml->game_key, $arch
-			);
-			break;
-		case "restart_server":
-			$remoteResult = $remote->remote_restart_server($server_home['home_id'],
-														$home_ip_ports['ip'],
-														$home_ip_ports['port'],
-														$server_xml->control_protocol,
-														$server_home['control_password'],
-														$server_xml->control_protocol_type,
-														$server_home['home_path'],
-														$server_xml->server_exec_name,
-														$server_xml->exe_location,
-														$startup_cmd,
-														$server_home['mods'][$mod_id]['cpu_affinity'],
-														$server_home['mods'][$mod_id]['nice'],
-														$preStart,
-														$envVars,
-														$server_xml->game_key
-														);
-			break;
-		case "stop_server":
-			$remoteResult = $remote->remote_stop_server($server_home['home_id'],
-														$home_ip_ports['ip'],
-														$home_ip_ports['port'],
-														$server_xml->control_protocol,
-														$server_home['control_password'],
-														$server_xml->control_protocol_type,
-														$server_home['home_path']
-														);
-			break;
-		case "start_server":
-			$remoteResult = $remote->universal_start($server_home['home_id'],
-							$server_home['home_path'],
-							$server_xml->server_exec_name, 
-							$server_xml->exe_location,
-							$startup_cmd, 
-							$home_ip_ports['port'], 
-							$home_ip_ports['ip'],
-							$server_home['mods'][$mod_id]['cpu_affinity'],
-							$server_home['mods'][$mod_id]['nice'],
-							$preStart,
-							$envVars,
-							$server_xml->game_key);
-			break;
+function api_token()
+{
+	global $request, $db;
+	if($request[0] == "test")
+	{
+		$token = isset($request[1])?$request[1]:$_POST['token'];
+		$query = "SELECT user_id FROM ".API_TABLE." WHERE `token` = '".$token."';";
+		$result = $db->resultQuery($query);
+		if(isset($result[0]['user_id']))
+		{
+			$user_info = $db->getUserById($result[0]['user_id']);
+			if(isset($user_info['users_login']))
+			{
+				$status = "200";
+				$message = $user_info['users_role'];
+			}
+			else
+			{
+				$status = "400";
+				$message = "Invalid Token";
+			}
+		}
+		else
+		{
+			$status = "400";
+			$message = "Invalid Token";
+		}
+	}
+	
+	if($request[0] == "create")
+	{
+		$user = $token = isset($request[1])?urldecode($request[1]):$_POST['user'];
+		$password = isset($request[2])?urldecode($request[2]):$_POST['password'];
+		
+		$userInfo = $db->getUser($user);
 		
 		
+		if(isset($userInfo['users_passwd']) && md5($password) == $userInfo['users_passwd'])
+		{
+			$token = bin2hex(openssl_random_pseudo_bytes(32));
+			$query ="INSERT INTO ".API_TABLE.
+					" (user_id, token)".
+					" VALUES".
+					" ('".$userInfo['user_id']."', '".$token."')".
+					" ON DUPLICATE KEY UPDATE".
+					" user_id = VALUES(user_id),".
+					" token = VALUES(token);";
+			if($db->query($query))
+			{
+				$status = "200";
+				$message = $token;
+			}
+			else
+			{
+				$status = "500";
+				$message = "database failure";
+			}
+		}
+		else
+		{
+			$status = "400";
+			$message = "Invalid login information";
+		}
 	}
 	}
+	return array("status" => $status, "message" => $message);
+}
 
 
-	if($remoteResult == 1){
-		return true;
-	}else if(hasValue($remoteResult, true)){
-		return $remoteResult;
+function api_server()
+{
+	global $request, $db, $user_info, $settings;
+	
+	if($user_info['users_role'] != "admin")
+		return array("status" => '350', "message" => "This function is restricted to administrator accounts.");
+	
+	if($request[0] == "list")
+	{
+		$status = "200";
+		$message = $db->getRemoteServers();
 	}
 	}
 	
 	
-	return false;
+	if($request[0] == "status")
+	{
+		$remote_server_id = $_POST['remote_server_id'];
+		$remote_server = $db->getRemoteServer($remote_server_id);
+		$remote = new OGPRemoteLibrary($remote_server['agent_ip'],$remote_server['agent_port'],$remote_server['encryption_key'],$remote_server['timeout']);
+		$status = "200";
+		$message = $remote->status_chk() == 1?'online':'offline';
+	}
+	
+	if($request[0] == "restart")
+	{
+		$remote_server_id = $_POST['remote_server_id'];
+		$remote_server = $db->getRemoteServer($remote_server_id);
+		$remote = new OGPRemoteLibrary($remote_server['agent_ip'],$remote_server['agent_port'],$remote_server['encryption_key'],$remote_server['timeout']);
+		$remote->agent_restart();
+		$status = "200";
+		$message = "success";
+	}
+	
+	if($request[0] == "create")
+	{
+		$agent_name = $_POST['agent_name'];
+		$agent_ip = $_POST['agent_ip'];
+		$agent_port = $_POST['agent_port'];
+		$agent_user = $_POST['agent_user'];
+		$encryption_key = $_POST['encryption_key'];
+		$ftp_ip = $_POST['ftp_ip'];
+		$ftp_port = $_POST['ftp_port'];
+		$timeout = $_POST['timeout'];
+		$use_nat = $_POST['use_nat'];
+		$display_public_ip = $_POST['display_public_ip'];
+		
+		$remote_server_id = $db->addRemoteServer($agent_ip,$agent_name,$agent_user,$agent_port,$ftp_ip,$ftp_port,$encryption_key,$timeout,$use_nat,$display_public_ip);
+		
+		$status = "200";
+		$message = $remote_server_id;
+	}
+	
+	if($request[0] == "remove")
+	{
+		$remote_server_id = $_POST['remote_server_id'];
+		$status = "200";
+		$message = $db->removeRemoteServer($remote_server_id);
+	}
+	
+	if($request[0] == "add_ip")
+	{
+		$remote_server_id = $_POST['remote_server_id'];
+		$ip = $_POST['ip'];
+		$status = "200";
+		$message = $db->addRemoteServerIP($remote_server_id, $ip);
+	}
+	
+	if($request[0] == "remove_ip")
+	{
+		$remote_server_id = $_POST['remote_server_id'];
+		$ip = $_POST['ip'];
+		$ip_infos = $db->getRemoteServerIPs($remote_server_id);
+		foreach($ip_infos as $ip_info)
+		{
+			if($ip_info['ip'] == $ip)
+			{
+				$message = $db->removeRemoteServerIPs($ip_info['ip_id']);
+				break;
+			}
+		}
+		$status = "200";
+	}
+	
+	if($request[0] == "list_ips")
+	{
+		$remote_server_id = $_POST['remote_server_id'];
+		$message = $db->getRemoteServerIPs($remote_server_id);
+		$status = "200";
+	}
+	
+	if($request[0] == "edit_ip")
+	{
+		$remote_server_id = $_POST['remote_server_id'];
+		$old_ip = $_POST['old_ip'];
+		$new_ip = $_POST['new_ip'];
+		$ip_infos = $db->getRemoteServerIPs($remote_server_id);
+		foreach($ip_infos as $ip_info)
+		{
+			if($ip_info['ip'] == $old_ip)
+			{
+				$message = $db->editRemoteServerIPs($ip_info['ip_id'], $new_ip);
+				break;
+			}
+		}
+		$status = "200";
+	}
+	
+	return array("status" => $status, "message" => $message);
 }
 }
 
 
-function callSteamAutoUpdate(){
-	global $settings, $db, $remote, $server_xml, $mod_xml, $server_home, $mod_key, $mod_id, $appId, $home_ip_ports, $resultOp;
-	
-	if($server_xml->installer == 'steamcmd') {
-		if($remote->rfile_exists($server_home['home_path'] . '/steamapps/appmanifest_' . $appId . '.acf') === 1){
-			$ourVersion = $remote->installed_steam_version($server_home['home_path'], $appId, 0);
-			$steamVersion = $remote->fetch_steam_version($appId, 0);
-			if($ourVersion != $steamVersion){
-				$success = runRemoteAction("steam_auto_update");
-				if($success == 1){
-					$resultOp["message"] = "Server \"" . $server_home["home_name"] . "\" has been successfully auto-updated via SteamCMD and restarted.";
-					$resultOp["success"] = true;
-				}else if($success == 2){
-					$resultOp["message"] = "Server \"" . $server_home["home_name"] . "\" has been successfully auto-updated via SteamCMD.";
-					$resultOp["success"] = true;
-				}else{
-					if(is_array($success)){
-						$resultOp["message"] = "Server \"" . $server_home["home_name"] . "\" failed to auto-update. Agent returned: " . print_r($success, true);
-					}else{
-						$resultOp["message"] = "Server \"" . $server_home["home_name"] . "\" failed to auto-update. Agent returned error code: " . $success;
-					}
-					$resultOp["success"] = false;
+function api_user_games()
+{
+	global $request, $db, $user_info, $settings;
+	
+	if($user_info['users_role'] != "admin")
+		return array("status" => '350', "message" => "This function is restricted to administrator accounts.");
+		
+	if($request[0] == "list_games")
+	{
+		$system = strtolower($_POST['system']);
+		if(!preg_match('/^(linux|windows)$/', $system))
+		{
+			$status = "302";
+			$message = "list games: Incorrect system, valid options: windows, linux";
+			return array("status" => $status, "message" => $message);
+		}
+		$architecture = strtolower($_POST['architecture']);
+		if(!preg_match('/^(32|64)$/', $architecture))
+		{
+			$status = "303";
+			$message = "list games: Incorrect architecture, valid options: 32, 64";
+			return array("status" => $status, "message" => $message);
+		}
+		$games = $db->getGameCfgs();
+		foreach($games as $key => $game)
+		{
+			$games[$key]['mods'] = $db->getCfgMods($game['home_cfg_id']);
+			preg_match("/^([a-z0-9_-]+)_(linux|win)(32|64)?$/i",$game['game_key'],$matches);
+			
+			if(count($matches) == 4)
+				list($game_key, $game_clean, $os, $arch) = $matches;
+			else
+			{
+				list($game_key, $game_clean, $os) = $matches;
+				$arch = "32";
+			}
+			if(strtolower($os) == 'linux')
+				$sorted_games['linux'][$arch][] = $games[$key];
+			elseif(strtolower($os) == 'win')
+				$sorted_games['windows'][$arch][] = $games[$key];
+		}
+		$status = "200";
+		$message = $sorted_games[$system][$architecture];
+	}
+	
+	if($request[0] == "list_servers")
+	{	
+		$status = "200";
+		$message = $db->getGameHomes();
+	}
+	
+	if($request[0] == "create")
+	{
+		$remote_server_id = $_POST['remote_server_id'];
+		$server_name = $_POST['server_name'];
+		$home_cfg_id = $_POST['home_cfg_id'];
+		$mod_cfg_id = $_POST['mod_cfg_id'];
+		$ip = $_POST['ip'];
+		$port = $_POST['port'];
+		$control_password = $_POST['control_password'];
+		$enable_ftp = $_POST['enable_ftp'];
+		$ftp_password = $_POST['ftp_password'];
+		$slots = $_POST['slots'];
+		$affinity = $_POST['affinity'];
+		$nice = $_POST['nice'];
+		
+		$remote_server = $db->getRemoteServer($remote_server_id);
+		if($remote_server === FALSE)
+			return array("status" => '304', "message" => "Remote Server ID#$remote_server_id does not exists");
+		
+		$game_cfg = $db->getGameCfg($home_cfg_id);
+		if($game_cfg === FALSE)
+			return array("status" => '305', "message" => "No game configuration found for home_cfg_id #" . $home_cfg_id . ".");
+		
+		$cfg_mods = $db->getCfgMods($home_cfg_id);
+		$mod_key = FALSE;
+		if($cfg_mods === FALSE)
+			return array("status" => '306', "message" => "No game mods found for home_cfg_id #" . $home_cfg_id . ".");
+		else
+		{
+			foreach($cfg_mods as $cfg_mod)
+			{
+				if($cfg_mod['mod_cfg_id'] == $mod_cfg_id)
+				{
+					$mod_key = $cfg_mod['mod_key'];
+					break;
 				}
 				}
-			}else{
-				$resultOp["message"] = "Server is already up-to-date.";
-				$resultOp["success"] = false;
 			}
 			}
-		}else{
-			$resultOp["message"] = "Unable to find appmanifest.";
-			$resultOp["success"] = false;
-		}	
-	}else{
-		$resultOp["message"] = "Game server does NOT integrate directly with Steam.";
-		$resultOp["success"] = false;
+		}
+		
+		if($mod_key === FALSE)
+			return array("status" => '307', "message" => "The mod_cfg_id #" . $mod_cfg_id . " does not belong to the game configuration for home_cfg_id #" . $home_cfg_id . ".");
+		
+		$ip_info = $db->resultQuery( "SELECT ip,ip_id FROM OGP_DB_PREFIXremote_server_ips WHERE ip='".$db->real_escape_string($ip)."' AND remote_server_id=".$db->real_escape_string($remote_server_id));
+		if($ip_info === FALSE)
+			return array("status" => '308', "message" => "The given IP address does not belongs to the given remote server.");
+		
+		$port = (int)(trim($port));
+		if(!isPortValid($port))
+			return array("status" => '309', "message" => "The given port is not a valid port.");
+		
+		$remote = new OGPRemoteLibrary($remote_server['agent_ip'],$remote_server['agent_port'],$remote_server['encryption_key'],$remote_server['timeout']);
+		$host_stat = $remote->status_chk();
+		if($host_stat !== 1)
+			return array("status" => '310', "message" => "The remote server is offline.");
+		
+		// Game path logic	
+		$skipId = false;
+		if(hasValue($settings["default_game_server_home_path_prefix"]))
+		{
+			// Replace some user supported variables with actual value.
+			$game_path = str_replace("{USERNAME}", $user_info['users_login'], $settings["default_game_server_home_path_prefix"]);
+			if(stripos($game_path, "{SKIPID}") !== false){
+				$game_path = str_replace("{SKIPID}", "",  $game_path);
+				$skipId = true;
+			}
+			$game_path = str_replace("{GAMEKEY}", strtolower(substr($game_cfg['game_key'], 0, stripos($game_cfg['game_key'], "_"))), $game_path);
+			// Make sure the path ends with forward slash
+			if($game_path[strlen($game_path)-1] != "/"){ 
+				$game_path .= "/";
+			}
+		}
+		else
+			$game_path = "/home/".$remote_server['ogp_user']."/OGP_User_Files/"; // Default
+		
+		$game_path = clean_path($game_path); // Clean it
+		
+		$home_id = $db->addGameHome($remote_server_id, $user_info['user_id'], $home_cfg_id, $game_path, $server_name, $control_password, $ftp_password, $skipId);
+		if($home_id === FALSE)
+			return array("status" => '311', "message" => "Server could not be added to the database.");
+		
+		if($db->addGameIpPort($home_id, $ip_info[0]['ip_id'], $port) === FALSE)
+		{
+			$db->deleteGameHome($home_id);
+			return array("status" => '312', "message" => "The given IP:Port is already in use.");
+		}
+		
+		if($db->addModToGameHome($home_id, $mod_cfg_id) === FALSE )
+		{
+			$db->deleteGameHome($home_id);
+			return array("status" => '313', "message" => "Failed to assing mod.");
+		}
+		
+		if($db->updateGameModParams($slots, '', $affinity, $nice, $home_id, $mod_cfg_id) === FALSE)
+		{
+			$db->deleteGameHome($home_id);
+			return array("status" => '314', "message" => "Maxplayers, affinity or nice could not be configured.");
+		}
+				
+		// Create new home directory if it doesn't already exist	
+		$game_path = $game_path . (!$skipId ? $home_id : "");
+		$remote->exec("mkdir -p " . $game_path);
+		
+		if($enable_ftp == "1")
+		{
+			$remote->ftp_mgr("useradd", $home_id, $ftp_password, $game_path);
+			$db->changeFtpStatus('enabled',$home_id);
+		}
+		
+		$status = "200";
+		$message = $home_id;
+	}
+	
+	if($request[0] == "clone")
+	{
+		$home_id = $_POST['origin_home_id'];
+		$server_name = $_POST['new_server_name'];
+		$ip = $_POST['new_ip'];
+		$port = $_POST['new_port'];
+		$control_password = $_POST['control_password'];
+		$enable_ftp = $_POST['enable_ftp'];
+		$ftp_password = $_POST['ftp_password'];
+		$slots = $_POST['slots'];
+		$affinity = $_POST['affinity'];
+		$nice = $_POST['nice'];
+				
+		$game_home = $db->getGameHome($home_id);
+		if($game_home === FALSE)
+			return array("status" => '315', "message" => "There is no game home with home_id #" . $home_id . ".");
+		
+		$remote = new OGPRemoteLibrary($game_home['agent_ip'],$game_home['agent_port'],$game_home['encryption_key'],$game_home['timeout']);
+		$host_stat = $remote->status_chk();
+		if($host_stat !== 1)
+			return array("status" => '310', "message" => "The remote server is offline.");
+		
+		$ip_info = $db->resultQuery("SELECT ip,ip_id FROM OGP_DB_PREFIXremote_server_ips WHERE ip='".$db->real_escape_string($ip)."' AND remote_server_id=".$db->real_escape_string($game_home['remote_server_id']));
+		if($ip_info === FALSE)
+			return array("status" => '308', "message" => "The given IP address does not belongs to the given remote server.");
+		
+		$port = (int)(trim($port));
+		if(!isPortValid($port))
+			return array("status" => '309', "message" => "The given port is not a valid port.");
+		
+		// Game path logic
+		$skipId = false;
+		if(hasValue($settings["default_game_server_home_path_prefix"]))
+		{
+			// Replace some user supported variables with actual value.
+			$game_path = str_replace("{USERNAME}", $user_info['users_login'], $settings["default_game_server_home_path_prefix"]);
+			if(stripos($game_path, "{SKIPID}") !== false){
+				$game_path = str_replace("{SKIPID}", "",  $game_path);
+				$skipId = true;
+			}
+			$game_path = str_replace("{GAMEKEY}", strtolower(substr($game_home['game_key'], 0, stripos($game_home['game_key'], "_"))), $game_path);
+			// Make sure the path ends with forward slash
+			if($game_path[strlen($game_path)-1] != "/"){ 
+				$game_path .= "/";
+			}
+		}
+		else
+			$game_path = "/home/".$game_home['ogp_user']."/OGP_User_Files/"; // Default
+		
+		$game_path = clean_path($game_path); // Clean it
+		
+		$clone_home_id = $db->addGameHome($game_home['remote_server_id'], $game_home['user_id_main'],
+			$game_home['home_cfg_id'], $game_path, $server_name, $control_password, $ftp_password, $skipId);
+		
+		if ($clone_home_id === FALSE)
+			return array("status" => '311', "message" => "Server could not be added to the database.");
+		
+		if($db->addGameIpPort($clone_home_id, $ip_info[0]['ip_id'], $port) === FALSE)
+		{
+			$db->deleteGameHome($clone_home_id);
+			return array("status" => '312', "message" => "The given IP:Port is already in use.");
+		}
+		
+		foreach ($game_home['mods'] as $mod_info)
+			if($db->addModToGameHome($clone_home_id, $mod_info['mod_cfg_id']) !== FALSE)
+				$db->updateGameModParams($slots, $mod_info['extra_params'], $affinity, $nice, $clone_home_id, $mod_info['mod_cfg_id']);
+		
+		// Create new home directory if it doesn't already exist	
+		$game_path = $game_path . (!$skipId ? $clone_home_id : "");
+		$remote->exec("mkdir -p " . $game_path);
+		
+		if($enable_ftp == "1")
+		{
+			$remote->ftp_mgr("useradd", $clone_home_id, $ftp_password, $game_path);
+			$db->changeFtpStatus('enabled', $clone_home_id);
+		}
+		
+		$user_group = get_user_uid_gid_from_passwd(explode("\n", $remote->sudo_exec('cat /etc/passwd')), $game_home['ogp_user']);
+		
+		$status = "200";
+		$message = array("clone_home_id" => $clone_home_id, "cloning_status" => $remote->clone_home($game_home['home_path'], $game_path, $user_group));
 	}
 	}
-}
-
-function callRestartServer(){
-	global $settings, $db, $remote, $server_xml, $mod_xml, $server_home, $mod_key, $mod_id, $appId, $home_ip_ports, $resultOp;
 	
 	
-	$success = runRemoteAction("restart_server");
-	if($success >= 0){
-		$resultOp["message"] = "Server \"" . $server_home["home_name"] . "\" has been successfully restarted.";
-		$resultOp["success"] = true;
-	}else{
-		$resultOp["message"] = "Server \"" . $server_home["home_name"] . "\" failed to restart. Agent returned: " . (is_array($success) ? print_r($success, true) : $success);
-		$resultOp["success"] = false;
+	if($request[0] == "set_expiration")
+	{
+		$home_id = $_POST['home_id'];
+		$date = date('d/m/Y H:i:s', $_POST['timestamp']);
+		
+		if($db->updateExpirationDate($home_id, $date, 'server') === TRUE)
+		{
+			$status = "200";
+			$message = "Expiration date changed";
+		}
+		else
+		{
+			$status = "316";
+			$message = "Expiration date could not be changed";
+		}
 	}
 	}
+	
+	return array("status" => $status, "message" => $message);
 }
 }
 
 
-function callStartServer(){
-	global $settings, $db, $remote, $server_xml, $mod_xml, $server_home, $mod_key, $mod_id, $appId, $home_ip_ports, $resultOp;
+function api_user_admin()
+{
+	global $request, $db, $user_info, $settings;
 	
 	
-	$success = runRemoteAction("start_server");
-	if($success == 1){
-		$resultOp["message"] = "Server \"" . $server_home["home_name"] . "\" has been successfully started.";
-		$resultOp["success"] = true;
-	}else{
-		$resultOp["message"] = "Server \"" . $server_home["home_name"] . "\" failed to start. Agent returned: " . (is_array($success) ? print_r($success, true) : $success);
-		$resultOp["success"] = false;
+	if($user_info['users_role'] != "admin")
+		return array("status" => '350', "message" => "This function is restricted to administrator accounts.");
+		
+	if($request[0] == "list")
+	{
+		$status = "200";
+		$message = $db->getUserList();
 	}
 	}
-}
+	
+	if($request[0] == "get")
+	{
+		$email = $_POST['email'];
+		$account = $db->getUserByEmail($email);
+		if($account === FALSE)
+		{
+			$status = "317";
+			$message = "There is no account with the given email address.";
+		}
+		else
+		{
+			$status = "200";
+			$message = $account;
+		}
+	}	
+	
+	if($request[0] == "create")
+	{
+		$name = $_POST['name'];
+		$email = $_POST['email'];
+		$password = $_POST['password'];
+		if($db->addUser($name,$password,'user',$email) === FALSE)
+		{
+			$status = "318";
+			$message = "Failed to create account, name or email already in use.";
+		}
+		else
+		{
+			$status = "200";
+			$message = "Account created";
+		}
+	}
+	
+	if($request[0] == "remove")
+	{
+		$email = $_POST['email'];
+		$account = $db->getUserByEmail($email);
+		if($account === FALSE)
+		{
+			$status = "319";
+			$message = "Failed to remove account, there is no account with the given email address ($email).";
+		}
+		else
+		{
+			$db->delUser($account['user_id']);
+			$status = "200";
+			$message = "Account removed successfully";
+		}
+	}
+	
+	if($request[0] == "set_expiration")
+	{
+		$email = $_POST['email'];
+		$account = $db->getUserByEmail($email);
+		if($account === FALSE)
+		{
+			$status = "319";
+			$message = "There is no account with the given email address ($email).";
+		}
+		else
+		{
+			$date = (strtoupper($_POST['timestamp']) == 'X' or $_POST['timestamp'] == '') ? 'X': $date;
+			
+			if($date != 'X' and !isValidTimeStamp($_POST['timestamp']))
+			{
+				$status = "321";
+				$message = "The given timestamp is not valid";
+			}
+			else
+			{
+				if($date != 'X')
+					$date = $_POST['timestamp'];
+				
+				$account['user_expires'] = $date;
+				if ($db->editUser($account, $account['user_id']) == FALSE)
+				{
+					$status = "316";
+					$message = "Expiration date could not be changed";
+				}
+				else
+				{
+					$status = "200";
+					$message = "Expiration date changed";
+				}
+			}
+		}
+	}
+	
+	if($request[0] == "list_assigned")
+	{
+		$email = $_POST['email'];
+		$account = $db->getUserByEmail($email);
+		if($account === FALSE)
+		{
+			$status = "319";
+			$message = "There is no account with the given email address ($email).";
+		}
+		else
+		{
+			$game_homes = $db->getHomesFor('user',$account['user_id']);
 
 
-function callStopServer(){
-	global $settings, $db, $remote, $server_xml, $mod_xml, $server_home, $mod_key, $mod_id, $appId, $home_ip_ports, $resultOp;
+			if(empty($game_homes))
+			{
+				$status = "323";
+				$message = "There are no game homes assigned for the given user.";
+			}
+			else
+			{
+				$status = "200";
+				$message = $game_homes;
+			}
+		}
+	}	
 	
 	
-	$success = runRemoteAction("stop_server");
-	if($success == 1){
-		$resultOp["message"] = "Server \"" . $server_home["home_name"] . "\" has stopped successfully.";
-		$resultOp["success"] = true;
-	}else{
-		$resultOp["message"] = "Server \"" . $server_home["home_name"] . "\" failed to stop. Agent returned: " . (is_array($success) ? print_r($success, true) : $success);
-		$resultOp["success"] = false;
+	if($request[0] == "assign")
+	{
+		$email = $_POST['email'];
+		$home_id = $_POST['home_id'];
+		$access_rights = strtolower($_POST['access_rights']);
+		
+		$game_home = $db->getGameHome($home_id);
+		if($game_home === FALSE)
+			return array("status" => '315', "message" => "There is no game home with home_id #" . $home_id . ".");
+		
+		if(!preg_match("/^u?f?p?e?t?c?$/", $access_rights))
+			return array("status" => "324", "message" => "Ivalid string for access rights");
+		
+		$account = $db->getUserByEmail($email);
+		if($account === FALSE)
+		{
+			$status = "319";
+			$message = "There is no account with the given email address ($email).";
+		}
+		else
+		{
+			$date = (strtoupper($_POST['timestamp']) == 'X' or $_POST['timestamp'] == '') ? 'X': $date;
+			
+			if($date != 'X' and !isValidTimeStamp($_POST['timestamp']))
+			{
+				$status = "321";
+				$message = "The given timestamp is not valid";
+			}
+			else
+			{
+				if($date != 'X')
+					$date = date('d/m/Y H:i:s', $_POST['timestamp']);
+				
+				if ( $db->assignHomeTo('user', $account['user_id'], $home_id, $access_rights) === TRUE )
+				{
+					$db->updateExpirationDate($game_home['home_id'], $date, 'user', $account['user_id']);
+					$status = "200";
+					$message = "Home assigned successfully";
+				}
+				else
+				{
+					$status = "325";
+					$message = "Home id#$home_id could not be assigned to $email.";
+				}
+			}
+		}
 	}
 	}
+	
+	if($request[0] == "remove_assign")
+	{
+		$email = $_POST['email'];
+		$home_id = $_POST['home_id'];
+		
+		$game_home = $db->getGameHome($home_id);
+		if($game_home === FALSE)
+			return array("status" => '315', "message" => "There is no game home with home_id #" . $home_id . ".");
+		
+		$account = $db->getUserByEmail($email);
+		if($account === FALSE)
+		{
+			$status = "319";
+			$message = "There is no account with the given email address ($email).";
+		}
+		else
+		{
+			if ($db->unassignHomeFrom("user",$account['user_id'],$game_home['home_id']) === TRUE)
+			{
+				$status = "200";
+				$message = "Home id#$game_home[home_id] has been unnassigned from $email successfully.";
+			}
+			else
+			{
+				$status = "326";
+				$message = "Home id#$home_id was not assigned to $email.";
+			}
+		}
+	}
+	
+	return array("status" => $status, "message" => $message);
 }
 }
 
 
-/****************** *
-*  CODE APP START   *
-* ******************/
+function api_gamemanager()
+{
+	global $request, $db, $user_info, $settings;
+	
+	$ip = trim($_POST['ip']);
+	$port = (int) trim($_POST['port']);
+	$mod_key = isset($_POST['mod_key'])?trim($_POST['mod_key']):'';
+		
+	if(!isPortValid($port))
+		return array("status" => '309', "message" => "The given port is not a valid port.");
+	if(!preg_match("/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/",$ip))
+		return array("status" => '327', "message" => "The given IP ($ip) is not a valid IP address.");
+	
+	$home_info = $db->getGameHomeByIP($ip, $port);
+	if($home_info === FALSE)
+		return array("status" => '328', "message" => "There is no game server with the given address ($ip:$port).");
+	
+	$mod_id = key($home_info['mods']);
+	
+	if($mod_key != '')
+	{
+		foreach($home_info['mods'] as $home_mod)
+		{
+			if($mod_key == $home_mod['mod_key'])
+			{
+				$mod_id = $home_mod['mod_id'];
+				break;
+			}
+		}
+	}
+	
+	$isAdmin = $db->isAdmin($user_info['user_id']);
+	
+	if(!$isAdmin and $db->getUserGameHome($user_info['user_id'], $home_info['home_id']) === FALSE)
+		return array("status" => '329', "message" => "The given address ($ip:$port) does not belong to your account.");
+	
+    $server_xml = read_server_config(SERVER_CONFIG_LOCATION."/".$home_info['home_cfg_file']);
 
 
-// Report all PHP errors
-error_reporting(E_ERROR);
+    if($server_xml === FALSE)
+		return array("status" => '305', "message" => "No game configuration found for home_cfg_id #" . $home_cfg_id . ".");
+	
+	$remote = new OGPRemoteLibrary($home_info['agent_ip'],$home_info['agent_port'],$home_info['encryption_key'],$home_info['timeout']);
+	$host_stat = $remote->status_chk();
+	if($host_stat !== 1)
+		return array("status" => '310', "message" => "The remote server is offline.");
+	
+	$os = $remote->what_os();
+	
+	if($request[0] == "start")
+	{
+		$start_cmd = get_start_cmd($user_info,$remote,$server_xml,$home_info,$mod_id,$ip,$port,$db);
+		
+		if(isset($server_xml->lgsl_query_name))
+			require_once('protocol/lgsl/lgsl_protocol.php');
+		
+		// Do text replacements in cfg file
+		if($server_xml->replace_texts)
+		{
+			foreach($home_info['mods'][$mod_id] as $key => $value)
+			{
+				$home_info[$key] = $value;
+			}
+			$server_home = $home_info;
+			require_once(MODULES."gamemanager/cfg_text_replace.php");
+		}
+		
+		// Run pre-start commands
+		if(isset($server_xml->pre_start) && !empty($server_xml->pre_start)){
+			$preStart = trim($server_xml->pre_start);
+		}else{
+			$preStart = "";
+		}
+		
+		// Environment variables
+		if(isset($server_xml->environment_variables) && !empty($server_xml->environment_variables)){
+			$envVars = trim($server_xml->environment_variables);
+		}else{
+			$envVars = "";
+		}
+		
+		// Additional files to lock
+		if(isset($server_xml->lock_files) && !empty($server_xml->lock_files)){
+			$lockFiles = trim($server_xml->lock_files);
+		}else{
+			$lockFiles = "";
+		}
+		
+		if(!empty($lockFiles)){
+			// Linux only call
+			if(preg_match("/Linux/", $os)){
+				$lockedFilesStatus = $remote->lock_additional_home_files($home_info['home_path'], $lockFiles, "lock");
+			}
+		}
+		
+		$start_retval = $remote->universal_start($home_info['home_id'],
+												 $home_info['home_path'],
+												 $server_xml->server_exec_name, 
+												 $server_xml->exe_location,
+												 $start_cmd, $port, $ip,
+												 $home_info['mods'][$mod_id]['cpu_affinity'],
+												 $home_info['mods'][$mod_id]['nice'],
+												 $preStart,
+												 $envVars,
+												 $server_xml->game_key
+												 );
+		
+		if( $start_retval == AGENT_ERROR_NOT_EXECUTABLE)
+			return array("status" => '330', "message" => "The server executable does not have execution permission.");
+		elseif($start_retval <= 0)
+			return array("status" => '331', "message" => "The server could not be started, already running.");
+		else
+		{
+			$firewall_settings = $db->getFirewallSettings($home_info['remote_server_id']);
+			if ($firewall_settings['status'] == "enable")
+			{
+				if ($server_xml->protocol == "gameq")
+				{
+					$query_port = get_query_port($server_xml, $port);
+				}
+				elseif ($server_xml->protocol == "lgsl")
+				{
+					$get_ports = lgsl_port_conversion((string)$server_xml->lgsl_query_name, $port, "", "");
+					$query_port = $get_ports['1'];
+				}
+				elseif ($server_xml->protocol == "teamspeak3")
+				{
+					$query_port = $port + 24;
+				}
+				set_firewall($remote, $firewall_settings, 'allow', $port, $ip);
+				if(isset($query_port) and $query_port != "" and $query_port != $port)
+					set_firewall($remote, $firewall_settings, 'allow', $query_port, $ip);
+			}
+			
+			$db->delServerStatusCache($home_info['ip_id'],$port);
+			$status = "200";
+			$message = "The server has been started.";
+		}
+	}
 
 
-// Path definitions
-define("IMAGES", "images/");
-define("INCLUDES", "includes/");
-define("MODULES", "modules/");
+	if($request[0] == "stop")
+	{
+		$remote_retval = $remote->remote_stop_server($home_info['home_id'],
+			$ip, $port, $server_xml->control_protocol,
+			$home_info['control_password'],$server_xml->control_protocol_type, $home_info['home_path']);
+		
+		if($remote_retval === -1)
+			return array("status" => '332', "message" => "The server could not be stopped.");
+		elseif($remote_retval === -2)
+			return array("status" => '332', "message" => "The server could not be stopped.");
+		else
+		{
+			$firewall_settings = $db->getFirewallSettings($home_info['remote_server_id']);
+			if ($firewall_settings['status'] == "enable")
+			{
+				if ($server_xml->protocol == "gameq")
+				{
+					$query_port = get_query_port($server_xml, $port);
+				}
+				elseif ($server_xml->protocol == "lgsl")
+				{
+					require('protocol/lgsl/lgsl_protocol.php');
+					$get_ports = lgsl_port_conversion((string)$server_xml->lgsl_query_name, $port, "", "");
+					$query_port = $get_ports['1'];
+				}
+				elseif ($server_xml->protocol == "teamspeak3")
+				{
+					$query_port = $port + 24;
+				}
+				set_firewall($remote, $firewall_settings, 'deny', $port, $ip);
+				if(isset($query_port) and $query_port != "" and $query_port != $port)
+					set_firewall($remote, $firewall_settings, 'deny', $query_port, $ip);
+			}
+			$status = "200";
+			$message = "The server has been stopped.";
+		}
+	}
 
 
-define("CONFIG_FILE","includes/config.inc.php");
+	if($request[0] == "restart")
+	{
+		$start_cmd = get_start_cmd($user_info,$remote,$server_xml,$home_info,$mod_id,$ip,$port,$db);
+		// Do text replacements in cfg file
+		if( $server_xml->replace_texts )
+		{
+			foreach($home_info['mods'][$mod_id] as $key => $value)
+			{
+				$home_info[$key] = $value;
+			}
+			$server_home = $home_info;
+			if(isset($server_xml->lgsl_query_name))
+				require_once('protocol/lgsl/lgsl_protocol.php');
+			require_once(MODULES."gamemanager/cfg_text_replace.php");
+		}
+		
+		// Run pre-start commands
+		if(isset($server_xml->pre_start) && !empty($server_xml->pre_start)){
+			$preStart = trim($server_xml->pre_start);
+		}else{
+			$preStart = "";
+		}
+			
+		// Environment variables
+		if(isset($server_xml->environment_variables) && !empty($server_xml->environment_variables)){
+			$envVars = trim($server_xml->environment_variables);
+		}else{
+			$envVars = "";
+		}
+		
+		// Additional files to lock
+		if(isset($server_xml->lock_files) && !empty($server_xml->lock_files)){
+			$lockFiles = trim($server_xml->lock_files);
+		}else{
+			$lockFiles = "";
+		}
+		
+		if(!empty($lockFiles)){
+			// Linux only call
+			if(preg_match("/Linux/", $os)){
+				$lockedFilesStatus = $remote->lock_additional_home_files($home_info['home_path'], $lockFiles, "lock");
+			}
+		}
+		
+		$remote_retval = $remote->remote_restart_server($home_info['home_id'],$ip,$port,$server_xml->control_protocol,
+														$home_info['control_password'],$server_xml->control_protocol_type,$home_info['home_path'],
+														$server_xml->server_exec_name,$server_xml->exe_location,$start_cmd,
+														$home_info['mods'][$mod_id]['cpu_affinity'],
+														$home_info['mods'][$mod_id]['nice'],
+														$preStart,
+														$envVars,
+														$server_xml->game_key);
+		
+		if($remote_retval === -1)
+			return array("status" => '333', "message" => "The server could not be restarted.");
+		elseif($remote_retval === -2)
+			return array("status" => '333', "message" => "The server could not be restarted.");
+		else
+		{
+			$ip_id = $db->getIpIdByIp($ip);
+			$db->delServerStatusCache($home_info['ip_id'],$port);
+			$status = "200";
+			$message = "The server has been restarted.";
+		}
+	}
 
 
-require_once 'includes/functions.php';
-require_once 'includes/helpers.php';
-require_once 'includes/html_functions.php';
-require_once 'modules/config_games/server_config_parser.php';
-require_once 'modules/gamemanager/home_handling_functions.php';
-require_once 'includes/lib_remote.php';
+	if($request[0] == "rcon")
+	{
+		$command = $_POST['command'];
+		$response = send_rcon_command($command, $remote, $server_xml, $home_info, $home_info['home_id'], $ip, $port);
+		if($response === FALSE)
+		{
+			$status = "334";
+			$message = "The command could not be sent";
+		}
+		else
+		{
+			$status = "200";
+			$message = $response;
+		}
+	}
+	
+	if($request[0] == "update")
+	{
+		if($_POST['type'] == "steam")
+		{
+			if($server_xml->installer == "steamcmd")
+			{
+				$exec_folder_path = clean_path($home_info['home_path'] . "/" . $server_xml->exe_location);
+				$exec_path = clean_path($exec_folder_path . "/" . $server_xml->server_exec_name);
+				$mod_xml = xml_get_mod($server_xml, $home_info['mods'][$mod_id]['mod_key']);
+				$installer_name = $mod_xml->installer_name;
+				$modkey = $home_info['mods'][$mod_id]['mod_key'];
+				// Some games like L4D2 require anonymous login
+				if($mod_xml->installer_login){
+					$login = $mod_xml->installer_login;
+					$pass = '';
+				}else{
+					$login = $settings['steam_user'];
+					$pass = $settings['steam_pass'];
+				}
+				$modname = ( $installer_name == '90' and !preg_match("/(cstrike|valve)/", $modkey) ) ? $modkey : '';
+				$betaname = isset($mod_xml->betaname) ? $mod_xml->betaname : '';
+				$betapwd = isset($mod_xml->betapwd) ? $mod_xml->betapwd : '';
+				preg_match("/(win|linux)(32|64)?$/", $server_xml->game_key, $matches);
+				$os = strtolower($matches[1]) == 'linux'? 'linux':'windows';
+				$arch = isset($matches[2])?$matches[2]:'32';
+				
+				$preInstallCMD = "";
+				if(isset($server_xml->post_install))
+					$preInstallCMD .= $server_xml->pre_install;
+				
+				$postInstallCMD = "";
+				if(isset($server_xml->post_install))
+					$postInstallCMD .= $server_xml->post_install;
+				$postInstallCMD .= "\n{OGP_LOCK_FILE} " . $home_info['home_path'] . "/" . ($server_xml->exe_location ? $server_xml->exe_location . "/" : "") . $server_xml->server_exec_name;
+				
+				$remote->steam_cmd($home_info['home_id'],$home_info['home_path'],$installer_name,$modname,
+								   $betaname,$betapwd,$login,$pass,$settings['steam_guard'],
+								   $exec_folder_path,$exec_path,$preInstallCMD,$postInstallCMD,$os,'',$arch);
+				$status = "200";
+				$message = "Steam installation started";
+			}
+			else
+			{
+				$status = "335";
+				$message = 'This game is not supported by Steam installation.';
+			}
+		}
+		
+		if($_POST['type'] == "rsync")
+		{
+			if(isset($server_xml->lgsl_query_name))
+			{
+				$rs_name = $server_xml->lgsl_query_name;
+				if($rs_name == "quake3" and $server_xml->game_name == "Quake 3")
+					$rs_name = "q3";
+			}
+			elseif(isset($server_xml->gameq_query_name))
+			{
+				$rs_name = $server_xml->gameq_query_name;
+				if($rs_name == "minecraft")
+				{
+					if($server_xml->game_name == "Minecraft Tekkit")
+						$rs_name = "tekkit";
+					elseif($server_xml->game_name == "Minecraft Bukkit")
+						$rs_name = "bukkit";
+				}
+			}
+			elseif(isset($server_xml->protocol))
+				$rs_name = $server_xml->protocol;
+			else
+				$rs_name = $server_xml->mods->mod['key'];
+			
+						
+			$rsync_available = isset($settings['rsync_available']) ? $settings['rsync_available'] : "1";
+			$remote_sites = MODULES."gamemanager/rsync_sites.list";
+			$local_sites = MODULES."gamemanager/rsync_sites_local.list";
+			$rsync_sites = array();
+			
+			switch ($rsync_available) {
+				case "0":
+					if(file_exists($remote_sites))
+					{
+						$sites = file($remote_sites);
+						if($sites !== FALSE)
+							$rsync_sites = array_merge($rsync_sites, $sites);
+					}
+					
+					if(file_exists($local_sites))
+					{
+						$sites = file($local_sites);
+						if($sites !== FALSE)
+							$rsync_sites = array_merge($rsync_sites, $sites);
+					}
+					break;
+				case "1":
+					if(file_exists($remote_sites))
+					{
+						$sites = file($remote_sites);
+						if($sites !== FALSE)
+							$rsync_sites = array_merge($rsync_sites, $sites);
+					}
+					break;
+				case "2":
+					if(file_exists($local_sites))
+					{
+						$sites = file($local_sites);
+						if($sites !== FALSE)
+							$rsync_sites = array_merge($rsync_sites, $sites);
+					}
+					break;
+			}
+			
+			if(empty($rsync_sites))
+				return array("status" => '336', "message" => "No sync sites found, check the panel settings (Available rsync sites).");
+			
+			$url = get_faster_rsync($rsync_sites);
+			
+			$sync_list_file = MODULES."gamemanager/rsync.list";
+			
+			if(!file_exists($sync_list_file))
+				return array("status" => '336', "message" => "The sync list file doesn't exists ($sync_list_file).");
+			
+			$sync_list = file($sync_list_file, FILE_IGNORE_NEW_LINES);
+			if(!$sync_list or empty($sync_list))
+				return array("status" => '337', "message" => "Failed to read sync list file ($sync_list_file).");
+			
+			if(in_array($rs_name, $sync_list)) 
+			{
+				$exec_folder_path = clean_path($home_info['home_path'] . "/" . $server_xml->exe_location);
+				$exec_path = clean_path($exec_folder_path . "/" . $server_xml->server_exec_name);
+				preg_match("/(win|linux)(32|64)?$/", $server_xml->game_key, $matches);
+				$os = strtolower($matches[1]) == 'linux'? 'linux':'windows';
+				$full_url = "$url/ogp_game_installer/$rs_name/$os/";
+				
+				$preInstallCMD = "";
+				if(isset($server_xml->post_install))
+					$preInstallCMD .= $server_xml->pre_install;
+				
+				$postInstallCMD = "";
+				if(isset($server_xml->post_install))
+					$postInstallCMD .= $server_xml->post_install;
+				$postInstallCMD .= "\n{OGP_LOCK_FILE} " . $home_info['home_path'] . "/" . ($server_xml->exe_location ? $server_xml->exe_location . "/" : "") . $server_xml->server_exec_name;
+				
+				$remote->start_rsync_install($home_id,$home_info['home_path'],"$full_url",$exec_folder_path,$exec_path,$preInstallCMD,$postInstallCMD);
+				$status = "200";
+				$message = "Rsync installation started";
+			}
+			else
+			{
+				$status = "335";
+				$message = 'This game is not supported by Rsync installation.';
+			}
+		}
+		
+		if($_POST['type'] == "manual")
+		{
+			$manual_url = trim($_POST['manual_url']);
+			$filename = get_download_filename($manual_url);
+			
+			if($filename)
+			{
+				$postInstallCMD = "";
+				if(isset($server_xml->post_install))
+					$postInstallCMD .= $server_xml->post_install;
+				$postInstallCMD .= "\n{OGP_LOCK_FILE} " . $home_info['home_path'] . "/" . ($server_xml->exe_location ? $server_xml->exe_location . "/" : "") . $server_xml->server_exec_name;
+				$remote->start_file_download($manual_url,$home_info['home_path'],$filename,"uncompress",$postInstallCMD);
+				$status = "200";
+				$message = "Manual installation started";
+			}
+			else
+			{
+				$status = "335";
+				$message = 'The URL for manual installation is empty or invalid.';
+			}
+		}
+		
+		if($_POST['type'] == "master")
+		{
+			$ms_home_id = $db->getMasterServer($home_info['remote_server_id'], $home_info['home_cfg_id']);
+			if($ms_home_id !== FALSE)
+			{
+				$exec_folder_path = clean_path($home_info['home_path'] . "/" . $server_xml->exe_location );
+				$exec_path = clean_path($exec_folder_path . "/" . $server_xml->server_exec_name );
+				$ms_info = $db->getGameHome($ms_home_id);
+				
+				$preInstallCMD = "";
+				if(isset($server_xml->post_install))
+					$preInstallCMD .= $server_xml->pre_install;
+				
+				$postInstallCMD = "";
+				if(isset($server_xml->post_install))
+					$postInstallCMD .= $server_xml->post_install;
+				$postInstallCMD .= "\n{OGP_LOCK_FILE} " . $home_info['home_path'] . "/" . ($server_xml->exe_location ? $server_xml->exe_location . "/" : "") . $server_xml->server_exec_name;
+				
+				$remote->masterServerUpdate($home_id,$home_info['home_path'],$ms_home_id,$ms_info['home_path'],$exec_folder_path,$exec_path,$preInstallCMD,$postInstallCMD);
+				$status = "200";
+				$message = "Installation from master server ($home_info[home_name]) started";
+			}
+			else
+			{
+				$status = "335";
+				$message = 'There is no master server assigned for this game.';
+			}
+		}
+	}
+	
+	return array("status" => $status, "message" => $message);
+}
 
 
-// Start the session valid for opengamepanel_web only
-startSession();
+function api_litefm()
+{
+	global $request, $db, $user_info, $settings;
+	
+	$ip = $_POST['ip'];
+	$port = $_POST['port'];
+	$relative_path = $_POST['relative_path'];
+		
+	$home_info = $db->getGameHomeByIP($ip, $port);
+	if($home_info === FALSE)
+		return array("status" => '328', "message" => "There is no game server with the given address ($ip:$port).");
+	
+	$isAdmin = $db->isAdmin($user_info['user_id']);
+	
+	if(!$isAdmin and $db->getUserGameHome($user_info['user_id'], $home_info['home_id']) === FALSE)
+		return array("status" => '329', "message" => "The given address ($ip:$port) does not belong to your account.");
+	
+    $server_xml = read_server_config(SERVER_CONFIG_LOCATION."/".$home_info['home_cfg_file']);
 
 
-require_once CONFIG_FILE;
-// Connect to the database server and select database.
-$db = createDatabaseConnection($db_type, $db_host, $db_user, $db_pass, $db_name, $table_prefix);
-$settings = $db->getSettings();
-@$GLOBALS['panel_language'] = $settings['panel_language'];
+    if($server_xml === FALSE)
+		return array("status" => '305', "message" => "No game configuration found for home_cfg_id #" . $home_cfg_id . ".");
+	
+	$remote = new OGPRemoteLibrary($home_info['agent_ip'],$home_info['agent_port'],$home_info['encryption_key'],$home_info['timeout']);
+	$host_stat = $remote->status_chk();
+	if($host_stat !== 1)
+		return array("status" => '310', "message" => "The remote server is offline.");
+	
+	$path = clean_path($home_info['home_path'].'/'.$relative_path);
+	
+	if($request[0] != "save" and $remote->rfile_exists($path) === 0)
+		return array("status" => '338', "message" => "$path does not exists.");
+	
+	if($request[0] == "list")
+	{
+		$status = "200";
+		$message = $remote->remote_dirlistfm($path);
+	}
+	
+	if($request[0] == "get")
+	{
+		$remote->remote_readfile($path, $data);
+		$status = "200";
+		$message = $data;
+	}
+	
+	if($request[0] == "save")
+	{
+		$contents = $_POST['contents'];
+		if($remote->remote_writefile($path, $contents) === 1)
+		{
+			$status = "200";
+			$message = "File $path written successfully";
+		}
+		else
+		{
+			$status = "339";
+			$message = "Could not write to the file.";
+		}
+	}
+	
+	if($request[0] == "remove")
+	{
+		$remote->shell_action('remove_recursive', $path);
+		if($remote->rfile_exists($path) === 0)
+		{
+			$status = '200';
+			$message = "$path removed successfully.";
+		}
+		else
+		{
+			$status = '340';
+			$message = "$path could not be removed.";
+		}
+		
+	}
+	
+	return array("status" => $status, "message" => $message);
+}
 
 
-// Handle API Request
-if(hasValue($_REQUEST["action"]) && hasValue($_REQUEST["homeid"]) && hasValue($_REQUEST["controlpass"]) && is_numeric($_REQUEST["homeid"])){
+function api_addonsmanager()
+{
+	global $request, $db, $user_info;
 	
 	
-	// Get the variables we need	
-	$action = $_REQUEST["action"];
-	$homeId = $_REQUEST["homeid"];
-	$controlPass = $_REQUEST["controlpass"];
+	if($db->isModuleInstalled('addonsmanager') === FALSE)
+		return array("status" => '349', "message" => "This function is not available because the module is not installed.");
 	
 	
-	// Get home information
-	$server_home = $db->getGameHome($homeId);
+	if($request[0] == "list")
+	{
+		$addons_rows = $db->resultQuery("SELECT * FROM OGP_DB_PREFIXaddons");
+		$status = "200";
+		$message = $addons_rows[0];
+	}
 	
 	
-	if(hasValue($server_home) && is_array($server_home) && count($server_home) > 0){
-		if(trim($server_home["control_password"]) == trim(strip_tags($controlPass))){
+	if($request[0] == "install")
+	{
+		$ip = $_POST['ip'];
+		$port = (int)$_POST['port'];
+		$mod_key = isset($_POST['mod_key'])?trim($_POST['mod_key']):'';
+		$addon_id = (int)$_POST['addon_id'];
+		
+		$home_info = $db->getGameHomeByIP($ip, $port);
+		if($home_info === FALSE)
+			return array("status" => '328', "message" => "There is no game server with the given address ($ip:$port).");
+		
+		$isAdmin = $db->isAdmin($user_info['user_id']);
+		
+		if(!$isAdmin and $db->getUserGameHome($user_info['user_id'], $home_info['home_id']) === FALSE)
+			return array("status" => '329', "message" => "The given address ($ip:$port) does not belong to your account.");
+		
+		$server_xml = read_server_config(SERVER_CONFIG_LOCATION."/".$home_info['home_cfg_file']);
+
+		if($server_xml === FALSE)
+			return array("status" => '305', "message" => "No game configuration found for home_cfg_id #" . $home_cfg_id . ".");
+		
+		$remote = new OGPRemoteLibrary($home_info['agent_ip'],$home_info['agent_port'],$home_info['encryption_key'],$home_info['timeout']);
+		$host_stat = $remote->status_chk();
+		if($host_stat !== 1)
+			return array("status" => '310', "message" => "The remote server is offline.");
+		
+		$mod_id = key($home_info['mods']);
+		
+		if($mod_key != '')
+		{
+			foreach($home_info['mods'] as $home_mod)
+			{
+				if($mod_key == $home_mod['mod_key'])
+				{
+					$mod_id = $home_mod['mod_id'];
+					break;
+				}
+			}
+		}
+		else
+			$mod_key = $home_info['mods'][$mod_id]['mod_key'];
+		
+		$query_groups = "";
+		if(!$isAdmin)
+		{
+			$groups = $db->getUsersGroups($user_info['user_id']);
+			$query_groups .= " AND (";
+			foreach($groups as $group)
+				$query_groups .= "group_id=".$group['group_id']." OR ";
+			$query_groups .= "group_id=0 OR group_id IS NULL)";
+		}
+
+		$addons_rows = $db->resultQuery("SELECT url, path, post_script FROM OGP_DB_PREFIXaddons WHERE addon_id=".$addon_id.$query_groups);
+
+		if($addons_rows === FALSE)
+			return array("status" => '341', "message" => "Invalid addon id #" . $addon_id . ".");
+		
+		$addon_info = $addons_rows[0];
+		
+		$url = $addon_info['url'];
+		$filename = basename($url);
+		
+		if($addon_info['post_script'] != "")
+		{
+			$addon_info['post_script'] = strip_real_escape_string($addon_info['post_script']);
+						
+			if(	isset($server_xml->gameq_query_name) )
+			{
+				$home_info['query_port'] = get_query_port($server_xml, $home_info['port']);
+			}
+			elseif(	isset($server_xml->lgsl_query_name) )
+			{
+				require_once('protocol/lgsl/lgsl_protocol.php');
+				$get_q_and_s = lgsl_port_conversion((string)$server_xml->lgsl_query_name, $home_info['port'], "", "");
+				$home_info['query_port'] = $get_q_and_s['1'];
+			}
+			elseif ($server_xml->protocol == "teamspeak3")
+			{
+				$query_port = $port + 24;
+			}
 			
 			
-			// Set command server variables (home server XML, IPs, etc)
-			$server_xml = read_server_config(SERVER_CONFIG_LOCATION . '/' . $server_home['home_cfg_file']);
-			if($server_xml){
-				$getIpPorts = $db->getHomeIpPorts($homeId);
-				$home_ip_ports = $getIpPorts[0];
-				$remote = new OGPRemoteLibrary($server_home['agent_ip'], $server_home['agent_port'], $server_home['encryption_key'], $server_home['timeout']);
-				$appId = (int)$server_xml->mods->mod->installer_name;
-				$mod_id = key($server_home['mods']);
-				$mod_key = $server_home['mods'][$mod_id]['mod_key'];
-				$mod_xml = xml_get_mod($server_xml, $mod_key);
-				if($mod_xml !== false){
-				
-					/****************************************/
-					//           Actual API Logic :)         /
-					/****************************************/
-					
-					// Handle API Action
-					switch($action){
-						case "autoUpdateSteamHome":
-							callSteamAutoUpdate();
-							break;
-						case "restartServer":
-							callRestartServer();
-							break;
-						case "startServer":
-							callStartServer();
-							break;
-						case "stopServer":
-							callStopServer();
-							break;
-						default: 
-							$resultOp["message"] = "Invalid action specified.";
-							$resultOp["success"] = false;
+			$home_info["incremental"] = $db->incrementalNumByHomeId($home_info['home_id'], $home_info['mods'][$mod_id]['mod_cfg_id'], $home_info['remote_server_id']);
+			
+			$post_script = preg_replace( "/\%home_path\%/i", $home_info['home_path'], $addon_info['post_script']);
+			$post_script = preg_replace( "/\%home_name\%/i", $home_info['home_name'], $post_script);
+			$post_script = preg_replace( "/\%control_password\%/i", $home_info['control_password'], $post_script);
+			$post_script = preg_replace( "/\%max_players\%/i", $home_info['mods'][$mod_id]['max_players'], $post_script);
+			$post_script = preg_replace( "/\%ip\%/i", $home_info['ip'], $post_script);
+			$post_script = preg_replace( "/\%port\%/i", $home_info['port'], $post_script);
+			$post_script = preg_replace( "/\%query_port\%/i", $home_info['query_port'], $post_script);
+			$post_script = preg_replace( "/\%incremental\%/i", $home_info['incremental'], $post_script);
+		}
+
+		$pid = $remote->start_file_download($addon_info['url'], $home_info['home_path']."/".$addon_info['path'], $filename, "uncompress", $post_script);
+		if($remote->is_file_download_in_progress($pid) === 1)
+		{
+			$status = "200";
+			$message = "Addon installation started with process id #".$pid;
+		}
+		else
+		{
+			$status = "342";
+			$message = "Addon installation failed, file download could not be started.";
+		}
+	}
+	
+	return array("status" => $status, "message" => $message);
+}
+
+function api_steam_workshop()
+{
+	global $request, $db, $user_info, $settings;
+	
+	if($db->isModuleInstalled('steam_workshop') === FALSE)
+		return array("status" => '349', "message" => "This function is not available because the module is not installed.");
+		
+	define('CONFIGS', "modules/steam_workshop/game_configs/");
+	
+	if($request[0] == "install")
+	{
+		$ip = $_POST['ip'];
+		$port = (int)$_POST['port'];
+		$mod_key = isset($_POST['mod_key'])?trim($_POST['mod_key']):'';
+		$mods_list = $_POST['mods_list'];
+		
+		$home_info = $db->getGameHomeByIP($ip, $port);
+		if($home_info === FALSE)
+			return array("status" => '328', "message" => "There is no game server with the given address ($ip:$port).");
+		
+		$isAdmin = $db->isAdmin($user_info['user_id']);
+		
+		if(!$isAdmin and $db->getUserGameHome($user_info['user_id'], $home_info['home_id']) === FALSE)
+			return array("status" => '329', "message" => "The given address ($ip:$port) does not belong to your account.");
+		
+		$server_xml = read_server_config(SERVER_CONFIG_LOCATION."/".$home_info['home_cfg_file']);
+
+		if($server_xml === FALSE)
+			return array("status" => '305', "message" => "No game configuration found for home_cfg_id #" . $home_cfg_id . ".");
+		
+		$remote = new OGPRemoteLibrary($home_info['agent_ip'],$home_info['agent_port'],$home_info['encryption_key'],$home_info['timeout']);
+		$host_stat = $remote->status_chk();
+		if($host_stat !== 1)
+			return array("status" => '310', "message" => "The remote server is offline.");
+		
+		require_once(MODULES.'steam_workshop/functions.php');
+		
+		if(preg_match('/^([0-9]+,?)+$/', $mods_list))
+		{			
+			$mod_id = key($home_info['mods']);
+						
+			if($mod_key != '')
+			{
+				foreach($home_info['mods'] as $home_mod)
+				{
+					if($mod_key == $home_mod['mod_key'])
+					{
+						$mod_id = $home_mod['mod_id'];
+						break;
 					}
 					}
+				}
+			}
+				
+			$mod_xml = xml_get_mod($server_xml, $home_info['mods'][$mod_id]['mod_key']);
+			
+			if($mod_xml == FALSE)
+				return array("status" => '344', "message" => "mod_key not found from game xml.");
+			
+			preg_match('/(linux|win)(32|64)?/i', $home_info['game_key'], $matches);
+			
+			if(strtolower($matches[1]) == 'linux')
+				$os = "Linux";
+			elseif(strtolower($matches[1]) == 'win')
+				$os = "Windows";
 					
 					
-					/****************************************/
-					//       End Actual API Logic :)         /
-					/****************************************/
+			$xml_file = CONFIGS.$mod_xml->installer_name."_".$os.".xml";
+			if(!file_exists($xml_file))
+				return array("status" => '344', "message" => "No Steam workshop xml file could be found for the game installed in the given ip:port.");
+			
+			$dom = new DOMDocument();
+			
+			if ( @$dom->load($xml_file) === FALSE )
+				return array("status" => '345', "message" => "The Steam workshop xml file for this game has bad format.");
 					
 					
-				}else{
-					$resultOp["message"] = "Problem retrieving server mod XML.";
-					$resultOp["success"] = false;
+			$xml = simplexml_load_file($xml_file);
+			
+			$mod_id_array = explode(',', $mods_list);
+
+			foreach($mod_id_array as $workshop_mod_id)
+			{
+				$exist = false;
+				foreach($xml->mods->mod as $mod)
+				{
+					if($mod['id'] == $workshop_mod_id)
+					{
+						$exist = true;
+						break;
+					}
+				}
+				
+				if(belongs_to_workshop($workshop_mod_id, $xml->workshop_id))
+				{
+					if(!$exist)
+					{
+						list($mod_title, $mod_description, $mod_image_url, $download_url, $filename, $file_size) = get_mod_info($workshop_mod_id);
+						//add mods to the xml
+						$mod = new SimpleXMLElement('<mod/>');
+						$mod->addAttribute('id', $workshop_mod_id);
+						$mod->addChild('name', $mod_title);
+						$mod->addChild('description', base64_encode($mod_description));
+						$mod->addChild('image_url', $mod_image_url);
+						$mod->addChild('download_url', $download_url);
+						$mod->addChild('filename', $filename);
+						$mod->addChild('file_size', $file_size);
+						$moddom = dom_import_simplexml($mod)->ownerDocument;
+						$moddom->formatOutput = true;
+						$mod_string = $moddom->saveXML($moddom->documentElement);
+						
+						$dom = dom_import_simplexml($xml)->ownerDocument;
+						$dom->formatOutput = true;
+						
+						$mods = $dom->getElementsByTagName('mods')->item(0);
+						
+						$f = $dom->createDocumentFragment();
+						$f->appendXML($mod_string."\n");
+						$mods->appendChild($f);
+										
+						
+						file_put_contents($xml_file, $dom->saveXML());
+						$xml = simplexml_load_file($xml_file);
+					}
+				}
+				else
+				{
+					break;
+					return array("status" => '346', "message" => "Mod $workshop_mod_id does not belong to workshop ".$xml->workshop_id.".");
 				}
 				}
-			}else{
-				$resultOp["message"] = "Failed to read server XML.";
-				$resultOp["success"] = false;
 			}
 			}
-		}else{
-			$resultOp["message"] = "Server home key does not match stored information.";
-			$resultOp["success"] = false;
+			
+			$config = $xml->config;
+			$anonymous_login = $xml->anonymous_login;
+			$download_method = $xml->download_method;
+			$user = $settings['steam_user'];
+			$pass = $settings['steam_pass'];
+			$regex = $config->regex;
+			$mods_backreference_index = (int)$config->mods_backreference_index;
+			$variable = $config->variable;
+			$place_after = $config->place_after;
+			$mod_string = $config->mod_string;
+			$string_separator = $config->string_separator;
+			$config_file_path = clean_path($home_info['home_path']."/".$config->filepath);
+			$post_install = $xml->post_install;
+			$mod_names_list = get_mod_names_list($mods_list, $xml->mods->mod);
+			$mods_full_path = clean_path($home_info['home_path'].'/'.$xml->mods_path);
+			$workshop_id = $xml->workshop_id;
+			
+			$url_list = "";
+			$filename_list = "";
+			if($download_method == "steamapi")
+			{
+				foreach($mod_id_array as $workshop_mod_id)
+				{
+					foreach($xml->mods->mod as $mod)
+					{
+						if($mod['id'] == $workshop_mod_id)
+						{
+							$separator = $url_list == ""?"":",";
+							$url_list .= $separator.$mod->download_url;
+							$filename_list .= $separator.$mod->filename;
+						}
+					}
+				}
+			}
+			
+			if($remote->steam_workshop( $home_info['home_id'],$mods_full_path,$workshop_id,$mods_list,$regex,$mods_backreference_index,
+										$variable,$place_after,$mod_string,$string_separator,$config_file_path,$post_install, 
+										$mod_names_list,$anonymous_login,$user,$pass,$download_method,$url_list,$filename_list ) == 1)
+			{
+				$status = "200";
+				$message = "Mods installation started successfully";
+			}
+			else
+			{
+				$status = '347';
+				$message = "The installation could not be started on the remote server.";
+			}
+		}
+		else
+		{
+			$status = '348';
+			$message = "The mods list has bad format ($mods_list), must be a list of mod ids separated by coma with no spaces, or only one mod id.";
 		}
 		}
-	}else{
-		$resultOp["message"] = "Unable to find game server home.";
-		$resultOp["success"] = false;
 	}
 	}
-}else{
-	$resultOp["message"] = "Invalid inputs.";
-	$resultOp["success"] = false;
-}
-	
-// Output JSON
-if(hasValue($resultOp["message"]) && hasValue($resultOp["success"], true)){
-	outPutJSON($resultOp);
+		
+	return array("status" => $status, "message" => $message);
 }
 }
-
-exit();
-?>
+?>

+ 56 - 0
test_api.php

@@ -0,0 +1,56 @@
+<?php
+require_once 'includes/api_functions.php';
+$functions = get_function_args("all");
+?>
+<html>
+<body>
+<form method=POST action="test_api.php">
+<select name="method" onchange="this.form.submit()">
+<?php
+$methods = array('POST', 'GET');
+foreach($methods as $method)
+{
+	$is_selected = (isset($_POST['method']) and $_POST['method'] == $method)?"selected":"";
+	echo "<option value='$method' $is_selected>Method $method</option>";
+}
+?>
+</select>
+<br>
+<select name="function" onchange="this.form.submit()">
+<option value="">Select</option>
+<?php
+foreach($functions as $key => $value)
+{
+	$selected = (isset($_POST['function']) and $key == $_POST['function'])?"selected":"";
+	echo "<option value='$key' $selected>$key</option>\n";
+}
+?>
+</select>
+</form>
+<?php
+if(isset($_POST['function']))
+{
+	$get_req = $_POST['method'] == 'POST'? "?".$_POST['function']:"";
+?>
+<form method='<?=$_POST['method']?>' action="ogp_api.php<?=$get_req?>" target="_blank">
+<?php
+if($_POST['method'] == 'GET')
+	echo "<input type=hidden name='$_POST[function]'>";
+?>
+<table>
+<?php
+$inputs = $functions["$_POST[function]"];
+foreach($inputs as $input => $mandatory)
+{
+	$is_mandatory = $mandatory?"":" (optional)";
+	echo "<tr><td>". strtoupper($input) ."$is_mandatory : </td><td><input type=text name='$input'></td></tr>\n";
+}
+?>
+<tr><td><input type=submit ></td></tr>
+</table>
+</form>
+</body>
+</html>
+<?php
+}
+?>