Files
RPG_FromClaude/saves.js
Maxim Dolgolyov ac1f348311 Initial commit: RPG game project
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-25 01:01:02 +03:00

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 */ }
}
}
},
};