array( // General information "getGeneralInfo", "getTechList", // Main page "getSubmitPage", "submitList", "sendOffer", // Requests page "getRequestsPage", "submitRequests", // Alliance-wide listing "getAllianceList", "setListOptions", // Viewing orders "getCurrentOrders", // Changing orders "getChangeOrdersData", "submitOrders" ), "init" => "new TechTrade(document.getElementById('init-data').value)" ); /* Valid pages */ static private $subPages = array( "Submit", "Req", "ViewList", "SOrders", "VOrders" ); /* Libraries */ private $pLib; private $aLib; private $rLib; /* Player information */ private $player; private $pInfo; private $vacation; private $alliance; private $hasRequests; private $accessLevel; /** This function initialises the libraries * and checks the current player's privileges * with regards to technology trading. */ private function init() { // Get libraries $this->pLib = $this->game->getLib('beta5/player'); $this->aLib = $this->game->getLib('beta5/alliance'); $this->rLib = $this->game->getLib('beta5/tech'); // Get player information $this->player = $_SESSION[game::sessName()]['player']; $this->pInfo = $this->pLib->call('get', $this->player); $this->vacation = $this->pLib->call('isOnVacation', $this->player); $this->alliance = $this->pInfo['aid']; $alInfo = $this->aLib->call('get', $this->alliance); $this->hasRequests = ($alInfo['enable_tt'] == 'R'); if (is_null($this->alliance)) { $this->accessLevel = 0; } else { $privileges = $this->aLib->call('getPrivileges', $this->player); $this->accessLevel = $privileges['tech_trade']; } } /** This method tries to set the current sub-page being viewed, accounting for * the user's privileges. */ private function currentPage($page = null) { // If we're not trying to change page or if we're trying to set an invalid page, // fetch the current page from the session. if (is_null($page) || !in_array($page, self::$subPages)) { $page = $_SESSION[game::sessName()]['tt_page']; } // Check privileges switch ($page) { case 'Submit': $ok = ($this->accessLevel > 0); break; case 'Req': $ok = ($this->accessLevel > 1 && $this->hasRequests); break; case 'ViewList': $ok = ($this->accessLevel > 2); break; case 'SOrders': $ok = ($this->accessLevel > 3); break; case 'VOrders': $ok = ($this->accessLevel > 3); break; default: $ok = false; break; } // If the privileges are invalid, set the page if (!$ok) { if ($this->accessLevel == 0) { $page = 'NoAccess'; } else { $page = 'Submit'; } } return ($_SESSION[game::sessName()]['tt_page'] = $page); } /*************************************************************************************** * General information retrieval * ***************************************************************************************/ /** This AJAX function reads the information about the player and returns * it. It allows the page to "know" what to display. */ public function getGeneralInfo() { // Initialise the handler $this->init(); // Get the current page $page = $this->currentPage(); $requests = ($this->hasRequests ? 1 : 0); return "$page#{$this->accessLevel}#$requests#{$this->alliance}#" . ($this->vacation ? 1 : 0); } /** This AJAX function returns the complete list of technologies as pairs * of ID / Name lines. */ public function getTechList() { // Prevent people from loading the list just for the sake of it if ($_SESSION[game::sessName()]['tt_list']) { return ""; } $_SESSION[game::sessName()]['tt_list'] = true; // Initialise the handler and get the language $this->init(); $language = getLanguage(); // Get the list $techList = $this->rLib->call('getAll', $language); // Create the result $result = array(); foreach ($techList as $id => $data) { $line = array($id, count($data['deps'])); $line = array_merge($line, $data['deps']); array_push($line, utf8entities($data['name'])); array_push($result, join('#', $line)); } return join("\n", $result); } /*************************************************************************************** * Submission / view orders page * ***************************************************************************************/ /** This is the actual method that generates the output for the submission page. */ private function __submitPage() { $result = array(); // Get last submission date list($canSubmit, $lastSubmission, $nextSubmission) = $this->aLib->call( 'getTechSubmission', $this->player); array_push($result, ($canSubmit ? 1 : 0) . "#$lastSubmission#$nextSubmission"); // Get orders list($sendWhat, $toWhom, $sDate, $oDate) = $this->aLib->call('getTechOrder', $this->player, true); if ($toWhom) { $toName = $this->pLib->call('getName', $toWhom); if (!$oDate) { $canSend = !($this->vacation || $this->rLib->call('checkOffer', $this->player)) ? 1 : 0; } else { $canSend = 0; } array_push($result, "$sDate#$oDate#$canSend#$sendWhat#$toWhom#" . utf8entities($toName)); } else { array_push($result, "-"); } list($getWhat, $fromWhom, $sDate, $oDate) = $this->aLib->call('getTechOrder', $this->player, false); if ($fromWhom) { $fromName = $this->pLib->call('getName', $fromWhom); array_push($result, "$sDate#$oDate#$getWhat#$fromWhom#" . utf8entities($fromName)); } else { array_push($result, "-"); } return join("\n", $result); } /** This AJAX function returns the contents for the submission page. */ public function getSubmitPage() { // Initialise page $this->init(); $page = $this->currentPage('Submit'); if ($page != 'Submit') { return "FU"; } return $this->__submitPage(); } /** This AJAX function submits a player's technology list to his alliance */ public function submitList() { // Initialise page $this->init(); $page = $this->currentPage('Submit'); if ($page != 'Submit') { return "FU"; } $result = array(); // Check if the player can submit list($canSubmit, $lastSubmission, $nextSubmission) = $this->aLib->call( 'getTechSubmission', $this->player); if ($this->vacation || ! $canSubmit) { return $this->__submitPage(); } // Submit the list $this->aLib->call('submitTechList', $this->player); return $this->__submitPage(); } /** This AJAX function causes a player to obey his tech trading order. */ public function sendOffer() { // Initialise page $this->init(); $page = $this->currentPage('Submit'); if ($page != 'Submit') { return "FU"; } $result = array(); // Check if the player can submit list($sendWhat, $toWhom, $sDate, $oDate) = $this->aLib->call('getTechOrder', $this->player, true); if ($toWhom) { $canSend = !($oDate || $this->vacation || $this->rLib->call('checkOffer', $this->player)); if ($canSend) { $this->rLib->call('makeOffer', $this->player, $toWhom, $sendWhat, 0); $this->aLib->call('obeyOrder', $this->player); } } return $this->__submitPage(); } /*************************************************************************************** * Player requests page * ***************************************************************************************/ /** This method generates the actual requests page data. */ private function __requestsPage() { // Get requests $requests = $this->aLib->call('getTechRequests', $this->player); // Get techs the player could request $requestable = $this->rLib->call('getAvailableTechs', $this->player); return join('#', $requests) . "\n" . join('#', $requestable); } /** This AJAX function returns the contents for the requests page. */ public function getRequestsPage() { // Initialise page $this->init(); $page = $this->currentPage('Req'); if ($page != 'Req') { return "FU"; } // Make sure the requests have been updated $this->aLib->call('updateRequests', $this->player); return $this->__requestsPage(); } /** This AJAX function updates a player's technology requests. */ public function submitRequests($requests = "") { // Initialise page $this->init(); $page = $this->currentPage('Req'); if ($page != 'Req') { return "FU"; } // Parse the list $requestable = $this->rLib->call('getAvailableTechs', $this->player); $rawList = explode('#', $requests); $list = array(); foreach ($rawList as $techID) { $techID = (int) $techID; if (in_array($techID, $list) || !in_array($techID, $requestable)) { continue; } array_push($list, $techID); } // Make sure the requests have been updated $this->aLib->call('setTechRequests', $this->player, $list); return $this->__requestsPage(); } /*************************************************************************************** * Alliance tech list page * ***************************************************************************************/ public function __allianceList() { // Get the list itself $aList = $this->aLib->call('getTechList', $this->alliance, $this->hasRequests); // Generate the output string $result = array(count($aList)); foreach ($aList as $player => $techData) { array_push($result, "$player#{$techData['vacation']}#{$techData['submitted']}#" . "{$techData['restrict']}#" . count($techData['list']) . "#" . utf8entities($this->pLib->call('getName', $player))); foreach ($techData['list'] as $tech => $status) { array_push($result, "$tech#$status"); } if (is_null($techData['requests'])) { array_push($result, ""); } else { array_push($result, join('#', $techData['requests'])); } } return join("\n", $result); } public function getAllianceList($oldMD5 = "") { // Initialise page $this->init(); $page = $this->currentPage('ViewList'); if ($page != 'ViewList') { return "FU"; } $rVal = $this->__allianceList(); $newMD5 = md5($rVal); $nTechs = prefs::get("beta5/ttTechs", 10); $nPlayers = prefs::get("beta5/ttPlayers", 3); return ($oldMD5 == $newMD5) ? "NC" : "$newMD5\n$nTechs#$nPlayers\n$rVal"; } public function setListOptions($playersPerPage, $techsPerPage) { // Initialise page $this->init(); $page = $this->currentPage('ViewList'); if ($page != 'ViewList') { return; } $ppp = min(10, max(2, (int) $playersPerPage)); prefs::set("beta5/ttPlayers", $ppp); $tpp = min(8, max(1, floor((int) $techsPerPage / 10))) * 10; prefs::set("beta5/ttTechs", $tpp); } /*************************************************************************************** * Order viewing and management * ***************************************************************************************/ private function __getOrders() { // Get list of orders $orders = $this->aLib->call('getTechOrders', $this->alliance, $this->hasRequests); // Generate output $result = array(); foreach ($orders as $player => $pRecord) { $pName = $this->pLib->call('getName', $player); array_push($result, "$player#{$pRecord['sendTo']}#{$pRecord['sendTech']}" ."#{$pRecord['sendSub']}#{$pRecord['sendDone']}" . "#{$pRecord['recvFrom']}#{$pRecord['recvTech']}" . "#{$pRecord['recvSub']}#{$pRecord['recvDone']}#" . utf8entities($pName)); } return join("\n", $result); } public function getCurrentOrders($oldMD5 = "") { // Initialise page $this->init(); $page = $this->currentPage('VOrders'); if ($page != 'VOrders') { return; } $rVal = $this->__getOrders(); $newMD5 = md5($rVal); return ($oldMD5 == $newMD5) ? "NC" : "$newMD5\n$rVal"; } public function getChangeOrdersData($oldMD5 = "") { // Initialise page $this->init(); $page = $this->currentPage('SOrders'); if ($page != 'SOrders') { return "FU"; } list($lastSet, $nextSet) = $this->aLib->call('getLatestTechOrders', $this->alliance); $rVal = "$lastSet#$nextSet"; if ($nextSet == 0) { $rVal .= "\n" . $this->__allianceList(); } $newMD5 = md5($rVal); return ($oldMD5 == $newMD5) ? "NC" : "$newMD5\n$rVal"; } public function submitOrders($orderString) { // Initialise page $this->init(); $page = $this->currentPage('SOrders'); if ($page != 'SOrders') { return "FU"; } // If the order string is not empty, extract orders $pfx = ''; if ($orderString != '') { $oList = explode('!', $orderString); $orders = array(); foreach ($oList as $oText) { $order = explode('#', $oText); if (count($order) != 3) { $pfx = "ERR"; break; } $order[0] = (int)$order[0]; $order[1] = (int)$order[1]; $order[2] = (int)$order[2]; $id = array_shift($order); if (array_key_exists($id, $orders)) { $pfx = "ERR"; break; } $orders[$id] = $order; } if ($pfx == '') { $pfx = $this->aLib->call('submitTechOrders', $this->alliance, $orders) ? '' : 'ERR'; } } else { $pfx = 'ERR'; } list($lastSet, $nextSet) = $this->aLib->call('getLatestTechOrders', $this->alliance); $rVal = "$lastSet#$nextSet"; if ($nextSet == 0) { $rVal .= "\n" . $this->__allianceList(); } $pfx .= md5($rVal); return "$pfx\n$rVal"; } /*************************************************************************************** * Main page handler * ***************************************************************************************/ public function handle($input) { $_SESSION[game::sessName()]['tt_list'] = false; $this->output = "techtrade"; $this->data = $this->getGeneralInfo(); } } ?>