Advertisement
Guest User

Untitled

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