diff --git a/lib/modAssist_func_lib.js b/lib/modAssist_func_lib.js index c7875f5a..d4477b94 100644 --- a/lib/modAssist_func_lib.js +++ b/lib/modAssist_func_lib.js @@ -1717,7 +1717,7 @@ const file = { obj.dest_filename ) - promises.push(fsPromise.cp(obj.source_file, destFile, { recursive : true }).then(() => { + promises.push(fsPromise.cp(obj.source_file, destFile, { recursive : true, force : true }).then(() => { file.log.info('Copy succeed', obj.source_file, destFile) results.push(file._result_ok('copy', obj.source_file, destFile)) }).catch((err) => { diff --git a/lib/modCheckLib.js b/lib/modCheckLib.js index 240c2316..dd421f16 100644 --- a/lib/modCheckLib.js +++ b/lib/modCheckLib.js @@ -1381,6 +1381,7 @@ class csvFileChecker { * @class */ class saveFileChecker { + #silent = false #fileName = null #isFolder = false #fileHandle = null @@ -1400,12 +1401,13 @@ class saveFileChecker { * @param {string} fileName full file and path of save * @param {boolean} isFolder Expect a folder */ - constructor( fileName, isFolder ) { + constructor( fileName, isFolder, silent = false ) { + this.#silent = silent this.#fileName = fileName this.#isFolder = isFolder this.#log = serveIPC.log.group(`savegame-${path.basename(fileName)}`) - this.#log.info(`Adding Save: ${fileName}`) + if ( ! this.#silent ) { this.#log.info(`Adding Save: ${fileName}`) } } /** @@ -1416,6 +1418,7 @@ class saveFileChecker { return { errorList : this.errorList, farms : this.farms, + isValid : this.errorList.length === 0, mapMod : this.mapMod, mods : this.mods, singleFarm : this.singleFarm, @@ -1432,8 +1435,9 @@ class saveFileChecker { const couldOpen = await this.#fileHandle.open() if ( ! couldOpen ) { - this.#log.danger(`Save open fail: ${this.#fileName}`) + if ( ! this.#silent ) { this.#log.danger(`Save open fail: ${this.#fileName}`) } this.errorList.push(['SAVEGAME_UNREADABLE', this.#fileName]) + this.isValid = false return this.dataReturn } @@ -1450,7 +1454,7 @@ class saveFileChecker { #util_readError(type) { this.errorList.push(['SAVEGAME_PARSE_ERROR', `${type}.xml`]) - this.#log.warning(`Parsing ${type}.xml failed`) + if ( ! this.#silent ) { this.#log.warning(`Parsing ${type}.xml failed`) } } #util_iterateXML(data) { diff --git a/lib/workerThreadLib.js b/lib/workerThreadLib.js index 39278c65..fec9b010 100644 --- a/lib/workerThreadLib.js +++ b/lib/workerThreadLib.js @@ -1828,8 +1828,8 @@ class fileHandlerAsync { } return thisParsedXML - } catch { - this.#log.warning(`Caught unrecoverable XML Parse error : ${fileName}`) + } catch (err) { + this.#log.warning(`Caught unrecoverable XML Parse error : ${fileName} :: ${err}`) return false } }).catch((err) => { diff --git a/modAssist_main.js b/modAssist_main.js index ffe49730..c331c0fe 100644 --- a/modAssist_main.js +++ b/modAssist_main.js @@ -119,13 +119,23 @@ ipcMain.handle('files:drop', async (_, files) => { }) return } else if ( files.length === 1 && files[0].endsWith('.json') ) { - // TODO: HANDLE JSON IMPORT + // HANDLE JSON IMPORT funcLib.general.importJSON_process(files[0]) + return } else if ( files.length === 1 && files[0].endsWith('.zip') ) { + // Handles ZIP packs, ZIP save game, and finally single ZIP add + const saveResult = await new saveFileChecker(files[0], false, true).getInfo() + + if ( saveResult.isValid ) { + serveIPC.windowLib.createNamedWindow('save', { + collectKey : null, + thisSaveGame : saveResult, + }) + return + } return getCopyMoveDelete('import', null, null, files, await new modPackChecker(files[0]).getInfo()) - } else { - return getCopyMoveDelete('import', null, null, files, false) } + return getCopyMoveDelete('import', null, null, files, false) }) function sendCopyMoveDelete(operation, modIDS) { @@ -613,7 +623,7 @@ ipcMain.handle('gamelog:auto', () => { ipcMain.handle('gamelog:open', () => { return dialog.showOpenDialog(serveIPC.windowLib.win.gamelog, { properties : ['openFile'], - defaultPath : path.join(serveIPC.prefs.basePath(), 'log.txt'), + defaultPath : path.join(funcLib.prefs.basePath(), 'log.txt'), filters : [{ name : 'Log Files', extensions : ['txt'] }], }).then((result) => { if ( ! result.canceled ) { funcLib.gameSet.setGameLog(result.filePaths[0]) } @@ -698,6 +708,8 @@ ipcMain.on('cache:clean', () => { } } + serveIPC.log.info('cache-cleaner', `Removed ${md5Set.size} stale entries.`) + for ( const md5 of md5Set ) { delete serveIPC.storeCache.remMod(md5) } serveIPC.storeCache.saveFile() diff --git a/renderer/a_changelog.html b/renderer/a_changelog.html index aaca0c48..c6740e9b 100644 --- a/renderer/a_changelog.html +++ b/renderer/a_changelog.html @@ -30,13 +30,11 @@
-

Version 4.0.0 Features

+

Version 5.0.0 Features

    -
  • ADDED Malware Detector for Mods
  • -
  • CHANGED New ZIP Library (no more 2Gb limit)
  • -
  • ADDED game.xml / gameSettings.xml Backups
  • -
  • ADDED Collection Import and Export
  • +
  • ADDED FS2025 Initial Support
  • +
  • CHANGED Backend re-write
@@ -45,6 +43,14 @@

GitHub Known Issues & Changes

Added Features by Major Version