1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
<?php
require_once("inc/messages.inc");
define("SAVEDIR", "data/save");
function genXML($v, $k, $xml) {
if(is_object($v))
{
if(is_callable(array($v, "addToXML")))
$v->addToXML($xml->addChild($k));
}
else
$xml->addChild($k, $v);
}
function genSave() {
header("Content-Type: application/xml");
$save = new SimpleXMLElement("<save/>");
array_walk_recursive($_SESSION, "genXML", $save);
return $save;
echo $save->asXML();
}
function genFilename() {
return "craftmine-".date("d-m-Y_H-i-s").".save.xml";
}
function saveGame() {
$save = genSave();
if($save->asXML(SAVEDIR."/".genFilename())) sendInfo("gamesave_ok");
else sendError("gamesave_error");
}
function downSave() {
$save = genSave();
header("Content-Type: application/xml");
header("Content-Disposition: attachment; filename=".genFilename());
header("Pragma: no-cache");
echo $save->asXML();
}
function listSaves() {
chdir(SAVEDIR); // Go to SAVEDIR folder, avoiding leading folder name in file list
echo json_encode(glob("*.save.xml"));
}
function parseSave($xml, &$table) { // Passing $table by reference
foreach($xml as $k => $v) {
if($v->count() == 0) { // No child, treat as string
$v = (string)$v;
if(is_numeric($v)) $v = +$v; // If it is in fact a number, treat it that way using PHP unary '+' coercion
$table[$k] = $v;
} elseif($k == "inventory") { // Special case for inventory: objects need to be created
foreach($v as $item) Inventory::addItem(Item::fromXML($item));
} else { // If nested array
$table[$k] = array();
parseXML($v, $table[$k]);
} // Other types unsupported (unused)
}
}
function loadSave() {
if(empty($_POST["filename"])) return;
$xml = simplexml_load_file(SAVEDIR . "/" . $_POST["filename"]);
if(empty($xml)) {
sendError("gamesave_not_found");
return;
}
$_SESSION = array(); // drop current game
parseSave($xml, $_SESSION);
}
?>
|