98 lines
3.3 KiB
JavaScript
98 lines
3.3 KiB
JavaScript
// ============================================================
|
|
// SAVES.JS — JSON-сохранения в отдельной папке (File System API)
|
|
// ============================================================
|
|
// Приоритет: если выбрана папка — пишем JSON-файлы.
|
|
// Всегда также пишем в localStorage как кэш/резерв.
|
|
// ============================================================
|
|
|
|
const SaveFS = {
|
|
_dir: null, // FileSystemDirectoryHandle
|
|
|
|
isSupported() {
|
|
return 'showDirectoryPicker' in window;
|
|
},
|
|
|
|
hasDir() {
|
|
return !!this._dir;
|
|
},
|
|
|
|
getDirName() {
|
|
return this._dir ? this._dir.name : null;
|
|
},
|
|
|
|
// Открыть диалог выбора папки, затем синхронизировать JSON → localStorage
|
|
async selectDir() {
|
|
try {
|
|
this._dir = await window.showDirectoryPicker({ id: 'eidon-saves', mode: 'readwrite' });
|
|
await this._syncFromDir();
|
|
return true;
|
|
} catch (e) {
|
|
if (e.name !== 'AbortError') console.warn('SaveFS.selectDir:', e);
|
|
return false;
|
|
}
|
|
},
|
|
|
|
// Записать слот в JSON-файл
|
|
async writeSlot(slot, data) {
|
|
if (!this._dir) return false;
|
|
try {
|
|
const fh = await this._dir.getFileHandle('save_' + slot + '.json', { create: true });
|
|
const w = await fh.createWritable();
|
|
await w.write(JSON.stringify(data, null, 2));
|
|
await w.close();
|
|
return true;
|
|
} catch (e) {
|
|
console.warn('SaveFS.writeSlot:', e);
|
|
return false;
|
|
}
|
|
},
|
|
|
|
// Прочитать слот из JSON-файла
|
|
async readSlot(slot) {
|
|
if (!this._dir) return null;
|
|
try {
|
|
const fh = await this._dir.getFileHandle('save_' + slot + '.json');
|
|
const file = await fh.getFile();
|
|
return JSON.parse(await file.text());
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
},
|
|
|
|
// Удалить JSON-файл слота
|
|
async deleteSlot(slot) {
|
|
if (!this._dir) return false;
|
|
try {
|
|
await this._dir.removeEntry('save_' + slot + '.json');
|
|
return true;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
},
|
|
|
|
// Прочитать все 3 JSON-файла из папки → обновить localStorage
|
|
// Если файла нет — слот в localStorage тоже очищается (папка — источник истины)
|
|
async _syncFromDir() {
|
|
for (let sl = 0; sl < 3; sl++) {
|
|
const data = await this.readSlot(sl);
|
|
if (data) {
|
|
localStorage.setItem(RPG.SAVE_PREFIX + sl, JSON.stringify(data));
|
|
} else {
|
|
localStorage.removeItem(RPG.SAVE_PREFIX + sl);
|
|
}
|
|
}
|
|
},
|
|
|
|
// Экспортировать все сохранения из localStorage → JSON-файлы
|
|
async exportAll() {
|
|
for (let sl = 0; sl < 3; sl++) {
|
|
const raw = localStorage.getItem(RPG.SAVE_PREFIX + sl);
|
|
if (raw) {
|
|
try {
|
|
await this.writeSlot(sl, JSON.parse(raw));
|
|
} catch (e) { /* skip */ }
|
|
}
|
|
}
|
|
},
|
|
};
|