Advertisement
Guest User

eBot - Match.php Kniferound-Fix

a guest
Feb 1st, 2016
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 152.25 KB | None | 0 0
  1. <?php
  2.  
  3. /**
  4. * eBot - A bot for match management for CS:GO
  5. * @license http://creativecommons.org/licenses/by/3.0/ Creative Commons 3.0
  6. * @author Julien Pardons <julien.pardons@esport-tools.net>
  7. * @version 3.0
  8. * @date 21/10/2012
  9. */
  10.  
  11. namespace eBot\Match;
  12.  
  13. use eTools\Utils\Logger;
  14. use eBot\Exception\MatchException;
  15. use eBot\Match\Map;
  16. use eTools\Task\TaskManager;
  17. use eTools\Task\Task;
  18. use eTools\Task\Taskable;
  19. use eTools\Rcon\CSGO as Rcon;
  20.  
  21. class Match implements Taskable {
  22.  
  23. const STATUS_NOT_STARTED = 0;
  24. const STATUS_STARTING = 1;
  25. const STATUS_WU_KNIFE = 2;
  26. const STATUS_KNIFE = 3;
  27. const STATUS_END_KNIFE = 4;
  28. const STATUS_WU_1_SIDE = 5;
  29. const STATUS_FIRST_SIDE = 6;
  30. const STATUS_WU_2_SIDE = 7;
  31. const STATUS_SECOND_SIDE = 8;
  32. const STATUS_WU_OT_1_SIDE = 9;
  33. const STATUS_OT_FIRST_SIDE = 10;
  34. const STATUS_WU_OT_2_SIDE = 11;
  35. const STATUS_OT_SECOND_SIDE = 12;
  36. const STATUS_END_MATCH = 13;
  37. const STATUS_ARCHIVE = 14;
  38. const TASK_ENGAGE_MAP = "engageMap";
  39. const CHANGE_HOSTNAME = "changeHostname";
  40. const TEST_RCON = "testRcon";
  41. const REINIT_RCON = "rconReinit";
  42. const SET_LIVE = "setLive";
  43. const STOP_RECORD = "stopRecord";
  44.  
  45. // Variable calculable (pas en BDD)
  46. private $players = array();
  47. private $players_old = array();
  48. private $rcon = null;
  49. private $lastMessage = 0;
  50. private $match = null;
  51. private $nbRS = 0;
  52. private $message = 0;
  53. private $pluginCsay = false;
  54. private $pluginESL = false;
  55. private $pluginSwitch = false;
  56. private $pluginPrintPlayers = false;
  57. private $waitForRestart = false;
  58. private $flood = array();
  59. private $gameBombPlanter = null;
  60. private $gameBombDefuser = null;
  61. private $enable = true;
  62. private $userToEnter;
  63. private $nbLast = array("nb_max_ct" => 0, "nb_max_t" => 0, "nb_ct" => 0, "nb_ct" => 0);
  64. private $winKnife = "";
  65. private $needDel = false;
  66. private $firstFrag = false;
  67. private $rsKnife = false;
  68. private $password;
  69. private $passwordChanged = false;
  70. private $updatedHeatmap = false;
  71. // Variable en BDD obligatoire
  72. private $match_id = 0;
  73. private $server_ip = "";
  74. private $season_id;
  75. private $score = array("team_a" => 0, "team_b" => 0);
  76. private $nbRound = 0;
  77. private $nbOT = 0;
  78. private $scoreSide = array();
  79. private $scoreJoueurSide = array();
  80. private $config_full_score = false;
  81. private $config_ot = false;
  82. private $ot_startmoney;
  83. private $ot_maxround;
  84. private $config_switch_auto = false;
  85. private $config_kniferound = false;
  86. private $config_streamer = false;
  87. private $streamerReady = false;
  88. private $rules;
  89. private $maxRound = 15;
  90. private $oldMaxround = 15;
  91. private $maps = array();
  92. private $matchData = array();
  93. private $currentMap = null;
  94. private $messageManager;
  95. private $teamAName;
  96. private $teamBName;
  97. private $teamAFlag;
  98. private $teamBFlag;
  99. private $rconPassword;
  100. private $isPaused;
  101. private $backupFile;
  102. private $timeRound = null;
  103. private $roundEndEvent;
  104. private $websocket = null;
  105. private $pause = array("ct" => false, "t" => false);
  106. private $unpause = array("ct" => false, "t" => false);
  107. private $continue = array("ct" => false, "t" => false);
  108. private $side = array("team_a" => "ct", "team_b" => "t");
  109. private $ready = array("ct" => false, "t" => false);
  110. private $stop = array("ct" => false, "t" => false);
  111. private $playMap = array("ct" => "", "t" => "");
  112. private $timeEngageMap = 0;
  113. private $mapIsEngaged = false;
  114. private $waitRoundStartRecord = false;
  115. private $forceRoundStartRecord = false;
  116.  
  117. public function __construct($match_id, $server_ip, $rcon) {
  118. Logger::debug("Registring MessageManager");
  119. $this->messageManager = \eBot\Manager\MessageManager::getInstance("CSGO");
  120.  
  121. Logger::debug("Creating match #" . $match_id . " on $server_ip");
  122.  
  123. $this->match_id = $match_id;
  124. $this->server_ip = $server_ip;
  125.  
  126. $query = \mysql_query("SELECT * FROM `matchs` WHERE id = '" . $match_id . "'");
  127. if (!$query) {
  128. throw new MatchException();
  129. }
  130. $this->matchData = \mysql_fetch_assoc($query);
  131.  
  132. // SETTING TEAMNAME AND FLAG
  133. $teama_details = $this->getTeamDetails($this->matchData["team_a"], "a");
  134. $this->teamAName = $teama_details['name'];
  135. $this->teamAFlag = $teama_details['flag'];
  136.  
  137. $teamb_details = $this->getTeamDetails($this->matchData["team_b"], "b");
  138. $this->teamBName = $teamb_details['name'];
  139. $this->teamBFlag = $teamb_details['flag'];
  140.  
  141. $this->season_id = $this->matchData["season_id"];
  142.  
  143. $this->addMatchLog("----------- Creating log file -----------", false, false);
  144. $this->addMatchLog("- Match Parameter", false, false);
  145. $this->addMatchLog("- Match ID: " . $this->match_id, false, false);
  146. $this->addMatchLog("- Teams: " . $this->teamAName . " - " . $this->teamBName, false, false);
  147. $this->addMatchLog("- MaxRound: " . $this->matchData["max_round"], false, false);
  148. $this->addMatchLog("- Overtime: " . ($this->matchData["config_ot"]) ? "yes (money: " . $this->matchData['overtime_startmoney'] . ", round: " . $this->matchData['overtime_max_round'] . ")" : "no", false, false);
  149.  
  150. // Get Websocket
  151. $this->websocket['match'] = \eBot\Application\Application::getInstance()->getWebSocket('match');
  152. $this->websocket['livemap'] = \eBot\Application\Application::getInstance()->getWebSocket('livemap');
  153. $this->websocket['logger'] = \eBot\Application\Application::getInstance()->getWebSocket('logger');
  154.  
  155. $ip = explode(":", $this->server_ip);
  156. try {
  157. $this->rcon = new Rcon($ip[0], $ip[1], $rcon);
  158. $this->rconPassword = $rcon;
  159. Logger::log("RCON init ok");
  160. $this->rcon->send("log on; mp_logdetail 0; logaddress_del " . \eBot\Config\Config::getInstance()->getBot_ip() . ":" . \eBot\Config\Config::getInstance()->getBot_port() . ";logaddress_add " . \eBot\Config\Config::getInstance()->getBot_ip() . ":" . \eBot\Config\Config::getInstance()->getBot_port());
  161. $this->addMatchLog("- RCON connection OK", true, false);
  162. } catch (\Exception $ex) {
  163. $this->needDel = true;
  164. \mysql_query("UPDATE `matchs` SET `enable` = 0, `auto_start` = 0, `status` = 0 WHERE `id` = '" . $this->match_id . "'");
  165. $this->websocket['match']->sendData(json_encode(array('message' => 'button', 'content' => 'stop', 'id' => $this->match_id)));
  166. Logger::error("Rcon failed - " . $ex->getMessage());
  167. Logger::error("Match destructed.");
  168. $this->addMatchLog("RCON Failed - " . $ex->getMessage(), false, false);
  169. throw new MatchException();
  170. }
  171. TaskManager::getInstance()->addTask(new Task($this, self::TEST_RCON, microtime(true) + 30));
  172.  
  173. // CSay Detection
  174. try {
  175. $text = $this->rcon->send("csay_version");
  176. if (preg_match('!"csay_version" = "(.*)"!', $text, $match)) {
  177. $this->addLog("CSay version " . $match[1]);
  178. $this->pluginCsay = true;
  179. $this->pluginPrintPlayers = true;
  180. $this->pluginSwitch = true;
  181. $this->addMatchLog("- CSay version " . $match[1], false, false);
  182. }
  183. } catch (\Exception $ex) {
  184. Logger::error("Error while getting plugins information");
  185. }
  186. // ESL Plugin Detection
  187. try {
  188. $text = $this->rcon->send("esl_version");
  189. if (preg_match('!"esl_version" = "(.*)"!', $text, $match)) {
  190. $this->addLog("ESL Plugin version " . $match[1]);
  191. $this->pluginESL = true;
  192. $this->addMatchLog("- ESL Plugin version " . $match[1], false, false);
  193. }
  194. } catch (\Exception $ex) {
  195. Logger::error("Error while getting plugins information");
  196. }
  197.  
  198. $this->config_full_score = $this->matchData["config_full_score"];
  199. $this->config_kniferound = $this->matchData["config_knife_round"];
  200. $this->config_switch_auto = $this->matchData["config_switch_auto"];
  201. $this->config_ot = $this->matchData["config_ot"];
  202. if ($this->config_ot) {
  203. $this->ot_startmoney = $this->matchData["overtime_startmoney"];
  204. $this->ot_maxround = $this->matchData["overtime_max_round"];
  205. }
  206. $this->config_streamer = $this->matchData["config_streamer"];
  207.  
  208. $this->maxRound = $this->matchData["max_round"];
  209. $this->oldMaxround = $this->maxRound;
  210. $this->rules = $this->matchData["rules"];
  211.  
  212. $this->status = $this->matchData["status"];
  213.  
  214. Logger::debug("Match config loaded - Printing configuration");
  215. $this->addLog("Match configuration" .
  216. " :: Full Score: " . (($this->config_full_score) ? "yes" : "no") .
  217. " :: Switch Auto: " . (($this->config_switch_auto) ? "yes" : "no") .
  218. " :: Over Time: " . (($this->config_ot) ? "yes" : "no") .
  219. " :: KnifeRound: " . (($this->config_kniferound) ? "yes" : "no"));
  220.  
  221. $this->addMatchLog("- Match configuration" .
  222. " :: Full Score: " . (($this->config_full_score) ? "yes" : "no") .
  223. " :: Switch Auto: " . (($this->config_switch_auto) ? "yes" : "no") .
  224. " :: Over Time: " . (($this->config_ot) ? "yes" : "no") .
  225. " :: KnifeRound: " . (($this->config_kniferound) ? "yes" : "no"), false, true);
  226.  
  227. $this->addLog("MaxRound: " . $this->maxRound . " :: Rules: " . $this->rules);
  228.  
  229. // Map Start
  230.  
  231. Logger::debug("Loading maps");
  232. $query = \mysql_query("SELECT * FROM `maps` WHERE match_id = '" . $match_id . "'");
  233. if (!$query) {
  234. throw new MatchException();
  235. }
  236.  
  237. while ($data = \mysql_fetch_assoc($query)) {
  238. $this->maps[$data["id"]] = new Map($data);
  239. $this->maps[$data["id"]]->setNbMaxRound($this->maxRound);
  240. }
  241.  
  242. // Fixing for maxround in OT
  243. if ($this->getStatus() >= self::STATUS_WU_OT_1_SIDE) {
  244. $this->maxRound = $this->ot_maxround;
  245. }
  246.  
  247. if ($this->matchData["current_map"] == null) {
  248. Logger::debug("No map is currently playing, picking one (based on default)");
  249. foreach ($this->maps as &$map) {
  250. if (($map->getStatus() == Map::STATUS_NOT_STARTED) && ($map->getMapsFor() == "default")) {
  251. $this->currentMap = $map;
  252. $this->matchData["current_map"] = $map->getMapId();
  253. Logger::debug("Map #" . $map->getMapId() . " selected");
  254. mysql_query("UPDATE `matchs` SET current_map='" . $map->getMapId() . "' WHERE id='" . $this->match_id . "'");
  255. break;
  256. }
  257. }
  258. } else {
  259. if ($this->maps[$this->matchData["current_map"]]) {
  260. $this->currentMap = $this->maps[$this->matchData["current_map"]];
  261. } else {
  262. $this->addLog("Can't find the map #" . $this->matchData["current_map"], Logger::ERROR);
  263. throw new MatchException();
  264. }
  265. }
  266.  
  267. if ($this->currentMap == null) {
  268. $this->addLog("No map found, exiting matchs", Logger::ERROR);
  269. mysql_query("UPDATE `matchs` SET enable='0', status='" . self::STATUS_END_MATCH . "' WHERE id='" . $this->match_id . "'");
  270. throw new MatchException();
  271. }
  272.  
  273. $this->addLog("Maps selected: #" . $this->currentMap->getMapId() . " - " . $this->currentMap->getMapName() . " - " . $this->currentMap->getStatusText());
  274.  
  275. if ($this->currentMap->getMapName() != "tba") {
  276. $this->mapIsEngaged = true;
  277. $this->addLog("Setting map engaged");
  278. } else {
  279. $this->mapIsEngaged = false;
  280. $this->addLog("Setting veto mode");
  281. }
  282.  
  283. if ($this->getStatus() == self::STATUS_STARTING) {
  284. if (($this->currentMap->getStatus() == Map::STATUS_NOT_STARTED) || ($this->currentMap->getStatus() == Map::STATUS_STARTING)) {
  285. if ($this->config_kniferound) {
  286. Logger::debug("Setting need knife round on map");
  287. $this->currentMap->setNeedKnifeRound(true);
  288. }
  289. }
  290. if ($this->currentMap->getMapName() != "tba") {
  291. Logger::debug("Schedule task for first map");
  292. TaskManager::getInstance()->addTask(new Task($this, self::TASK_ENGAGE_MAP, microtime(true) + 1));
  293. } else {
  294. if ($this->config_kniferound) {
  295. $this->setStatus(self::STATUS_WU_KNIFE, true);
  296. $this->currentMap->setStatus(Map::STATUS_WU_KNIFE, true);
  297. } else {
  298. $this->setStatus(self::STATUS_WU_1_SIDE, true);
  299. $this->currentMap->setStatus(Map::STATUS_WU_1_SIDE, true);
  300. }
  301. }
  302. } else {
  303. if (($this->currentMap->getStatus() == Map::STATUS_NOT_STARTED) || ($this->currentMap->getStatus() == Map::STATUS_STARTING)) {
  304. if ($this->currentMap->getMapName() != "tba") {
  305. Logger::debug("Current map is not started/starting, engaging map");
  306. TaskManager::getInstance()->addTask(new Task($this, self::TASK_ENGAGE_MAP, microtime(true) + 1));
  307. } else {
  308. if ($this->config_kniferound) {
  309. $this->setStatus(self::STATUS_WU_KNIFE, true);
  310. $this->currentMap->setStatus(Map::STATUS_WU_KNIFE, true);
  311. } else {
  312. $this->setStatus(self::STATUS_WU_1_SIDE, true);
  313. $this->currentMap->setStatus(Map::STATUS_WU_1_SIDE, true);
  314. }
  315. }
  316. } else {
  317. Logger::debug("Restore score");
  318. }
  319. }
  320.  
  321. TaskManager::getInstance()->addTask(new Task($this, self::CHANGE_HOSTNAME, microtime(true) + 5));
  322.  
  323. // Setting side for maps
  324. if ($this->currentMap->getCurrentSide() == "ct") {
  325. $this->side['team_a'] = "ct";
  326. $this->side['team_b'] = "t";
  327. } else {
  328. $this->side['team_a'] = "t";
  329. $this->side['team_b'] = "ct";
  330. }
  331.  
  332. // Calculating scores
  333. $this->currentMap->calculScores();
  334.  
  335. $this->score["team_a"] = $this->currentMap->getScore1();
  336. $this->score["team_b"] = $this->currentMap->getScore2();
  337.  
  338. @mysql_query("UPDATE `matchs` SET score_a = '" . $this->score["team_a"] . "', score_b ='" . $this->score["team_b"] . "' WHERE id='" . $this->match_id . "'");
  339.  
  340. // Setting nb OverTime
  341. $this->nbOT = $this->currentMap->getNbOt();
  342.  
  343. // This case happens only when the bot shutdown and restart at this status
  344. if ($this->currentMap->getStatus() == Map::STATUS_END_KNIFE) {
  345. $this->addLog("Setting round to knife round, because was waiting end knife");
  346. $this->currentMap->setStatus(Map::STATUS_WU_KNIFE, true);
  347. $this->setStatus(Map::STATUS_WU_KNIFE, true);
  348. }
  349.  
  350. // Getting all players
  351. $this->recupStatus();
  352.  
  353. // Setting server password
  354. if ($this->matchData["config_password"] != "") {
  355. $this->rcon->send("sv_password \"" . $this->matchData["config_password"] . "\"");
  356. }
  357.  
  358. $this->addMatchLog("----------- End match loading -----------", false, false);
  359.  
  360. if ($this->getStatus() <= self::STATUS_WU_1_SIDE) {
  361. $this->sendTeamNames();
  362. }
  363.  
  364. if ($this->matchData["ingame_enable"] != null && !$this->matchData["ingame_enable"]) {
  365. $this->addLog("Setting match not enabled");
  366. $this->enable = false;
  367. }
  368.  
  369. if ($this->getStatus() > self::STATUS_WU_1_SIDE) {
  370. $this->streamerReady = true;
  371. }
  372.  
  373. // Setting nbMaxRound for sided score
  374. if ($this->getStatus() > self::STATUS_WU_OT_1_SIDE && $this->config_ot) {
  375. $this->currentMap->setNbMaxRound($this->ot_maxround);
  376. }
  377.  
  378. // Sending roundbackup format file
  379. $this->rcon->send("mp_backup_round_file \"ebot_" . $this->match_id . "\"");
  380.  
  381. TaskManager::getInstance()->addTask(new Task($this, self::CHANGE_HOSTNAME, microtime(true) + 60));
  382. }
  383.  
  384. private function recupStatus($eraseAll = false) {
  385. if ($eraseAll) {
  386. unset($this->players);
  387. $this->players = array();
  388. $this->addLog("Deleting all player in BDD");
  389. mysql_query("DELETE FROM players WHERE map_id='" . $this->currentMap->getMapId() . "'");
  390. }
  391.  
  392. if ($this->pluginPrintPlayers) {
  393. $this->addLog("Getting status");
  394. $text = $this->rcon->send("steamu_printPlayer");
  395. $texts = explode("\n", trim($text));
  396. foreach ($texts as $v) {
  397. if (preg_match('!#(\d+) "(.*)" (.*) (\d+) (\d+).(\d+).(\d+).(\d+)!', $v, $arr)) {
  398. $ip = $arr[5] . "." . $arr[6] . "." . $arr[7] . "." . $arr[8];
  399. switch ($arr[4]) {
  400. case 0:
  401. $team = "";
  402. break;
  403. case 1:
  404. $team = "SPECTATOR";
  405. break;
  406. case 2:
  407. $team = "TERRORIST";
  408. break;
  409. case 3:
  410. $team = "CT";
  411. break;
  412. }
  413.  
  414. $this->userToEnter[$arr[1]] = $ip;
  415. $this->processPlayer($arr[1], $arr[2], $team, $arr[3]);
  416. }
  417. }
  418. }
  419. }
  420.  
  421. public function getNbRound() {
  422. return $this->score["team_a"] + $this->score["team_b"] + 1;
  423. }
  424.  
  425. public function getStatusText() {
  426. switch ($this->getStatus()) {
  427. case self::STATUS_NOT_STARTED:
  428. return "Not started";
  429. case self::STATUS_STARTING:
  430. return "Starting";
  431. case self::STATUS_WU_KNIFE:
  432. return "Warmup Knife";
  433. case self::STATUS_KNIFE:
  434. return "Knife Round";
  435. case self::STATUS_END_KNIFE:
  436. return "Waiting choose team - Knife Round";
  437. case self::STATUS_WU_1_SIDE:
  438. return "Warmup first side";
  439. case self::STATUS_FIRST_SIDE:
  440. return "First side - Round #" . $this->getNbRound();
  441. case self::STATUS_WU_2_SIDE:
  442. return "Warmup second side";
  443. case self::STATUS_SECOND_SIDE:
  444. return "Second side - Round #" . $this->getNbRound();
  445. case self::STATUS_WU_OT_1_SIDE:
  446. return "Warmup first side OverTime";
  447. case self::STATUS_OT_FIRST_SIDE:
  448. return "First side OverTime - Round #" . $this->getNbRound();
  449. case self::STATUS_WU_OT_2_SIDE:
  450. return "Warmup second side OverTime";
  451. case self::STATUS_OT_SECOND_SIDE:
  452. return "Second side OverTime - Round #" . $this->getNbRound();
  453. case self::STATUS_END_MATCH:
  454. return "Finished";
  455. }
  456. }
  457.  
  458. public function getStatus() {
  459. return $this->status;
  460. }
  461.  
  462. public function setStatus($newStatus, $save = false) {
  463. $this->status = $newStatus;
  464. $this->websocket['match']->sendData(json_encode(array('message' => 'status', 'content' => $this->getStatusText(), 'id' => $this->match_id)));
  465. $this->websocket['match']->sendData(json_encode(array('message' => 'button', 'content' => $this->getStatus(), 'id' => $this->match_id)));
  466. if ($save) {
  467. $this->message = 0;
  468. Logger::debug("Updating status to " . $this->getStatusText() . " in database");
  469. if ($newStatus == self::STATUS_END_MATCH)
  470. $setDisable = ", enable = '0'";
  471. mysql_query("UPDATE `matchs` SET status='" . $newStatus . "' " . $setDisable . " WHERE id='" . $this->match_id . "'");
  472. }
  473. }
  474.  
  475. private function getHostname() {
  476. return "eBot :: " . $this->teamAName . " vs " . $this->teamBName;
  477. }
  478.  
  479. private function getStreamerReady() {
  480. if ($this->config_streamer)
  481. return $this->streamerReady;
  482. else
  483. return false;
  484. }
  485.  
  486. private function getTeamDetails($id, $t) {
  487. if (is_numeric($id) && $id > 0) {
  488. $ds = mysql_fetch_array(mysql_query("SELECT * FROM `teams` WHERE `id` = '$id'"));
  489. return $ds;
  490. } else {
  491. if ($t == "a") {
  492. return array("name" => $this->matchData['team_a_name'], "flag" => $this->matchData['team_a_flag']);
  493. } elseif ($t == "b") {
  494. return array("name" => $this->matchData['team_b_name'], "flag" => $this->matchData['team_b_flag']);
  495. }
  496. }
  497. }
  498.  
  499. public function taskExecute($name) {
  500. if ($name == self::SET_LIVE) {
  501. $this->addLog("Setting live");
  502. $this->enable = true;
  503. } elseif ($name == self::TASK_ENGAGE_MAP) {
  504. $tvTimeRemaining = $this->rcon->send("tv_time_remaining");
  505. if (preg_match('/(?<time>\d+\.\d+) seconds/', $tvTimeRemaining, $preg)) {
  506. TaskManager::getInstance()->addTask(new Task($this, self::TASK_ENGAGE_MAP, microtime(true) + floatval($preg['time']) + 1));
  507. $this->addLog("Waiting till GOTV broadcast is finished! Mapchange in " . (intval($preg['time']) + 1) . " seconds");
  508. } else {
  509. $this->engageMap();
  510. }
  511. } elseif ($name == self::CHANGE_HOSTNAME) {
  512. if ($this->rcon->getState()) {
  513. $this->rcon->send('hostname "' . $this->getHostname() . '"');
  514. } else {
  515. TaskManager::getInstance()->addTask(new Task($this, self::CHANGE_HOSTNAME, microtime(true) + 5));
  516. }
  517. } elseif ($name == self::TEST_RCON) {
  518. if ($this->rcon->getState()) {
  519. if (!$this->rcon->send('echo eBot')) {
  520. $ip = explode(":", $this->server_ip);
  521. try {
  522. $this->rcon = new Rcon($ip[0], $ip[1], $this->rconPassword);
  523. $this->rcon->send("echo eBot");
  524. } catch (\Exception $ex) {
  525. Logger::error("Reinit rcon failed - " . $ex->getMessage());
  526. Logger::error("Trying to rengage in 10 seconds");
  527. $this->addMatchLog("RCON Connection failed, trying to engage the match in 10 seconds", true);
  528.  
  529. \eBot\Manager\MatchManager::getInstance()->delayServer($this->server_ip, 10);
  530. $this->needDel = true;
  531. }
  532. }
  533. }
  534. TaskManager::getInstance()->addTask(new Task($this, self::TEST_RCON, microtime(true) + 10));
  535. } elseif ($name == self::REINIT_RCON) {
  536. $ip = explode(":", $this->server_ip);
  537. try {
  538. $this->rcon = new Rcon($ip[0], $ip[1], $this->rconPassword);
  539. $this->rcon->send("echo eBot");
  540. } catch (\Exception $ex) {
  541. Logger::error("Reinit rcon failed - " . $ex->getMessage());
  542. Logger::error("Trying to rengage in 10 seconds");
  543. $this->addMatchLog("RCON Connection failed, trying to engage the match in 10 seconds", true);
  544.  
  545. \eBot\Manager\MatchManager::getInstance()->delayServer($this->server_ip, 10);
  546. $this->needDel = true;
  547. }
  548. } elseif ($name == self::STOP_RECORD) {
  549. $this->needDelTask = false;
  550. $this->addLog("Stopping record & push");
  551. $this->rcon->send("tv_stoprecord");
  552. if (\eBot\Config\Config::getInstance()->getDemoDownload())
  553. $this->rcon->send('csay_tv_demo_push "' . $this->currentRecordName . '.dem" "http://' . \eBot\Config\Config::getInstance()->getBot_ip() . ':' . \eBot\Config\Config::getInstance()->getBot_port() . '/upload"');
  554. $this->currentRecordName = "";
  555. $this->rcon->send("exec server.cfg;");
  556. }
  557. }
  558.  
  559. /**
  560. * Engaging the first map
  561. */
  562. private function engageMap() {
  563. $this->timeEngageMap = 0;
  564. if ($this->currentMap == null) {
  565. $this->addLog("Can't engage the map, map is null");
  566. return;
  567. }
  568.  
  569. if ((($this->currentMap->getStatus() == Map::STATUS_STARTING) || ($this->currentMap->getStatus() == Map::STATUS_NOT_STARTED)) OR !$this->mapIsEngaged) {
  570. $this->addLog("Engaging the first map");
  571.  
  572. // Warmup
  573. $this->rcon->send("mp_warmuptime 1");
  574. $this->rcon->send("mp_warmup_pausetimer 1; mp_halftime_duration 5;");
  575. if ($this->config_full_score) {
  576. $this->rcon->send("mp_match_can_clinch 0;");
  577. }
  578.  
  579. // Changing map
  580. $this->addLog("Changing map to " . $this->currentMap->getMapName());
  581. $this->rcon->send("changelevel " . $this->currentMap->getMapName());
  582.  
  583. if ($this->config_kniferound) {
  584. $this->setStatus(self::STATUS_WU_KNIFE, true);
  585. $this->currentMap->setStatus(Map::STATUS_WU_KNIFE, true);
  586. } else {
  587. $this->setStatus(self::STATUS_WU_1_SIDE, true);
  588. $this->currentMap->setStatus(Map::STATUS_WU_1_SIDE, true);
  589. }
  590.  
  591. $this->mapIsEngaged = true;
  592.  
  593. TaskManager::getInstance()->addTask(new Task($this, self::CHANGE_HOSTNAME, microtime(true) + 3));
  594. } else {
  595. $this->setStatus($this->currentMap->getStatus(), true);
  596. Logger::error("Map already engaged");
  597. }
  598. }
  599.  
  600. private function isWarmupRound() {
  601. return ($this->getStatus() == self::STATUS_WU_1_SIDE) || ($this->getStatus() == self::STATUS_WU_2_SIDE) || ($this->getStatus() == self::STATUS_WU_KNIFE) || ($this->getStatus() == self::STATUS_WU_OT_1_SIDE) || ($this->getStatus() == self::STATUS_WU_OT_2_SIDE);
  602. }
  603.  
  604. private function isMatchRound() {
  605. return ($this->getStatus() == self::STATUS_KNIFE) || ($this->getStatus() == self::STATUS_FIRST_SIDE) || ($this->getStatus() == self::STATUS_SECOND_SIDE) || ($this->getStatus() == self::STATUS_OT_FIRST_SIDE) || ($this->getStatus() == self::STATUS_OT_SECOND_SIDE);
  606. }
  607.  
  608. public function sendRotateMessage() {
  609. // This is to send to players the status
  610. if ($this->isMatchRound() && !$this->enable) {
  611. if (time() - $this->lastMessage >= 8) {
  612. $this->say("\001Match is paused, write !continue to continue the match");
  613. $teamA = strtoupper($this->side['team_a']);
  614. $teamB = strtoupper($this->side['team_b']);
  615.  
  616. if ($this->continue[$this->side['team_a']])
  617. $teamA = "\004$teamA\001";
  618. if ($this->continue[$this->side['team_b']])
  619. $teamB = "\004$teamB\001";
  620. $this->lastMessage = time();
  621.  
  622. $message = "\003Waiting to continue the match - \005" . $this->teamAName . " \001($teamA\001) \001VS \001($teamB\001) \005" . $this->teamBName;
  623. $this->say($message);
  624. }
  625. }
  626.  
  627. if ($this->isMatchRound())
  628. return;
  629.  
  630. if ($this->matchData["enable"] == 1) {
  631. if (time() - $this->lastMessage >= 8) {
  632. if ($this->getStatus() == self::STATUS_STARTING && $this->timeEngageMap > 0) {
  633. $time = ceil($this->timeEngageMap - microtime(true));
  634. $this->lastMessage = time();
  635. $this->say("Waiting till GOTV Broadcast is finished.");
  636. $this->say("The next map will start in #lightgreen" . $time . "#default seconds!");
  637. } else {
  638. // Récupération du SIDE de l'équipe
  639. $teamA = strtoupper($this->side['team_a']);
  640. $teamB = strtoupper($this->side['team_b']);
  641.  
  642. if ($this->ready[$this->side['team_a']])
  643. $teamA = "\004$teamA\001";
  644. if ($this->ready[$this->side['team_b']])
  645. $teamB = "\004$teamB\001";
  646.  
  647. $message = "";
  648. // Récupération du texte
  649. switch ($this->getStatus()) {
  650. case self::STATUS_WU_KNIFE: $message = "Warmup Knife Round";
  651. break;
  652. case self::STATUS_END_KNIFE: $message = "Waiting for team select from knife winner (!stay/!switch))";
  653. break;
  654. case self::STATUS_WU_1_SIDE: $message = "Warmup First Side";
  655. break;
  656. case self::STATUS_WU_2_SIDE: $message = "Warmup Second Side";
  657. break;
  658. case self::STATUS_WU_OT_1_SIDE: $message = "Warmup First Side OverTime";
  659. break;
  660. case self::STATUS_WU_OT_2_SIDE: $message = "Warmup Second Side OverTime";
  661. break;
  662. }
  663. if ($this->mapIsEngaged && ($this->streamerReady || !$this->config_streamer)) {
  664. $messages [] = "\003Please write \006!ready \003when your team is ready !";
  665. $messages [] = "\003Available commands: !help, !rules, !ready, !notready";
  666. } elseif ($this->mapIsEngaged && (!$this->streamerReady || $this->config_streamer)) {
  667. $messages [] = "\003Streamers are not ready yet !";
  668. } else {
  669. $messages [] = "\003Please write \006!map mapname \003to select the map!";
  670. $maps = \eBot\Config\Config::getInstance()->getMaps();
  671. foreach ($maps as $map) {
  672. $mapmessage .= "$map, ";
  673. }
  674. $messages [] = "\003" . substr($mapmessage, 0, -2);
  675. }
  676.  
  677. if ($message)
  678. $messages [] = "\003$message - \005" . $this->teamAName . " \001($teamA\001) \001VS \001($teamB\001) \005" . $this->teamBName;
  679.  
  680. $adverts = \eBot\Config\Config::getInstance()->getAdvertising($this->season_id);
  681.  
  682. for ($i = 0; $i < count($adverts['season_id']); $i++) {
  683. $messages [] = "\003" . $adverts['message'][$i];
  684. if ($message)
  685. $messages [] = "\003$message - \005" . $this->teamAName . " \001($teamA\001) \001VS \001($teamB\001) \005" . $this->teamBName;
  686. }
  687.  
  688. $message = $messages[$this->message++ % count($messages)];
  689. $this->lastMessage = time();
  690. $this->say($message);
  691. }
  692. }
  693. }
  694. }
  695.  
  696. public function say($message) {
  697. /**
  698. * \001 white
  699. * \002 red
  700. * \003 white
  701. * \004 green
  702. * \005 lightgreen
  703. * \006 lightgreen2
  704. * \007 lightred
  705. */
  706. $message = str_replace("#default", "\001", $message);
  707. $message = str_replace("#green", "\004", $message);
  708. $message = str_replace("#lightgreen2", "\006", $message);
  709. $message = str_replace("#lightgreen", "\005", $message);
  710. $message = str_replace("#red", "\002", $message);
  711. $message = str_replace("#lightred", "\007", $message);
  712.  
  713. // temporary fix because of ugly chatcolor after last csgo update
  714. $message = str_replace("\003", "\001", $message);
  715.  
  716. try {
  717. if (!$this->pluginCsay) {
  718. $message = str_replace(array("\001", "\002", "\003", "\004", "\005", "\006", "\007"), array("", "", "", "", "", "", ""), $message);
  719. $message = str_replace(";", ",", $message);
  720. $this->rcon->send('say eBot: ' . addslashes($message) . '');
  721. } else {
  722. $message = str_replace('"', '\\"', $message);
  723. $this->rcon->send('csay_all "' . "e\004Bot\001: " . $message . '"');
  724. }
  725. } catch (\Exception $ex) {
  726. Logger::error("Say failed - " . $ex->getMessage());
  727. }
  728. }
  729.  
  730. public function destruct() {
  731. $this->websocket['logger']->sendData('removeMatch_' . $this->match_id);
  732. TaskManager::getInstance()->removeAllTaskForObject($this);
  733. unset($this->rcon);
  734. $this->addLog("Destructing match " . $this->match_id);
  735. }
  736.  
  737. public function getNeedDel() {
  738. return $this->needDel;
  739. }
  740.  
  741. public function getNeedDelTask() {
  742. return $this->needDelTask;
  743. }
  744.  
  745. /**
  746. * Process a message from log stream
  747. * @param String $message
  748. */
  749. public function processMessage($message) {
  750. if ($this->getStatus() >= self::STATUS_END_MATCH)
  751. return;
  752.  
  753. $message = $this->messageManager->processMessage($message);
  754.  
  755. if ($message != null) {
  756. switch (get_class($message)) {
  757. case "eBot\Message\Type\BombDefusing":
  758. return $this->processBombDefusing($message);
  759. case "eBot\Message\Type\BombPlanting":
  760. return $this->processBombPlanting($message);
  761. case "eBot\Message\Type\ChangeMap":
  762. return $this->processChangeMap($message);
  763. case "eBot\Message\Type\ChangeName":
  764. return $this->processChangeName($message);
  765. case "eBot\Message\Type\Connected":
  766. return $this->processConnected($message);
  767. case "eBot\Message\Type\Disconnected":
  768. return $this->processDisconnected($message);
  769. case "eBot\Message\Type\EnteredTheGame":
  770. return $this->processEnteredTheGame($message);
  771. case "eBot\Message\Type\GotTheBomb":
  772. return $this->processGotTheBomb($message);
  773. case "eBot\Message\Type\JoinTeam":
  774. return $this->processJoinTeam($message);
  775. case "eBot\Message\Type\Kill":
  776. return $this->processKill($message);
  777. case "eBot\Message\Type\KillAssist":
  778. return $this->processKillAssist($message);
  779. case "eBot\Message\Type\RoundRestart":
  780. return $this->processRoundRestart($message);
  781. case "eBot\Message\Type\RoundScored":
  782. return $this->processRoundScored($message);
  783. case "eBot\Message\Type\RoundStart":
  784. return $this->processRoundStart($message);
  785. case "eBot\Message\Type\Say":
  786. return $this->processSay($message);
  787. case "eBot\Message\Type\ThrewStuff":
  788. return $this->processThrewStuff($message);
  789. case "eBot\Message\Type\Purchased":
  790. return $this->processPurchased($message);
  791. case "eBot\Message\Type\TeamScored":
  792. return $this->processTeamScored($message);
  793. case "eBot\Message\Type\RoundEnd":
  794. return $this->processRoundEnd($message);
  795. default:
  796. $this->addLog("Message non traité: " . get_class($message));
  797. break;
  798. }
  799. }
  800. }
  801.  
  802. private $tempScoreA = null;
  803. private $tempScoreB = null;
  804.  
  805. private function processTeamScored(\eBot\Message\Type\TeamScored $message) {
  806. if (!$this->roundEndEvent) {
  807. if ($message->team == $this->side['team_a']) {
  808. $this->tempScoreA = $message->score;
  809. $this->addLog("Score for ".$this->teamAName.": ".$this->tempScoreA);
  810. } else {
  811. $this->tempScoreB = $message->score;
  812. $this->addLog("Score for ".$this->teamBName.": ".$this->tempScoreB);
  813. }
  814. }
  815. }
  816.  
  817. private function processRoundEnd(\eBot\Message\Type\RoundEnd $message) {
  818. if (!$this->roundEndEvent) {
  819. $this->addLog(($this->tempScoreA + $this->tempScoreB) - ($this->score['team_a'] + $this->score['team_b']));
  820. if (($this->tempScoreA + $this->tempScoreB) - ($this->score['team_a'] + $this->score['team_b']) == 1) {
  821. $messageNew = new \eBot\Message\Type\RoundScored();
  822. if ($this->tempScoreA > $this->score['team_a']) {
  823. $messageNew->team = strtoupper($this->side['team_a']);
  824. $messageNew->team_win = strtoupper($this->side['team_a']);
  825. $messageNew->teamWin = strtoupper($this->side['team_a']);
  826. } else {
  827. $messageNew->team = strtoupper($this->side['team_b']);
  828. $messageNew->team_win = strtoupper($this->side['team_b']);
  829. $messageNew->teamWin = strtoupper($this->side['team_b']);
  830. }
  831.  
  832. if ($messageNew->team == "T") {
  833. $messageNew->team = "TERRORIST";
  834. }
  835. $messageNew->type = "normal";
  836.  
  837. $this->addLog("Need a score fix ! Score detected: ".$this->tempScoreA.":".$this->tempScoreB." - Score in system: ".$this->score['team_a'].":".$this->score['team_b']);
  838. $this->processRoundScored($messageNew);
  839. }
  840. }
  841. $this->tempScoreA = null;
  842. $this->tempScoreB = null;
  843. }
  844.  
  845. private function processChangeMap(\eBot\Message\Type\ChangeMap $message) {
  846. Logger::debug("Processing Change Map");
  847.  
  848. $this->addLog("Loading maps " . $message->maps);
  849. $this->addMatchLog("Loading maps " . $message->maps);
  850.  
  851. $ip = explode(":", $this->server_ip);
  852. try {
  853. $this->rcon = new Rcon($ip[0], $ip[1], $this->rconPassword);
  854. $this->rcon->send("echo eBot;");
  855.  
  856. if ($this->matchData["config_password"] != "") {
  857. $this->rcon->send("sv_password \"" . $this->matchData["config_password"] . "\"");
  858. }
  859.  
  860. $this->rcon->send("mp_warmup_pausetimer 1");
  861.  
  862. if ($this->config_ot) {
  863. $this->rcon->send("mp_overtime_enable 1");
  864. $this->rcon->send("mp_overtime_maxrounds " . ($this->ot_maxround * 2));
  865. $this->rcon->send("mp_overtime_startmoney " . $this->ot_startmoney);
  866. $this->rcon->send("mp_overtime_halftime_pausetimer 1");
  867. }
  868.  
  869. $this->sendTeamNames();
  870. } catch (\Exception $ex) {
  871. Logger::error("Reinit rcon failed - " . $ex->getMessage());
  872. TaskManager::getInstance()->addTask(new Task($this, self::REINIT_RCON, microtime(true) + 1));
  873. }
  874. }
  875.  
  876. /**
  877. * Processing message for planting bomb.
  878. * Setting the gameBombPlanter to the user
  879. * @param \eBot\Message\Type\BombPlanting $message
  880. */
  881. private function processBombPlanting(\eBot\Message\Type\BombPlanting $message) {
  882. Logger::debug("Processing Bomb Planting");
  883.  
  884. // Getting the player who planted the bomb
  885. $user = $this->processPlayer($message->getUserId(), $message->getUserName(), $message->getUserTeam(), $message->getUserSteamid());
  886. $this->gameBombPlanter = $user;
  887.  
  888. $this->addLog($message->getUserName() . " planted the bomb");
  889. $this->addMatchLog($this->getColoredUserNameHTML($message->getUserName(), $message->getUserTeam()) . " planted the bomb");
  890.  
  891. // Dispatching events
  892. $event = new \eBot\Events\Event\BombPlanting();
  893. $event->setMatch($this);
  894. $event->setUserId($message->getUserId());
  895. $event->setUserName($message->getUserName());
  896. $event->setUserTeam($message->getUserTeam());
  897. $event->setUserSteamid($message->getUserSteamid());
  898. \eBot\Events\EventDispatcher::getInstance()->dispatchEvent($event);
  899.  
  900. // Round TimeLine
  901. $text = addslashes(serialize(array("id" => $user->getId(), "name" => $message->getUserName())));
  902. \mysql_query("
  903. INSERT INTO `round`
  904. (`match_id`,`map_id`,`event_name`,`event_text`,`event_time`,`round_id`,`created_at`,`updated_at`)
  905. VALUES
  906. ('" . $this->match_id . "', '" . $this->currentMap->getMapId() . "', 'bomb_planting', '" . $text . "', '" . $this->getRoundTime() . "', '" . $this->getNbRound() . "', NOW(), NOW())
  907. ");
  908. }
  909.  
  910. /**
  911. * Processing message for defusing bomb.
  912. * Setting the gameBombDefuser to the user
  913. * @param \eBot\Message\Type\BombDefusing $message
  914. */
  915. private function processBombDefusing(\eBot\Message\Type\BombDefusing $message) {
  916. Logger::debug("Processing Bomb Defusing");
  917. // Getting the player who is defusing the bomb
  918. $user = $this->processPlayer($message->getUserId(), $message->getUserName(), $message->getUserTeam(), $message->getUserSteamid());
  919. $this->gameBombDefuser = $user;
  920.  
  921. $this->addLog($message->getUserName() . " is defusing bomb");
  922. $this->addMatchLog($this->getColoredUserNameHTML($message->getUserName(), $message->getUserTeam()) . " is defusing bomb");
  923.  
  924. // Dispatching events
  925. $event = new \eBot\Events\Event\BombDefusing();
  926. $event->setMatch($this);
  927. $event->setUserId($message->getUserId());
  928. $event->setUserName($message->getUserName());
  929. $event->setUserTeam($message->getUserTeam());
  930. $event->setUserSteamid($message->getUserSteamid());
  931. \eBot\Events\EventDispatcher::getInstance()->dispatchEvent($event);
  932.  
  933. // Round TimeLine
  934. $text = addslashes(serialize(array("id" => $user->getId(), "name" => $message->getUserName())));
  935. \mysql_query("
  936. INSERT INTO `round`
  937. (`match_id`,`map_id`,`event_name`,`event_text`,`event_time`,`round_id`,`created_at`,`updated_at`)
  938. VALUES
  939. ('" . $this->match_id . "', '" . $this->currentMap->getMapId() . "', 'bomb_defusing', '" . $text . "', '" . $this->getRoundTime() . "', '" . $this->getNbRound() . "', NOW(), NOW())
  940. ");
  941. }
  942.  
  943. private function processThrewStuff(\eBot\Message\Type\ThrewStuff $message) {
  944. Logger::debug("Processing ThrewStuff Message");
  945.  
  946. if (!$this->waitForRestart && $this->enable && in_array($this->getStatus(), array(self::STATUS_FIRST_SIDE, self::STATUS_SECOND_SIDE, self::STATUS_OT_FIRST_SIDE, self::STATUS_OT_SECOND_SIDE))) {
  947. $user = $this->processPlayer($message->getUserId(), $message->getUserName(), $message->getUserTeam(), $message->getUserSteamid());
  948.  
  949. \mysql_query("INSERT INTO `players_heatmap` (`match_id`,`map_id`,`event_name`,`event_x`,`event_y`,`event_z`,`player_name`,`player_id`,`player_team`,`round_id`,`round_time`, `created_at`,`updated_at`)
  950. VALUES
  951. (" . $this->match_id . ", " . $this->currentMap->getMapId() . ", '" . $message->stuff . "', '" . $message->posX . "', '" . $message->posY . "', '" . $message->posZ . "', '" . addslashes($message->userName) . "', '" . $user->getId() . "', '" . $message->userTeam . "', '" . $this->getNbRound() . "', '" . $this->getRoundTime() . "', NOW(), NOW())
  952. ");
  953.  
  954. $this->addLog($message->userName . " (" . $message->userTeam . ") threw " . $message->stuff . " at [" . $message->posX . " " . $message->posY . " " . $message->posZ . "]");
  955. }
  956. }
  957.  
  958. private function processPurchased(\eBot\Message\Type\Purchased $message) {
  959. Logger::debug("Processing Purchased Message");
  960. if (!$this->waitForRestart && $this->enable && in_array($this->getStatus(), array(self::STATUS_FIRST_SIDE, self::STATUS_SECOND_SIDE, self::STATUS_OT_FIRST_SIDE, self::STATUS_OT_SECOND_SIDE))) {
  961. $user = $this->processPlayer($message->getUserId(), $message->getUserName(), $message->getUserTeam(), $message->getUserSteamid());
  962.  
  963. $text = \addslashes(\serialize(array("item" => $message->object, "player" => $user->getId(), "playerName" => $user->get("name"))));
  964.  
  965. \mysql_query("
  966. INSERT INTO `round`
  967. (`match_id`,`map_id`,`event_name`,`event_text`,`event_time`,`round_id`,`created_at`,`updated_at`)
  968. VALUES
  969. ('" . $this->match_id . "', '" . $this->currentMap->getMapId() . "', 'purchased', '$text', '" . $this->getRoundTime() . "', '" . $this->getNbRound() . "', NOW(), NOW())
  970. ");
  971.  
  972. // $this->addLog($message->userName . " (" . $message->userTeam . ") purchased " . $message->object);
  973. }
  974. }
  975.  
  976. /**
  977. * Processing say message
  978. * Made action with the message
  979. * Dispatch a Say event
  980. * @param \eBot\Message\Type\Say $message
  981. */
  982. private function processSay(\eBot\Message\Type\Say $message) {
  983. Logger::debug("Processing Say Message");
  984.  
  985. $user = $this->processPlayer($message->getUserId(), $message->getUserName(), $message->getUserTeam(), $message->getUserSteamid());
  986.  
  987. $text = trim($message->getText());
  988. if (preg_match('/\!map (?<mapname>.*)/', $text, $preg)) {
  989. if (!$this->mapIsEngaged && (( $this->getStatus() == self::STATUS_WU_KNIFE && $this->config_kniferound ) || ( $this->getStatus() == self::STATUS_WU_1_SIDE && !$this->config_kniferound ))) {
  990. $this->addLog($message->getUserName() . " (" . $message->getUserTeam() . ") wants to play " . $preg['mapname']);
  991. Logger::log($message->getUserName() . " (" . $message->getUserTeam() . ") wants to play " . $preg['mapname']);
  992. if ($message->getUserTeam() == "CT") {
  993. $team = ($this->side['team_a'] == "ct") ? $this->teamAName : $this->teamBName;
  994. $maps = \eBot\Config\Config::getInstance()->getMaps();
  995. if (in_array($preg['mapname'], $maps)) {
  996. $this->playMap['ct'] = $preg['mapname'];
  997. $this->say($team . " (CT) \003wants to play \004" . $preg['mapname']);
  998. } else {
  999. $this->say($preg['mapname'] . " was not found! Available maps are:");
  1000. foreach ($maps as $map) {
  1001. $mapmessage .= "$map, ";
  1002. }
  1003. $this->say(substr($mapmessage, 0, -2));
  1004. }
  1005. } elseif ($message->getUserTeam() == "TERRORIST") {
  1006. $team = ($this->side['team_a'] == "t") ? $this->teamAName : $this->teamBName;
  1007.  
  1008. $maps = \eBot\Config\Config::getInstance()->getMaps();
  1009. if (in_array($preg['mapname'], $maps)) {
  1010. $this->playMap['t'] = $preg['mapname'];
  1011. $this->say($team . " (T) \003wants to play \004" . $preg['mapname']);
  1012. } else {
  1013. $this->say($preg['mapname'] . " was not found! Available maps are:");
  1014. foreach ($maps as $map) {
  1015. $mapmessage .= "$map, ";
  1016. }
  1017. $this->say(substr($mapmessage, 0, -2));
  1018. }
  1019. }
  1020.  
  1021. $this->setMatchMap($preg['mapname']);
  1022. } else {
  1023. $this->addLog("Veto isn't enabled");
  1024. }
  1025. } elseif ($text == "!stats") {
  1026. $this->addLog($message->getUserName() . " ask his stats");
  1027.  
  1028. if ($user) {
  1029. $this->rcon->send("csay_to_player " . $message->userId . " \"e\004Bot\001: \001stats pour \003" . $message->userName . "\"");
  1030. if ($user->get("death") == 0) {
  1031. $ratio = $user->get("kill");
  1032. } else {
  1033. $ratio = round($user->get("kill") / $user->get("death"), 2);
  1034. }
  1035.  
  1036. if ($user->get("kill") == 0) {
  1037. $ratiohs = 0;
  1038. } else {
  1039. $ratiohs = round(($user->get("hs") / $user->get("kill")) * 100, 2);
  1040. }
  1041.  
  1042. $this->rcon->send("csay_to_player " . $message->userId . " \" \005Kill: \004" . $user->get("kill") . " \001- \005HS: \004" . $user->get("hs") . "\"");
  1043. $this->rcon->send("csay_to_player " . $message->userId . " \" \005Death: \004" . $user->get("death") . " \001- \005Score: \004" . $user->get("point") . "\"");
  1044. $this->rcon->send("csay_to_player " . $message->userId . " \" \005Ratio K/D: \004" . $ratio . " \001- \005HS%: \004" . $ratiohs . "\"");
  1045. } else {
  1046. $this->rcon->send("csay_to_player " . $message->userId . " \"e\004Bot\001: pas de stats pour le moment pour \003" . $message->userName . "\"");
  1047. }
  1048. } elseif ($text == "!morestats") {
  1049. $this->addLog($message->getUserName() . " ask more stats");
  1050.  
  1051. if ($user) {
  1052. $this->rcon->send('csay_to_player ' . $message->userId . " \"e\004Bot\001: stats pour \003" . $message->userName . "\"");
  1053.  
  1054. $stats = array();
  1055. for ($i = 1; $i <= 5; $i++) {
  1056. if ($user->get("v$i") > 0) {
  1057. $stats[] = array("name" => "1v$i", "val" => $user->get("v$i"));
  1058. }
  1059.  
  1060. if ($user->get("k$i") > 0) {
  1061. $stats[] = array("name" => $i . " kill/round", "val" => $user->get("k$i"));
  1062. }
  1063. }
  1064.  
  1065. if ($user->get("bombe") > 0) {
  1066. $stats[] = array("name" => "Bombe", "val" => $user->get("bombe"));
  1067. }
  1068.  
  1069. if ($user->get("defuse") > 0) {
  1070. $stats[] = array("name" => "Defuse", "val" => $user->get("defuse"));
  1071. }
  1072.  
  1073. if ($user->get("tk") > 0) {
  1074. $stats[] = array("name" => "TK", "val" => $user->get("tk"));
  1075. }
  1076.  
  1077. if ($user->get("firstKill") > 0) {
  1078. $stats[] = array("name" => "First Kill", "val" => $user->get("firstKill"));
  1079. }
  1080.  
  1081. $messageText = "";
  1082. $count = 0;
  1083. $doit = true;
  1084. foreach ($stats as $v) {
  1085. $count++;
  1086. $doit = false;
  1087. if ($messageText == "")
  1088. $messageText = " \005" . $v["name"] . ": \004" . $v["val"];
  1089. else
  1090. $messageText .= " \001- \005" . $v["name"] . ": \004" . $v["val"];
  1091.  
  1092. if ($count == 2) {
  1093. $this->rcon->send('csay_to_player ' . $message->userId . ' "' . $messageText . '"');
  1094. $messageText = "";
  1095. $count = 0;
  1096. }
  1097. }
  1098.  
  1099. if ($count > 0) {
  1100. $this->rcon->send('csay_to_player ' . $message->userId . ' "' . $messageText . '"');
  1101. }
  1102.  
  1103. if ($doit) {
  1104. $this->rcon->send('csay_to_player ' . $message->userId . " \"e\004Bot\001: Pas de stats pour le moment\"");
  1105. }
  1106. } else {
  1107. $this->rcon->send('csay_to_player ' . $message->userId . " \"e\004Bot\001: Pas de stats pour le moment pour \005" . $message->userName . '"');
  1108. }
  1109. } elseif ($text == "!rules") {
  1110. if ($this->pluginCsay) {
  1111. $this->addLog($message->getUserName() . " ask rules");
  1112.  
  1113. $this->rcon->send("csay_to_player " . $message->userId . " \"e\004Bot\001: Full Score: \005" . (($this->config_full_score) ? "yes" : "no") . " \001:: Switch Auto: \005" . (($this->config_switch_auto) ? "yes" : "no") . "\"");
  1114. $this->rcon->send("csay_to_player " . $message->userId . " \"e\004Bot\001: Over Time: \005" . (($this->config_ot) ? "yes" : "no") . " \001:: MaxRound: \005" . $this->maxRound . "\"");
  1115. }
  1116. } elseif ($text == "!help") {
  1117. if ($this->pluginCsay) {
  1118. $this->addLog($message->getUserName() . " ask help");
  1119. $this->rcon->send("csay_to_player " . $message->userId . " \"e\004Bot\001: commands available: !help, !status, !stats, !morestats, !score, !ready, !notready, !stop, !restart (for knife round), !stay, !switch\"");
  1120. }
  1121. } elseif ($text == "!restart") {
  1122. $this->addLog($message->getUserName() . " say restart");
  1123. if (($this->getStatus() == self::STATUS_KNIFE) || ($this->getStatus() == self::STATUS_END_KNIFE)) {
  1124. if ($message->getUserTeam() == "CT") {
  1125. $team = ($this->side['team_a'] == "ct") ? $this->teamAName : $this->teamBName;
  1126.  
  1127. if (!$this->restart['ct']) {
  1128. $this->restart['ct'] = true;
  1129. $this->say($team . " (CT) \003want to restart the knife");
  1130. }
  1131. } elseif ($message->getUserTeam() == "TERRORIST") {
  1132. $team = ($this->side['team_a'] == "t") ? $this->teamAName : $this->teamBName;
  1133.  
  1134. if (!$this->restart['t']) {
  1135. $this->restart['t'] = true;
  1136. $this->say($team . " (T) \003want to restart the knife");
  1137. }
  1138. }
  1139.  
  1140. if ($this->restart["ct"] && $this->restart["t"]) {
  1141. $this->ready["ct"] = true;
  1142. $this->ready["t"] = true;
  1143.  
  1144. $this->setStatus(self::STATUS_WU_KNIFE);
  1145. $this->currentMap->setStatus(Map::STATUS_WU_KNIFE);
  1146.  
  1147. $this->restart["ct"] = false;
  1148. $this->restart["ct"] = false;
  1149.  
  1150. $this->addMatchLog("Restarting knife");
  1151. $this->addLog("Restarting knife");
  1152. $this->startMatch();
  1153. }
  1154. }
  1155. } elseif (($text == "!stop" || $text == ".stop") && !\eBot\Config\Config::getInstance()->getConfigStopDisabled()) {
  1156. if ($this->isMatchRound() && $this->enable) {
  1157. $this->addLog($message->getUserName() . " (" . $message->getUserTeam() . ") say stop");
  1158.  
  1159. if ($message->getUserTeam() == "CT") {
  1160. $team = ($this->side['team_a'] == "ct") ? $this->teamAName : $this->teamBName;
  1161.  
  1162. if (!$this->stop['ct']) {
  1163. $this->stop['ct'] = true;
  1164. $this->say($team . " (CT) \003want to stop");
  1165. }
  1166. } elseif ($message->getUserTeam() == "TERRORIST") {
  1167. $team = ($this->side['team_a'] == "t") ? $this->teamAName : $this->teamBName;
  1168.  
  1169. if (!$this->stop['t']) {
  1170. $this->stop['t'] = true;
  1171. $this->say($team . " (T) \003want to stop");
  1172. }
  1173. }
  1174.  
  1175. $this->stopMatch();
  1176. } else {
  1177. if (!$this->enable) {
  1178. $this->addLog("Can't stop, it's already stop");
  1179. }
  1180. }
  1181. } elseif ($text == "!continue" || $text == ".continue") {
  1182. if ($this->isMatchRound() && !$this->enable) {
  1183. if ($message->getUserTeam() == "CT") {
  1184. $team = ($this->side['team_a'] == "ct") ? $this->teamAName : $this->teamBName;
  1185.  
  1186. if (!$this->continue['ct']) {
  1187. $this->continue['ct'] = true;
  1188. $this->say($team . " (CT) \003want to go live");
  1189. }
  1190. } elseif ($message->getUserTeam() == "TERRORIST") {
  1191. $team = ($this->side['team_a'] == "t") ? $this->teamAName : $this->teamBName;
  1192.  
  1193. if (!$this->continue['t']) {
  1194. $this->continue['t'] = true;
  1195. $this->say($team . " (T) \003want to go live");
  1196. }
  1197. }
  1198.  
  1199. $this->continueMatch();
  1200. }
  1201. } elseif ($text == "!ready" || $text == ".ready") {
  1202. if ($this->isWarmupRound() && $this->mapIsEngaged) {
  1203. if ($this->config_streamer && !$this->getStreamerReady()) {
  1204. $this->say("\002Streamers are not ready yet. \001Please wait, till they are ready.");
  1205. } else {
  1206. $this->addLog($message->getUserName() . " (" . $message->getUserTeam() . ") say ready");
  1207.  
  1208. if ($message->getUserTeam() == "CT") {
  1209. if (($this->getStatus() == self::STATUS_WU_2_SIDE) || ($this->getStatus() == self::STATUS_WU_OT_2_SIDE)) {
  1210. $team = ($this->side['team_a'] == "ct") ? $this->teamBName : $this->teamAName;
  1211. } else {
  1212. $team = ($this->side['team_a'] == "ct") ? $this->teamAName : $this->teamBName;
  1213. }
  1214.  
  1215. if (!$this->ready['ct']) {
  1216. $this->ready['ct'] = true;
  1217. $this->say($team . " (CT) \003is now \004ready");
  1218. } else {
  1219. $this->say($team . " (CT) \003is already \004ready");
  1220. }
  1221. } elseif ($message->getUserTeam() == "TERRORIST") {
  1222. if (($this->getStatus() == self::STATUS_WU_2_SIDE) || ($this->getStatus() == self::STATUS_WU_OT_2_SIDE)) {
  1223. $team = ($this->side['team_a'] == "t") ? $this->teamBName : $this->teamAName;
  1224. } else {
  1225. $team = ($this->side['team_a'] == "t") ? $this->teamAName : $this->teamBName;
  1226. }
  1227.  
  1228.  
  1229. if (!$this->ready['t']) {
  1230. $this->ready['t'] = true;
  1231. $this->say($team . " (T) \003is now \004ready");
  1232. } else {
  1233. $this->say($team . " (T) \003is already \004ready");
  1234. }
  1235. }
  1236.  
  1237. $this->startMatch();
  1238. }
  1239. }
  1240. } elseif ($text == "!pause" || $text == ".pause") {
  1241. if ($this->isMatchRound() && !$this->isPaused && $this->enable) {
  1242. $this->addLog($message->getUserName() . " (" . $message->getUserTeam() . ") say pause");
  1243.  
  1244. if ($message->getUserTeam() == "CT") {
  1245. $team = ($this->side['team_a'] == "ct") ? $this->teamAName : $this->teamBName;
  1246.  
  1247. if (!$this->pause['ct']) {
  1248. $this->pause['ct'] = true;
  1249. if (\eBot\Config\Config::getInstance()->getPauseMethod() == "instantConfirm")
  1250. $this->say($team . " (CT) \003want to pause, write !pause to confirm");
  1251. elseif (\eBot\Config\Config::getInstance()->getPauseMethod() == "instantNoConfirm")
  1252. $this->say($team . " (CT) \003 will be paused now!");
  1253. else
  1254. $this->say($team . " (CT) \003want to pause, match will be paused next freezetime.");
  1255. }
  1256. } elseif ($message->getUserTeam() == "TERRORIST") {
  1257. $team = ($this->side['team_a'] == "t") ? $this->teamAName : $this->teamBName;
  1258.  
  1259. if (!$this->pause['t']) {
  1260. $this->pause['t'] = true;
  1261. if (\eBot\Config\Config::getInstance()->getPauseMethod() == "instantConfirm")
  1262. $this->say($team . " (T) \003want to pause, write !pause to confirm");
  1263. elseif (\eBot\Config\Config::getInstance()->getPauseMethod() == "instantNoConfirm")
  1264. $this->say($team . " (T) \003 will be paused now!");
  1265. else
  1266. $this->say($team . " (T) \003want to pause, match will be paused next freezetime.");
  1267. }
  1268. }
  1269. $this->pauseMatch();
  1270. }
  1271. } elseif ($text == "!unpause" || $text == ".unpause") {
  1272. if ($this->isMatchRound() && $this->isPaused && $this->enable) {
  1273. $this->addLog($message->getUserName() . " (" . $message->getUserTeam() . ") say pause");
  1274.  
  1275. if ($message->getUserTeam() == "CT") {
  1276. $team = ($this->side['team_a'] == "ct") ? $this->teamAName : $this->teamBName;
  1277.  
  1278. if (!$this->unpause['ct']) {
  1279. $this->unpause['ct'] = true;
  1280. $this->say($team . " (CT) \003want to remove pause, write !unpause to confirm");
  1281. }
  1282. } elseif ($message->getUserTeam() == "TERRORIST") {
  1283. $team = ($this->side['team_a'] == "t") ? $this->teamAName : $this->teamBName;
  1284.  
  1285. if (!$this->unpause['t']) {
  1286. $this->unpause['t'] = true;
  1287. $this->say($team . " (T) \003want to remove pause, write !unpause to confirm");
  1288. }
  1289. }
  1290.  
  1291. $this->unpauseMatch();
  1292. }
  1293. } elseif (($this->getStatus() == self::STATUS_END_KNIFE) && ($text == "!stay" || $text == ".stay")) {
  1294. if ($message->getUserTeam() == $this->winKnife) {
  1295. $this->addLog($message->getUserName() . " want to stay, going to warmup");
  1296.  
  1297. $this->setStatus(self::STATUS_WU_1_SIDE, true);
  1298. $this->currentMap->setStatus(Map::STATUS_WU_1_SIDE, true);
  1299.  
  1300. $this->rcon->send("mp_do_warmup_period 1");
  1301. $this->rcon->send("mp_warmuptime 30");
  1302. $this->rcon->send("mp_warmup_pausetimer 1");
  1303. $this->rcon->send("mp_warmup_start");
  1304. $this->say("nothing change, going to warmup");
  1305. }
  1306. } elseif (($this->getStatus() == self::STATUS_END_KNIFE) && ($text == "!switch" || $text == ".switch" || $text == "!swap" || $text == ".swap")) {
  1307. if ($message->getUserTeam() == $this->winKnife) {
  1308. $this->addLog($message->getUserName() . " want to stay, going to warmup");
  1309.  
  1310. $this->setStatus(self::STATUS_WU_1_SIDE, true);
  1311. $this->currentMap->setStatus(Map::STATUS_WU_1_SIDE, true);
  1312.  
  1313. $this->swapSides();
  1314.  
  1315. $this->rcon->send("mp_do_warmup_period 1");
  1316. $this->rcon->send("mp_warmuptime 30");
  1317. $this->rcon->send("mp_warmup_pausetimer 1");
  1318. $this->rcon->send("mp_warmup_start");
  1319. $this->say("swaping teams");
  1320. $this->rcon->send("mp_swapteams");
  1321. $this->sendTeamNames();
  1322. }
  1323. } elseif ($text == "!notready" || $text == ".notready" || $text == "!unready" || $text == ".unready") {
  1324. if ($this->isWarmupRound() && $this->mapIsEngaged) {
  1325. $this->addLog($message->getUserName() . " (" . $message->getUserTeam() . ") say notready");
  1326.  
  1327. if ($message->getUserTeam() == "CT") {
  1328. $team = ($this->side['team_a'] == "ct") ? $this->teamAName : $this->teamBName;
  1329.  
  1330. if ($this->ready['ct']) {
  1331. $this->ready['ct'] = false;
  1332. $this->say($team . " (CT) \003is now \004not ready");
  1333. } else {
  1334. $this->say($team . " (CT) \003is already \004not ready");
  1335. }
  1336. } elseif ($message->getUserTeam() == "TERRORIST") {
  1337. $team = ($this->side['team_a'] == "t") ? $this->teamAName : $this->teamBName;
  1338.  
  1339. if ($this->ready['t']) {
  1340. $this->ready['t'] = false;
  1341. $this->say($team . " (T) \003is now \004not ready");
  1342. } else {
  1343. $this->say($team . " (T) \003is already \004not ready");
  1344. }
  1345. }
  1346. }
  1347. } elseif ($text == "!status") {
  1348. if ($this->pluginCsay) {
  1349. $this->addLog($message->getUserName() . " ask status");
  1350. if ($this->enable) {
  1351. $this->rcon->send("csay_to_player " . $message->userId . " \"e\004Bot\001: Current status: \002" . $this->getStatusText() . "\"");
  1352. } else {
  1353. $this->rcon->send("csay_to_player " . $message->userId . " \"e\004Bot\001: Current status: \002" . $this->getStatusText() . " - Match paused\"");
  1354. }
  1355. }
  1356. } elseif ($text == "!score") {
  1357. if ($this->pluginCsay) {
  1358. $this->addLog($message->getUserName() . " ask status");
  1359. $this->rcon->send("csay_to_player " . $message->userId . " \"e\004Bot\001: \005" . $this->teamAName . " \004" . $this->currentMap->getScore1() . " \001- \004" . $this->currentMap->getScore2() . " \005" . $this->teamBName . "\"");
  1360. }
  1361. } else {
  1362. // Dispatching events
  1363. $event = new \eBot\Events\Event\Say();
  1364. $event->setMatch($this);
  1365. $event->setUserId($message->getUserId());
  1366. $event->setUserName($message->getUserName());
  1367. $event->setUserTeam($message->getUserTeam());
  1368. $event->setUserSteamid($message->getUserSteamid());
  1369. $event->setType($message->getType());
  1370. $event->setText($message->getText());
  1371. \eBot\Events\EventDispatcher::getInstance()->dispatchEvent($event);
  1372. }
  1373.  
  1374. switch ($message->getType()) {
  1375. case \eBot\Message\Type\Say::SAY:
  1376. $this->addMatchLog($this->getColoredUserNameHTML($message->getUserName(), $message->getUserTeam()) . ": " . htmlentities($message->getText()));
  1377. break;
  1378. case \eBot\Message\Type\Say::SAY_TEAM:
  1379. $this->addMatchLog($this->getColoredUserNameHTML($message->getUserName(), $message->getUserTeam()) . " (private): " . htmlentities($message->getText()), true);
  1380. break;
  1381. }
  1382. }
  1383.  
  1384. private function processRoundScored(\eBot\Message\Type\RoundScored $message) {
  1385. $this->addLog("RoundScore : " . $message->getTeamWin());
  1386.  
  1387. if ($this->getStatus() == self::STATUS_KNIFE) {
  1388. $this->winKnife = ($message->getTeamWin() == "T") ? "TERRORIST" : $message->getTeamWin();
  1389. $this->addLog($message->getTeamWin() . " won the knife round");
  1390.  
  1391. $this->setStatus(self::STATUS_END_KNIFE, true);
  1392. $this->currentMap->setStatus(Map::STATUS_END_KNIFE, true);
  1393.  
  1394. $team = ($this->side['team_a'] == \strtolower($message->getTeamWin())) ? $this->teamAName : $this->teamBName;
  1395.  
  1396. $this->say("\005$team won the knife, !stay or !switch");
  1397.  
  1398. return;
  1399. }
  1400.  
  1401. if (!$this->waitForRestart && $this->enable && in_array($this->getStatus(), array(self::STATUS_FIRST_SIDE, self::STATUS_SECOND_SIDE, self::STATUS_OT_FIRST_SIDE, self::STATUS_OT_SECOND_SIDE))) {
  1402. // Add point
  1403. foreach ($this->players as $player)
  1404. $player->saveKillRound();
  1405.  
  1406. $teamWin = $this->currentMap->addRound($message->getTeamWin());
  1407.  
  1408. $bestActionType = "";
  1409. $bestActionParam = array();
  1410.  
  1411. if ($message->type != "saved") {
  1412. if ($this->specialSituation['active']) {
  1413. $nbAlive = 0;
  1414. foreach ($this->players as $k => $v) {
  1415. if ($v->get("alive") && ($v->get("currentSide") != "other")) {
  1416. $nbAlive++;
  1417. }
  1418. }
  1419.  
  1420. $team = strtolower($message->team_win);
  1421.  
  1422. if ($nbAlive == 1) {
  1423. if (($this->specialSituation['side'] == strtolower($team)) || ($this->specialSituation['side'] == "both") || ($this->specialSituation['side2'] == "both")) {
  1424.  
  1425. if ($this->specialSituation['side2'] == "both") {
  1426. if ($this->specialSituation['side'] != "both") {
  1427. $nbAlive = 0;
  1428. foreach ($this->players as $k => $v) {
  1429. if ($v->get("alive") && ($v->get("currentSide") != "other")) {
  1430. $nbAlive++;
  1431. $id = $k;
  1432. }
  1433. }
  1434.  
  1435. if ($this->specialSituation['id'] != $id) {
  1436. $this->addLog("situationSpecialchecker2 found another player");
  1437. $this->specialSituation['side'] = "both";
  1438. $this->specialSituation['situation'] = 1;
  1439. }
  1440. }
  1441. }
  1442.  
  1443.  
  1444. if ($this->specialSituation['side'] == "both") {
  1445. $id = 0;
  1446. $nbAlive = 0;
  1447. foreach ($this->players as $k => $v) {
  1448. if ($v->get("alive") && ($v->get("currentSide") != "other")) {
  1449. $nbAlive++;
  1450. $id = $k;
  1451. }
  1452. }
  1453.  
  1454. $this->specialSituation['id'] = $id;
  1455.  
  1456. if ($nbAlive == 2) {
  1457. $this->addLog("Incohérence situation spéciale");
  1458. } else {
  1459. if ($this->players[$id]) {
  1460. $bestActionType = "1v1";
  1461. $bestActionParam = array("player" => $this->players[$id]->getId(), "playerName" => $this->players[$id]->get("name"));
  1462. mysql_query("UPDATE players SET nb1 = nb1 + 1 WHERE id = '" . $this->players[$id]->getId() . "'") or Logger::error("Can't update " . $this->players[$id]->getId() . " situation");
  1463. $this->addLog("Situation spécial réussie 1v" . $this->specialSituation['situation'] . " (" . $this->players[$id]->get("name") . ")");
  1464. $this->addMatchLog("<b>" . htmlentities($this->players[$id]->get("name")) . "</b> a mis un 1v" . $this->specialSituation['situation'] . " !");
  1465. $this->players[$id]->inc("v1");
  1466.  
  1467. $text = \addslashes(\serialize(array("situation" => 1, "player" => $this->players[$id]->getId(), "playerName" => $this->players[$id]->get("name"))));
  1468.  
  1469. // Round TimeLine
  1470. \mysql_query("
  1471. INSERT INTO `round`
  1472. (`match_id`,`map_id`,`event_name`,`event_text`,`event_time`,`round_id`,`created_at`,`updated_at`)
  1473. VALUES
  1474. ('" . $this->match_id . "', '" . $this->currentMap->getMapId() . "', '1vx_ok', '$text','" . $this->getRoundTime() . "', '" . $this->getNbRound() . "', NOW(), NOW())
  1475. ");
  1476. }
  1477. }
  1478. } else {
  1479. $id = $this->specialSituation['id'];
  1480. if ($this->players[$id]) {
  1481. $bestActionType = "1v" . $this->specialSituation['situation'];
  1482. $bestActionParam = array("player" => $this->players[$id]->getId(), "playerName" => $this->players[$id]->get("name"));
  1483.  
  1484. $this->addMatchLog("<b>" . htmlentities($this->players[$id]->get("name")) . "</b> a mis un 1v" . $this->specialSituation['situation'] . " !");
  1485. mysql_query("UPDATE players SET nb" . $this->specialSituation['situation'] . " = nb" . $this->specialSituation['situation'] . " + 1 WHERE id='" . $this->players[$id]->getId() . "'") or Logger::error("Can't update " . $this->players[$id]->getId() . " situation");
  1486. $this->players[$id]->inc("v" . $this->specialSituation['situation']);
  1487. $this->addLog("Situation spécial réussie 1v" . $this->specialSituation['situation'] . " (" . $this->players[$id]->get("name") . ")");
  1488.  
  1489. $text = \addslashes(\serialize(array("situation" => $this->specialSituation['situation'], "player" => $this->players[$id]->getId(), "playerName" => $this->players[$id]->get("name"))));
  1490.  
  1491. // Round TimeLine
  1492. \mysql_query("
  1493. INSERT INTO `round`
  1494. (`match_id`,`map_id`,`event_name`,`event_text`,`event_time`,`round_id`,`created_at`,`updated_at`)
  1495. VALUES
  1496. ('" . $this->match_id . "', '" . $this->currentMap->getMapId() . "', '1vx_ok', '$text','" . $this->getRoundTime() . "', '" . $this->getNbRound() . "', NOW(), NOW())
  1497. ");
  1498. }
  1499. }
  1500. }
  1501. } else {
  1502. $this->addLog("Situation ratée - alive players: $nbAlive");
  1503. }
  1504. }
  1505. }
  1506.  
  1507. if ($message->type == "bombdefused") {
  1508. if ($this->gameBombDefuser != null) {
  1509. $this->gameBombDefuser->inc("defuse");
  1510. $this->gameBombDefuser->inc("point", 3);
  1511. $this->gameBombDefuser->saveScore();
  1512.  
  1513. // Round TimeLine
  1514. \mysql_query("
  1515. INSERT INTO `round`
  1516. (`match_id`,`map_id`,`event_name`,`event_time`,`round_id`,`created_at`,`updated_at`)
  1517. VALUES
  1518. ('" . $this->match_id . "', '" . $this->currentMap->getMapId() . "', 'bomb_defused', '" . $this->getRoundTime() . "', '" . $this->getNbRound() . "', NOW(), NOW())
  1519. ");
  1520. }
  1521. }
  1522.  
  1523. if ($message->type == "bombeexploded") {
  1524. if ($this->gameBombPlanter != null) {
  1525. $this->gameBombPlanter->inc("bombe");
  1526. $this->gameBombPlanter->inc("point", 2);
  1527. $this->gameBombPlanter->saveScore();
  1528.  
  1529. // Round TimeLine
  1530. \mysql_query("
  1531. INSERT INTO `round`
  1532. (`match_id`,`map_id`,`event_name`,`event_time`,`round_id`,`created_at`,`updated_at`)
  1533. VALUES
  1534. ('" . $this->match_id . "', '" . $this->currentMap->getMapId() . "', 'bomb_exploded', '" . $this->getRoundTime() . "', '" . $this->getNbRound() . "', NOW(), NOW())
  1535. ");
  1536. }
  1537. }
  1538.  
  1539. // Round TimeLine
  1540. \mysql_query("
  1541. INSERT INTO `round`
  1542. (`match_id`,`map_id`,`event_name`,`event_time`,`round_id`,`created_at`,`updated_at`)
  1543. VALUES
  1544. ('" . $this->match_id . "', '" . $this->currentMap->getMapId() . "', 'round_end', '" . $this->getRoundTime() . "', '" . $this->getNbRound() . "', NOW(), NOW())
  1545. ");
  1546.  
  1547. $this->score["team_a"] = $this->currentMap->getScore1();
  1548. $this->score["team_b"] = $this->currentMap->getScore2();
  1549.  
  1550. if ($this->getNbRound() == $this->maxRound - 1) {
  1551. // Ensure that halftime_pausetimer is set
  1552. $this->rcon->send("mp_halftime_pausetimer 1");
  1553. }
  1554.  
  1555. $this->say("\005" . $this->teamAName . " \004" . $this->currentMap->getScore1() . " \001- \004" . $this->currentMap->getScore2() . " \005" . $this->teamBName);
  1556.  
  1557. $this->addLog($this->teamAName . " (" . $this->currentMap->getScore1() . ") - (" . $this->currentMap->getScore2() . ") " . $this->teamBName);
  1558. $this->addMatchLog("Un round a été marqué - " . $this->teamAName . " (" . $this->currentMap->getScore1() . ") - (" . $this->currentMap->getScore2() . ") " . $this->teamBName);
  1559.  
  1560. @mysql_query("UPDATE `matchs` SET score_a = '" . $this->score["team_a"] . "', score_b ='" . $this->score["team_b"] . "' WHERE id='" . $this->match_id . "'") or $this->addLog("Can't match " . $this->match_id . " scores", Logger::ERROR);
  1561.  
  1562. // ROUND SUMMARY
  1563. $nb = 0;
  1564. $playerBest = null;
  1565. foreach ($this->players as $player) {
  1566. if ($player->killRound > $nb) {
  1567. $playerBest = $player;
  1568. $nb = $player->killRound;
  1569. } elseif ($player->killRound == $nb) {
  1570. $tmp = ($player->currentSide == "ct") ? "CT" : "TERRORIST";
  1571. if ($tmp == $teamWin) {
  1572. $playerBest = $player;
  1573. }
  1574. }
  1575. }
  1576.  
  1577. if ($playerBest != null) {
  1578. $playerId = $playerBest->getId();
  1579. $playerFirstKill = (int) $playerBest->gotFirstKill;
  1580. } else {
  1581. $playerId = "NULL";
  1582. $playerFirstKill = "NULL";
  1583. }
  1584.  
  1585. $data = $this->rcon->send("mp_backup_round_file_last");
  1586. if (preg_match('!"mp_backup_round_file_last" = "(?<backup>[a-zA-Z0-9\-_\.]+)"!', $data, $match)) {
  1587. $backupFile = "'" . $match["backup"] . "'";
  1588. } else {
  1589. $backupFile = 'NULL';
  1590. }
  1591.  
  1592. if ($bestActionType == "") {
  1593. if ($playerBest != null) {
  1594. $bestActionType = $nb . "kill";
  1595. $bestActionParam = array("player" => $playerBest->getId(), "playerName" => $playerBest->get("name"));
  1596. } else {
  1597. $bestActionType = null;
  1598. $bestActionParam = null;
  1599. }
  1600. }
  1601.  
  1602. mysql_query("INSERT INTO round_summary
  1603. (`match_id`,`map_id`,`score_a`,`score_b`,`bomb_planted`,`bomb_defused`,`bomb_exploded`,`ct_win`, `t_win`,`round_id`,`win_type`,`team_win`,`best_killer`,`best_killer_fk`,`best_killer_nb`,`best_action_type`,`best_action_param`, `backup_file_name`,`created_at`,`updated_at`)
  1604. VALUES
  1605. ('" . $this->match_id . "', '" . $this->currentMap->getMapId() . "', '" . $this->score["team_a"] . "', '" . $this->score["team_b"] . "',
  1606. '" . ($this->gameBombPlanter != null) . "',
  1607. '" . ($message->type == "bombdefused") . "',
  1608. '" . ($message->type == "bombeexploded") . "',
  1609. '" . ($message->getTeamWin() == "CT") . "',
  1610. '" . ($message->getTeamWin() != "CT") . "',
  1611. '" . ($this->getNbRound() - 1) . "',
  1612. '" . $message->type . "','" . $teamWin . "',
  1613. $playerId, " . $playerFirstKill . ", $nb, " . (($bestActionType != null) ? "'$bestActionType'" : "NULL") . ", " . (($bestActionParam != null) ? "'" . addslashes(serialize($bestActionParam)) . "'" : "NULL") . ",
  1614. " . $backupFile . ",
  1615. NOW(),
  1616. NOW()
  1617. )") or $this->addLog("Can't insert round summary match " . $this->match_id . " - " . mysql_error(), Logger::ERROR);
  1618. // END ROUND SUMMARY
  1619. // Prevent the OverTime bug
  1620. if ($this->config_ot) {
  1621. if ($this->score['team_a'] + $this->score['team_b'] == ($this->maxRound * 2) - 1) {
  1622. $this->rcon->send("mp_overtime_enable 1");
  1623. $this->rcon->send("mp_overtime_maxrounds " . ($this->ot_maxround * 2));
  1624. $this->rcon->send("mp_overtime_startmoney " . $this->ot_startmoney);
  1625. $this->rcon->send("mp_overtime_halftime_pausetimer 1");
  1626. }
  1627. }
  1628.  
  1629. foreach ($this->players as &$player) {
  1630. $player->snapshot($this->getNbRound() - 1);
  1631. }
  1632.  
  1633. $this->resetSpecialSituation();
  1634. if ($this->getStatus() == self::STATUS_FIRST_SIDE) {
  1635. if ($this->score["team_a"] + $this->score["team_b"] == $this->maxRound) {
  1636. $this->swapSides();
  1637. $this->setStatus(self::STATUS_WU_2_SIDE, true);
  1638. $this->currentMap->setStatus(Map::STATUS_WU_2_SIDE, true);
  1639. $this->saveScore();
  1640.  
  1641. $this->rcon->send("mp_halftime_pausetimer 1");
  1642. }
  1643. } elseif ($this->getStatus() == self::STATUS_SECOND_SIDE) {
  1644. if (($this->score["team_a"] + $this->score["team_b"] == $this->maxRound * 2) || ($this->score["team_a"] > $this->maxRound && !$this->config_full_score) || ($this->score["team_b"] > $this->maxRound && !$this->config_full_score)) {
  1645.  
  1646. if (($this->score["team_a"] == $this->score["team_b"]) && ($this->config_ot)) {
  1647. $this->setStatus(self::STATUS_WU_OT_1_SIDE, true);
  1648. $this->currentMap->setStatus(Map::STATUS_WU_OT_1_SIDE, true);
  1649. $this->maxRound = $this->ot_maxround;
  1650. $this->currentMap->addOvertime();
  1651. $this->nbOT++;
  1652. $this->addLog("Going to overtime");
  1653. $this->say("Going to overtime");
  1654. $this->currentMap->setNbMaxRound($this->ot_maxround);
  1655. //$this->rcon->send("mp_do_warmup_period 1; mp_warmuptime 30; mp_warmup_pausetimer 1");
  1656. //$this->rcon->send("mp_restartgame 1");
  1657. //$this->sendTeamNames();
  1658. } else {
  1659. $this->currentMap->setStatus(Map::STATUS_MAP_ENDED, true);
  1660.  
  1661. $this->lookEndingMatch();
  1662. }
  1663.  
  1664. $this->saveScore();
  1665. }
  1666. } elseif ($this->getStatus() == self::STATUS_OT_FIRST_SIDE) {
  1667. $scoreToReach = $this->oldMaxround * 2 + $this->ot_maxround + ($this->ot_maxround * 2 * ($this->nbOT - 1));
  1668.  
  1669. if ($this->score["team_a"] + $this->score["team_b"] == $scoreToReach) {
  1670. $this->setStatus(self::STATUS_WU_OT_2_SIDE, true);
  1671. $this->currentMap->setStatus(Map::STATUS_WU_OT_2_SIDE, true);
  1672. $this->saveScore();
  1673. $this->swapSides();
  1674. $this->sendTeamNames();
  1675.  
  1676. // Not needed anymore with last updates
  1677. // $this->rcon->send("mp_restartgame 1");
  1678.  
  1679. $this->rcon->send("mp_halftime_pausetimer 1");
  1680. }
  1681. } elseif ($this->getStatus() == self::STATUS_OT_SECOND_SIDE) {
  1682. $scoreToReach = $this->oldMaxround * 2 + $this->ot_maxround * 2 + ($this->ot_maxround * 2 * ($this->nbOT - 1));
  1683. $scoreToReach2 = $this->oldMaxround + $this->ot_maxround + ($this->ot_maxround * ($this->nbOT - 1));
  1684.  
  1685. if (($this->score["team_a"] + $this->score["team_b"] == $scoreToReach) || ($this->score["team_a"] > $scoreToReach2) || ($this->score["team_b"] > $scoreToReach2)) {
  1686.  
  1687. if ($this->score["team_a"] == $this->score["team_b"]) {
  1688. $this->setStatus(self::STATUS_WU_OT_1_SIDE, true);
  1689. $this->currentMap->setStatus(Map::STATUS_WU_OT_1_SIDE, true);
  1690. $this->maxRound = $this->ot_maxround;
  1691. $this->currentMap->addOvertime();
  1692. $this->currentMap->setNbMaxRound($this->ot_maxround);
  1693. $this->nbOT++;
  1694. $this->addLog("Going to overtime");
  1695. //$this->rcon->send("mp_do_warmup_period 1; mp_warmuptime 30; mp_warmup_pausetimer 1");
  1696. //$this->rcon->send("mp_restartgame 1");
  1697. } else {
  1698. $this->currentMap->setStatus(Map::STATUS_MAP_ENDED, true);
  1699.  
  1700. $this->lookEndingMatch();
  1701. }
  1702. $this->saveScore();
  1703. }
  1704. }
  1705.  
  1706. // Dispatching to Websocket
  1707.  
  1708. $this->websocket['match']->sendData(json_encode(array('message' => 'status', 'content' => $this->getStatusText(), 'id' => $this->match_id)));
  1709. $this->websocket['match']->sendData(json_encode(array('message' => 'button', 'content' => $this->getStatus(), 'id' => $this->match_id)));
  1710. $this->websocket['match']->sendData(json_encode(array('message' => 'score', 'scoreA' => $this->score['team_a'], 'scoreB' => $this->score['team_b'], 'id' => $this->match_id)));
  1711.  
  1712. // Dispatching events
  1713. $event = new \eBot\Events\Event\RoundScored();
  1714. $event->setMatch($this);
  1715. $event->setTeamA($this->teamAName);
  1716. $event->setTeamB($this->teamAName);
  1717. $event->setScoreA($this->score["team_a"]);
  1718. $event->setScoreB($this->score["team_b"]);
  1719. $event->setStatus($this->getStatus());
  1720. \eBot\Events\EventDispatcher::getInstance()->dispatchEvent($event);
  1721. }
  1722. $this->roundEndEvent = true;
  1723. }
  1724.  
  1725. private $needDelTask = false;
  1726. private $currentRecordName = false;
  1727.  
  1728. private function lookEndingMatch() {
  1729.  
  1730. /**
  1731. * TV PUSH
  1732. */
  1733. TaskManager::getInstance()->addTask(new Task($this, self::STOP_RECORD, microtime(true) + 2));
  1734. $record_name = $this->currentMap->getTvRecordFile();
  1735. if ($record_name != "") {
  1736. $this->currentRecordName = $record_name;
  1737. }
  1738.  
  1739. if ($this->matchData['map_selection_mode'] == "normal") {
  1740. $allFinish = true;
  1741. } else {
  1742. $team1win = 0;
  1743. $team2win = 0;
  1744.  
  1745. $countPlayed = 0;
  1746. foreach ($this->maps as $map) {
  1747. if ($map->getStatus() == Map::STATUS_MAP_ENDED) {
  1748. $countPlayed++;
  1749. if ($map->getScore1() > $map->getScore2())
  1750. $team1win++;
  1751. else
  1752. $team2win++;
  1753. }
  1754. }
  1755.  
  1756. $this->addLog("Score end: $team1win - $team2win");
  1757. $this->addLog("Number of map to win: ".ceil(count($this->maps) / 2));
  1758.  
  1759. if ($countPlayed == count($this->maps)) {
  1760. $allFinish = true;
  1761. } elseif ($this->matchData['map_selection_mode'] == "bo2") {
  1762. if ($team1win > $team2win)
  1763. $allFinish = true;
  1764. else
  1765. $allFinish = false;
  1766. } else {
  1767. if (($team1win > $team2win && $team1win >= ceil(count($this->maps) / 2)) || ($team1win < $team2win && $team2win >= ceil(count($this->maps) / 2)))
  1768. $allFinish = true;
  1769. else
  1770. $allFinish = false;
  1771. }
  1772. }
  1773.  
  1774. if (count($this->maps) == 1 || $allFinish) {
  1775. $this->needDelTask = true;
  1776. $this->setStatus(self::STATUS_END_MATCH, true);
  1777.  
  1778. $this->addLog("Match is closed");
  1779. if ($this->score["team_a"] > $this->score["team_b"]) {
  1780. $this->say($this->teamAName . " win ! Final score: " . $this->score["team_a"] . "/" . $this->score["team_b"]);
  1781. $this->addMatchLog($this->teamAName . " win ! Final score: " . $this->score["team_a"] . "/" . $this->score["team_b"]);
  1782. } elseif ($this->score["team_a"] < $this->score["team_b"]) {
  1783. $this->say($this->teamBName . " win ! Final score: " . $this->score["team_b"] . "/" . $this->score["team_a"]);
  1784. $this->addMatchLog($this->teamBName . " win ! Final score: " . $this->score["team_b"] . "/" . $this->score["team_a"]);
  1785. } else {
  1786. $this->say("Final score: " . $this->score["team_a"] . " - " . $this->score["team_b"] . " - Draw !");
  1787. $this->addMatchLog("Final score: " . $this->score["team_a"] . " - " . $this->score["team_b"] . " - Draw !");
  1788. }
  1789. $this->rcon->send("mp_teamname_1 \"\"; mp_teamflag_1 \"\";");
  1790. $this->rcon->send("mp_teamname_2 \"\"; mp_teamflag_2 \"\";");
  1791.  
  1792. $this->websocket['match']->sendData(json_encode(array('message' => 'status', 'content' => $this->getStatusText(), 'id' => $this->match_id)));
  1793.  
  1794. $event = new \eBot\Events\Event\MatchEnd();
  1795. $event->setMatch($this);
  1796. $event->setScore1($this->score["team_a"]);
  1797. $event->setScore2($this->score["team_a"]);
  1798. \eBot\Events\EventDispatcher::getInstance()->dispatchEvent($event);
  1799. } else {
  1800. $backupMap = $this->currentMap;
  1801. $this->currentMap = null;
  1802.  
  1803. // bo2, bo3_modea, bo3_modeb, normal
  1804. if ($this->matchData['map_selection_mode'] == "bo2") {
  1805. if (count($this->maps) == 2) {
  1806. $this->addLog("Best Of Two matches - Engaging next map");
  1807. foreach ($this->maps as $map) {
  1808. if ($map->getStatus() == Map::STATUS_NOT_STARTED) {
  1809. $this->addLog("Engaging " . $map->getMapName());
  1810. $this->currentMap = $map;
  1811. break;
  1812. }
  1813. }
  1814. }
  1815. } elseif ($this->matchData['map_selection_mode'] == "bo3_modea") {
  1816. if ($backupMap->getMapsFor() == "default") {
  1817. if ($this->score["team_a"] > $this->score["team_b"]) {
  1818. $mapFor = "team2";
  1819. } else {
  1820. $mapFor = "team1";
  1821. }
  1822.  
  1823. foreach ($this->maps as $map) {
  1824. if ($map->getMapsFor() == $mapFor) {
  1825. if ($map->getStatus() == Map::STATUS_NOT_STARTED) {
  1826. $this->currentMap = $map;
  1827. break;
  1828. }
  1829. }
  1830. }
  1831. } else {
  1832. foreach ($this->maps as $map) {
  1833. if ($map->getStatus() == Map::STATUS_NOT_STARTED) {
  1834. $this->currentMap = $map;
  1835. break;
  1836. }
  1837. }
  1838. }
  1839. } elseif ($this->matchData['map_selection_mode'] == "bo3_modeb") {
  1840. if ($backupMap->getMapsFor() == "team1") {
  1841. $mapFor = "team2";
  1842. } elseif ($backupMap->getMapsFor() == "team2") {
  1843. $mapFor = "default";
  1844. }
  1845.  
  1846. foreach ($this->maps as $map) {
  1847. if ($map->getMapsFor() == $mapFor) {
  1848. if ($map->getStatus() == Map::STATUS_NOT_STARTED) {
  1849. $this->currentMap = $map;
  1850. break;
  1851. }
  1852. }
  1853. }
  1854. } else {
  1855. foreach ($this->maps as $map) {
  1856. if ($map->getStatus() == Map::STATUS_NOT_STARTED) {
  1857. $this->currentMap = $map;
  1858. break;
  1859. }
  1860. }
  1861. }
  1862.  
  1863. if ($this->currentMap != null) {
  1864. $this->currentMap->setStatus(Map::STATUS_STARTING, true);
  1865. $this->setStatus(self::STATUS_STARTING, true);
  1866. \mysql_query("UPDATE `matchs` SET `current_map` = '" . $this->currentMap->getMapId() . "' WHERE `id` = '" . $this->match_id . "'");
  1867.  
  1868. Logger::debug("Setting need knife round on map");
  1869. $this->currentMap->setNeedKnifeRound(true);
  1870. $this->nbOT = 0;
  1871. $this->score["team_a"] = 0;
  1872. $this->score["team_b"] = 0;
  1873. $currentSide = $this->currentMap->getCurrentSide();
  1874. if ($currentSide == 'ct') {
  1875. $this->side['team_a'] = "ct";
  1876. $this->side['team_b'] = "t";
  1877. } else {
  1878. $this->side['team_a'] = "t";
  1879. $this->side['team_b'] = "ct";
  1880. }
  1881.  
  1882. $this->addLog("Engaging next map " . $this->currentMap->getMapName());
  1883. $this->addMatchLog("Engaging next map " . $this->currentMap->getMapName());
  1884. $time = microtime(true) + \eBot\Config\Config::getInstance()->getDelay_busy_server();
  1885. $this->timeEngageMap = $time;
  1886. $this->addLog("Launching map in " . \eBot\Config\Config::getInstance()->getDelay_busy_server() . " seconds");
  1887. TaskManager::getInstance()->addTask(new Task($this, self::TASK_ENGAGE_MAP, $time));
  1888. } else {
  1889. $this->setStatus(self::STATUS_END_MATCH, true);
  1890. Logger::error("Not map found");
  1891. $this->addLog("Match is closed");
  1892. }
  1893. }
  1894. }
  1895.  
  1896. private function processChangeName(\eBot\Message\Type\ChangeName $message) {
  1897. $this->processPlayer($message->getUserId(), $message->newName, $message->getUserTeam(), $message->getUserSteamid());
  1898. }
  1899.  
  1900. private function processKillAssist(\eBot\Message\Type\KillAssist $message) {
  1901. $killer = $this->processPlayer($message->getUserId(), $message->getUserName(), $message->getUserTeam(), $message->getUserSteamid());
  1902. //$killed = $this->processPlayer($message->getKilledUserId(), $message->getKilledUserName(), $message->getKilledUserTeam(), $message->getKilledUserSteamid());
  1903.  
  1904. if (!$this->waitForRestart && $this->enable && in_array($this->getStatus(), array(self::STATUS_FIRST_SIDE, self::STATUS_SECOND_SIDE, self::STATUS_OT_FIRST_SIDE, self::STATUS_OT_SECOND_SIDE))) {
  1905. $killer->inc("assist");
  1906. $killer->save();
  1907. }
  1908.  
  1909. // $this->addLog($message->userName . " assisted the kill of " . $message->killedUserName);
  1910. // $this->addMatchLog($this->getColoredUserNameHTML($message->userName, $message->userTeam) . " assisted the kill of " . $this->getColoredUserNameHTML($message->killedUserName, $message->killedUserTeam));
  1911. }
  1912.  
  1913. private function processKill(\eBot\Message\Type\Kill $message) {
  1914. $this->processPlayer($message->getUserId(), $message->getUserName(), $message->getUserTeam(), $message->getUserSteamid());
  1915. $this->processPlayer($message->getKilledUserId(), $message->getKilledUserName(), $message->getKilledUserTeam(), $message->getKilledUserSteamid());
  1916.  
  1917. if (!$this->waitForRestart && $this->enable && in_array($this->getStatus(), array(self::STATUS_FIRST_SIDE, self::STATUS_SECOND_SIDE, self::STATUS_OT_FIRST_SIDE, self::STATUS_OT_SECOND_SIDE))) {
  1918. $killer = $this->findPlayer($message->userId, $message->userSteamid);
  1919. $killed = $this->findPlayer($message->killedUserId, $message->killedUserSteamid);
  1920.  
  1921. if ($this->firstFrag) {
  1922. if ($killer != null) {
  1923. $killer->inc("firstKill");
  1924. $killer->gotFirstKill = true;
  1925. }
  1926. $this->firstFrag = false;
  1927. }
  1928.  
  1929. if ($killed != null) {
  1930. $killed->set("alive", false);
  1931. }
  1932.  
  1933. if ($message->userTeam == $message->killedUserTeam) {
  1934. if ($killer) {
  1935. $killer->inc("tk");
  1936. $killer->deinc("point");
  1937. }
  1938.  
  1939. if ($killed) {
  1940. $killed->inc("death");
  1941. }
  1942. } else {
  1943. if ($killer) {
  1944. $killer->inc("killRound");
  1945. $killer->inc("kill");
  1946. $killer->inc("point");
  1947. if ($message->headshot) {
  1948. $killer->inc("hs");
  1949. }
  1950. }
  1951.  
  1952. if ($killed) {
  1953. $killed->inc("death");
  1954. }
  1955. }
  1956.  
  1957. $killer_id = null;
  1958. $killed_id = null;
  1959. $killer_name = $message->userName;
  1960. $killed_name = $message->killedUserName;
  1961. if ($killer != null) {
  1962. $killer_id = $killer->getId();
  1963. }
  1964.  
  1965. if ($killed != null) {
  1966. $killed_id = $killed->getId();
  1967. }
  1968.  
  1969. //getNbRound
  1970. \mysql_query("INSERT INTO player_kill
  1971. (`match_id`,`map_id`, `killer_team`,`killer_name`,`killer_id`,`killed_team`,`killed_name`,`killed_id`,`weapon`,`headshot`,`round_id`,`created_at`,`updated_at`)
  1972. VALUES
  1973. ('" . $this->match_id . "','" . $this->currentMap->getMapId() . "', '" . $message->userTeam . "', '" . addslashes($killer_name) . "', " . (($killer_id != null) ? $killer_id : "NULL") . ", '" . $message->killedUserTeam . "' ,'" . addslashes($killed_name) . "', " . (($killed_id != null) ? $killed_id : "NULL") . ", '" . $message->weapon . "', '" . $message->headshot . "','" . (($this->roundEndEvent) ? $this->getNbRound() - 1 : $this->getNbRound() ) . "', NOW(), NOW())
  1974. ") or $this->addLog("Can't insert player_kill " . mysql_error(), Logger::ERROR);
  1975.  
  1976. // Round Event
  1977. $id = \mysql_insert_id();
  1978. if (is_numeric($id)) {
  1979. // Inserting round event
  1980. \mysql_query("
  1981. INSERT INTO `round`
  1982. (`match_id`,`map_id`,`event_name`,`event_time`,`kill_id`,`round_id`,`created_at`,`updated_at`)
  1983. VALUES
  1984. ('" . $this->match_id . "', '" . $this->currentMap->getMapId() . "', 'kill', '" . $this->getRoundTime() . "', $id, '" . (($this->roundEndEvent) ? $this->getNbRound() - 1 : $this->getNbRound() ) . "', NOW(), NOW())
  1985. ");
  1986. }
  1987.  
  1988. // HeatMap !
  1989. \mysql_query("INSERT INTO `players_heatmap`
  1990. (`match_id`,`map_id`,`event_name`,`event_x`,`event_y`,`event_z`,`player_name`,`player_id`,`player_team`,`attacker_x`,`attacker_y`,`attacker_z`,`attacker_name`,`attacker_id`,`attacker_team`,`round_id`,`round_time`,`created_at`,`updated_at`) VALUES
  1991. (" . $this->match_id . ", " . $this->currentMap->getMapId() . ", 'kill', '" . $message->killedPosX . "', '" . $message->killedPosY . "', '" . $message->killedPosZ . "','" . addslashes($message->killedUserName) . "', '" . $killed_id . "', '" . $message->killedUserTeam . "', '" . $message->killerPosX . "', '" . $message->killerPosY . "', '" . $message->killerPosZ . "', '" . $message->userName . "', '" . $killer_id . "', '" . $message->userTeam . "', '" . (($this->roundEndEvent) ? $this->getNbRound() - 1 : $this->getNbRound() ) . "', '" . $this->getRoundTime() . "', NOW(), NOW())
  1992. ");
  1993.  
  1994. if ($killer) {
  1995. $killer->saveScore();
  1996. }
  1997.  
  1998. if ($killed) {
  1999. $killed->saveScore();
  2000. }
  2001. }
  2002.  
  2003. if ($message->killedUserTeam == "CT") {
  2004. $this->nbLast["nb_ct"]--;
  2005. } elseif ($message->killedUserTeam == "TERRORIST") {
  2006. $this->nbLast["nb_t"]--;
  2007. }
  2008.  
  2009. $this->addLog($message->getUserName() . " killed " . $message->getKilledUserName() . " with " . $message->weapon . (($message->headshot) ? " (headshot)" : "") . " (CT: " . $this->nbLast["nb_ct"] . " - T: " . $this->nbLast['nb_t'] . ")");
  2010. $this->addMatchLog($this->getColoredUserNameHTML($message->getUserName(), $message->userTeam) . " killed " . $this->getColoredUserNameHTML($message->getKilledUserName(), $message->killedUserTeam) . " with " . $message->weapon . (($message->headshot) ? " (headshot)" : "") . " (CT: " . $this->nbLast["nb_ct"] . " - T: " . $this->nbLast['nb_t'] . ")");
  2011.  
  2012. $this->watchForSpecialSituation();
  2013.  
  2014. if ($this->isMatchRound()) {
  2015. $sendToWebsocket = json_encode(array(
  2016. 'type' => 'kill',
  2017. 'id' => $this->match_id,
  2018. 'killer' => $message->getUserName(),
  2019. 'killerPosX' => $message->killerPosX,
  2020. 'killerPosY' => $message->killerPosY,
  2021. 'weapon' => $message->getWeapon(),
  2022. 'killed' => $message->getKilledUserName(),
  2023. 'killedPosX' => $message->killedPosX,
  2024. 'killedPosY' => $message->killedPosY,
  2025. 'headshot' => $message->getHeadshot()
  2026. ));
  2027. $this->websocket['livemap']->sendData($sendToWebsocket);
  2028. }
  2029.  
  2030. $event = new \eBot\Events\Event\Kill();
  2031. $event->setMatch($this);
  2032. $event->setUserId($message->getUserId());
  2033. $event->setUserName($message->getUserName());
  2034. $event->setUserTeam($message->getUserTeam());
  2035. $event->setUserSteamid($message->getUserSteamid());
  2036. $event->setKilledUserId($message->getKilledUserId());
  2037. $event->setKilledUserName($message->getKilledUserName());
  2038. $event->setKilledUserTeam($message->getKilledUserTeam());
  2039. $event->setKilledUserSteamid($message->getKilledUserSteamid());
  2040. $event->setHeadshot($message->getHeadshot());
  2041. $event->setWeapon($message->getWeapon());
  2042. \eBot\Events\EventDispatcher::getInstance()->dispatchEvent($event);
  2043. }
  2044.  
  2045. private function processConnected(\eBot\Message\Type\Connected $message) {
  2046. $this->addLog($message->userName . " connected (" . $message->address . ")");
  2047. $this->addMatchLog(htmlentities($message->userName) . " connected");
  2048. $this->userToEnter[$message->userId] = $message->address;
  2049. }
  2050.  
  2051. private function processEnteredTheGame(\eBot\Message\Type\EnteredTheGame $message) {
  2052. $this->addLog($message->userName . " entered the game");
  2053. }
  2054.  
  2055. private function processGotTheBomb(\eBot\Message\Type\GotTheBomb $message) {
  2056. /*if (\eBot\Config\Config::getInstance()->getPauseMethod() == "nextRound") {
  2057. // pauseNextRound
  2058. if (($this->pause['ct'] || $this->pause['t']) && $this->isMatchRound() && !$this->isPaused && $this->roundEndEvent) {
  2059. $this->isPaused = true;
  2060. $this->say("Match is paused");
  2061. $this->say("Write !unpause to remove the pause when ready");
  2062. $this->addMatchLog("Pausing match");
  2063. $this->rcon->send("pause");
  2064. \mysql_query("UPDATE `matchs` SET `is_paused` = '1' WHERE `id` = '" . $this->match_id . "'");
  2065. $this->websocket['match']->sendData(json_encode(array('message' => 'status', 'content' => 'is_paused', 'id' => $this->match_id)));
  2066.  
  2067. $this->pause["ct"] = false;
  2068. $this->pause["t"] = false;
  2069. $this->unpause["ct"] = false;
  2070. $this->unpause["t"] = false;
  2071. }
  2072. }*/
  2073.  
  2074. if (\eBot\Config\Config::getInstance()->getPauseMethod() == "nextRound") {
  2075. if ($this->isMatchRound() && $this->isPaused && $this->roundEndEvent) {
  2076. $this->say("Match is paused !");
  2077. $this->say("Write !unpause to remove the pause when ready");
  2078. }
  2079. }
  2080.  
  2081. if ($this->roundEndEvent) {
  2082. foreach ($this->players as $k => &$v) {
  2083. if ($this->getNbRound() > 1) {
  2084. $v->snapshot($this->getNbRound() - 1);
  2085. }
  2086. }
  2087. }
  2088. }
  2089.  
  2090. private function processJoinTeam(\eBot\Message\Type\JoinTeam $message) {
  2091. $this->processPlayer($message->getUserId(), $message->getUserName(), $message->joinTeam, $message->getUserSteamid());
  2092. $this->addLog($message->userName . " join team " . $message->joinTeam);
  2093. $this->addMatchLog(htmlentities($message->userName) . " join team " . $message->joinTeam);
  2094. }
  2095.  
  2096. private function processDisconnected(\eBot\Message\Type\Disconnected $message) {
  2097. $this->addLog($message->userName . " disconnected");
  2098. $this->addMatchLog(htmlentities($message->userName) . " disconnected");
  2099. $player = $this->findPlayer($message->userId, $message->userSteamid);
  2100. if ($player != null) {
  2101. $player->setOnline(false);
  2102. }
  2103. }
  2104.  
  2105. private function processRoundRestart(\eBot\Message\Type\RoundRestart $message) {
  2106. if ($this->waitForRestart && $this->getStatus() == self::STATUS_FIRST_SIDE && ( \eBot\Config\Config::getInstance()->getConfigKnifeMethod() == "matchstart" || $this->forceRoundStartRecord)) {
  2107. $this->waitRoundStartRecord = true;
  2108. $this->forceRoundStartRecord = false;
  2109. } elseif ($this->waitForRestart && $this->getStatus() == self::STATUS_KNIFE && \eBot\Config\Config::getInstance()->getConfigKnifeMethod() == "knifestart") {
  2110. $this->waitRoundStartRecord = true;
  2111. }
  2112. }
  2113.  
  2114. private function processRoundStart(\eBot\Message\Type\RoundStart $message) {
  2115. if ($this->waitForRestart) {
  2116. $this->waitForRestart = false;
  2117. Logger::log("Starting counting score");
  2118. }
  2119.  
  2120. if ($this->waitRoundStartRecord) {
  2121. $record_name = $this->match_id . "_" . \eTools\Utils\Slugify::cleanTeamName($this->teamAName) . "-" . \eTools\Utils\Slugify::cleanTeamName($this->teamBName) . "_" . $this->currentMap->getMapName();
  2122. $text = $this->rcon->send("tv_autorecord");
  2123. if (preg_match('!"tv_autorecord" = "(?<value>.*)"!', $text, $match)) {
  2124. if ($match["value"] == 1) {
  2125. Logger::log("Stopping running records (tv_autorecord)");
  2126. $this->rcon->send("tv_autorecord 0; tv_stoprecord");
  2127. }
  2128. }
  2129.  
  2130. Logger::log("Launching record $record_name");
  2131. $this->rcon->send("tv_record $record_name");
  2132. $this->currentMap->setTvRecordFile($record_name);
  2133. $this->waitRoundStartRecord = false;
  2134.  
  2135. \mysql_query("UPDATE `maps` SET tv_record_file='" . $record_name . "' WHERE id='" . $this->currentMap->getMapId() . "'") or $this->addLog("Error while updating tv record name - " . mysql_error(), Logger::ERROR);
  2136. }
  2137.  
  2138. $this->nbLast['nb_ct'] = $this->nbLast['nb_max_ct'];
  2139. $this->nbLast['nb_t'] = $this->nbLast['nb_max_t'];
  2140. $this->gameBombPlanter = null;
  2141. $this->gameBombeDefuser = null;
  2142. $this->firstFrag = true;
  2143. $this->timeRound = time();
  2144. $this->saveScore();
  2145. $this->resetSpecialSituation();
  2146.  
  2147. foreach ($this->players as $k => &$v) {
  2148. $v->roundStart();
  2149. if ($this->getNbRound() > 1) {
  2150. $v->snapshot($this->getNbRound() - 1);
  2151. }
  2152. }
  2153.  
  2154. $this->countPlayers();
  2155.  
  2156. $this->watchForSpecialSituation();
  2157.  
  2158. // Feedback from players
  2159. $this->pause["ct"] = false;
  2160. $this->pause["t"] = false;
  2161. $this->unpause["ct"] = false;
  2162. $this->unpause["t"] = false;
  2163. $this->stop["ct"] = false;
  2164. $this->stop["t"] = false;
  2165.  
  2166. // Preventing old data
  2167. mysql_query("DELETE FROM player_kill WHERE round_id = " . $this->getNbRound() . " AND map_id='" . $this->currentMap->getMapId() . "'");
  2168. mysql_query("DELETE FROM round WHERE round_id = " . $this->getNbRound() . " AND map_id='" . $this->currentMap->getMapId() . "'");
  2169. mysql_query("DELETE FROM round_summary WHERE round_id = " . $this->getNbRound() . " AND map_id='" . $this->currentMap->getMapId() . "'");
  2170.  
  2171. \mysql_query("
  2172. INSERT INTO `round`
  2173. (`match_id`,`map_id`,`event_name`,`event_time`,`round_id`,`created_at`,`updated_at`)
  2174. VALUES
  2175. ('" . $this->match_id . "', '" . $this->currentMap->getMapId() . "', 'round_start', '" . $this->getRoundTime() . "', '" . $this->getNbRound() . "', NOW(), NOW())
  2176. ");
  2177. if ($this->isMatchRound())
  2178. $this->websocket['livemap']->sendData(json_encode(array(
  2179. 'type' => 'newRound',
  2180. 'id' => $this->match_id,
  2181. 'message' => "newRound",
  2182. 'round' => $this->getNbRound(),
  2183. 'status' => $this->getStatusText()
  2184. )));
  2185.  
  2186. $this->roundEndEvent = false;
  2187. }
  2188.  
  2189. private function processPlayer($user_id, $user_name, $team, $steamid) {
  2190. Logger::debug("Processing player $user_id $user_name $team $steamid");
  2191. $player = $this->findPlayer($user_id, $steamid);
  2192. if ($player == null) {
  2193. $player = new Player($this->match_id, $this->currentMap->getMapId(), $steamid);
  2194. $this->players[$user_id] = $player;
  2195. $this->countPlayers();
  2196. }
  2197.  
  2198. if (@$this->userToEnter[$user_id]) {
  2199. $player->setIp($this->userToEnter[$user_id]);
  2200. }
  2201.  
  2202. $player->setUserName($user_name);
  2203. $player->setOnline(true);
  2204.  
  2205. $teamToSet = null;
  2206. if (strtolower($team) == "ct") {
  2207. if (($this->side["team_a"] == "ct")) {
  2208. $teamToSet = "a";
  2209. } elseif (($this->side["team_b"] == "ct")) {
  2210. $teamToSet = "b";
  2211. }
  2212. } elseif ((strtolower($team) == "terrorist") || (strtolower($team) == "t")) {
  2213. if (($this->side["team_a"] == "t")) {
  2214. $teamToSet = "a";
  2215. } elseif (($this->side["team_b"] == "t")) {
  2216. $teamToSet = "b";
  2217. }
  2218. }
  2219.  
  2220. $player->setCurrentTeam($team, $teamToSet);
  2221. $player->save();
  2222.  
  2223. return $player;
  2224. }
  2225.  
  2226. private function resetSpecialSituation() {
  2227. $this->specialSituation['id'] = 0;
  2228. $this->specialSituation['situation'] = 0;
  2229. $this->specialSituation['active'] = false;
  2230. $this->specialSituation['side'] = "";
  2231. $this->specialSituation['side2'] = "";
  2232. $this->specialSituation['status'] = false;
  2233. }
  2234.  
  2235. private $specialSituation = array("id" => 0, "situation" => 0, "active" => false, "side" => "");
  2236.  
  2237. private function watchForSpecialSituation() {
  2238. if (!$this->specialSituation['active']) {
  2239. if (($this->nbLast['nb_ct'] == 1) && ($this->nbLast['nb_t'] == 1)) {
  2240. $this->specialSituation['id'] = 0;
  2241. $this->specialSituation['situation'] = 1;
  2242. $this->specialSituation['active'] = true;
  2243. $this->specialSituation['side'] = "both";
  2244. $this->addLog("1v1 situation !");
  2245. $this->addMatchLog("<b>Situation 1v1</b>", true);
  2246. \mysql_query("
  2247. INSERT INTO `round`
  2248. (`match_id`,`map_id`,`event_name`,`event_time`,`round_id`,`created_at`,`updated_at`)
  2249. VALUES
  2250. ('" . $this->match_id . "', '" . $this->currentMap->getMapId() . "', '1vx', '" . $this->getRoundTime() . "', '" . $this->getNbRound() . "', NOW(), NOW())
  2251. ");
  2252. } else {
  2253. if ($this->nbLast['nb_ct'] == 1) {
  2254. $nbAlive = 0;
  2255. $id = false;
  2256. foreach ($this->players as $k => &$v) {
  2257. if (!$v->get("online"))
  2258. continue;
  2259.  
  2260. if (($v->get("currentSide") == "t") && $v->get("alive")) {
  2261. $nbAlive++;
  2262. } elseif (($v->get("currentSide") == "ct") && $v->get("alive")) {
  2263. $id = $k;
  2264. }
  2265. }
  2266.  
  2267. if (($nbAlive > 0) && $id) {
  2268. $this->specialSituation['id'] = $id;
  2269. $this->specialSituation['situation'] = $nbAlive;
  2270. $this->specialSituation['active'] = true;
  2271. $this->specialSituation['side'] = "ct";
  2272.  
  2273. $this->addLog("Situation spécial ! 1v" . $nbAlive . " (" . $this->players[$id]->get("name") . ")");
  2274. $this->addMatchLog("<b>Situation spécial ! 1v" . $nbAlive . " (" . htmlentities($this->players[$id]->get("name")) . ")</b>");
  2275.  
  2276. \mysql_query("
  2277. INSERT INTO `round`
  2278. (`match_id`,`map_id`,`event_name`, `event_text`,`event_time`,`round_id`,`created_at`,`updated_at`)
  2279. VALUES
  2280. ('" . $this->match_id . "', '" . $this->currentMap->getMapId() . "', '1vx', '" . addslashes(serialize(array("situation" => $nbAlive, "player_id" => $this->players[$id]->get("name"), "player_id" => $this->players[$id]->getId()))) . "', '" . $this->getRoundTime() . "', '" . $this->getNbRound() . "', NOW(), NOW())
  2281. ");
  2282. }
  2283. } elseif ($this->nbLast['nb_t'] == 1) {
  2284. $nbAlive = 0;
  2285. $id = false;
  2286. foreach ($this->players as $k => &$v) {
  2287. if (!$v->get("online"))
  2288. continue;
  2289.  
  2290. if (($v->get("currentSide") == "ct") && $v->get("alive")) {
  2291. $nbAlive++;
  2292. } elseif (($v->get("currentSide") == "t") && $v->get("alive")) {
  2293. $id = $k;
  2294. }
  2295. }
  2296.  
  2297. if (($nbAlive > 0) && $id) {
  2298. $this->specialSituation['id'] = $id;
  2299. $this->specialSituation['situation'] = $nbAlive;
  2300. $this->specialSituation['active'] = true;
  2301. $this->specialSituation['side'] = "t";
  2302.  
  2303. $this->addLog("Situation spécial ! 1v" . $nbAlive . " (" . $this->players[$id]->get("name") . ")");
  2304. $this->addMatchLog("<b>Situation spécial ! 1v" . $nbAlive . " (" . htmlentities($this->players[$id]->get("name")) . ")</b>");
  2305. \mysql_query("
  2306. INSERT INTO `round`
  2307. (`match_id`,`map_id`,`event_name`, `event_text`,`event_time`,`round_id`,`created_at`,`updated_at`)
  2308. VALUES
  2309. ('" . $this->match_id . "', '" . $this->currentMap->getMapId() . "', '1vx', '" . addslashes(serialize(array("situation" => $nbAlive, "player_id" => $this->players[$id]->get("name"), "player_id" => $this->players[$id]->getId()))) . "', '" . $this->getRoundTime() . "', '" . $this->getNbRound() . "', NOW(), NOW())
  2310. ");
  2311. }
  2312. }
  2313. }
  2314. } else {
  2315. if (($this->specialSituation['side2'] != "both") && ($this->specialSituation['side'] != "both")) {
  2316. if (($this->nbLast['nb_ct'] == 1) && ($this->nbLast['nb_t'] == 1)) {
  2317. if ($this->players[$this->specialSituation['id']]) {
  2318. $this->addLog("Situation spécial 1v1 ! - Le joueur " . $this->players[$this->specialSituation['id']]->get("name") . " est en 1v" . $this->specialSituation['situation']);
  2319. $this->addMatchLog("<b>Situation spécial 1v1 ! - Le joueur " . htmlentities($this->players[$this->specialSituation['id']]->get("name")) . " est en 1v" . $this->specialSituation['situation'] . "</b>", false);
  2320. $this->specialSituation['side2'] = "both";
  2321.  
  2322. \mysql_query("
  2323. INSERT INTO `round`
  2324. (`match_id`,`map_id`,`event_name`,`event_time`,`round_id`,`created_at`,`updated_at`)
  2325. VALUES
  2326. ('" . $this->match_id . "', '" . $this->currentMap->getMapId() . "', '1v1', '" . $this->getRoundTime() . "', '" . $this->getNbRound() . "', NOW(), NOW())
  2327. ");
  2328. }
  2329. }
  2330. }
  2331. }
  2332. }
  2333.  
  2334. /**
  2335. *
  2336. * @param type $user_id
  2337. * @param type $steamid
  2338. * @return \eBot\Match\Player
  2339. */
  2340. private function findPlayer($user_id = null, $steamid = null) {
  2341. foreach ($this->players as $player) {
  2342. if (($player->getSteamid() == $steamid)) {
  2343. return $player;
  2344. }
  2345. }
  2346.  
  2347. return null;
  2348. }
  2349.  
  2350. private function saveScore() {
  2351. foreach ($this->players as $player) {
  2352.  
  2353. }
  2354. }
  2355.  
  2356. private function countPlayers() {
  2357. $this->nbLast['nb_max_ct'] = 0;
  2358. $this->nbLast['nb_max_t'] = 0;
  2359. $this->nbLast["nb_ct"] = 0;
  2360. $this->nbLast["nb_t"] = 0;
  2361.  
  2362. foreach ($this->players as $k => &$v) {
  2363. if (!$v->get("online"))
  2364. continue;
  2365. if ($v->get("currentSide") == "ct") {
  2366. $this->nbLast['nb_max_ct']++;
  2367. if ($v->get("alive"))
  2368. $this->nbLast["nb_ct"]++;
  2369. } elseif ($v->get("currentSide") == "t") {
  2370. $this->nbLast['nb_max_t']++;
  2371. if ($v->get("alive"))
  2372. $this->nbLast["nb_t"]++;
  2373. }
  2374. }
  2375.  
  2376. $this->addLog("Counting players :: CT:" . $this->nbLast['nb_max_ct'] . " :: T:" . $this->nbLast['nb_max_t']);
  2377. }
  2378.  
  2379. private function pauseMatch() {
  2380. if (\eBot\Config\Config::getInstance()->getPauseMethod() == "instantConfirm") {
  2381. if ($this->pause["ct"] && $this->pause["t"] && $this->isMatchRound() && !$this->isPaused) {
  2382. $this->isPaused = true;
  2383. $this->say("Match is paused");
  2384. $this->say("Write !unpause to remove the pause when ready");
  2385. $this->addMatchLog("Pausing match");
  2386. $this->rcon->send("pause");
  2387. \mysql_query("UPDATE `matchs` SET `is_paused` = '1' WHERE `id` = '" . $this->match_id . "'");
  2388. $this->websocket['match']->sendData(json_encode(array('message' => 'status', 'content' => 'is_paused', 'id' => $this->match_id)));
  2389.  
  2390. $this->pause["ct"] = false;
  2391. $this->pause["t"] = false;
  2392. $this->unpause["ct"] = false;
  2393. $this->unpause["t"] = false;
  2394. }
  2395. } elseif (\eBot\Config\Config::getInstance()->getPauseMethod() == "instantNoConfirm") {
  2396. if (($this->pause["ct"] || $this->pause["t"]) && $this->isMatchRound() && !$this->isPaused) {
  2397. $this->isPaused = true;
  2398. $this->say("Match is paused");
  2399. $this->say("Write !unpause to remove the pause when ready");
  2400. $this->addMatchLog("Pausing match");
  2401. $this->rcon->send("pause");
  2402. \mysql_query("UPDATE `matchs` SET `is_paused` = '1' WHERE `id` = '" . $this->match_id . "'");
  2403. $this->websocket['match']->sendData(json_encode(array('message' => 'status', 'content' => 'is_paused', 'id' => $this->match_id)));
  2404.  
  2405. $this->pause["ct"] = false;
  2406. $this->pause["t"] = false;
  2407. $this->unpause["ct"] = false;
  2408. $this->unpause["t"] = false;
  2409. }
  2410. } elseif (\eBot\Config\Config::getInstance()->getPauseMethod() == "nextRound") {
  2411. if (($this->pause["ct"] || $this->pause["t"]) && $this->isMatchRound() && !$this->isPaused) {
  2412. $this->isPaused = true;
  2413. $this->say("Match will be paused at next round !");
  2414. $this->say("Write !unpause to remove the pause when ready");
  2415. $this->addMatchLog("Pausing match");
  2416. $this->rcon->send("mp_pause_match");
  2417. \mysql_query("UPDATE `matchs` SET `is_paused` = '1' WHERE `id` = '" . $this->match_id . "'");
  2418. $this->websocket['match']->sendData(json_encode(array('message' => 'status', 'content' => 'is_paused', 'id' => $this->match_id)));
  2419.  
  2420. $this->pause["ct"] = false;
  2421. $this->pause["t"] = false;
  2422. $this->unpause["ct"] = false;
  2423. $this->unpause["t"] = false;
  2424. }
  2425. }
  2426. }
  2427.  
  2428. private function unpauseMatch() {
  2429. if ($this->unpause["ct"] && $this->unpause["t"] && $this->isMatchRound() && $this->isPaused) {
  2430. $this->isPaused = false;
  2431. $this->say("Match is unpaused, live !");
  2432. $this->addMatchLog("Unpausing match");
  2433. if (\eBot\Config\Config::getInstance()->getPauseMethod() == "nextRound") {
  2434. $this->rcon->send("mp_unpause_match");
  2435. } else {
  2436. $this->rcon->send("pause");
  2437. }
  2438. \mysql_query("UPDATE `matchs` SET `is_paused` = '0' WHERE `id` = '" . $this->match_id . "'");
  2439. $this->websocket['match']->sendData(json_encode(array('message' => 'status', 'content' => 'is_unpaused', 'id' => $this->match_id)));
  2440.  
  2441. $this->pause["ct"] = false;
  2442. $this->pause["t"] = false;
  2443. $this->unpause["ct"] = false;
  2444. $this->unpause["t"] = false;
  2445. }
  2446. }
  2447.  
  2448. private function setMatchMap($mapname) {
  2449. if ($this->playMap["ct"] == $this->playMap["t"] AND $this->playMap["ct"] != "") {
  2450. \mysql_query("UPDATE `maps` SET `map_name` = '" . $this->playMap["ct"] . "' WHERE `match_id` = '" . $this->match_id . "'");
  2451. Logger::debug("Loading map");
  2452. $query = \mysql_query("SELECT * FROM `maps` WHERE match_id = '" . $this->match_id . "'");
  2453. if (!$query) {
  2454. throw new MatchException();
  2455. }
  2456. while ($data = \mysql_fetch_assoc($query)) {
  2457. $this->maps[$data["id"]] = new Map($data);
  2458. $this->maps[$data["id"]]->setNbMaxRound($this->maxRound);
  2459. }
  2460. if ($this->maps[$this->matchData["current_map"]]) {
  2461. $this->currentMap = $this->maps[$this->matchData["current_map"]];
  2462. } else {
  2463. $this->addLog("Can't find the map #" . $this->matchData["current_map"], Logger::ERROR);
  2464. throw new MatchException();
  2465. }
  2466. $this->addLog("Maps selected: #" . $this->currentMap->getMapId() . " - " . $this->currentMap->getMapName() . " - " . $this->currentMap->getStatusText());
  2467. Logger::debug("Engage new Map.");
  2468. TaskManager::getInstance()->addTask(new Task($this, self::TASK_ENGAGE_MAP, microtime(true) + 1));
  2469.  
  2470. if ($this->currentMap->getCurrentSide() == "ct") {
  2471. $this->side['team_a'] = "ct";
  2472. $this->side['team_b'] = "t";
  2473. } else {
  2474. $this->side['team_a'] = "t";
  2475. $this->side['team_b'] = "ct";
  2476. }
  2477.  
  2478. $this->currentMap->calculScores();
  2479.  
  2480. $this->score["team_a"] = $this->currentMap->getScore1();
  2481. $this->score["team_b"] = $this->currentMap->getScore2();
  2482.  
  2483. @mysql_query("UPDATE `matchs` SET score_a = '" . $this->score["team_a"] . "', score_b ='" . $this->score["team_b"] . "' WHERE id='" . $this->match_id . "'");
  2484.  
  2485. // Setting nb OverTime
  2486. $this->nbOT = $this->currentMap->getNbOt();
  2487. }
  2488. }
  2489.  
  2490. private function continueMatch() {
  2491. if ($this->continue["ct"] && $this->continue["t"]) {
  2492. $this->continue["ct"] = false;
  2493. $this->continue["t"] = false;
  2494.  
  2495. $this->addMatchLog("Getting back to the match");
  2496. $this->addLog("Getting back to the match");
  2497.  
  2498. // Sending roundbackup format file
  2499. $this->rcon->send("mp_backup_round_file \"ebot_" . $this->match_id . "\"");
  2500.  
  2501. // Prevent the halftime pausetimer
  2502. $this->rcon->send("mp_halftime_pausetimer 0");
  2503.  
  2504. if (!$this->backupFile) {
  2505. $this->addLog("Backup file not found, simulating one");
  2506. $this->backupFile = "ebot_" . $this->match_id . "_round" . sprintf("%02s", $this->getNbRound()) . ".txt";
  2507. }
  2508. // Sending restore
  2509. $this->rcon->send("mp_backup_restore_load_file " . $this->backupFile);
  2510.  
  2511. // Prevent a bug for double stop
  2512. $this->rcon->send("mp_backup_round_file_last " . $this->backupFile);
  2513.  
  2514. foreach ($this->players as &$player) {
  2515. $player->restoreSnapshot($this->getNbRound() - 1);
  2516. }
  2517.  
  2518. $this->say("Round restored, going live !");
  2519. \mysql_query("UPDATE `matchs` SET ingame_enable = 1 WHERE id='" . $this->match_id . "'") or $this->addLog("Can't update ingame_enable", Logger::ERROR);
  2520. TaskManager::getInstance()->addTask(new Task($this, self::SET_LIVE, microtime(true) + 2));
  2521. }
  2522. }
  2523.  
  2524. private function stopMatch() {
  2525. if ($this->stop["ct"] && $this->stop["t"]) {
  2526. if (in_array($this->getStatus(), array(self::STATUS_FIRST_SIDE, self::STATUS_SECOND_SIDE, self::STATUS_OT_FIRST_SIDE, self::STATUS_OT_SECOND_SIDE))) {
  2527. if ($this->getNbRound() == 1) {
  2528. $this->setStatus($this->getStatus() - 1, true);
  2529. $this->currentMap->setStatus($this->currentMap->getStatus() - 1, true);
  2530.  
  2531. $this->addLog("Stopping current side, new status: " . $this->getStatusText());
  2532.  
  2533. $this->recupStatus(true);
  2534. mysql_query("DELETE FROM player_kill WHERE round_id >= 1 AND map_id='" . $this->currentMap->getMapId() . "'");
  2535. mysql_query("DELETE FROM round WHERE round_id >= 1 AND map_id='" . $this->currentMap->getMapId() . "'");
  2536. mysql_query("DELETE FROM round_summary WHERE round_id >= 1 AND map_id='" . $this->currentMap->getMapId() . "'");
  2537. } else {
  2538. // Getting file to restore
  2539. $data = $this->rcon->send("mp_backup_round_file_last");
  2540. if (preg_match('!"mp_backup_round_file_last" = "(?<backup>[a-zA-Z0-9\-_\.]+)"!', $data, $match)) {
  2541. $this->backupFile = $match["backup"];
  2542. } else {
  2543. $this->addLog("Backup file not found, simulating one ");
  2544. $this->backupFile = "ebot_" . $this->match_id . "_round" . sprintf("%02s", $this->getNbRound()) . ".txt";
  2545. }
  2546.  
  2547. $this->addLog("Backup file :" . $this->backupFile);
  2548.  
  2549. $this->say("\001This round has been cancelled, we will restart at the begin of the round");
  2550. $this->enable = false;
  2551.  
  2552. $this->rcon->send("mp_backup_round_file \"ebot_paused_" . $this->match_id . "\"");
  2553. $this->rcon->send("mp_restartgame 1");
  2554. \mysql_query("UPDATE `matchs` SET ingame_enable = 0 WHERE id='" . $this->match_id . "'") or $this->addLog("Can't update ingame_enable", Logger::ERROR);
  2555.  
  2556. /* if ($this->getNbRound() == $this->maxRound + 1) {
  2557. $this->rcon->send("mp_swapteams");
  2558. $this->say("\001Don't panic, to prevent a bug from backup system, you are switched. You will be switched when you continue the match");
  2559. }
  2560.  
  2561. if ($this->getStatus() > self::STATUS_WU_OT_1_SIDE) {
  2562. $round = $this->getNbRound() - ($this->oldMaxround * 2);
  2563. if ($round % ($this->maxRound * 2) == $this->maxRound + 1) {
  2564. $this->rcon->send("mp_swapteams");
  2565. $this->say("\001Don't panic, to prevent a bug from backup system, you are switched. You will be switched when you continue the match");
  2566. }
  2567. } */
  2568.  
  2569. mysql_query("DELETE FROM player_kill WHERE round_id = " . $this->getNbRound() . " AND map_id='" . $this->currentMap->getMapId() . "'");
  2570. mysql_query("DELETE FROM round WHERE round_id = " . $this->getNbRound() . " AND map_id='" . $this->currentMap->getMapId() . "'");
  2571. mysql_query("DELETE FROM round_summary WHERE round_id = " . $this->getNbRound() . " AND map_id='" . $this->currentMap->getMapId() . "'");
  2572. }
  2573.  
  2574. $this->ready["ct"] = false;
  2575. $this->ready["t"] = false;
  2576. $this->stop["ct"] = false;
  2577. $this->stop["t"] = false;
  2578. $this->pause["ct"] = false;
  2579. $this->pause["t"] = false;
  2580. $this->unpause["ct"] = false;
  2581. $this->unpause["t"] = false;
  2582. } elseif ($this->getStatus() == self::STATUS_KNIFE) {
  2583. $this->setStatus($this->getStatus() - 1, true);
  2584. $this->currentMap->setStatus($this->currentMap->getStatus() - 1, true);
  2585.  
  2586. $this->ready["ct"] = false;
  2587. $this->ready["t"] = false;
  2588. $this->stop["ct"] = false;
  2589. $this->stop["t"] = false;
  2590. $this->pause["ct"] = false;
  2591. $this->pause["t"] = false;
  2592. $this->unpause["ct"] = false;
  2593. $this->unpause["t"] = false;
  2594.  
  2595. $this->say("\001The knife round is stopped \005- \003" . $this->getStatusText());
  2596. $this->rcon->send("mp_restartgame 1");
  2597. }
  2598. }
  2599. }
  2600.  
  2601. private function startMatch() {
  2602. if ($this->ready['ct'] && $this->ready['t']) {
  2603. if ($this->getStatus() == self::STATUS_WU_KNIFE) {
  2604. $this->stop['t'] = false;
  2605. $this->stop['ct'] = false;
  2606.  
  2607. $this->addMatchLog("<b>INFO:</b> Starting Knife Round");
  2608. $this->addLog("Starting Knife Round");
  2609.  
  2610. $this->setStatus(self::STATUS_KNIFE, true);
  2611. $this->currentMap->setStatus(Map::STATUS_KNIFE, true);
  2612.  
  2613. // FIX for warmup
  2614.  
  2615. $this->rcon->send("exec " . $this->matchData["rules"] . ".cfg; mp_warmuptime 0; mp_halftime_pausetimer 1; mp_warmup_pausetimer 0;");
  2616. $this->rcon->send("sv_rcon_whitelist_address \"" . \eBot\Config\Config::getInstance()->getBot_ip() . "\"");
  2617. $this->rcon->send("mp_halftime_duration 1; mp_roundtime_defuse 60; mp_ct_default_secondary \"\"; mp_t_default_secondary \"\"; mp_startmoney 0; mp_give_player_c4 0; mp_free_armor 1;");
  2618.  
  2619. $this->rcon->send("mp_warmup_end");
  2620. if (\eBot\Config\Config::getInstance()->getKo3Method() == "csay" && $this->pluginCsay) {
  2621. $this->rcon->send("csay_ko3");
  2622. } elseif (\eBot\Config\Config::getInstance()->getKo3Method() == "esl" && $this->pluginESL) {
  2623. $this->rcon->send("esl_ko3");
  2624. $this->say("KNIFE LIVE!");
  2625. } else {
  2626. $this->rcon->send("mp_restartgame 3");
  2627. $this->say("KNIFE!");
  2628. $this->say("KNIFE!");
  2629. $this->say("KNIFE!");
  2630. }
  2631.  
  2632. $this->waitForRestart = true;
  2633. } else {
  2634. // FIX for warmup
  2635. $this->rcon->send("mp_warmup_pausetimer 0;");
  2636.  
  2637. $this->stop['t'] = false;
  2638. $this->stop['ct'] = false;
  2639. $this->waitForRestart = true;
  2640. $this->nbRS = 0;
  2641.  
  2642. $this->addMatchLog("<b>INFO:</b> Launching RS");
  2643. $this->addLog("Launching RS");
  2644.  
  2645. switch ($this->currentMap->getStatus()) {
  2646. case Map::STATUS_WU_1_SIDE:
  2647. $this->currentMap->setStatus(Map::STATUS_FIRST_SIDE, true);
  2648. $this->setStatus(self::STATUS_FIRST_SIDE, true);
  2649. $fichier = $this->matchData["rules"] . ".cfg; mp_maxrounds " . ($this->maxRound * 2);
  2650.  
  2651. // NEW
  2652. $this->rcon->send("exec $fichier; mp_warmuptime 0; mp_halftime_pausetimer 1;");
  2653. $this->rcon->send("sv_rcon_whitelist_address \"" . \eBot\Config\Config::getInstance()->getBot_ip() . "\"");
  2654. $this->rcon->send("mp_halftime_duration 1");
  2655. $this->rcon->send("mp_warmup_end");
  2656. if (\eBot\Config\Config::getInstance()->getLo3Method() == "csay" && $this->pluginCsay) {
  2657. $this->rcon->send("csay_lo3");
  2658. } elseif (\eBot\Config\Config::getInstance()->getLo3Method() == "esl" && $this->pluginESL) {
  2659. $this->rcon->send("esl_lo3");
  2660. $this->say("1st Side: LIVE!");
  2661. } else {
  2662. $this->rcon->send("mp_restartgame 3");
  2663. $this->say("LIVE!");
  2664. $this->say("LIVE!");
  2665. $this->say("LIVE!");
  2666. }
  2667. break;
  2668. case Map::STATUS_WU_2_SIDE :
  2669. $this->currentMap->setStatus(Map::STATUS_SECOND_SIDE, true);
  2670. $this->setStatus(self::STATUS_SECOND_SIDE, true);
  2671. $fichier = $this->matchData["rules"] . ".cfg";
  2672.  
  2673. // NEW
  2674. $this->waitForRestart = false;
  2675. $this->rcon->send("mp_halftime_pausetimer 0; ");
  2676. if ($this->config_full_score) {
  2677. $this->rcon->send("mp_match_can_clinch 0");
  2678. }
  2679. $this->say("2nd Side: LIVE!");
  2680. break;
  2681. case Map::STATUS_WU_OT_1_SIDE :
  2682. $this->currentMap->setStatus(Map::STATUS_OT_FIRST_SIDE, true);
  2683. $this->setStatus(self::STATUS_OT_FIRST_SIDE, true);
  2684. // NEW
  2685. $this->rcon->send("mp_halftime_pausetimer 0");
  2686. $this->say("1st Side OT: LIVE!");
  2687. $this->waitForRestart = false;
  2688. break;
  2689. case Map::STATUS_WU_OT_2_SIDE :
  2690. $this->currentMap->setStatus(Map::STATUS_OT_SECOND_SIDE, true);
  2691. $this->setStatus(self::STATUS_OT_SECOND_SIDE, true);
  2692.  
  2693. // NEW
  2694. $this->waitForRestart = false;
  2695. $this->rcon->send("mp_halftime_pausetimer 0");
  2696. $this->say("2nd Side OT: LIVE!");
  2697. break;
  2698. }
  2699.  
  2700. if ($this->getStatus() == self::STATUS_FIRST_SIDE) {
  2701. $this->recupStatus(true);
  2702. }
  2703. }
  2704.  
  2705. $this->ready['ct'] = false;
  2706. $this->ready['t'] = false;
  2707. $this->pause["ct"] = false;
  2708. $this->pause["t"] = false;
  2709. $this->unpause["ct"] = false;
  2710. $this->unpause["t"] = false;
  2711. }
  2712. }
  2713.  
  2714. private function addLog($text, $type = Logger::LOG) {
  2715. $text = $this->server_ip . " :: " . $text;
  2716.  
  2717. switch ($type) {
  2718. case Logger::DEBUG:
  2719. Logger::debug($text);
  2720. break;
  2721. case Logger::LOG:
  2722. Logger::log($text);
  2723. break;
  2724. case Logger::ERROR:
  2725. Logger::error($text);
  2726. break;
  2727. }
  2728. }
  2729.  
  2730. private function addMatchLog($text, $admin = false, $time = true) {
  2731. if ($time) {
  2732. $text = date('Y-m-d H:i:s') . " - " . $text;
  2733. }
  2734.  
  2735. @file_put_contents($this->getLogAdminFilePath(), $text . "<br/>\n", FILE_APPEND);
  2736.  
  2737. if ($admin) {
  2738. return;
  2739. }
  2740.  
  2741. @file_put_contents($this->getLogFilePath(), $text . "<br/>\n", FILE_APPEND);
  2742. }
  2743.  
  2744. private function getColoredUserNameHTML($user, $team) {
  2745. if ($team == "CT") {
  2746. $color = "blue";
  2747. } elseif ($team == "TERRORIST") {
  2748. $color = "red";
  2749. } else {
  2750. $color = "orange";
  2751. }
  2752.  
  2753. return '<font color="' . $color . '">' . htmlentities($user) . '</font>';
  2754. }
  2755.  
  2756. private function swapSides() {
  2757. if ($this->side['team_a'] == "ct") {
  2758. $this->side['team_a'] = "t";
  2759. $this->side['team_b'] = "ct";
  2760. } else {
  2761. $this->side['team_a'] = "ct";
  2762. $this->side['team_b'] = "t";
  2763. }
  2764. $this->currentMap->setCurrentSide($this->side["team_a"], true);
  2765. }
  2766.  
  2767. private function getLogAdminFilePath() {
  2768. return Logger::getInstance()->getLogPathAdmin() . "/match-" . $this->matchData["id"] . ".html";
  2769. }
  2770.  
  2771. private function getLogFilePath() {
  2772. return Logger::getInstance()->getLogPath() . "/match-" . $this->matchData["id"] . ".html";
  2773. }
  2774.  
  2775. public function __call($name, $arguments) {
  2776. $this->addLog("Call to inexistant function $name", Logger::ERROR);
  2777. }
  2778.  
  2779. public function adminStopNoRs() {
  2780. $this->addLog("Match stopped by admin");
  2781. $this->addMatchLog("Match stopped by admin");
  2782. $this->say("#redMatch stopped by admin");
  2783.  
  2784. $this->rcon->send("mp_teamname_1 \"\"; mp_teamflag_2 \"\";");
  2785. $this->rcon->send("mp_teamname_2 \"\"; mp_teamflag_1 \"\";");
  2786. $this->rcon->send("exec server.cfg");
  2787.  
  2788.  
  2789. mysql_query("UPDATE `matchs` SET enable = 0, auto_start = 0 WHERE id = '" . $this->match_id . "'");
  2790. $this->needDel = true;
  2791. return true;
  2792. }
  2793.  
  2794. public function adminStop() {
  2795. $this->addLog("Match stopped by admin");
  2796. $this->addMatchLog("Match stopped by admin");
  2797. $this->say("#redMatch stopped by admin");
  2798.  
  2799. $this->rcon->send("mp_restartgame 1");
  2800.  
  2801. $this->rcon->send("exec server.cfg");
  2802. $this->rcon->send("mp_teamname_1 \"\"; mp_teamname_2 \"\"; mp_teamflag_1 \"\"; mp_teamflag_2 \"\"");
  2803.  
  2804. mysql_query("UPDATE `matchs` SET enable = 0, auto_start = 0 WHERE id = '" . $this->match_id . "'");
  2805. $this->needDel = true;
  2806. return true;
  2807. }
  2808.  
  2809. public function adminPassKnife() {
  2810. if ($this->getStatus() == self::STATUS_WU_KNIFE) {
  2811. $this->addLog("Knife has been skipped by the admin");
  2812. $this->addMatchLog("Knife has been skipped by the admin");
  2813. $this->say("#redKnife has been skipped by the admin");
  2814.  
  2815. $this->ready["ct"] = false;
  2816. $this->ready["t"] = false;
  2817. $this->currentMap->setStatus(Map::STATUS_WU_1_SIDE, true);
  2818. $this->setStatus(self::STATUS_WU_1_SIDE, true);
  2819. if (\eBot\Config\Config::getInstance()->getConfigKnifeMethod() == "knifestart")
  2820. $this->forceRoundStartRecord = true;
  2821. return true;
  2822. }
  2823. }
  2824.  
  2825. public function adminExecuteCommand($command) {
  2826. $reply = $this->rcon->send($command);
  2827. return $reply;
  2828. }
  2829.  
  2830. public function adminSkipMap() {
  2831. $backupMap = $this->currentMap;
  2832. $this->currentMap = null;
  2833. if ($backupMap->getMapsFor() == "team1") {
  2834. $mapFor = "team2";
  2835. } elseif ($backupMap->getMapsFor() == "team2") {
  2836. $mapFor = "default";
  2837. }
  2838.  
  2839. foreach ($this->maps as $map) {
  2840. if ($map->getMapsFor() == $mapFor) {
  2841. if ($map->getStatus() == Map::STATUS_NOT_STARTED) {
  2842. $this->currentMap = $map;
  2843. break;
  2844. }
  2845. }
  2846. }
  2847. foreach ($this->maps as $map) {
  2848. if ($map->getStatus() == Map::STATUS_NOT_STARTED) {
  2849. if ($map->getMapsFor() == $mapFor) {
  2850. $this->currentMap = $map;
  2851. break;
  2852. }
  2853. }
  2854. }
  2855.  
  2856. if ($this->currentMap != null) {
  2857. $this->currentMap->setStatus(Map::STATUS_STARTING, true);
  2858. $this->setStatus(self::STATUS_STARTING, true);
  2859. \mysql_query("UPDATE `matchs` SET `current_map` = '" . $this->currentMap->getMapId() . "' WHERE `id` = '" . $this->match_id . "'");
  2860.  
  2861. Logger::debug("Setting need knife round on map");
  2862. $this->currentMap->setNeedKnifeRound(true);
  2863. $this->nbOT = 0;
  2864. $this->score["team_a"] = 0;
  2865. $this->score["team_b"] = 0;
  2866.  
  2867. $this->addLog("Engaging next map " . $this->currentMap->getMapName());
  2868. $this->addMatchLog("Engaging next map " . $this->currentMap->getMapName());
  2869. $time = microtime(true);
  2870. $this->timeEngageMap = $time;
  2871. $this->addLog("Skipping Map");
  2872. TaskManager::getInstance()->addTask(new Task($this, self::TASK_ENGAGE_MAP, $time));
  2873. } else {
  2874. $this->setStatus(self::STATUS_END_MATCH, true);
  2875. Logger::error("Not map found");
  2876. $this->addLog("Match is closed");
  2877. }
  2878. return true;
  2879. }
  2880.  
  2881. public function adminFixSides() {
  2882. $this->swapSides();
  2883. $this->sendTeamNames();
  2884. $this->addLog("Hot swapping sides");
  2885. return true;
  2886. }
  2887.  
  2888. public function adminStreamerReady() {
  2889. if ($this->config_streamer) {
  2890. $this->streamerReady = true;
  2891. if (($this->getStatus() == self::STATUS_WU_1_SIDE) || ($this->getStatus() == self::STATUS_WU_KNIFE)) {
  2892. $this->say("\002Streamers are ready now! \001Please confirm, that you are ready too: !ready");
  2893. }
  2894. }
  2895. else
  2896. $this->streamerReady = false;
  2897. return true;
  2898. }
  2899.  
  2900. public function adminForceKnife() {
  2901. if ($this->getStatus() == self::STATUS_WU_KNIFE) {
  2902. $this->addLog("Knife has been forced by the admin");
  2903. $this->addMatchLog("Knife has been forced by the admin");
  2904. $this->say("#redKnife has been forced by the admin");
  2905.  
  2906. $this->ready["ct"] = true;
  2907. $this->ready["t"] = true;
  2908.  
  2909. $this->startMatch();
  2910. return true;
  2911. }
  2912. }
  2913.  
  2914. public function adminForceKnifeEnd() {
  2915. if ($this->getStatus() == self::STATUS_KNIFE) {
  2916. $this->addLog("Knife has been skipped by the admin");
  2917. $this->addMatchLog("Knife has been skipped by the admin");
  2918. $this->say("#redKnife has been skipped by the admin");
  2919.  
  2920. $this->ready["ct"] = false;
  2921. $this->ready["t"] = false;
  2922. $this->currentMap->setStatus(Map::STATUS_WU_1_SIDE, true);
  2923. $this->setStatus(self::STATUS_WU_1_SIDE, true);
  2924. return true;
  2925. }
  2926. }
  2927.  
  2928. public function adminForceStart() {
  2929. if ($this->isWarmupRound()) {
  2930. $this->addLog("The match has been forced by the admin");
  2931. $this->addMatchLog("The match has been forced by the admin");
  2932. $this->say("#redThe match has been forced by the admin");
  2933.  
  2934. $this->ready["ct"] = true;
  2935. $this->ready["t"] = true;
  2936.  
  2937. $this->startMatch();
  2938. return true;
  2939. }
  2940. }
  2941.  
  2942. public function adminPauseUnpause() {
  2943. if ($this->isMatchRound() && $this->isPaused) {
  2944. $this->isPaused = false;
  2945. $this->say("Match is unpaused by admin, live !");
  2946. $this->addMatchLog("Unpausing match by admin");
  2947. $this->addLog('Match is unpaused!');
  2948. $this->rcon->send("pause");
  2949. \mysql_query("UPDATE `matchs` SET `is_paused` = '0' WHERE `id` = '" . $this->match_id . "'");
  2950. $this->websocket['match']->sendData(json_encode(array('message' => 'status', 'content' => 'is_unpaused', 'id' => $this->match_id)));
  2951.  
  2952. $this->pause["ct"] = false;
  2953. $this->pause["t"] = false;
  2954. $this->unpause["ct"] = false;
  2955. $this->unpause["t"] = false;
  2956. return true;
  2957. } elseif ($this->isMatchRound() && !$this->isPaused) {
  2958. $this->isPaused = true;
  2959. $this->say("Match is paused by admin");
  2960. $this->say("Write !unpause to remove the pause when ready");
  2961. $this->addMatchLog("Pausing match by admin");
  2962. $this->addLog('Match is paused!');
  2963. $this->rcon->send("pause");
  2964. \mysql_query("UPDATE `matchs` SET `is_paused` = '1' WHERE `id` = '" . $this->match_id . "'");
  2965. $this->websocket['match']->sendData(json_encode(array('message' => 'status', 'content' => 'is_paused', 'id' => $this->match_id)));
  2966.  
  2967. $this->pause["ct"] = false;
  2968. $this->pause["t"] = false;
  2969. $this->unpause["ct"] = false;
  2970. $this->unpause["t"] = false;
  2971. return true;
  2972. }
  2973. }
  2974.  
  2975. public function adminStopBack() {
  2976. if ($this->isMatchRound()) {
  2977. $this->addLog("The match has been stopped by the admin");
  2978. $this->addMatchLog("The match has been stopped by the admin");
  2979. $this->say("#redThe match has been stopped by the admin");
  2980. $this->say("#redBack to warmup");
  2981.  
  2982. $this->stop["ct"] = true;
  2983. $this->stop["t"] = true;
  2984.  
  2985. $this->stopMatch();
  2986. return true;
  2987. }
  2988. }
  2989.  
  2990. public function adminGoBackRounds($round) {
  2991. $this->enable = false;
  2992. $sql = mysql_query("SELECT * FROM round_summary WHERE match_id = '" . $this->match_id . "' AND map_id = '" . $this->currentMap->getMapId() . "' AND round_id = $round");
  2993. $req = mysql_fetch_array($sql);
  2994.  
  2995. $backup = $req['backup_file_name'];
  2996.  
  2997. $this->addLog("Admin backup round $round");
  2998. $this->addLog("Backup file " . $backup);
  2999.  
  3000. $this->stop["ct"] = false;
  3001. $this->stop["t"] = false;
  3002. if ($this->isPaused) {
  3003. $this->rcon->send("pause");
  3004. $this->isPaused = false;
  3005. $this->addLog("Disabling pause");
  3006. \mysql_query("UPDATE `matchs` SET `is_paused` = '0' WHERE `id` = '" . $this->match_id . "'");
  3007. $this->websocket['match']->sendData(json_encode(array('message' => 'status', 'content' => 'is_unpaused', 'id' => $this->match_id)));
  3008. }
  3009.  
  3010. $this->score["team_a"] = $req['score_a'];
  3011. $this->score["team_b"] = $req['score_b'];
  3012.  
  3013. @mysql_query("UPDATE `matchs` SET score_a = '" . $this->score["team_a"] . "', score_b ='" . $this->score["team_b"] . "' WHERE id='" . $this->match_id . "'");
  3014.  
  3015. // To check with overtime
  3016. if ($this->score["team_a"] + $this->score["team_b"] < $this->matchData["max_round"]) {
  3017. $score = $this->currentMap->getCurrentScore();
  3018. if ($score != null) {
  3019. $score->setScore1Side1($this->score['team_a']);
  3020. $score->setScore2Side1($this->score['team_b']);
  3021. $score->setScore1Side2(0);
  3022. $score->setScore2Side2(0);
  3023. $score->saveScore();
  3024. }
  3025. $this->currentMap->calculScores();
  3026. } else {
  3027. $score = $this->currentMap->getCurrentScore();
  3028. if ($score != null) {
  3029. $score->setScore1Side2($this->score['team_a'] - $score->getScore1Side1());
  3030. $score->setScore2Side2($this->score['team_b'] - $score->getScore2Side1());
  3031. $score->saveScore();
  3032. }
  3033. $this->currentMap->calculScores();
  3034. }
  3035.  
  3036. // Sending roundbackup format file
  3037. $this->rcon->send("mp_backup_round_file \"ebot_" . $this->match_id . "\"");
  3038.  
  3039. // Prevent the halftime pausetimer
  3040. $this->rcon->send("mp_halftime_pausetimer 0");
  3041.  
  3042. // Sending restore
  3043. $this->rcon->send("mp_backup_restore_load_file " . $backup);
  3044.  
  3045. // Prevent a bug for double stop
  3046. $this->rcon->send("mp_backup_round_file_last " . $backup);
  3047.  
  3048. foreach ($this->players as &$player) {
  3049. $player->restoreSnapshot($this->getNbRound() - 1);
  3050. }
  3051.  
  3052. // Determine status
  3053. $status = false;
  3054. $total = $this->score["team_a"] + $this->score["team_b"];
  3055. if ($total < $this->matchData["max_round"]) {
  3056. $status = self::STATUS_FIRST_SIDE;
  3057. $statusMap = Map::STATUS_FIRST_SIDE;
  3058. } elseif ($total < $this->matchData["max_round"] * 2) {
  3059. $status = self::STATUS_SECOND_SIDE;
  3060. $statusMap = Map::STATUS_SECOND_SIDE;
  3061. } else {
  3062. if ($this->config_ot) {
  3063. $total -= $this->matchData["max_round"] * 2;
  3064. $total_rest = $total % $this->ot_maxround * 2;
  3065. if ($total_rest < $this->ot_maxround) {
  3066. $status = self::STATUS_OT_FIRST_SIDE;
  3067. $statusMap = Map::STATUS_OT_FIRST_SIDE;
  3068. } else {
  3069. $status = self::STATUS_OT_SECOND_SIDE;
  3070. $statusMap = Map::STATUS_OT_SECOND_SIDE;
  3071. }
  3072. }
  3073. }
  3074.  
  3075. if ($status && $this->getStatus() != $status) {
  3076. $this->addLog("Setting match to another status: " . $status);
  3077. switch ($this->getStatus()) {
  3078. case self::STATUS_SECOND_SIDE:
  3079. if ($status == self::STATUS_FIRST_SIDE) {
  3080. $this->addLog("Swapping teams !");
  3081. $this->swapSides();
  3082. }
  3083. break;
  3084. case self::STATUS_OT_FIRST_SIDE:
  3085. if ($status == self::STATUS_FIRST_SIDE) {
  3086. $this->addLog("Swapping teams !");
  3087. $this->swapSides();
  3088. }
  3089. break;
  3090. case self::STATUS_OT_SECOND_SIDE:
  3091. if ($status == self::STATUS_OT_FIRST_SIDE) {
  3092. $this->addLog("Swapping teams !");
  3093. $this->swapSides();
  3094. }
  3095.  
  3096. if ($status == self::STATUS_SECOND_SIDE) {
  3097. $this->addLog("Swapping teams !");
  3098. $this->swapSides();
  3099. }
  3100. break;
  3101. }
  3102. $this->setStatus($status, true);
  3103. $this->currentMap->setStatus($statusMap, true);
  3104. }
  3105.  
  3106. $this->say("Round restored, going live !");
  3107. \mysql_query("UPDATE `matchs` SET ingame_enable = 1 WHERE id='" . $this->match_id . "'") or $this->addLog("Can't update ingame_enable", Logger::ERROR);
  3108. TaskManager::getInstance()->addTask(new Task($this, self::SET_LIVE, microtime(true) + 2));
  3109. return true;
  3110. }
  3111.  
  3112. private function sendTeamNames() {
  3113. if ($this->currentMap->getCurrentSide() == "ct") {
  3114. $this->rcon->send("mp_teamname_1 \"" . $this->teamAName . "\"");
  3115. $this->rcon->send("mp_teamname_2 \"" . $this->teamBName . "\"");
  3116. $this->rcon->send("mp_teamflag_1 \"" . $this->teamAFlag . "\"");
  3117. $this->rcon->send("mp_teamflag_2 \"" . $this->teamBFlag . "\"");
  3118. } else {
  3119. $this->rcon->send("mp_teamname_2 \"" . $this->teamAName . "\"");
  3120. $this->rcon->send("mp_teamname_1 \"" . $this->teamBName . "\"");
  3121. $this->rcon->send("mp_teamflag_2 \"" . $this->teamAFlag . "\"");
  3122. $this->rcon->send("mp_teamflag_1 \"" . $this->teamBFlag . "\"");
  3123. }
  3124. }
  3125.  
  3126. private function getRoundTime() {
  3127. return time() - $this->timeRound;
  3128. }
  3129.  
  3130. public function getIdentifier() {
  3131. return @$this->matchData["identifier_id"];
  3132. }
  3133.  
  3134. public function getMatchId() {
  3135. return @$this->matchData["id"];
  3136. }
  3137.  
  3138. public function getCurrentMapId() {
  3139. return $this->currentMap->getMapId();
  3140. }
  3141.  
  3142. }
  3143.  
  3144. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement