247 реда
6,5 КиБ
PHP
247 реда
6,5 КиБ
PHP
<?php
|
|
|
|
class display_engine {
|
|
|
|
private $document;
|
|
private $outputMode;
|
|
private $data;
|
|
|
|
function __construct() {
|
|
$this->document = new DomDocument('1.0', 'utf-8');
|
|
$this->outputMode = "xml";
|
|
}
|
|
|
|
function maintenance($maintenance) {
|
|
$this->data = new data_node('Maintenance');
|
|
$this->data->addContents(new data_leaf('Until', strftime("%Y-%m-%d %H:%M:%S", $maintenance['until'])));
|
|
$this->data->addContents(new data_leaf('Current', gmstrftime("%Y-%m-%d %H:%M:%S")));
|
|
$this->data->addContents(new data_leaf('Reason', $maintenance['reason']));
|
|
|
|
$this->rawOutput($this->genOutput('xml'));
|
|
}
|
|
|
|
|
|
function displayFatalError($code, $i, $i2) {
|
|
$this->data = new data_node('FatalError');
|
|
$this->data->setAttribute('code', $code);
|
|
$this->data->addContents(new data_leaf('Text', $i));
|
|
|
|
return $this->genOutput('xml');
|
|
}
|
|
|
|
|
|
private function loginFailed($code) {
|
|
$this->data = new data_node('Failed');
|
|
$this->data->setAttribute('code', $code);
|
|
$this->rawOutput($this->genOutput('xml'));
|
|
}
|
|
|
|
|
|
private function kicked($reason) {
|
|
$this->data = new data_node('Kicked');
|
|
$this->data->addContents(new data_leaf('Reason', $reason));
|
|
$this->rawOutput($this->genOutput('xml'));
|
|
}
|
|
|
|
|
|
function initSession() {
|
|
// Check for "single-shot" request
|
|
if (input::$input['__s'] == 1) {
|
|
$_SESSION = array();
|
|
return;
|
|
}
|
|
|
|
// FIXME: handle session, but why bother doing it when the whole thing will be rewritten?
|
|
}
|
|
|
|
|
|
function checkAuth() {
|
|
// Check authentication directly in "single-shot" mode
|
|
if (input::$input['__s'] == 1) {
|
|
$this->singleShotAuth(input::$input['__l'], input::$input['__p']);
|
|
$this->outputMode = "lw";
|
|
return;
|
|
}
|
|
|
|
// FIXME: handle authentication, but why bother doing it when the whole thing will be rewritten?
|
|
}
|
|
|
|
|
|
private function singleShotAuth($login, $password) {
|
|
// Check the account's login and password
|
|
if (!$this->checkAccountAuth($login, $password)) {
|
|
sleep(5);
|
|
$this->loginFailed(0);
|
|
}
|
|
|
|
// Make sure the account is in a valid state
|
|
$q = dbQuery("SELECT status,reason FROM account WHERE id={$_SESSION['userid']}");
|
|
if (!$q || dbCount($q) != 1) {
|
|
$this->loginFailed(1);
|
|
}
|
|
|
|
list($status,$reason) = dbFetchArray($q);
|
|
if ($status == 'KICKED') {
|
|
$this->kicked($reason);
|
|
} elseif ($status == 'QUIT' || $status == 'INAC') {
|
|
$this->loginFailed(2);
|
|
} elseif ($status == 'NEW') {
|
|
$this->loginFailed(3);
|
|
}
|
|
|
|
$_SESSION['authok'] = true;
|
|
if (!$this->checkVersionRegistration()) {
|
|
$this->loginFailed(4);
|
|
}
|
|
|
|
$this->singleShotLog();
|
|
}
|
|
|
|
|
|
private function checkAccountAuth($l, $p) {
|
|
$l1 = addslashes($l); $p1 = addslashes($p);
|
|
$q = "SELECT id,name,password FROM account WHERE lower(name)=lower('$l1')";
|
|
$qr = dbQuery($q);
|
|
|
|
if (!$qr || dbCount($qr) != 1) {
|
|
l::info("Single-shot account authentication failed: login '".urlencode($l)."' not found");
|
|
if ($qr) {
|
|
l::debug("Query returned " . dbCount($qr) . " row(s)", LOG_DEBUG);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
list($uid,$l2,$pw) = dbFetchArray($qr);
|
|
if ($p != $pw) {
|
|
l::info("Single-shot account authentication failed: login '"
|
|
. urlencode($l) . "' used invalid password");
|
|
l::debug("User ID: $uid ; real user name: $l2");
|
|
return false;
|
|
}
|
|
|
|
$_SESSION['login'] = $l2;
|
|
$_SESSION['userid'] = $uid;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
private function checkVersionRegistration() {
|
|
if (input::$path == "main") {
|
|
return true;
|
|
}
|
|
|
|
$game = config::getGame(input::$path);
|
|
$lib = $game->getLib();
|
|
$pid = $lib->call("doesUserPlay", $_SESSION['userid']);
|
|
if (is_null($pid)) {
|
|
return false;
|
|
}
|
|
if (!is_array($_SESSION["{$game->name}_data"])) {
|
|
$_SESSION["{$game->name}_data"] = array("player" => $pid);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
private function singleShotLog() {
|
|
$uid = $_SESSION['userid'];
|
|
|
|
$q = dbQuery("SELECT id FROM web_session WHERE account = $uid");
|
|
if (!($q && dbCount($q))) {
|
|
$in = time();
|
|
$out = $in + 1;
|
|
$q = dbQuery("UPDATE account SET last_login=$in,last_logout=$out WHERE id=$uid");
|
|
}
|
|
|
|
dbQuery("INSERT INTO account_log(account,ip_addr,action,t) VALUES ($uid,'AUTO','IN',unix_timestamp(now()) - 1)");
|
|
dbQuery("INSERT INTO account_log(account,ip_addr,action) VALUES ($uid,'AUTO','OUT')");
|
|
}
|
|
|
|
|
|
function handleInput() {
|
|
$data = handler::$h->xml(input::$input);
|
|
if (!($data instanceof data_gen)) {
|
|
l::fatal(18, "In XML handler for " . input::$path . "/" . input::$page);
|
|
}
|
|
|
|
$this->data = $data;
|
|
}
|
|
|
|
|
|
function initRPC() { /*NO RPC*/ }
|
|
|
|
|
|
function outputData() {
|
|
$data = $this->genOutput($this->outputMode);
|
|
|
|
if (input::$IE || input::$safari || tracking::$disabled) {
|
|
$this->rawOutput($data);
|
|
} else {
|
|
$this->cachedOutput($data);
|
|
}
|
|
}
|
|
|
|
|
|
private function cachedOutput($data) {
|
|
// Generate an XML resource from the data
|
|
addRawResource('xml', $data);
|
|
$resId = storeResource("xml", 21600, false);
|
|
$xmlId = md5($_SERVER['REQUEST_URI']) . ":$resId";
|
|
|
|
// Check the tracking cookie for the required contents
|
|
if (!is_array(tracking::$data['xmlId'])) {
|
|
tracking::$data['xmlId'] = array();
|
|
}
|
|
if (!isset(tracking::$data['xmlId'][$xmlId])) {
|
|
tracking::$data['xmlId'][$xmlId] = time();
|
|
}
|
|
|
|
// Send the page's header
|
|
$time = tracking::$data['xmlId'][$xmlId];
|
|
$lastModified = substr(date('r', $time), 0, -5).'GMT';
|
|
$etag = '"'.md5($lastModified).'"';
|
|
header("Content-Type: text/xml; charset=utf-8");
|
|
header("Last-Modified: $lastModified GMT");
|
|
header("ETag: $etag");
|
|
header("Cache-Control: no-cache, must-revalidate");
|
|
|
|
// Sends either a 304 reply or the data depending on the browser's will
|
|
$ifModifiedSince = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']) : false;
|
|
$ifNoneMatch = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : false;
|
|
if (($ifNoneMatch || $ifModifiedSince) && (!$ifNoneMatch || $ifNoneMatch == $etag) && (!$ifModifiedSince || $ifModifiedSince != $lastModified)) {
|
|
header('HTTP/1.0 304 Not Modified');
|
|
} else {
|
|
endRequest(false);
|
|
echo $data;
|
|
exit(0);
|
|
}
|
|
}
|
|
|
|
|
|
private function rawOutput($data) {
|
|
header("Content-Type: text/xml; charset=utf-8");
|
|
header("Expires: Thu, 19 Feb 1981 05:00:00 GMT");
|
|
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
|
|
header("Cache-Control: no-cache, must-revalidate");
|
|
header("Pragma: no-cache");
|
|
|
|
// Send the data directly
|
|
endRequest(false);
|
|
echo $data;
|
|
exit(0);
|
|
}
|
|
|
|
|
|
private function genOutput($mode) {
|
|
if ($mode == 'xml') {
|
|
$data = $this->data->toXML($this->document);
|
|
} else {
|
|
$data = $this->data->toLWData($this->document);
|
|
}
|
|
$this->document->appendChild($data);
|
|
return $this->document->saveXML();
|
|
}
|
|
}
|
|
|
|
?>
|