diff options
author | piernov <piernov@piernov.org> | 2016-05-09 22:06:30 +0200 |
---|---|---|
committer | piernov <piernov@piernov.org> | 2016-05-09 22:06:30 +0200 |
commit | f10c51f07a755d75a583f85316efbcd3bd1e4b6d (patch) | |
tree | 87419a11e12f5b7433459fcb5cb9da5211dcbd9e /inc/savegame.inc | |
parent | 54635d17eef27eb2546d69599e4107b242509ced (diff) | |
parent | 2f32bc3153b7f2c2561e4603f912573921e6449f (diff) | |
download | candybox-f10c51f07a755d75a583f85316efbcd3bd1e4b6d.tar.gz candybox-f10c51f07a755d75a583f85316efbcd3bd1e4b6d.tar.bz2 candybox-f10c51f07a755d75a583f85316efbcd3bd1e4b6d.tar.xz candybox-f10c51f07a755d75a583f85316efbcd3bd1e4b6d.zip |
Merge branch 'alexichi' of ssh://piernov.org/srv/git/candybox into alexichi
Diffstat (limited to 'inc/savegame.inc')
-rw-r--r-- | inc/savegame.inc | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/inc/savegame.inc b/inc/savegame.inc new file mode 100644 index 0000000..6d92af2 --- /dev/null +++ b/inc/savegame.inc @@ -0,0 +1,117 @@ +<?php + +require_once("inc/messages.inc"); +require_once("inc/Inventory.inc"); +require_once("inc/Item.inc"); + +define("SAVEDIR", "data/save"); + +function genXML($table, $xml) { + foreach($table as $k => $v) { + if(is_object($v)) { // Object: either Item or Inventory + if(is_callable(array($v, "addToXML"))) // Check if the object has a addToXML method + $v->addToXML($xml->addChild($k)); + } elseif(is_array($v)) // Nested array + genXML($v, $xml->addChild($k)); + else // Single value (numeric or string) + $xml->addChild($k, $v); + } +} + +function genSave() { + $save = new SimpleXMLElement("<save/>"); + genXML($_SESSION, $save); + return $save; +} + +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 = ""; + $filename = ""; + + if(empty($_GET["filename"])) { + $filename = genFilename(); + $save = genSave()->asXML(); // Send current game save file if no file specified + } else { + $filename = $_GET["filename"]; + $save = file_get_contents(SAVEDIR . "/" . $filename); + if(empty($save)) return; // Probably file not found + } + + header("Content-Type: application/xml"); // Force browser to intepret the file as XML + header("Content-Disposition: attachment; filename=".$filename); // Force download with specific filename + header("Cache-Control: no-cache"); // Avoid storing save file in proxy/browser cache + echo $save; +} + +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) { + for($i=0; $i<+$item->count; $i++) // Add the right count of items to Inventory + Inventory::addItem(Item::fromXML($item)); + } + } else { // If nested array + $table[$k] = array(); + parseSave($v, $table[$k]); + } // Other types unsupported (unused) + } +} + +function deleteSave() { + if(empty($_POST["filename"])) return; + $path = SAVEDIR . "/" . basename($_POST["filename"]); // remove any leading directory + if(file_exists($path) && unlink($path)) + sendInfo("gamesave_delete_success"); + else sendError("gamesave_delete_fail"); +} + +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); +} + +function uploadSave() { + $fname = basename($_FILES['savefile']['name']); + $src = $_FILES['savefile']['tmp_name']; + + libxml_use_internal_errors(true); // Ignore errors when loading the received file + $xml = simplexml_load_file($src); + libxml_use_internal_errors(false); + if(!$xml) { + sendError("upload_fail"); + return; + } + $table = array(); + parseSave($xml, $table); // Parse received file + + $save = new SimpleXMLElement("<save/>"); + genXML($table, $save); // Regenerate it + if($save->asXML(SAVEDIR."/".$fname)) sendInfo("upload_success", array($fname)); + else sendError("upload_error"); +} +?> |