This repository has been archived on 2024-07-18. You can view files and clone it, but cannot push or open issues or pull requests.
lwb5/scripts/site/beta5/handlers/techtrade.inc

490 lines
14 KiB
PHP

<?php
class page_handler {
/* Engine data */
public $needsAuth = true;
public $ajax = array(
"func" => 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();
}
}
?>