diff --git a/README.md b/README.md index f55e76b..6529335 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Android port of OMORI RPG game - [x] Main/Options menu fix - [x] Physical gamepad support - [x] replaceAll polyfill -- [ ] External saves (Android/data) +- [x] External saves (Android/data) - [x] Cordova localhost bug - [x] WakeLock - [x] Fix game canvas size diff --git a/www/img/pictures/VERY_IMPORTANT_SHIT.jpeg b/www/img/pictures/VERY_IMPORTANT_SHIT.jpeg new file mode 100644 index 0000000..f4c5953 Binary files /dev/null and b/www/img/pictures/VERY_IMPORTANT_SHIT.jpeg differ diff --git a/www/js/plugins/CordovaFixes.js b/www/js/plugins/CordovaFixes.js index bc13991..bc823c4 100644 --- a/www/js/plugins/CordovaFixes.js +++ b/www/js/plugins/CordovaFixes.js @@ -247,60 +247,83 @@ document.addEventListener("deviceready", () => { // Saves in external storage // ============================= -var save_exists; -var save_data; +window._SAYGEXES = {}; + +function setSayGexValue(key, f, fallback) { + let saygex = window._SAYGEXES[key]; + if (saygex != undefined) { + return f(saygex); + } else { + window._SAYGEXES[key] = fallback; + } +} + +function getSaveName(path) { + return require.libs.path._solve_dots(path).split("/")[1]; +} + +function getAndroidSavePath(path) { + return cordova.file.externalDataDirectory + "save/" + getSaveName(path); +} document.addEventListener("deviceready", () => { StorageManager.isLocalMode = function () { return true; }; - // NativeFunctions.saveFileExists = function(path) { - // var split_path = require.libs.path._solve_dots(path).split("/"); - // save_exists = null; - // window.resolveLocalFileSystemURL(cordova.file.externalDataDirectory, function (dirEntry) { - // console.log(`Using externalStorage while checking save file ${path} existence`); - // dirEntry.getDirectory(split_path[0], { create: true }, function (subDirEntry) { - // subDirEntry.getFile(split_path[1], {create: false, exclusive: false}, function(fileEntry) { - // save_exists = true; - // console.log(`After "save_exists = true" - ${save_exists}`); - // }, () => { - // save_exists = false; - // console.log(`After "save_exists = false" - ${save_exists}`); - // }); - // }); - // }); - // console.log(`Before return - ${save_exists}`); - // return save_exists; - // } + NativeFunctions.saveFileExists = function(path) { + if (window._SAYGEXES[path] != undefined) { + return window._SAYGEXES[path].exists; + } - // NativeFunctions.readSaveFileUTF8 = function(path, fnCallback) { - // var split_path = require.libs.path._solve_dots(path).split("/"); - // save_data = null; - // window.resolveLocalFileSystemURL(cordova.file.externalDataDirectory, function (dirEntry) { - // console.log(`Using externalStorage to read save at ${path}`); - // dirEntry.getDirectory(split_path[0], { create: true }, function (subDirEntry) { - // subDirEntry.getFile(split_path[1], {create: false, exclusive: false}, function(fileEntry) { - // fileEntry.file(function (file) { - // var reader = new FileReader(); - - // reader.onloadend = function() { - // save_data = this.result; - // }; - - // reader.readAsText(file); - // }, () => { - // console.log("Error to read external save file: " + e.toString()); - // }); - // }, (e) => { - // console.log("Error to find external save file: " + e.toString()); - // }); - // }); - // }); - // return save_data; - // } + let xhr = new XMLHttpRequest(); + xhr.open("GET", getAndroidSavePath(path), false); + try { + xhr.send(); + } catch (e) { + setSayGexValue(path, (v) => { v.exists = false; }, {exists: false, content: null}); + return false; + } + + setSayGexValue(path, (v) => { v.exists = true; }, {exists: true, content: null}); + return xhr.status === 200 || xhr.status === 0; + } + + NativeFunctions.readSaveFileUTF8 = function(path) { + let gex = window._SAYGEXES[path]; + if (gex != undefined) { + if (gex.content != null) { + return gex.content; + } + } + + let xhr = new XMLHttpRequest(); + + xhr.open("GET", getAndroidSavePath(path), false); + xhr.setRequestHeader("Cache-Control", "no-cache, no-store, max-age=0"); + xhr.setRequestHeader("Expires", "Tue, 01 Jan 1980 1:00:00 GMT"); + xhr.setRequestHeader("Pragma", "no-cache"); + try { + xhr.send(); + } catch (e) { + if (e.message.startsWith("Failed to execute 'send'")) { + alert(`Server returned status code 404 (${getAndroidSavePath(path)})`); + } else { + alert(e); + } + } + if (xhr.status !== 200 && xhr.status !== 0) { + alert(`Server returned status code ${xhr.status}`); + } + + let text = xhr.responseText; + setSayGexValue(path, (v) => { v.content = text; }, {exists: true, content: text}); + return text; + } NativeFunctions.writeSaveFileUTF8 = function(path, data) { + setSayGexValue(path, (v) => { v.exists = true; v.content = data; }, {exists: true, content: data}); + var split_path = require.libs.path._solve_dots(path).split("/"); window.resolveLocalFileSystemURL(cordova.file.externalDataDirectory, function (dirEntry) { console.log(`Writing ${path} save file to the externalStorage`); diff --git a/www/js/plugins/GTP_OmoriFixes.js b/www/js/plugins/GTP_OmoriFixes.js index bab375f..fefe1ca 100644 --- a/www/js/plugins/GTP_OmoriFixes.js +++ b/www/js/plugins/GTP_OmoriFixes.js @@ -2989,7 +2989,7 @@ Gamefall.Encryption = Gamefall.Encryption || {}; const path = require('path'); const fs = require('fs'); var base = path.dirname(process.mainModule.filename); - let mapName = require("fs").cachedAlternativeName(`/maps/map${mapId}.json`); + let mapName = require("fs").cachedAlternativeName(`maps/map${mapId}.json`); this.unloadTiledMapData(); fs.readFile(base + mapName, (err, buffer) => { if (!!err) { diff --git a/www/js/porting/compat/nwjs.js b/www/js/porting/compat/nwjs.js index ef761bd..f8d678c 100644 --- a/www/js/porting/compat/nwjs.js +++ b/www/js/porting/compat/nwjs.js @@ -348,6 +348,9 @@ require.libs.fs = { }, readFile: function (path, callback) { + if (path.startsWith(".") && !path.startsWith("./")) { + path = "./" + path.substr(1); + } let xhr = new XMLHttpRequest(); xhr.responseType = "arraybuffer"; xhr.open("GET", path, true);