From 48b377b1ad73dd3e674b912a97234219bbe12145 Mon Sep 17 00:00:00 2001 From: LightningHyperBlaze45654 <73149145+LightningHyperBlaze45654@users.noreply.github.com> Date: Thu, 2 Jan 2025 11:52:32 -0800 Subject: [PATCH] fix: backup size limit ## Issue track Previously, the backup loading was depending on ArrayBuffer. In chromium based browsers, ArrayBuffer's size is limited to 2GB, and anything more will fail to read the data. This affects Tauri too, as Tauri uses Edge webview2 which also is based on chromium. The proposed change uses file stream instead of ArrayBuffer, effectively ignoring file size limit/ --- src/ts/drive/backuplocal.ts | 152 +++++++++++++++++++++--------------- 1 file changed, 88 insertions(+), 64 deletions(-) diff --git a/src/ts/drive/backuplocal.ts b/src/ts/drive/backuplocal.ts index c9cccdcd..a6b0240b 100644 --- a/src/ts/drive/backuplocal.ts +++ b/src/ts/drive/backuplocal.ts @@ -14,7 +14,6 @@ function getBasename(data:string){ return lasts } - export async function SaveLocalBackup(){ alertWait("Saving local backup...") const writer = new LocalWriter() @@ -36,7 +35,6 @@ export async function SaveLocalBackup(){ alertError('Failed, Backup data is corrupted') return } - if(isTauri){ const assets = await readDir('assets', {baseDir: BaseDirectory.AppData}) @@ -80,74 +78,100 @@ export async function SaveLocalBackup(){ } export async function LoadLocalBackup(){ - //select file try { - const input = document.createElement('input') - input.type = 'file' - input.accept = '.bin' + const input = document.createElement('input'); + input.type = 'file'; + input.accept = '.bin'; input.onchange = async () => { - if(!input.files || input.files.length === 0){ - input.remove() - return + if (!input.files || input.files.length === 0) { + input.remove(); + return; } - const file = input.files[0] - const reader = new FileReader() - input.remove() - reader.onload = async () => { - const buffer = reader.result as ArrayBuffer - const bufferLength = buffer.byteLength - for(let i=0;i remainingBuffer.length) { + break; + } + const nameBuffer = remainingBuffer.slice(offset + 4, offset + 4 + nameLength); + const name = new TextDecoder().decode(nameBuffer); + + if (offset + 4 + nameLength + 4 > remainingBuffer.length) { + break; + } + const dataLength = new Uint32Array(remainingBuffer.slice(offset + 4 + nameLength, offset + 4 + nameLength + 4).buffer)[0]; + + if (offset + 4 + nameLength + 4 + dataLength > remainingBuffer.length) { + break; + } + const data = remainingBuffer.slice(offset + 4 + nameLength + 4, offset + 4 + nameLength + 4 + dataLength); + + if (name === 'database.risudat') { + const db = new Uint8Array(data); + const dbData = await decodeRisuSave(db); + setDatabaseLite(dbData); + if (isTauri) { + await writeFile('database/database.bin', db, { baseDir: BaseDirectory.AppData }); + await relaunch(); + alertStore.set({ + type: "wait", + msg: "Success, Refreshing your app." + }); + } else { + await forageStorage.setItem('database/database.bin', db); + location.search = ''; + alertStore.set({ + type: "wait", + msg: "Success, Refreshing your app." + }); + } + } else { + if (isTauri) { + await writeFile(`assets/` + name, data, { baseDir: BaseDirectory.AppData }); + } else { + await forageStorage.setItem('assets/' + name, data); + } + } + await sleep(10); + if (forageStorage.isAccount) { + await sleep(1000); + } + + offset += 4 + nameLength + 4 + dataLength; + } + remainingBuffer = remainingBuffer.slice(offset); } - reader.readAsArrayBuffer(file) - } - - input.click() + + alertNormal('Success'); + }; + + input.click(); } catch (error) { - console.error(error) + console.error(error); alertError('Failed, Is file corrupted?') } } \ No newline at end of file