فهرست منبع

Pre-added RUST

The necessary files and directories have been created
Sergei Solovev 1 سال پیش
والد
کامیت
33f3660fcc
79فایلهای تغییر یافته به همراه5192 افزوده شده و 13 حذف شده
  1. 32 1
      enginegp.sql
  2. 2 2
      system/acp/engine/index.php
  3. 4 0
      system/acp/engine/servers.php
  4. 75 0
      system/acp/sections/servers/rust.php
  5. 1 1
      system/acp/sections/tarifs/add.php
  6. 1 1
      system/acp/sections/tarifs/copy.php
  7. 3 3
      system/acp/sections/tarifs/tarif.php
  8. 3 1
      system/acp/sections/units/add.php
  9. 4 2
      system/acp/sections/units/unit.php
  10. 1 0
      system/data/acpengine.php
  11. 17 1
      system/data/config.php
  12. 4 0
      system/data/engine.php
  13. 20 0
      system/data/filedits.php
  14. 26 0
      system/data/params.php
  15. 2 1
      system/engine/services.php
  16. 2 0
      system/library/cron.php
  17. 295 0
      system/library/games/rust/action.php
  18. 109 0
      system/library/games/rust/rcon.php
  19. 135 0
      system/library/games/rust/scan.php
  20. 354 0
      system/library/games/rust/service.php
  21. 220 0
      system/library/games/rust/tarif.php
  22. 63 0
      system/sections/servers/rust/console.php
  23. 80 0
      system/sections/servers/rust/copy.php
  24. 68 0
      system/sections/servers/rust/graph.php
  25. 44 0
      system/sections/servers/rust/index.php
  26. 94 0
      system/sections/servers/rust/maps.php
  27. 69 0
      system/sections/servers/rust/maps/delete.php
  28. 55 0
      system/sections/servers/rust/maps/install.php
  29. 61 0
      system/sections/servers/rust/maps/list.php
  30. 90 0
      system/sections/servers/rust/maps/listing.php
  31. 59 0
      system/sections/servers/rust/maps/search.php
  32. 165 0
      system/sections/servers/rust/owners.php
  33. 149 0
      system/sections/servers/rust/plugins.php
  34. 51 0
      system/sections/servers/rust/rcon.php
  35. 74 0
      system/sections/servers/rust/settings.php
  36. 110 0
      system/sections/servers/rust/settings/admins.php
  37. 154 0
      system/sections/servers/rust/settings/bans.php
  38. 28 0
      system/sections/servers/rust/settings/debug.php
  39. 86 0
      system/sections/servers/rust/settings/logs.php
  40. 113 0
      system/sections/servers/rust/settings/server.php
  41. 86 0
      system/sections/servers/rust/settings/smlogs.php
  42. 164 0
      system/sections/servers/rust/settings/start.php
  43. 12 0
      system/sections/servers/rust/tarif.php
  44. 50 0
      system/sections/servers/rust/tarif/extend.php
  45. 64 0
      system/sections/servers/rust/tarif/plan.php
  46. 33 0
      system/sections/servers/rust/tarif/slots.php
  47. 50 0
      system/sections/servers/rust/tarif/unit.php
  48. 81 0
      system/sections/servers/rust/web.php
  49. 145 0
      system/sections/services/rust.php
  50. 5 0
      template/acp/main.html
  51. 1 0
      template/acp/sections/servers/menu.html
  52. 1 0
      template/acp/sections/tarifs/add.html
  53. 4 0
      template/acp/sections/units/add.html
  54. 4 0
      template/acp/sections/units/unit.html
  55. 64 0
      template/js/sections/services/rust.js
  56. 6 0
      template/sections/servers/players/rust.html
  57. 4 0
      template/sections/servers/rust/change_list.html
  58. 151 0
      template/sections/servers/rust/console.html
  59. 86 0
      template/sections/servers/rust/copy.html
  60. 44 0
      template/sections/servers/rust/gmenu.html
  61. 157 0
      template/sections/servers/rust/index.html
  62. 78 0
      template/sections/servers/rust/maps/listing.html
  63. 18 0
      template/sections/servers/rust/maps/map_server.html
  64. 63 0
      template/sections/servers/rust/maps/types.html
  65. 108 0
      template/sections/servers/rust/owners.html
  66. 75 0
      template/sections/servers/rust/rcon.html
  67. 18 0
      template/sections/servers/rust/rcon/player.html
  68. 138 0
      template/sections/servers/rust/settings.html
  69. 43 0
      template/sections/servers/rust/settings/admins.html
  70. 16 0
      template/sections/servers/rust/settings/admins/list.html
  71. 68 0
      template/sections/servers/rust/settings/bans.html
  72. 151 0
      template/sections/servers/rust/settings/crontab.html
  73. 0 0
      template/sections/servers/rust/settings/crontab/list.html
  74. 23 0
      template/sections/servers/rust/settings/servercfg.html
  75. 92 0
      template/sections/servers/rust/settings/start.html
  76. 38 0
      template/sections/servers/rust/vmenu.html
  77. 1 0
      template/sections/servers/rust/web.html
  78. 120 0
      template/sections/services/games/rust.html
  79. 7 0
      template/sections/services/index.html

+ 32 - 1
enginegp.sql

@@ -157,6 +157,25 @@ CREATE TABLE `admins_cssold` (
 
 -- --------------------------------------------------------
 
+--
+-- Структура таблицы `admins_rust`
+--
+
+CREATE TABLE `admins_rust` (
+  `id` int(11) NOT NULL,
+  `server` int(11) NOT NULL,
+  `active` tinyint(1) NOT NULL,
+  `value` varchar(50) NOT NULL,
+  `passwd` char(32) NOT NULL,
+  `flags` varchar(50) NOT NULL,
+  `immunity` int(11) NOT NULL,
+  `time` int(11) NOT NULL,
+  `text` varchar(100) NOT NULL,
+  `info` varchar(100) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
 --
 -- Структура таблицы `admins_mc`
 --
@@ -1286,13 +1305,14 @@ CREATE TABLE `units` (
   `sql_ftp` char(20) NOT NULL,
   `cs` tinyint(1) NOT NULL DEFAULT '0',
   `cssold` tinyint(1) NOT NULL DEFAULT '0',
+  `rust` tinyint(1) NOT NULL DEFAULT '0',
   `css` tinyint(1) NOT NULL DEFAULT '0',
   `csgo` tinyint(1) NOT NULL DEFAULT '0',
   `cs2` tinyint(1) NOT NULL DEFAULT '0',
   `samp` tinyint(1) NOT NULL DEFAULT '0',
   `crmp` tinyint(1) NOT NULL DEFAULT '0',
   `mta` tinyint(1) NOT NULL DEFAULT '0',
-  `mc` tinyint(1) NOT NULL DEFAULT '0',
+  `mc` tinyint(1) NOT NULL DEFAULT '0',,
   `ram` int(11) NOT NULL,
   `test` int(11) NOT NULL,
   `show` tinyint(1) NOT NULL,
@@ -1459,6 +1479,12 @@ ALTER TABLE `admins_css`
 ALTER TABLE `admins_cssold`
   ADD PRIMARY KEY (`id`);
 
+--
+-- Индексы таблицы `admins_rust`
+--
+ALTER TABLE `admins_rust`
+  ADD PRIMARY KEY (`id`);
+
 --
 -- Индексы таблицы `admins_mc`
 --
@@ -1924,6 +1950,11 @@ ALTER TABLE `admins_css`
 ALTER TABLE `admins_cssold`
   MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
 --
+-- AUTO_INCREMENT для таблицы `admins_rust`
+--
+ALTER TABLE `admins_rust`
+    MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
+--
 -- AUTO_INCREMENT для таблицы `admins_mc`
 --
 ALTER TABLE `admins_mc`

+ 2 - 2
system/acp/engine/index.php

@@ -35,8 +35,8 @@ if ($html->arr['main'] == '') {
     $sql->query('SELECT `id`, `game`, `slots` FROM `servers`');
     $servers = $sql->num();
 
-    $aSlots = array('cs' => 0, 'cssold' => 0, 'css' => 0, 'csgo' => 0, 'cs2' => 0, 'samp' => 0, 'crmp' => 0, 'mta' => 0, 'mc' => 0);
-    $aServers = array('cs' => 0, 'cssold' => 0, 'css' => 0, 'csgo' => 0, 'cs2' => 0, 'samp' => 0, 'crmp' => 0, 'mta' => 0, 'mc' => 0);
+    $aSlots = array('cs' => 0, 'cssold' => 0, 'css' => 0, 'csgo' => 0, 'cs2' => 0, 'rust' => 0, 'samp' => 0, 'crmp' => 0, 'mta' => 0, 'mc' => 0);
+    $aServers = array('cs' => 0, 'cssold' => 0, 'css' => 0, 'csgo' => 0, 'cs2' => 0, 'rust' => 0, 'samp' => 0, 'crmp' => 0, 'mta' => 0, 'mc' => 0);
 
     while ($server = $sql->get()) {
         $aSlots[$server['game']] += $server['slots'];

+ 4 - 0
system/acp/engine/servers.php

@@ -11,6 +11,7 @@ $aSection = array(
     'css',
     'csgo',
     'cs2',
+    'rust',
     'samp',
     'crmp',
     'mta',
@@ -52,6 +53,9 @@ $html->set('csgo', $sql->num());
 $sql->query('SELECT `id` FROM `servers` WHERE `user`!="-1" AND `game`="cs2"');
 $html->set('cs2', $sql->num());
 
+$sql->query('SELECT `id` FROM `servers` WHERE `user`!="-1" AND `game`="rust"');
+$html->set('rust', $sql->num());
+
 $sql->query('SELECT `id` FROM `servers` WHERE `user`!="-1" AND `game`="samp"');
 $html->set('samp', $sql->num());
 

+ 75 - 0
system/acp/sections/servers/rust.php

@@ -0,0 +1,75 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+if ($id)
+    include(SEC . 'servers/server.php');
+else {
+    $list = '';
+
+    $status = array(
+        'working' => '<span class="text-green">Работает</span>',
+        'off' => '<span class="text-red">Выключен</span>',
+        'start' => 'Запускается',
+        'restart' => 'Перезапускается',
+        'change' => 'Смена карты',
+        'install' => 'Устанавливается',
+        'reinstall' => 'Переустанавливается',
+        'update' => 'Обновляется',
+        'recovery' => 'Восстанавливается',
+        'overdue' => 'Просрочен',
+        'blocked' => 'Заблокирован'
+    );
+
+    $select = 'WHERE `user`!="-1"';
+    $url_search = '';
+
+    if (isset($url['search']) and in_array($url['search'], array('unit', 'tarif'))) {
+        $select = 'WHERE `' . $url['search'] . '`="' . sys::int($url[$url['search']]) . '" AND `user`!="-1"';
+        $url_search = '/search/' . $url['search'] . '/' . $url['search'] . '/' . $url[$url['search']];
+    }
+
+    $sql->query('SELECT `id` FROM `servers` ' . $select . ' AND `game`="rust"');
+
+    $aPage = sys::page($page, $sql->num(), 20);
+
+    sys::page_gen($aPage['ceil'], $page, $aPage['page'], 'acp/servers/section/rust' . $url_search);
+
+    $servers = $sql->query('SELECT `id`, `unit`, `tarif`, `user`, `address`, `game`, `status`, `slots`, `name`, `time` FROM `servers` ' . $select . ' AND `game`="rust" ORDER BY `id` ASC LIMIT ' . $aPage['num'] . ', 20');
+    while ($server = $sql->get($servers)) {
+        $sql->query('SELECT `name` FROM `units` WHERE `id`="' . $server['unit'] . '" LIMIT 1');
+        $unit = $sql->get();
+
+        $sql->query('SELECT `name` FROM `tarifs` WHERE `id`="' . $server['tarif'] . '" LIMIT 1');
+        $tarif = $sql->get();
+
+        $list .= '<tr>';
+        $list .= '<td class="text-center">' . $server['id'] . '</td>';
+        $list .= '<td><a href="' . $cfg['http'] . 'acp/servers/id/' . $server['id'] . '">' . $server['name'] . '</a></td>';
+        $list .= '<td><a href="' . $cfg['http'] . 'acp/servers/search/unit/unit/' . $server['unit'] . '">#' . $server['unit'] . ' ' . $unit['name'] . '</a></td>';
+        $list .= '<td class="text-center">' . $server['slots'] . ' шт.</td>';
+        $list .= '<td class="text-center">' . strtoupper($server['game']) . '</td>';
+        $list .= '<td class="text-center"><a href="' . $cfg['http'] . 'servers/id/' . $server['id'] . '" target="_blank">Перейти</a></td>';
+        $list .= '</tr>';
+
+        $list .= '<tr>';
+        $list .= '<td class="text-center"><a href="' . $cfg['http'] . 'acp/users/id/' . $server['user'] . '">USER_' . $server['user'] . '</a></td>';
+        $list .= '<td>' . $server['address'] . '</td>';
+        $list .= '<td><a href="' . $cfg['http'] . 'acp/servers/search/tarif/tarif/' . $server['tarif'] . '">#' . $server['tarif'] . ' ' . $tarif['name'] . '</a></td>';
+        $list .= '<td class="text-center">' . $status[$server['status']] . '</td>';
+        $list .= '<td class="text-center">' . date('d.m.Y - H:i:s', $server['time']) . '</td>';
+        $list .= '<td class="text-center"><a href="#" onclick="return servers_delete(\'' . $server['id'] . '\')" class="text-red">Удалить</a></td>';
+        $list .= '</tr>';
+    }
+
+    $html->get('index', 'sections/servers');
+
+    $html->set('list', $list);
+
+    $html->set('url_search', $url_search);
+
+    $html->set('pages', isset($html->arr['pages']) ? $html->arr['pages'] : '');
+
+    $html->pack('main');
+}
+?>

+ 1 - 1
system/acp/sections/tarifs/add.php

@@ -47,7 +47,7 @@ if ($go) {
     if (!$sql->num())
         sys::outjs(array('e' => 'Необходимо указать локацию'));
 
-    if (!in_array($aData['game'], array('cs', 'cssold', 'css', 'csgo', 'cs2', 'samp', 'crmp', 'mta', 'mc')))
+    if (!in_array($aData['game'], array('cs', 'cssold', 'css', 'csgo', 'cs2', 'rust', 'samp', 'crmp', 'mta', 'mc')))
         sys::outjs(array('e' => 'Необходимо указать игру'));
 
     $aSlots = explode('-', $aData['slots']);

+ 1 - 1
system/acp/sections/tarifs/copy.php

@@ -6,7 +6,7 @@ $sql->query('SELECT * FROM `tarifs` WHERE `id`="' . $id . '" LIMIT 1');
 $tarif = $sql->get();
 
 $games = '<option value="cs">Counter-Strike: 1.6</option><option value="cssold">Counter-Strike: Source v34</option><option value="css">Counter-Strike: Source</option>'
-    . '<option value="csgo">Counter-Strike: Global Offensive</option><option value="cs2">Counter-Strike: 2</option><option value="samp">San Andreas Multiplayer</option><option value="crmp">GTA: Criminal Russia</option>'
+    . '<option value="csgo">Counter-Strike: Global Offensive</option><option value="cs2">Counter-Strike: 2</option><option value="rust">RUST</option><option value="samp">San Andreas Multiplayer</option><option value="crmp">GTA: Criminal Russia</option>'
     . '<option value="mta">Multi Theft Auto</option><option value="mc">Minecraft</option>';
 
 $fix = $tarif['param_fix'] ? '<option value="1">Фиксированные параметры</option><option value="0">Не фиксированные параметры</option>' : '<option value="0">Не фиксированные параметры</option><option value="1">Фиксированные параметры</option>';

+ 3 - 3
system/acp/sections/tarifs/tarif.php

@@ -50,7 +50,7 @@ if ($go) {
     if (!$sql->num())
         sys::outjs(array('e' => 'Необходимо указать локацию'));
 
-    if (!in_array($aData['game'], array('cs', 'cssold', 'css', 'csgo', 'cs2', 'samp', 'crmp', 'mta', 'mc')))
+    if (!in_array($aData['game'], array('cs', 'cssold', 'css', 'csgo', 'cs2', 'rust', 'samp', 'crmp', 'mta', 'mc')))
         sys::outjs(array('e' => 'Необходимо указать игру'));
 
     $aSlots = explode('-', $aData['slots']);
@@ -84,7 +84,7 @@ if ($go) {
     if ($aData['install'] == '')
         sys::outjs(array('e' => 'Необходимо указать путь для установки серверов'));
 
-    if ($aData['update'] == '' and !in_array($aData['game'], array('css', 'csgo', 'cs2')))
+    if ($aData['update'] == '' and !in_array($aData['game'], array('css', 'csgo', 'cs2', 'rust')))
         sys::outjs(array('e' => 'Необходимо указать путь до обновления сборки'));
 
     if (substr($aData['path'], -1) != '/' || substr($aData['install'], -1) != '/' || (substr($aData['update'], -1) != '/' and !in_array($aData['game'], array('css', 'csgo'))))
@@ -391,7 +391,7 @@ if ($go) {
 }
 
 $games = '<option value="cs">Counter-Strike: 1.6</option><option value="cssold">Counter-Strike: Source v34</option><option value="css">Counter-Strike: Source</option>'
-    . '<option value="csgo">Counter-Strike: Global Offensive</option><option value="cs2">Counter-Strike: 2</option><option value="samp">San Andreas Multiplayer</option><option value="crmp">GTA: Criminal Russia</option>'
+    . '<option value="csgo">Counter-Strike: Global Offensive</option><option value="cs2">Counter-Strike: 2</option><option value="rust">RUST</option><option value="samp">San Andreas Multiplayer</option><option value="crmp">GTA: Criminal Russia</option>'
     . '<option value="mta">Multi Theft Auto</option><option value="mc">Minecraft</option>';
 
 $fix = $tarif['param_fix'] ? '<option value="1">Фиксированные параметры</option><option value="0">Не фиксированные параметры</option>' : '<option value="0">Не фиксированные параметры</option><option value="1">Фиксированные параметры</option>';

+ 3 - 1
system/acp/sections/units/add.php

@@ -17,6 +17,7 @@ if ($go) {
     $aData['css'] = isset($_POST['css']) ? $_POST['css'] : 0;
     $aData['csgo'] = isset($_POST['csgo']) ? $_POST['csgo'] : 0;
     $aData['cs2'] = isset($_POST['cs2']) ? $_POST['cs2'] : 0;
+    $aData['rust'] = isset($_POST['rust']) ? $_POST['rust'] : 0;
     $aData['samp'] = isset($_POST['samp']) ? $_POST['samp'] : 0;
     $aData['crmp'] = isset($_POST['crmp']) ? $_POST['crmp'] : 0;
     $aData['mta'] = isset($_POST['mta']) ? $_POST['mta'] : 0;
@@ -27,7 +28,7 @@ if ($go) {
     $aData['sort'] = isset($_POST['sort']) ? sys::int($_POST['sort']) : 0;
     $aData['domain'] = isset($_POST['domain']) ? trim($_POST['domain']) : '';
 
-    foreach (array('cs', 'cssold', 'css', 'csgo', 'cs2', 'samp', 'crmp', 'mta', 'mc') as $game)
+    foreach (array('cs', 'cssold', 'css', 'csgo', 'cs2', 'rust', 'samp', 'crmp', 'mta', 'mc') as $game)
         $aData[$game] = (string)$aData[$game] == 'on' ? '1' : '0';
 
     if (in_array('', $aData))
@@ -51,6 +52,7 @@ if ($go) {
         . '`css`="' . $aData['css'] . '",'
         . '`csgo`="' . $aData['csgo'] . '",'
         . '`cs2`="' . $aData['cs2'] . '",'
+        . '`rust`="' . $aData['rust'] . '",'
         . '`samp`="' . $aData['samp'] . '",'
         . '`crmp`="' . $aData['crmp'] . '",'
         . '`mta`="' . $aData['mta'] . '",'

+ 4 - 2
system/acp/sections/units/unit.php

@@ -20,6 +20,7 @@ if ($go) {
     $aData['css'] = isset($_POST['css']) ? $_POST['css'] : $unit['css'];
     $aData['csgo'] = isset($_POST['csgo']) ? $_POST['csgo'] : $unit['csgo'];
     $aData['cs2'] = isset($_POST['cs2']) ? $_POST['cs2'] : $unit['cs2'];
+    $aData['rust'] = isset($_POST['rust']) ? $_POST['rust'] : $unit['rust'];
     $aData['samp'] = isset($_POST['samp']) ? $_POST['samp'] : $unit['samp'];
     $aData['crmp'] = isset($_POST['crmp']) ? $_POST['crmp'] : $unit['crmp'];
     $aData['mta'] = isset($_POST['mta']) ? $_POST['mta'] : $unit['mta'];
@@ -30,7 +31,7 @@ if ($go) {
     $aData['sort'] = isset($_POST['sort']) ? sys::int($_POST['sort']) : $unit['sort'];
     $aData['domain'] = isset($_POST['domain']) ? trim($_POST['domain']) : $unit['domain'];
 
-    foreach (array('cs', 'cssold', 'css', 'csgo', 'cs2', 'samp', 'crmp', 'mta', 'mc') as $game)
+    foreach (array('cs', 'cssold', 'css', 'csgo', 'cs2', 'rust', 'samp', 'crmp', 'mta', 'mc') as $game)
         $aData[$game] = (string)$aData[$game] == 'on' ? '1' : '0';
 
     if (in_array('', $aData))
@@ -54,6 +55,7 @@ if ($go) {
         . '`css`="' . $aData['css'] . '",'
         . '`csgo`="' . $aData['csgo'] . '",'
         . '`cs2`="' . $aData['cs2'] . '",'
+        . '`rust`="' . $aData['rust'] . '",'
         . '`samp`="' . $aData['samp'] . '",'
         . '`crmp`="' . $aData['crmp'] . '",'
         . '`mta`="' . $aData['mta'] . '",'
@@ -72,7 +74,7 @@ $html->get('unit', 'sections/units');
 foreach ($unit as $i => $val)
     $html->set($i, $val);
 
-foreach (array('cs', 'cssold', 'css', 'csgo', 'cs2', 'samp', 'crmp', 'mta', 'mc') as $game) {
+foreach (array('cs', 'cssold', 'css', 'csgo', 'cs2', 'rust', 'samp', 'crmp', 'mta', 'mc') as $game) {
     if ($unit[$game])
         $html->unit('game_' . $game, 1);
     else

+ 1 - 0
system/data/acpengine.php

@@ -46,6 +46,7 @@ $aGname = array(
     'cssold' => 'CS: Source v34',
     'csgo' => 'CS: Global Offensive',
     'cs2' => 'CS: 2',
+    'rust' => 'RUST',
     'mc' => 'MineCraft',
     'mta' => 'GTA: MTA',
     'samp' => 'GTA: SAMP'

+ 17 - 1
system/data/config.php

@@ -128,6 +128,7 @@ $cfg = array(
         'css' => '60',
         'csgo' => '60',
         'cs2' => '60',
+        'rust' => '60',
         'samp' => '60',
         'crmp' => '60',
         'mta' => '60',
@@ -140,7 +141,8 @@ $cfg = array(
         'cssold' => '60',
         'css' => '60',
         'csgo' => '60',
-        'cs2' => '60'
+        'cs2' => '60',
+        'rust' => '60'
     ),
 
     // RAM на 1 слот
@@ -150,6 +152,7 @@ $cfg = array(
         'css' => '32',
         'csgo' => '32',
         'cs2' => '32',
+        'rust' => '32',
         'samp' => '32',
         'crmp' => '32',
         'mta' => '32'
@@ -162,6 +165,7 @@ $cfg = array(
         'css' => '99',
         'csgo' => '99',
         'cs2' => '99',
+        'rust' => '99',
         'samp' => '99',
         'crmp' => '99',
         'mta' => '99',
@@ -174,6 +178,7 @@ $cfg = array(
         'css' => '99',
         'csgo' => '99',
         'cs2' => '99',
+        'rust' => '99',
         'samp' => '99',
         'crmp' => '99',
         'mta' => '99',
@@ -189,6 +194,7 @@ $cfg = array(
             'css' => false,
             'csgo' => false,
             'cs2' => false,
+            'rust' => false,
             'samp' => false,
             'crmp' => false,
             'mta' => false,
@@ -202,6 +208,7 @@ $cfg = array(
             'css' => '/cstrike',
             'csgo' => '/csgo',
             'cs2' => '/csgo',
+            'rust' => '/',
             'samp' => '/',
             'crmp' => '/',
             'mta' => '/mods/deathmatch',
@@ -215,6 +222,7 @@ $cfg = array(
             'css' => '/cstrike',
             'csgo' => '/csgo',
             'cs2' => '/game',
+            'rust' => '/',
             'samp' => '/',
             'crmp' => '/',
             'mta' => '/mods/deathmatch',
@@ -254,6 +262,12 @@ $cfg = array(
             'add' => true // Если 'down == true', то при уменьшении кол-во слот, добавлять дни к аренде
         ),
 
+        'rust' => array(
+            'days' => false, // При смене кол-ва слот вычитывать/добавлять дни аренды (add == true), если false, то смена (увеличение) на платной основе
+            'down' => true, // Если 'days == true', то дать возможность уменьшать слоты
+            'add' => true // Если 'down == true', то при уменьшении кол-во слот, добавлять дни к аренде
+        ),
+
         'samp' => array(
             'days' => true, // При смене кол-ва слот вычитывать/добавлять дни аренды (add == true), если false, то смена (увеличение) на платной основе
             'down' => true, // Если 'days == true', то дать возможность уменьшать слоты
@@ -286,6 +300,7 @@ $cfg = array(
         'css' => false,
         'csgo' => false,
         'cs2' => false,
+        'rust' => false,
         'samp' => false,
         'crmp' => false,
         'mta' => false,
@@ -299,6 +314,7 @@ $cfg = array(
         'css' => true,
         'csgo' => true,
         'cs2' => true,
+        'rust' => true,
         'samp' => true,
         'crmp' => true,
         'mta' => true,

+ 4 - 0
system/data/engine.php

@@ -121,6 +121,7 @@ $aGname = array(
     'cssold' => 'CS: Source v34',
     'csgo' => 'CS: Global Offensive',
     'cs2' => 'CS: 2',
+    'rust' => 'RUST',
     'mc' => 'MineCraft',
     'mta' => 'GTA: MTA',
     'samp' => 'GTA: SAMP',
@@ -146,6 +147,7 @@ $aSLdir = array(
     'css' => 'cstrike/oldstart',
     'csgo' => 'csgo/oldstart',
     'cs2' => 'csgo/oldstart',
+    'rust' => 'oldstart',
     'mc' => 'oldstart',
     'mta' => 'mods/deathmatch/oldstart',
     'samp' => 'oldstart',
@@ -159,6 +161,7 @@ $aSLdirFtp = array(
     'css' => 'oldstart',
     'csgo' => 'csgo/oldstart',
     'cs2' => 'csgo/oldstart',
+    'rust' => 'oldstart',
     'mc' => 'oldstart',
     'mta' => 'mods/deathmatch/oldstart',
     'samp' => 'oldstart',
@@ -172,6 +175,7 @@ $aOwners = array(
     'css' => array('start', 'stop', 'restart', 'change', 'reinstall', 'update', 'console', 'settings', 'plugins', 'maps', 'filetp', 'tarif', 'copy', 'graph'),
     'csgo' => array('start', 'stop', 'restart', 'change', 'reinstall', 'update', 'console', 'settings', 'plugins', 'maps', 'filetp', 'tarif', 'copy', 'graph'),
     'cs2' => array('start', 'stop', 'restart', 'change', 'reinstall', 'update', 'console', 'settings', 'plugins', 'maps', 'filetp', 'tarif', 'copy', 'graph'),
+    'rust' => array('start', 'stop', 'restart', 'reinstall', 'console', 'settings', 'plugins', 'filetp', 'tarif', 'copy', 'graph'),
     'mc' => array('start', 'stop', 'restart', 'reinstall', 'console', 'settings', 'plugins', 'filetp', 'tarif', 'copy', 'graph'),
     'mta' => array('start', 'stop', 'restart', 'reinstall', 'console', 'settings', 'plugins', 'filetp', 'tarif', 'copy', 'graph'),
     'samp' => array('start', 'stop', 'restart', 'reinstall', 'console', 'settings', 'plugins', 'filetp', 'tarif', 'copy', 'graph'),

+ 20 - 0
system/data/filedits.php

@@ -111,6 +111,26 @@ $aEdits = array(
         )
     ),
 
+    'rust' => array(
+        'all' => array(
+            'files' => array(
+                'autoexec.cfg',
+                'fastdl.cfg',
+                'webapi_authkey.txt',
+            ),
+            'path' => array(
+                'autoexec.cfg' => 'csgo/cfg/',
+                'fastdl.cfg' => 'csgo/cfg/',
+                'webapi_authkey.txt' => 'csgo/',
+            ),
+            'desc' => array(
+                'autoexec.cfg' => 'Автоподключаемый конфигурационный файл.',
+                'fastdl.cfg' => 'Быстрая закачка файлов с сервера.',
+                'webapi_authkey.txt' => 'API ключ для установки карт из мастерской <u>WorkShop</u>.',
+            )
+        )
+    ),
+
     'mta' => array(
         'all' => array(
             'files' => array(

+ 26 - 0
system/data/params.php

@@ -41,6 +41,7 @@ class params
         'css' => 27015,
         'csgo' => 27015,
         'cs2' => 27015,
+        'rust' => 28015,
         'samp' => 7777,
         'crmp' => 7777,
         'mta' => 22003,
@@ -168,6 +169,29 @@ class params
             )
         ),
 
+        'rust' => array(
+            'CopyFull' => '*',
+
+            'aCopy' => array(
+                'addons' => 'Директория с дополнениями (модули/плагины)',
+                'cfg' => 'Файлы настроек (server.cfg/motd.txt/banned_user.cfg/banned_ip.cfg и т.д.)',
+                'maps' => 'Директория с картами (название.bsp)',
+                'models' => 'Директория с моделями (название.mdl)',
+                'sound' => 'Директория со звуками (название.mp3/название.wav)'
+            ),
+
+            'aCopyDir' => array(
+                'addons' => 'csgo/addons',
+                'maps' => 'csgo/maps',
+                'models' => 'csgo/models',
+                'sound' => 'csgo/sound'
+            ),
+
+            'aCopyFile' => array(
+                'cfg' => 'csgo/cfg/server.cfg csgo/motd.txt csgo/fastdl.cfg csgo/banned_user.cfg csgo/banned_ip.cfg csgo/mapcycle.txt csgo/maplist.txt'
+            )
+        ),
+
         'samp' => array(
             'CopyFull' => '*',
 
@@ -253,6 +277,7 @@ class params
         'css' => 'cstrike',
         'csgo' => 'csgo',
         'cs2' => 'cs2',
+        'rust' => '',
         'samp' => '',
         'crmp' => '',
         'mta' => '',
@@ -266,6 +291,7 @@ class params
         'css' => 'srcds_linux srcds_run',
         'csgo' => 'srcds_linux srcds_run',
         'cs2' => 'srcds_linux srcds_run',
+        'rust' => 'RustDedicated',
         'samp' => 'samp03svr',
         'crmp' => 'samp03svr-cr',
         'mta' => 'mta-server',

+ 2 - 1
system/engine/services.php

@@ -3,7 +3,7 @@ if (!DEFINED('EGP'))
     exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
 
 // Подключение раздела
-if (!in_array($section, array('cs', 'css', 'cssold', 'csgo', 'cs2', 'mc', 'mta', 'samp', 'crmp', 'hosting', 'privileges', 'control'))) {
+if (!in_array($section, array('cs', 'css', 'cssold', 'csgo', 'cs2', 'rust',  'mc', 'mta', 'samp', 'crmp', 'hosting', 'privileges', 'control'))) {
     $title = 'Список услуг';
     $html->nav($title);
 
@@ -16,6 +16,7 @@ if (!in_array($section, array('cs', 'css', 'cssold', 'csgo', 'cs2', 'mc', 'mta',
         'cssold' => 'Counter-Srike: Source v34',
         'csgo' => 'Counter-Srike: Global Offensive',
         'cs2' => 'Counter-Srike: 2',
+        'rust' => 'RUST',
         'mc' => 'MineCraft',
         'mta' => 'GTA: MTA',
         'samp' => 'GTA: SA-MP',

+ 2 - 0
system/library/cron.php

@@ -20,6 +20,7 @@ class cron
         'css' => 'srcds_',
         'csgo' => 'srcds_',
         'cs2' => 'cs2',
+        'cs2' => 'RustDedicated',
         'samp' => 'samp',
         'crmp' => 'samp',
         'mta' => 'mta',
@@ -32,6 +33,7 @@ class cron
         'css' => 'a2s',
         'csgo' => 'a2s',
         'cs2' => 'a2s',
+        'rust' => 'a2s',
         'mta' => 'eye'
     );
 

+ 295 - 0
system/library/games/rust/action.php

@@ -0,0 +1,295 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+include(LIB . 'games/actions.php');
+
+class action extends actions
+{
+    public static function start($id, $type = 'start')
+    {
+        global $cfg, $sql, $user, $start_point;
+
+        $sql->query('SELECT `uid`, `unit`, `tarif`, `game`, `address`, `slots_start`, `name`, `tickrate`, `map_start`, `vac`, `time_start`, `core_fix`, `pingboost` FROM `servers` WHERE `id`="' . $id . '" LIMIT 1');
+        $server = $sql->get();
+
+        $sql->query('SELECT `install` FROM `tarifs` WHERE `id`="' . $server['tarif'] . '" LIMIT 1');
+        $tarif = $sql->get();
+
+        include(LIB . 'ssh.php');
+
+        $sql->query('SELECT `address`, `passwd` FROM `units` WHERE `id`="' . $server['unit'] . '" LIMIT 1');
+        $unit = $sql->get();
+
+        // Проверка ssh соедниения пу с локацией
+        if (!$ssh->auth($unit['passwd'], $unit['address']))
+            return array('e' => sys::text('error', 'ssh'));
+
+        list($ip, $port) = explode(':', $server['address']);
+
+        // Убить процессы
+        $ssh->set('kill -9 `ps aux | grep s_' . $server['uid'] . ' | grep -v grep | awk ' . "'{print $2}'" . ' | xargs;'
+            . 'lsof -i@' . $server['address'] . ' | awk ' . "'{print $2}'" . ' | grep -v PID | xargs`; sudo -u server' . $server['uid'] . ' screen -wipe');
+
+        $taskset = '';
+
+        // Если включена система автораспределения и не установлен фиксированный поток
+        if ($cfg['cpu_route'] and !$server['core_fix']) {
+            $proc_stat = array();
+
+            $proc_stat[0] = $ssh->get('cat /proc/stat');
+        }
+
+        // Проверка наличия стартовой карты
+        $ssh->set('cd ' . $tarif['install'] . $server['uid'] . '/game/csgo/maps/ && du -ah | grep -e "\.vpk$" | awk \'{print $2}\'');
+
+        include_once(LIB . 'games/games.php');
+
+        if (games::map2($server['map_start'], $ssh->get()))
+            return array('e' => sys::updtext(sys::text('servers', 'nomap'), array('map' => $server['map_start'] . '.vpk')));
+
+        // Если система автораспределения продолжить парсинг загрузки процессора
+        if (isset($proc_stat)) {
+            $proc_stat[1] = $ssh->get('cat /proc/stat');
+
+            // Ядро/поток, на котором будет запущен игровой сервер (поток выбран с рассчетом наименьшей загруженности в момент запуска игрового сервера)
+            $core = sys::cpu_idle($proc_stat, $server['unit'], false); // число от 1 до n (где n число ядер/потоков в процессоре (без нулевого)
+
+            if (!is_numeric($core))
+                return array('e' => sys::text('error', 'cpu'));
+
+            $taskset = 'taskset -c ' . $core;
+        }
+
+        if ($server['core_fix']) {
+            $core = $server['core_fix'] - 1;
+            $taskset = 'taskset -c ' . $core;
+        }
+
+        // Античит VAC
+        $vac = $server['vac'] == 0 ? '-insecure' : '-secure';
+
+        // Боты
+        $bots = $cfg['bots'][$server['game']] ? '' : '-nobots';
+
+        // TV
+        $tv = isset($server['tv']) ? '+tv_enable 1 +tv_maxclients 30 +tv_port ' . ($port + 10000) : '-nohltv';
+
+        $check = explode('/', $server['map_start']);
+
+        // Стартовая карта
+        $map = $check[0] == 'workshop' ? '+workshop_start_map ' . $check[1] : '+map \'' . $server['map_start'] . '\'';
+
+        // Игровой режим
+        $mods = array(
+            1 => '+game_type 0 +game_mode 0',
+            2 => '+game_type 0 +game_mode 1',
+            3 => '+game_type 1 +game_mode 0',
+            4 => '+game_type 1 +game_mode 1',
+            5 => '+game_type 1 +game_mode 2'
+        );
+
+        $mod = !$server['pingboost'] ? $mods[2] : $mods[$server['pingboost']];
+
+        // Параметры запуска
+        $bash = './RustDedicated -dedicated -debug -norestart -condebug console.log -usercon -ip ' . $ip . ' -port ' . $port . ' -maxplayers ' . $server['slots_start'] . ' -tickrate ' . $server['tickrate'] . ' ' . $mod . ' +servercfgfile server.cfg ' . $map . ' ' . $vac . ' ' . $bots . ' ' . $tv;
+
+        // Временный файл
+        $temp = sys::temp($bash);
+
+        // Обновление файла start.sh
+        $ssh->setfile($temp, $tarif['install'] . $server['uid'] . '/start.sh', 0500);
+
+        // Строка запуска
+        $ssh->set('cd ' . $tarif['install'] . $server['uid'] . ';' // переход в директорию игрового сервера
+            . 'rm *.pid;' // Удаление *.pid файлов
+            . 'sudo -u server' . $server['uid'] . ' mkdir -p game/csgo/oldstart;' // Создание папки логов
+            . 'cat game/csgo/console.log >> game/csgo/oldstart/' . date('d.m.Y_H:i:s', $server['time_start']) . '.log; rm game/csgo/console.log; rm game/csgo/oldstart/01.01.1970_03:00:00.log;'  // Перемещение лога предыдущего запуска
+            . 'chown server' . $server['uid'] . ':1000 start.sh;' // Обновление владельца файла start.sh
+            . 'sudo -u server' . $server['uid'] . ' screen -dmS s_' . $server['uid'] . ' ' . $taskset . ' sh -c "./start.sh"'); // Запуск игровго сервера
+
+        $core = !isset($core) ? 0 : $core + 1;
+
+        // Обновление информации в базе
+        $sql->query('UPDATE `servers` set `status`="' . $type . '", `online`="0", `players`="", `core_use`="' . $core . '", `time_start`="' . $start_point . '", `stop`="1" WHERE `id`="' . $id . '" LIMIT 1');
+
+        unlink($temp);
+
+        // Сброс кеша
+        actions::clmcache($id);
+
+        sys::reset_mcache('server_scan_mon_pl_' . $id, $id, array('name' => $server['name'], 'game' => $server['game'], 'status' => $type, 'online' => 0, 'players' => ''));
+        sys::reset_mcache('server_scan_mon_' . $id, $id, array('name' => $server['name'], 'game' => $server['game'], 'status' => $type, 'online' => 0));
+
+        return array('s' => 'ok');
+    }
+
+    public static function change($id, $map = false)
+    {
+        global $cfg, $sql, $html, $user, $mcache;
+
+        // Если в кеше есть карты
+        if ($mcache->get('server_maps_change_' . $id) != '' and !$map)
+            return array('maps' => $mcache->get('server_maps_change_' . $id));
+
+        include(LIB . 'ssh.php');
+
+        include(LIB . 'games/games.php');
+
+        $sql->query('SELECT `uid`, `unit`, `game`, `tarif`, `online`, `players`, `name` FROM `servers` WHERE `id`="' . $id . '" LIMIT 1');
+        $server = $sql->get();
+
+        $sql->query('SELECT `address`, `passwd` FROM `units` WHERE `id`="' . $server['unit'] . '" LIMIT 1');
+        $unit = $sql->get();
+
+        $sql->query('SELECT `install` FROM `tarifs` WHERE `id`="' . $server['tarif'] . '" LIMIT 1');
+        $tarif = $sql->get();
+
+        // Проверка ssh соедниения пу с локацией
+        if (!$ssh->auth($unit['passwd'], $unit['address']))
+            return array('e' => sys::text('error', 'ssh'));
+
+        // Массив карт игрового сервера (папка "maps")
+        $aMaps = explode("\n", $ssh->get('cd ' . $tarif['install'] . $server['uid'] . '/game/csgo/maps/ && du -ah | grep -e "\.vpk$" | awk \'{print $2}\''));
+
+        // Удаление пустого элемента
+        unset($aMaps[count($aMaps) - 1]);
+
+        // Удаление ".vpk"
+        $aMaps = str_ireplace(array('./', '.vpk'), '', $aMaps);
+
+        // Если выбрана карта
+        if ($map) {
+            $map = str_replace('|', '/', $map);
+
+            // Проверка наличия выбранной карты
+            if (games::map($map, $aMaps))
+                return array('e' => sys::updtext(sys::text('servers', 'change'), array('map' => $map . '.vpk')));
+
+            // Отправка команды changelevel
+            $ssh->set('sudo -u server' . $server['uid'] . ' screen -p 0 -S s_' . $server['uid'] . ' -X eval ' . "'stuff \"changelevel " . sys::cmd($map) . "\"\015'");
+
+            // Обновление информации в базе
+            $sql->query('UPDATE `servers` set `status`="change" WHERE `id`="' . $id . '" LIMIT 1');
+
+            // Сброс кеша
+            actions::clmcache($id);
+
+            sys::reset_mcache('server_scan_mon_pl_' . $id, $id, array('name' => $server['name'], 'game' => $server['game'], 'status' => 'change', 'online' => $server['online'], 'players' => base64_decode($server['players'])));
+            sys::reset_mcache('server_scan_mon_' . $id, $id, array('name' => $server['name'], 'game' => $server['game'], 'status' => 'change', 'online' => $server['online']));
+
+            return array('s' => 'ok');
+        }
+
+        // Сортировка списка карт
+        sort($aMaps);
+        reset($aMaps);
+
+        // Генерация списка карт для выбора
+        foreach ($aMaps as $map) {
+            $aName = explode('/', $map);
+            $name = end($aName);
+
+            $html->get('change_list', 'sections/servers/cs2');
+
+            $html->set('img', file_exists(DIR . '/maps/' . $server['game'] . '/' . $name . '.jpg') ? $cfg['http'] . 'maps/' . $server['game'] . '/' . $name . '.jpg' : $cfg['http'] . 'template/images/status/none.jpg');
+            $html->set('map', str_replace('/', '|', $map));
+            $html->set('name', $name);
+            $html->set('id', $id);
+
+            if (count($aName) > 1)
+                $html->unit('workshop', true);
+            else
+                $html->unit('workshop');
+
+            $html->pack('maps');
+        }
+
+        // Запись карт в кеш
+        $mcache->set('server_maps_change_' . $id, $html->arr['maps'], false, 60);
+
+        return array('maps' => $html->arr['maps']);
+    }
+
+    public static function update($id)
+    {
+        global $cfg, $sql, $user, $start_point;
+
+        include(LIB . 'ssh.php');
+
+        $sql->query('SELECT `uid`, `unit`, `tarif`, `game`, `name`, `ftp`, `update`, `core_fix` FROM `servers` WHERE `id`="' . $id . '" LIMIT 1');
+        $server = $sql->get();
+
+        // Проверка времени обновления
+        $update = $server['update'] + $cfg['update'][$server['game']] * 60;
+
+        if ($update > $start_point and $user['group'] != 'admin')
+            return array('e' => sys::updtext(sys::text('servers', 'update'), array('time' => sys::date('max', $update))));
+
+        $sql->query('SELECT `address`, `passwd`, `sql_login`, `sql_passwd`, `sql_port`, `sql_ftp` FROM `units` WHERE `id`="' . $server['unit'] . '" LIMIT 1');
+        $unit = $sql->get();
+
+        $sql->query('SELECT `install`, `plugins_install` FROM `tarifs` WHERE `id`="' . $server['tarif'] . '" LIMIT 1');
+        $tarif = $sql->get();
+
+        // Проверка ssh соедниения пу с локацией
+        if (!$ssh->auth($unit['passwd'], $unit['address']))
+            return array('e' => sys::text('error', 'ssh'));
+
+        $taskset = '';
+
+        // Если включена система автораспределения и не установлен фиксированный поток
+        if ($cfg['cpu_route'] and !$server['core_fix']) {
+            $proc_stat = array();
+
+            $proc_stat[0] = $ssh->get('cat /proc/stat');
+        }
+
+        // Директория игрового сервера
+        $install = $tarif['install'] . $server['uid'];
+
+        // Если система автораспределения продолжить парсинг загрузки процессора
+        if (isset($proc_stat)) {
+            $proc_stat[1] = $ssh->get('cat /proc/stat');
+
+            // Ядро/поток, на котором будет запущен игровой сервер (поток выбран с рассчетом наименьшей загруженности в момент запуска игрового сервера)
+            $core = sys::cpu_idle($proc_stat, $server['unit'], false); // число от 1 до n (где n число ядер/потоков в процессоре (без нулевого)
+
+            if (!is_numeric($core))
+                return array('e' => 'Не удается выполнить операцию, нет свободного потока.');
+
+            $taskset = 'taskset -c ' . $core;
+        }
+
+        if ($server['core_fix']) {
+            $core = $server['core_fix'] - 1;
+            $taskset = 'taskset -c ' . $core;
+        }
+
+        $ssh->set('cd ' . $cfg['steamcmd'] . ' && ' . $taskset . ' screen -dmS u_' . $server['uid'] . ' sh -c "'
+            . './steamcmd.sh +login anonymous +force_install_dir "' . $install . '" +app_update 730 +quit;'
+            . 'cd ' . $install . ';'
+            . 'chown -R server' . $server['uid'] . ':servers .;'
+            . 'find . -type d -exec chmod 700 {} \;;'
+            . 'find . -type f -exec chmod 600 {} \;;'
+            . 'chmod 500 ' . params::$aFileGame[$server['game']] . '"');
+
+        $core = !isset($core) ? 0 : $core + 1;
+
+        // Обновление информации в базе
+        $sql->query('UPDATE `servers` set `status`="update", `update`="' . $start_point . '", `core_use`="' . $core . '" WHERE `id`="' . $id . '" LIMIT 1');
+
+        // Логирование
+        $sql->query('INSERT INTO `logs_sys` set `user`="' . $user['id'] . '", `server`="' . $id . '", `text`="' . sys::text('syslogs', 'update') . '", `time`="' . $start_point . '"');
+
+        // Сброс кеша
+        actions::clmcache($id);
+
+        sys::reset_mcache('server_scan_mon_pl_' . $id, $id, array('name' => $server['name'], 'game' => $server['game'], 'status' => 'update', 'online' => 0, 'players' => ''));
+        sys::reset_mcache('server_scan_mon_' . $id, $id, array('name' => $server['name'], 'game' => $server['game'], 'status' => 'update', 'online' => 0));
+
+        return array('s' => 'ok');
+    }
+}
+
+?>

+ 109 - 0
system/library/games/rust/rcon.php

@@ -0,0 +1,109 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+use xPaw\SourceQuery\SourceQuery;
+
+class rcon
+{
+    public static function cmd($server, $cmd = 'status')
+    {
+
+        $sq = new SourceQuery();
+
+        list($ip, $port) = explode(':', $server['address']);
+
+        $sq->Connect($ip, $port, 3, SourceQuery::SOURCE);
+
+        $sq->SetRconPassword(rcon::rcon_passwd($server));
+
+        $out = $sq->Rcon($cmd);
+
+        $sq->Disconnect();
+
+        return $out;
+    }
+
+    public static function players($data)
+    {
+        $aPlayers = array();
+        $n = 1;
+
+        $lines = explode("\n", $data);
+
+        foreach ($lines as $line) {
+            if (strpos($line, '#') === FALSE)
+                continue;
+
+            $start = strpos($line, '"') + 1;
+            $end = strrpos($line, '"');
+
+            $userid = sys::int(substr($line, 0, $start));
+
+            $name = htmlspecialchars(substr($line, $start, $end - $start));
+
+            $line = trim(substr($line, $end + 1));
+
+            $aData = array_values(array_diff(explode(' ', $line), array('', ' ')));
+
+            $steamid = trim($aData[0]);
+            $ip = trim(sys::first(explode(':', $aData[5])));
+
+            if ((sys::valid($steamid, 'steamid') and sys::valid($steamid, 'steamid3')) || sys::valid($ip, 'ip'))
+                continue;
+
+            $aPlayers[$n]['userid'] = $userid;
+            $aPlayers[$n]['name'] = $name;
+            $aPlayers[$n]['steamid'] = $steamid;
+            $aPlayers[$n]['time'] = trim($aData[1]);
+            $aPlayers[$n]['ping'] = trim($aData[2]);
+            $aPlayers[$n]['ip'] = $ip;
+
+            $whois = rcon::country($ip);
+
+            $aPlayers[$n]['ico'] = $whois['ico'];
+            $aPlayers[$n]['country'] = $whois['name'];
+
+            $n += 1;
+        }
+
+        return $aPlayers;
+    }
+
+    public static function rcon_passwd($server)
+    {
+        global $cfg, $sql, $user, $nmch;
+
+        include(LIB . 'ssh.php');
+
+        $sql->query('SELECT `address`, `passwd` FROM `units` WHERE `id`="' . $server['unit'] . '" LIMIT 1');
+        $unit = $sql->get();
+
+        if (!$ssh->auth($unit['passwd'], $unit['address']))
+            sys::outjs(array('e' => sys::text('error', 'ssh')));
+
+        $sql->query('SELECT `install` FROM `tarifs` WHERE `id`="' . $server['tarif'] . '" LIMIT 1');
+        $tarif = $sql->get();
+
+        $ssh->set('cat ' . $tarif['install'] . '/' . $server['uid'] . '/game/csgo/cfg/server.cfg | grep rcon_password');
+        $get = explode(' ', str_replace('"', '', trim($ssh->get())));
+        $rcon = trim(end($get));
+
+        if (!isset($rcon[0]))
+            sys::outjs(array('r' => 'Необходимо установить rcon пароль (rcon_password).', 'url' => $cfg['http'] . 'servers/id/' . $server['id'] . '/section/settings/subsection/server'), $nmch);
+
+        return $rcon;
+    }
+
+    public static function country($ip)
+    {
+        global $SxGeo;
+
+        $cData = $SxGeo->getCityFull($ip);
+        $ico = sys::country($cData['country']['iso']);
+
+        return array('ico' => $ico, 'name' => empty($cData['country']['name_ru']) ? 'Не определена' : $cData['country']['name_ru']);
+    }
+}
+
+?>

+ 135 - 0
system/library/games/rust/scan.php

@@ -0,0 +1,135 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+include(LIB . 'games/scans.php');
+
+use xPaw\SourceQuery\SourceQuery;
+
+class scan extends scans
+{
+    public static function mon($id, $players_get = false)
+    {
+        global $cfg, $sql, $html, $mcache;
+
+        $sq = new SourceQuery();
+
+        if ($players_get)
+            $nmch = 'server_scan_mon_pl_' . $id;
+        else
+            $nmch = 'server_scan_mon_' . $id;
+
+        if (is_array($mcache->get($nmch)))
+            return $mcache->get($nmch);
+
+        $out = array();
+
+        $info = scan::info($sq, $id);
+
+        $sql->query('SELECT `game`, `name`, `map`, `online`, `players`, `status`, `time`, `overdue` FROM `servers` WHERE `id`="' . $id . '" LIMIT 1');
+        $server = $sql->get();
+
+        $out['time'] = 'Арендован до: ' . date('d.m.Y - H:i', $server['time']);
+
+        if ($server['status'] == 'overdue')
+            $out['time_end'] = 'Удаление через: ' . sys::date('min', $server['overdue'] + $cfg['server_delete'] * 86400);
+        else
+            $out['time_end'] = 'Осталось: ' . sys::date('min', $server['time']);
+
+        if (!$info['status']) {
+            $out['name'] = $server['name'];
+            $out['status'] = sys::status($server['status'], $server['game'], $server['map']);
+            $out['online'] = $server['online'];
+            $out['image'] = '<img src="' . sys::status($server['status'], $server['game'], $server['map'], 'img') . '">';
+            $out['buttons'] = sys::buttons($id, $server['status']);
+
+            if ($players_get)
+                $out['players'] = base64_decode($server['players']);
+
+            $mcache->set($nmch, $out, false, $cfg['mcache_server_mon']);
+
+            return $out;
+        }
+
+        if ($players_get)
+            $players = scan::info($sq, $id, true);
+
+        $out['name'] = htmlspecialchars($info['name']);
+        $out['status'] = sys::status('working', $server['game'], $info['map']);
+        $out['online'] = $info['online'];
+        $out['image'] = '<img src="' . sys::status('working', $server['game'], $info['map'], 'img') . '">';
+        $out['buttons'] = sys::buttons($id, 'working');
+        $out['players'] = '';
+
+        if ($players_get) {
+            foreach ($players as $index => $player) {
+                $html->get($server['game'], 'sections/servers/players');
+
+                $html->set('i', $player['i']);
+                $html->set('name', $player['name']);
+                $html->set('score', $player['score']);
+                $html->set('time', $player['time']);
+
+                $html->pack('list');
+            }
+
+            $out['players'] = isset($html->arr['list']) ? $html->arr['list'] : '';
+        }
+
+        $sql->query('UPDATE `servers` set '
+            . '`name`="' . $out['name'] . '", '
+            . '`online`="' . $out['online'] . '", '
+            . '`map`="' . $info['map'] . '", '
+            . '`status`="working" WHERE `id`="' . $id . '" LIMIT 1');
+
+        if ($players_get)
+            $sql->query('UPDATE `servers` set `players`="' . base64_encode($out['players']) . '" WHERE `id`="' . $id . '" LIMIT 1');
+
+        $mcache->set($nmch, $out, false, $cfg['mcache_server_mon']);
+
+        return $out;
+    }
+
+    public static function info($sq, $id, $pl = false)
+    {
+        global $sql;
+
+        $sql->query('SELECT `address` FROM `servers` WHERE `id`="' . $id . '" LIMIT 1');
+        $server = $sql->get();
+
+        list($ip, $port) = explode(':', $server['address']);
+
+        $sq->Connect($ip, $port, 1, SourceQuery::SOURCE);
+
+        if ($pl) {
+            $players = $sq->GetPlayers();
+
+            $i = 1;
+            $data = array();
+
+            foreach ($players as $n => $player) {
+                $data[$i]['i'] = $i;
+                $data[$i]['name'] = $player['Name'] == '' ? 'Подключается' : $player['Name'];
+                $data[$i]['score'] = $player['Frags'];
+                $data[$i]['time'] = $player['TimeF'];
+
+                $i += 1;
+            }
+
+            return $data;
+        }
+
+        $data = $sq->GetInfo();
+
+        $map = explode('/', $data['Map'] ?? '');
+
+        $server['name'] = $data['HostName'];
+        $server['map'] = end($map);
+        $server['online'] = $data['Players'];
+        $server['status'] = strlen($server['map']) > 3 ? true : false;
+
+        return $server;
+    }
+}
+
+?>

+ 354 - 0
system/library/games/rust/service.php

@@ -0,0 +1,354 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+class service
+{
+    public static function buy($aData = array())
+    {
+        global $cfg, $sql, $user, $start_point;
+
+        // Проверка локации
+        $sql->query('SELECT `address`, `test` FROM `units` WHERE `id`="' . $aData['unit'] . '" AND `rust`="1" AND `show`="1" LIMIT 1');
+        if (!$sql->num())
+            sys::outjs(array('e' => 'Локация не найдена.'));
+
+        $unit = $sql->get();
+
+        // Проверка тарифа
+        $sql->query('SELECT `id` FROM `tarifs` WHERE `id`="' . $aData['tarif'] . '" AND `unit`="' . $aData['unit'] . '" AND `show`="1" LIMIT 1');
+        if (!$sql->num())
+            sys::outjs(array('e' => 'Тариф не найден.'));
+
+        $sql->query('SELECT '
+            . '`slots_min`,'
+            . '`slots_max`,'
+            . '`port_min`,'
+            . '`port_max`,'
+            . '`hostname`,'
+            . '`packs`,'
+            . '`tickrate`,'
+            . '`time`,'
+            . '`test`,'
+            . '`tests`,'
+            . '`discount`,'
+            . '`map`,'
+            . '`ftp`,'
+            . '`plugins`,'
+            . '`console`,'
+            . '`stats`,'
+            . '`copy`,'
+            . '`web`,'
+            . '`plugins_install`,'
+            . '`hdd`,'
+            . '`autostop`,'
+            . '`core_fix`,'
+            . '`ip`,'
+            . '`price`'
+            . ' FROM `tarifs` WHERE `id`="' . $aData['tarif'] . '" LIMIT 1');
+
+        $tarif = $sql->get();
+
+        // Проверка сборки
+        if (!array_key_exists($aData['pack'], sys::b64djs($tarif['packs'], true)))
+            sys::outjs(array('e' => 'Сборка не найдена.'));
+
+        // Проверка TickRate
+        if (!in_array($aData['tickrate'], explode(':', $tarif['tickrate'])))
+            sys::outjs(array('e' => 'Переданные данные tickrate неверны.'));
+
+        $test = 0;
+
+        // Проверка периода на тест
+        if ($aData['test']) {
+            if (!$tarif['test'] || !$unit['test'])
+                sys::outjs(array('e' => 'Тестовый период недоступен.'));
+
+
+            // Проверка на повторный запрос
+            $sql->query('SELECT `id`, `game` FROM `tests` WHERE `user`="' . $user['id'] . '" LIMIT 1');
+            if ($sql->num()) {
+                $test_info = $sql->get();
+
+                if (!$cfg['tests']['game'] || $test_info['game'] == 'rust')
+                    sys::outjs(array('e' => 'Тестовый период предоставляется один раз.'));
+
+                $sql->query('SELECT `id` FROM `servers` WHERE `user`="' . $user['id'] . '" AND `test`="1" LIMIT 1');
+                if ($sql->num() and !$cfg['tests']['sametime'])
+                    sys::outjs(array('e' => 'Чтобы получить тестовый период другой игры, дождитесь окончания текущего.'));
+            }
+
+            // Проверка наличия мест на локации
+            $sql->query('SELECT `id` FROM `servers` WHERE `unit`="' . $aData['unit'] . '" AND `test`="1" AND `time`>"' . $start_point . '" LIMIT ' . $unit['test']);
+            if ($sql->num() == $unit['test'])
+                sys::outjs(array('e' => 'Свободного места для тестового периода нет.'));
+
+            // Проверка наличия мест для выбранного тарифа
+            $sql->query('SELECT `id` FROM `servers` WHERE `tarif`="' . $aData['tarif'] . '" AND `test`="1" AND `time`>"' . $start_point . '" LIMIT ' . $tarif['tests']);
+            if ($sql->num() == $tarif['tests'])
+                sys::outjs(array('e' => 'Свободного места для тестового периода выбранного тарифа нет.'));
+
+            $test = 1;
+        } else
+            // Проверка периода
+            if (!$cfg['settlement_period'] and !in_array($aData['time'], explode(':', $tarif['time'])))
+                sys::outjs(array('e' => 'Переданные данные периода неверны.'));
+
+        // Проверка слот
+        if ($aData['slots'] < $tarif['slots_min'] || $aData['slots'] > $tarif['slots_max'])
+            sys::outjs(array('e' => 'Переданные данные слот неверны.'));
+
+        // Определение цены
+        $aPrice = explode(':', $tarif['price']);
+        $price = $aPrice[array_search($aData['tickrate'], explode(':', $tarif['tickrate']))];
+
+        // Определение суммы
+        if ($cfg['settlement_period']) {
+            // Цена аренды за расчетный период
+            $sum = games::define_sum($tarif['discount'], $price, $aData['slots'], $start_point);
+
+            $aData['time'] = games::define_period('buy', params::$aDayMonth);
+        } else
+            $sum = games::define_sum($tarif['discount'], $price, $aData['slots'], $aData['time']);
+
+        // Проверка промо-кода
+        $promo = games::define_promo(
+            $aData['promo'],
+            array(
+                'tarif' => $aData['tarif'],
+                'tickrate' => $aData['tickrate'],
+                'slots' => $aData['slots'],
+                'time' => $aData['time'],
+                'user' => $user['id']
+            ),
+            $tarif['discount'],
+            $sum
+        );
+
+        $days = $aData['time']; // Кол-во дней аренды
+
+        // Использование промо-кода
+        if (is_array($promo)) {
+            if (array_key_exists('sum', $promo))
+                $sum = $promo['sum'];
+            else
+                $days += $promo['days']; // Кол-во дней аренды с учетом подарочных (промо-код)
+        }
+
+        // Проверка баланса
+        if ($user['balance'] < $sum)
+            sys::outjs(array('e' => 'У вас не хватает ' . (round($sum - $user['balance'], 2)) . ' ' . $cfg['currency']));
+
+        // Выделенный адрес игрового сервера
+        if (!empty($tarif['ip'])) {
+            $aIp = explode(':', $tarif['ip']);
+
+            $ip = false;
+            $port = params::$aDefPort['rust'];
+
+            // Проверка наличия свободного адреса
+            foreach ($aIp as $adr) {
+                $adr = trim($adr);
+
+                $sql->query('SELECT `id` FROM `servers` WHERE `unit`="' . $aData['unit'] . '" AND `address` LIKE "' . $adr . ':%" LIMIT 1');
+                if (!$sql->num()) {
+                    $ip = $adr;
+
+                    break;
+                }
+            }
+        } else {
+            $ip = sys::first(explode(':', $unit['address']));
+            $port = false;
+
+            // Проверка наличия свободного порта
+            for ($tarif['port_min']; $tarif['port_min'] <= $tarif['port_max']; $tarif['port_min'] += 1) {
+                $sql->query('SELECT `id` FROM `servers` WHERE `unit`="' . $aData['unit'] . '" AND (`address`="' . $ip . ':' . $tarif['port_min'] . '" OR `port`="' . $tarif['port_min'] . '") LIMIT 1');
+                if (!$sql->num()) {
+                    $port = $tarif['port_min'];
+
+                    break;
+                }
+            }
+        }
+
+        if (!$ip || !$port) {
+            $sql->query('UPDATE `tarifs` set `show`="0" WHERE `id`="' . $aData['tarif'] . '" LIMIT 1');
+
+            sys::outjs(array('e' => 'К сожалению нет доступных мест, обратитесь в тех.поддержку.'));
+        }
+
+        if ($test)
+            $aData['time'] = games::time($start_point, $tarif['test']);
+        else
+            $aData['time'] = games::time($start_point, $days);
+
+        $fix_one = 0;
+        $core = 0;
+
+        if ($tarif['core_fix'] != '') {
+            $aCore = explode(',', $tarif['core_fix']);
+
+            foreach ($aCore as $cpu) {
+                $sql->query('SELECT `id` FROM `servers` WHERE `unit`="' . $aData['unit'] . '" AND `tarif`="' . $aData['tarif'] . '" AND `core_fix`="' . $cpu . '" AND `core_fix_one`="1" LIMIT 1');
+
+                if ($sql->num())
+                    continue;
+
+                $fix_one = 1;
+                $core = $cpu;
+
+                break;
+            }
+
+            if (!$core) {
+                $sql->query('UPDATE `tarifs` set `show`="0" WHERE `id`="' . $aData['tarif'] . '" LIMIT 1');
+
+                sys::outjs(array('e' => 'К сожалению нет доступных мест, обратитесь в тех.поддержку.'));
+            }
+        }
+
+        $ram = isset($tarif['param_fix']) ? $aData['ram'] : $cfg['ram']['rust'] * $aData['slots'];
+
+        // Массив данных
+        $aSDATA = array(
+            'unit' => $aData['unit'], // идентификатор локации
+            'tarif' => $aData['tarif'], // идентификатор тарифа
+            'ram' => $ram, // значение ram
+            'param_fix' => isset($tarif['param_fix']), // фиксированные параметры
+            'tickrate' => $aData['tickrate'], // значение tickrate
+            'pack' => $aData['pack'], // Выбранная сборка для установки
+            'time' => $aData['time'], // Время аренды
+            'days' => $days, // Число дней
+            'sum' => $sum, // Сумма списания
+            'test' => $test, // тестовый период
+            'address' => $ip . ':' . $port, // адрес игрового сервера
+            'port' => $port, // порт игрового сервера
+            'slots' => $aData['slots'], // Кол-во слот
+            'map' => $tarif['map'], // Фиксированное значение слот
+            'autostop' => $tarif['autostop'], // Выключение при 0 онлайне
+            'ftp' => $tarif['ftp'], // Использование ftp
+            'plugins' => $tarif['plugins'], // Использование плагинов
+            'console' => $tarif['console'], // Использование консоли
+            'stats' => $tarif['stats'], // Использование графиков (ведение статистики)
+            'copy' => $tarif['copy'], // Использование резервных копий
+            'web' => $tarif['web'], // Использование доп услуг
+            'plugins_install' => $tarif['plugins_install'], // Список установленных плагинов
+            'hdd' => $tarif['hdd'], // Дисковое пространство
+            'core_fix' => $core, // Выделенный поток
+            'core_fix_one' => $fix_one, // Выделенный поток
+            'promo' => $promo // Использование промо-кода
+        );
+
+        return $aSDATA;
+    }
+
+    public static function install($aSDATA = array())
+    {
+        global $cfg, $sql, $user, $start_point;
+
+        include(LIB . 'ssh.php');
+
+        // Массив данных локации (адрес,пароль)
+        $sql->query('SELECT `address`, `passwd` FROM `units` WHERE `id`="' . $aSDATA['unit'] . '" LIMIT 1');
+        $unit = $sql->get();
+
+        // Проверка ssh соединения с локацией
+        if (!$ssh->auth($unit['passwd'], $unit['address']))
+            sys::outjs(array('e' => sys::text('error', 'ssh')));
+
+        // Массив данных тарифа (путь сборки,путь установки)
+        $sql->query('SELECT `path`, `install`, `hostname` FROM `tarifs` WHERE `id`="' . $aSDATA['tarif'] . '" LIMIT 1');
+        $tarif = $sql->get();
+
+        // Получение идентификаторов игрового сервера
+        $sql->query('INSERT INTO `servers` set uid="1"');
+        $id = $sql->id();
+        $uid = $id + 1000;
+
+        // Директория сборки
+        $path = $tarif['path'] . $aSDATA['pack'];
+
+        // Директория игрового сервера
+        $install = $tarif['install'] . $uid;
+
+        $ssh->set('mkdir ' . $install . ';' // Создание директории
+            . 'useradd -s /bin/false -d ' . $install . ' -g servers -u ' . $uid . ' server' . $uid . ';' // Создание пользователя сервера на локации
+            . 'chown server' . $uid . ':1000 ' . $install . ';' // Изменение владельца и группы директории
+            . 'cd ' . $install . ' && sudo -u server' . $uid . ' screen -dmS i_' . $uid . ' sh -c "cp -r ' . $path . '/. .;' // Копирование файлов сборки для сервера
+            . 'find . -type d -exec chmod 700 {} \;;'
+            . 'find . -type f -exec chmod 600 {} \;;'
+            . 'chmod 500 ' . params::$aFileGame['RustDedicated'] . '"');
+
+        // Запись данных нового сервера
+        $sql->query('UPDATE `servers` set
+				`uid`="' . $uid . '",
+				`unit`="' . $aSDATA['unit'] . '",
+				`tarif`="' . $aSDATA['tarif'] . '",
+				`user`="' . $user['id'] . '",
+				`address`="' . $aSDATA['address'] . '",
+				`port`="' . $aSDATA['port'] . '",
+				`game`="rust",
+				`slots`="' . $aSDATA['slots'] . '",
+				`slots_start`="' . $aSDATA['slots'] . '",
+				`status`="install",
+				`name`="' . $tarif['hostname'] . '",
+				`pack`="' . $aSDATA['pack'] . '",
+				`plugins_use`="' . $aSDATA['plugins'] . '",
+				`ftp_use`="' . $aSDATA['ftp'] . '",
+				`console_use`="' . $aSDATA['console'] . '",
+				`stats_use`="' . $aSDATA['stats'] . '",
+				`copy_use`="' . $aSDATA['copy'] . '",
+				`web_use`="' . $aSDATA['web'] . '",
+				`tickrate`="' . $aSDATA['tickrate'] . '",
+				`map_start`="' . $aSDATA['map'] . '",
+				`vac`="1",
+				`hdd`="' . $aSDATA['hdd'] . '",
+				`time`="' . $aSDATA['time'] . '",
+				`date`="' . $start_point . '",
+				`test`="' . $aSDATA['test'] . '",
+				`ram`="' . $aSDATA['ram'] . '",
+				`core_fix`="' . $aSDATA['core_fix'] . '",
+				`core_fix_one`="' . $aSDATA['core_fix_one'] . '",
+				`autostop`="' . $aSDATA['autostop'] . '" WHERE `id`="' . $id . '" LIMIT 1');
+
+        // Запись установленных плагинов
+        if ($aSDATA['plugins']) {
+            // Массив идентификаторов плагинов
+            $aPlugins = sys::b64djs($aSDATA['plugins_install']);
+
+            if (isset($aPlugins[$aSDATA['pack']])) {
+                $plugins = explode(',', $aPlugins[$aSDATA['pack']]);
+
+                foreach ($plugins as $plugin)
+                    if ($plugin)
+                        $sql->query('INSERT INTO `plugins_install` set `server`="' . $id . '", `plugin`="' . $plugin . '", `time`="' . $start_point . '"');
+            }
+        }
+
+        // Списание средств с баланса пользователя
+        $sql->query('UPDATE `users` set `balance`="' . ($user['balance'] - $aSDATA['sum']) . '" WHERE `id`="' . $user['id'] . '" LIMIT 1');
+
+        // Запись получения тестового периода
+        if ($aSDATA['test']) {
+            $sql->query('INSERT INTO `tests` set `server`="' . $id . '", `unit`="' . $aSDATA['unit'] . '", `game`="rust", `user`="' . $user['id'] . '", `time`="' . $start_point . '"');
+            $sql->query('INSERT INTO `logs` set `user`="' . $user['id'] . '", `text`="' . sys::updtext(sys::text('logs', 'buy_server_test'), array('id' => $id)) . '", `date`="' . $start_point . '", `type`="buy", `money`="0"');
+        } else {
+            // Реф. система
+            games::part($user['id'], $aSDATA['sum']);
+
+            // Запись логов
+            if (!is_array($aSDATA['promo']))
+                $sql->query('INSERT INTO `logs` set `user`="' . $user['id'] . '", `text`="' . sys::updtext(sys::text('logs', 'buy_server'), array('days' => games::parse_day($aSDATA['days'], true), 'money' => $aSDATA['sum'], 'id' => $id)) . '", `date`="' . $start_point . '", `type`="buy", `money`="' . $aSDATA['sum'] . '"');
+            else {
+                $sql->query('UPDATE `servers` set `benefit`="' . $aSDATA['time'] . '" WHERE `id`="' . $id . '" LIMIT 1');
+                $sql->query('INSERT INTO `promo_use` set `promo`="' . $aSDATA['promo']['id'] . '", `user`="' . $user['id'] . '", `time`="' . $start_point . '"');
+                $sql->query('INSERT INTO `logs` set `user`="' . $user['id'] . '", `text`="' . sys::updtext(sys::text('logs', 'buy_server_promo'), array('days' => games::parse_day($aSDATA['days'], true), 'money' => $aSDATA['sum'], 'promo' => $aSDATA['promo']['cod'], 'id' => $id)) . '", `date`="' . $start_point . '", `type`="buy", `money`="' . $aSDATA['sum'] . '"');
+            }
+        }
+
+        return $id;
+    }
+}
+
+?>

+ 220 - 0
system/library/games/rust/tarif.php

@@ -0,0 +1,220 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+class tarif extends tarifs
+{
+    public static function extend($options, $server, $tarif_name, $sid)
+    {
+        global $cfg, $sql, $html, $start_point;
+
+        tarifs::extend_address($server['game'], $sid);
+
+        $html->get('extend', 'sections/servers/games/tarif');
+
+        if (isset($html->arr['extend_address'])) {
+            $html->unit('extend_address', 1);
+            $html->set('extend_address', $html->arr['extend_address']);
+        } else
+            $html->unit('extend_address');
+
+        $html->set('id', $sid);
+        $html->set('time', sys::date('min', $server['time']));
+        $html->set('options', '<option value="0">Выберете период продления</option>' . $options);
+        $html->set('slots', $server['slots']);
+        $html->set('info', $server['tickrate'] . ' TickRate');
+        $html->set('tarif', $tarif_name);
+        $html->set('cur', $cfg['currency']);
+
+        $html->pack('main');
+
+        return NULL;
+    }
+
+    public static function extend_sp($server, $tarif, $sid)
+    {
+        global $cfg, $sql, $html, $start_point;
+
+        tarifs::extend_address($server['game'], $sid);
+
+        $aPrice = explode(':', $tarif['price']);
+        $aTICK = explode(':', $tarif['tickrate']);
+
+        $sum = $tarif['slots'] ? $aPrice[array_search($server['tickrate'], $aTICK)] : $aPrice[array_search($server['tickrate'], $aTICK)] * $server['slots'];
+
+        $html->get('extend_sp', 'sections/servers/games/tarif');
+
+        if (isset($html->arr['extend_address'])) {
+            $html->unit('extend_address', 1);
+            $html->set('extend_address', $html->arr['extend_address']);
+        } else
+            $html->unit('extend_address');
+
+        $html->set('id', $sid);
+        $html->set('time', sys::date('min', $server['time']));
+        $html->set('date', $server['time'] > $start_point ? 'Сервер продлен до: ' . date('d.m.Y', $server['time']) : 'Текущая дата: ' . date('d.m.Y', $start_point));
+        $html->set('options', '<option value="0">Выберете период продления</option>' . $options);
+        $html->set('slots', $server['slots']);
+        $html->set('info', $server['tickrate'] . ' TickRate');
+        $html->set('tarif', $tarif['name']);
+        $html->set('sum', $sum);
+        $html->set('cur', $cfg['currency']);
+
+        $html->pack('main');
+
+        return NULL;
+    }
+
+    public static function plan($server, $tarif_name, $sid)
+    {
+        global $cfg, $sql, $html;
+
+        $sql->query('SELECT `tickrate`, `price` FROM `tarifs` WHERE `id`="' . $server['tarif'] . '" LIMIT 1');
+
+        if (!$sql->num())
+            return NULL;
+
+        $tarif = $sql->get();
+
+        $options = '<option value="0">Выберете тарифный план</option>';
+
+        $aPrice = explode(':', $tarif['price']);
+        $aTick = explode(':', $tarif['tickrate']);
+
+        // Если есть выбор
+        if (count($aTick) > 1) {
+            // Удалить при наличии tickrate сервера из выбора
+            if (in_array($server['tickrate'], $aTick))
+                unset($aTick[array_search($server['tickrate'], $aTick)]);
+
+            foreach ($aTick as $index => $tickrate)
+                $options .= '<option value="' . $tickrate . '">'
+                    . $tickrate . ' TickRate '
+                    . '(' . $aPrice[$index] . ' ' . $cfg['currency'] . '/слот | '
+                    . ($aPrice[$index] * $server['slots']) . ' ' . $cfg['currency'] . '/месяц)'
+                    . '</option>';
+        } else
+            return NULL;
+
+        $html->get('plan', 'sections/servers/games/tarif');
+
+        $html->set('id', $sid);
+        $html->set('options', $options);
+        $html->set('info', $server['tickrate'] . ' TickRate');
+        $html->set('tarif', $tarif_name);
+
+        $html->pack('main');
+
+        return NULL;
+    }
+
+    public static function unit($server, $unit_name, $tarif_name, $sid)
+    {
+        global $cfg, $sql, $html;
+
+        if (!$cfg['change_unit'][$server['game']])
+            return NULL;
+
+        $tarifs = $sql->query('SELECT `unit`, `tickrate` FROM `tarifs` WHERE `game`="' . $server['game'] . '" AND `name`="' . $tarif_name . '" AND `id`!="' . $server['tarif'] . '" AND `show`="1" ORDER BY `unit`');
+        if (!$sql->num($tarifs))
+            return NULL;
+
+        $units = 0;
+
+        $options = '<option value="0">Выберете новую локацию</option>';
+
+        while ($tarif = $sql->get($tarifs)) {
+            if (!in_array($server['tickrate'], explode(':', $tarif['tickrate'])))
+                continue;
+
+            $sql->query('SELECT `id`, `name` FROM `units` WHERE `id`="' . $tarif['unit'] . '" AND `show`="1" LIMIT 1');
+            if (!$sql->num())
+                continue;
+
+            $unit = $sql->get();
+
+            $options .= '<option value="' . $unit['id'] . '">' . $unit['name'] . '</option>';
+
+            $units += 1;
+        }
+
+        if (!$units)
+            return NULL;
+
+        $html->get('unit', 'sections/servers/games/tarif');
+
+        $html->set('id', $sid);
+        $html->set('options', $options);
+        $html->set('slots', $server['slots']);
+        $html->set('info', $server['tickrate'] . ' TickRate');
+        $html->set('unit', $unit_name);
+        $html->set('tarif', $tarif_name);
+
+        $html->pack('main');
+
+        return NULL;
+    }
+
+    public static function unit_new($tarif, $unit, $server, $mcache)
+    {
+        global $ssh, $sql, $user, $start_point;
+
+        // Проверка ssh соединения с локацией
+        if (!$ssh->auth($unit['passwd'], $unit['address']))
+            sys::outjs(array('e' => sys::text('error', 'ssh')));
+
+        // Директория сборки
+        $path = $tarif['path'] . $tarif['pack'];
+
+        // Директория игрового сервера
+        $install = $tarif['install'] . $server['uid'];
+
+        // Пользователь сервера
+        $uS = 'server' . $server['uid'];
+
+        $ssh->set('mkdir ' . $install . ';' // Создание директории
+            . 'useradd -d ' . $install . ' -g servers -u ' . $server['uid'] . ' ' . $uS . ';' // Создание пользователя сервера на локации
+            . 'chown ' . $uS . ':1000 ' . $install . ';' // Изменение владельца и группы директории
+            . 'cd ' . $install . ' && sudo -u ' . $uS . ' screen -dmS i_' . $server['uid'] . ' cp -r ' . $path . '/. .'); // Копирование файлов сборки для сервера
+
+        $address = explode(':', $server['address']);
+
+        $fix_one = $tarif['core_fix'] ? 1 : 0;
+
+        // Обновление данных нового сервера
+        $sql->query('UPDATE `servers` set
+				`unit`="' . $tarif['unit'] . '",
+				`tarif`="' . $tarif['id'] . '",
+				`address`="' . $server['address'] . '",
+				`port`="' . $address[1] . '",
+				`status`="install",
+				`name`="' . $tarif['hostname'] . '",
+				`pack`="' . $tarif['pack'] . '",
+				`map_start`="' . $tarif['map'] . '",
+				`vac`="1",
+				`hdd`="' . $tarif['hdd'] . '",
+				`time`="' . $tarif['time'] . '",
+				`autostop`="' . $tarif['autostop'] . '",
+				`core_fix`="' . $tarif['core_fix'] . '",
+				`core_fix_one`="' . $fix_one . '",
+				`reinstall`="' . $start_point . '" WHERE `id`="' . $server['id'] . '" LIMIT 1');
+
+        // Запись установленных плагинов
+        if ($tarif['plugins']) {
+            // Массив идентификаторов плагинов
+            $aPlugins = sys::b64js($tarif['plugins_install']);
+
+            if (isset($aPlugins[$tarif['pack']])) {
+                $plugins = explode(',', $aPlugins[$tarif['pack']]);
+
+                foreach ($plugins as $plugin)
+                    if ($plugin)
+                        $sql->query('INSERT INTO `plugins_install` set `server`="' . $server['id'] . '", `plugin`="' . $plugin . '", `time`="' . $start_point . '"');
+            }
+        }
+
+        return NULL;
+    }
+}
+
+?>

+ 63 - 0
system/sections/servers/rust/console.php

@@ -0,0 +1,63 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+$sql->query('SELECT `uid`, `unit`, `tarif`, `time_start` FROM `servers` WHERE `id`="' . $id . '" LIMIT 1');
+$server = array_merge($server, $sql->get());
+
+if ($go) {
+    $sql->query('SELECT `address`, `passwd` FROM `units` WHERE `id`="' . $server['unit'] . '" LIMIT 1');
+    $unit = $sql->get();
+
+    $sql->query('SELECT `install` FROM `tarifs` WHERE `id`="' . $server['tarif'] . '" LIMIT 1');
+    $tarif = $sql->get();
+
+    include(LIB . 'ssh.php');
+
+    $command = isset($_POST['command']) ? sys::cmd($_POST['command']) : '';
+
+    if ($server['status'] == 'off') {
+        if ($command)
+            sys::outjs(array('e' => sys::text('servers', 'off')));
+
+        sys::out(sys::text('servers', 'off'));
+    }
+
+    if (!$ssh->auth($unit['passwd'], $unit['address'])) {
+        if ($command)
+            sys::outjs(array('e' => sys::text('error', 'ssh')));
+
+        sys::out(sys::text('error', 'ssh'));
+    }
+
+    $dir = $tarif['install'] . $server['uid'] . '/game/csgo/';
+
+    $filecmd = $dir . 'console.log';
+
+    if ($command) {
+        if (strtolower($command) == 'clear')
+            $ssh->set('sudo -u server' . $server['uid'] . ' sh -c "echo \"Очистка консоли\n\" > ' . $filecmd . '"');
+        else
+            $ssh->set('sudo -u server' . $server['uid'] . ' screen -p 0 -S s_' . $server['uid'] . ' -X eval \'stuff "' . $command . '"\015\';'
+                . 'sudo -u server' . $server['uid'] . ' screen -p 0 -S s_' . $server['uid'] . ' -X eval \'stuff \015\'');
+
+        sys::outjs(array('s' => 'ok'));
+    }
+
+    $filecmd_copy = $dir . 'oldstart/' . date('d.m.Y_H:i:s', $server['time_start']) . '.log';
+
+    $weight = sys::int($ssh->get('du --block-size=1 ' . $filecmd . ' | awk \'{print $1}\''));
+
+    if ($weight > 524288)
+        $ssh->set('sudo -u server' . $server['uid'] . ' sh -c "mkdir -p ' . $dir . 'oldstart; cat ' . $filecmd . ' >> ' . $filecmd_copy . '; echo \"Выполнена очистка консоли, слишком большой объем данных\n\" > ' . $filecmd . '"');
+
+    sys::out(htmlspecialchars($ssh->get('cat ' . $filecmd), NULL, ''));
+}
+
+$html->nav($server['address'], $cfg['http'] . 'servers/id/' . $id);
+$html->nav('Консоль');
+
+$html->get('console', 'sections/servers/' . $server['game']);
+$html->set('id', $id);
+$html->pack('main');
+?>

+ 80 - 0
system/sections/servers/rust/copy.php

@@ -0,0 +1,80 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+if ($go) {
+    // Подразделы
+    $aSub = array('fullcopy', 'create', 'recfull', 'recpart', 'remove', 'check');
+
+    // Если выбран подраздел
+    if (isset($url['subsection']) and in_array($url['subsection'], $aSub)) {
+        if ($url['subsection'] != 'check')
+            $nmch = sys::rep_act('server_copy_go_' . $id, 10);
+
+        if ($server['status'] != 'off' and $url['subsection'] != 'remove')
+            sys::outjs(array('e' => 'Игровой сервер должен быть выключен'), $nmch);
+
+        $sql->query('SELECT `install` FROM `tarifs` WHERE `id`="' . $server['tarif'] . '" LIMIT 1');
+        $tarif = $sql->get();
+
+        $sql->query('SELECT `address`, `passwd` FROM `units` WHERE `id`="' . $server['unit'] . '" LIMIT 1');
+        $unit = $sql->get();
+
+        include(LIB . 'ssh.php');
+
+        if (!$ssh->auth($unit['passwd'], $unit['address']))
+            sys::outjs(array('e' => sys::text('error', 'ssh')), $nmch);
+
+        include(SEC . 'servers/games/copy/' . $url['subsection'] . '.php');
+    }
+}
+
+$html->nav($server['address'], $cfg['http'] . 'servers/id/' . $id);
+$html->nav('Резервные копии');
+
+if ($mcache->get('server_copy_' . $id) != '')
+    $html->arr['main'] = $mcache->get('server_copy_' . $id);
+else {
+    // Построение списка создания копии
+    foreach (params::$section_copy[$server['game']]['aCopy'] as $name => $info) {
+        $html->get('list', 'sections/servers/games/copy');
+
+        $html->set('name', $name);
+        $html->set('info', $info);
+
+        $html->pack('list');
+    }
+
+    // Построение списка созданных копий
+    $sql->query('SELECT `id`, `server`, `info`, `date`, `status` FROM `copy` WHERE `user`="' . $server['user'] . '_' . $server['unit'] . '" AND `game`="' . $server['game'] . '" ORDER BY `id` ASC');
+    while ($copy = $sql->get()) {
+        $html->get('copy', 'sections/servers/games/copy');
+
+        $html->set('id', $copy['id']);
+        $html->set('info', $copy['info']);
+        $html->set('server', $copy['server']);
+        $html->set('date', sys::today($copy['date']));
+
+        if ($copy['status']) {
+            $html->unit('created', 1);
+            $html->unit('!created');
+        } else {
+            $html->unit('created');
+            $html->unit('!created', 1);
+        }
+
+        $html->pack('copy');
+    }
+
+    $html->get('copy', 'sections/servers/' . $server['game']);
+
+    $html->set('id', $id);
+
+    $html->set('list', isset($html->arr['list']) ? $html->arr['list'] : '');
+    $html->set('copy', isset($html->arr['copy']) ? $html->arr['copy'] : 'Резервные копии отсутствуют.');
+
+    $html->pack('main');
+
+    $mcache->set('server_copy_' . $id, $html->arr['main'], false, 4);
+}
+?>

+ 68 - 0
system/sections/servers/rust/graph.php

@@ -0,0 +1,68 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+if ($go) {
+    $sql->query('SELECT `key` FROM `graph` WHERE `server`="' . $id . '" LIMIT 1');
+    $graph = $sql->get();
+
+    $nmch = 'server_graph_full_' . $id;
+
+    $time = isset($url['time']) ? $url['time'] : 'day';
+
+    if (!in_array($time, array('day', 'week', 'month')))
+        $time = 'day';
+
+    // Выхлоп кеш графика
+    if ($mcache->get($nmch) and file_exists(TEMP . (md5($graph['key'] . 'full_' . $time)) . '.png')) {
+        header('Content-type: image/png');
+        exit(file_get_contents(TEMP . (md5($graph['key'] . 'full_' . $time)) . '.png'));
+    }
+
+    include(LIB . 'games/graph/pData.php');
+    include(LIB . 'games/graph/pDraw.php');
+    include(LIB . 'games/graph/pImage.php');
+
+    include(LIB . 'games/graph.php');
+
+    graph::full($id, $server['slots_start'], $graph['key'], $time);
+
+    $mcache->set($nmch, true, false, 300);
+
+    header('Content-type: image/png');
+    exit(file_get_contents(TEMP . (md5($graph['key'] . 'full_' . $time)) . '.png'));
+}
+
+$html->nav($server['address'], $cfg['http'] . 'servers/id/' . $id);
+$html->nav('Графики');
+
+if ($mcache->get('server_graph_' . $id) != '')
+    $html->arr['main'] = $mcache->get('server_graph_' . $id);
+else {
+    $sql->query('SELECT `key` FROM `graph` WHERE `server`="' . $id . '" LIMIT 1');
+
+    // Если отсутствует ключ, создать
+    if (!$sql->num()) {
+        // Генерация ключа
+        $key = md5($id . sys::key('graph'));
+
+        $sql->query('INSERT INTO `graph` set `server`="' . $id . '", `key`="' . $key . '", `time`="0"');
+    } else {
+        $graph = $sql->get();
+
+        $key = $graph['key'];
+    }
+
+    $html->get('graph', 'sections/servers/games');
+
+    $html->set('id', $id);
+
+    $html->set('key', $key);
+    $html->set('address', $server['address']);
+    $html->set('_img', '[img]');
+
+    $html->pack('main');
+
+    $mcache->set('server_graph_' . $id, $html->arr['main'], false, 4);
+}
+?>

+ 44 - 0
system/sections/servers/rust/index.php

@@ -0,0 +1,44 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+$sql->query('SELECT `unit`, `tarif`, `slots_start`, `online`, `players`, `name`, `pack`, `tickrate`, `map`, `time`, `date`, `overdue` FROM `servers` WHERE `id`="' . $id . '" LIMIT 1');
+$server = array_merge($server, $sql->get());
+
+$html->nav($server['address']);
+
+$sql->query('SELECT `name` FROM `units` WHERE `id`="' . $server['unit'] . '" LIMIT 1');
+$unit = $sql->get();
+
+$sql->query('SELECT `name`, `packs` FROM `tarifs` WHERE `id`="' . $server['tarif'] . '" LIMIT 1');
+$tarif = $sql->get();
+
+$btn = sys::buttons($id, $server['status']);
+
+$time_end = $server['status'] == 'overdue' ? 'Удаление через: ' . sys::date('min', $server['overdue'] + $cfg['server_delete'] * 86400) : 'Осталось: ' . sys::date('min', $server['time']);
+
+$html->get('index', 'sections/servers/' . $server['game']);
+
+$html->set('id', $id);
+$html->set('unit', $unit['name']);
+$html->set('tarif', $tarif['name'] . ' / ' . $server['tickrate'] . ' TickRate');
+
+$tarif['packs'] = sys::b64djs($tarif['packs']);
+
+$html->set('pack', $tarif['packs'][$server['pack']]);
+$html->set('address', $server['address']);
+$html->set('game', $aGname[$server['game']]);
+$html->set('slots', $server['slots_start']);
+$html->set('online', $server['online']);
+$html->set('players', base64_decode($server['players']));
+$html->set('name', $server['name']);
+$html->set('status', sys::status($server['status'], $server['game'], $server['map']));
+$html->set('img', sys::status($server['status'], $server['game'], $server['map'], 'img'));
+$html->set('time_end', $time_end);
+$html->set('time', sys::today($server['time']));
+$html->set('date', sys::today($server['date']));
+
+$html->set('btn', $btn);
+
+$html->pack('main');
+?>

+ 94 - 0
system/sections/servers/rust/maps.php

@@ -0,0 +1,94 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+$sql->query('SELECT `unit`, `tarif` FROM `servers` WHERE `id`="' . $id . '" LIMIT 1');
+$server = array_merge($server, $sql->get());
+
+$html->nav($server['address'], $cfg['http'] . 'servers/id/' . $id);
+
+// Подразделы
+$aSub = array('install', 'delete', 'list', 'listing', 'search');
+
+// Если выбран подраздел
+if (isset($url['subsection']) and in_array($url['subsection'], $aSub)) {
+    $html->nav('Карты', $cfg['http'] . 'servers/id/' . $id . '/section/maps');
+
+    $nmch = sys::rep_act('server_maps_go_' . $id, 10);
+
+    include(SEC . 'servers/' . $server['game'] . '/maps/' . $url['subsection'] . '.php');
+} else {
+    $html->nav('Карты');
+
+    // Построение списка установленных карт
+    $sql->query('SELECT `address`, `passwd` FROM `units` WHERE `id`="' . $server['unit'] . '" LIMIT 1');
+    $unit = $sql->get();
+
+    if (!isset($ssh))
+        include(LIB . 'ssh.php');
+
+    if (!$ssh->auth($unit['passwd'], $unit['address'])) {
+        if ($go)
+            sys::outjs(array('e' => sys::text('error', 'ssh')), $nmch);
+
+        sys::back($cfg['http'] . 'servers/id/' . $id);
+    }
+
+    $sql->query('SELECT `install` FROM `tarifs` WHERE `id`="' . $server['tarif'] . '" LIMIT 1');
+    $tarif = $sql->get();
+
+    $ssh->set('cd ' . $tarif['install'] . $server['uid'] . '/game/csgo/maps/ && du -ah | grep -e "\.vpk$" | awk \'{print $2}\'');
+
+    $maps = $ssh->get();
+
+    $aMaps = explode("\n", str_ireplace('.vpk', '', $maps));
+
+    // Сортировка карт
+    sort($aMaps);
+    reset($aMaps);
+
+    $mapsjs = '';
+    $i = 0;
+
+    foreach ($aMaps as $index => $map) {
+        if (!isset($map[3]))
+            continue;
+
+        $map = str_replace('./', '', $map);
+
+        $mapjs = str_replace('$', '-_-', $map);
+
+        $aName = explode('/', $map);
+        $name = end($aName);
+
+        $html->get('map_server', 'sections/servers/cs2/maps');
+        $html->set('img', sys::img($name, $server['game']));
+        $html->set('map', $mapjs);
+        $html->set('name', $name);
+
+        if (count($aName) > 1)
+            $html->unit('workshop', true, true);
+        else {
+            $i += 1;
+            $mapsjs .= $i . ' : "' . $mapjs . '",';
+
+            $html->unit('workshop', false, true);
+        }
+        $html->pack('maps');
+    }
+
+    // Если есть кеш
+    if ($mcache->get('server_maps_' . $id) != '')
+        $html->arr['main'] = $mcache->get('server_maps_' . $id);
+    else {
+        $html->get('maps', 'sections/servers/games');
+        $html->set('id', $id);
+        $html->set('types', isset($html->arr['types']) ? $html->arr['types'] : '');
+        $html->set('maps', isset($html->arr['maps']) ? $html->arr['maps'] : '');
+        $html->set('mapsjs', $mapsjs);
+        $html->pack('main');
+
+        $mcache->set('server_maps_' . $id, $html->arr['main'], false, 3);
+    }
+}
+?>

+ 69 - 0
system/sections/servers/rust/maps/delete.php

@@ -0,0 +1,69 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+if (!$go)
+    exit;
+
+$sql->query('SELECT `unit`, `tarif`, `map_start` FROM `servers` WHERE `id`="' . $id . '" LIMIT 1');
+$server = array_merge($server, $sql->get());
+
+$sql->query('SELECT `address`, `passwd` FROM `units` WHERE `id`="' . $server['unit'] . '" LIMIT 1');
+$unit = $sql->get();
+
+if (!isset($ssh))
+    include(LIB . 'ssh.php');
+
+if (!$ssh->auth($unit['passwd'], $unit['address']))
+    sys::outjs(array('e' => sys::text('error', 'ssh')), $nmch);
+
+$sql->query('SELECT `install` FROM `tarifs` WHERE `id`="' . $server['tarif'] . '" LIMIT 1');
+$tarif = $sql->get();
+
+$dir = $tarif['install'] . $server['uid'] . '/game/csgo/';
+
+// Генерация списка карт
+$ssh->set('cd ' . $dir . 'maps/ && ls | grep -iE "\.vpk$"');
+
+$maps = $ssh->get();
+
+$aMaps = explode("\n", str_ireplace('.vpk', '', $maps));
+
+// Массив переданных карт
+$in_aMaps = isset($_POST['maps']) ? $_POST['maps'] : array();
+
+// Обработка выборки
+foreach ($in_aMaps as $name => $sel)
+    if ($sel) {
+        $map = str_replace(array("\\", "'", "'", '-_-'), array('', '', '', '$'), $name);
+
+        // Проверка наличия карты
+        if (!in_array($map, $aMaps))
+            continue;
+
+        // Проверка: является ли карта стартовой
+        if ($server['map_start'] == $map)
+            continue;
+
+        $ssh->set('cd /path/maps/' . $server['game'] . '/' . sys::map($map) . ' && du -a | grep -iE "\.[a-z]{1,3}$" | awk \'{print $2}\'');
+
+        $aFiles = explode("\n", str_replace('./', '', $ssh->get()));
+
+        if (isset($aFiles[count($aFiles) - 1]) and $aFiles[count($aFiles) - 1] == '')
+            unset($aFiles[count($aFiles) - 1]);
+
+        $files = '';
+
+        foreach ($aFiles as $file)
+            $files .= $dir . $file . ' ';
+
+        $rm = '';
+        $aFlrm = explode(' ', $dir . 'maps/' . $map . '.* ' . trim($files));
+
+        foreach ($aFlrm as $flrm)
+            $rm .= sys::map($flrm) . ' ';
+
+        $ssh->set('sudo -u server' . $server['uid'] . ' screen -dmS md' . $start_point . $id . ' sh -c \'rm ' . trim($rm) . '\'');
+    }
+
+sys::outjs(array('s' => 'ok'), $nmch);
+?>

+ 55 - 0
system/sections/servers/rust/maps/install.php

@@ -0,0 +1,55 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+if (!$go)
+    exit;
+
+$sql->query('SELECT `unit`, `tarif`, `hdd` FROM `servers` WHERE `id`="' . $id . '" LIMIT 1');
+$server = array_merge($server, $sql->get());
+
+$sql->query('SELECT `address`, `passwd` FROM `units` WHERE `id`="' . $server['unit'] . '" LIMIT 1');
+$unit = $sql->get();
+
+if (!isset($ssh))
+    include(LIB . 'ssh.php');
+
+if (!$ssh->auth($unit['passwd'], $unit['address']))
+    sys::outjs(array('e' => sys::text('error', 'ssh')), $nmch);
+
+$sql->query('SELECT `install` FROM `tarifs` WHERE `id`="' . $server['tarif'] . '" LIMIT 1');
+$tarif = $sql->get();
+
+$dir = $tarif['install'] . $server['uid'] . '/game/csgo/';
+
+// Проверить наличие свободного места
+$ssh->set('cd ' . $dir . ' && du -ms');
+$hdd = ceil(sys::int($ssh->get()) / ($server['hdd'] / 100));
+$hdd = $hdd > 100 ? 100 : $hdd;
+
+if ($hdd == 100)
+    sys::outjs(array('e' => 'Невозможно выполнить установку, нет свободного места'), $nmch);
+
+// Массив переданных карт
+$in_aMaps = isset($_POST['maps']) ? $_POST['maps'] : array();
+
+// Обработка выборки
+foreach ($in_aMaps as $mid => $sel)
+    if ($sel) {
+        $map = sys::int($mid);
+
+        // Проверка наличия карты
+        $sql->query('SELECT `id`, `name` FROM `maps` WHERE `id`="' . $map . '" AND `unit`="' . $server['unit'] . '" AND `game`="' . $server['game'] . '" LIMIT 1');
+        if (!$sql->num())
+            continue;
+
+        $map = $sql->get();
+
+        $cp = 'cp /path/maps/' . $server['game'] . '/' . sys::map($map['name']) . '.* ' . $dir . 'maps/;'
+            . 'cd /path/maps/' . $server['game'] . '/' . sys::map($map['name']) . '/ && cp -r * ' . $dir;
+
+        $ssh->set('sudo -u server' . $server['uid'] . ' screen -dmS mc' . $start_point . $id . ' sh -c \'' . $cp . '\'');
+    }
+
+sys::outjs(array('s' => 'ok'), $nmch);
+?>

+ 61 - 0
system/sections/servers/rust/maps/list.php

@@ -0,0 +1,61 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+$html->nav('Установка карт');
+
+// Категории для быстрой сортировки
+$html->get('types', 'sections/servers/' . $server['game'] . '/maps');
+
+$html->set('id', $id);
+
+$html->pack('types');
+
+$type = false;
+
+if (isset($url['type']) and in_array($url['type'], array('de', 'cs', 'aim', 'awp', 'bhop', 'csde', 'deathrun', 'jail')))
+    $type = '^' . $url['type'] . '\_';
+
+if ($type)
+    $sql->query('SELECT `id`, `name` FROM `maps` WHERE `unit`="' . $server['unit'] . '" AND `game`="' . $server['game'] . '" AND `name` REGEXP FROM_BASE64(\'' . base64_encode($type) . '\') ORDER BY `name` ASC LIMIT 72');
+else {
+    $sql->query('SELECT `id` FROM `maps` WHERE `unit`="' . $server['unit'] . '" AND `game`="' . $server['game'] . '"');
+
+    // Массив для построения страниц
+    $aPage = sys::page($page, $sql->num(), 30);
+
+    // Генерация массива ($html->arr['pages']) страниц
+    sys::page_gen($aPage['ceil'], $page, $aPage['page'], 'servers/id/' . $id . '/section/maps/subsection/list');
+
+    $sql->query('SELECT `id`, `name` FROM `maps` WHERE `unit`="' . $server['unit'] . '" AND `game`="' . $server['game'] . '" ORDER BY `name` ASC LIMIT ' . $aPage['num'] . ', 30');
+}
+
+$mapsjs = '';
+$i = 0;
+
+while ($map = $sql->get()) {
+    $i += 1;
+
+    $mapsjs .= $i . ' : "' . $map['id'] . '",';
+
+    $html->get('map_install', 'sections/servers/games/maps');
+
+    $html->set('id', $map['id']);
+    $html->set('img', sys::img($map['name'], $server['game']));
+    $html->set('name', $map['name']);
+
+    $html->pack('maps');
+}
+
+$html->get('install', 'sections/servers/games/maps');
+
+$html->set('id', $id);
+
+$html->set('types', isset($html->arr['types']) ? $html->arr['types'] : '');
+$html->set('maps', isset($html->arr['maps']) ? $html->arr['maps'] : 'К сожалению карты не найдены в базе');
+$html->set('amaps', $mapsjs);
+$html->set('pages', isset($html->arr['pages']) ? $html->arr['pages'] : '');
+$html->set('cdn', $cfg['cdn']);
+
+$html->pack('main');
+?>

+ 90 - 0
system/sections/servers/rust/maps/listing.php

@@ -0,0 +1,90 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+$html->nav('Списки карт');
+
+$sql->query('SELECT `address`, `passwd` FROM `units` WHERE `id`="' . $server['unit'] . '" LIMIT 1');
+$unit = $sql->get();
+
+if (!isset($ssh))
+    include(LIB . 'ssh.php');
+
+if (!$ssh->auth($unit['passwd'], $unit['address'])) {
+    if ($go)
+        sys::outjs(array('e' => sys::text('error', 'ssh')), $nmch);
+
+    sys::back($cfg['http'] . 'servers/id/' . $id . '/section/maps');
+}
+
+$sql->query('SELECT `install` FROM `tarifs` WHERE `id`="' . $server['tarif'] . '" LIMIT 1');
+$tarif = $sql->get();
+
+// Директория сервера
+$dir = $tarif['install'] . $server['uid'] . '/game/csgo/';
+
+// Генерация списка
+if ($go and isset($url['gen'])) {
+    $ssh->set('cd ' . $dir . 'maps/ && du -ah | grep -e "\.vpk$" | awk \'{print $2}\'');
+
+    $maps = $ssh->get();
+
+    $aMaps = explode("\n", str_ireplace(array('./', '.vpk'), '', $maps));
+
+    sort($aMaps);
+    reset($aMaps);
+
+    $list = '';
+
+    foreach ($aMaps as $index => $map) {
+        $aMap = explode('/', $map);
+        $name = end($aMap);
+        if (strlen($name) < 4)
+            continue;
+
+        $list .= $map . "\n";
+    }
+
+    sys::outjs(array('s' => $list), $nmch);
+}
+
+$aFiles = array(
+    'mapcycle' => 'mapcycle.txt',
+    'maps' => 'maplist.txt'
+);
+
+// Сохранение
+if ($go and isset($url['file'])) {
+    if (!array_key_exists($url['file'], $aFiles))
+        exit;
+
+    $data = isset($_POST['data']) ? $_POST['data'] : '';
+
+    $temp = sys::temp($data);
+
+    // Отправление файла на сервер
+    $ssh->setfile($temp, $dir . $aFiles[$url['file']], 0644);
+
+    // Смена владельца/группы файла
+    $ssh->set('chown server' . $server['uid'] . ':servers ' . $dir . $aFiles[$url['file']]);
+
+    unlink($temp);
+
+    sys::outjs(array('s' => 'ok'), $nmch);
+}
+
+$ssh->set('sudo -u server' . $server['uid'] . ' sh -c "touch ' . $dir . $aFiles['mapcycle'] . '; cat ' . $dir . $aFiles['mapcycle'] . '"');
+$mapcycle = $ssh->get();
+
+$ssh->set('sudo -u server' . $server['uid'] . ' sh -c "touch ' . $dir . $aFiles['maps'] . '; cat ' . $dir . $aFiles['maps'] . '"');
+$maps = $ssh->get();
+
+$html->get('listing', 'sections/servers/' . $server['game'] . '/maps');
+
+$html->set('id', $id);
+
+$html->set('mapcycle', $mapcycle);
+$html->set('maps', $maps);
+
+$html->pack('main');
+?>

+ 59 - 0
system/sections/servers/rust/maps/search.php

@@ -0,0 +1,59 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+$text = isset($_POST['text']) ? str_ireplace('.vpk', '', $_POST['text']) : '';
+
+$mkey = md5($text . $id);
+
+$cache = $mcache->get($mkey);
+
+if (is_array($cache)) {
+    if ($go)
+        sys::outjs($cache, $nmch);
+
+    sys::outjs($cache);
+}
+
+if (!isset($text{2})) {
+    if ($go)
+        sys::outjs(array('e' => 'Для выполнения поиска, необходимо больше данных'), $nmch);
+
+    sys::outjs(array('e' => ''));
+}
+
+// Поиск по картам
+if ($text{0} == '^') {
+    $sql->query('SELECT `id`, `name` FROM `maps` WHERE `unit`="' . $server['unit'] . '" AND `game`="' . $server['game'] . '" AND `name` REGEXP FROM_BASE64(\'' . base64_encode(str_replace('_', '\_', $text) . '') . '\') ORDER BY `name` ASC LIMIT 12');
+    $text = substr($text, 1);
+} else
+    $sql->query('SELECT `id`, `name` FROM `maps` WHERE `unit`="' . $server['unit'] . '" AND `game`="' . $server['game'] . '" AND `name` LIKE FROM_BASE64(\'' . base64_encode('%' . str_replace('_', '\_', $text) . '%') . '\') ORDER BY `name` ASC LIMIT 12');
+
+if (!$sql->num()) {
+    if ($go)
+        sys::outjs(array('e' => 'По вашему запросу ничего не найдено'), $nmch);
+
+    sys::outjs(array('e' => 'По вашему запросу ничего не найдено'));
+}
+
+$i = 0;
+$mapsjs = '';
+
+while ($map = $sql->get()) {
+    $i += 1;
+
+    $mapsjs[$i] = 's' . $map['id'];
+
+    $html->get('map_search', 'sections/servers/games/maps');
+
+    $html->set('id', 's' . $map['id']);
+    $html->set('img', sys::img($map['name'], $server['game']));
+    $html->set('name', sys::find($map['name'], $text));
+
+    $html->pack('maps');
+}
+
+$mcache->set($mkey, array('maps' => $html->arr['maps'], 'mapsjs' => $mapsjs), false, 15);
+
+sys::outjs(array('maps' => $html->arr['maps'], 'mapsjs' => $mapsjs));
+?>

+ 165 - 0
system/sections/servers/rust/owners.php

@@ -0,0 +1,165 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+$aAccessI = array(
+    'start' => 'Включение',
+    'stop' => 'Выключение',
+    'restart' => 'Перезагрузка',
+    'change' => 'Смена карты',
+    'reinstall' => 'Переустановка',
+    'update' => 'Обновление',
+    'console' => 'Раздел "Консоль"',
+    'settings' => 'Раздел "Настройки"',
+    'plugins' => 'Раздел "Плагины"',
+    'maps' => 'Раздел "Карты"'
+);
+
+$aAccess = array('start', 'stop', 'restart', 'change', 'reinstall', 'update', 'console', 'settings', 'plugins', 'maps');
+
+// Проверка прав
+if (isset($url['rights']) and $url['rights'] > 0) {
+    $sql->query('SELECT `rights` FROM `owners` WHERE `id`="' . sys::int($url['rights']) . '" AND `server`="' . $id . '" LIMIT 1');
+
+    if (!$sql->num())
+        sys::outjs(array('e' => 'Совладелец не найден.'));
+
+    $owner = $sql->get();
+
+    $aRights = sys::b64djs($owner['rights']);
+
+    $rights = '';
+
+    foreach ($aAccess as $access)
+        if ($aRights[$access]) $rights .= $aAccessI[$access] . ', ';
+
+    sys::outjs(array('s' => substr($rights, 0, -2)));
+}
+
+// Удаление совладельца
+if (isset($url['delete']) and $url['delete'] > 0) {
+    $sql->query('SELECT `rights` FROM `owners` WHERE `id`="' . sys::int($url['delete']) . '" AND `server`="' . $id . '" LIMIT 1');
+
+    if ($sql->num())
+        $sql->query('DELETE FROM `owners` WHERE `id`="' . sys::int($url['delete']) . '" AND `server`="' . $id . '" LIMIT 1');
+
+    sys::back($cfg['http'] . 'servers/id/' . $id . '/section/owners');
+}
+
+// Добавление совладельца
+if ($go) {
+    $nmch = sys::rep_act('server_owners_go_' . $id, 5);
+
+    $aData = (isset($_POST['owner']) and is_array($_POST['owner'])) ? $_POST['owner'] : array();
+
+    $aDate = isset($aData['\'time\'']) ? explode('.', $aData['\'time\'']) : explode('.', date('d.m.Y', $start_point));
+    $aTime = explode(':', date('H:i:s', $start_point));
+
+    if (!isset($aDate[1], $aDate[0], $aDate[2]) || !checkdate($aDate[1], $aDate[0], $aDate[2]))
+        sys::outjs(array('e' => 'Дата доступа указана неверно.'), $nmch);
+
+    $time = mktime($aTime[0], $aTime[1], $aTime[2], $aDate[1], $aDate[0], $aDate[2]) + 3600;
+
+    if ($time < $start_point)
+        sys::outjs(array('e' => 'Время доступа не может быть меньше 60 минут.'), $nmch);
+
+    // Проверка пользователя
+    if (!isset($aData['\'user\'']))
+        sys::outjs(array('e' => 'Необходимо указать пользователя.'), $nmch);
+
+    if (is_numeric($aData['\'user\'']))
+        $sql->query('SELECT `id` FROM `users` WHERE `id`="' . $aData['\'user\''] . '" LIMIT 1');
+    else {
+        if (sys::valid($aData['\'user\''], 'other', $aValid['login']))
+            sys::outjs(array('e' => sys::text('input', 'login_valid')), $nmch);
+
+        $sql->query('SELECT `id` FROM `users` WHERE `login`="' . $aData['\'user\''] . '" LIMIT 1');
+    }
+
+    if (!$sql->num())
+        sys::outjs(array('e' => 'Пользователь не найден в базе.'), $nmch);
+
+    $uowner = $sql->get();
+
+    $owner = $sql->query('SELECT `id` FROM `owners` WHERE `server`="' . $id . '" AND `user`="' . $uowner['id'] . '" LIMIT 1');
+
+    // Если не обновление доступа совладельца, проверить кол-во
+    if (!$sql->num($owner)) {
+        $sql->query('SELECT `id` FROM `owners` WHERE `server`="' . $id . '" LIMIT 5');
+
+        if ($sql->num() == 5)
+            sys::outjs(array('e' => 'Вы добавили максимально число совладельцев.'), $nmch);
+    }
+
+    $sql->query('SELECT `id` FROM `servers` WHERE `id`="' . $id . '" AND `user`="' . $uowner['id'] . '" LIMIT 1');
+    if ($sql->num())
+        sys::outjs(array('e' => 'Владельца сервера нельзя добавить в совладельцы.'), $nmch);
+
+    $aRights = array();
+
+    $check = 0;
+
+    foreach ($aAccess as $access) {
+        $aRights[$access] = isset($aData['\'' . $access . '\'']) ? 1 : 0;
+
+        $check += $aRights[$access];
+    }
+
+    if (!$check)
+        sys::outjs(array('e' => 'Необходимо включить минимум одно разрешение.'), $nmch);
+
+
+    if ($sql->num($owner))
+        $sql->query('UPDATE `owners` set `rights`="' . sys::b64js($aRights) . '", `time`="' . $time . '" WHERE `server`="' . $id . '" AND `user`="' . $uowner['id'] . '" LIMIT 1');
+    else
+        $sql->query('INSERT INTO `owners` set `server`="' . $id . '", `user`="' . $uowner['id'] . '", `rights`="' . sys::b64js($aRights) . '", `time`="' . $time . '"');
+
+    sys::outjs(array('s' => 'ok'), $nmch);
+}
+
+$html->nav($server['address'], $cfg['http'] . 'servers/id/' . $id);
+
+$html->nav('Друзья');
+
+$cache = $mcache->get('server_owners_' . $id);
+
+if ($cache != '')
+    $html->arr['main'] = $cache;
+else {
+    $owners = $sql->query('SELECT `id`, `user`, `rights`, `time` FROM `owners` WHERE `server`="' . $id . '" AND `time`>"' . $start_point . '" ORDER BY `id` ASC LIMIT 5');
+
+    if ($sql->num())
+        include(LIB . 'games/games.php');
+
+    while ($owner = $sql->get($owners)) {
+        $sql->query('SELECT `login` FROM `users` WHERE `id`="' . $owner['user'] . '" LIMIT 1');
+        if (!$sql->num())
+            continue;
+
+        $uowner = $sql->get();
+
+        $rights = games::owners(sys::b64djs($owner['rights']));
+
+        $html->get('owners_list', 'sections/servers/games');
+
+        $html->set('id', $id);
+        $html->set('oid', $owner['id']);
+        $html->set('user', $uowner['login']);
+        $html->set('rights', $rights);
+        $html->set('time', date('d.m.Y - H:i', $owner['time']));
+
+        $html->pack('owners');
+    }
+
+    $html->get('owners', 'sections/servers/' . $server['game']);
+
+    $html->set('id', $id);
+    $html->set('time', date('d.m.Y', $start_point));
+
+    $html->set('owners', isset($html->arr['owners']) ? $html->arr['owners'] : 'Для данного сервера совладельцы отсутсвуют.');
+
+    $html->pack('main');
+
+    $mcache->set('server_owners_' . $id, $html->arr['main'], false, 1);
+}
+?>

+ 149 - 0
system/sections/servers/rust/plugins.php

@@ -0,0 +1,149 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+$sql->query('SELECT `unit`, `tarif`, `pack` FROM `servers` WHERE `id`="' . $id . '" LIMIT 1');
+$server = array_merge($server, $sql->get());
+
+$html->nav($server['address'], $cfg['http'] . 'servers/id/' . $id);
+
+// Подразделы
+$aSub = array('install', 'delete', 'update', 'plugin', 'config', 'search');
+
+// Если выбран подраздел
+if (isset($url['subsection']) and in_array($url['subsection'], $aSub)) {
+    $html->nav('Плагины', $cfg['http'] . 'servers/id/' . $id . '/section/plugins');
+
+    $nmch = sys::rep_act('server_plugins_go_' . $id, 10);
+
+    include(SEC . 'servers/games/plugins/' . $url['subsection'] . '.php');
+} else {
+    $html->nav('Плагины');
+
+    // Если есть кеш
+    if ($mcache->get('server_plugins_' . $id) != '')
+        $html->arr['main'] = $mcache->get('server_plugins_' . $id);
+    else {
+        include(LIB . 'games/plugins.php');
+
+        // Категории
+        $cats = $sql->query('SELECT `id`, `name` FROM `plugins_category` WHERE `game`="' . $server['game'] . '" ORDER BY `sort` ASC');
+        while ($cat = $sql->get($cats)) {
+            // Плагины
+            $plugins = $sql->query('SELECT `id`, `name`, `desc`, `images`, `status`, `upd`, `packs`, `price` FROM `plugins` WHERE `cat`="' . $cat['id'] . '" ORDER BY `sort`, `id` ASC');
+            while ($plugin = $sql->get($plugins)) {
+                // Проверка, установлен ли плагин на сервер
+                $sql->query('SELECT `id` FROM `plugins_install` WHERE `server`="' . $id . '" AND `plugin`="' . $plugin['id'] . '" LIMIT 1');
+                if ($sql->num())
+                    continue;
+
+                // Проверка наличия обновленной версии плагина
+                if ($plugin['upd']) {
+                    $idp = $plugin['id'];
+
+                    $sql->query('SELECT `name`, `desc`, `images`, `status`, `packs`, `price` FROM `plugins_update` WHERE `plugin`="' . $plugin['id'] . '" ORDER BY `id` DESC LIMIT 1');
+                    if ($sql->num()) {
+                        $plugin = $sql->get();
+
+                        $plugin['id'] = $idp;
+                    } else
+                        $plugin['upd'] = 0;
+                }
+
+                // Проверка на доступность плагина к установленной на сервере сборке
+                $packs = strpos($plugin['packs'], ':') ? explode(':', $plugin['packs']) : array($plugin['packs']);
+                if (!in_array($server['pack'], $packs) and $plugin['packs'] != 'all')
+                    continue;
+
+                $images = plugins::images($plugin['images'], $plugin['id']);
+
+                if ($plugin['price']) {
+                    $sql->query('SELECT `id` FROM `plugins_buy` WHERE `plugin`="' . $plugin['id'] . '" AND `server`="' . $id . '" LIMIT 1');
+                    $buy = $sql->num();
+                }
+
+                // Шаблон плагина
+                $html->get('plugin', 'sections/servers/games/plugins');
+
+                $html->set('id', $id);
+                $html->set('plugin', $plugin['id']);
+
+                plugins::status($plugin['status']);
+
+                $html->set('name', htmlspecialchars_decode($plugin['name']));
+                $html->set('desc', htmlspecialchars_decode($plugin['desc']));
+
+                if (!empty($images)) {
+                    $html->unit('images', 1);
+                    $html->set('images', $images);
+                } else
+                    $html->unit('images');
+
+                if (!$buy and $plugin['price']) {
+                    $html->unit('price', true, true);
+                    $html->set('price', $plugin['price']);
+                } else
+                    $html->unit('price', false, true);
+
+                $html->pack('plugins');
+            }
+
+            // Шаблон блока плагинов
+            $html->get('category', 'sections/servers/games/plugins');
+
+            $html->set('name', $cat['name']);
+            $html->set('plugins', isset($html->arr['plugins']) ? $html->arr['plugins'] : 'Доступных для установки плагинов нет.', 1);
+
+            $html->pack('addons');
+        }
+
+        unset($cats, $cat, $plugins, $plugin);
+
+        // Список установленных плагинов на сервер (отдельный блок)
+        $pl_ins = $sql->query('SELECT `plugin`, `upd`, `time` FROM `plugins_install` WHERE `server`="' . $id . '" ORDER BY `plugin`');
+        while ($plugin = $sql->get($pl_ins)) {
+            $sql->query('SELECT `id` FROM `plugins` WHERE `id`="' . $plugin['plugin'] . '" LIMIT 1');
+            if (!$sql->num())
+                continue;
+
+            $isUpd = $plugin['upd'];
+
+            // Если установлен обновленный плагин
+            if ($isUpd)
+                $sql->query('SELECT `name`, `desc`, `status`, `cfg`, `upd` FROM `plugins_update` WHERE `id`="' . $isUpd . '" LIMIT 1');
+            else
+                $sql->query('SELECT `name`, `desc`, `status`, `cfg`, `upd` FROM `plugins` WHERE `id`="' . $plugin['plugin'] . '" LIMIT 1');
+
+            $plugin = array_merge($plugin, $sql->get());
+
+            // Шаблон плагина
+            $html->get('plugin_install', 'sections/servers/games/plugins');
+
+            $html->set('id', $id);
+            $html->set('plugin', $plugin['plugin']);
+
+            plugins::status($plugin['status']);
+
+            if ($plugin['cfg']) $html->unit('config', 1); else $html->unit('config');
+
+            if ($plugin['upd']) $html->unit('update', 1); else $html->unit('update');
+
+            $html->set('name', htmlspecialchars_decode($plugin['name']));
+            $html->set('time', sys::today($plugin['time']));
+            $html->set('desc', htmlspecialchars_decode($plugin['desc']));
+
+            $html->pack('install');
+        }
+
+        $html->get('plugins', 'sections/servers/games');
+
+        $html->set('id', $id);
+        $html->set('addons', isset($html->arr['addons']) ? $html->arr['addons'] : '');
+        $html->set('install', isset($html->arr['install']) ? $html->arr['install'] : 'Установленные плагины отсутствуют.');
+
+        $html->pack('main');
+
+        $mcache->set('server_plugins_' . $id, $html->arr['main'], false, 60);
+    }
+}
+?>

+ 51 - 0
system/sections/servers/rust/rcon.php

@@ -0,0 +1,51 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+if ($go) {
+    include(LIB . 'games/' . $server['game'] . '/rcon.php');
+
+    if (isset($url['action']) and in_array($url['action'], array('kick', 'kill'))) {
+        $player = isset($_POST['player']) ? $_POST['player'] : sys::outjs(array('e' => 'Необходимо выбрать игрока.'));
+
+        if ($url['action'] == 'kick')
+            rcon::cmd(array_merge($server, array('id' => $id)), 'kickid "' . $player . '" "EGP Panel"');
+        else
+            rcon::cmd(array_merge($server, array('id' => $id)), 'sm_slay "' . $player . '"');
+
+        sys::outjs(array('s' => 'ok'));
+    }
+
+    include(LIB . 'geo.php');
+    $SxGeo = new SxGeo(DATA . 'SxGeoCity.dat');
+
+    $aPlayers = rcon::players(rcon::cmd(array_merge($server, array('id' => $id))));
+
+    foreach ($aPlayers as $i => $aPlayer) {
+        $html->get('player', 'sections/servers/' . $server['game'] . '/rcon');
+
+        $html->set('i', $i);
+        $html->set('userid', $aPlayer['userid']);
+        $html->set('name', $aPlayer['name']);
+        $html->set('steamid', $aPlayer['steamid']);
+        $html->set('time', $aPlayer['time']);
+        $html->set('ping', $aPlayer['ping']);
+        $html->set('ip', $aPlayer['ip']);
+        $html->set('ico', $aPlayer['ico']);
+        $html->set('country', $aPlayer['country']);
+
+        $html->pack('players');
+    }
+
+    sys::outjs(array('s' => isset($html->arr['players']) ? $html->arr['players'] : ''));
+}
+
+$html->nav($server['address'], $cfg['http'] . 'servers/id/' . $id);
+$html->nav('Rcon управление игроками');
+
+$html->get('rcon', 'sections/servers/' . $server['game']);
+
+$html->set('id', $id);
+
+$html->pack('main');
+?>

+ 74 - 0
system/sections/servers/rust/settings.php

@@ -0,0 +1,74 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+$sql->query('SELECT `uid`, `unit`, `tarif`, `pack`, `ddos` FROM `servers` WHERE `id`="' . $id . '" LIMIT 1');
+$server = array_merge($server, $sql->get());
+
+$html->nav($server['address'], $cfg['http'] . 'servers/id/' . $id);
+
+$aSub = array('start', 'server', 'admins', 'bans', 'firewall', 'crontab', 'startlogs', 'debug', 'logs', 'smlogs', 'pack', 'file', 'antiddos', 'api');
+
+// Если выбран подраздел
+if (isset($url['subsection']) and in_array($url['subsection'], $aSub)) {
+    $html->nav('Настройки', $cfg['http'] . 'servers/id/' . $id . '/section/settings');
+
+    if ($go)
+        $nmch = sys::rep_act('server_settings_go_' . $id, 10);
+
+    if (in_array($url['subsection'], $aRouteSub['settings']))
+        include(SEC . 'servers/games/settings/' . $url['subsection'] . '.php');
+    else
+        include(SEC . 'servers/' . $server['game'] . '/settings/' . $url['subsection'] . '.php');
+} else {
+    $html->nav('Настройки');
+
+    if ($mcache->get('server_settings_' . $id) != '')
+        $html->arr['main'] = $mcache->get('server_settings_' . $id);
+    else {
+        $sql->query('SELECT `name`, `packs` FROM `tarifs` WHERE `id`="' . $server['tarif'] . '" LIMIT 1');
+        $tarif = $sql->get();
+
+        $aEditslist = 1;
+        include(DATA . 'filedits.php');
+
+        // Построение списка доступных сборок
+        $aPacks = sys::b64djs($tarif['packs']);
+
+        $packs = '<option value="' . $server['pack'] . '">' . $aPacks[$server['pack']] . '</option>';
+        unset($aPacks[$server['pack']]);
+
+        foreach ($aPacks as $pack => $desc)
+            $packs .= '<option value="' . $pack . '">' . $desc . '</option>';
+
+        $antiddos = '<option value="0">Индивидуальная защита отключена</option>'
+            . '<option value="1">Индивидуальная защита (Заблокировать всех кроме: RU, UA)</option>'
+            . '<option value="2">Индивидуальная защита (Заблокировать всех кроме: AM, BY, UA, RU, KZ)</option>';
+
+        include(SEC . 'servers/' . $server['game'] . '/settings/start.php');
+
+        $html->get('settings', 'sections/servers/' . $server['game']);
+        $html->set('id', $id);
+        $html->set('packs', $packs);
+        $html->set('antiddos', str_replace($server['ddos'], $server['ddos'] . '" selected="select', $antiddos));
+        $html->set('start', $html->arr['start']);
+        if (isset($html->arr['edits'])) {
+            $html->set('edits', $html->arr['edits']);
+            $html->unit('edits', 1);
+        } else
+            $html->unit('edits');
+
+        $sql->query('SELECT `key` FROM `api` WHERE `server`="' . $id . '" LIMIT 1');
+        if ($sql->num()) {
+            $api = $sql->get();
+
+            $html->set('api', $api['key']);
+            $html->unit('api', 1, 1);
+        } else
+            $html->unit('api', 0, 1);
+        $html->pack('main');
+
+        $mcache->set('server_settings_' . $id, $html->arr['main'], false, 60);
+    }
+}
+?>

+ 110 - 0
system/sections/servers/rust/settings/admins.php

@@ -0,0 +1,110 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+$html->nav('Управление администраторами');
+
+if ($go) {
+    $sql->query('SELECT `address`, `passwd` FROM `units` WHERE `id`="' . $server['unit'] . '" LIMIT 1');
+    $unit = $sql->get();
+
+    $sql->query('SELECT `install` FROM `tarifs` WHERE `id`="' . $server['tarif'] . '" LIMIT 1');
+    $tarif = $sql->get();
+
+    include(LIB . 'ssh.php');
+
+    if (!$ssh->auth($unit['passwd'], $unit['address']))
+        sys::outjs(array('e' => sys::text('error', 'ssh')), $nmch);
+
+    $aData = array();
+
+    $aData['active'] = isset($_POST['active']) ? $_POST['active'] : '';
+    $aData['value'] = isset($_POST['value']) ? $_POST['value'] : '';
+    $aData['passwd'] = isset($_POST['passwd']) ? $_POST['passwd'] : '';
+    $aData['flags'] = isset($_POST['flags']) ? $_POST['flags'] : '';
+    $aData['immunity'] = isset($_POST['immunity']) ? sys::int($_POST['immunity']) : '';
+    $aData['time'] = isset($_POST['time']) ? $_POST['time'] : '';
+    $aData['info'] = isset($_POST['info']) ? $_POST['info'] : '';
+
+    // Удаление текущих записей
+    $sql->query('DELETE FROM `admins_' . $server['game'] . '` WHERE `server`="' . $id . '"');
+
+    $usini = '';
+
+    foreach ($aData['value'] as $index => $val) {
+        if ($val != '') {
+            $aDate = isset($aData['time'][$index]) ? explode('.', $aData['time'][$index]) : explode('.', date('d.m.Y', $start_point));
+
+            if (!isset($aDate[1], $aDate[0], $aDate[2]) || !checkdate($aDate[1], $aDate[0], $aDate[2]))
+                $aDate = explode('.', date('d.m.Y', $start_point));
+
+            $time = mktime(0, 0, 0, $aDate[1], $aDate[0], $aDate[2]);
+
+            $aData['active'][$index] = isset($aData['active'][$index]) ? 1 : 0;
+            $aData['passwd'][$index] = isset($aData['passwd'][$index]) ? $aData['passwd'][$index] : '';
+            $aData['flags'][$index] = isset($aData['flags'][$index]) ? $aData['flags'][$index] : '';
+            $aData['info'][$index] = isset($aData['info'][$index]) ? $aData['info'][$index] : '';
+
+            $text = '"' . $val . '" "' . $aData['immunity'][$index] . ':' . $aData['flags'][$index] . '" "' . $aData['passwd'][$index] . '"';
+
+            $sql->query('INSERT INTO `admins_' . $server['game'] . '` set'
+                . '`server`="' . $id . '",'
+                . '`value`="' . htmlspecialchars($val) . '",'
+                . '`active`="' . $aData['active'][$index] . '",'
+                . '`passwd`="' . htmlspecialchars($aData['passwd'][$index]) . '",'
+                . '`flags`="' . htmlspecialchars($aData['flags'][$index]) . '",'
+                . '`immunity`="' . $aData['immunity'][$index] . '",'
+                . '`time`="' . $time . '",'
+                . '`text`="' . htmlspecialchars($text) . '",'
+                . '`info`="' . htmlspecialchars($aData['info'][$index]) . '"');
+
+            if ($aData['active'][$index])
+                $usini .= $text . PHP_EOL;
+        }
+    }
+
+    $temp = sys::temp($usini);
+
+    $ssh->setfile($temp, $tarif['install'] . $server['uid'] . '/game/csgo/addons/sourcemod/configs/admins_simple.ini', 0644);
+
+    unlink($temp);
+
+    $ssh->set('chown server' . $server['uid'] . ':servers ' . $tarif['install'] . $server['uid'] . '/game/csgo/addons/sourcemod/configs/admins_simple.ini');
+
+    $ssh->set("sudo -u server" . $server['uid'] . " screen -p 0 -S s_" . $server['uid'] . " -X eval 'stuff \" sm_reloadadmins\"\015'");
+
+    sys::outjs(array('s' => 'ok'), $nmch);
+}
+
+// Построение списка добавленных админов
+$sql->query('SELECT `id`, `value`, `active`, `passwd`, `flags`, `immunity`, `time`, `info` FROM `admins_' . $server['game'] . '` WHERE `server`="' . $id . '" ORDER BY `id` ASC');
+while ($admin = $sql->get()) {
+    $html->get('list', 'sections/servers/' . $server['game'] . '/settings/admins');
+
+    if ($admin['active'])
+        $html->unit('active', 1);
+    else
+        $html->unit('active');
+
+    $html->set('id', $admin['id']);
+    $html->set('value', $admin['value']);
+    $html->set('passwd', $admin['passwd']);
+    $html->set('flags', $admin['flags']);
+    $html->set('immunity', $admin['immunity']);
+    $html->set('time', date('d.m.y', $admin['time']));
+    $html->set('info', $admin['info']);
+
+    $html->pack('admins');
+}
+
+$sql->query('SELECT `id` FROM `admins_' . $server['game'] . '` WHERE `server`="' . $id . '" ORDER BY `id` DESC LIMIT 1');
+$max = $sql->get();
+
+$html->get('admins', 'sections/servers/' . $server['game'] . '/settings');
+
+$html->set('id', $id);
+$html->set('admins', isset($html->arr['admins']) ? $html->arr['admins'] : '');
+$html->set('index', $max['id'] < 1 ? 0 : $max['id']);
+
+$html->pack('main');
+?>

+ 154 - 0
system/sections/servers/rust/settings/bans.php

@@ -0,0 +1,154 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+$html->nav('Бан листы');
+
+$sql->query('SELECT `address`, `passwd` FROM `units` WHERE `id`="' . $server['unit'] . '" LIMIT 1');
+$unit = $sql->get();
+
+$sql->query('SELECT `install` FROM `tarifs` WHERE `id`="' . $server['tarif'] . '" LIMIT 1');
+$tarif = $sql->get();
+
+include(LIB . 'ssh.php');
+
+if (!$ssh->auth($unit['passwd'], $unit['address']))
+    sys::back($cfg['http'] . 'servers/id/' . $id . '/section/settings');
+
+// Путь к файлам (banned_user.cfg / banned_ip.cfg)
+$folder = $tarif['install'] . $server['uid'] . '/game/csgo';
+
+// Если бан/разбан/проверка
+if ($go) {
+    $aData = array();
+
+    $aData['value'] = isset($_POST['value']) ? trim($_POST['value']) : sys::outjs(array('e' => sys::text('servers', 'bans')), $nmch);
+    $aData['userid'] = isset($_POST['userid']) ? sys::int($_POST['userid']) : false;
+    $aData['amxbans'] = isset($_POST['amxbans']) ? true : false;
+
+    // Проверка входных данных
+    if (sys::valid($aData['value'], 'steamid') and sys::valid($aData['value'], 'steamid3') and sys::valid($aData['value'], 'ip'))
+        sys::outjs(array('e' => sys::text('servers', 'bans')), $nmch);
+
+    // Если указан steamid
+    if (sys::valid($aData['value'], 'ip')) {
+        // бан
+        if (isset($url['action']) and $url['action'] == 'ban') {
+            // Если включен sourcebans
+            if ($aData['amxbans'] and $aData['userid'])
+                $ssh->set("sudo -u server" . $server['uid'] . " screen -p 0 -S s_" . $server['uid'] . " -X eval 'stuff \"sm_ban 0 " . $aData['userid'] . " EGP\"\015'");
+            else
+                $ssh->set("sudo -u server" . $server['uid'] . " screen -p 0 -S s_" . $server['uid'] . " -X eval 'stuff \"banid 0.0 " . $aData['value'] . " kick\"\015'");
+
+            $ssh->set('cd ' . $folder . ' && sudo -u server' . $server['uid'] . ' fgrep ' . $aData['value'] . ' banned_user.cfg | awk \'{print $3}\'');
+
+            if ($aData['value'] != trim($ssh->get()))
+                $ssh->set('sudo -u server' . $server['uid'] . ' sh -c "echo \"banid 0.0 ' . $aData['value'] . '\" >> ' . $folder . '/banned_user.cfg"');
+
+            sys::outjs(array('s' => 'ok'), $nmch);
+
+            // разбан
+        } elseif (isset($url['action']) and $url['action'] == 'unban') {
+            // Убираем запись из banned_user.cfg
+            $ssh->set('cd ' . $folder . ' && sudo -u server' . $server['uid'] . ' sh -c "cat banned_user.cfg | grep -v ' . $aData['value'] . ' > temp_banned.cfg; echo "" >> temp_banned.cfg && cat temp_banned.cfg > banned_user.cfg; rm temp_banned.cfg"');
+
+            // Если включен sourcebans
+            if ($aData['amxbans'])
+                $ssh->set("sudo -u server" . $server['uid'] . " screen -p 0 -S s_" . $server['uid'] . " -X eval 'stuff \"sm_unban " . $aData['value'] . "\"\015'");
+            else {
+                $ssh->set("sudo -u server" . $server['uid'] . " screen -p 0 -S s_" . $server['uid'] . " -X eval 'stuff \"removeid " . $aData['value'] . "\"\015'");
+                $ssh->set("sudo -u server" . $server['uid'] . " screen -p 0 -S s_" . $server['uid'] . " -X eval 'stuff \"writeid\"\015'");
+            }
+
+            sys::outjs(array('s' => 'ok'), $nmch);
+            // проверка
+        } else {
+            $ssh->set('cd ' . $folder . ' && sudo -u server' . $server['uid'] . ' fgrep ' . $aData['value'] . ' banned_user.cfg | awk \'{print $3}\'');
+
+            if ($aData['value'] == trim($ssh->get()))
+                sys::outjs(array('ban' => 'Данный SteamID <u>найден</u> в файле banned_user.cfg'), $nmch);
+
+            sys::outjs(array('unban' => 'Данный SteamID <u>не найден</u> в файле banned_user.cfg'), $nmch);
+        }
+    } else {
+        // бан
+        if (isset($url['action']) and $url['action'] == 'ban') {
+            // Если включен sourcebans
+            if ($aData['amxbans'])
+                $ssh->set("sudo -u server" . $server['uid'] . " screen -p 0 -S s_" . $server['uid'] . " -X eval 'stuff \"sm_ban 0 " . $aData['value'] . " EGP\"\015'");
+            else
+                $ssh->set("sudo -u server" . $server['uid'] . " screen -p 0 -S s_" . $server['uid'] . " -X eval 'stuff \"addip 0.0 " . $aData['value'] . " EGP\"\015'");
+
+            $ssh->set('cd ' . $folder . ' && sudo -u server' . $server['uid'] . ' fgrep ' . $aData['value'] . ' banned_ip.cfg | awk \'{print $3}\'');
+
+            if ($aData['value'] != trim($ssh->get()))
+                $ssh->set('sudo -u server' . $server['uid'] . ' sh -c "echo \"addip 0.0 ' . $aData['value'] . '\" >> ' . $folder . '/banned_ip.cfg"');
+
+            sys::outjs(array('s' => 'ok'), $nmch);
+
+            // разбан
+        } elseif (isset($url['action']) and $url['action'] == 'unban') {
+            // Убираем запись из banned_ip.cfg
+            $ssh->set('cd ' . $folder . ' && sudo -u server' . $server['uid'] . ' sh -c "cat banned_ip.cfg | grep -v ' . $aData['value'] . ' > temp_listip.cfg; echo "" >> temp_listip.cfg && cat temp_listip.cfg > banned_ip.cfg; rm temp_listip.cfg"');
+
+            // Если включен sourcebans
+            if ($aData['amxbans'])
+                $ssh->set("sudo -u server" . $server['uid'] . " screen -p 0 -S s_" . $server['uid'] . " -X eval 'stuff \"amx_unban " . $aData['value'] . "\"\015'");
+            else {
+                $ssh->set("sudo -u server" . $server['uid'] . " screen -p 0 -S s_" . $server['uid'] . " -X eval 'stuff \"removeip " . $aData['value'] . "\"\015'");
+                $ssh->set("sudo -u server" . $server['uid'] . " screen -p 0 -S s_" . $server['uid'] . " -X eval 'stuff \"writeip\"\015'");
+            }
+
+            sys::outjs(array('s' => 'ok'), $nmch);
+            // проверка
+        } else {
+            $ssh->set('cd ' . $folder . ' && sudo -u server' . $server['uid'] . ' fgrep ' . $aData['value'] . ' banned_ip.cfg | awk \'{print $3}\'');
+
+            if ($aData['value'] == trim($ssh->get()))
+                sys::outjs(array('ban' => 'Данный IP <u>найден</u> в файле banned_ip.cfg'), $nmch);
+
+            sys::outjs(array('unban' => 'Данный IP <u>не найден</u> в файле banned_ip.cfg'), $nmch);
+        }
+    }
+}
+
+// Содержимое banned_user.cfg
+$ssh->set('cd ' . $folder . ' && cat banned_user.cfg | awk \'{print $3}\' | egrep "^\[U:[01]:[0-9]{3,12}\]$"');
+$aBanned = explode("\n", $ssh->get());
+
+// Содержимое banned_ip.cfg
+$ssh->set('cd ' . $folder . ' && cat banned_ip.cfg | awk \'{print $3}\' | egrep "(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[0-9]{2}|[0-9])(\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[0-9]{2}|[0-9])){3}"');
+$aListip = explode("\n", $ssh->get());
+
+if (isset($aBanned[count($aBanned) - 1]) and $aBanned[count($aBanned) - 1] == '')
+    unset($aBanned[count($aBanned) - 1]);
+
+if (isset($aListip[count($aListip) - 1]) and $aListip[count($aListip) - 1] == '')
+    unset($aListip[count($aListip) - 1]);
+
+// Построение списка забаненых по steamid
+foreach ($aBanned as $line => $steam) {
+    $html->get('bans_list', 'sections/servers/games/settings');
+
+    $html->set('value', trim($steam));
+
+    $html->pack('banned');
+}
+
+// Построение списка забаненых по ip
+foreach ($aListip as $line => $ip) {
+    $html->get('bans_list', 'sections/servers/games/settings');
+
+    $html->set('value', trim($ip));
+
+    $html->pack('listip');
+}
+
+$html->get('bans', 'sections/servers/' . $server['game'] . '/settings');
+
+$html->set('id', $id);
+$html->set('banned', isset($html->arr['banned']) ? $html->arr['banned'] : '');
+$html->set('listip', isset($html->arr['listip']) ? $html->arr['listip'] : '');
+
+$html->pack('main');
+?>

+ 28 - 0
system/sections/servers/rust/settings/debug.php

@@ -0,0 +1,28 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+$html->nav('Отладочный лог');
+
+$sql->query('SELECT `address`, `passwd` FROM `units` WHERE `id`="' . $server['unit'] . '" LIMIT 1');
+$unit = $sql->get();
+
+$sql->query('SELECT `install` FROM `tarifs` WHERE `id`="' . $server['tarif'] . '" LIMIT 1');
+$tarif = $sql->get();
+
+include(LIB . 'ssh.php');
+
+if (!$ssh->auth($unit['passwd'], $unit['address']))
+    sys::back($cfg['http'] . 'servers/id/' . $id . '/section/settings');
+
+// Чтение файла - oldstart.log
+$file = $tarif['install'] . $server['uid'] . '/debug.log';
+
+$ssh->set('echo "" >> ' . $file . ' && cat ' . $file . ' | grep "CRASH: " | grep -ve "^#\|^[[:space:]]*$"');
+
+$html->get('debug', 'sections/servers/games/settings');
+
+$html->set('log', htmlspecialchars($ssh->get()));
+
+$html->pack('main');
+?>

+ 86 - 0
system/sections/servers/rust/settings/logs.php

@@ -0,0 +1,86 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+$html->nav('Логи');
+
+$sql->query('SELECT `address`, `passwd` FROM `units` WHERE `id`="' . $server['unit'] . '" LIMIT 1');
+$unit = $sql->get();
+
+$sql->query('SELECT `install` FROM `tarifs` WHERE `id`="' . $server['tarif'] . '" LIMIT 1');
+$tarif = $sql->get();
+
+include(LIB . 'ssh.php');
+
+if (!$ssh->auth($unit['passwd'], $unit['address']))
+    sys::back($cfg['http'] . 'servers/id/' . $id . '/section/settings');
+
+// Путь к логам
+$folder = $tarif['install'] . $server['uid'] . '/game/csgo/logs';
+
+// Если выбран лог
+if (isset($url['log'])) {
+    if (sys::valid($url['log'], 'other', $aValid['cslogs']))
+        sys::back($cfg['http'] . 'servers/id/' . $id . '/section/settings/subsection/logs');
+
+    $ssh->set('sudo -u server' . $server['uid'] . ' cat ' . $folder . '/' . $url['log']);
+
+    $html->get('view', 'sections/servers/games/settings/logs');
+
+    $html->set('id', $id);
+    $html->set('name', $url['log']);
+    $html->set('log', htmlspecialchars($ssh->get()));
+    $html->set('uri', 'logs');
+
+    $html->pack('main');
+} else {
+    if (isset($url['delall'])) {
+        $ssh->set('cd ' . $folder . ' && rm *.log');
+
+        sys::back($cfg['http'] . 'servers/id/' . $id . '/section/settings/subsection/logs');
+    }
+
+    $ssh->set('cd ' . $folder . ' && du -ab --time | grep -e .log$ | awk \'{print $2" "$3"\/"$1"\/"$4}\' | sort -Mr');
+
+    // Массив данных
+    $aData = explode("\n", $ssh->get());
+
+    if (isset($aData[count($aData) - 1]))
+        unset($aData[count($aData) - 1]);
+
+    // Построение списка
+    foreach ($aData as $line => $log) {
+        $aLog = explode('\/', $log);
+
+        // Название
+        $name = explode('/', $aLog[2]);
+
+        if (count($name) > 2)
+            continue;
+
+        // Дата
+        $date = sys::unidate($aLog[0]);
+
+        // Вес
+        $size = sys::size($aLog[1]);
+
+        $html->get('list', 'sections/servers/games/settings/logs');
+
+        $html->set('id', $id);
+        $html->set('name', end($name));
+        $html->set('uri', 'logs/log/' . end($name));
+        $html->set('date', $date);
+        $html->set('size', $size);
+
+        $html->pack('logs');
+    }
+
+    $html->get('logs', 'sections/servers/games/settings');
+
+    $html->set('id', $id);
+    $html->set('uri', '');
+    $html->set('logs', isset($html->arr['logs']) ? $html->arr['logs'] : '');
+
+    $html->pack('main');
+}
+?>

+ 113 - 0
system/sections/servers/rust/settings/server.php

@@ -0,0 +1,113 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+$html->nav('Параметры server.cfg');
+
+$sql->query('SELECT `address`, `passwd` FROM `units` WHERE `id`="' . $server['unit'] . '" LIMIT 1');
+$unit = $sql->get();
+
+$sql->query('SELECT `install` FROM `tarifs` WHERE `id`="' . $server['tarif'] . '" LIMIT 1');
+$tarif = $sql->get();
+
+include(LIB . 'ssh.php');
+
+if (!$ssh->auth($unit['passwd'], $unit['address'])) {
+    if ($go)
+        sys::outjs(array('e' => sys::text('error', 'ssh')), $nmch);
+
+    sys::back($cfg['http'] . 'servers/id/' . $id . '/section/settings');
+}
+
+include(DATA . 'scfg/' . $server['game'] . '.php');
+
+// Сохранение изменений
+if ($go) {
+    $servercfg = isset($_POST['config']) ? $_POST['config'] : '';
+
+    $config = '';
+
+    $config_end = $servercfg['\'other\''];
+
+    unset($servercfg['\'other\'']);
+
+    foreach ($servercfg as $cvar => $val)
+        if ($val != '')
+            $config .= str_replace("'", '', $cvar) . ' "' . $val . '"' . "\n";
+
+    // Временый файл
+    $temp = sys::temp($config . $config_end);
+
+    $ssh->setfile($temp, $tarif['install'] . $server['uid'] . '/game/csgo/cfg/server.cfg', 0644);
+
+    $ssh->set('chown server' . $server['uid'] . ':servers ' . $tarif['install'] . $server['uid'] . '/game/csgo/cfg/server.cfg');
+
+    unlink($temp);
+
+    sys::outjs(array('s' => 'ok'), $nmch);
+}
+
+// Чтение файла - server.cfg
+$file = $tarif['install'] . $server['uid'] . '/game/csgo/cfg/server.cfg';
+
+$ssh->set('echo "" >> ' . $file . ' && cat ' . $file . ' | grep -ve "^#\|^[[:space:]]*$"');
+
+$fScfg = explode("\n", strip_tags($ssh->get()));
+
+$servercfg = array();
+$other = '';
+
+// Убираем пробелы и генерируем массив
+foreach ($fScfg as $line) {
+    // имя квара
+    $cvar = sys::first(explode(' ', $line));
+
+    if ($cvar == '')
+        continue;
+
+    // убираем имя квара и оставляем только значение
+    $value = str_replace($cvar . ' ', "", $line);
+
+    // выбираем только то, что нам нужно
+    preg_match_all('~([^"]+)~', $value, $cvar_value, PREG_SET_ORDER);
+
+    // Исключаем комментарии
+    if ($cvar == '//')
+        continue;
+
+    $val = sys::first(explode(' //', $cvar_value[0][1]));
+
+    // Добавляем данные в массив
+    if (array_key_exists($cvar, $aScfg))
+        $servercfg[$cvar] = trim($val);
+    else
+        $other .= $line . "\n";
+}
+
+foreach ($aScfg as $name => $desc) {
+    if (!isset($servercfg[$name]))
+        $servercfg[$name] = '';
+
+    // Формирование формы
+    if (strpos($aScfg_form[$name], 'select'))
+        $form = str_replace('value="' . $servercfg[$name] . '"', 'value="' . $servercfg[$name] . '" selected="select"', $aScfg_form[$name]);
+    else
+        $form = str_replace('[' . $name . ']', $servercfg[$name], $aScfg_form[$name]);
+
+    $html->get('servercfg_list', 'sections/servers/games/settings');
+
+    $html->set('name', $name);
+    $html->set('desc', $desc);
+    $html->set('form', $form);
+
+    $html->pack('list');
+}
+
+$html->get('servercfg', 'sections/servers/' . $server['game'] . '/settings');
+
+$html->set('id', $id);
+$html->set('cfg', $html->arr['list']);
+$html->set('other', $other);
+
+$html->pack('main');
+?>

+ 86 - 0
system/sections/servers/rust/settings/smlogs.php

@@ -0,0 +1,86 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+$html->nav('Логи SourceMod');
+
+$sql->query('SELECT `address`, `passwd` FROM `units` WHERE `id`="' . $server['unit'] . '" LIMIT 1');
+$unit = $sql->get();
+
+$sql->query('SELECT `install` FROM `tarifs` WHERE `id`="' . $server['tarif'] . '" LIMIT 1');
+$tarif = $sql->get();
+
+include(LIB . 'ssh.php');
+
+if (!$ssh->auth($unit['passwd'], $unit['address']))
+    sys::back($cfg['http'] . 'servers/id/' . $id . '/section/settings');
+
+// Путь к логам
+$folder = $tarif['install'] . $server['uid'] . '/game/csgo/addons/sourcemod/logs';
+
+// Если выбран лог
+if (isset($url['log'])) {
+    if (sys::valid($url['log'], 'other', $aValid['csssmlogs']))
+        sys::back($cfg['http'] . 'servers/id/' . $id . '/section/settings/subsection/smlogs');
+
+    $ssh->set('sudo -u server' . $server['uid'] . ' cat ' . $folder . '/' . $url['log']);
+
+    $html->get('view', 'sections/servers/games/settings/logs');
+
+    $html->set('id', $id);
+    $html->set('name', $url['log']);
+    $html->set('log', htmlspecialchars($ssh->get()));
+    $html->set('uri', 'smlogs');
+
+    $html->pack('main');
+} else {
+    if (isset($url['delall'])) {
+        $ssh->set('cd ' . $folder . ' && rm *.log');
+
+        sys::back($cfg['http'] . 'servers/id/' . $id . '/section/settings/subsection/smlogs');
+    }
+
+    $ssh->set('cd ' . $folder . ' && du -ab --time | grep -e .log$ | awk \'{print $2" "$3"\/"$1"\/"$4}\' | sort -Mr');
+
+    // Массив данных
+    $aData = explode("\n", $ssh->get());
+
+    if (isset($aData[count($aData) - 1]))
+        unset($aData[count($aData) - 1]);
+
+    // Построение списка
+    foreach ($aData as $line => $log) {
+        $aLog = explode('\/', $log);
+
+        // Название
+        $name = explode('/', $aLog[2]);
+
+        if (count($name) > 2)
+            continue;
+
+        // Дата
+        $date = sys::unidate($aLog[0]);
+
+        // Вес
+        $size = sys::size($aLog[1]);
+
+        $html->get('list', 'sections/servers/games/settings/logs');
+
+        $html->set('id', $id);
+        $html->set('name', end($name));
+        $html->set('uri', 'smlogs/log/' . end($name));
+        $html->set('date', $date);
+        $html->set('size', $size);
+
+        $html->pack('logs');
+    }
+
+    $html->get('logs', 'sections/servers/games/settings');
+
+    $html->set('id', $id);
+    $html->set('uri', 'sm');
+    $html->set('logs', isset($html->arr['logs']) ? $html->arr['logs'] : '');
+
+    $html->pack('main');
+}
+?>

+ 164 - 0
system/sections/servers/rust/settings/start.php

@@ -0,0 +1,164 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+$sql->query('SELECT `uid`, `slots`, `slots_start`, `map_start`, `vac`, `fastdl`, `autorestart`, `fps`, `tickrate`, `pingboost` FROM `servers` WHERE `id`="' . $id . '" LIMIT 1');
+$server = array_merge($server, $sql->get());
+
+$sql->query('SELECT `address`, `passwd` FROM `units` WHERE `id`="' . $server['unit'] . '" LIMIT 1');
+$unit = $sql->get();
+
+$sql->query('SELECT `install`, `tickrate`, `price` FROM `tarifs` WHERE `id`="' . $server['tarif'] . '" LIMIT 1');
+$tarif = $sql->get();
+
+include(LIB . 'games/games.php');
+include(LIB . 'games/tarifs.php');
+include(LIB . 'games/' . $server['game'] . '/tarif.php');
+
+// Вывод списка карт
+if (isset($url['maps']))
+    games::maplist($id, $unit, $tarif['install'] . $server['uid'] . '/game/csgo/maps', $server['map_start'], false);
+
+// Сохранение
+if ($go and $url['save']) {
+    $value = isset($url['value']) ? sys::int($url['value']) : sys::outjs(array('s' => 'ok'), $nmch);
+
+    switch ($url['save']) {
+        case 'map':
+            $map = isset($url['value']) ? trim($url['value']) : sys::outjs(array('s' => 'ok'), $nmch);
+
+            if ($map != $server['map_start'])
+                games::maplist($id, $unit, $tarif['install'] . $server['uid'] . '/game/csgo/maps', $map, true, $nmch);
+
+            $mcache->delete('server_settings_' . $id);
+            sys::outjs(array('s' => 'ok'), $nmch);
+
+        case 'vac':
+            if ($value != $server['vac'])
+                $sql->query('UPDATE `servers` set `vac`="' . $value . '" WHERE `id`="' . $id . '" LIMIT 1');
+
+            $mcache->delete('server_settings_' . $id);
+            sys::outjs(array('s' => 'ok'), $nmch);
+
+        case 'mod':
+            if (in_array($value, array(1, 2, 3, 4, 5)))
+                $sql->query('UPDATE `servers` set `pingboost`="' . $value . '" WHERE `id`="' . $id . '" LIMIT 1');
+
+            $mcache->delete('server_settings_' . $id);
+            sys::outjs(array('s' => 'ok'), $nmch);
+
+        case 'slots':
+            $slots = $value > $server['slots'] ? $server['slots'] : $value;
+            $slots = $value < 2 ? 2 : $slots;
+
+            if ($slots != $server['slots_start'])
+                $sql->query('UPDATE `servers` set `slots_start`="' . $slots . '" WHERE `id`="' . $id . '" LIMIT 1');
+
+            $mcache->delete('server_settings_' . $id);
+            sys::outjs(array('s' => 'ok'), $nmch);
+
+        case 'autorestart':
+            if ($value != $server['autorestart'])
+                $sql->query('UPDATE `servers` set `autorestart`="' . $value . '" WHERE `id`="' . $id . '" LIMIT 1');
+
+            $mcache->delete('server_settings_' . $id);
+            sys::outjs(array('s' => 'ok'), $nmch);
+
+        case 'tickrate':
+            if (!tarif::price($tarif['price']) and in_array($value, explode(':', $tarif['tickrate'])))
+                $sql->query('UPDATE `servers` set `tickrate`="' . $value . '" WHERE `id`="' . $id . '" LIMIT 1');
+
+            $mcache->delete('server_settings_' . $id);
+            sys::outjs(array('s' => 'ok'), $nmch);
+
+        case 'fastdl':
+            include(LIB . 'ssh.php');
+
+            if (!$ssh->auth($unit['passwd'], $unit['address']))
+                sys::outjs(array('e' => sys::text('error', 'ssh')), $nmch);
+
+            if ($value) {
+                $fastdl = 'sv_downloadurl "http://' . sys::first(explode(':', $unit['address'])) . ':8080/fast_' . $server['uid'] . '"' . PHP_EOL
+                    . 'sv_consistency 1' . PHP_EOL
+                    . 'sv_allowupload 1' . PHP_EOL
+                    . 'sv_allowdownload 1';
+
+                // Временый файл
+                $temp = sys::temp($fastdl);
+
+                $ssh->setfile($temp, $tarif['install'] . $server['uid'] . '/game/csgo/cfg/fastdl.cfg', 0644);
+
+                $ssh->set('chown server' . $server['uid'] . ':servers ' . $tarif['install'] . $server['uid'] . '/game/csgo/cfg/fastdl.cfg;'
+                    . 'ln -s ' . $tarif['install'] . $server['uid'] . '/game/csgo /var/nginx/fast_' . $server['uid'] . ';'
+                    . 'sed -i ' . "'s/exec fastdl.cfg//g'" . ' ' . $tarif['install'] . $server['uid'] . '/game/csgo/cfg/server.cfg;'
+                    . 'echo "exec fastdl.cfg" >> ' . $tarif['install'] . $server['uid'] . '/game/csgo/cfg/server.cfg');
+
+                unlink($temp);
+            } else
+                $ssh->set('sed -i ' . "'s/exec fastdl.cfg//g'" . ' ' . $tarif['install'] . $server['uid'] . '/game/csgo/cfg/server.cfg;'
+                    . 'rm ' . $tarif['install'] . $server['uid'] . '/game/csgo/cfg/fastdl.cfg; rm /var/nginx/fast_' . $server['uid']);
+
+            $sql->query('UPDATE `servers` set `fastdl`="' . $value . '" WHERE `id`="' . $id . '" LIMIT 1');
+
+            $mcache->delete('server_settings_' . $id);
+            sys::outjs(array('s' => 'ok'), $nmch);
+    }
+}
+
+// Генерация списка слот
+$slots = '';
+
+for ($slot = 2; $slot <= $server['slots']; $slot += 1)
+    $slots .= '<option value="' . $slot . '">' . $slot . ' шт.</option>';
+
+// Античит VAC
+$vac = $server['vac'] ? '<option value="1">Включен</option><option value="0">Выключен</option>' : '<option value="0">Выключен</option><option value="1">Включен</option>';
+
+// Быстрая скачака
+$fastdl = $server['fastdl'] ? '<option value="1">Включен</option><option value="0">Выключен</option>' : '<option value="0">Выключен</option><option value="1">Включен</option>';
+
+// Авторестарт при зависании
+$autorestart = $server['autorestart'] ? '<option value="1">Включен</option><option value="0">Выключен</option>' : '<option value="0">Выключен</option><option value="1">Включен</option>';
+
+$tickrate = '<option value="' . $server['tickrate'] . '">' . $server['tickrate'] . ' TickRate</option>';
+
+if (!tarif::price($tarif['price'])) {
+    $aTick = explode(':', $tarif['tickrate']);
+
+    unset($aTick[array_search($server['tickrate'], $aTick)]);
+
+    if (count($aTick))
+        foreach ($aTick as $value)
+            $tickrate .= '<option value="' . $value . '">' . $value . ' TickRate</option>';
+}
+
+// Игровой режим
+$mods = '<option value="1">Классический обычный</option>'
+    . '<option value="2">Классический соревновательный</option>'
+    . '<option value="3">Гонка вооружений</option>'
+    . '<option value="4">Уничтожение объекта</option>'
+    . '<option value="5">Бой насмерть</option>';
+
+if (!$server['pingboost'])
+    $server['pingboost'] = 2;
+
+$mod = str_replace('value="' . $server['pingboost'], 'value="' . $server['pingboost'] . '" selected="select', $mods);
+
+$html->get('start', 'sections/servers/' . $server['game'] . '/settings');
+
+$html->set('id', $id);
+$html->set('map', $server['map_start']);
+$html->set('vac', $vac);
+$html->set('fastdl', $fastdl);
+$html->set('autorestart', $autorestart);
+$html->set('mod', $mod);
+$html->set('slots', str_replace('"' . $server['slots_start'] . '"', '"' . $server['slots_start'] . '" selected="select"', $slots));
+
+if (!tarif::price($tarif['price'])) {
+    $html->unit('tickrate', true);
+    $html->set('tickrate', $tickrate);
+} else
+    $html->unit('tickrate');
+
+$html->pack('start');
+?>

+ 12 - 0
system/sections/servers/rust/tarif.php

@@ -0,0 +1,12 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+$sql->query('SELECT `name`, `slots_min`, `slots_max`, `install`, `fps`, `tickrate`, `ram`, `timext`, `discount`, `price` FROM `tarifs` WHERE `id`="' . $server['tarif'] . '" LIMIT 1');
+$tarif = $sql->get();
+
+// Подразделы
+$aSub = array('extend', 'plan', 'address', 'addextend', 'unit', 'slots');
+
+include(SEC . 'servers/games/tarif.php');
+?>

+ 50 - 0
system/sections/servers/rust/tarif/extend.php

@@ -0,0 +1,50 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+if (!isset($nmch))
+    $nmch = false;
+
+$aData = array();
+
+// Если не расчетный период
+if (!$cfg['settlement_period']) {
+    $aData['time'] = isset($_POST['time']) ? sys::int($_POST['time']) : sys::outjs(array('e' => 'Переданы не все данные'), $nmch);
+
+    // Проверка периода
+    if (!in_array($aData['time'], explode(':', $tarif['timext'])))
+        sys::outjs(array('e' => 'Переданы неверные данные'), $nmch);
+
+}
+
+$aData['promo'] = isset($_POST['promo']) ? $_POST['promo'] : '';
+$aData['address'] = isset($_POST['address']) ? $_POST['address'] : false;
+$aData['server'] = $id;
+$aData['user'] = $server['user'];
+$aData['tarif'] = $server['tarif'];
+$aData['tickrate'] = $server['tickrate'];
+$aData['slots'] = $server['slots'];
+
+// Цена за выделенный адрес
+$add_sum = tarifs::address_add_sum($aData['address'], $server);
+
+$aPrice = explode(':', $tarif['price']);
+
+// Цена за 30 дней 1 слота
+$price = $aPrice[array_search($server['tickrate'], explode(':', $tarif['tickrate']))];
+
+// Если расчетный период
+if ($cfg['settlement_period'])
+    $aData['time'] = $server['time'];
+
+// Цена аренды
+$sum = games::define_sum($tarif['discount'], $price, $server['slots'], $aData['time'], 'extend') + $add_sum;
+
+// Если расчетный период
+if ($cfg['settlement_period'])
+    $aData['time'] = games::define_period('extend', params::$aDayMonth, $server['time']);
+
+$days = params::$aDayMonth[date('n', $server['time'])] == $aData['time'] ? 'месяц' : games::parse_day($aData['time'], true);
+
+include(SEC . 'servers/games/tarif/extend.php');
+?>

+ 64 - 0
system/sections/servers/rust/tarif/plan.php

@@ -0,0 +1,64 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+if (!isset($nmch))
+    $nmch = false;
+
+$plan = isset($url['plan']) ? sys::int($url['plan']) : sys::outjs(array('e' => 'Переданые не все данные'), $nmch);
+
+$aPrice = explode(':', $tarif['price']);
+$aTICK = explode(':', $tarif['tickrate']);
+
+// Проверка плана
+if (array_search($plan, $aTICK) === FALSE)
+    sys::outjs(array('e' => 'Переданы неверные данные'), $nmch);
+
+if ($plan == $server['tickrate'])
+    sys::outjs(array('e' => 'Смысла в этой операции нет'), $nmch);
+
+if (!tarif::price($tarif['price']))
+    sys::outjs(array('e' => 'Чтобы изменить тариф, перейдите в настройки запуска'), $nmch);
+
+if ($server['time'] < $start_point + 86400)
+    $time = $server['time'];
+else {
+    // Цена за 1 день аренды (по новому тарифному плану)
+    $price = $aPrice[array_search($plan, $aTICK)] / 30 * $server['slots'];
+
+    // Цена за 1 день аренды (по старому тарифному плану)
+    $price_old = $aPrice[array_search($server['tickrate'], $aTICK)] / 30 * $server['slots'];
+
+    // Остаток дней аренды
+    $days = ($server['time'] - $start_point) / 86400;
+
+    $time = date('H:i:s', $server['time']);
+    $date = date('d.m.Y', round($start_point + $days * $price_old / $price * 86400 - 86400));
+
+    $aDate = explode('.', $date);
+    $aTime = explode(':', $time);
+
+    $time = mktime($aTime[0], $aTime[1], $aTime[2], $aDate[1], $aDate[0], $aDate[2]);
+}
+
+// Выполнение смена тарифного плана
+if ($go) {
+    sys::benefitblock($id, $nmch);
+
+    $sql->query('UPDATE `servers` set `time`="' . $time . '", `tickrate`="' . $plan . '" WHERE `id`="' . $id . '" LIMIT 1');
+
+    if (in_array($server['status'], array('working', 'start', 'restart', 'change'))) {
+        include(LIB . 'games/' . $server['game'] . '/action.php');
+
+        action::start($id, 'restart');
+    }
+
+    // Запись логов
+    $sql->query('INSERT INTO `logs_sys` set `user`="' . $user['id'] . '", `server`="' . $id . '", `text`="' . sys::text('syslogs', 'change_plan') . '", `time`="' . $start_point . '"');
+
+    sys::outjs(array('s' => 'ok'), $nmch);
+}
+
+// Выхлоп информации
+sys::outjs(array('s' => date('d.m.Y - H:i', $time) . ' (' . sys::date('min', $time) . ')'), $nmch);
+?>

+ 33 - 0
system/sections/servers/rust/tarif/slots.php

@@ -0,0 +1,33 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+if (!isset($nmch))
+    $nmch = false;
+
+// Если фикс. значение слот
+if ($tarif['slots_min'] == $tarif['slots_max'])
+    sys::outjs(array('e' => 'На данном тарифе нельзя изменить количество слот.'), $nmch);
+
+$slots = isset($url['slots']) ? sys::int($url['slots']) : sys::outjs(array('e' => 'Переданы не все данные.'), $nmch);
+
+$aPrice = explode(':', $tarif['price']);
+$aTICK = explode(':', $tarif['tickrate']);
+
+$overdue = $server['time'] < $start_point;
+
+if ($cfg['change_slots'][$server['game']]['days'] || $overdue) {
+    // Цена за 1 день
+    $price = $aPrice[array_search($server['tickrate'], $aTICK)] / 30;
+
+    // Цена аренды за остаток дней (с текущим кол-вом слот)
+    $price_old = ($server['time'] - $start_point) / 86400 * $price * $server['slots'];
+}
+
+$max = $tarif['slots_max'] - $server['slots'];
+
+// Сумма за добавляемые слоты
+$sum = round(($server['time'] - $start_point) / 86400 * ($aPrice[array_search($server['tickrate'], $aTICK)] / 30) * $slots, 2);
+
+include(SEC . 'servers/games/tarif/slots.php');
+?>

+ 50 - 0
system/sections/servers/rust/tarif/unit.php

@@ -0,0 +1,50 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+if (!isset($nmch))
+    $nmch = false;
+
+$uid = isset($url['uid']) ? sys::int($url['uid']) : sys::outjs(array('e' => 'Переданы не все данные.'), $nmch);
+
+if (!$cfg['change_unit'][$server['game']] || $server['time'] < $start_point + 86400 || $server['test'])
+    exit;
+
+$sql->query('SELECT `id`, `unit`, `packs`, `tickrate`, `price` FROM `tarifs` WHERE `unit`="' . $uid . '" AND `game`="' . $server['game'] . '" AND `name`="' . $tarif['name'] . '" AND `id`!="' . $server['tarif'] . '" AND `show`="1" ORDER BY `unit`');
+if (!$sql->num())
+    sys::outjs(array('e' => 'Не найден подходящий тариф.'), $nmch);
+
+$oldTarif = $tarif;
+
+$tarif = $sql->get();
+
+$sql->query('SELECT `address`, `passwd`, `sql_login`, `sql_passwd`, `sql_port`, `sql_ftp` FROM `units` WHERE `id`="' . $server['unit'] . '" LIMIT 1');
+$oldUnit = $sql->get();
+
+$aPriceold = explode(':', $oldTarif['price']);
+$aTICKold = explode(':', $oldTarif['tickrate']);
+
+$sql->query('SELECT `id` FROM `units` WHERE `id`="' . $tarif['unit'] . '" AND `show`="1" LIMIT 1');
+if (!$sql->num())
+    sys::outjs(array('e' => 'Выбранная локация не доступна.'), $nmch);
+
+$aPrice = explode(':', $tarif['price']);
+$aTICK = explode(':', $tarif['tickrate']);
+
+if (!in_array($server['tickrate'], $aTICK))
+    sys::outjs(array('e' => 'Не найден подходящий тарифный план.'), $nmch);
+
+// Цена за 1 день (при новом тарифном плане)
+$price = $aPrice[array_search($server['tickrate'], $aTICK)] / 30 * $server['slots'];
+
+// Цена аренды за остаток дней (с текущим тарифным планом)
+$oldprice = ($server['time'] - $start_point) / 86400 * ($aPriceold[array_search($server['tickrate'], $aTICKold)] / 30 * $server['slots']);
+
+$date = date('H.i.s.d.m.Y', round($start_point + $oldprice / $price * 86400 - 86400));
+
+$aDate = explode('.', $date);
+
+$time = mktime($aDate[0], $aDate[1], $aDate[2], $aDate[4], $aDate[3], $aDate[5]);
+
+include(SEC . 'servers/games/tarif/unit.php');
+?>

+ 81 - 0
system/sections/servers/rust/web.php

@@ -0,0 +1,81 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+$html->nav($server['address'], $cfg['http'] . 'servers/id/' . $id);
+
+include(DATA . 'web.php');
+
+// Если выбран подраздел
+if (isset($url['subsection']) and in_array($url['subsection'], $aSub) and in_array($url['action'], array_merge($aAction[$url['subsection']], array('install', 'manage')))) {
+    if ($go)
+        $nmch = sys::rep_act('server_web_go_' . $id, 10);
+    else
+        $html->nav('Web', $cfg['http'] . 'servers/id/' . $id . '/section/web');
+
+    include(SEC . 'web/' . $url['subsection'] . '/free/' . $url['action'] . '.php');
+} else {
+    $html->nav('Web');
+
+    if ($mcache->get('server_web_' . $id) != '')
+        $html->arr['main'] = $mcache->get('server_web_' . $id);
+    else {
+        // Услуги
+        foreach ($aWeb[$server['game']] as $service => $active) {
+            if ($active) {
+                if ($service == 'hosting') {
+                    if (!$aWebVHTtype && !in_array($server['tarif'], $aWebVHT))
+                        continue;
+
+                    if ($aWebVHTtype && in_array($server['tarif'], $aWebVHT))
+                        continue;
+                }
+
+                // Проверка на установку
+                switch ($aWebInstall[$server['game']][$service]) {
+                    case 'server':
+                        $sql->query('SELECT `id` FROM `web` WHERE `type`="' . $service . '" AND `server`="' . $id . '" LIMIT 1');
+                        break;
+
+                    case 'user':
+                        $sql->query('SELECT `id` FROM `web` WHERE `type`="' . $service . '" AND `user`="' . $server['user'] . '" LIMIT 1');
+                        break;
+
+                    case 'unit':
+                        $sql->query('SELECT `id` FROM `web` WHERE `type`="' . $service . '" AND `user`="' . $server['user'] . '" AND `unit`="' . $server['unit'] . '" LIMIT 1');
+                }
+
+                if ($sql->num())
+                    $html->get('list_install', 'sections/servers/games/web');
+                else
+                    $html->get('list', 'sections/servers/games/web');
+
+                $html->set('id', $id);
+                $html->set('service', $service);
+                $html->set('name', $aWebname[$service]);
+                $html->set('desc', $aWebDesc[$service]);
+
+                $html->pack($aWebType[$service]);
+            }
+        }
+
+        // Блоки услуг
+        foreach ($aWebTypeInfo[$server['game']] as $type => $name) {
+            if (!isset($html->arr[$type]))
+                continue;
+
+            $html->get('block', 'sections/servers/games/web');
+            $html->set('name', $name);
+            $html->set('list', $html->arr[$type]);
+            $html->pack('web');
+        }
+
+        $html->get('web', 'sections/servers/' . $server['game']);
+        $html->set('id', $id);
+        $html->set('web', isset($html->arr['web']) ? $html->arr['web'] : 'Дополнительные услуги отсутствуют');
+        $html->pack('main');
+
+        $mcache->set('server_web_' . $id, $html->arr['main'], false, 4);
+    }
+}
+?>

+ 145 - 0
system/sections/services/rust.php

@@ -0,0 +1,145 @@
+<?php
+if (!DEFINED('EGP'))
+    exit(header('Refresh: 0; URL=http://' . $_SERVER['SERVER_NAME'] . '/404'));
+
+include(LIB . 'games/games.php');
+
+// Обработка заказа
+if ($go) {
+    // Проверка на авторизацию
+    sys::noauth();
+
+    if ($mcache->get('buy_server'))
+        sleep(1.5);
+
+    $mcache->set('buy_server', true, false, 3);
+
+    include(LIB . 'games/' . $section . '/service.php');
+
+    // Входные данные
+    $aData = array(
+        'unit' => isset($_POST['unit']) ? sys::int($_POST['unit']) : 0,
+        'tarif' => isset($_POST['tarif']) ? sys::int($_POST['tarif']) : 0,
+        'pack' => isset($_POST['pack']) ? $_POST['pack'] : '',
+        'tickrate' => isset($_POST['tickrate']) ? sys::int($_POST['tickrate']) : 0,
+        'slots' => isset($_POST['slots']) ? sys::int($_POST['slots']) : 0,
+        'time' => isset($_POST['time']) ? sys::int($_POST['time']) : 30,
+        'test' => (isset($_POST['time']) and $_POST['time'] == 'test') ? true : false,
+        'promo' => isset($_POST['promo']) ? $_POST['promo'] : false,
+    );
+
+    // Массвив данных
+    $aSDATA = service::buy($aData);
+
+    // Процесс выдачи игрового сервера
+    $id = service::install($aSDATA);
+
+    sys::outjs(array('s' => 'ok', 'id' => $id));
+}
+
+include(LIB . 'games/services.php');
+
+$check = false;
+
+// Проверка наличия доступной локации
+$sql->query(services::unit($section));
+if ($sql->num()) {
+    // Выбранная локация
+    if (isset($url['get']) and in_array($url['get'], array('tarifs', 'data')))
+        $sql->query('SELECT `id`, `test` FROM `units` WHERE `id`="' . $id . '" LIMIT 1');
+
+    $select_unit = $sql->get();
+
+    // Генерация списка локаций
+    $units = services::units($section);
+
+    // Генерация списка тарифов
+    $tarifs = services::tarifs($section, $select_unit['id']);
+
+    if (isset($url['get']) and in_array($url['get'], array('price', 'promo'))) {
+        $aGet = array(
+            'tarif' => sys::int($url['tarif']),
+            'tickrate' => sys::int($url['tickrate']),
+            'slots' => sys::int($url['slots']),
+            'time' => sys::int($url['time']),
+            'user' => $user['id']
+        );
+
+        $sql->query('SELECT `price`, `tickrate`, `discount` FROM `tarifs` WHERE `id`="' . $aGet['tarif'] . '" LIMIT 1');
+        $tarif = $sql->get();
+
+        $aPrice = explode(':', $tarif['price']);
+
+        // Определение цены
+        $price = $aPrice[array_search($aGet['tickrate'], explode(':', $tarif['tickrate']))];
+
+        // Выхлоп цены за выбранные параметры
+        if ($url['get'] == 'price') {
+            // Если выбран тестовый период
+            if ($url['time'] == 'test')
+                sys::outjs(array('sum' => 0));
+
+            sys::outjs(array(
+                'sum' => games::define_sum($tarif['discount'], $price, $aGet['slots'], $aGet['time'])
+            ));
+        }
+
+        // Выхлоп цены с учетом промо-кода
+        if ($url['get'] == 'promo')
+            games::define_promo(
+                $url['cod'],
+                $aGet,
+                $tarif['discount'],
+                games::define_sum($tarif['discount'], $price, $aGet['slots'], $aGet['time'])
+            );
+    }
+
+    // Генерация сборок/слот/периодов
+    if (isset($url['get']) and $url['get'] == 'data')
+        $sql->query('SELECT `id`, `name`, `price`, `slots_min`, `slots_max`, `packs`, `tickrate`, `time`, `test`, `discount` FROM `tarifs` WHERE `id`="' . sys::int($url['tarif']) . '" LIMIT 1');
+    else
+        $sql->query('SELECT `id`, `name`, `price`, `slots_min`, `slots_max`, `packs`, `tickrate`, `time`, `test`, `discount` FROM `tarifs` WHERE `game`="' . $section . '" AND `unit`="' . $select_unit['id'] . '" AND `show`="1" ORDER BY `sort` ASC LIMIT 1');
+
+    if ($sql->num()) {
+        $select_tarif = $sql->get();
+
+        $aTarif = games::parse_tarif($select_tarif, $select_unit);
+
+        if (isset($url['get'])) {
+            // Выхлоп при выборе локации
+            if ($url['get'] == 'tarifs')
+                sys::outjs(array_merge(array('tarifs' => $tarifs), $aTarif));
+
+            // Выхлоп при выборе тарифа
+            if ($url['get'] == 'data')
+                sys::outjs($aTarif);
+        }
+
+        $html->get($section, 'sections/services/games');
+        $html->set('units', $units);
+        $html->set('tarifs', $tarifs);
+        $html->set('packs', $aTarif['packs']);
+        $html->set('tickrate', $aTarif['tickrate']);
+        $html->set('slots', $aTarif['slots']);
+        $html->set('time', $aTarif['time']);
+        $html->set('cur', $cfg['currency']);
+        $html->set('date', date('d.m.Y', $start_point));
+
+        if ($cfg['settlement_period'])
+            $html->unit('settlement_period', true, true);
+        else
+            $html->unit('settlement_period', false, true);
+
+        $html->unit('informer', false, true);
+        $html->pack('main');
+
+        $check = true;
+    }
+}
+
+if (!$check) {
+    $html->get($section, 'sections/services/games');
+    $html->unit('informer', true, true);
+    $html->pack('main');
+}
+?>

+ 5 - 0
template/acp/main.html

@@ -59,6 +59,11 @@
         <td class="text-center">[cs2] шт.</td>
         <td class="text-right">[slots_cs2] шт.</td>
     </tr>
+    <tr>
+        <td>RUST</td>
+        <td class="text-center">[rust] шт.</td>
+        <td class="text-right">[rust] шт.</td>
+    </tr>
     <tr>
         <td>GTA: SA-MP</td>
         <td class="text-center">[samp] шт.</td>

+ 1 - 0
template/acp/sections/servers/menu.html

@@ -12,6 +12,7 @@
     <li><a href="[acp]servers/section/csgo" |s_csgo|class="active" |_s_csgo|><i class="fa fa-steam"></i> CS: Global
         Offensive <span>[csgo]</span></a></li>
     <li><a href="[acp]servers/section/cs2" |s_cs2|class="active" |_s_cs2|><i class="fa fa-steam"></i> CS: 2 <span>[cs2]</span></a></li>
+    <li><a href="[acp]servers/section/rust" |s_rust|class="active" |_s_rust|><i class="fa fa-steam"></i> RUST <span>[rust]</span></a></li>
     <li><a href="[acp]servers/section/mta" |s_mta|class="active" |_s_mta|><i class="fa fa-car"></i> GTA: MTA
         <span>[mta]</span></a></li>
     <li><a href="[acp]servers/section/samp" |s_samp|class="active" |_s_samp|><i class="fa fa-bus"></i> GTA: SAMP <span>[samp]</span></a>

+ 1 - 0
template/acp/sections/tarifs/add.html

@@ -20,6 +20,7 @@
                     <option value="css">Counter-Strike: Source</option>
                     <option value="csgo">Counter-Strike: Global Offensive</option>
                     <option value="cs2">Counter-Strike: 2</option>
+                    <option value="rust">RUST</option>
                     <option value="samp">San Andreas Multiplayer</option>
                     <option value="crmp">GTA: Criminal Russia</option>
                     <option value="mta">Multi Theft Auto</option>

+ 4 - 0
template/acp/sections/units/add.html

@@ -61,6 +61,10 @@
                     CS:2
                     <input type="checkbox" name="cs2" checked>
                 </label>
+                <label>
+                    RUST
+                    <input type="checkbox" name="rust" checked>
+                </label>
                 <label>
                     SA-MP
                     <input type="checkbox" name="samp" checked>

+ 4 - 0
template/acp/sections/units/unit.html

@@ -61,6 +61,10 @@
                     CS:2
                     <input type="checkbox" name="cs2" |game_cs2|checked|_game_cs2|>
                 </label>
+                <label>
+                    RUST
+                    <input type="checkbox" name="rust" |game_rust|checked|_game_rust|>
+                </label>
                 <label>
                     SA-MP
                     <input type="checkbox" name="samp" |game_samp|checked|_game_samp|>

+ 64 - 0
template/js/sections/services/rust.js

@@ -0,0 +1,64 @@
+$('#rust').ajaxForm({
+    dataType: 'json',
+    success: function (data) {
+        $.each(data, function (i, val) {
+            if (i == 'e')
+                bootbox.dialog('<h3 class="red">Ошибка</h3>' + val,
+                    [{
+                        "label": "Продолжить",
+                    }]
+                );
+
+            if (i == 's')
+                location.href = home + 'servers/id/' + data['id'];
+        });
+
+        loading(0);
+    }
+});
+
+function change_data(data) {
+    $.getJSON('services/section/rust/id/' + $('#unit').val() + '/tarif/' + $('#tarifs').val() + '/get/' + data, function (arr) {
+        $.each(arr, function (id, val) {
+            $('#' + id).html(val);
+        });
+
+        upd_price();
+        promo();
+    });
+}
+
+function upd_price() {
+    $.getJSON('services/section/rust/id/' + $('#unit').val() + '/tarif/' + $('#tarifs').val() + '/slots/' + $('#slots').val() + '/time/' + $('#time').val() + '/tickrate/' + $('#tickrate').val() + '/get/price', function (arr) {
+        $.each(arr, function (id, val) {
+            $('#' + id).html(val);
+        });
+
+        promo();
+    });
+}
+
+function promo() {
+    if ($('#promo').val() == '') {
+        $('#promo_tr').css('display', 'none');
+        $('#sum_info').css('text-decoration', 'none');
+        return false;
+    }
+
+    $.getJSON('services/section/rust/id/' + $('#unit').val() + '/tarif/' + $('#tarifs').val() + '/slots/' + $('#slots').val() + '/time/' + $('#time').val() + '/tickrate/' + $('#tickrate').val() + '/cod/' + $('#promo').val() + '/get/promo', function (arr) {
+        $('#promo_tr').css('display', 'table-row');
+
+        if (arr['e'] != undefined) {
+            $('#promo_info').html(arr['e']);
+            $('#sum_info').css('text-decoration', 'none');
+        } else {
+            if (arr['discount'] == 1) {
+                $('#sum_info').css('text-decoration', 'line-through');
+                $('#promo_info').html('Цена с учетом промо-кода: ' + arr['sum'] + ' ' + arr['cur']);
+            } else {
+                $('#sum_info').css('text-decoration', 'none');
+                $('#promo_info').html('Подарочные дни: ' + arr['days']);
+            }
+        }
+    });
+}

+ 6 - 0
template/sections/servers/players/rust.html

@@ -0,0 +1,6 @@
+<tr>
+    <td align="center">[i]</td>
+    <td>[name]</td>
+    <td align="center">[score]</td>
+    <td align="center">[time]</td>
+</tr>

+ 4 - 0
template/sections/servers/rust/change_list.html

@@ -0,0 +1,4 @@
+<div onclick="server_change_map('[id]', '[map]')">|workshop|<i class="fa fa-cloud-download"
+                                                               title="Карта из WorkShop"></i>|_workshop|<img src="[img]"
+                                                                                                             width="120"><span>[name]</span>
+</div>

+ 151 - 0
template/sections/servers/rust/console.html

@@ -0,0 +1,151 @@
+<h4 class="hblock_content">Интерактивная консоль</h4>
+
+<div class="block_content">
+    <div class="server_console">
+
+        <pre id="console">...</pre>
+
+        <form action="[home]servers/id/[id]/section/console/go" method="POST" id="form_console">
+            <table class="table_pad input_pad">
+                <tbody>
+                <tr>
+                    <td colspan="4">
+                        <div class="btn" onclick="set_command('status')">status</div>
+                        <div class="btn" onclick="set_command('stats')">stats</div>
+                        <div class="btn" onclick="set_command('sm plugins list')">sm plugins list</div>
+                        <div class="btn" onclick="set_command('meta list')">meta list</div>
+                        <div class="btn" onclick="set_command(sm_reloadadmins')">sm_reloadadmins</div>
+                        <div class="btn" onclick="set_command('sm version')">sm version</div>
+                        <div class="btn btn-error right" onclick="set_command('clear')">Очистка консоли</div>
+                    </td>
+                </tr>
+
+                <!-- цвет консоли начало-->
+                <tr>
+                    <td colspan="4">
+                        <p>Цвет консоли:</p>
+                        <div class="btn console_hover" onclick="console_color('#fff')"><i class="fa fa-terminal"></i>
+                        </div>
+                        <div class="btn console_slategray" onclick="console_color('#708090')"><i
+                                class="fa fa-terminal"></i></div>
+                        <div class="btn console_red" onclick="console_color('#f94747')"><i class="fa fa-terminal"></i>
+                        </div>
+                        <div class="btn console_maroon" onclick="console_color('#800000')"><i
+                                class="fa fa-terminal"></i></div>
+                        <div class="btn console_green" onclick="console_color('#03aa46')"><i class="fa fa-terminal"></i>
+                        </div>
+                        <div class="btn console_darkgreen" onclick="console_color('#105310')"><i
+                                class="fa fa-terminal"></i></div>
+                        <div class="btn console_lime" onclick="console_color('#7CFC00')"><i class="fa fa-terminal"></i>
+                        </div>
+                        <div class="btn console_olive" onclick="console_color('#808000')"><i class="fa fa-terminal"></i>
+                        </div>
+                        <div class="btn console_yellow" onclick="console_color('#ffcc3c')"><i
+                                class="fa fa-terminal"></i></div>
+                        <div class="btn console_tan" onclick="console_color('#D2B48C')"><i class="fa fa-terminal"></i>
+                        </div>
+                        <div class="btn console_blue" onclick="console_color('#3c7fff')"><i class="fa fa-terminal"></i>
+                        </div>
+                        <div class="btn console_skyblue" onclick="console_color('#87CEEB')"><i
+                                class="fa fa-terminal"></i></div>
+                    </td>
+                </tr>
+                <!-- цвет консоли конец-->
+
+                <tr>
+                    <td width="5">
+                        <div class="btn btn-info" onclick="update_switch()">Обновление</div>
+                    </td>
+                    <td width="5" id="console_update"><i class="fa fa-toggle-on"></i></td>
+                    <td><input placeholder="Введите команду для отправки" name="command"></td>
+                    <td width="5">
+                        <button class="btn-success" onclick="loading(1)">Отправить</button>
+                    </td>
+                </tr>
+                </tbody>
+            </table>
+        </form>
+    </div>
+</div>
+
+<script src="[js]sections/servers/console.js" type="text/javascript"></script>
+<script type="text/javascript">
+    var server = [id];
+    $(document).ready(function () {
+        setTimeout(function () {
+            update_console(true)
+        }, 1000);
+    });
+</script>
+
+<!-- цвет консоли начало-->
+<script type="text/javascript">
+    function console_color(color) {
+        $('#console').css('color', color);
+
+        return null;
+    }
+</script>
+<style>
+    #console {
+        height: 350px;
+        overflow-y: scroll;
+        overflow-x: hidden;
+        border-radius: 0;
+        padding: 5px;
+        margin-bottom: 10px;
+        background-color: #141617;
+        color: #fff;
+        white-space: pre-wrap;
+        word-break: break-all;
+    }
+
+    .console_hover {
+        background: #9b9f9e;
+    }
+
+    .console_slategray {
+        background: #708090;
+    }
+
+    .console_maroon {
+        background: #800000;
+    }
+
+    .console_green {
+        background: #03aa46;
+    }
+
+    .console_olive {
+        background: #808000;
+    }
+
+    .console_yellow {
+        background: #ffcc3c;
+    }
+
+    .console_tan {
+        background: #D2B48C;
+    }
+
+    .console_red {
+        background: #f94747;
+    }
+
+    .console_blue {
+        background: #558efa;
+    }
+
+    .console_skyblue {
+        background: #87CEEB;
+    }
+
+    .console_darkgreen {
+        background: #006400;
+    }
+
+    .console_lime {
+        background: #00FF00;
+    }
+</style>
+<!-- цвет консоли конец-->

+ 86 - 0
template/sections/servers/rust/copy.html

@@ -0,0 +1,86 @@
+<h4 class="hblock_content">Создание полной копии</h4>
+
+<div class="block_content">
+    <table class="table_pad">
+        <tbody>
+        <tr>
+            <td>
+                <b>csgo</b>
+                <p>Все содержимое директории csgo</p>
+            </td>
+            <td width="35%" align="right">
+                <div onclick="fullcopy()" class="btn btn-success">Создать полную резервную копию</div>
+            </td>
+        </tr>
+        </tbody>
+    </table>
+</div>
+
+<div class="space"></div>
+
+<h4 class="hblock_content">Создание копии</h4>
+
+<div class="block_content">
+    <form action="[home]servers/id/[id]/section/copy/subsection/create/go" method="POST" id="copy">
+        <table class="table_pad">
+            <tbody>
+            [list]
+            <tr>
+                <td colspan="2" align="right">
+                    <span class="btn btn-none left">Перед созданием резервной копии, убедитесь что игровой север выключен.</span>
+                    <button onclick="loading(1)" class="btn-success">Создать резервную копию</button>
+                </td>
+            </tr>
+            </tbody>
+        </table>
+    </form>
+</div>
+
+<div class="space"></div>
+
+<h4 class="hblock_content">Созданные копии</h4>
+
+<div class="block_content">
+    <table class="table_pad">
+        <tbody>
+        [copy]
+        </tbody>
+    </table>
+</div>
+<div class="space"></div>
+
+<h4 class="hblock_content">Информация</h4>
+
+<div class="block_content">
+    <p>
+        <i class="fa fa-reply-all" title="Восстановить полностью"></i>
+        <u>Полное восстановление</u> - при восстановлении все директории в копии будут полностью заменена на имеющиеся.
+    </p>
+    <p>
+        <i class="fa fa-retweet" title="Восстановить частично"></i>
+        <u>Частичное восстановление</u> - при восстановлении происходит замена одинаковых файлов, не удаляются другие
+        файлы и папки.
+    </p>
+    <p>
+        <i class="fa fa-times" title="Удалить копию"></i>
+        <u>Удаление копии</u> - после удаление резервной копии, восстановить её будет невозможно.
+    </p>
+</div>
+
+<div class="space"></div>
+
+<link rel="stylesheet" type="text/css" href="[css]switch.css" media="screen"/>
+
+<script src="[js]switch.js" type="text/javascript"></script>
+<script src="[js]sections/servers/copy.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+    var server = '[id]';
+
+    $(document).ready(function (e) {
+        $('input').lc_switch();
+
+        $.get(home + 'servers/id/' + server + '/section/copy/subsection/check/go', function () {
+        });
+    });
+</script>

+ 44 - 0
template/sections/servers/rust/gmenu.html

@@ -0,0 +1,44 @@
+[notice]
+
+<div class="full_screen">
+    <table class="server_nav">
+        <tbody>
+        <tr>
+            <td><a |index|class="active" |_index| href="[home]servers/id/[id]"><i class="fa fa-bars"></i>Основное</a>
+            </td>
+            |console_use|
+            <td><a |console|class="active" |_console| href="[home]servers/id/[id]/section/console"><i
+                    class="fa fa-television"></i>Консоль</a></td>
+            |_console_use|
+            <td><a |settings|class="active" |_settings| href="[home]servers/id/[id]/section/settings"><i
+                    class="fa fa-cog"></i>Настройки</a></td>
+            |plugins_use|
+            <td><a |plugins|class="active" |_plugins| href="[home]servers/id/[id]/section/plugins"><i
+                    class="fa fa-cubes"></i>Плагины</a></td>
+            |_plugins_use|
+            <td><a |maps|class="active" |_maps| href="[home]servers/id/[id]/section/maps"><i
+                    class="fa fa-picture-o"></i>Карты</a></td>
+            <td><a |owners|class="active" |_owners| href="[home]servers/id/[id]/section/owners"><i
+                    class="fa fa-user-plus"></i>Друзья</a></td>
+            |ftp_use|
+            <td><a |filetp|class="active" |_filetp| href="[home]servers/id/[id]/section/filetp"><i
+                    class="fa fa-folder-open"></i>FTP</a></td>
+            |_ftp_use|
+            <td><a |tarif|class="active" |_tarif| href="[home]servers/id/[id]/section/tarif"><i
+                    class="fa fa-dropbox"></i>Тариф</a></td>
+            |copy_use|
+            <td><a |copy|class="active" |_copy| href="[home]servers/id/[id]/section/copy"><i class="fa fa-clone"></i>Копии</a>
+            </td>
+            |_copy_use|
+            |graph_use|
+            <td><a |graph|class="active" |_graph| href="[home]servers/id/[id]/section/graph"><i
+                    class="fa fa-area-chart"></i>Графики</a></td>
+            |_graph_use|
+            |web_use|
+            <td><a |web|class="active" |_web| href="[home]servers/id/[id]/section/web"><i
+                    class="fa fa-globe"></i>Web</a></td>
+            |_web_use|
+        </tr>
+        </tbody>
+    </table>
+</div>

+ 157 - 0
template/sections/servers/rust/index.html

@@ -0,0 +1,157 @@
+<h4 class="hblock_content">Игровой сервер: #[id]</h4>
+
+<div class="block_content">
+    <div class="server_list">
+        <div class="server_img" id="image"><img src="[img]"></div>
+        <table>
+            <tbody>
+            <tr>
+                <td width="32%">
+                    <div class="server_name" id="name">[name]</div>
+                </td>
+                <td width="33%">Игра: [game] <u>(id: [id])</u></td>
+                <td width="35%">Создан: [date]</td>
+            </tr>
+            <tr>
+                <td>Адрес: [address]</td>
+                <td>Локация: [unit]</td>
+                <td id="time">Арендован до: [time]</td>
+            </tr>
+            <tr>
+                <td id="status">[status]</td>
+                <td>Сборка: [pack]</td>
+                <td id="time_end">[time_end]</td>
+            </tr>
+            <tr>
+                <td>
+                    Онлайн: <span id="online">[online]</span> / [slots]
+                    <div class="change_close" id="maps_close" onclick="server_change_close('[id]')">x</div>
+                    <div class="change_map" id="maps_list"></div>
+                </td>
+                <td colspan="2">Тариф: [tarif]</td>
+            </tr>
+            <tr>
+                <td colspan="2" id="buttons">[btn]</td>
+                <td align="center"><a href="[home]servers/id/[id]/section/tarif">
+                    <div class="btn btn-short">Продлить аренду</div>
+                </a></td>
+            </tr>
+            </tbody>
+        </table>
+    </div>
+</div>
+
+<div class="space"></div>
+
+<div class="left">
+
+    <h4 class="hblock_content">Показатели нагрузки</h4>
+
+    <div class="block_content width550">
+        <table class="table_pad">
+            <tbody>
+            <tr>
+                <td align="center">
+                    <div id="load_usr"></div>
+                </td>
+                <td align="center">
+                    <div id="load_cpu"></div>
+                </td>
+                <td align="center">
+                    <div id="load_ram"></div>
+                </td>
+                <td align="center">
+                    <div id="load_hdd"></div>
+                </td>
+            </tr>
+            </tbody>
+        </table>
+    </div>
+</div>
+
+<div class="right">
+
+    <h4 class="hblock_content">Быстрый доступ</h4>
+
+    <div class="block_content width350">
+        <table class="table_pad" style="height: 113px">
+            <tbody>
+            <tr>
+                <td>Админы на сервере (admins_simple.ini)</td>
+                <td width="1%"><a href="[home]servers/id/[id]/section/settings/subsection/admins">
+                    <div class="btn btn-short">Перейти</div>
+                </a></td>
+            </tr>
+            <tr>
+                <td>Бан листы (banned_user.cfg / banned_ip.cfg)</td>
+                <td width="1%"><a href="[home]servers/id/[id]/section/settings/subsection/bans">
+                    <div class="btn btn-short">Перейти</div>
+                </a></td>
+            </tr>
+            <tr>
+                <td>Основные настройки (server.cfg)</td>
+                <td width="1%"><a href="[home]servers/id/[id]/section/settings/subsection/server">
+                    <div class="btn btn-short">Перейти</div>
+                </a></td>
+            </tr>
+            <tr>
+                <td>Снимки консоли (StartLogs)</td>
+                <td width="1%"><a href="[home]servers/id/[id]/section/settings/subsection/startlogs">
+                    <div class="btn btn-short">Перейти</div>
+                </a></td>
+            </tr>
+            </tbody>
+        </table>
+    </div>
+</div>
+
+<div class="space"></div>
+
+<a href="[home]servers/id/[id]/section/rcon">
+    <div class="btn btn-success btn-short right">RCON УПРАВЛЕНИЕ</div>
+</a>
+
+<div class="space"></div>
+
+<h4 class="hblock_content">Игроки онлайн</h4>
+
+<div class="block_content">
+    <table class="table_pad">
+        <thead>
+        <tr>
+            <th width="1%" align="left">#</th>
+            <th width="69%" align="left">Ник</th>
+            <th width="15%" align="center">Фраги</th>
+            <th width="15%" align="center">Время</th>
+        </tr>
+        </thead>
+        <tbody id="players">
+        [players]
+        </tbody>
+    </table>
+</div>
+
+<script src="[js]load.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+    var wait = false;
+
+    $(document).ready(function () {
+        setTimeout(function () {
+            update_resources('[id]')
+        }, 500);
+        setTimeout(function () {
+            update_info('[id]', true)
+        }, 500);
+        setTimeout(function () {
+            update_status('[id]', true)
+        }, 500);
+    });
+
+    var $load_usr = $("#load_usr").percentageLoader({width: 105, height: 105, progress: 0, value: 'USR'});
+    var $load_cpu = $("#load_cpu").percentageLoader({width: 105, height: 105, progress: 0, value: 'CPU'});
+    var $load_ram = $("#load_ram").percentageLoader({width: 105, height: 105, progress: 0, value: 'RAM'});
+    var $load_hdd = $("#load_hdd").percentageLoader({width: 105, height: 105, progress: 0, value: 'SSD'});
+</script>
+
+<script src="[js]sections/servers/index.js" type="text/javascript"></script>

+ 78 - 0
template/sections/servers/rust/maps/listing.html

@@ -0,0 +1,78 @@
+<a href="[home]servers/id/[id]/section/maps/subsection/listing">
+    <div class="btn margin-right">Настроить списки</div>
+</a>
+
+<a href="[home]servers/id/[id]/section/maps/subsection/list">
+    <div class="btn btn-success right">Установить карты</div>
+</a>
+
+<div class="space"></div>
+
+<div class="width50p">
+
+    <h4 class="hblock_content">Файл: maplist.txt</h4>
+
+    <div class="block_content">
+
+        <form action="[home]servers/id/[id]/section/maps/subsection/listing/file/maps/go" method="POST" class="form">
+            <table class="table_pad input_pad">
+                <tbody>
+                <tr>
+                    <td colspan="2">Путь: cstrike/maplist.txt</td>
+                </tr>
+                <tr>
+                    <td colspan="2"><textarea rows="10" id="maps" name="data">[maps]</textarea></td>
+                </tr>
+                <tr>
+                    <td>
+                        <div class="btn btn-short left" onclick="genlist('maps')">Сгенерировать</div>
+                    </td>
+                    <td>
+                        <button class="btn-success btn-short right" onclick="loading(1)">Сохранить</button>
+                    </td>
+                </tr>
+                </tbody>
+            </table>
+        </form>
+
+    </div>
+
+</div>
+
+<div class="width50p right">
+
+    <h4 class="hblock_content">Файл: mapcycle.txt</h4>
+
+    <div class="block_content">
+
+        <form action="[home]servers/id/[id]/section/maps/subsection/listing/file/mapcycle/go" method="POST"
+              class="form">
+            <table class="table_pad input_pad">
+                <tbody>
+                <tr>
+                    <td colspan="2">Путь: cstrike/mapcycle.txt</td>
+                </tr>
+                <tr>
+                    <td colspan="2"><textarea rows="10" id="mapcycle" name="data">[mapcycle]</textarea></td>
+                </tr>
+                <tr>
+                    <td>
+                        <div class="btn btn-short left" onclick="genlist('mapcycle')">Сгенерировать</div>
+                    </td>
+                    <td>
+                        <button class="btn-success btn-short right" onclick="loading(1)">Сохранить</button>
+                    </td>
+                </tr>
+                </tbody>
+            </table>
+        </form>
+
+    </div>
+
+</div>
+
+<script src="[js]sections/servers/maps.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+    var server = '[id]';
+</script>

+ 18 - 0
template/sections/servers/rust/maps/map_server.html

@@ -0,0 +1,18 @@
+<div id="form_[map]">
+    |!workshop|
+    <div onclick="select_map('[map]')" id="block_[map]">
+        <i class="fa fa-square-o"></i>
+        <img src="[img]" width="140">
+        <span>[name]</span>
+        <input id="[map]" name="maps['[map]']" value="0" type="hidden">
+    </div>
+    |_!workshop|
+
+    |workshop|
+    <div title="Карта из WorkShop">
+        <i class="fa fa-cloud-download"></i>
+        <img src="[img]" width="140">
+        <span>[name]</span>
+    </div>
+    |_workshop|
+</div>

+ 63 - 0
template/sections/servers/rust/maps/types.html

@@ -0,0 +1,63 @@
+<h4 class="hblock_content">Тип карт</h4>
+
+<div class="block_content maps_types">
+
+    <a href="[home]servers/id/[id]/section/maps/subsection/list/type/de">
+        <div>
+            <div>DE_</div>
+            <img src="[cdn]maps/css/de_aztec2.jpg">
+        </div>
+    </a>
+
+    <a href="[home]servers/id/[id]/section/maps/subsection/list/type/cs">
+        <div>
+            <div>CS_</div>
+            <img src="[cdn]maps/css/cs_assault.jpg">
+        </div>
+    </a>
+
+    <a href="[home]servers/id/[id]/section/maps/subsection/list/type/aim">
+        <div>
+            <div>AIM_</div>
+            <img src="[cdn]maps/css/aim_ak_colt.jpg">
+        </div>
+    </a>
+
+    <a href="[home]servers/id/[id]/section/maps/subsection/list/type/awp">
+        <div>
+            <div>AWP_</div>
+            <img src="[cdn]maps/css/awp_8gua_32.jpg">
+        </div>
+    </a>
+
+    <a href="[home]servers/id/[id]/section/maps/subsection/list/type/bhop">
+        <div>
+            <div>BHOP_</div>
+            <img src="[cdn]maps/css/bhop_aeonflux.jpg">
+        </div>
+    </a>
+
+    <a href="[home]servers/id/[id]/section/maps/subsection/list/type/csde">
+        <div>
+            <div>CSDE_</div>
+            <img src="[cdn]maps/css/csde_tropic.jpg">
+        </div>
+    </a>
+
+    <a href="[home]servers/id/[id]/section/maps/subsection/list/type/deathrun">
+        <div>
+            <div>DEATHRUN_</div>
+            <img src="[cdn]maps/css/deathrun_2010.jpg">
+        </div>
+    </a>
+
+    <a href="[home]servers/id/[id]/section/maps/subsection/list/type/jail">
+        <div>
+            <div>JAIL_</div>
+            <img src="[cdn]maps/css/jail_crime.jpg">
+        </div>
+    </a>
+
+</div>
+
+<div class="space"></div>

+ 108 - 0
template/sections/servers/rust/owners.html

@@ -0,0 +1,108 @@
+<div class="width50p">
+    <h4 class="hblock_content">Добавление совладельца</h4>
+
+    <div class="block_content">
+        <form action="[home]servers/id/[id]/section/owners/go" method="POST" id="add">
+            <table class="table_pad input_pad">
+                <tbody>
+                <tr>
+                    <td>Логин / Ид</td>
+                    <td><input name="owner['user']" placeholder="Введите логин или ид совладельца"></td>
+                </tr>
+                <tr>
+                    <td>Включение сервера</td>
+                    <td align="center"><input type="checkbox" name="owner['start']" class="lcs_check left"/></td>
+                </tr>
+                <tr>
+                    <td>Выключение сервера</td>
+                    <td align="center"><input type="checkbox" name="owner['stop']" class="lcs_check left"/></td>
+                </tr>
+                <tr>
+                    <td>Перезагрузка сервера</td>
+                    <td align="center"><input type="checkbox" name="owner['restart']" class="lcs_check left"/></td>
+                </tr>
+                <tr>
+                    <td>Смена карты сервера</td>
+                    <td align="center"><input type="checkbox" name="owner['change']" class="lcs_check left"/></td>
+                </tr>
+                <tr>
+                    <td>Переустановка сервера</td>
+                    <td align="center"><input type="checkbox" name="owner['reinstall']" class="lcs_check left"/></td>
+                </tr>
+                <tr>
+                    <td>Обновление сервера</td>
+                    <td align="center"><input type="checkbox" name="owner['update']" class="lcs_check left"/></td>
+                </tr>
+                <tr>
+                    <td>Раздел "Консоль"</td>
+                    <td align="center"><input type="checkbox" name="owner['console']" class="lcs_check left"/></td>
+                </tr>
+                <tr>
+                    <td>Раздел "Настройки"</td>
+                    <td align="center"><input type="checkbox" name="owner['settings']" class="lcs_check left"/></td>
+                </tr>
+                <tr>
+                    <td>Раздел "Плагины"</td>
+                    <td align="center"><input type="checkbox" name="owner['plugins']" class="lcs_check left"/></td>
+                </tr>
+                <tr>
+                    <td>Раздел "Карты"</td>
+                    <td align="center"><input type="checkbox" name="owner['maps']" class="lcs_check left"/></td>
+                </tr>
+                <tr>
+                    <td>Доступ выдан до</td>
+                    <td align="center">
+                        <input name="owner['time']" value="[time]" class="date-picker width50p"
+                               data-date-format="dd.mm.yy">
+                        <div class="btn btn-none">+ 60 мин.</div>
+                    </td>
+                </tr>
+                <tr>
+                    <td align="center" colspan="2">
+                        <button class="btn-success">Добавить совладельца</button>
+                    </td>
+                </tr>
+                </tbody>
+            </table>
+        </form>
+    </div>
+</div>
+
+<div class="width50p right">
+    <h4 class="hblock_content">Список совладельцев</h4>
+
+    <div class="block_content">
+        <table class="table_pad input_pad">
+            <tbody>
+            [owners]
+            </tbody>
+        </table>
+    </div>
+
+    <div class="none" id="rights_block">
+        <div class="space"></div>
+
+        <h4 class="hblock_content">Выданные права</h4>
+
+        <div class="block_content" id="rights"></div>
+    </div>
+</div>
+
+<link rel="stylesheet" type="text/css" href="[css]date.css" media="screen"/>
+<link rel="stylesheet" type="text/css" href="[css]switch.css" media="screen"/>
+
+<script src="[js]switch.js" type="text/javascript"></script>
+<script src="[js]ace-elements.js" type="text/javascript"></script>
+<script src="[js]ace.js" type="text/javascript"></script>
+<script src="[js]date.js" type="text/javascript"></script>
+<script src="[js]sections/servers/owners.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+    $(function () {
+        $('.date-picker').datepicker();
+    });
+
+    $(document).ready(function (e) {
+        $('input').lc_switch();
+    });
+</script>

+ 75 - 0
template/sections/servers/rust/rcon.html

@@ -0,0 +1,75 @@
+<h4 class="hblock_content">Управление игроками</h4>
+
+<div class="block_content">
+    <table class="table_pad">
+        <tbody>
+        <tr>
+            <td>
+                Выбранный игрок:
+                <b id="sel_player_info">____________</b>
+            </td>
+            <td width="15%">
+                <div onclick="update_players_list()" class="btn btn-gray right">Обновить список</div>
+            </td>
+            <td width="5%">
+                <div onclick="rcon_kill()" class="btn right">Убить</div>
+            </td>
+            <td width="5%">
+                <div onclick="rcon_kick()" class="btn right">Кикнуть</div>
+            </td>
+            <td width="5%">
+                <div onclick="rcon_ban()" class="btn right">Забанить</div>
+            </td>
+            <td width="5%">
+                <div onclick="firewall()" class="btn btn-error right">Заблокировать</div>
+            </td>
+        </tr>
+        </tbody>
+    </table>
+
+    <div class="space"></div>
+
+    <table class="table_pad">
+        <thead>
+        <tr>
+            <th width="1%">#</th>
+            <th width="29%">Ник</th>
+            <th width="20%">SteamID</th>
+            <th width="10%">Время</th>
+            <th width="10%">Пинг</th>
+            <th width="15%">Адрес</th>
+            <th width="15%">Управление</th>
+        </tr>
+        </thead>
+        <tbody id="players"></tbody>
+    </table>
+</div>
+
+<input type="hidden" id="sel_player" value="0">
+
+<div class="space"></div>
+
+<h2 class="hblock_content">Game Server Control Panel</h2>
+
+<div class="block_content">
+    <p>
+    <center>Приложение для удобного управления игровыми серверами со своего смартфона.</center>
+    </p>
+    <div class="space"></div>
+    <p>
+    <center>С помощью него Вы всегда будете в курсе состояния вашего игрового сервера.</center>
+    </p>
+    <br>
+    <center><a href="https://play.google.com/store/apps/details?id=ru.air.gscp&hl=ru" target="_blank"><img
+            src="[home]template/images/gscp.png"></a></center>
+</div>
+
+<script type="text/javascript">
+    var server = '[id]';
+
+    $(document).ready(function () {
+        update_players_list();
+    });
+</script>
+
+<script src="[js]sections/servers/rcon.js" type="text/javascript"></script>

+ 18 - 0
template/sections/servers/rust/rcon/player.html

@@ -0,0 +1,18 @@
+<tr id="[i]">
+    <td align="center">[i]</td>
+    <td>[name]</td>
+    <td align="center">[steamid]</td>
+    <td align="center">[time]</td>
+    <td align="center">[ping]мс</td>
+    <td align="left">
+        <img src="[ico]" title="[country]" align="right"/>
+        [ip]
+    </td>
+    <td width="2%" style="text-align: center;">
+        <input type="radio" name="sel_player" id="player_[i]" class="rcon" onclick="select_player('[i]', '[name]')">
+        <input type="hidden" id="userid_[i]" value="[userid]">
+        <input type="hidden" id="steamid_[i]" value="[steamid]">
+        <input type="hidden" id="nickname_[i]" value="[name]">
+        <input type="hidden" id="address_[i]" value="[ip]">
+    </td>
+</tr>

+ 138 - 0
template/sections/servers/rust/settings.html

@@ -0,0 +1,138 @@
+<div class="left" style="width: 260px">[start]</div>
+
+<div class="right" style="width: 630px">
+    <h4 class="hblock_content">Основное</h4>
+
+    <div class="block_content">
+        <table width="100%" class="table_pad">
+            <tbody>
+            <tr>
+                <td>Основные настройки (<u>SERVER.CFG</u>)</td>
+                <td width="5"><a href="[home]servers/id/[id]/section/settings/subsection/server">
+                    <div class="btn btn-short btn-max">Настроить</div>
+                </a></td>
+            </tr>
+            <tr>
+                <td>Администраторы на сервере (<u>ADMINS_SIMPLE.INI</u>)</td>
+                <td><a href="[home]servers/id/[id]/section/settings/subsection/admins">
+                    <div class="btn btn-short btn-max">Настроить</div>
+                </a></td>
+            </tr>
+            <tr>
+                <td>Забаненные на сервере (<u>banned_user.cfg / banned_ip.cfg</u>)</td>
+                <td><a href="[home]servers/id/[id]/section/settings/subsection/bans">
+                    <div class="btn btn-short btn-max">Настроить</div>
+                </a></td>
+            </tr>
+            <tr>
+                <td>Блокировка на оборудовании (<u>FireWall</u>)</td>
+                <td><a href="[home]servers/id/[id]/section/settings/subsection/firewall">
+                    <div class="btn btn-short btn-max">Настроить</div>
+                </a></td>
+            </tr>
+            <tr>
+                <td>Планировщик задач (<u>CronTab</u>)</td>
+                <td><a href="[home]servers/id/[id]/section/settings/subsection/crontab">
+                    <div class="btn btn-short btn-max">Настроить</div>
+                </a></td>
+            </tr>
+            <tr>
+                <td colspan="2"><h4>Защита от DDoS атак</h4> <u class="right"><a href="#">Информация</a></u></td>
+            </tr>
+            <tr>
+                <td class="input_pad">
+                    <select id="rules">
+                        [antiddos]
+                    </select>
+                </td>
+                <td>
+                    <div class="btn btn-short btn-max" onclick="antiddos('[id]')">Сохранить</div>
+                </td>
+            </tr>
+            <tr>
+                <td colspan="2"><h4>Сборка игрового сервера</h4> <i class="right">(После изменения сборки, сервер
+                    необходимо переустановить, чтобы все изменения вступили в силу)</i></td>
+            </tr>
+            <tr>
+                <td class="input_pad">
+                    <select id="packs">
+                        [packs]
+                    </select>
+                </td>
+                <td>
+                    <div class="btn btn-short btn-max" onclick="repack('[id]')">Сохранить</div>
+                </td>
+            </tr>
+            <tr>
+                <td class="input_pad">
+                    |!api|Для получения ключа, необходимо активировать API|_!api|
+                    |api|Индивидуальный ключ: <u>[api]</u> <a href="[home]api_v1">
+                    <div class="btn btn-success btn-short btn-mix pull-right">API интерфейс</div>
+                </a>|_api|
+                </td>
+                <td>
+                    <a href="[home]servers/id/[id]/section/settings/subsection/api">
+                        |!api|
+                        <div class="btn btn-success btn-short btn-max">Включить</div>
+                        |_!api|
+                        |api|
+                        <div class="btn btn-error btn-short btn-max">Отключить</div>
+                        |_api|
+                    </a>
+                </td>
+            </tr>
+            </tbody>
+        </table>
+    </div>
+</div>
+
+<div class="space"></div>
+
+<h4 class="hblock_content">Логи</h4>
+
+<div class="block_content">
+    <table width="100%" class="table_pad">
+        <tbody>
+        <tr>
+            <td>Снимки консоли (<u>StartLogs</u>)</td>
+            <td width="5"><a href="[home]servers/id/[id]/section/settings/subsection/startlogs">
+                <div class="btn btn-short btn-max">Посмотреть</div>
+            </a></td>
+        </tr>
+        <tr>
+            <td>Краш сервера (<u>debug</u>)</td>
+            <td><a href="[home]servers/id/[id]/section/settings/subsection/debug">
+                <div class="btn btn-short btn-max">Посмотреть</div>
+            </a></td>
+        </tr>
+        <tr>
+            <td>Логи игрового сервера (<u>logs/*.log</u>)</td>
+            <td><a href="[home]servers/id/[id]/section/settings/subsection/logs">
+                <div class="btn btn-short btn-max">Посмотреть</div>
+            </a></td>
+        </tr>
+        <tr>
+            <td>Логи SourceMod (<u>addons/sourcemod/logs/*.log</u>)</td>
+            <td><a href="[home]servers/id/[id]/section/settings/subsection/smlogs">
+                <div class="btn btn-short btn-max">Посмотреть</div>
+            </a></td>
+        </tr>
+        </tbody>
+    </table>
+</div>
+
+|edits|
+<div class="space"></div>
+
+<h4 class="hblock_content">Редактируемые файлы</h4>
+
+<div class="block_content">
+    <table width="100%" class="table_pad">
+        <tbody>
+        [edits]
+        </tbody>
+    </table>
+</div>
+|_edits|
+
+<script src="[js]sections/servers/settings.js" type="text/javascript"></script>

+ 43 - 0
template/sections/servers/rust/settings/admins.html

@@ -0,0 +1,43 @@
+<h4 class="hblock_content">Управление администраторами на сервере</h4>
+
+<div class="block_content">
+    <form method="POST" action="[home]servers/id/[id]/section/settings/subsection/admins/go" id="form">
+        <table class="table_pad input_pad">
+            <tbody id="forms">
+            <tr>
+                <td align="center" width="7%"></td>
+                <td align="center" width="21%">Ник / Steam / Ip</td>
+                <td align="center" width="17%">Пароль</td>
+                <td align="center" width="17%">Флаги доступа</td>
+                <td align="center" width="10%">Иммунитет</td>
+                <td align="center" width="10%">Истекает</td>
+                <td align="center" width="10%">Примечание</td>
+                <td align="center" width="7%">
+                    <button class="btn-success btn-max" onclick="return addform();">Добавить</button>
+                </td>
+            </tr>
+            [admins]
+            </tbody>
+        </table>
+        <button type="submit" class="btn-success btn-max">Сохранить</button>
+    </form>
+</div>
+
+<link rel="stylesheet" type="text/css" href="[css]date.css" media="screen"/>
+<link rel="stylesheet" type="text/css" href="[css]switch.css" media="screen"/>
+
+<script src="[js]switch.js" type="text/javascript"></script>
+<script src="[js]ace-elements.js" type="text/javascript"></script>
+<script src="[js]ace.js" type="text/javascript"></script>
+<script src="[js]date.js" type="text/javascript"></script>
+<script src="[js]sections/servers/settings.js" type="text/javascript"></script>
+<script type="text/javascript">
+    var index = [index];
+    $(function () {
+        $('.date-picker').datepicker();
+    });
+    $(document).ready(function (e) {
+        $('input').lc_switch();
+    });
+</script>
+<script src="[js]sections/servers/settings/admins_css.js" type="text/javascript"></script>

+ 16 - 0
template/sections/servers/rust/settings/admins/list.html

@@ -0,0 +1,16 @@
+<tr id="[id]">
+    <td align="center"><input type="checkbox" name="active['[id]']" class="lcs_check left" |active|checked|_active|/>
+    </td>
+    <td align="center"><input name="value['[id]']" value="[value]" placeholder="Ник / Steam / Ip"></td>
+    <td align="center"><input name="passwd['[id]']" value="[passwd]" placeholder="Введите пароль"></td>
+    <td align="center" class="adminflags">
+        <input name="flags['[id]']" value="[flags]" id="flags_[id]">
+        <div onclick="flags_admin('[id]')"><i class="fa fa-pencil-square-o"></i></div>
+    </td>
+    <td align="center"><input name="immunity['[id]']" value="[immunity]"></td>
+    <td align="center"><input name="time['[id]']" value="[time]" class="date-picker" data-date-format="dd.mm.yy"></td>
+    <td align="center"><input name="info['[id]']" value="[info]"></td>
+    <td align="center">
+        <button class="btn-error btn-max" onclick="return delete_admin('[id]');">Удалить</button>
+    </td>
+</tr>

+ 68 - 0
template/sections/servers/rust/settings/bans.html

@@ -0,0 +1,68 @@
+<div class="width50p left">
+    <h4 class="hblock_content">Файл: banned_user.cfg</h4>
+
+    <div class="block_content">
+        <div class="height200">
+            <table class="table_pad">
+                <tbody>
+                [banned]
+                </tbody>
+            </table>
+        </div>
+    </div>
+</div>
+
+<div class="width50p right">
+    <h4 class="hblock_content">Файл: banned_ip.cfg</h4>
+
+    <div class="block_content">
+        <div class="height200">
+            <table class="table_pad">
+                <tbody>
+                [listip]
+                </tbody>
+            </table>
+        </div>
+    </div>
+</div>
+
+<div class="space"></div>
+
+<h4 class="hblock_content">Инструменты</h4>
+
+<div class="block_content">
+    <table class="table_pad input_pad">
+        <tbody>
+        <tr>
+            <td><input placeholder="Введит SteamID или IP" id="ban_val"></td>
+            <td width="1%">
+                <div class="btn btn-success" onclick="ban_action('unban', false)">Разбанить</div>
+            </td>
+            <td width="1%">
+                <div class="btn btn-error" onclick="ban_action('ban', false)">Забанить</div>
+            </td>
+            <td width="1%">
+                <div class="btn" onclick="ban_action('info', false)">Проверить</div>
+            </td>
+            <td align="right">
+                <div class="btn btn-none">SourceBans</div>
+            </td>
+            <td width="1%"><input type="checkbox" id="webbans" class="lcs_check left" checked/></td>
+        </tr>
+        </tbody>
+    </table>
+</div>
+
+<link rel="stylesheet" type="text/css" href="[css]switch.css" media="screen"/>
+
+<script src="[js]switch.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+    var server = '[id]';
+
+    $(document).ready(function (e) {
+        $('input').lc_switch();
+    });
+</script>
+
+<script src="[js]sections/servers/settings/bans.js" type="text/javascript"></script>

+ 151 - 0
template/sections/servers/rust/settings/crontab.html

@@ -0,0 +1,151 @@
+<h4 class="hblock_content">Планировщик задач</h4>
+
+<div class="block_content">
+    <form action="[home]servers/id/[id]/section/settings/subsection/crontab/go" method="POST" id="form">
+        <table class="table_pad input_pad">
+            <tbody>
+            <tr>
+                <td width="5%" align="right">Задание:</td>
+                <td>
+                    <select name="task" id="task" onchange="cron_check_type()">
+                        <option value="start">Включение сервера</option>
+                        <option value="stop">Выключение сервера</option>
+                        <option value="restart">Перезагрузка сервера</option>
+                        <option value="update">Обновление сервера</option>
+                        <option value="console">Отправка команд на сервер</option>
+                    </select>
+                </td>
+            </tr>
+            <tr id="console" style="display: none">
+                <td align="right">Команды:</td>
+                <td>
+                    <textarea name="commands" rows="5" placeholder="Каждая команда с новой строки"></textarea>
+                </td>
+            </tr>
+            <tr>
+                <td align="right">Время:</td>
+                <td>
+                    <select name="hour" class="left" style="width: 50px">
+                        <option value="00">00</option>
+                        <option value="01">01</option>
+                        <option value="02">02</option>
+                        <option value="03">03</option>
+                        <option value="04">04</option>
+                        <option value="05">05</option>
+                        <option value="06">06</option>
+                        <option value="07">07</option>
+                        <option value="08">08</option>
+                        <option value="09">09</option>
+                        <option value="10">10</option>
+                        <option value="11">11</option>
+                        <option value="12">12</option>
+                        <option value="13">13</option>
+                        <option value="14">14</option>
+                        <option value="15">15</option>
+                        <option value="16">16</option>
+                        <option value="17">17</option>
+                        <option value="18">18</option>
+                        <option value="19">19</option>
+                        <option value="20">20</option>
+                        <option value="21">21</option>
+                        <option value="22">22</option>
+                        <option value="23">23</option>
+                    </select>
+
+                    <div class="btn btn-none"> :</div>
+
+                    <select name="minute" class="left" style="width: 50px">
+                        <option value="00">00</option>
+                        <option value="05">05</option>
+                        <option value="10">10</option>
+                        <option value="15">15</option>
+                        <option value="20">20</option>
+                        <option value="25">25</option>
+                        <option value="30">30</option>
+                        <option value="35">35</option>
+                        <option value="40">40</option>
+                        <option value="45">45</option>
+                        <option value="50">50</option>
+                        <option value="55">55</option>
+                    </select>
+
+                    |!autostop|
+                    <div class="btn btn-none margin-top">Выполнять задание каждый час:</div>
+                    <input type="checkbox" name="allhour" class="lcs_check left"/>
+                    |_!autostop|
+
+                    <div class="btn right margin-top">Время на сайте: [time]</div>
+                </td>
+            </tr>
+            <tr>
+                <td colspan="2" align="center">
+                    <div class="btn btn-none btn-switch">Пн.
+                        <input type="checkbox" name="week['1']" class="lcs_check left" checked/>
+                    </div>
+
+                    <div class="btn btn-none btn-switch">Вт.
+                        <input type="checkbox" name="week['2']" class="lcs_check left" checked/>
+                    </div>
+
+                    <div class="btn btn-none btn-switch">Ср.
+                        <input type="checkbox" name="week['3']" class="lcs_check left" checked/>
+                    </div>
+
+                    <div class="btn btn-none btn-switch">Чт.
+                        <input type="checkbox" name="week['4']" class="lcs_check left" checked/>
+                    </div>
+
+                    <div class="btn btn-none btn-switch">Пт.
+                        <input type="checkbox" name="week['5']" class="lcs_check left" checked/>
+                    </div>
+
+                    <div class="btn btn-none btn-switch">Сб.
+                        <input type="checkbox" name="week['6']" class="lcs_check left" checked/>
+                    </div>
+
+                    <div class="btn btn-none btn-switch">Вс.
+                        <input type="checkbox" name="week['7']" class="lcs_check left" checked/>
+                    </div>
+                </td>
+            </tr>
+            <tr>
+                <td colspan="2" align="center">
+                    <button class="btn-success" onclick="loading(1)">Добавить задание</button>
+                </td>
+            </tr>
+            </tbody>
+        </table>
+    </form>
+</div>
+
+<div class="space"></div>
+
+<h4 class="hblock_content">Список добавленных задач</h4>
+
+<div class="block_content">
+    <table class="table_pad">
+        <thead>
+        <tr>
+            <th width="25%">Задание</th>
+            <th width="10%">Время</th>
+            <th align="left">Дни недели</th>
+        </tr>
+        </thead>
+        <tbody>
+        [crontab]
+        </tbody>
+    </table>
+</div>
+
+<link rel="stylesheet" type="text/css" href="[css]switch.css" media="screen"/>
+<script src="[js]switch.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+    var server = '[id]';
+
+    $(document).ready(function (e) {
+        $('input').lc_switch();
+    });
+</script>
+
+<script src="[js]sections/servers/settings/crontab.js" type="text/javascript"></script>

+ 0 - 0
template/sections/servers/rust/settings/crontab/list.html


+ 23 - 0
template/sections/servers/rust/settings/servercfg.html

@@ -0,0 +1,23 @@
+<h4 class="hblock_content">Параметры server.cfg</h4>
+
+<div class="block_content">
+    <form action="[home]servers/id/[id]/section/settings/subsection/server/go" method="POST" id="form">
+        <table class="table_pad input_pad">
+            <tbody>
+            [cfg]
+            <tr>
+                <td colspan="2">
+                    <textarea rows="10" name="config['other']">[other]</textarea>
+                </td>
+            </tr>
+            <tr>
+                <td colspan="2" align="center">
+                    <button class="btn-success" onclick="loading(1)">Сохранить</button>
+                </td>
+            </tr>
+            </tbody>
+        </table>
+    </form>
+</div>
+
+<script src="[js]sections/servers/settings.js" type="text/javascript"></script>

+ 92 - 0
template/sections/servers/rust/settings/start.html

@@ -0,0 +1,92 @@
+<h4 class="hblock_content">Параметры запуска</h4>
+
+<div class="block_content">
+    <table class="table_pad input_pad">
+        <tbody>
+        <!-- Стартовая карта !-->
+        <tr>
+            <td align="center" colspan="2"><b>Стартовая карта</b></td>
+        </tr>
+        <tr>
+            <td>
+                <select id="map">
+                    <option value="[map]">[map]</option>
+                </select>
+            </td>
+            <td width="5">
+                <button class="btn-success" onclick="settings_save('map')">Сохранить</button>
+            </td>
+        </tr>
+        <!-- Количество слот !-->
+        <tr>
+            <td align="center" colspan="2"><b>Количество слот</b></td>
+        </tr>
+        <tr>
+            <td>
+                <select id="slots">[slots]</select>
+            </td>
+            <td width="5">
+                <button class="btn-success" onclick="settings_save('slots')">Сохранить</button>
+            </td>
+        </tr>
+        <!-- VAC !-->
+        <tr>
+            <td align="center" colspan="2"><b>Античит VAC</b></td>
+        </tr>
+        <tr>
+            <td>
+                <select id="vac">[vac]</select>
+            </td>
+            <td width="5">
+                <button class="btn-success" onclick="settings_save('vac')">Сохранить</button>
+            </td>
+        </tr>
+        <!-- Быстрая скачка файлов с сервера (FastDL) !-->
+        <tr>
+            <td align="center" colspan="2"><b>Быстрая скачка файлов с сервера (FastDL)</b></td>
+        </tr>
+        <tr>
+            <td>
+                <select id="fastdl">[fastdl]</select>
+            </td>
+            <td width="5">
+                <button class="btn-success" onclick="settings_save('fastdl')">Сохранить</button>
+            </td>
+        </tr>
+        <!-- Авторестарт игрового сервера при зависании !-->
+        <tr>
+            <td align="center" colspan="2"><b>Авторестарт при зависании</b></td>
+        </tr>
+        <tr>
+            <td>
+                <select id="autorestart">[autorestart]</select>
+            </td>
+            <td width="5">
+                <button class="btn-success" onclick="settings_save('autorestart')">Сохранить</button>
+            </td>
+        </tr>
+        |tickrate|
+        <!-- Параметр tickrate игрового сервера !-->
+        <tr>
+            <td align="center" colspan="2"><b>Значение TickRate</b></td>
+        </tr>
+        <tr>
+            <td>
+                <select id="tickrate">[tickrate]</select>
+            </td>
+            <td width="5">
+                <button class="btn-success" onclick="settings_save('tickrate')">Сохранить</button>
+            </td>
+        </tr>
+        |_tickrate|
+        </tbody>
+    </table>
+</div>
+
+<script src="[js]sections/servers/settings/start.js" type="text/javascript"></script>
+<script type="text/javascript">
+    var server = '[id]';
+    $(document).ready(function () {
+        maplist();
+    });
+</script>

+ 38 - 0
template/sections/servers/rust/vmenu.html

@@ -0,0 +1,38 @@
+<div class="mini_screen">
+    <div class="title">Управление</div>
+    <ul>
+        <li><a |index|class="active" |_index| href="[home]servers/id/[id]"><i class="fa fa-bars"></i> Основное</a></li>
+        |console_use|
+        <li><a |console|class="active" |_console| href="[home]servers/id/[id]/section/console"><i
+                class="fa fa-television"></i> Консоль</a></li>
+        |_console_use|
+        <li><a |settings|class="active" |_settings| href="[home]servers/id/[id]/section/settings"><i
+                class="fa fa-cog"></i> Настройки</a></li>
+        |plugins_use|
+        <li><a |plugins|class="active" |_plugins| href="[home]servers/id/[id]/section/plugins"><i
+                class="fa fa-cubes"></i> Плагины</a></li>
+        |_plugins_use|
+        <li><a |maps|class="active" |_maps| href="[home]servers/id/[id]/section/maps"><i class="fa fa-picture-o"></i>
+            Карты</a></li>
+        <li><a |owners|class="active" |_owners| href="[home]servers/id/[id]/section/owners"><i
+                class="fa fa-user-plus"></i> Друзья</a></li>
+        |ftp_use|
+        <li><a |filetp|class="active" |_filetp| href="[home]servers/id/[id]/section/filetp"><i
+                class="fa fa-folder-open"></i> FTP</a></li>
+        |_ftp_use|
+        <li><a |tarif|class="active" |_tarif| href="[home]servers/id/[id]/section/tarif"><i class="fa fa-dropbox"></i>
+            Тариф</a></li>
+        |copy_use|
+        <li><a |copy|class="active" |_copy| href="[home]servers/id/[id]/section/copy"><i class="fa fa-clone"></i> Копии</a>
+        </li>
+        |_copy_use|
+        |graph_use|
+        <li><a |graph|class="active" |_graph| href="[home]servers/id/[id]/section/graph"><i
+                class="fa fa-area-chart"></i> Графики</a></li>
+        |_graph_use|
+        |web_use|
+        <li><a |web|class="active" |_web| href="[home]servers/id/[id]/section/web"><i class="fa fa-globe"></i> Web</a>
+        </li>
+        |_web_use|
+    </ul>
+</div>

+ 1 - 0
template/sections/servers/rust/web.html

@@ -0,0 +1 @@
+[web]

+ 120 - 0
template/sections/services/games/rust.html

@@ -0,0 +1,120 @@
+<h4 class="hblock_content">Аренда игрового сервера</h4>
+
+|!informer|
+<div class="block_content">
+    <form action="[home]services/section/rust/go/" method="POST" id="rust">
+        <table class="table_pad form">
+            <tbody>
+            <tr>
+                <td colspan="2">
+                    <label for="unit">Локация:</label>
+                    <select id="unit" name="unit" onchange="change_data('tarifs')">
+                        [units]
+                    </select>
+                </td>
+            </tr>
+            <tr>
+                <td colspan="2">
+                    <label for="tarifs">Тариф:</label>
+                    <select id="tarifs" name="tarif" onchange="change_data('data')">
+                        [tarifs]
+                    </select>
+                </td>
+            </tr>
+            <tr>
+                <td colspan="2">
+                    <label for="packs">Сборка:</label>
+                    <select id="packs" name="pack">
+                        [packs]
+                    </select>
+                </td>
+            </tr>
+            <tr>
+                <td colspan="2">
+                    <label for="tickrate">TickRate:</label>
+                    <select id="tickrate" name="tickrate" onchange="upd_price()">
+                        [tickrate]
+                    </select>
+                </td>
+            </tr>
+            <tr>
+                <td colspan="2">
+                    <label for="slots">Слоты:</label>
+                    <select id="slots" name="slots" onchange="upd_price()">
+                        [slots]
+                    </select>
+                </td>
+            </tr>
+            |!settlement_period|
+            <tr>
+                <td colspan="2">
+                    <label for="time">Период:</label>
+                    <select id="time" name="time" onchange="upd_price()">
+                        [time]
+                    </select>
+                </td>
+            </tr>
+            |_!settlement_period|
+            <tr>
+                <td>
+                    <label for="time">Промо-код:</label>
+                    <input id="promo" name="promo" placeholder="Введите имеющийся промо-код">
+                </td>
+                <td width="5%" class="vbot">
+                    <div class="btn margin-bottom" onclick="promo()">Проверить</div>
+                </td>
+            </tr>
+            <tr id="promo_tr" class="none">
+                <td colspan="2" id="promo_info"></td>
+            </tr>
+            |!settlement_period|
+            <tr>
+                <td colspan="2" id="sum_info">Цена за выбранный период: <span id="sum">...</span> [cur]</td>
+            </tr>
+            |_!settlement_period|
+            |settlement_period|
+            <tr>
+                <td colspan="2">
+                    <p>Текущая дата: [date]</p>
+                    <p id="sum_info">Итого к оплате: <span id="sum">...</span> [cur]</p>
+
+                    <br>
+                    <div class="informer blue">
+                        <p>Система оплаты работает по расчетному периоду.</p>
+                        <p>При оплате до 15-го числа взымается плата за остаток текущего месяца.</p>
+                        <p>При оплате после 15-го числа взымается плата за остаток текущего месяца + следующий
+                            месяц.</p>
+                    </div>
+                </td>
+            </tr>
+            |_settlement_period|
+            <tr>
+                <td colspan="2">
+                    <button onclick="loading(1)" class="btn-success right">Арендовать игровой сервер</button>
+                </td>
+            </tr>
+            </tbody>
+        </table>
+    </form>
+</div>
+
+<div class="space"></div>
+
+<p>Внимание: заказывая сервер, вы соглашаетесь с условиями <a href="[home]agreement"><u>договора</u></a>.</p>
+|_!informer|
+|informer|
+<div class="space"></div>
+<div class="informer blue">
+    <center>К сожалению, в данный момент нет свободного места на оборудовании для предоставления аренды нового игрового
+        сервера.
+    </center>
+</div>
+|_informer|
+
+<script src="[js]sections/services/rust.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+    $(document).ready(function () {
+        upd_price();
+    });
+</script>

+ 7 - 0
template/sections/services/index.html

@@ -35,6 +35,13 @@
     <a href="[home]services/section/cs2">Заказать</a>
 </div>
 
+<div class="service">
+    <div class="line"></div>
+    <span class="title">RUST</span>
+    <img src="[img]services/csgo.png" width="180">
+    <a href="[home]services/section/rust">Заказать</a>
+</div>
+
 <div class="service">
     <div class="line"></div>
     <span class="title">GTA: SA-MP</span>