aboutsummaryrefslogtreecommitdiffstats
path: root/inc
diff options
context:
space:
mode:
authorpiernov <piernov@piernov.org>2016-05-03 10:28:50 +0200
committerpiernov <piernov@piernov.org>2016-05-03 10:28:50 +0200
commitb8112f72b322fe5bf7048ac76251c8c637b9fee2 (patch)
treedaf86f704f8e3246d54ae3eab2fa37aba9346dd5 /inc
parent6bff76321ab05d6193bc1d35327cb44128f9ed66 (diff)
parentadb3df3d85ee081fd961602397d11186de08fef0 (diff)
downloadcandybox-b8112f72b322fe5bf7048ac76251c8c637b9fee2.tar.gz
candybox-b8112f72b322fe5bf7048ac76251c8c637b9fee2.tar.bz2
candybox-b8112f72b322fe5bf7048ac76251c8c637b9fee2.tar.xz
candybox-b8112f72b322fe5bf7048ac76251c8c637b9fee2.zip
Merge branch 'feat/savegame' into piernov
Diffstat (limited to 'inc')
-rw-r--r--inc/Item.inc4
-rw-r--r--inc/messages.inc3
-rw-r--r--inc/savegame.inc80
3 files changed, 71 insertions, 16 deletions
diff --git a/inc/Item.inc b/inc/Item.inc
index bef6d00..8e90998 100644
--- a/inc/Item.inc
+++ b/inc/Item.inc
@@ -20,6 +20,10 @@ class Item {
$item->addChild("icon", $this->icon);
$item->addChild("desc", $this->desc);
}
+
+ public static function fromXML($xml) {
+ return new static((string)$xml->name, +(string)$xml->cost /* convert to number */, (string)$xml->icon, (string)$xml->desc);
+ }
}
?>
diff --git a/inc/messages.inc b/inc/messages.inc
index 9f3a09d..4938fa1 100644
--- a/inc/messages.inc
+++ b/inc/messages.inc
@@ -9,6 +9,9 @@ $messages = array(
"gamesave_ok" => "Game saved.",
"gamesave_error" => "An error occured when trying to save the game.",
+ "gamesave_not_found" => "Couldn't find the specified save file.",
+ "gamesave_delete_fail" => "Couldn't delete the specified save file.",
+ "gamesave_delete_success" => "Game save successfully removed from server",
);
function sendMessage($type, $msg) {
diff --git a/inc/savegame.inc b/inc/savegame.inc
index f3b6da6..1fa95b0 100644
--- a/inc/savegame.inc
+++ b/inc/savegame.inc
@@ -4,23 +4,22 @@ 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));
+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);
}
- else
- $xml->addChild($k, $v);
}
function genSave() {
- header("Content-Type: application/xml");
$save = new SimpleXMLElement("<save/>");
-
- array_walk_recursive($_SESSION, "genXML", $save);
+ genXML($_SESSION, $save);
return $save;
- echo $save->asXML();
}
function genFilename() {
@@ -34,11 +33,60 @@ function saveGame() {
}
function downSave() {
- $save = genSave();
- header("Content-Type: application/xml");
- header("Content-Disposition: attachment; filename=".genFilename());
- header("Pragma: no-cache");
- echo $save->asXML();
+ $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) 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);
+}
?>