Added full source code

This commit is contained in:
Emmanuel BENOîT 2016-01-10 11:01:49 +01:00
commit 33f8586698
1377 changed files with 123808 additions and 0 deletions

20
admin/as_log.inc Normal file
View file

@ -0,0 +1,20 @@
<?php
/** This function writes an entry to the system log. */
function __logAdmin($txt, $level = null) {
static $logInit = false;
if (!$logInit) {
global $__logPrefix;
define_syslog_variables();
openlog("lwControl", LOG_PID, LOG_USER);
$logInit = true;
}
if (is_null($level)) {
$level = LOG_INFO;
}
syslog($level, "*** ADMIN {$_SERVER['PHP_AUTH_USER']} $txt");
}
?>

24
admin/as_manager.inc Normal file
View file

@ -0,0 +1,24 @@
<?php
function __isManagerRunning() {
global $aConfig;
$fName = $aConfig['ctrlPath'] . "/tickManager.pid";
if (!file_exists($fName)) {
return false;
}
$file = fopen($fName, "r");
$line = rtrim(fgets($file));
fclose($file);
list($pid, $time) = explode(" ", $line);
if (time() - $time > 22) {
return false;
}
return $pid;
}
?>

80
admin/bot.php Normal file
View file

@ -0,0 +1,80 @@
<?php
set_magic_quotes_runtime(false);
include('config.inc');
include('../scripts/config.inc');
include('as_manager.inc');
include('as_log.inc');
function redirect() {
?>
<html>
<head>
<title>LegacyWorlds Beta 5 > Administration > IRC bot</title>
</head>
<body>
<h1><a href="index.html">LWB5 > Administration</a> > IRC bot</h1>
<h2>Operation in progress...</h2>
<p>
A system operation is in progress. Please wait, the page will update in a few seconds.
</p>
<script language="JavaScript">
window.setTimeout('window.location="bot.php"', 1000);
</script>
</body>
</html>
<?php
exit(0);
}
function sendCommand($cmd) {
global $aConfig;
$fName = $aConfig['ctrlFifo'];
if (!file_exists($fName)) {
return false;
}
$fifo = fopen($fName, "w");
fwrite($fifo, "$cmd\n");
fclose($fifo);
redirect();
}
if ($_GET['c'] == 'kb') {
__logAdmin("is stopping the IRC bot");
sendCommand("BOTOFF");
} elseif ($_GET['c'] == 'sb') {
__logAdmin("is starting the IRC bot");
sendCommand("BOTON");
}
$running = file_exists($config['cs_path'] . "/ircbot.pid");
?>
<html>
<head>
<title>LegacyWorlds Beta 5 > Administration > IRC bot</title>
</head>
<body>
<h1><a href="index.html">LWB5 > Administration</a> > IRC bot</h1>
<?php
if ($running) {
?>
<p>
IRC bot is (probably) running. <a href="?c=kb">Kill bot</a>
</p>
<?php
} else {
?>
<p>
IRC bot is not running. <a href="?c=sb">Start bot</a>
</p>
<?php
}
?>
</body>
</html>

56
admin/cg_done.php Normal file
View file

@ -0,0 +1,56 @@
<?php
set_magic_quotes_runtime(false);
session_start();
?>
<html>
<head>
<title>Legacy Worlds Beta 5 > Administration > Create game</title>
</head>
<body style="background-color: #dfdfff">
<table style="margin: 50px 0; padding: 0px;width:100%" cellspacing="0" cellpadding="0">
<tr>
<td width="33%">&nbsp;</td>
<td width="34%"><table style="border: 4px solid blue; background-color:white; padding: 5px;width: 100%">
<tr>
<td colspan="3" style="padding: 2px 0px;font-size:150%;color:blue;text-align:center">LegacyWorlds Beta 5</td>
</tr>
<tr>
<td colspan="3" style="padding: 2px 0px;font-size:150%;color:red;text-align:center"><?=$_SESSION['lw_new_game']['name']?></td>
</tr>
<tr><td colspan="3" style="height:5px;font-size:1pt">&nbsp;</td></tr>
<tr><td colspan="3" style="padding: 2px 0px;color:#3f3fff;text-align:center">Game creation complete!</td></tr>
<tr>
<td style="width:10%">&nbsp;</td>
<td><table style="border: 1px solid black; padding: 1px; margin: 0px; width: 100%; height: 16px"><tr>
<td style='font-size:1pt;background-color:#00007f'>&nbsp;</td>
</tr></table></td>
<td style="width:10%">&nbsp;</td>
</tr>
<tr><td colspan="3" style="padding: 2px 0px;color:#ff3f3f;text-align:center">100% complete</td></tr>
<tr><td colspan="3">&nbsp;</td></tr>
</table></td>
<td width="33%">&nbsp;</td>
<tr><td colspan="3">&nbsp;</td></tr>
<tr>
<td>&nbsp;</td>
<td style="text-align:center">
The new game has been created; however, it is not visible from the interface yet, you will have to
<a href="game_status.php">make it visible</a><br/>
<br/>
The server is still in <a href="maintenance.php">maintenance mode</a>, you will have to disable it manually.<br/>
<br/>
<a href="index.html">Main admin page</a>
</td>
<td>&nbsp;</td>
</tr>
</table>
</body>
</html>
<?php
$_SESSION['lw_new_game']['started'] = false;
?>

45
admin/cg_operation.inc Normal file
View file

@ -0,0 +1,45 @@
<html>
<head>
<title>Legacy Worlds Beta 5 > Administration > Create game</title>
</head>
<body style="background-color: #ffdfdf">
<table style="margin: 50px 0; padding: 0px;width:100%" cellspacing="0" cellpadding="0">
<tr>
<td width="33%">&nbsp;</td>
<td width="34%"><table style="border: 4px solid red; background-color:white; padding: 5px;width: 100%">
<tr>
<td colspan="3" style="padding: 2px 0px;font-size:150%;color:red;text-align:center">LegacyWorlds Beta 5</td>
</tr>
<tr>
<td colspan="3" style="padding: 2px 0px;font-size:150%;color:red;text-align:center">Game creation in progress</td>
</tr>
<tr><td colspan="3" style="height:5px;font-size:1pt">&nbsp;</td></tr>
<tr><td colspan="3" style="padding: 2px 0px;color:#ff3f3f;text-align:center"><?=$op['text']?></td></tr>
<tr>
<td style="width:10%">&nbsp;</td>
<td><table style="border: 1px solid black; padding: 1px; margin: 0px; width: 100%; height: 16px"><tr>
<?php
if ($op['pc'] == 0) {
print "<td style='font-size:1pt'>&nbsp;</td>";
} elseif ($op['pc'] == 100) {
print "<td style='font-size:1pt;background-color:#7f0000'>&nbsp;</td>";
} else {
print "<td style='font-size:1pt;background-color:#7f0000;width:" . $op['pc'] . "%'>&nbsp;</td>"
. "<td style='font-size:1pt'>&nbsp;</td>";
}
?>
</tr></table></td>
<td style="width:10%">&nbsp;</td>
</tr>
<tr><td colspan="3" style="padding: 2px 0px;color:#ff3f3f;text-align:center"><?=$op['pc']?>% complete</td></tr>
<tr><td colspan="3">&nbsp;</td></tr>
</table></td>
<td width="33%">&nbsp;</td>
</table>
<script language="JavaScript">
window.setTimeout('window.location="<?=$op['to']?>"', <?=$op['delay']*1000?>);
</script>
</body>
</html>

24
admin/cg_step0.php Normal file
View file

@ -0,0 +1,24 @@
<?php
set_magic_quotes_runtime(false);
session_start();
if (!is_array($_SESSION['lw_new_game']) || !$_SESSION['lw_new_game']['do_it_now'] || $_SESSION['lw_new_game']['started']) {
echo "Sorry, can't do that.";
exit(0);
}
$_SESSION['lw_new_game']['started'] = true;
include("as_log.inc");
__logAdmin("is creating game {$_SESSION['lw_new_game']['name']}");
$op = array(
"pc" => 0,
"text" => "Initialising ...",
"delay" => 1,
"to" => "cg_step1.php"
);
include('cg_operation.inc');
?>

30
admin/cg_step1.php Normal file
View file

@ -0,0 +1,30 @@
<?php
set_magic_quotes_runtime(false);
session_start();
if (!is_array($_SESSION['lw_new_game']) || !$_SESSION['lw_new_game']['do_it_now'] || !$_SESSION['lw_new_game']['started']) {
echo "Sorry, can't do that.";
exit(0);
}
$_SESSION['lw_new_game']['started'] = true;
include("../scripts/config.inc");
if (is_null($config['maintenance'])) {
$text = "Enabling maintenance mode";
$next = "cg_step2.php";
} else {
$text = "Checking existing IDs";
$next = "cg_step4.php";
}
$op = array(
"pc" => 5,
"text" => $text,
"delay" => 1,
"to" => $next
);
include('cg_operation.inc');
?>

28
admin/cg_step10.php Normal file
View file

@ -0,0 +1,28 @@
<?php
set_magic_quotes_runtime(false);
session_start();
if (!is_array($_SESSION['lw_new_game']) || !$_SESSION['lw_new_game']['do_it_now'] || !$_SESSION['lw_new_game']['started']) {
echo "Sorry, can't do that.";
exit(0);
}
/* Execute an universe tick manually */
$ns = $_SESSION['lw_new_game']['found_id'];
$__runFromAdmin = true;
$__adminParams = array($ns, 'universe');
include("../scripts/ticks.php");
$op = array(
"pc" => 85,
"text" => "Adding silent admins",
"delay" => 1,
"to" => "cg_step11.php"
);
include('cg_operation.inc');
?>

60
admin/cg_step11.php Normal file
View file

@ -0,0 +1,60 @@
<?php
set_magic_quotes_runtime(false);
session_start();
if (!is_array($_SESSION['lw_new_game']) || !$_SESSION['lw_new_game']['do_it_now'] || !$_SESSION['lw_new_game']['started']) {
echo "Sorry, can't do that.";
exit(0);
}
include("config.inc");
include('as_manager.inc');
/* Insert "silent admins" into the new game's player table */
$cnx = __dbConnect();
if (!$cnx) {
$argh = "Could not connect to the database";
} else {
$ns = $_SESSION['lw_new_game']['found_id'];
$error = false;
foreach ($_SESSION['lw_new_game']['silent'] as $aId) {
if (!pg_query($cnx, "INSERT INTO \"{$ns}\".player (userid, first_planet, hidden) VALUES ($aId, 1, TRUE)")) {
$error = true;
break;
}
}
if ($error) {
$argh = "Failed to insert silent admin data";
} else {
$argh = null;
}
pg_close($cnx);
}
if (!is_null($argh)) {
include('cg_argh.inc');
exit(0);
}
if (__isManagerRunning()) {
$op = array(
"pc" => 90,
"text" => "Restarting ticks",
"delay" => 1,
"to" => "cg_step12.php"
);
} else {
$op = array(
"pc" => 100,
"text" => "Cleaning up",
"delay" => 1,
"to" => "cg_done.php"
);
}
include('cg_operation.inc');
?>

35
admin/cg_step12.php Normal file
View file

@ -0,0 +1,35 @@
<?php
set_magic_quotes_runtime(false);
session_start();
if (!is_array($_SESSION['lw_new_game']) || !$_SESSION['lw_new_game']['do_it_now'] || !$_SESSION['lw_new_game']['started']) {
echo "Sorry, can't do that.";
exit(0);
}
include("config.inc");
include("as_manager.inc");
include("../scripts/config.inc");
if (!__isManagerRunning() || !file_exists($config['cachedir'] . "/ticks_stopped")) {
$op = array(
"pc" => 100,
"text" => "Cleaning up",
"delay" => 1,
"to" => "cg_done.php"
);
} else {
touch($config['cachedir'] . "/start_ticks");
$op = array(
"pc" => 95,
"text" => "Waiting for ticks to restart",
"delay" => 1,
"to" => "cg_step13.php"
);
}
include('cg_operation.inc');
?>

33
admin/cg_step13.php Normal file
View file

@ -0,0 +1,33 @@
<?php
set_magic_quotes_runtime(false);
session_start();
if (!is_array($_SESSION['lw_new_game']) || !$_SESSION['lw_new_game']['do_it_now'] || !$_SESSION['lw_new_game']['started']) {
echo "Sorry, can't do that.";
exit(0);
}
include("config.inc");
include("as_manager.inc");
include("../scripts/config.inc");
if (__isManagerRunning() && file_exists($config['cachedir'] . "/ticks_stopped")) {
$op = array(
"pc" => 95,
"text" => "Waiting for ticks to restart",
"delay" => 1,
"to" => "cg_step13.php"
);
} else {
$op = array(
"pc" => 100,
"text" => "Cleaning up",
"delay" => 1,
"to" => "cg_done.php"
);
}
include('cg_operation.inc');
?>

31
admin/cg_step2.php Normal file
View file

@ -0,0 +1,31 @@
<?php
set_magic_quotes_runtime(false);
session_start();
if (!is_array($_SESSION['lw_new_game']) || !$_SESSION['lw_new_game']['do_it_now'] || !$_SESSION['lw_new_game']['started']) {
echo "Sorry, can't do that.";
exit(0);
}
$maintenance = array(
"until" => time() + 15 * 60,
"reason" => "Creating game " . $_SESSION['lw_new_game']['name']
);
include("../scripts/config.inc");
$f = fopen($config['cachedir'] . '/maintenance.ser', "w");
fwrite($f, serialize($maintenance));
fclose($f);
$_SESSION['lw_new_game']['menable'] = time();
$op = array(
"pc" => 10,
"text" => "Waiting ...",
"delay" => 1,
"to" => "cg_step3.php"
);
include('cg_operation.inc');
?>

29
admin/cg_step3.php Normal file
View file

@ -0,0 +1,29 @@
<?php
set_magic_quotes_runtime(false);
session_start();
if (!is_array($_SESSION['lw_new_game']) || !$_SESSION['lw_new_game']['do_it_now'] || !$_SESSION['lw_new_game']['started']) {
echo "Sorry, can't do that.";
exit(0);
}
$t = time() - $_SESSION['lw_new_game']['menable'];
if ($t < 20) {
$text = "Waiting ...";
$next = "cg_step3.php";
} else {
$text = "Checking existing IDs";
$next = "cg_step4.php";
}
$op = array(
"pc" => 10 + floor($t/2),
"text" => $text,
"delay" => 1,
"to" => $next
);
include('cg_operation.inc');
?>

41
admin/cg_step4.php Normal file
View file

@ -0,0 +1,41 @@
<?php
set_magic_quotes_runtime(false);
session_start();
if (!is_array($_SESSION['lw_new_game']) || !$_SESSION['lw_new_game']['do_it_now'] || !$_SESSION['lw_new_game']['started']) {
echo "Sorry, can't do that.";
exit(0);
}
include("config.inc");
$cnx = __dbConnect();
$minId = 1;
$gameType = "b5" . ($_SESSION['lw_new_game']['game_type'] == 'r' ? 'r' : 'm');
do {
$minId ++;
$q = pg_query($cnx, "SELECT nspname FROM pg_namespace WHERE nspname='{$gameType}{$minId}'");
} while ($q && pg_num_rows($q) == 1);
pg_close($cnx);
if (!$q) {
$argh = "Error while accessing the database";
include('cg_argh.inc');
exit(1);
}
$_SESSION['lw_new_game']['found_id'] = $gameType . $minId;
$op = array(
"pc" => 25,
"text" => "Inserting data for ID $gameType$minId",
"delay" => 1,
"to" => "cg_step5.php"
);
include('cg_operation.inc');
?>

205
admin/cg_step5.php Normal file
View file

@ -0,0 +1,205 @@
<?php
set_magic_quotes_runtime(false);
session_start();
if (!is_array($_SESSION['lw_new_game']) || !$_SESSION['lw_new_game']['do_it_now'] || !$_SESSION['lw_new_game']['started']) {
echo "Sorry, can't do that.";
exit(0);
}
include("config.inc");
include("as_manager.inc");
class dbParser {
static private $instructions = array();
static private $aConnection;
static private $uConnection;
static private $cConnection = null;
static public function parse($contents) {
$all = explode("\n", $contents);
$state = 0;
foreach ($all as $line) {
// print "PARSING LINE: $line<br/>\n";
if ($state == 0) {
// Remove comments
$line = preg_replace('/\s*--.*$/', '', $line);
if ($line == '') {
continue;
}
// \c ?
if (preg_match('/^\\\\c\s+[^\s]+\s([^\s]+)\s*$/', $line, $match)) {
if ($match[1] == "legacyworlds_admin") {
//echo "<b>CONNECT AS ADMIN</b><br/>";
array_push(self::$instructions, array("CADM"));
} else {
//echo "<b>CONNECT AS USER</b><br/>";
array_push(self::$instructions, array("CUSR"));
}
}
// \i ?
elseif (preg_match('/^\\\\i\s+([^\s]+)\s*$/', $line, $match)) {
self::parseFile($match[1]);
}
// COPY table FROM STDIN ?
elseif (preg_match('/^COPY\s+([^\s]+)\s+FROM\s+STDIN\s*;\s*$/i', $line, $match)) {
//echo "<b>COPY DATA</b> INTO {$match[1]}: ";
array_push(self::$instructions, array("COPY", $match[1]));
$state = 1;
$copyArray = array();
}
// Other commands
else {
$rv = self::parseCommand($line);
if ($rv[0]) {
//echo "<b>EXECUTE QUERY</b> " . htmlentities($rv[1]) . "<br/>\n";
array_push(self::$instructions, array("QUERY", $rv[1]));
} else {
$buffer = $rv[1];
$state = 2;
}
}
} elseif ($state == 1) {
if ($line == "\\.") {
//echo count($copyArray) . " LINE(S) OF DATA<br/>\n";
self::$instructions[count(self::$instructions) - 1][2] = $copyArray;
$state = 0;
} else {
array_push($copyArray, "$line\n");
}
} elseif ($state == 2) {
$rv = self::parseCommand($line, $buffer);
if ($rv[0]) {
//echo "<b>EXECUTE QUERY</b> " . htmlentities($rv[1]) . "<br/>\n";
array_push(self::$instructions, array("QUERY", $rv[1]));
$state = 0;
} else {
$buffer = $rv[1];
}
}
}
}
private static function parseFile($fileName) {
$file = fopen("../sql/$fileName", "r");
$text = "";
while (($line = fgets($file)) !== FALSE) {
$text .= $line;
}
fclose($file);
self::parse($text);
}
private static function parseCommand($line, $buffer = "") {
$state = 0;
for ($i = 0; $i < strlen($line); $i ++) {
if ($state == 0) {
if ($line{$i} == ';') {
return array(true, $buffer);
}
$buffer .= $line{$i};
if ($line{$i} == "'") {
$state = 1;
}
} else {
$buffer .= $line{$i};
if ($line{$i} == "'") {
$state = 0;
}
}
}
return array(false, "$buffer ");
}
public static function connect() {
self::$uConnection = __dbConnect(false);
if (!self::$uConnection) {
$argh = "Error while accessing the database in user mode";
include('cg_argh.inc');
exit(1);
}
self::$aConnection = __dbConnect(true);
if (!self::$aConnection) {
$argh = "Error while accessing the database in admin mode";
include('cg_argh.inc');
exit(1);
}
}
public static function execute($schema) {
foreach (self::$instructions as $instr) {
$iType = array_shift($instr);
if ($iType == 'CADM') {
self::setConnection(self::$aConnection);
} elseif ($iType == 'CUSR') {
self::setConnection(self::$aConnection);
} elseif ($iType == 'QUERY') {
if (!pg_query(self::$cConnection, $instr[0])) {
$argh = "Could not execute query {$instr[0]}";
pg_query(self::$aConnection, "DROP SCHEMA \"$schema\" CASCADE");
include('cg_argh.inc');
exit(1);
}
} elseif ($iType == 'COPY') {
if (!pg_copy_from(self::$cConnection, $instr[0], $instr[1])) {
$argh = "Copy failed for table {$instr[0]}";
pg_query(self::$aConnection, "DROP SCHEMA \"$schema\" CASCADE");
include('cg_argh.inc');
exit(1);
}
}
}
}
public static function setConnection($cnx) {
self::$cConnection = $cnx;
}
}
$gtData = array(
"r" => array('round', 'r'),
"m" => array('match', 'm'),
"c" => array('ctf', 'm'),
);
$gData = $gtData[$_SESSION['lw_new_game']['game_type']];
$substStr = "b5" . $gData[1] . "X";
// Load base match script
$fileName = "../sql/beta5/beta5-" . $gData[0] . ".sql";
$baseFile = fopen($fileName, "r");
$base = "";
while (($line = fgets($baseFile)) !== FALSE) {
$base .= preg_replace("/$substStr/", $_SESSION['lw_new_game']['found_id'], $line);
}
fclose($baseFile);
dbParser::parse($base);
dbParser::connect();
dbParser::execute($_SESSION['lw_new_game']['found_id']);
if (__isManagerRunning()) {
$op = array(
"pc" => 50,
"text" => "Stopping all ticks",
"delay" => 1,
"to" => "cg_step6.php"
);
} else {
$op = array(
"pc" => 60,
"text" => "Generating configuration",
"delay" => 1,
"to" => "cg_step8.php"
);
}
include('cg_operation.inc');
?>

35
admin/cg_step6.php Normal file
View file

@ -0,0 +1,35 @@
<?php
set_magic_quotes_runtime(false);
session_start();
if (!is_array($_SESSION['lw_new_game']) || !$_SESSION['lw_new_game']['do_it_now'] || !$_SESSION['lw_new_game']['started']) {
echo "Sorry, can't do that.";
exit(0);
}
include("config.inc");
include("as_manager.inc");
include("../scripts/config.inc");
if (!__isManagerRunning() || file_exists($config['cachedir'] . "/ticks_stopped")) {
$op = array(
"pc" => 60,
"text" => "Generating configuration",
"delay" => 1,
"to" => "cg_step8.php"
);
} else {
touch($config['cachedir'] . "/stop_ticks");
$op = array(
"pc" => 55,
"text" => "Waiting for ticks to stop",
"delay" => 1,
"to" => "cg_step7.php"
);
}
include('cg_operation.inc');
?>

33
admin/cg_step7.php Normal file
View file

@ -0,0 +1,33 @@
<?php
set_magic_quotes_runtime(false);
session_start();
if (!is_array($_SESSION['lw_new_game']) || !$_SESSION['lw_new_game']['do_it_now'] || !$_SESSION['lw_new_game']['started']) {
echo "Sorry, can't do that.";
exit(0);
}
include("config.inc");
include("as_manager.inc");
include("../scripts/config.inc");
if (__isManagerRunning() && !file_exists($config['cachedir'] . "/ticks_stopped")) {
$op = array(
"pc" => 55,
"text" => "Waiting for ticks to stop",
"delay" => 1,
"to" => "cg_step7.php"
);
} else {
$op = array(
"pc" => 60,
"text" => "Generating configuration",
"delay" => 1,
"to" => "cg_step8.php"
);
}
include('cg_operation.inc');
?>

109
admin/cg_step8.php Normal file
View file

@ -0,0 +1,109 @@
<?php
set_magic_quotes_runtime(false);
session_start();
if (!is_array($_SESSION['lw_new_game']) || !$_SESSION['lw_new_game']['do_it_now'] || !$_SESSION['lw_new_game']['started']) {
echo "Sorry, can't do that.";
exit(0);
}
require_once("config.inc");
function makeCTFParams() {
$cnx = __dbConnect();
if (!$cnx) {
print "<b>DATABASE CONNECTION ERROR</b>";
exit(1);
}
$query = pg_query("SELECT * FROM main.ctf_map_def ORDER BY name");
if (!$query) {
print "<b>DATABASE ERROR</b>";
exit(1);
}
$ctfMaps = array();
while ($r = pg_fetch_assoc($query)) {
$ctfMaps[$r['id']] = $r;
$query2 = pg_query("SELECT COUNT(*) FROM main.ctf_map_layout WHERE map={$r['id']} AND spawn_here");
if (!$query2) {
print "<b>DATABASE ERROR</b>";
exit(1);
}
list($ctfMaps[$r['id']]['players']) = pg_fetch_array($query2);
pg_free_result($query2);
}
pg_free_result($query);
pg_close($cnx);
$map = $ctfMaps[$_SESSION['lw_new_game']['ctfmap']];
$cParams = $_SESSION['lw_new_game']['ctfparams'];
$params = array(
'usemap' => $map['id'],
'maxplayers' => $map['players'],
'norealloc' => 1,
'partialtechs' => 0,
'lockalliances' => $map['alliances'],
'alliancecap' => 0,
'victory' => 2,
'novacation' => 1
);
foreach ($cParams as $p => $v) {
$params[$p] = $v;
}
return $params;
}
$ns = $_SESSION['lw_new_game']['found_id'];
$newConfig = "\t\t<!-- Game added automatically by the game creation tool -->\n"
. "\t\t<Game id=\"$ns\" version=\"beta5\" namespace=\"$ns\" text=\""
. $_SESSION['lw_new_game']['name'] . "\" public=\"0\" canjoin=\"0\">\n"
. "\t\t\t<!-- Game parameters -->\n";
if ($_SESSION['lw_new_game']['game_type'] == 'c') {
$_SESSION['lw_new_game']['params'] = makeCTFParams();
}
foreach ($_SESSION['lw_new_game']['params'] as $p => $v) {
$newConfig .= "\t\t\t<Param name=\"$p\" value=\"$v\" />\n";
}
$newConfig .= "\n"
. "\t\t\t<!-- Description -->\n"
. "\t\t\t<Description lang=\"en\">\n"
. "\t\t\t\t" . $_SESSION['lw_new_game']['descr'] . "\n"
. "\t\t\t</Description>\n\n"
. "\t\t\t<!-- Ticks -->\n\n";
require_once("cg_ticks_schedule.inc");
$ticks = __computeTicks($_SESSION['lw_new_game']['ft_y'],
$_SESSION['lw_new_game']['ft_m'], $_SESSION['lw_new_game']['ft_d'],
$_SESSION['lw_new_game']['speed'], $_SESSION['lw_new_game']['shift_ticks']);
foreach ($ticks as $tid => $data) {
$time = $data[1];
$time = ($time - ($secs = $time % 60)) / 60;
$time = ($time - ($mins = $time % 60)) / 60;
$newConfig .= "\t\t\t<!-- \"$tid\" tick: first tick " . gmstrftime("%H:%M:%S on %Y-%m-%d", $data[0])
. ", interval {$time}h, {$mins}min, {$secs}s -->\n"
. "\t\t\t<Tick script=\"$tid\" first=\"{$data[0]}\" interval=\"{$data[1]}\" />\n";
}
$newConfig .= "\t\t</Game>\n";
$file = fopen($aConfig['ctrlPath'] . "/config.$ns.xml", "w");
fwrite($file, $newConfig);
fclose($file);
$op = array(
"pc" => 70,
"text" => "Merging configuration",
"delay" => 1,
"to" => "cg_step9.php"
);
include('cg_operation.inc');
?>

27
admin/cg_step9.php Normal file
View file

@ -0,0 +1,27 @@
<?php
set_magic_quotes_runtime(false);
session_start();
if (!is_array($_SESSION['lw_new_game']) || !$_SESSION['lw_new_game']['do_it_now'] || !$_SESSION['lw_new_game']['started']) {
echo "Sorry, can't do that.";
exit(0);
}
include("config.inc");
$ns = $_SESSION['lw_new_game']['found_id'];
$file = fopen($aConfig['ctrlFifo'], "w");
fwrite($file, "MERGE $ns\n");
fclose($file);
$op = array(
"pc" => 75,
"text" => "Initialising universe",
"delay" => 1,
"to" => "cg_step10.php"
);
include('cg_operation.inc');
?>

View file

@ -0,0 +1,86 @@
<?php
function __computeTicks($year, $month, $day, $speed, $shift) {
$tickDefs = array(
// Modifiable ticks
"hour" => array(
'now' => false,
'change' => true,
'interval' => 60 * 60,
'desync' => 60 * 60
),
"battle" => array(
'now' => false,
'change' => true,
'interval' => 4 * 60 * 60,
'desync' => 55 * 60,
),
"cash" => array(
'now' => false,
'change' => true,
'interval' => 12 * 60 * 60,
'desync' => (12 * 60 + 5) * 60
),
"day" => array(
'now' => false,
'change' => true,
'interval' => 24 * 60 * 60,
'desync' => (24 * 60 + 10) * 60
),
"move" => array(
'now' => false,
'change' => true,
'interval' => 60,
'desync' => 60 * 60 + 27
),
// Immediate ticks
'universe' => array(
'now' => true,
'change' => false,
'interval' => 60 * 5,
'desync' => 57
),
'punishment' => array(
'now' => true,
'change' => false,
'interval' => 39,
'desync' => 28
),
// Immutable ticks
'quit' => array(
'now' => false,
'change' => false,
'interval' => 50,
'desync' => 7
),
'sales' => array(
'now' => false,
'change' => false,
'interval' => 21,
'desync' => 13
),
);
$startTime = gmmktime(7, 0, 0, $month, $day, $year);
$now = time();
$results = array();
foreach ($tickDefs as $tid => $def) {
$interval = $def['change'] ? ceil($def['interval']/$speed) : $def['interval'];
if ($def['now']) {
$first = $startTime + $def['desync'];
while ($first > $now) {
$first -= $def['interval'];
}
} else {
$first = $startTime + ($def['change'] ? ceil($def['desync']/$speed) : $def['desync']);
}
$results[$tid] = array($first + $shift * 60, $interval);
}
return $results;
}
?>

12
admin/cg_user_dsp_1.inc Normal file
View file

@ -0,0 +1,12 @@
<h2>Step 1 / 6 : game type</h2>
<p>Please select the type of game you want to create from the form below.</p>
<form method="GET" action="?">
<p>
<input type="radio" value="m" name="gt" id="gtm" <?=$_SESSION['lw_new_game']['game_type'] == 'm' ? "checked='checked'" : ""?>/> <label for="gtm"><b>Match</b></label><br/>
<input type="radio" value="r" name="gt" id="gtr" <?=$_SESSION['lw_new_game']['game_type'] == 'r' ? "checked='checked'" : ""?>/> <label for="gtr"><b>Round</b></label><br/>
<input type="radio" value="c" name="gt" id="gtc" <?=$_SESSION['lw_new_game']['game_type'] == 'c' ? "checked='checked'" : ""?>/> <label for="gtc"><b>Kings of the Hill</b></label>
</p>
<p>
<input type="submit" value="Proceed >>" />
</p>
</form>

30
admin/cg_user_dsp_2.inc Normal file
View file

@ -0,0 +1,30 @@
<h2>Step 2 / 6 : game description</h2>
<p>Please type in the name and description of the new game.</p>
<form method="POST" action="?">
<p>
<b>Game name:</b> <input type="text" name="gn" size="31" maxlength="30" value="<?=htmlentities($_SESSION['lw_new_game']['name'], ENT_QUOTES)?>" /><?php
switch ($err1) :
case 1: print " <span style='color:red;font-weigth:bold'>Too short!</span>\n"; break;
case 2: print " <span style='color:red;font-weigth:bold'>Invalid characters!</span>\n"; break;
endswitch;
?><br/>
This is the name that will appear in menus and lists.
</p>
<p>
<b>Description:</b> <input type="text" name="gd" size="50" maxlength="200" value="<?=htmlentities($_SESSION['lw_new_game']['descr'], ENT_QUOTES)?>" /><?php
switch ($err2) :
case 1: print " <span style='color:red;font-weigth:bold'>Too short!</span>\n"; break;
case 2: print " <span style='color:red;font-weigth:bold'>Invalid characters!</span>\n"; break;
endswitch;
?><br/>
This is the description that will appear next to the name on people's account pages.
</p>
<p>
<input type="submit" name="back" value="<< Back" />
<input type="submit" name="go" value="Proceed >>" />
</p>
</form>

111
admin/cg_user_dsp_3.inc Normal file
View file

@ -0,0 +1,111 @@
<?php
if ($_SESSION['lw_new_game']['game_type'] == 'c') {
include('cg_user_dsp_3ctf.inc');
return;
}
if (!is_array($errors)) {
$errors = array();
}
$params = array(
array(
'id' => 'maxplayers',
'title' => 'Maximum amount of players',
'notes' => '0 for unlimited, -1 for "1/system"'
),
array(
'id' => 'minsystems',
'title' => 'Minimum amount of free systems',
'notes' => 'Also influences the initial universe'
),
array(
'id' => 'maxsystems',
'title' => 'Maximum amount of systems',
'notes' => '0 for unlimited'
),
array(
'id' => 'partialtechs',
'title' => 'Partial tech graph',
'notes' => '0 for complete tech graph, 1 for partial'
),
array(
'id' => 'initialcash',
'title' => 'Initial amount of money',
'notes' => '0 for default (20,000)'
),
array(
'id' => 'zonesize',
'title' => 'Universe generator: zone size',
'notes' => '0 = default (5x5); 1 for 3x3, 2 for 5x5, etc...'
),
array(
'id' => 'nebulaprob',
'title' => 'Probability of a nebula',
'notes' => '0 .. 20, -1 = default'
),
array(
'id' => 'norealloc',
'title' => 'Prevent planet reallocation',
'notes' => '0 to allow players to get new planets'
),
array(
'id' => 'novacation',
'title' => 'Disable vacation mode',
'notes' => '0 = normal / 1 = disable'
),
array(
'id' => 'victory',
'title' => 'Victory conditions',
'notes' => '0 = none / 1 = alliance holds 75% of the planets for 1 week'
),
array(
'id' => 'lockalliances',
'title' => 'Use predefined alliances',
'notes' => 'Disabled if smaller than 2; maximum value = 8'
),
array(
'id' => 'alliancecap',
'title' => 'Alliance capping %',
'notes' => '% of players; 0 to disable (no effect on predefined alliances)'
),
array(
'id' => 'prot_after',
'title' => 'Protection after',
'notes' => 'Day ticks. Only applies to rounds.'
),
array(
'id' => 'prot_duration',
'title' => 'Protection duration',
'notes' => 'Day ticks. Only applies to rounds.'
)
);
?>
<h2>Step 3 / 6 : parameters</h2>
<p>Define the new game's parameters here.</p>
<form method="POST" action="?">
<table border="1">
<?php
foreach ($params as $p) {
print "<tr><th style='align:right";
if (in_array($p['id'], $errors)) {
print ";color:red";
}
print "'>" . htmlentities($p['title']) . " : </th><td>"
. "<input type='text' name='p_{$p['id']}' size='10' maxlength='10' value='"
. $_SESSION['lw_new_game']['params'][$p['id']] . "' /></td><td><i>"
. htmlentities($p['notes']) . "</i></td></tr>";
}
?>
<tr><td colspan="3"><input type="submit" name="gtdef" value="Game type defaults" style="width: 100%" /></td></tr>
</table>
<p>
<input type="submit" name="back" value="<< Back" />
<input type="submit" name="go" value="Proceed >>" />
</p>
</form>

137
admin/cg_user_dsp_3ctf.inc Normal file
View file

@ -0,0 +1,137 @@
<?php
if (!is_array($ctfMaps)) {
require_once("config.inc");
$cnx = __dbConnect();
if (!$cnx) {
print "<b>DATABASE CONNECTION ERROR</b>";
exit(1);
}
$query = pg_query("SELECT * FROM main.ctf_map_def ORDER BY name");
if (!$query) {
print "<b>DATABASE ERROR</b>";
exit(1);
}
$ctfMaps = array();
while ($r = pg_fetch_assoc($query)) {
$ctfMaps[$r['id']] = $r;
$query2 = pg_query("SELECT COUNT(*) FROM main.ctf_map_layout WHERE map={$r['id']} AND spawn_here");
if (!$query2) {
print "<b>DATABASE ERROR</b>";
exit(1);
}
list($ctfMaps[$r['id']]['players']) = pg_fetch_array($query2);
pg_free_result($query2);
}
pg_free_result($query);
pg_close($cnx);
}
if (!is_array($errors)) {
$errors = array();
}
$params = array(
array(
'id' => 'initialcash',
'title' => 'Initial amount of money',
'notes' => '0 for default (20,000)'
),
array(
'id' => 'v2time',
'title' => 'Time for victory',
'notes' => 'Number of hours an alliance must hold the targets to win'
),
array(
'id' => 'v2grace',
'title' => 'Grace period',
'notes' => 'Number of hours an alliance has to retake the targets. Set to 0 to disable.'
),
array(
'id' => 'v2points',
'title' => 'Points per victory',
'notes' => 'Number of points an alliance gains at each victory. Must be > 0 and < 100'
)
);
?>
<h2>Step 3 / 6 : parameters</h2>
<script language="JavaScript"><!--
var games = [];
<?php
foreach ($ctfMaps as $id => $map) {
print "games[$id] = {\n\tdescription: '" . addslashes($map['description'])
. "',\n\tsize: '{$map['width']}x{$map['height']}',\n\t"
. "alliances: {$map['alliances']},\n\tplayers: {$map['players']}\n};\n";
}
?>
function showDetails(selector) {
var sel = selector.options[selector.selectedIndex].value;
var str;
if (sel == '') {
str = "&nbsp;";
} else {
str = "<h4>Map information</h4><p><b>Players:</b> " + games[sel].players
+ " - <b>Teams:</b> " + games[sel].alliances
+ " - <b>Size:</b> " + games[sel].size;
if (games[sel].description != '') {
str += '<br/><b>Description:</b> ' + games[sel].description;
}
str += '</p>';
}
document.getElementById('mapinfo').innerHTML = str;
}
// --></script>
<p>Define the new game's parameters here.</p>
<form method="POST" action="?">
<div id="mapinfo" style="float:right;width: 50%;padding: 0px 10px">&nbsp;</div>
<table border="1" width="45%">
<tr>
<th style='align:right<?php if (in_array('map', $errors)) { print ";color:red"; } ?>'>
Map to use:
</th>
<td colspan="2">
<select name="map" onChange="showDetails(this)">
<option value="">-- Select --</option>
<?php
foreach ($ctfMaps as $id => $map) {
print " <option value='$id'";
if ($_SESSION['lw_new_game']['ctfmap'] == $id) {
print " selected='selected'";
}
print ">" . htmlentities($map['name']) . "</option>\n";
}
?>
</select>
</td>
</tr>
<?php
foreach ($params as $p) {
print "<tr><th style='align:right";
if (in_array($p['id'], $errors)) {
print ";color:red";
}
print "'>" . htmlentities($p['title']) . " : </th><td>"
. "<input type='text' name='p_{$p['id']}' size='10' maxlength='10' value='"
. $_SESSION['lw_new_game']['ctfparams'][$p['id']] . "' /></td><td><i>"
. htmlentities($p['notes']) . "</i></td></tr>";
}
?>
</table>
<p>
<input type="submit" name="back" value="<< Back" />
<input type="submit" name="go" value="Proceed >>" />
</p>
</form>

54
admin/cg_user_dsp_4.inc Normal file
View file

@ -0,0 +1,54 @@
<?php
$speeds = array(
"" => "-- select speed --",
"1" => "Normal",
"2" => "2x",
"3" => "3x",
"4" => "4x"
);
?>
<h2>Step 4 / 6 : ticks configuration</h2>
<p>Please indicate the speed of the game and the day the game will begin on.</p>
<form method="GET" action="?">
<p>
Game speed:
<select name="gs">
<?php
foreach ($speeds as $val => $disp) {
print "<option value='$val'";
if ($_SESSION['lw_new_game']['speed'] == $val) {
print " selected='selected'";
}
print ">$disp</option>\n";
}
?>
</select> (4x games = bad for the server!)
</p>
<p>
First tick on (YYYY-MM-DD):
<input type="text" name="ft_y" size="4" maxlength="4" value="<?=htmlentities($_SESSION['lw_new_game']['ft_y'], ENT_QUOTES)?>" /> -
<input type="text" name="ft_m" size="2" maxlength="2" value="<?=htmlentities($_SESSION['lw_new_game']['ft_m'], ENT_QUOTES)?>" /> -
<input type="text" name="ft_d" size="2" maxlength="2" value="<?=htmlentities($_SESSION['lw_new_game']['ft_d'], ENT_QUOTES)?>" /><br/>
<?php
if ($ftError) {
print "<span style='color:red'>Invalid date! Must be in the future.</span>";
} else {
print "Ticks will start on the specified day, at the first hour tick after 7:00 AM";
}
?>
</p>
<p>
Shift ticks by <input type="text" name="st" size="3" maxlength="3" value="<?=(int) $_SESSION['lw_new_game']['shift_ticks']?>" /> minutes
</p>
<p>
<input type="submit" name="back" value="<< Back" />
<input type="submit" name="go" value="Proceed >>" />
</p>
</form>

43
admin/cg_user_dsp_5.inc Normal file
View file

@ -0,0 +1,43 @@
<?php
if (!is_array($allAdmins)) {
require_once("config.inc");
$cnx = __dbConnect();
if (!$cnx) {
print "<b>DATABASE CONNECTION ERROR</b>";
exit(1);
}
$query = pg_query("SELECT id,name FROM main.account WHERE admin AND NOT name LIKE 'AI>%' ORDER BY name");
if (!$query) {
print "<b>DATABASE CONNECTION ERROR</b>";
exit(1);
}
$allAdmins = array();
while ($r = pg_fetch_row($query)) {
$allAdmins[$r[0]] = $r[1];
}
pg_close($cnx);
}
?>
<h2>Step 5 / 6 : silent admins</h2>
<p>"Silent admins" are admins that will join the game for administrative purposes but won't play it. Please beware with this function, as a silent admin will no longer be able to join the game as a player.</p>
<form method="POST" action="?">
<p>
<?php
foreach ($allAdmins as $id => $name) {
?>
<input type="checkbox" name="sa[]" value="<?=$id?>" id="sa<?=$id?>" <?=(is_array($_SESSION['lw_new_game']['silent']) && in_array($id, $_SESSION['lw_new_game']['silent'])) ? "checked='checked'" : ""?> /> <label for="sa<?=$id?>"><?=htmlentities($name)?></label><br/>
<?
}
?>
</p>
<p>
<input type="submit" name="back" value="<< Back" />
<input type="submit" name="go" value="Proceed >>" />
</p>
</form>

213
admin/cg_user_dsp_6.inc Normal file
View file

@ -0,0 +1,213 @@
<?php
require_once("cg_ticks_schedule.inc");
require_once("config.inc");
require_once("as_manager.inc");
require_once("../scripts/config.inc");
$cnx = __dbConnect();
if (!$cnx) {
print "<b>DATABASE CONNECTION ERROR</b>";
exit(1);
}
$query = pg_query("SELECT id,name FROM main.account WHERE admin AND NOT name LIKE 'AI>%' ORDER BY name");
if (!$query) {
print "<b>DATABASE CONNECTION ERROR</b>";
exit(1);
}
$allAdmins = array();
while ($r = pg_fetch_row($query)) {
$allAdmins[$r[0]] = $r[1];
}
$query = pg_query("SELECT * FROM main.ctf_map_def ORDER BY name");
if (!$query) {
print "<b>DATABASE ERROR</b>";
exit(1);
}
$ctfMaps = array();
while ($r = pg_fetch_assoc($query)) {
$ctfMaps[$r['id']] = $r;
$query2 = pg_query("SELECT COUNT(*) FROM main.ctf_map_layout WHERE map={$r['id']} AND spawn_here");
if (!$query2) {
print "<b>DATABASE ERROR</b>";
exit(1);
}
list($ctfMaps[$r['id']]['players']) = pg_fetch_array($query2);
pg_free_result($query2);
}
pg_free_result($query);
pg_close($cnx);
function __start($title) {
?>
<h3><?=htmlentities($title)?></h3>
<table border="1" width="80%" style="margin: 5px 30px">
<?
}
function __line($title, $contents) {
?>
<tr>
<th align="right" width="50%"><?=htmlentities($title)?>: </th>
<td><?=htmlentities($contents)?></td>
</tr>
<?
}
function __end() {
echo "</table>\n";
}
$params = array(
array(
'id' => 'maxplayers',
'title' => 'Maximum amount of players',
),
array(
'id' => 'minsystems',
'title' => 'Minimum amount of free systems',
),
array(
'id' => 'maxsystems',
'title' => 'Maximum amount of systems',
),
array(
'id' => 'partialtechs',
'title' => 'Partial tech graph',
),
array(
'id' => 'initialcash',
'title' => 'Initial amount of money',
),
array(
'id' => 'zonesize',
'title' => 'Universe generator: zone size',
),
array(
'id' => 'nebulaprob',
'title' => 'Probability of a nebula',
),
array(
'id' => 'norealloc',
'title' => 'Prevent planet reallocation',
),
array(
'id' => 'novacation',
'title' => 'Disable vacation mode',
),
array(
'id' => 'victory',
'title' => 'Victory conditions',
),
array(
'id' => 'lockalliances',
'title' => 'Use predefined alliances',
),
array(
'id' => 'alliancecap',
'title' => 'Alliance capping %',
)
);
$ctfParams = array(
array(
'id' => 'initialcash',
'title' => 'Initial amount of money',
),
array(
'id' => 'v2time',
'title' => 'Time for victory',
),
array(
'id' => 'v2grace',
'title' => 'Grace period',
),
array(
'id' => 'v2points',
'title' => 'Points per victory',
)
);
?>
<h2>Step 6 / 6 : recap</h2>
<p>Please check the information below <b>CAREFULLY</b>.</p>
<?php
$gTypes = array(
'm' => 'Match',
'r' => 'Round',
'c' => 'Kings of the Hill'
);
__start("Main information");
__line("Game type", $gTypes[$_SESSION['lw_new_game']['game_type']]);
__line("Game name", $_SESSION['lw_new_game']['name']);
__line("Description", $_SESSION['lw_new_game']['descr']);
__end();
__start("Parameters");
if ($_SESSION['lw_new_game']['game_type'] == 'c') {
$map = $ctfMaps[$_SESSION['lw_new_game']['ctfmap']];
__line("Map name", $map['name']);
if ($map['description'] != '') {
__line("Description", $map['description']);
}
__line("Players", $map['players']);
__line("Teams", $map['alliances']);
__line("Size", $map['width'] . "x" . $map['height']);
foreach ($ctfParams as $p) {
__line($p['title'], $_SESSION['lw_new_game']['ctfparams'][$p['id']]);
}
} else {
foreach ($params as $p) {
__line($p['title'], $_SESSION['lw_new_game']['params'][$p['id']]);
}
}
__end();
$speeds = array("Normal", "2x", "3x", "4x");
__start("Ticks configuration");
__line("Speed", $speeds[$_SESSION['lw_new_game']['speed'] - 1]);
__line("First tick (YYYY-MM-DD)", $_SESSION['lw_new_game']['ft_y'] . "-" .
$_SESSION['lw_new_game']['ft_m'] . "-" . $_SESSION['lw_new_game']['ft_d']);
__end();
$ticks = __computeTicks($_SESSION['lw_new_game']['ft_y'],
$_SESSION['lw_new_game']['ft_m'], $_SESSION['lw_new_game']['ft_d'],
$_SESSION['lw_new_game']['speed'], $_SESSION['lw_new_game']['shift_ticks']);
__start("Ticks schedule");
foreach ($ticks as $tid => $data) {
__line("\"$tid\" / first tick", gmstrftime("%H:%M:%S on %Y-%m-%d", $data[0]));
$time = $data[1];
$time = ($time - ($secs = $time % 60)) / 60;
$time = ($time - ($mins = $time % 60)) / 60;
__line("\"$tid\" / interval", "{$time}h, {$mins}min, {$secs}s");
__line("\"$tid\" / numeric values", $data[0] . " / " . $data[1]);
}
__end();
__start("Silent admins");
foreach ($allAdmins as $id => $name) {
__line($name, in_array($id, $_SESSION['lw_new_game']['silent']) ? "YES" : "no");
}
__end();
__start("Server information");
__line("Maintenance mode", is_null($config['maintenance']) ? "No - will enable automatically (DANGEROUS)" : "yes");
__line("Ticks manager", __isManagerRunning() ? "running" : "stopped");
__end();
?>
<form method="GET" action="?">
<p>
<input type="submit" name="back" value="<< Back" />
<input type="submit" name="go" value="Proceed >>" />
</p>
</form>

23
admin/cg_user_dsp_7.inc Normal file
View file

@ -0,0 +1,23 @@
<?php
$_SESSION['lw_new_game']['do_it_now'] = true;
?>
<br/><br/><br/>
<hr/>
<br/><br/><br/>
<h1 style="text-align:center;font-size:32pt">LAST CHANCE</h1>
<br/><br/>
<form method="GET" action="?">
<p style="text-align:center;font-size:150%">
This is your last chance to get back.<br/>
You are about to create a new LegacyWorlds game, which is no small operation.</br>
<br/>
Please, be reasonable and stop now, while you can. Any client crash during the operation could cause the server to be unusable.<br/>
<br/>
<input type="submit" name="back" value="Yes, please, take me back, I want the server to live on!" /><br/>
<br/>
Ok, you're still reading. That's bad news.<br/>
Scroll down to access the next step.
</p>
</form>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<p style="text-align:center"><a href="cg_step0.php">Alea jacta est.</a></p>

8
admin/cg_user_hdl_1.inc Normal file
View file

@ -0,0 +1,8 @@
<?php
if (in_array($_GET['gt'], array('m','r', 'c'))) {
$_SESSION['lw_new_game']['game_type'] = $_GET['gt'];
$_SESSION['lw_new_game']['step'] = 2;
}
?>

27
admin/cg_user_hdl_2.inc Normal file
View file

@ -0,0 +1,27 @@
<?php
function __checktext($text, $minLen, $okChars) {
if (strlen($text) < $minLen) {
return 1;
}
if (preg_match('/[^' . $okChars . ']/', $text)) {
return 2;
}
return 0;
}
if ($_POST['go']) {
$n = $_SESSION['lw_new_game']['name'] = stripslashes($_POST['gn']);
$d = $_SESSION['lw_new_game']['descr'] = stripslashes($_POST['gd']);
$err1 = __checktext($n, 5, 'A-Za-z0-9\.\-\ \,\#');
$err2 = __checktext($d, 15, 'A-Za-z0-9\\.\\- ,#!\'%');
if (!($err1 || $err2)) {
$_SESSION['lw_new_game']['step'] = 3;
}
} elseif ($_POST['back']) {
$_SESSION['lw_new_game']['name'] = stripslashes($_POST['gn']);
$_SESSION['lw_new_game']['descr'] = stripslashes($_POST['gd']);
$_SESSION['lw_new_game']['step'] = 1;
}
?>

73
admin/cg_user_hdl_3.inc Normal file
View file

@ -0,0 +1,73 @@
<?php
if ($_SESSION['lw_new_game']['game_type'] == 'c') {
include('cg_user_hdl_3ctf.inc');
return;
}
$pDefaults = array(
'm' => array(
'maxplayers' => -1,
'minsystems' => 30,
'maxsystems' => 30,
'norealloc' => 1,
'partialtechs' => 0,
'initialcash' => 40000,
'zonesize' => 1,
'nebulaprob' => 15,
'lockalliances' => 4,
'alliancecap' => 0,
'victory' => 1,
'novacation' => 1,
'prot_after' => 0,
'prot_duration' => 0,
),
'r' => array(
'maxplayers' => 0,
'minsystems' => 40,
'maxsystems' => 0,
'norealloc' => 0,
'partialtechs' => 1,
'initialcash' => 0,
'zonesize' => 1,
'nebulaprob' => -1,
'lockalliances' => 0,
'alliancecap' => 20,
'victory' => 0,
'novacation' => 0,
'prot_after' => 20,
'prot_duration' => 20,
)
);
$pList = array_keys($pDefaults['m']);
if (!is_array($_SESSION['lw_new_game']['params'])) {
$_SESSION['lw_new_game']['params'] = array();
}
if ($_POST['gtdef']) {
$_SESSION['lw_new_game']['params'] = $pDefaults[$_SESSION['lw_new_game']['game_type']];
} elseif ($_POST['go']) {
$errors = array();
foreach ($pList as $pid) {
$val = $_POST["p_$pid"];
if (strcmp($val, (string)(int)$val)) {
array_push($errors, $pid);
}
$_SESSION['lw_new_game']['params'][$pid] = $val;
}
if (! count($errors)) {
$_SESSION['lw_new_game']['step'] = 4;
}
} elseif ($_POST['back']) {
foreach ($pList as $pid) {
$_SESSION['lw_new_game']['params'][$pid] = $_POST["p_$pid"];
}
$_SESSION['lw_new_game']['step'] = 2;
}
?>

View file

@ -0,0 +1,66 @@
<?php
require_once("config.inc");
$cnx = __dbConnect();
if (!$cnx) {
print "<b>DATABASE CONNECTION ERROR</b>";
exit(1);
}
$query = pg_query("SELECT * FROM main.ctf_map_def ORDER BY name");
if (!$query) {
print "<b>DATABASE ERROR</b>";
exit(1);
}
$ctfMaps = array();
while ($r = pg_fetch_assoc($query)) {
$ctfMaps[$r['id']] = $r;
$query2 = pg_query("SELECT COUNT(*) FROM main.ctf_map_layout WHERE map={$r['id']} AND spawn_here");
if (!$query2) {
print "<b>DATABASE ERROR</b>";
exit(1);
}
list($ctfMaps[$r['id']]['players']) = pg_fetch_array($query2);
pg_free_result($query2);
}
pg_free_result($query);
pg_close($cnx);
$pList = array('initialcash', 'v2time','v2grace','v2points');
if (!is_array($_SESSION['lw_new_game']['ctfparams'])) {
$_SESSION['lw_new_game']['ctfparams'] = array();
}
if ($_POST['go']) {
$errors = array();
$mapID = (int) $_POST['map'];
if (!array_key_exists($mapID, $ctfMaps)) {
$errors[0] = 'map';
} else {
$_SESSION['lw_new_game']['ctfmap'] = $mapID;
}
foreach ($pList as $pid) {
$val = $_POST["p_$pid"];
if (strcmp($val, (string)(int)$val)) {
array_push($errors, $pid);
}
$_SESSION['lw_new_game']['ctfparams'][$pid] = $val;
}
if (! count($errors)) {
$_SESSION['lw_new_game']['step'] = 4;
}
} elseif ($_POST['back']) {
foreach ($pList as $pid) {
$_SESSION['lw_new_game']['ctfparams'][$pid] = $_POST["p_$pid"];
}
$_SESSION['lw_new_game']['ctfmap'] = $_POST['map'];
$_SESSION['lw_new_game']['step'] = 2;
}
?>

30
admin/cg_user_hdl_4.inc Normal file
View file

@ -0,0 +1,30 @@
<?php
if ($_GET['back'] || $_GET['go']) {
$_SESSION['lw_new_game']['ft_y'] = $_GET['ft_y'];
$_SESSION['lw_new_game']['ft_m'] = $_GET['ft_m'];
$_SESSION['lw_new_game']['ft_d'] = $_GET['ft_d'];
$_SESSION['lw_new_game']['shift_ticks'] = (int) $_GET['st'];
$_SESSION['lw_new_game']['speed'] = $_GET['gs'];
}
if ($_GET['back']) {
$_SESSION['lw_new_game']['step'] = 3;
} elseif ($_GET['go']) {
$speedOk = in_array($_GET['gs'], array("1","2","3","4"));
$mkts = mktime(7, 0, 0, (int)$_GET['ft_m'], (int)$_GET['ft_d'], (int)$_GET['ft_y']);
if ($mkts === FALSE || $mkts <= time()) {
$ftError = 1;
}
if ($_SESSION['lw_new_game']['shift_ticks'] < 0) {
$_SESSION['lw_new_game']['shift_ticks'] = 0;
}
if ($speedOk && !$ftError) {
$_SESSION['lw_new_game']['step'] = 5;
}
}
?>

44
admin/cg_user_hdl_5.inc Normal file
View file

@ -0,0 +1,44 @@
<?php
require_once("config.inc");
$cnx = __dbConnect();
if (!$cnx) {
print "<b>DATABASE CONNECTION ERROR</b>";
exit(1);
}
$query = pg_query("SELECT id,name FROM main.account WHERE admin AND NOT name LIKE 'AI>%' ORDER BY name");
if (!$query) {
print "<b>DATABASE CONNECTION ERROR</b>";
exit(1);
}
$allAdmins = array();
while ($r = pg_fetch_row($query)) {
$allAdmins[$r[0]] = $r[1];
}
pg_close($cnx);
$sa = $_POST['sa'];
if (!is_array($sa)) {
$sa = array();
}
if ($_POST['go'] || $_POST['back']) {
$_SESSION['lw_new_game']['silent'] = array();
foreach ($sa as $saId) {
if (array_key_exists($saId, $allAdmins)) {
array_push($_SESSION['lw_new_game']['silent'], $saId);
}
}
} elseif (!is_array($_SESSION['lw_new_game']['silent'])) {
$_SESSION['lw_new_game']['silent'] = array();
}
if ( $_POST['back']) {
$_SESSION['lw_new_game']['step'] = 4;
} elseif ($_POST['go']) {
$_SESSION['lw_new_game']['step'] = 6;
}
?>

10
admin/cg_user_hdl_6.inc Normal file
View file

@ -0,0 +1,10 @@
<?php
$_SESSION['lw_new_game']['do_it_now'] = false;
if ($_GET['back']) {
$_SESSION['lw_new_game']['step'] = 5;
} elseif ($_GET['go']) {
$_SESSION['lw_new_game']['step'] = 7;
}
?>

8
admin/cg_user_hdl_7.inc Normal file
View file

@ -0,0 +1,8 @@
<?php
if ($_GET['back']) {
$_SESSION['lw_new_game']['step'] = 6;
$_SESSION['lw_new_game']['do_it_now'] = false;
}
?>

9
admin/cg_user_hdr.inc Normal file
View file

@ -0,0 +1,9 @@
<html>
<head>
<title>LegacyWorlds Beta 5 > Administration > Create game</title>
</head>
<body>
<h1><a href="index.html">LWB5 > Administration</a> > Create game</h1>
<p>
This administrative tools allows you to create new LegacyWorlds games.
</p>

39
admin/config.inc Normal file
View file

@ -0,0 +1,39 @@
<?php
$aConfig = array(
"user" => 'legacyworlds',
"password" => 'password for the standard database user',
"adminUser" => 'legacyworlds_admin',
"adminPassword" => 'password for the administrative database user',
"ctrlFifo" =>'/tmp/.lwFifo',
"ctrlPath" =>'/tmp/.lwControl'
);
function __dbConnect($admin = false) {
global $aConfig;
$u = $aConfig[$admin ? 'adminUser' : 'user'];
$p = $aConfig[$admin ? 'adminPassword' : 'password'];
$cString = "dbname='legacyworlds' host='127.0.0.1' sslmode='prefer' user='$u' password='$p'";
return pg_connect($cString);
}
function __sendControl($command) {
global $aConfig;
$fName = $aConfig['ctrlFifo'];
if (!file_exists($fName)) {
return false;
}
$fifo = @fopen($fName, "w");
if ($fifo === false) {
return false;
}
fwrite($fifo, "$command\n");
fclose($fifo);
return true;
}
?>

19
admin/create.php Normal file
View file

@ -0,0 +1,19 @@
<?php
set_magic_quotes_runtime(false);
session_start();
if (!is_array($_SESSION['lw_new_game']) || $_GET['reset']) {
$_SESSION['lw_new_game'] = array(
"step" => 1
);
}
include("cg_user_hdl_" . $_SESSION['lw_new_game']['step'] . ".inc");
include("cg_user_hdr.inc");
include("cg_user_dsp_" . $_SESSION['lw_new_game']['step'] . ".inc");
?>
</body>
</html>

425
admin/ctf_map.inc Normal file
View file

@ -0,0 +1,425 @@
<?php
class ctf_map_sys {
private $x;
private $y;
private $type;
private $alloc;
private $spawn;
public function __construct($x, $y, $type = null, $alloc = null, $spawn = null) {
$this->x = $x;
$this->y = $y;
$this->type = $type;
$this->alloc = $alloc;
if (is_bool($spawn)) {
$this->spawn = $spawn;
} elseif (is_string($spawn)) {
$this->spawn = ($spawn == 't');
} else {
$this->spawn = null;
}
}
public function setType($type) {
if (is_null($type) || !in_array((string) $type, array('S', '1', '2', '3', '4'))) {
throw new Exception('Invalid type');
}
$this->type = $type;
if ($this->type != 'S') {
$this->alloc = $this->spawn = null;
} elseif (is_null($this->alloc)) {
$this->alloc = 0;
$this->spawn = null;
}
}
public function setAllocation($alloc) {
if ($alloc < 0 || $this->type != 'S') {
throw new Exception('Invalid allocation type');
}
$this->alloc = $alloc;
if ($this->alloc != 0 && is_null($this->spawn)) {
$this->spawn = false;
} elseif ($this->alloc = 0) {
$this->spawn = null;
}
}
public function setSpawn($spawn) {
if (is_null($this->alloc) || $this->alloc == 0 || !is_bool($spawn)) {
throw new Exception("Invalid spawning value");
}
$this->spawn = $spawn;
}
public function getType() {
return $this->type;
}
public function getAllocation() {
return $this->alloc;
}
public function getSpawn() {
return $this->spawn;
}
public function getX() {
return $this->x;
}
public function getY() {
return $this->y;
}
public function store($db, $map) {
$q = pg_query_params($db, "INSERT INTO main.ctf_map_layout(map,sys_x,sys_y,sys_type,alloc_for,spawn_here)"
. " VALUES ($map,$1,$2,$3,$4,$5)", array(
$this->x, $this->y, $this->type, $this->alloc,
($this->type == 'S' && $this->alloc > 0) ? ($this->spawn ? 't' : 'f') : null
));
if (!$q) {
throw new Exception("Failed to store system at {$this->x};{$this->y}");
}
}
}
class ctf_map {
private $dbID;
private $name;
private $description;
private $width;
private $height;
private $alliances;
private $map;
public static function allMaps() {
$db = __dbConnect();
if (! $db) {
throw new Exception('Unable to connect to the database');
}
$result = pg_query($db, "SELECT id FROM main.ctf_map_def ORDER BY id");
if (!$result) {
throw new Exception("Database error");
}
$IDs = array();
while ($row = pg_fetch_array($result)) {
array_push($IDs, $row[0]);
}
pg_free_result($result);
pg_close($db);
$maps = array();
foreach ($IDs as $id) {
$maps[$id] = new ctf_map($id);
}
return $maps;
}
public function __construct($dbID = null) {
if (is_null($dbID)) {
$this->dbID = $this->name = $this->description = null;
$this->alliances = 2;
$this->width = $this->height = 3;
} else {
$db = __dbConnect();
if (! $db) {
throw new Exception("Unable to connect to the database");
}
$result = pg_query($db, "SELECT * FROM main.ctf_map_def WHERE id = $dbID");
if (!($result && pg_num_rows($result) == 1)) {
pg_close($db);
throw new Exception("Definition '$dbID' not found");
}
$row = pg_fetch_assoc($result);
pg_free_result($result);
pg_close($db);
$this->dbID = $dbID;
$this->name = $row['name'];
$this->description = $row['description'];
$this->width = $row['width'];
$this->height = $row['height'];
$this->alliances = $row['alliances'];
}
$this->map = null;
}
public function getID() {
return $this->dbID;
}
public function getName() {
return $this->name;
}
public function getDescription() {
return $this->description;
}
public function getWidth() {
return $this->width;
}
public function getHeight() {
return $this->height;
}
public function getAlliances() {
return $this->alliances;
}
public function setName($value) {
$this->name = $value;
}
public function setDescription($value) {
$this->description = ($value == '') ? null : $value;
}
public function setAlliances($value) {
$this->alliances = $value;
}
public function setWidth($value) {
if (is_null($this->map) && !is_null($this->dbID)) {
$this->load();
}
$this->width = $value;
if (is_array($this->map)) {
$this->initBlankMap();
}
}
public function setHeight($value) {
if (is_null($this->map) && !is_null($this->dbID)) {
$this->load();
}
$this->height = $value;
if (is_array($this->map)) {
$this->initBlankMap();
}
}
public function getMapInfo($x, $y) {
if (! is_array($this->map)) {
if ($this->dbID) {
$this->load();
} else {
return null;
}
}
$offset = $this->getOffset($x, $y);
return $this->map[$offset];
}
public function setSystemType($x, $y, $t) {
if (! is_array($this->map)) {
if ($this->dbID) {
$this->load();
} else {
$this->initBlankMap();
}
}
$offset = $this->getOffset($x, $y);
$v = $this->map[$offset];
if (is_null($v)) {
$v = $this->map[$offset] = new ctf_map_sys($x, $y, $t);
} else {
$v->setType($t);
}
}
public function setSystemAlloc($x, $y, $a) {
if (! is_array($this->map)) {
if ($this->dbID) {
$this->load();
} else {
$this->initBlankMap();
}
}
$offset = $this->getOffset($x, $y);
$v = $this->map[$offset];
if (is_null($v)) {
$v = $this->map[$offset] = new ctf_map_sys($x, $y, 'S');
}
if ($v->getType() != 'S') {
throw new Exception("Can't set allocation type for a nebula");
}
if ($a < 0 || $a > $this->alliances) {
throw new Exception("Invalid allocation type $a");
}
$v->setAllocation($a);
}
public function setSystemSpawn($x, $y, $s) {
if (! is_array($this->map)) {
if ($this->dbID) {
$this->load();
} else {
$this->initBlankMap();
}
}
$offset = $this->getOffset($x, $y);
$v = $this->map[$offset];
if (is_null($v)) {
$v = $this->map[$offset] = new ctf_map_sys($x, $y, 'S', 1, $s);
} else {
if ($v->getType() != 'S' || $v->getAllocation() < 1) {
throw new Exception("Can't set spawning point");
}
$v->setSpawn($s);
}
}
public function jsDump() {
$parts = array();
if (is_null($this->map)) {
if ($this->dbID) {
$this->load();
} else {
$this->initBlankMap();
}
}
foreach ($this->map as $s) {
if (is_null($s)) {
continue;
}
$str = '[' . $s->getX() . ',' . $s->getY() . ',"' . $s->getType() . '",';
if ($s->getType() != 'S') {
$str .= 'null,null';
} else {
$str .= $s->getAllocation() . ',';
if ($s->getAllocation()) {
$str .= $s->getSpawn() ? 'true' : 'false';
} else {
$str .= 'null';
}
}
array_push($parts, "$str]");
}
return join(',', $parts);
}
public function save() {
$db = __dbConnect();
if (!$db) {
throw new Exception("Database error");
}
pg_query($db, "BEGIN TRANSACTION");
pg_query($db, "SET search_path = public, main");
if ($this->dbID) {
$id = $this->dbID;
pg_query_params($db, "UPDATE main.ctf_map_def SET name=$2, description=$3, alliances=$4, "
. "width=$5, height=$6 WHERE id=$1", array(
$id, $this->name, $this->description, $this->alliances,
$this->width, $this->height
));
pg_query($db, "DELETE FROM main.ctf_map_layout WHERE map=$id");
} else {
pg_query_params($db, "INSERT INTO main.ctf_map_def(name,description,alliances,width,height) "
. "VALUES ($1, $2, $3, $4, $5)", array(
$this->name, $this->description, $this->alliances,
$this->width, $this->height
));
$q = pg_query($db, "SELECT last_inserted('ctf_map_def')");
if (!($q && pg_num_rows($q))) {
throw new Exception("Database error");
}
list($id) = pg_fetch_array($q);
}
foreach ($this->map as $sys) {
$sys->store($db, $id);
}
pg_query($db, "COMMIT");
pg_close($db);
$this->dbID = $id;
}
public function destroy() {
if (! $this->dbID) {
return;
}
$db = __dbConnect();
if (!$db) {
throw new Exception("Database error");
}
pg_query($db, "DELETE FROM main.ctf_map_def WHERE id={$this->dbID}");
pg_close($db);
}
private function load() {
$db = __dbConnect();
if (!$db) {
throw new Exception("Database error");
}
$result = pg_query($db, "SELECT * FROM main.ctf_map_layout WHERE map = {$this->dbID}");
if (!($result && pg_num_rows($result) == $this->height * $this->width)) {
throw new Exception("Unable to load map");
}
$map = array();
while ($row = pg_fetch_assoc($result)) {
$offset = $this->getOffset($row['sys_x'], $row['sys_y']);
$map[$offset] = new ctf_map_sys($row['sys_x'], $row['sys_y'],
$row['sys_type'], $row['alloc_for'], $row['spawn_here']);
}
$this->map = $map;
pg_free_result($result);
pg_close($db);
}
private function initBlankMap() {
$map = array();
for ($i = 0; $i < $this->width * $this->height; $i ++) {
$map[$i] = null;
}
$this->map = $map;
}
private function getOffset($x, $y) {
return $this->width * (floor($this->height / 2) + $y) + floor($this->width / 2) + $x;
}
}
?>

494
admin/deathofrats.php Normal file
View file

@ -0,0 +1,494 @@
<html>
<head>
<title>LegacyWorlds Beta 5 > Administration > Death of Rats</title>
</head>
<body>
<h1><a href="index.html">LWB5 > Administration</a> > Death of Rats</h1>
<p>
The Death of Rats is LegacyWorlds' experimental multi detection tool.<br/>
Select page:
<?
set_magic_quotes_runtime(false);
include('config.inc');
switch ($_GET['p']) {
case 'e': $page = 'execution'; break;
case 'sl': $page = 'singlelog'; break;
case 'sp': $page = 'signlepoints'; break;
case 'ml': $page = 'multilog'; break;
case 'mp': $page = 'multipoints'; break;
case 'al': $page = 'actions'; break;
case 'fp': $page = 'finalpoints'; break;
case 'il': $page = 'ingamelog'; break;
default: $page = "status"; break;
}
$pages = array(
'status' => array('s', 'Current status', 'showStatus'),
'actions' => array('al', 'Actions taken', 'showActionLog'),
'finalpoints' => array('fp', 'Decision points', 'showFinalPoints'),
'ingamelog' => array('il', 'In-game checks', 'showInGameChecks'),
'multipoints' => array('mp', 'Multiplayer points', 'showMultiPoints'),
'multilog' => array('ml', 'Multiplayer log', 'showMultiLog'),
'signlepoints' => array('sp', 'Single player points', 'showSinglePoints'),
'singlelog' => array('sl', 'Single player events', 'showSingleLog'),
'execution' => array('e', 'Execution log', 'showExecLog'),
);
foreach ($pages as $pName => $data) {
if ($pName == $page) {
echo "<b>";
} else {
echo "<a href='?p={$data[0]}'>";
}
echo $data[1];
if ($pName == $page) {
echo "</b> ";
} else {
echo "</a> ";
}
}
echo "</p>";
$func = $pages[$page][2];
$func();
function showStatus() {
?>
<h2>Current status</h2>
<p>
The Death of Rats is still in an <b><u>experimental</u></b> stage at this time, and no actual action is taken. What
it <i>would</i> do if it were fully enabled is logged on the "Actions taken" page nonetheless.<br/>
Most of the information it provides can be trusted, tho; however, if you suspect it sent a warning or "punished" a
player for no good reason, manual checks should be performed.
</p>
<p>
The following checks are performed:
</p>
<ul>
<li>use of open proxies</li>
<li>cookie deletion</li>
<li>trying to log on with a banned account</li>
<li>passwords shared between multiple accounts</li>
<li>simple multiing, as well as pass sharing</li>
<li>"vicious" multiing, implying that the cookies are cleared between each use</li>
<li>in-game checks for donations, tech exchanges, gifts and sales, and planet retake after abandon</li>
</ul>
<p>
Checks for concurrent session from the same IP as well as more in-game checks (alliance, posts, messages,
TA list, battles) are still missing.
</p>
<h2>About the different pages</h2>
<p>
This tool consists in a few different pages which give different information about the Death of Rats' current status.
These pages are:
</p>
<ul>
<li>
<b>Actions taken</b>: the log of all actions the Death of Rats performed. This includes sending
warnings and deciding to punish players.
</li>
<li>
<b>Decision points</b>: the current amount of points for each pair of players that has been investigated thoroughly
by the Death of Rats. Pairs with over 100 points will cause the Death of Rats to act.
</li>
<li>
<b>In-game checks log</b>: the latest 400 entries of the checks performed in-game on suspicious players as well
as the results of these checks.
</li>
<li>
<b>Multiplayer points</b>: the current amount of points for each pair of accounts that could be multiing or
abusing pass-sharing.
</li>
<li>
<b>Multiplayer log</b>: the latest 200 entries of the suspicious events detected between pairs of accounts.
</li>
<li>
<b>Single player points</b>: the current amount of points for each account that has performed suspicious actions.
While these points are normally not a problem, they influence multiplayer scores.
</li>
<li>
<b>Single player log</b>: the latest 200 suspicious events detected for single accounts.
</li>
<li>
<b>Execution log</b>: the latest 200 runs of the Death of Rats.
</li>
</ul>
<?
}
function showExecLog() {
$db = __dbConnect();
$entries = array();
$q = pg_query($db, "SELECT * FROM main.dor_exec ORDER BY ts DESC LIMIT 200");
while ($r = pg_fetch_assoc($q)) {
$entries[] = $r;
}
pg_close($db);
?>
<h2>Previous 200 runs of the Death of Rats</h2>
<p>
This page shows the log of the previous 200 executions of the Death of Rats tick. The <i>Changes</i> column indicates
the amount of changes (connection records, password updates) examined; the <i>Events</i> column indicates the amount
of entries added to either the single player log or the multiplayer log.
</p>
<table border="1">
<tr>
<th>Time &amp; date</th>
<th>Changes</th>
<th>Events</th>
</tr>
<?
foreach ($entries as $entry) {
?>
<tr>
<td align="center"><?=$entry['events'] ? "<b>" : ""?><?=gmstrftime("%H:%M:%S / %Y-%m-%d", $entry['ts'])?><?=$entry['events'] ? "</b>" : ""?></td>
<td align="center"><?=$entry['events'] ? "<b>" : ""?><?=$entry['entries']?><?=$entry['events'] ? "</b>" : ""?></td>
<td align="center"><?=$entry['events'] ? "<b>" : ""?><?=$entry['events']?><?=$entry['events'] ? "</b>" : ""?></td>
</tr>
<?
}
?>
</table>
<?
}
function showSingleLog() {
$db = __dbConnect();
$entries = array();
$q = pg_query($db, "SELECT a.name,l.message,l.ts FROM main.dor_single l, main.account a WHERE a.id = l.account AND a.status NOT IN ('QUIT', 'INAC', 'KICKED') ORDER BY l.ts DESC,a.name ASC LIMIT 200");
while ($r = pg_fetch_assoc($q)) {
$entries[] = $r;
}
pg_close($db);
?>
<h2>Previous 200 single player log entries</h2>
<p>
This page shows the log of the previous 200 log entries generated for single players.
</p>
<table border="1">
<tr>
<th>Time &amp; date</th>
<th>Account</th>
<th align="left">Message</th>
</tr>
<?
$messages = array(
"ASSHOLE" => "Tried to log on using a banned account",
"PROXY" => "Currently using an open proxy",
"CLCOOK-SIP" => "Cleared cookies from the same IP",
"CLCOOK-DIP" => "Cleared cookies from a different (but close) IP",
);
foreach ($entries as $entry) {
?>
<tr>
<td align="center"><?=gmstrftime("%H:%M:%S / %Y-%m-%d", $entry['ts'])?>
<td align="center"><?=htmlentities($entry['name'])?></td>
<td><?=$messages[$entry['message']]?></td>
</tr>
<?
}
?>
</table>
<?
}
function showSinglePoints() {
$db = __dbConnect();
$entries = array();
$q = pg_query($db, "SELECT a.name,l.points FROM main.dor_single_points l, main.account a WHERE a.id = l.account AND a.status NOT IN ('QUIT', 'INAC', 'KICKED') ORDER BY l.points DESC,a.name ASC");
while ($r = pg_fetch_assoc($q)) {
$entries[] = $r;
}
pg_close($db);
?>
<h2>Single player "badness points"</h2>
<p>
These points correspond to recent suspicious activities from active accounts.
</p>
<table border="1">
<tr>
<th>Account</th>
<th>Points</th>
</tr>
<?
foreach ($entries as $entry) {
?>
<tr>
<td align="center"><?=htmlentities($entry['name'])?></td>
<td align="center"><?=$entry['points']?></td>
</tr>
<?
}
?>
</table>
<?
}
function showInGameChecks() {
$db = __dbConnect();
$entries = array();
$q = pg_query($db, "SELECT a1.name as name1, a2.name as name2, l.message, l.ts, l.game FROM main.dor_ingame_check l, main.account a1, main.account a2 WHERE a1.id = l.account1 AND a2.id = l.account2 AND a1.status NOT IN ('QUIT', 'INAC', 'KICKED') AND a2.status NOT IN ('QUIT', 'INAC', 'KICKED') ORDER BY l.ts DESC,a1.name ASC, a2.name ASC LIMIT 400");
while ($r = pg_fetch_assoc($q)) {
$entries[] = $r;
}
pg_close($db);
?>
<h2>Latest 400 in-game checks log entries</h2>
<p>
This page shows the log of the latest 400 log entries generated by in-game checks on players. Events logged here
belong to different categories:
</p>
<ul>
<li><b>Somewhat suspicious events</b>: donations of less than &euro;100,000; rejected tech offers</li>
<li>
<b>Suspicious events</b>: donations of less than &euro;1,000,000; pending tech offers; accepted techs offer with
a price greater than &euro;1,000; planets taken by a player within 5 days of being abandonned by the other; sales
of planets or fleets.
</li>
<li>
<b>Highly suspicious events</b>: donations of less than &euro;10,000,000; gifts; tech offers with a price lower
than &euro;1,000.
</li>
<li>
<b>Extremely suspicious events</b>: donations of more than &euro;10,000,000.
</li>
</ul>
<table border="1">
<tr>
<th>Time &amp; date</th>
<th>Game ID</th>
<th>Account 1</th>
<th>Account 2</th>
<th align="left">Message</th>
<th>Count</th>
</tr>
<?
$messages = array(
"CHECK" => "Verifying accounts",
"VHSE" => "Extremely suspicious in-game events",
"HSE" => "Highly suspicious in-game events",
"SE" => "Suspicious in-game events",
"LSE" => "Somewhat suspicious in-game events"
);
foreach ($entries as $entry) {
list($message, $count) = explode('-', $entry['message']);
if ($message == 'CHECK') {
$count = "N/A";
}
?>
<tr>
<td align="center"><?=gmstrftime("%H:%M:%S / %Y-%m-%d", $entry['ts'])?>
<td align="center"><?=$entry['game']?></td>
<td align="center"><?=htmlentities($entry['name1'])?></td>
<td align="center"><?=htmlentities($entry['name2'])?></td>
<td><?=$messages[$message]?></td>
<td align="center"><?=$count?></td>
</tr>
<?
}
?>
</table>
<?
}
function showMultiLog() {
$db = __dbConnect();
$entries = array();
$q = pg_query($db, "SELECT (a1.id || ',' || a2.id) as id, a1.name as name1, a2.name as name2, l.message, l.ts FROM main.dor_multi l, main.account a1, main.account a2 WHERE a1.id = l.account1 AND a2.id = l.account2 AND a1.status NOT IN ('QUIT', 'INAC', 'KICKED') AND a2.status NOT IN ('QUIT', 'INAC', 'KICKED') ORDER BY l.ts DESC,a1.name ASC, a2.name ASC LIMIT 400");
while ($r = pg_fetch_assoc($q)) {
$entries[] = $r;
}
pg_close($db);
$displayed = array();
?>
<h2>Previous 200 multiplayer log entries</h2>
<p>
This page shows the log of the previous 200 log entries generated for pairs of players.
</p>
<table border="1">
<tr>
<th>Time &amp; date</th>
<th>Account 1</th>
<th>Account 2</th>
<th align="left">Message</th>
</tr>
<?
$messages = array(
"SIMPLE" => "Simple multiing / open pass sharing detected",
"SIMPLE-10" => "Simple multiing / open pass sharing detected (within 10 seconds!)",
"PASS" => "Accounts are using the same password",
"NOPASS" => "Accounts are no longer using the same password",
"VICIOUS-LP" => "Potential attempt to conceal pass-sharing",
"VICIOUS-MP" => "Probable attempt to conceal pass-sharing",
"VICIOUS-HP" => "Highly probable attempt to conceal pass-sharing",
);
foreach ($entries as $entry) {
$id = explode(',', $entry['id']);
sort($id);
$id = join(',', $id) . "-" . $entry['ts'] . "-" . $entry['message'];
if (in_array($id, $displayed)) {
continue;
}
$displayed[] = $id;
?>
<tr>
<td align="center"><?=gmstrftime("%H:%M:%S / %Y-%m-%d", $entry['ts'])?>
<td align="center"><?=htmlentities($entry['name1'])?></td>
<td align="center"><?=htmlentities($entry['name2'])?></td>
<td><?=$messages[$entry['message']]?></td>
</tr>
<?
}
?>
</table>
<?
}
function showFinalPoints() {
$db = __dbConnect();
$entries = array();
$q = pg_query($db, "SELECT a1.name as name1, a2.name as name2, l.points FROM main.dor_final_points l, main.account a1, main.account a2 WHERE a1.id = l.account1 AND a2.id = l.account2 AND a1.status NOT IN ('QUIT', 'INAC', 'KICKED') AND a2.status NOT IN ('QUIT', 'INAC', 'KICKED') ORDER BY l.points DESC,a1.name ASC, a2.name ASC");
while ($r = pg_fetch_assoc($q)) {
$entries[] = $r;
}
pg_close($db);
?>
<h2>Final decision points</h2>
<p>
This page displays the current amount of points for each pair of players that has been investigated thoroughly
by the Death of Rats. Pairs will over 100 points will cause the Death of Rats to act.
</p>
<table border="1">
<tr>
<th>Account 1</th>
<th>Account 2</th>
<th>Points</th>
</tr>
<?
foreach ($entries as $entry) {
?>
<tr>
<td align="center"><?=htmlentities($entry['name1'])?></td>
<td align="center"><?=htmlentities($entry['name2'])?></td>
<td><?=$entry['points']?></td>
</tr>
<?
}
?>
</table>
<?
}
function showMultiPoints() {
$db = __dbConnect();
$entries = array();
$q = pg_query($db, "SELECT (a1.id || ',' || a2.id) as id, a1.name as name1, a2.name as name2, l.points FROM main.dor_multi_points l, main.account a1, main.account a2 WHERE a1.id = l.account1 AND a2.id = l.account2 AND a1.status NOT IN ('QUIT', 'INAC', 'KICKED') AND a2.status NOT IN ('QUIT', 'INAC', 'KICKED') ORDER BY l.points DESC,a1.name ASC, a2.name ASC");
while ($r = pg_fetch_assoc($q)) {
$entries[] = $r;
}
pg_close($db);
$displayed = array();
?>
<h2>Multiplayer "badness points"</h2>
<p>
This page shows the list of "badness points" between pairs of accounts. The higher the badness points, the more likely
the accounts are multis.
</p>
<table border="1">
<tr>
<th>Account 1</th>
<th>Account 2</th>
<th>Points</th>
</tr>
<?
foreach ($entries as $entry) {
$id = explode(',', $entry['id']);
sort($id);
$id = join(',', $id);
if (in_array($id, $displayed)) {
continue;
}
$displayed[] = $id;
?>
<tr>
<td align="center"><?=htmlentities($entry['name1'])?></td>
<td align="center"><?=htmlentities($entry['name2'])?></td>
<td><?=$entry['points']?></td>
</tr>
<?
}
?>
</table>
<?
}
function showActionLog() {
$db = __dbConnect();
$entries = array();
$q = pg_query($db,
"SELECT * FROM ("
. "SELECT a1.name AS name1, a2.name AS name2, l.ts AS ts, 'WARN' AS atype "
. "FROM main.dor_warning l, main.account a1, main.account a2 "
. "WHERE a1.id = l.account1 AND a2.id = l.account2 "
. "AND a1.status NOT IN ('QUIT', 'INAC', 'KICKED') "
. "AND a2.status NOT IN ('QUIT', 'INAC', 'KICKED') "
. "UNION SELECT a1.name AS name1, a2.name AS name2, l.ts AS ts, 'PUNISH' AS atype "
. "FROM main.dor_warning l, main.account a1, main.account a2 "
. "WHERE a1.id = l.account1 AND a2.id = l.account2 "
. "AND a1.status NOT IN ('QUIT', 'INAC', 'KICKED') "
. "AND a2.status NOT IN ('QUIT', 'INAC', 'KICKED')"
. ") AS t ORDER BY t.ts DESC, t.name1 ASC, t.name2 ASC"
);
while ($r = pg_fetch_assoc($q)) {
$entries[] = $r;
}
pg_close($db);
?>
<h2>Actions performed by the Death of Rats</h2>
<p>
This page lists all the actions the Death of Rats has performed.
</p>
<table border="1">
<tr>
<th>Time &amp; date</th>
<th>Account 1</th>
<th>Account 2</th>
<th align="left">Message</th>
</tr>
<?
$messages = array(
"WARN" => "Warned player",
"PUNISH" => "Slaughtered player with a rat-sized scythe"
);
foreach ($entries as $entry) {
?>
<tr>
<td align="center"><?=gmstrftime("%H:%M:%S / %Y-%m-%d", $entry['ts'])?>
<td align="center"><?=htmlentities($entry['name1'])?></td>
<td align="center"><?=htmlentities($entry['name2'])?></td>
<td><?=$messages[$entry['atype']]?></td>
</tr>
<?
}
?>
</table>
<?
}
?>
</body>
</html>

242
admin/game_status.php Normal file
View file

@ -0,0 +1,242 @@
<?php
set_magic_quotes_runtime(false);
include("config.inc");
include("as_log.inc");
function redirect() {
?>
<html>
<head>
<title>LegacyWorlds Beta 5 > Administration > Game status</title>
</head>
<body>
<h1><a href="index.html">LWB5 > Administration</a> > Game status</h1>
<h2>Operation in progress...</h2>
<p>
A system operation is in progress. Please wait, the page will update in 5 seconds.
</p>
<script language="JavaScript">
window.setTimeout('window.location="game_status.php"', 5000);
</script>
</body>
</html>
<?php
exit(0);
}
function printStatus($status) {
static $styles = array(
"PRE" => array('yellow', 'red'),
"READY" => array('red', 'yellow'),
"RUNNING" => array('white', 'green'),
"VICTORY" => array('yellow', 'blue'),
"ENDING" => array('black', 'yellow'),
"FINISHED" => array("white", "black")
);
print "<th style='color:" . $styles[$status][0] . ";background-color:"
. $styles[$status][1] . "'>$status</th>";
}
function sendFifo($command) {
global $aConfig;
$fName = $aConfig['ctrlFifo'];
if (!file_exists($fName)) {
return false;
}
$fifo = fopen($fName, "w");
fwrite($fifo, "$command\n");
fclose($fifo);
redirect();
}
function handleCommand($command, $game) {
if ($command == 'mv' && $game->status() == 'PRE') {
__logAdmin("is making game {$game->name} visible");
sendFifo("READY {$game->name}");
} elseif ($command == 'te' && $game->status() == 'READY' && $game->firstTick() - time() > 24 * 60 * 60 + 30) {
__logAdmin("made game {$game->name} start 24h earlier");
sendFifo("START {$game->name} EARLY");
} elseif ($command == 'tl' && $game->status() == 'READY') {
__logAdmin("made game {$game->name} start 24h later");
sendFifo("START {$game->name} LATE");
} elseif ($command == 'en' && ($game->status() == 'RUNNING' || $game->status() == "VICTORY")) {
__logAdmin("terminated game {$game->name}");
sendFifo("SETEND {$game->name} 0");
} elseif ($command == 'e24' && $game->status() == 'RUNNING') {
__logAdmin("set game {$game->name} to end in 24h");
sendFifo("SETEND {$game->name} 24");
} elseif ($command == 'kr' && $game->status() == 'ENDING') {
__logAdmin("prevented game {$game->name} from ending");
sendFifo("NOEND {$game->name}");
} elseif ($command == 'ee' && $game->status() == 'ENDING' && $game->lastTick() - time() > 24 * 60 * 60 + 30) {
__logAdmin("made game {$game->name} end 24h earlier");
sendFifo("END {$game->name} EARLY");
} elseif ($command == 'el' && $game->status() == 'ENDING') {
__logAdmin("made game {$game->name} end 24h later");
sendFifo("END {$game->name} LATE");
} elseif ($command == 'en' && $game->status() == 'ENDING') {
__logAdmin("terminated game {$game->name}");
sendFifo("END {$game->name} NOW");
}
}
// Load the list of games
$oldDir = getcwd();
chdir("../scripts");
$__logPrefix = "lwControl";
$__loader = array(
'log', 'classloader',
'version', 'game', 'tick', 'config',
'db_connection', 'db_accessor', 'db',
'library'
);
require_once("loader.inc");
chdir($oldDir);
$games = config::getGames();
dbConnect();
// Handle commands
if ($_GET['c'] != '') {
$cGame = $_GET['g'];
if (array_key_exists($cGame, $games) && $cGame != 'main') {
handleCommand($_GET['c'], $games[$cGame]);
}
}
?>
<html>
<head>
<title>LegacyWorlds Beta 5 > Administration > Game status</title>
</head>
<body>
<h1><a href="index.html">LWB5 > Administration</a> > Game status</h1>
<h2>Game list</h2>
<p>
<b>WARNING:</b> make sure you know what you're doing here - there are no second chances on this page;
if you click something, that "something" <i>will</i> happen <i>at once</i>.
</p>
<table border="1" width="100%">
<tr>
<th style="text-align:left; width:10%">ID</th>
<th style="width:10%">Status</th>
<th style="text-align:left;width:20%">Name</th>
<th style="text-align:left">Ticks</th>
<th style="text-align:left;width:30%">Commands</th>
</tr>
<?php
foreach ($games as $name => $game) {
if ($name == 'main') {
continue;
}
$status = $game->status();
$firstTick = $game->firstTick();
$lastTick = $game->lastTick();
print " <tr>\n <td><b>$name</b></td>\n";
printStatus($status);
print " <td>" . htmlentities($game->text) . "</td>\n";
print " <td>";
if ($firstTick > time()) {
print "Starting at " . gmstrftime('%H:%M:%S on %Y-%m-%d', $firstTick);
} elseif ($lastTick == 0) {
print "Running since " . gmstrftime('%H:%M:%S on %Y-%m-%d', $firstTick);
} elseif ($lastTick > time()) {
print "Running until " . gmstrftime('%H:%M:%S on %Y-%m-%d', $lastTick);
} else {
print "Stopped since " . gmstrftime('%H:%M:%S on %Y-%m-%d', $lastTick);
}
if ($status == 'PRE') {
$cmd = array(
array('mv', 'Make visible')
);
} elseif ($status == 'READY') {
$cmd = array(
array('tl', 'Start 24h later')
);
if ($firstTick - time() > 24 * 60 * 60 + 30) {
array_push($cmd, array('te', 'Start 24h earlier'));
}
} elseif ($status == 'RUNNING') {
$cmd = array(
array('e24', 'End in 24h'),
array('en', 'End now')
);
} elseif ($status == 'VICTORY') {
$cmd = array(
array('en', 'End game')
);
} elseif ($status == 'ENDING') {
$cmd = array(
array('el', 'Postpone by 24h')
);
if ($lastTick - time() > 24 * 60 * 60 + 30) {
array_push($cmd, array('ee', 'End 24h earlier'));
}
array_push($cmd, array('en', 'End now'));
array_push($cmd, array('kr', 'Keep running'));
} else {
$cmd = array();
}
print "</td>\n <td>";
if (count($cmd)) {
$lk = array();
foreach ($cmd as $c) {
array_push($lk, "<a href='?c=" . $c[0] . "&g=$name' onclick=\"return confirm('You selected \\'"
. $c[1] . "\\' on game \\'$name\\'. Please confirm.');\">" . $c[1] . "</a>");
}
print join(' - ', $lk);
} else {
print "&nbsp;";
}
print "</td>\n </tr>\n";
}
?>
</table>
<h3>About game status</h3>
<p>Games can have the following status:</p>
<table>
<tr>
<?printStatus('PRE');?>
<td>The game is configured, but is hidden for now</td>
</tr>
<tr>
<?printStatus('READY');?>
<td>The game is visible, but ticks have not started</td>
</tr>
<tr>
<?printStatus('RUNNING');?>
<td>The game is running normally</td>
</tr>
<tr>
<?printStatus('VICTORY');?>
<td>The game is still running but someone reached victory</td>
</tr>
<tr>
<?printStatus('ENDING');?>
<td>The game is still available but is about to end.</td>
</tr>
<tr>
<?printStatus('FINISHED');?>
<td>The game is no longer running and only visible through the rankings page</td>
</tr>
</table>
</body>
</html>

25
admin/index.html Normal file
View file

@ -0,0 +1,25 @@
<html>
<head>
<title>LegacyWorlds Beta 5 > Administration</title>
</head>
<body>
<h1>LW Beta 5 administration tools</h1>
<h2>Game management</h2>
<ul>
<li><a href="game_status.php">Game status</a>: display and manage existing games</li>
<li><a href="create.php?reset=1">Game creation</a>: create new LegacyWorlds rounds or matches</li>
<li><a href="set_default.php">Default game</a> (game for which rankings are displayed)</li>
<li><a href="deathofrats.php">Death of Rats</a>: experimental multi detection tool</li>
</ul>
<h2>Server management</h2>
<ul>
<li><a href="ticks.php">Ticks</a>: enable / disable the tick manager, run ticks manually</li>
<li><a href="proxy.php">Proxy detector</a>: control the detector's status and manually check for open proxies</li>
<li><a href="maintenance.php">Maintenance</a>: activate / de-activate maintenance mode</li>
<li><a href="maps.php">Maps management</a>: manage maps used for <i>Kings of the Hill</i> games</li>
<li><a href="bot.php">IRC bot</a>: control the IRC bot</li>
</ul>
</body>
</html>

79
admin/maintenance.php Normal file
View file

@ -0,0 +1,79 @@
<html>
<head>
<title>LegacyWorlds Beta 5 > Administration > Maintenance mode</title>
</head>
<body>
<h1><a href="index.html">LWB5 > Administration</a> > Maintenance mode</h1>
<?php
set_magic_quotes_runtime(false);
include('../scripts/config.inc');
include('as_log.inc');
$err = $reason = $duration = null;
if ($_GET['disable'] == '1' && !is_null($config['maintenance'])) {
unlink($config['cachedir'] . '/maintenance.ser');
include('../scripts/config.inc');
__logAdmin("put the server out of maintenance mode");
} elseif ($_POST['enable'] != '' && is_null($config['maintenance'])) {
$reason = $_POST['reason'];
$duration = (int) $_POST['duration'];
if (strlen($reason) < 10) {
$err = "Reason too short (min 10 characters).";
} elseif ($duration < 5) {
$err = "Duration too short (min 5 minutes).";
} else {
$maintenance = array(
"until" => time() + $duration * 60,
"reason" => $reason
);
$f = fopen($config['cachedir'] . '/maintenance.ser', "w");
fwrite($f, serialize($maintenance));
fclose($f);
include('../scripts/config.inc');
__logAdmin("put the server in maintenance mode for reason: $reason");
}
}
if (is_null($config['maintenance'])) {
?>
<p>
Maintenance mode is currently inactive. Please use the form below to activate it.
</p>
<form method="POST" action="?">
<p>
Reason for maintenance: <input type="text" maxlength="100" name="reason" size="40" value="<?=htmlentities($reason)?>" /><br/>
Maintenance mode duration: <input type="text" maxlength="3" name="duration" size="4" value="<?=$duration?>" /> minutes
</p>
<?php
if ($err) {
print "<p style='color:red'>$err</p>\n";
}
?>
<p>
<input type="submit" name="enable" value="Activate maintenance mode" />
</p>
</form>
<?php
} else {
?>
<p>
Maintenance mode is currently <b>active</b>.
</p>
<p>
<u>Reason:</u> <?=$config['maintenance']['reason']?><br/>
<u>Until:</u> <?=gmstrftime("%H:%M:%S on %m/%d/%Y", $config['maintenance']['until'])?>
(current: <?=gmstrftime("%H:%M:%S on %m/%d/%Y", time())?>).
</p>
<p><a href="?disable=1">Disable maintenance mode</a></p>
<?
}
?>
</body>
</html>

703
admin/map_edit.js Normal file
View file

@ -0,0 +1,703 @@
// Generic text input component
TextInput = function (id, title, multi, min, max, init) {
this.id = id;
this.title = title;
this.multi = multi;
var value = init;
this.min = min;
this.max = max;
this.valid = false;
this.onChange = null;
var readValue = function () {
var e = document.getElementById(id + '-input');
if (e) {
value = e.value;
}
};
this.getText = function () {
readValue();
return value;
};
this.draw = function () {
readValue();
var str = '<table style="width: 100%; border-style: none; padding: 2px; margin: 0px">'
+ '<tr><th style="text-align:right; padding: 0px 5px; width: 120px;vertical-align:top">'
+ this.title + ':</th><td style="text-align: center">';
var jsStr = '="TextInput.byId[\'' + this.id + '\'].__change(); return true"';
if (this.multi) {
str += '<textarea id="' + this.id + '-input" rows="5" style="width: 100%" onChange'
+ jsStr + ' onKeyUp' + jsStr + ' onClick' + jsStr + '></textarea>';
} else {
str += '<input type="text" id="' + this.id + '-input" style="width: 100%" onChange'
+ jsStr + ' onKeyUp' + jsStr + ' onClick' + jsStr + '/>';
}
str += '</td></tr></table>';
document.getElementById(this.id).innerHTML = str;
document.getElementById(this.id + '-input').value = value;
this.checkValidity();
};
this.checkValidity = function () {
this.valid = (this.min == 0 && this.max == 0);
if (!this.valid) {
this.valid = (this.min > 0 && value.length >= this.min || this.min == 0)
&& (this.max > 0 && value.length <= this.max || this.max == 0);
}
with (document.getElementById(this.id + '-input').style) {
color = this.valid ? 'black' : 'white';
backgroundColor = this.valid ? 'white' : 'red';
}
};
this.__change = function () {
readValue();
this.checkValidity();
if (this.onChange) {
this.onChange(value);
}
};
TextInput.byId[this.id] = this;
};
TextInput.byId = {};
// Generic numeric control for size and amount of alliances
NumericControl = function (id, title, min, max, init) {
this.id = id;
this.title = title;
this.min = min;
this.max = max;
this.value = init;
this.onChange = null;
this.draw = function () {
var str = '<table style="width: 100%; border-style: none; padding: 2px; margin: 0px">'
+ '<tr><th style="text-align:right; padding: 0px 5px">' + this.title
+ ':</th><td style="text-align: center; width: 20px">' + this.value
+ '</td><td style="width: 70px; text-align:center">'
+ '<input type="button" onClick="NumericControl.byId[\''
+ this.id + '\'].decrease()" value="-" style="width: 24px" /> '
+ '<input type="button" onClick="NumericControl.byId[\''
+ this.id + '\'].increase()" value="+" style="width: 24px" /></td>'
+ '</tr></table>';
document.getElementById(this.id).innerHTML = str;
};
this.increase = function () {
if (this.value == this.max) {
return;
}
this.value ++;
this.draw();
if (this.onChange) {
this.onChange(this.value);
}
};
this.decrease = function () {
if (this.value == this.min) {
return;
}
this.value --;
this.draw();
if (this.onChange) {
this.onChange(this.value);
}
};
NumericControl.byId[this.id] = this;
};
NumericControl.byId = {};
// A system on the map
MapLocation = function (type, alloc, spawn) {
this.type = type;
this.alloc = alloc;
this.spawn = spawn;
};
// The map itself
Map = function (initFrom) {
// Copy basic map information
this.name = initFrom.name;
this.description = initFrom.description;
this.alliances = initFrom.alliances;
this.width = initFrom.width;
this.height = initFrom.height;
// Copy the map
this.map = { };
for (var i in initFrom.map) {
var ma = initFrom.map[i];
this.map['x' + ma[0] + 'y' + ma[1]] = new MapLocation(ma[2], ma[3], ma[4]);
}
// Function that computes min/max x/y
this.updateCoordinates = function () {
this.minX = - Math.floor(this.width / 2);
this.maxX = this.minX + this.width - 1;
this.minY = - Math.floor(this.height / 2);
this.maxY = this.minY + this.height - 1;
};
// Creates a nebula area
this.setNebula = function (x, y, opacity) {
if (this.map['x' + x + 'y' + y]) {
this.map['x' + x + 'y' + y].type = opacity;
} else {
this.map['x' + x + 'y' + y] = new MapLocation(opacity, null, null);
}
};
// Creates a target system
this.setTarget = function (x, y) {
if (this.map['x' + x + 'y' + y]) {
this.map['x' + x + 'y' + y].type = 'S';
this.map['x' + x + 'y' + y].alloc = 0;
} else {
this.map['x' + x + 'y' + y] = new MapLocation('S', 0, null);
}
};
// Creates an alliance-controlled system
this.setAlliance = function (x, y, alliance) {
var sys = this.map['x' + x + 'y' + y];
if (sys) {
sys.type = 'S';
sys.alloc = alliance;
sys.spawn = false;
} else {
this.map['x' + x + 'y' + y] = new MapLocation('S', alliance, false);
}
};
// Switches spawning status for an alliance-controlled system
this.switchSpawnPoint = function (x, y) {
var sys = this.map['x' + x + 'y' + y];
if (sys && sys.type == 'S' && sys.alloc > 0) {
sys.spawn = !sys.spawn;
}
};
// Removes systems allocated to alliances which no longer exist
this.removeExtraAlliances = function () {
for (var i in this.map) {
var sys = this.map[i];
if (sys.type == 'S' && sys.alloc > this.alliances) {
this.map[i] = null;
}
}
};
this.updateCoordinates();
};
// The editor's grid
Grid = function (id, map) {
this.id = id;
this.map = map;
this.cX = 0;
this.cY = 0;
this.onClick = null;
// This function draws the grid in which the map is displayed
this.draw = function () {
var i, j;
var str = '<table style="border: 1px solid black; border-collapse: collapse; padding: 0px; margin: 0px">'
+ '<tr><td style="border: 1px solid black;width: 32px;height:32px">&nbsp;</td>'
+ '<td style="border: 1px solid black; width:416px" colspan="13" id="map-up">&nbsp;</td>'
+ '<td style="border: 1px solid black;width: 32px">&nbsp;</td></tr>'
+ '<tr><td style="border: 1px solid black; height:416px" rowspan="13" id="map-left">&nbsp;</td>'
+ '<td style="border: 1px solid black;width: 32px;height:32px">&nbsp;</td>';
for (i = 0; i < 11; i ++) {
str += '<td style="border: 1px solid black;width: 32px; height: 32px; text-align: center" '
+ 'id="top-x-' + i + '">&nbsp;</td>';
}
str += '<td style="border: 1px solid black;width: 32px;height:32px">&nbsp;</td>'
+ '<td style="border: 1px solid black; height:416px" rowspan="13" id="map-right">&nbsp;</td>'
+ '</tr>';
for (i = 0; i < 11; i ++) {
str += '<tr><td style="border: 1px solid black;width: 32px; height: 32px; text-align: center" '
+ 'id="left-y-' + i + '">&nbsp;</td>';
for (j = 0; j < 11; j ++) {
str += '<td style="border: 1px solid #7f7f7f; width: 32px; height: '
+ '32px; text-align:center" id="map-' + j + '-' + i
+ '" onclick="Editor.editor.mapClick(' + j + ',' + i +')">&nbsp;</td>';
}
str += '<td style="border: 1px solid black;width: 32px; height: 32px; text-align:center" '
+ 'id="right-y-' + i + '">&nbsp;</td></tr>';
}
str += '<tr><td style="border: 1px solid black;width: 32px;height:32px">&nbsp;</td>';
for (i = 0; i < 11; i ++) {
str += '<td style="border: 1px solid black;width: 32px; height: 32px;text-align:center" '
+ 'id="bottom-x-' + i + '">&nbsp;</td>';
}
str += '<td style="border: 1px solid black;width: 32px;height:32px">&nbsp;</td></tr>'
+ '<tr><td style="border: 1px solid black;width: 32px; height:32px">&nbsp;</td>'
+ '<td style="border: 1px solid black; width:416px" colspan="13" id="map-down">&nbsp;</td>'
+ '<td style="border: 1px solid black;width: 32px">&nbsp;</td></tr>'
+ '</table>';
document.getElementById(this.id).innerHTML = str;
this.drawMap();
};
// This function draws the map on the grid
this.drawMap = function () {
var i, j, str, x, y;
// Scroll buttons
if (this.cX - 5 > this.map.minX) {
str = '<input type="button" value="<" style="width:100%;height:100%;margin:0"'
+ ' onclick="Editor.editor.scroll(-1, 0)" />';
} else {
str = '&nbsp;';
}
document.getElementById('map-left').innerHTML = str;
if (this.cX + 5 < this.map.maxX) {
str = '<input type="button" value=">" style="width:100%;height:100%;margin:0"'
+ ' onclick="Editor.editor.scroll(1, 0)" />';
} else {
str = '&nbsp;';
}
document.getElementById('map-right').innerHTML = str;
if (this.cY - 5 > this.map.minY) {
str = '<input type="button" value="\\/" style="width:100%;height:100%;margin:0"'
+ ' onclick="Editor.editor.scroll(0, -1)" />';
} else {
str = '&nbsp;';
}
document.getElementById('map-down').innerHTML = str;
if (this.cY + 5 < this.map.maxY) {
str = '<input type="button" value="/\\" style="width:100%;height:100%;margin:0"'
+ ' onclick="Editor.editor.scroll(0, 1)" />';
} else {
str = '&nbsp;';
}
document.getElementById('map-up').innerHTML = str;
// Draw X coordinates
for (i = 0; i < 11; i ++) {
x = this.cX + i - 5;
if (x < this.map.minX || x > this.map.maxX) {
str = '&nbsp;';
} else {
str = '<b>' + x + '</b>';
}
document.getElementById('top-x-' + i).innerHTML =
document.getElementById('bottom-x-' + i).innerHTML = str;
}
// Draw Y coordinates
for (i = 0; i < 11; i ++) {
y = this.cY - i + 5;
if (y < this.map.minY || y > this.map.maxY) {
str = '&nbsp;';
} else {
str = '<b>' + y + '</b>';
}
document.getElementById('left-y-' + i).innerHTML =
document.getElementById('right-y-' + i).innerHTML = str;
}
// Draw contents
for (i = 0; i < 11; i ++) {
x = this.cX + i - 5;
for (j = 0; j < 11; j ++) {
y = this.cY - j + 5;
var cell = document.getElementById('map-' + i + '-' + j);
if (y < this.map.minY || y > this.map.maxY || x < this.map.minX || x > this.map.maxX) {
cell.innerHTML = '&nbsp;';
cell.style.backgroundColor = 'black';
continue;
}
var sys = this.map.map['x' + x + 'y' + y];
if (!sys) {
cell.innerHTML = '&nbsp;';
cell.style.backgroundColor = '#3f3f3f';
} else if (sys.type != 'S') {
cell.innerHTML = '<b>' + sys.type + '</b>';
cell.style.backgroundColor = '#afafaf';
cell.style.color = Grid.nebulaColours[parseInt(sys.type, 10) - 1];
} else if (sys.alloc == 0) {
cell.innerHTML = 'T';
cell.style.backgroundColor = 'black';
cell.style.color = 'white';
} else {
cell.style.color = 'black';
cell.style.backgroundColor = Grid.allianceColours[sys.alloc - 1];
cell.innerHTML = sys.spawn ? 'X' : '&nbsp;';
}
}
}
};
// This function handle clicks on the map
this.handleClick = function(i, j) {
x = this.cX + i - 5;
y = this.cY - j + 5;
if (x >= this.map.minX && x <= this.map.maxX
&& y >= this.map.minY && y <= this.map.maxY && this.onClick) {
this.onClick(x, y);
}
};
};
Grid.allianceColours = [
'ff0000', '00ff00', '0000ff', '007f7f', '7f007f', 'afaf00', 'ffaf3f', '003f7f'
];
Grid.nebulaColours = [
'#ff0000', '#ff2f00', '#ff5f00', '#ff7f00'
];
// Toolbox
Toolbox = function (id, map) {
this.id = id;
this.map = map;
this.currentTool = null;
var drawToolCell = function (id, title, ctxt, cbg, cfg) {
return str = '<tr><td><table style="width:100%;padding:6px;margin:0px" id="tool-' + id
+ '" onClick="Editor.editor.selectTool(\'' + id + '\');"><tr>'
+ '<td style="color:' + cfg + '; background-color: ' + cbg
+ '; text-align:center;width:32px;height:32px">' + ctxt + '</td>'
+ '<td style="text-align:center;font-weight:bold">' + title + '</td>'
+ '</tr></table></td></tr>';
};
this.draw = function () {
var i, str = '<table style="width: 200px; border-style: none">'
+ '<tr><th style="font-size: 120%">Map drawing tools</th></tr>'
+ '<tr><th>Nebulae</th></tr>';
for (i = 1; i < 5; i ++) {
str += drawToolCell('n' + i, 'Class ' + i + ' nebula', '<b>' + i + '</b>',
'#afafaf', Grid.nebulaColours[i - 1]);
}
str += '<tr><th>Misc</th></tr>'
+ drawToolCell('tg', 'Target system', 'T', 'black', 'white')
+ drawToolCell('sp', 'Spawing point', 'X', 'white', 'black')
+ '<tr><th>Alliances</th></tr>';
for (i = 1; i <= this.map.alliances; i ++) {
str += drawToolCell('a' + i, 'Alliance ' + i, '&nbsp;', Grid.allianceColours[i - 1], 'black');
}
str += '</table>';
document.getElementById(this.id).innerHTML = str;
if (this.currentTool) {
this.selectTool(this.currentTool);
}
};
this.selectTool = function(tool) {
if (this.currentTool && document.getElementById('tool-' + this.currentTool)) {
document.getElementById('tool-' + this.currentTool).style.borderStyle = 'none';
}
if (! document.getElementById('tool-' + tool)) {
this.currentTool = null;
return;
}
with (document.getElementById('tool-' + tool).style) {
borderColor = 'red';
borderWidth = '2px';
borderStyle = 'solid';
}
this.currentTool = tool;
};
};
// Validity check / submit button
CheckAndSubmit = function (id, map) {
this.id = id;
this.map = map;
this.error = "---";
var mapCheck = function (map) {
var ax = [];
var tgc = 0;
for (var i = 0; i < map.alliances; i ++) {
ax[i] = [0, 0];
}
for (var i = map.minX; i <= map.maxX; i ++) {
for (var j = map.minY; j <= map.maxY; j ++) {
var m = map.map['x' + i + 'y' + j];
if (! m) {
return 1;
}
if (m.type != 'S') {
continue;
}
if (m.alloc == 0) {
tgc ++;
continue;
}
ax[m.alloc - 1][0] ++;
if (m.spawn) {
ax[m.alloc - 1][1] ++;
}
}
}
if (tgc == 0) {
return 2;
}
var min = -1;
for (var i = 0; i < map.alliances; i ++) {
if (ax[i][0] == 0) {
return 3 + i;
}
if (min == -1) {
min = ax[i][0];
} else if (ax[i][0] < min) {
return 19;
} else if (ax[i][0] > min) {
return 19 + i;
}
}
min = -1;
for (var i = 0; i < map.alliances; i ++) {
if (ax[i][1] == 0) {
return 11 + i;
}
if (min == -1) {
min = ax[i][1];
} else if (ax[i][1] < min) {
return 27;
} else if (ax[i][1] > min) {
return 27 + i;
}
}
return 0;
};
this.draw = function () {
if (this.error == '---') {
this.check();
}
var str;
if (this.error == "") {
str = '<input type="button" value="Save map" onclick="Editor.editor.submit()" />';
} else {
str = '<span style="color:red;font-weight:bold">' + this.error + '</span>';
}
document.getElementById(this.id).innerHTML = str;
};
this.check = function () {
var error = "";
if (map.name.length < 4) {
error = "Name too short";
} else if (map.name.length > 32) {
error = "Name too long";
} else {
var i = mapCheck(this.map);
switch (i) {
case 0: break;
case 1: error = "Map has undefined areas"; break;
case 2: error = "Map has no target areas"; break;
default:
if (i < 11) {
i -= 2;
error = "Alliance " + i + " has no systems.";
} else if (i < 19) {
i -= 10;
error = "Alliance " + i + " has no spawning points.";
} else if (i < 27) {
i -= 18;
error = "Alliance " + i + " has too many systems.";
} else if (i < 35) {
i -= 26;
error = "Alliance " + i + " has too many spawning points.";
}
break;
}
}
if (this.error != error) {
this.error = error;
this.draw();
}
};
};
// Main editor object
Editor = function (initFrom) {
var map = new Map(initFrom);
var components = [];
var cSub = new CheckAndSubmit('check-and-send', map);
var tools = new Toolbox('tools', map);
components.push(tools);
var grid = new Grid('grid', map);
grid.onClick = function(x, y) {
var tool = tools.currentTool;
if (!tool) {
return;
}
if (tool.match(/^n[1-4]$/)) {
map.setNebula(x, y, tool.charAt(1));
} else if (tool == 'tg') {
map.setTarget(x, y);
} else if (tool.match(/^a[1-8]$/)) {
map.setAlliance(x, y, parseInt(tool.charAt(1), 10));
} else if (tool == 'sp') {
map.switchSpawnPoint(x, y);
}
grid.drawMap();
cSub.check();
};
components.push(grid);
var c;
c = new TextInput('name', 'Map name', false, 4, 32, map.name);
c.onChange = function (value) {
map.name = value;
cSub.check();
};
components.push(c);
c = new TextInput('desc', 'Description', true, 0, 0, map.description);
c.onChange = function (value) {
map.description = value;
};
components.push(c);
c = new NumericControl('n-alliances', 'Alliances', 2, 8, map.alliances);
c.onChange = function (value) {
var old = map.alliances;
map.alliances = value;
tools.draw();
if (value < old) {
map.removeExtraAlliances();
grid.drawMap();
}
cSub.check();
};
components.push(c);
c = new NumericControl('m-width', 'Map width', 3, 41, map.width);
c.onChange = function (value) {
map.width = value;
map.updateCoordinates();
grid.drawMap();
cSub.check();
};
components.push(c);
c = new NumericControl('m-height', 'Map height', 3, 41, map.height);
c.onChange = function (value) {
map.height = value;
map.updateCoordinates();
grid.drawMap();
cSub.check();
};
components.push(c);
components.push(cSub);
this.draw = function () {
var str = '<h3>Parameters</h3>'
+ '<table style="width: 100%; border-style: none; margin: 0px; padding: 0px">'
+ '<tr><td colspan="3" id="name">&nbsp;</td></tr>'
+ '<tr><td colspan="3" id="desc">&nbsp;</td></tr>'
+ '<tr><td style="width: 33%" id="n-alliances">&nbsp;</td>'
+ '<td style="width: 34%" id="m-width">&nbsp;</td>'
+ '<td style="width: 33%" id="m-height">&nbsp;</td></tr>'
+ '<tr><td colspan="3" id="check-and-send" style="text-align:center">&nbsp;</td></tr>'
+ '</table>'
+ '<h3>Map</h3>'
+ '<div><div id="tools" style="float:right">&nbsp;</div><div id="grid">&nbsp;</div></div>';
document.getElementById('mapedit').innerHTML = str;
for (var i in components) {
components[i].draw();
}
};
this.scroll = function (dx, dy) {
grid.cX += dx; grid.cY += dy;
grid.drawMap();
};
this.mapClick = function(x,y) {
grid.handleClick(x, y);
};
this.selectTool = function(tool) {
tools.selectTool(tool);
};
this.submit = function () {
document.getElementById('sf-name').value = map.name;
document.getElementById('sf-desc').value = map.description;
document.getElementById('sf-width').value = map.width;
document.getElementById('sf-height').value = map.height;
document.getElementById('sf-alliances').value = map.alliances;
var ma = [];
for (var j = map.minY; j <= map.maxY; j ++) {
var str = '';
for (var i = map.minX; i <= map.maxX; i ++) {
var m = map.map['x' + i + 'y' + j];
str += m.type;
if (m.type != 'S') {
continue;
}
str += m.alloc;
if (m.alloc == 0) {
continue;
}
str += m.spawn ? '1' : '0';
}
ma.push(str);
}
document.getElementById('sf-map').value = ma.join('#');
document.getElementById('sendform').submit();
};
};
Editor.editor = new Editor(initMap);
Editor.editor.draw();

189
admin/maps.php Normal file
View file

@ -0,0 +1,189 @@
<?php
include('config.inc');
include('ctf_map.inc');
session_start();
function handleInput() {
if ($_GET['c'] == 'n') {
$op = 'e';
$_SESSION['edit_map'] = new ctf_map();
} elseif ($_GET['c'] == 'e') {
$op = 'e';
$_SESSION['edit_map'] = new ctf_map($_GET['id']);
} elseif ($_GET['c'] == 'd') {
if ($_GET['ok']) {
$map = new ctf_map($_GET['id']);
$map->destroy();
$op = '';
} else if ($_GET['cancel']) {
$op = "";
} else {
$op = 'd';
}
} elseif ($_POST['c'] == 'ms' && $_SESSION['edit_map'] instanceof ctf_map) {
$map = $_SESSION['edit_map'];
$map->setName(stripslashes($_POST['name']));
$map->setDescription(stripslashes($_POST['desc']));
$map->setWidth((int) $_POST['width']);
$map->setHeight((int) $_POST['height']);
$map->setAlliances((int) $_POST['alliances']);
$minY = -floor($map->getHeight() / 2); $maxY = $minY + $map->getHeight() - 1;
$minX = -floor($map->getWidth() / 2); $maxX = $minX + $map->getWidth() - 1;
$layout = explode('#', $_POST['map']);
for ($y = $minY; $y <= $maxY; $y ++) {
$str = array_shift($layout);
for ($x = $minX; $x <= $maxX; $x ++) {
$type = $str{0};
$map->setSystemType($x, $y, $type);
if ($type != 'S') {
$str = substr($str, 1);
continue;
}
$alloc = (int) $str{1};
$map->setSystemAlloc($x, $y, $alloc);
if ($alloc == 0) {
$str = substr($str, 2);
continue;
}
$map->setSystemSpawn($x, $y, $str{2} == '1');
$str = substr($str, 3);
}
}
$map->save();
$_SESSION['edit_map'] = null;
$op = '';
} else {
$op = '';
}
return $op;
}
function listMaps() {
?>
<h2>Available maps</h2>
<?php
$maps = ctf_map::allMaps();
if (count($maps) == 0) {
?>
<p>
There are no maps on the server at this time.
</p>
<?php
} else {
?>
<table border="1">
<tr>
<th align="left">Name &amp; description</th>
<th align="center">Size</th>
<th align="center">Alliances</th>
<th align="left">&nbsp;</th>
</tr>
<?php
foreach ($maps as $map) {
?>
<tr>
<td style='vertical-align:top'><?="<u>" . htmlentities($map->getName()) . "</u>"
. (is_null($map->getDescription()) ? "" : ("<br/>" . htmlentities($map->getDescription())))?></td>
<td style='text-align:center'><?=$map->getWidth()?>x<?=$map->getHeight()?></td>
<td style='text-align:center'><?=$map->getAlliances()?></td>
<td><a href="?c=e&id=<?=$map->getID()?>">Edit</a> - <a href="?c=d&id=<?=$map->getID()?>">Delete</a></td>
</tr>
<?php
}
?>
</table>
<?
}
?>
<p>
<a href='?c=n'>Create a map</a>
</p>
<?php
}
function editMap() {
?>
<h2>Map editor</h2>
<form method="POST" action="?" onSubmit="return false;">
<div id="mapedit"><p>Loading, please wait ...</p></div>
</form>
<form method="POST" action="?" id="sendform" style="display: none">
<input type="hidden" name="c" value="ms" />
<input type="hidden" id="sf-name" name="name" value="" />
<input type="hidden" id="sf-desc" name="desc" value="" />
<input type="hidden" id="sf-width" name="width" value="" />
<input type="hidden" id="sf-height" name="height" value="" />
<input type="hidden" id="sf-alliances" name="alliances" value="" />
<input type="hidden" id="sf-map" name="map" value="" />
</form>
<script language="JavaScript"><!--
var initMap = {
name: '<?=addslashes($_SESSION['edit_map']->getName())?>',
description: '<?=preg_replace(array('/\\n/', '/\\r/'), array('\\n', '\\r'), addslashes($_SESSION['edit_map']->getDescription()))?>',
alliances: <?=$_SESSION['edit_map']->getAlliances()?>,
width: <?=$_SESSION['edit_map']->getWidth()?>,
height: <?=$_SESSION['edit_map']->getHeight()?>,
map: [ <?=$_SESSION['edit_map']->jsDump()?> ]
};
//--></script>
<script language="JavaScript" src="map_edit.js"></script>
<?
}
function confirmDelete() {
$map = new ctf_map((int)$_GET['id']);
?>
<h2>Map deletion</h2>
<p>
You are about to delete the map called <b><?=htmlentities($map->getName())?></b>.<br/>
Please confirm.
</p>
<form method="GET" action="?">
<input type="hidden" name="c" value="d" />
<input type="hidden" name="id" value="<?=$map->getID()?>" />
<input type="submit" name="ok" value="Confirm" />
<input type="submit" name="cancel" value="Cancel" />
</form>
<?
}
?>
<html>
<head>
<title>LegacyWorlds Beta 5 > Administration > Maps management</title>
</head>
<body>
<h1><a href="index.html">LWB5 > Administration</a> > Maps management</h1>
<p>
The purpose of this tool is to create new maps, edit existing ones or delete unused ones.
</p>
<?php
$h = handleInput();
switch($h) :
case 'e':
editMap();
break;
case 'd':
confirmDelete();
break;
default:
listMaps();
break;
endswitch;
?>
</body>
</html>

128
admin/proxy.php Normal file
View file

@ -0,0 +1,128 @@
<?php
set_magic_quotes_runtime(false);
include('config.inc');
include('../scripts/config.inc');
include('as_manager.inc');
include('as_log.inc');
function redirect() {
?>
<html>
<head>
<title>LegacyWorlds Beta 5 > Administration > Proxy detector</title>
</head>
<body>
<h1><a href="index.html">LWB5 > Administration</a> > Proxy detector</h1>
<h2>Operation in progress...</h2>
<p>
A system operation is in progress. Please wait, the page will update in 5 seconds.
</p>
<script language="JavaScript">
window.setTimeout('window.location="proxy.php"', 5000);
</script>
</body>
</html>
<?php
exit(0);
}
function startDetector() {
__logAdmin("is starting the proxy detector");
__sendControl("PCON");
redirect();
}
function stopDetector() {
__logAdmin("is stopping the proxy detector");
__sendControl("PCOFF");
redirect();
}
$oldDir = getcwd();
chdir("../scripts");
$__loader = array(
'log', 'classloader',
'version', 'game', 'tick',
'config', 'pcheck'
);
require_once("loader.inc");
chdir($oldDir);
$isRunning = pcheck::isRunning();
if ($_GET['c'] == 'sd') {
startDetector();
} elseif ($_GET['c'] == 'kd') {
stopDetector();
} elseif ($_GET['ip'] != '') {
$ip = $_GET['ip'];
$status = "";
if (preg_match('/^\d{1,3}(\.\d{1,3}){3}$/', $ip)) {
if ($ip == "127.0.0.1") {
$status = "Host not allowed";
} else {
$addr = explode('.', $ip);
foreach ($addr as $piece) {
if ($piece > 254) {
$status = "Invalid IP address";
break;
}
}
if ($status == "") {
try {
$result = pcheck::check(array($ip));
$status = "$ip - ";
switch ($result[$ip]) {
case -1: $status .= "detection failed"; break;
case 0: $status .= "no proxy detected"; break;
case 1: $status .= "OPEN PROXY DETECTED!"; break;
}
} catch (Exception $e) {
$status = $e->getMessage();
}
}
}
} else {
$status = "Invalid IP address";
}
} else {
$status = $ip = "";
}
?>
<html>
<head>
<title>LegacyWorlds Beta 5 > Administration > Proxy detector</title>
</head>
<body>
<h1><a href="index.html">LWB5 > Administration</a> > Proxy detector</h1>
<?php
if ($isRunning) {
?>
<p>
Proxy detector is <b>running</b>; process ID #<?=$isRunning?>. <a href="?c=kd">Stop detector</a>
</p>
<form action="?" method="GET">
<p>
Manually check address <input type="text" size="16" maxlength="15" name="ip" value="<?=htmlentities($ip, ENT_QUOTES)?>" />
<input type="submit" value="Scan" />
<?=($status != '') ? ('<br/><b>' . $status . '</b>') : ''?>
</p>
</form>
<?php
} else {
?>
<p>
Proxy detector is <b>not running</b>. <a href="?c=sd">Start detector</a>
</p>
<?php
}
?>
</body>
</html>

104
admin/set_default.php Normal file
View file

@ -0,0 +1,104 @@
<?php
set_magic_quotes_runtime(false);
include('config.inc');
include('as_log.inc');
function redirect() {
?>
<html>
<head>
<title>LegacyWorlds Beta 5 > Administration > Default game</title>
</head>
<body>
<h1><a href="index.html">LWB5 > Administration</a> > Default game</h1>
<h2>Operation in progress...</h2>
<p>
A system operation is in progress. Please wait, the page will update in 2 seconds.
</p>
<script language="JavaScript">
window.setTimeout('window.location="set_default.php"', 2000);
</script>
</body>
</html>
<?php
exit(0);
}
function sendFifo($command) {
global $aConfig;
$fName = $aConfig['ctrlFifo'];
if (!file_exists($fName)) {
return false;
}
$fifo = fopen($fName, "w");
fwrite($fifo, "$command\n");
fclose($fifo);
}
// Load the list of games
$oldDir = getcwd();
chdir("../scripts");
$__logPrefix = "lwControl";
$__loader = array(
'log', 'classloader',
'version', 'game', 'tick', 'config',
'db_connection', 'db_accessor', 'db',
'library'
);
require_once("loader.inc");
chdir($oldDir);
dbConnect();
if ($_GET['d'] != '') {
$cDef = config::getDefaultGame();
$games = config::getGames();
if ($cDef->name != $_GET['d'] && array_key_exists($_GET['d'], $games) && $_GET['d'] != 'main') {
sendFifo("SETDEF {$_GET['d']}");
redirect();
}
}
$games = config::getGames();
$defGame = config::getDefaultGame();
?>
<html>
<head>
<title>LegacyWorlds Beta 5 > Administration > Default game</title>
</head>
<body>
<h1><a href="index.html">LWB5 > Administration</a> > Default game</h1>
<p>
The <b>default game</b> is the game for which overall round rankings are displayed on the site's
main page.
</p>
<form action="?" method="GET">
<p>
Current default game:
<select name="d">
<?php
foreach ($games as $id => $game) {
if ($id == "main" || $game->status() == 'PRE') {
continue;
}
print " <option value='$id'";
if ($defGame->name == $id) {
echo " selected='selected'";
}
echo ">" . htmlentities($game->text) . "</option>\n";
}
?>
</select>
<input type="submit" value="Change" />
</p>
</form>
</body>
</html>

221
admin/ticks.php Normal file
View file

@ -0,0 +1,221 @@
<?php
set_magic_quotes_runtime(false);
include('config.inc');
include('../scripts/config.inc');
include('as_manager.inc');
include('as_log.inc');
function redirect() {
?>
<html>
<head>
<title>LegacyWorlds Beta 5 > Administration > Ticks</title>
</head>
<body>
<h1><a href="index.html">LWB5 > Administration</a> > Ticks</h1>
<h2>Operation in progress...</h2>
<p>
A system operation is in progress. Please wait, the page will update in 5 seconds.
</p>
<script language="JavaScript">
window.setTimeout('window.location="ticks.php"', 5000);
</script>
</body>
</html>
<?php
exit(0);
}
function ticksActive() {
global $config;
$stopped = $config['cachedir'] . '/ticks_stopped';
$stop = $config['cachedir'] . '/stop_ticks';
$start = $config['cachedir'] . '/start_ticks';
return (file_exists($start) || file_exists($stop)) ? 'pending' : !file_exists($stopped);
}
function startManager() {
global $aConfig;
__logAdmin("is starting the ticks manager");
$fName = $aConfig['ctrlFifo'];
if (!file_exists($fName)) {
return false;
}
$fifo = fopen($fName, "w");
fwrite($fifo, "TMINIT\n");
fclose($fifo);
redirect();
}
function killManager() {
global $aConfig;
__logAdmin("is stopping the ticks manager");
$fName = $aConfig['ctrlFifo'];
if (!file_exists($fName)) {
return false;
}
$fifo = fopen($fName, "w");
fwrite($fifo, "TMSTOP\n");
fclose($fifo);
redirect();
}
function enableTicks() {
global $config;
touch($config['cachedir'] . "/start_ticks");
__logAdmin("is enabling the ticks");
}
function disableTicks() {
global $config;
touch($config['cachedir'] . "/stop_ticks");
__logAdmin("is disabling the ticks");
}
$statusMessage = "";
// Start / stop manager
if ($_GET['c'] == 'sm') {
startManager();
} elseif ($_GET['c'] == 'km') {
killManager();
} else {
$mRunning = __isManagerRunning();
$tActive = ($mRunning !== false) ? ticksActive() : false;
// Run tick manually
if ($_GET['c'] == 'rt' && $_GET['g'] != '' && $_GET['t'] != '') {
$__runFromAdmin = true;
$__adminParams = array($_GET['g'], $_GET['t']);
__logAdmin("is running tick " . join("::", $__adminParams));
include("../scripts/ticks.php");
$statusMessage = is_null($argh)
? ("Tick <b>" . join("::", $__adminParams) . "</b> run successfully")
: ("<b>Error while running tick " . join("::", $__adminParams) . ":</b><br/>$argh");
} else {
// Enable / disable ticks
if ($tActive === true && $_GET['c'] == 'dt') {
disableTicks();
$tActive = 'pending';
} elseif ($mRunning !== false && $tActive === false && $_GET['c'] == 'et') {
enableTicks();
$tActive = 'pending';
}
}
}
// Load the list of games if no ticks were run
if (!class_exists('config')) {
$oldDir = getcwd();
chdir("../scripts");
$__logPrefix = "lwControl";
$__loader = array(
'log', 'classloader',
'version', 'game', 'tick', 'config'
);
require_once("loader.inc");
chdir($oldDir);
}
?>
<html>
<head>
<title>LegacyWorlds Beta 5 > Administration > Ticks</title>
</head>
<body>
<h1><a href="index.html">LWB5 > Administration</a> > Ticks</h1>
<h2>Manager status</h2>
<p>Tick manager status: <?
if ($mRunning === false) {
?>
<b>not running</b> - <a href="?c=sm">Start manager</a>
<?
} else {
?> <b>running</b>, process ID #<?=$mRunning?> - <a href="?c=km">Kill manager</a><br/>
<?
if ($tActive === 'pending') {
?> Ticks status change pending; please <a href="?">reload</a> the page.<br/>
This can take up to 20 seconds, be patient.
<?
} elseif ($tActive) {
?> Ticks are <b>active</b> - <a href="?c=dt">Disable ticks</a>
<?
} else {
?> Ticks are <b>inactive</b> - <a href="?c=et">Enable ticks</a>
<?
}
}
?>
</p>
<h2>Manual controls</h2>
<?php
if ($statusMessage != '') {
echo " <p>$statusMessage</p>\n";
}
?>
<form action="?" method="GET">
<input type="hidden" name="c" value="rt" />
<input type="hidden" name="g" value="main" />
<p>
Engine tick:
<select name="t">
<option value="">-- select --</option>
<option value="day">day</option>
<option value="deathofrats">deathofrats</option>
<option value="vacation">vacation</option>
<option value="session">session</option>
</select>
<input type="submit" value="Run" />
</p>
</form>
<form action="?" method="GET">
<input type="hidden" name="c" value="rt" />
<p>
Tick
<select name="t">
<option value="">-- select --</option>
<option>battle</option>
<option>cash</option>
<option>day</option>
<option>hour</option>
<option>move</option>
<option>quit</option>
<option>sales</option>
<option>universe</option>
<option>punishment</option>
</select>
for game
<select name="g">
<option value="">-- select --</option>
<?
$games = config::getGames();
foreach (array_keys($games) as $game) {
if ($game == 'main') {
continue;
}
print " <option>$game</option>\n";
}
?>
</select>
<input type="submit" value="Run" />
</p>
</form>
</body>
</html>