From eb26f15266c9826dab23f610e2675389ccf87bd4 Mon Sep 17 00:00:00 2001 From: Eywek Date: Fri, 13 Oct 2017 13:06:17 +0200 Subject: [PATCH] Add RCON --- app/Config/Schema/schema.php | 3 +- app/Controller/Component/ServerComponent.php | 87 +++++++++++++++----- app/Controller/ServerController.php | 16 +++- app/Controller/UserController.php | 4 - app/Model/Server.php | 30 ++++--- app/Plugin/Shop | 2 +- app/Plugin/Vote | 2 +- app/View/Server/admin_link.ctp | 61 ++++++++++---- app/View/User/admin_edit.ctp | 8 -- lang/fr_FR.json | 6 +- 10 files changed, 155 insertions(+), 64 deletions(-) diff --git a/app/Config/Schema/schema.php b/app/Config/Schema/schema.php index b6ba2c37..bc66377a 100755 --- a/app/Config/Schema/schema.php +++ b/app/Config/Schema/schema.php @@ -70,7 +70,7 @@ public function after($event = array(), $install = false, $updateContent = array 'server_cache' => 0, 'server_secretkey' => '', 'server_timeout' => 1, - 'version' => '1.2.5', + 'version' => '1.3.0', 'skype' => 'http://mineweb.org', 'youtube' => 'http://mineweb.org', 'twitter' => 'http://mineweb.org', @@ -378,6 +378,7 @@ public function after($event = array(), $install = false, $updateContent = array 'ip' => array('type' => 'string', 'null' => false, 'length' => 120, 'collate' => 'latin1_swedish_ci', 'charset' => 'latin1'), 'port' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 5, 'unsigned' => false), 'type' => array('type' => 'integer', 'null' => false, 'default' => 0, 'length' => 1, 'unsigned' => false), + 'port' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 255, 'unsigned' => false), 'indexes' => array( 'PRIMARY' => array('column' => 'id', 'unique' => 1) ), diff --git a/app/Controller/Component/ServerComponent.php b/app/Controller/Component/ServerComponent.php index 05d00bca..6c2b76b5 100755 --- a/app/Controller/Component/ServerComponent.php +++ b/app/Controller/Component/ServerComponent.php @@ -56,7 +56,7 @@ private function parseResult($result) return $methods; } - public function call($methods = false, $server_id = false, $debug = false) + public function call($methods = [], $server_id = false, $debug = false) { $multi = true; if (!$server_id) @@ -67,18 +67,6 @@ public function call($methods = false, $server_id = false, $debug = false) } $config = $this->getConfig($server_id); - if ($config['type'] == 1) { // only ping - // ping - $ping = $this->ping(array('ip' => $config['ip'], 'port' => $config['port'])); - // each method - $result = array(); - if (!is_array($methods)) - $methods = array($methods); - foreach ($methods as $methodName => $methodValue) - $result[$methodName] = (isset($ping[$methodName])) ? $ping[$methodName] : false; - return $result; - } - if (!is_array($methods)) {// transform into array $methods = array(array($methods => array())); $multi = false; @@ -90,6 +78,41 @@ public function call($methods = false, $server_id = false, $debug = false) $multi = false; } + if ($config['type'] == 1 || $config['type'] == 2) { + $methodsName = array_map(function ($method) { + return array_keys($method)[0]; + }, $methods); + $result = []; + + if (in_array('RUN_COMMAND', $methodsName) && $config['type'] == 2) { + foreach ($methods as $key => $method) { + if (array_keys($method)[0] === 'RUN_COMMAND') + $result[$key]['RUN_COMMAND'] = $this->rcon(['ip' => $config['ip'], 'port' => $config['data']['rcon_port'], 'password' => $config['data']['rcon_password']], $method['RUN_COMMAND']) !== false; + } + $methodsName = array_delete_value($methodsName, 'RUN_COMMAND'); + } + + if (count($methodsName) > 0) { + $ping = $this->ping(array('ip' => $config['ip'], 'port' => $config['port'])); + foreach ($methods as $key => $method) { + $name = array_keys($method)[0]; + if (isset($ping[$name])) + $result[$key][$name] = $ping[$name]; + } + } + + if (!$multi) { + $parsedResult = []; + foreach ($result as $item) { + foreach ($item as $key => $value) { + $parsedResult[$key] = $value; + } + } + $result = $parsedResult; + } + return $result; + } + // plugin $url = $this->getUrl($server_id); $data = $this->encryptWithKey(json_encode($this->parse($methods))); @@ -217,7 +240,12 @@ public function getConfig($server_id = false) if (empty($search)) return $this->config[$server_id] = false; - return $this->config[$server_id] = array('ip' => $search['Server']['ip'], 'port' => $search['Server']['port'], 'type' => $search['Server']['type']); + return $this->config[$server_id] = array( + 'ip' => $search['Server']['ip'], + 'port' => $search['Server']['port'], + 'type' => $search['Server']['type'], + 'data' => json_decode($search['Server']['data'], true) + ); } public function ping($config = false) @@ -236,7 +264,24 @@ public function ping($config = false) } $Query->Close(); - return (isset($Info['players'])) ? array('getMOTD' => $Info['description'], 'getVersion' => $Info['version']['name'], 'GET_PLAYER_COUNT' => $Info['players']['online'], 'GET_MAX_PLAYERS' => $Info['players']['max']) : false; + return (isset($Info['players'])) ? array( + 'GET_MOTD' => $Info['description'], + 'GET_VERSION' => $Info['version']['name'], + 'GET_PLAYER_COUNT' => $Info['players']['online'], + 'GET_MAX_PLAYERS' => $Info['players']['max']) : false; + } + + public function rcon($config = false, $cmd = '') + { + if (!$config || !isset($config['ip']) || !isset($config['port']) || !isset($config['password'])) + return false; + + App::import('Vendor', 'Rcon', array('file' => 'rcon/Rcon.php')); + + $rcon = new Thedudeguy\Rcon($config['ip'], $config['port'], $config['password'], $this->getTimeout()); + if ($rcon->connect()) + return $rcon->sendCommand($cmd); + return false; } public function getUrl($server_id) @@ -265,8 +310,8 @@ public function online($server_id = false, $debug = false) if (!$config) // server not found return $this->online[$server_id] = false; - if ($config['type'] == 1) // ping only - return ($this->ping(array('ip' => $config['ip'], 'port' => $config['port']))) ? true : false; + if ($config['type'] == 1 || $config['type'] == 2) // ping only + return $this->online[$server_id] = ($this->ping(array('ip' => $config['ip'], 'port' => $config['port']))) ? true : false; list($return, $code, $error) = $this->request($this->getUrl($server_id), $this->encryptWithKey("[]")); if ($return && $code === 200) @@ -375,7 +420,7 @@ public function banner_infos($serverId = false) 'GET_MAX_PLAYERS' => 0 ); foreach ($serverId as $id) { - $req = $this->call(array('GET_PLAYER_COUNT' => array(), 'GET_MAX_PLAYERS' => array()), $id); + $req = $this->call(['GET_PLAYER_COUNT' => [], 'GET_MAX_PLAYERS' => []], $id); if (!$req) continue; $data['GET_PLAYER_COUNT'] += intval($req['GET_PLAYER_COUNT']); $data['GET_MAX_PLAYERS'] += intval($req['GET_MAX_PLAYERS']); @@ -393,7 +438,11 @@ public function banner_infos($serverId = false) public function userIsConnected($username, $server_id = false) { $result = $this->call(['IS_CONNECTED' => $username], $server_id); - return ($result && isset($result['IS_CONNECTED']) && $result['IS_CONNECTED']); + if ($result && isset($result['IS_CONNECTED']) && $result['IS_CONNECTED']) + return true; + else if (!isset($result['IS_CONNECTED'])) + return true; + return false; } public function send_command($cmd, $server_id = false) diff --git a/app/Controller/ServerController.php b/app/Controller/ServerController.php index 3251dfd8..4800d7ab 100755 --- a/app/Controller/ServerController.php +++ b/app/Controller/ServerController.php @@ -25,6 +25,9 @@ public function admin_link() } } + foreach ($servers as $key => $value) + $servers[$key]['Server']['data'] = json_decode($servers[$key]['Server']['data'], true); + $bannerMsg = $this->Lang->get('SERVER__STATUS_MESSAGE'); $this->set(compact('servers', 'bannerMsg')); @@ -195,6 +198,9 @@ public function admin_link_ajax() else if ($this->request->data['type'] == 1) { if (!$this->Server->ping(array('ip' => $this->request->data['host'], 'port' => $this->request->data['port']))) return $this->response->body(json_encode(array('statut' => false, 'msg' => $this->Lang->get('SERVER__LINK_FAILED')))); + } else if ($this->request->data['type'] == 2) { + if (!$this->Server->rcon(array('ip' => $this->request->data['host'], 'port' => $this->request->data['server_data']['rcon_port'], 'password' => $this->request->data['server_data']['rcon_password']), 'say ' . $this->Lang->get('SERVER__LINK_SUCCESS'))) + return $this->response->body(json_encode(array('statut' => false, 'msg' => $this->Lang->get('SERVER__LINK_FAILED')))); } else { return $this->response->body(json_encode(array('statut' => false, 'msg' => $this->Lang->get('ERROR__FILL_ALL_FIELDS')))); } @@ -205,10 +211,16 @@ public function admin_link_ajax() $this->loadModel('Server'); $this->Server->read(null, $id); - $this->Server->set(array('name' => $this->request->data['name'], 'ip' => $this->request->data['host'], 'port' => $this->request->data['port'], 'type' => $this->request->data['type'])); + $this->Server->set(array( + 'name' => $this->request->data['name'], + 'ip' => $this->request->data['host'], + 'port' => $this->request->data['port'], + 'type' => $this->request->data['type'], + 'data' => json_encode($this->request->data['server_data']) + )); $this->Server->save(); - if ($this->request->data['type'] != 1 && $secretKey) + if ($this->request->data['type'] == 0 && isset($secretKey) && $secretKey) $this->Configuration->setKey('server_secretkey', $secretKey); return $this->response->body(json_encode(array('statut' => true, 'msg' => $this->Lang->get('SERVER__LINK_SUCCESS')))); diff --git a/app/Controller/UserController.php b/app/Controller/UserController.php index 2524329c..54ac7451 100755 --- a/app/Controller/UserController.php +++ b/app/Controller/UserController.php @@ -766,10 +766,6 @@ function admin_edit_ajax() $data['money'] = $this->request->data['money']; } - if ($this->EyPlugin->isInstalled('eywek.vote.3')) { - $data['vote'] = $this->request->data['vote']; - } - $event = new CakeEvent('beforeEditUser', $this, array('user_id' => $findUser['User']['id'], 'data' => $data, 'password_updated' => $password_updated)); $this->getEventManager()->dispatch($event); if ($event->isStopped()) { diff --git a/app/Model/Server.php b/app/Model/Server.php index eb58cf7b..5680b1bc 100755 --- a/app/Model/Server.php +++ b/app/Model/Server.php @@ -1,15 +1,21 @@ find('all', array('conditions' => array('type' => 0))); - if (empty($search_servers)) - return array(); - - $servers = array(); - foreach ($search_servers as $server) - $servers[$server['Server']['id']] = $server['Server']['name']; - return $servers; - } + +class Server extends AppModel +{ + + public function findSelectableServers($rcon = true) + { + $types = [0]; + if ($rcon) + $types = [0, 2]; + $search_servers = $this->find('all', array('conditions' => array('type' => $types))); + if (empty($search_servers)) + return array(); + + $servers = array(); + foreach ($search_servers as $server) + $servers[$server['Server']['id']] = $server['Server']['name']; + return $servers; + } } diff --git a/app/Plugin/Shop b/app/Plugin/Shop index 8796734f..482851ce 160000 --- a/app/Plugin/Shop +++ b/app/Plugin/Shop @@ -1 +1 @@ -Subproject commit 8796734f92eefcd0fdc398edeabd3a95c61ccafa +Subproject commit 482851ce73d488435a21f170a7c20d4e94269c64 diff --git a/app/Plugin/Vote b/app/Plugin/Vote index bc5b6e65..d868dcb4 160000 --- a/app/Plugin/Vote +++ b/app/Plugin/Vote @@ -1 +1 @@ -Subproject commit bc5b6e65f45aa34558a65ec5be719e70cb6b787a +Subproject commit d868dcb45d3f1193bfc51ce88272ac559c823408 diff --git a/app/View/Server/admin_link.ctp b/app/View/Server/admin_link.ctp index a6b9d922..f072f19d 100755 --- a/app/View/Server/admin_link.ctp +++ b/app/View/Server/admin_link.ctp @@ -72,6 +72,7 @@ @@ -87,9 +88,21 @@
- +
+ +
+ + +
+ +
+ + +
+ + get('GLOBAL__DELETE') ?> @@ -134,21 +147,38 @@ function initSelectInfos() { }) } $('select[name="type"]').each(function () { - selectInfos($(this)) + selectInfos($(this), true) }) -function selectInfos(select) { - var type = select.val() - - var infosDiv = select.parent().find('.infos-type') - if (infosDiv) - infosDiv.remove() - - if (type == 0) - var infos = '
get('SERVER__TYPE_DEFAULT_INFOS')) ?>
' - else - var infos = '
get('SERVER__TYPE_QUERY_INFOS')) ?>
' +function selectInfos(select, init) { + var type = select.val() + + var infosDiv = select.parent().find('.infos-type') + if (infosDiv) + infosDiv.remove() + + if (type == 0) { + var infos = '
get('SERVER__TYPE_DEFAULT_INFOS')) ?>
' + select.parent().parent().find('input[name="server_data[rcon_port]"]').parent().remove() + select.parent().parent().find('input[name="server_data[rcon_password]"]').parent().remove() + } else if (type == 1) { + var infos = '
get('SERVER__TYPE_QUERY_INFOS')) ?>
' + select.parent().parent().find('input[name="server_data[rcon_port]"]').parent().remove() + select.parent().parent().find('input[name="server_data[rcon_password]"]').parent().remove() + } else if (type == 2) { + var infos = '
get('SERVER__TYPE_RCON_INFOS')) ?>
' + var new_server = '
'; + new_server += ''; + new_server += ''; + new_server += '
'; + new_server += '
'; + new_server += ''; + new_server += ''; + new_server += '
'; + if (!init) + $(new_server).insertBefore($(select.parent().parent().find('button')[0])) + } - $('

' + infos + '
').insertAfter(select) + $('

' + infos + '
').insertAfter(select) } var i = 0; @@ -168,6 +198,7 @@ $("#add_server").click(function() { new_server += ''; new_server += ''; new_server += '
'; @@ -180,7 +211,7 @@ $("#add_server").click(function() { new_server += '
'; new_server += '
'; new_server += ''; - new_server += ''; + new_server += ''; new_server += '
'; new_server += ''; new_server += ''; diff --git a/app/View/User/admin_edit.ctp b/app/View/User/admin_edit.ctp index b9f27f71..dd38df02 100755 --- a/app/View/User/admin_edit.ctp +++ b/app/View/User/admin_edit.ctp @@ -53,14 +53,6 @@ - isInstalled('eywek.vote.3')) { ?> -
- - -
- - -
diff --git a/lang/fr_FR.json b/lang/fr_FR.json index bd96bc38..ba6e19a8 100755 --- a/lang/fr_FR.json +++ b/lang/fr_FR.json @@ -483,10 +483,14 @@ "SERVER__TYPE": "Type de la connexion", "SERVER__TYPE_DEFAULT": "Par défaut", "SERVER__TYPE_QUERY": "Ping (pas besoin de plugin)", + "SERVER__TYPE_RCON": "RCON (pas besoin de plugin)", "SERVER__TYPE_DEFAULT_INFOS": "Vous avez besoin d'installer le plugin MineWebBridge sur votre serveur pour utiliser ce type de liaison. Toutes les informations relatives à cette manipulation sont disponible sur la documentation", "SERVER__TYPE_QUERY_INFOS": "Vous n'avez pas besoin d'installer le plugin MineWebBridge sur votre serveur pour utiliser ce type de liaison. Ce type de liaison vous permet seulement d'afficher le nombre de connectés sur votre infrastructure. Toutes les informations relatives à cette manipulation sont disponible sur la documentation", + "SERVER__TYPE_RCON_INFOS": "some explanation", "SERVER__HOST":"IP du serveur", "SERVER__PORT":"Port", + "SERVER__RCON_PASSWORD": "Mot de passe RCON", + "SERVER__RCON_PORT": "Port RCON", "SERVER__TIMEOUT":"Temps maximum d'éxécution", "SERVER__LINK_SUCCESS":"La connexion au serveur a bien été établie !", "SERVER__LINK_ERROR_MINEWEB_DOWN":"L'API de MineWeb est indisponible.", @@ -514,7 +518,7 @@ "SERVER__MUST_BE_ON":"Le serveur doit être allumé pour effectuer cette action.", "SERVER__STATUS_OFF":"Le serveur est éteint", "SERVER__DELETE_SERVER_SUCCESS":"Le serveur a bien été supprimé !", - "SERVER__STATUS_MESSAGE":"{MOTD} - {VERSION}. Il y a {ONLINE} connectés sur {ONLINE_LIMIT}.", + "SERVER__STATUS_MESSAGE":"Il y a {ONLINE} connectés sur {ONLINE_LIMIT}.", "SERVER__PARSE_NEW_COMMAND":"Pour une nouvelle commande", "SERVER__SUCCESS_SWITCH":"Vous avez bien changé l'état de la fonctionnalité serveur.", "SERVER__DISABLE_SERVER":"Désactiver la fonctionnalité",