addToXML($xml->addChild($k)); } else $xml->addChild($k, $v); } function genSave() { header("Content-Type: application/xml"); $save = new SimpleXMLElement(""); 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); } ?>