/** * {@inheritdoc} * * @param \Match $match */ public function update($form, $match) { if ($match->getDuration() != $form->get('duration')->getData() || $match->getTimestamp()->ne($form->get('time')->getData())) { // The timestamp of the match was changed, we might need to // recalculate its ELO $this->controller->recalculateNeeded = true; } $firstTeam = $form->get('first_team'); $secondTeam = $form->get('second_team'); $serverInfo = $this->getServerInfo($form->get('server_address')); $match->setTeamPlayers($this->getPlayerList($firstTeam), $this->getPlayerList($secondTeam)); $match->setTeamPoints($firstTeam->get('score')->getData(), $secondTeam->get('score')->getData()); $match->setDuration($form->get('duration')->getData())->setServerAddress($serverInfo[0], $serverInfo[1])->setTimestamp($form->get('time')->getData())->setMap($form->get('map')->getData()->getId()); if (!$match->isEloCorrect()) { $this->controller->recalculateNeeded = true; } }
/** * Recalculates match history for all teams and matches * * Recalculation is done as follows: * 1. A match is chosen as a starting point - it's stored old team ELOs are * considered correct * 2. Team ELOs are reset to their values at the starting point * 3. Each match that occurred since the first specified match has its ELO * recalculated based on the current team values, and the new match data * and team ELOs are stored in the database * * @param Match $match The first match */ private function recalculate(Match $match) { try { // Commented out to prevent ridiculously large recalculations //set_time_limit(0); $query = Match::getQueryBuilder()->where('status')->notEquals('deleted')->where('type')->equals(Match::OFFICIAL)->where('time')->isAfter($match->getTimestamp(), $inclusive = true)->sortBy('time'); /** @var Match[] $matches */ $matches = $query->getModels($fast = true); // Send the total count to client-side javascript $this->log(count($matches) . "\n"); // Start a transaction so tables are locked and we don't stay with // messed up data if something goes wrong Database::getInstance()->startTransaction(); $teamsReset = []; // Reset match teams, in case the selected match is deleted and does // not show up in the list of matches to recalculate $match->getTeamA()->setElo($match->getTeamAEloOld()); $match->getTeamB()->setElo($match->getTeamBEloOld()); $teamsReset[$match->getTeamA()->getId()] = true; $teamsReset[$match->getTeamB()->getId()] = true; foreach ($matches as $i => $match) { // Reset teams' ELOs if they haven't been reset already if (!isset($teamsReset[$match->getTeamA()->getId()])) { $teamsReset[$match->getTeamA()->getId()] = true; $match->getTeamA()->setElo($match->getTeamAEloOld()); } if (!isset($teamsReset[$match->getTeamB()->getId()])) { $teamsReset[$match->getTeamB()->getId()] = true; $match->getTeamB()->setElo($match->getTeamBEloOld()); } $match->recalculateElo(); // Send an update to the client-side javascript, so that a // progress bar can be updated $this->log("m"); } } catch (Exception $e) { Database::getInstance()->rollback(); Database::getInstance()->finishTransaction(); throw $e; } Database::getInstance()->finishTransaction(); $this->log("\n\nCalculation successful\n"); }
/** * Check whether or not a player been in a match or has logged on in the specified amount of time to be considered * active * * @return bool True if the player has been active */ public function hasBeenActive() { $this->lazyLoad(); $interval = Service::getParameter('bzion.miscellaneous.active_interval'); $lastLogin = $this->last_login->copy()->modify($interval); $hasBeenActive = TimeDate::now() <= $lastLogin; if ($this->last_match->isValid()) { $lastMatch = $this->last_match->getTimestamp()->copy()->modify($interval); $hasBeenActive = $hasBeenActive || TimeDate::now() <= $lastMatch; } return $hasBeenActive; }