/** * Create a clean new game to apply the test to * * @var string $testID The test ID */ function __construct($testID) { global $DB, $Game, $Variant; /* * Create a clean new game to apply the test to */ $this->testID = $testID; list($id) = $DB->sql_row("SELECT id FROM wD_Games WHERE name='DATC-Adjudicator-Test'"); if ($id) { $DB->sql_put("UPDATE wD_Games SET phase = 'Diplomacy', turn = " . $testID . ", gameOver = 'No' WHERE id = " . $id); } else { $Game = processGame::create(1, 'DATC-Adjudicator-Test', '', 5, 'Winner-takes-all', 30, 30, 'No', 'Regular'); $id = $Game->id; $DB->sql_put("UPDATE wD_Games SET phase = 'Diplomacy', turn = " . $testID . " WHERE id = " . $id); } if (!isset($_REQUEST['DATCResults'])) { self::wipe($id); $countries = array(); for ($i = 1; $i <= count($Variant->countries); $i++) { $countries[] = $i; } $DB->sql_put("INSERT INTO wD_Members (gameID, userID, countryID, bet, timeLoggedIn)\r\n\t\t\t\t\tVALUES " . Database::packArray("(" . $id . ", 2, ", $countries, ", 5, " . time() . ")", ",")); } parent::__construct($id); $GLOBALS['Game'] = $this; $Game = $this; }
protected function changePhase() { if ($this->phase == 'Pre-game') { // Builds first after the game starts $this->setPhase('Builds'); // This gives the map some color to start with $this->archiveTerrStatus(); return false; } elseif ($this->phase == 'Builds' && $this->turn == 0) { // The first Spring builds just finished, make sure we don't go to the next turn $this->phase = 'Pre-game'; // This prevents a turn being added on in setPhase, keeping it in Spring, 1901 // (It won't activate twice because the next time it won't go into a Builds phase in Spring) $this->setPhase('Diplomacy'); // Diplomacy, Spring 1901, and from then on like nothing was different $this->archiveTerrStatus(); return false; } else { return parent::changePhase(); } // Except those two phases above behave normally }
public function wipeDATCTestGame(array $params) { global $DB; require_once 'gamemaster/game.php'; $DB->sql_put("BEGIN"); list($gameID) = $DB->sql_row("SELECT id FROM wD_Games WHERE name='DATC-Adjudicator-Test'"); processGame::eraseGame($gameID); $DB->sql_put("COMMIT"); return l_t("DATC test game and associated data removed."); }
public function banUser(array $params) { global $User, $DB, $Game; $userID = (int) $params['userID']; if (!isset($params['reason']) || strlen($params['reason']) == 0) { return l_t('Couldn\'t ban user; no reason was given.'); } $banReason = $DB->msg_escape($params['reason']); $banUser = new User($userID); if ($banUser->type['Banned']) { throw new Exception(l_t("The user is already banned")); } if ($banUser->type['Admin']) { throw new Exception(l_t("Admins can't be banned")); } if ($banUser->type['Moderator'] and !$User->type['Admin']) { throw new Exception(l_t("Moderators can't be banned by non-admins")); } User::banUser($userID, l_t("Banned by a moderator:") . ' ' . $params['reason']); require_once l_r('gamemaster/game.php'); /* * Explain what has happened to the games the banned user was in, and extend the * turn */ $tabl = $DB->sql_tabl("SELECT gameID, status FROM wD_Members\r\n\t\t\t\t\tWHERE userID = " . $userID); while (list($gameID, $status) = $DB->tabl_row($tabl)) { if ($status != 'Playing') { continue; } $Variant = libVariant::loadFromGameID($gameID); $Game = $Variant->processGame($gameID); $banMessage = l_t('%s was banned: %s. ', $banUser->username, $banReason); if ($Game->phase == 'Pre-game') { if (count($Game->Members->ByID) == 1) { processGame::eraseGame($Game->id); } else { $DB->sql_put("DELETE FROM wD_Members WHERE gameID = " . $Game->id . " AND userID = " . $userID); } } elseif ($Game->processStatus != 'Paused' and $Game->phase != 'Finished') { // The game may need a time extension to allow for a new player to be added // Would the time extension would give a difference of more than ten minutes? If not don't bother if (time() + $Game->phaseMinutes * 60 - $Game->processTime > 10 * 60) { // It is worth adding an extension $DB->sql_put("UPDATE wD_Games\r\n\t\t\t\t\t\tSET processTime = " . time() . " + phaseMinutes*60\r\n\t\t\t\t\t\tWHERE id = " . $Game->id); $Game->processTime = time() + $Game->phaseMinutes * 60; $banMessage .= l_t('The time until the next phase has been extended by one phase length ' . 'to give an opportunity to replace the player.') . "\n" . l_t('Remember to finalize your orders if you don\'t want ' . 'to wait, so the game isn\'t held up unnecessarily!'); } } // IF the game is still running first remove the player from the game and reset the minimum bet so other can join. if ($Game->phase != 'Finished' && $Game->phase != 'Pre-game') { $Game->Members->ByUserID[$userID]->setLeft(1); $Game->resetMinimumBet(); } libGameMessage::send('Global', 'GameMaster', $banMessage); $Game->Members->sendToPlaying('No', l_t('%s was banned, see in-game for details.', $banUser->username)); } $DB->sql_put("UPDATE wD_Orders o INNER JOIN wD_Members m ON ( m.gameID = o.gameID AND m.countryID = o.countryID )\r\n\t\t\t\t\tSET o.toTerrID = NULL, o.fromTerrID = NULL\r\n\t\t\t\t\tWHERE m.userID = " . $userID); unset($Game); return l_t('This user was banned, and had their %s points removed and their games set to civil disorder.', $banUser->points); }
$input['drawType'] = 'draw-votes-hidden'; break; default: $input['drawType'] = 'draw-votes-public'; break; } $input['minimumReliabilityRating'] = (int) $input['minimumReliabilityRating']; if ($input['minimumReliabilityRating'] < 0 or $input['minimumReliabilityRating'] > 100) { throw new Exception(l_t("The reliability rating threshold must range from 0-100")); } if ($input['minimumReliabilityRating'] > $User->reliabilityRating) { throw new Exception(l_t("Your reliability rating is %s%%, so you can't create a game which requires players to have a RR of %s%% or greater.", $User->reliabilityRating, $input['minimumReliabilityRating'])); } // Create Game record & object require_once l_r('gamemaster/game.php'); $Game = processGame::create($input['variantID'], $input['name'], $input['password'], $input['bet'], $input['potType'], $input['phaseMinutes'], $input['joinPeriod'], $input['anon'], $input['pressType'], $input['missingPlayerPolicy'], $input['drawType'], $input['minimumReliabilityRating']); // Create first Member record & object processMember::create($User->id, $input['bet']); $Game->Members->joinedRedirect(); } catch (Exception $e) { print '<div class="content">'; print '<p class="notice">' . $e->getMessage() . '</p>'; print '</div>'; } } if ($User->points >= 5) { $roundedDefault = round($User->points / 7 / 10) * 10; if ($roundedDefault > 5) { $defaultPoints = $roundedDefault; } else { $defaultPoints = 5;
public function cancelGame(array $params) { global $DB, $Game; $gameID = (int) $this->fixedGameID; $DB->sql_put("BEGIN"); require_once l_r('gamemaster/game.php'); $Variant = libVariant::loadFromGameID($gameID); $Game = $Variant->processGame($gameID); if ($Game->phase == 'Diplomacy' or $Game->phase == 'Retreats' or $Game->phase == 'Builds') { $Game->setCancelled(); // This throws an exception, since it expects to be run from within the // main gamemaster loop, and wants to stop the loop from continuing to use this game after // it has been cancelled. But it also contains its own commit, so the exception does not prevent // the game from being cancelled (it is messy though). // This point after $Game->setCancelled(); shouldn't actually be reached. } elseif ($Game->phase == 'Finished') { /* * Some special action is needed; this game has already finished. * * We need to get back all winnings that have been distributed first, then we need to * return all starting bets. */ $transactions = array(); $sumPoints = 0; // Used to ensure the total points transactions add up roughly to 0 $tabl = $DB->sql_tabl("SELECT type, points, userID, memberID FROM wD_PointsTransactions WHERE gameID = " . $Game->id . " FOR UPDATE"); // Lock it for update, so other transactions can't interfere with these ones while (list($type, $points, $userID, $memberID) = $DB->tabl_row($tabl)) { if (!isset($transactions[$userID])) { $transactions[$userID] = array(); } if (!isset($transactions[$userID][$type])) { $transactions[$userID][$type] = 0; } if ($type != 'Bet') { $points = $points * -1; } // Bets are to be credited back, everything else is to be debited if ($type != 'Supplement') { $sumPoints += $points; } $transactions[$userID][$type] += $points; } // Check that the total points transactions within this game make sense (i.e. they add up to roughly 0 accounting for rounding errors) if ($sumPoints < count($transactions) * -1 or count($transactions) < $sumPoints) { throw new Exception(l_t("The total points transactions (in a finished game) add up to %s, but there are %s members; " . "cannot cancel game with an unusual points transaction log.", $sumPoints, count($transactions)), 274); } // The points transactions make sense; we can now try and reverse them. // Get the current points each user has $tabl = $DB->sql_tabl("SELECT u.id, u.points FROM wD_Users u INNER JOIN wD_PointsTransactions pt ON pt.userID = u.id WHERE pt.gameID = " . $Game->id . " GROUP BY u.id, u.points " . " FOR UPDATE"); // Lock it for update, so other transactions can't interfere with these ones $pointsInAccount = array(); $pointsInPlay = array(); while (list($userID, $points) = $DB->tabl_row($tabl)) { $sumPoints = 0; foreach ($transactions[$userID] as $type => $typePoints) { $sumPoints += $typePoints; } if ($points + $sumPoints < 0) { // If the user doesn't have enough points on hand to pay back the points transactions for this game we will need to supplement him the points to do it: $supplementPoints = -($points + $sumPoints); $points += $supplementPoints; $DB->sql_put("INSERT INTO wD_PointsTransactions ( type, points, userID, gameID ) VALUES ( 'Supplement', " . $supplementPoints . ", " . $userID . ", " . $Game->id . ")"); $DB->sql_put("UPDATE wD_Users SET points = " . $points . " WHERE id = " . $userID); } // Now we have given the user enough points so their points transactions for this game can definitely be undone: $DB->sql_put("INSERT INTO wD_PointsTransactions ( type, points, userID, gameID ) VALUES ( 'Correction', " . $sumPoints . ", " . $userID . ", " . $Game->id . ")"); $points += $sumPoints; $DB->sql_put("UPDATE wD_Users SET points = " . $points . " WHERE id = " . $userID); // Now check that they don't need a supplement to bring their total points in play back up to 100: $pointsInPlay = User::pointsInPlay($userID); if ($points + $pointsInPlay < 100) { $supplementPoints = 100 - ($points + $pointsInPlay); $points += $supplementPoints; $DB->sql_put("INSERT INTO wD_PointsTransactions ( type, points, userID, gameID ) VALUES ( 'Supplement', " . $supplementPoints . ", " . $userID . ", " . $Game->id . ")"); $DB->sql_put("UPDATE wD_Users SET points = " . $points . " WHERE id = " . $userID); } notice::send($userID, $Game->id, 'Game', 'No', 'No', l_t("This game has been cancelled after having finished (usually to undo the effects of cheating). " . "%s points had to be added/taken from your account to undo the effects of the game. " . "Please contact the mod team with any queries.", $sumPoints, $points), $Game->name, $Game->id); } // Now backup and erase the game from existence, then commit: processGame::eraseGame($Game->id); } else { throw new Exception(l_t('This game is in phase %s, so it can\'t be cancelled', $Game->phase), 987); } // $DB->sql_put("COMMIT"); // $ return l_t('This game was cancelled.'); }
foreach ($files as $file) { unlink($file); } } $DB->sql_put("UPDATE wD_DATC SET status = 'NotPassed' WHERE status = 'Passed'"); } unset($testID); // Determine the test ID to test list($testID) = $DB->sql_row("SELECT testID FROM wD_DATC\r\n\t\t\t\t\tWHERE status = 'NotPassed'\r\n\t\t\t\t\tORDER BY testID ASC LIMIT 1"); if (isset($_REQUEST['testID'])) { $testID = (int) $_REQUEST['testID']; } elseif (!isset($testID) or !$testID) { $DB->sql_put("BEGIN"); list($gameID) = $DB->sql_row("SELECT id FROM wD_Games WHERE name='DATC-Adjudicator-Test'"); if ($gameID) { processGame::eraseGame($gameID); } $DB->sql_put("COMMIT"); print '<p class="notice">' . l_t('There appear to be no more tests left! All tests have passed!') . ' <a href="datc.php?reset=on">' . l_t('Reset tests') . '</a></p>'; print '</div>'; print '<div class="content">'; return; } print '<div class="gamelistings-tabs"> <a href="datc.php?next=on">Next</a> <a href="datc.php?testID=' . $testID . '&verySlowStep=on&rand=' . rand(0, 99999) . '">' . l_t('Run first third') . '</a> <a href="datc.php?testID=' . $testID . '&slowStep=on&rand=' . rand(0, 99999) . '">' . l_t('Run first two thirds') . '</a> <a href="datc.php?testID=' . $testID . '&rand=' . rand(0, 99999) . '">' . l_t('Run full') . '</a> <a href="datc.php?testID=' . $testID . '&batchTest=' . rand(0, 99999) . '#map">' . l_t('Batch-test') . '</a> <a href="datc.php?reset=on">' . l_t('Reset all') . '</a> </div>';
/** * The game has been cancelled. Send messages, refund points, erase game. */ function setCancelled() { assert('$this->phase != "Finished"'); $this->Members->setCancelled(); processGame::eraseGame($this->id); // This will be caught by gamemaster.php throw new Exception("Cancelled", 12345); }