import fspromises from "fs/promises"; import { v4 as uuidv4 } from 'uuid'; import { version } from '../../package.json' import { graphics } from "systeminformation" import { app, shell, BrowserWindow, ipcMain, dialog, nativeTheme } from 'electron' import path, { join } from 'path' import { electronApp, optimizer, is } from '@electron-toolkit/utils' import icon from '../../resources/icon.ico?asset' import { define } from '../define/define.js' import { func } from './func.js' import { AsyncQueue } from "./quene.js" import { DEFINE_STRING } from '../define/define_string.js' import { Tools } from './tools.js' import { ImageGenerate } from './backPrompt/imageGenerate.js' import { Setting } from './setting/setting.js' import { has, isEmpty } from 'lodash' // ipc import { SettingIpc } from './IPCEvent/settingIpc.js' import { ImageGenerateIpc } from './IPCEvent/imageGenerateIpc.js' import { WritingIpc } from './IPCEvent/writingIpc.js' import { VideoGenerateIpc } from './IPCEvent/videoGenerateIpc' import { TranslateIpc } from './IPCEvent/translateIpc.js' import { GptIpc } from './IPCEvent/gptIpc.js' import { MjIpc } from './IPCEvent/mjIpc.js' import { OriginalImageGenerateIpc } from './IPCEvent/originalImageGenerateIpc' import { SdIpc } from './IPCEvent/sdIpc.js' import { DiscordIpc, RemoveDiscordIpc } from './IPCEvent/discordIpc.js' import { MainIpc } from './IPCEvent/mainIpc.js' import { GlobalIpc } from "./IPCEvent/globalIpc.js"; import { ImageIpc } from "./IPCEvent/imageIpc.js"; import { system } from "systeminformation"; let tools = new Tools(); let imageGenerate = new ImageGenerate(global); let setting = new Setting(global); async function InitData(gl) { let res = await setting.getSettingDafultData(); gl.config = res; gl.requestQuene = new AsyncQueue(gl, res.task_number); gl.fileQueue = new AsyncQueue(gl, 1); return res; } function setIpcHandler(hash) { if (hash == "discord") { DiscordIpc(global); } } function removeIpcHandler(hash) { if (hash == "discord") { RemoveDiscordIpc(); } } async function createWindow(hash = "ShowMessage", data, url = null) { // Create the browser window. await InitData(global); global.currentHash = hash; // 判断当前是不是有设置的宽高,用的话记忆 let isRe = global.config.window_wh_bm_remember && hash == "ShowMessage" && global.config.window_wh_bm; let mainWindow = new BrowserWindow({ width: isRe ? global.config.window_wh_bm.width : 900, height: isRe ? global.config.window_wh_bm.height : 675, x: isRe ? global.config.window_wh_bm.x : 100, y: isRe ? global.config.window_wh_bm.y : 100, title: 'LAITool', icon: '../../resources/icon.ico', show: false, autoHideMenuBar: true, ...(process.platform === 'linux' ? { icon } : {}), webPreferences: { preload: join(__dirname, '../preload/index.js'), sandbox: false, nodeIntegration: (hash == 'discord' ? false : true), // 在网页中集成Node nodeIntegrationInWorker: true, webSecurity: false, partition: "persist:my-partition", } }) mainWindow.myID = uuidv4(); mainWindow.on('ready-to-show', () => { mainWindow.show() }) mainWindow.webContents.setWindowOpenHandler((details) => { shell.openExternal(details.url) return { action: 'deny' } }) // HMR for renderer base on electron-vite cli. // Load the remote URL for development or the local html file for production. // 判断是不是加载外部网页 if (url) { mainWindow.loadURL(url) } else { if (is.dev && process.env['ELECTRON_RENDERER_URL']) { mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'] + "/#/" + hash); mainWindow.webContents.openDevTools(); } else { if (hash != "") { mainWindow.loadURL(`file://${path.join(__dirname, '../renderer/index.html')}#/${hash}`) } else { mainWindow.loadFile(join(__dirname, '../renderer/index.html')) } } } mainWindow.on("close", async () => { // 判断指定的窗口,移除指定的监听 removeIpcHandler(hash); global.newWindow = global.newWindow.filter(item => item.id != mainWindow.id) // 判断当前的是不是开启了记录功能 if (global.config.window_wh_bm_remember && hash == "ShowMessage") { let window_wh_bm = mainWindow.getBounds(); // 记录到文件中 await setting.ModifySampleSetting(JSON.stringify({ window_wh_bm: window_wh_bm })) } }) // 创建一个新的窗口,添加对应的监听 global.newWindow.push({ hash, id: mainWindow.id, win: mainWindow, init_folder: data }) setIpcHandler(hash); return mainWindow; } let mainWindow; global.createWindow = createWindow; // This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. app.whenReady().then(async () => { // Set app user model id for windows electronApp.setAppUserModelId('com.electron') // Default open or close DevTools by F12 in development // and ignore CommandOrControl + R in production. // see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils app.on('browser-window-created', (_, window) => { optimizer.watchWindowShortcuts(window) }) // global.newWindow = []; mainWindow = createWindow('ShowMessage', null) //判断是不是又配置文件,没有的话,将temp中的基础配置加载 // 判断文件夹是不是存在 let config_p = path.dirname(define.config_path); let isE = await tools.checkExists(config_p); // 文件夹存在判断json文件数量 let ex_json = []; if (isE) { let ex_json_path = await tools.getFilesWithExtensions(config_p, '.json'); for (let i = 0; i < ex_json_path.length; i++) { const element = ex_json_path[i]; ex_json.push(path.basename(element)); } } else { await fspromises.mkdir(config_p, { recursive: true }); } // 判断文件是不是存在,不存在添加 if (ex_json.length != 5) { let temp_path = path.join(path.dirname(define.draft_temp_path), 'config'); let tmp_json_path = await tools.getFilesWithExtensions(temp_path, ".json"); for (let i = 0; i < tmp_json_path.length; i++) { const element = tmp_json_path[i]; if (!ex_json.includes(path.basename(element))) { await fspromises.copyFile(element, path.join(config_p, path.basename(element))) } } } // 判断动态文件是不是存在 tools.checkJsonFileExistsOrCreate(path.normalize(define.dynamic_setting)); // 判断标签文件是不是存在 tools.checkJsonFileExistsOrCreate(path.normalize(define.tag_setting)); // 判断SD图片缓存文件是不是存在(不存在创建) tools.checkFolderExistsOrCreate(path.normalize(define.temp_sd_image)); tools.checkFolderExistsOrCreate(path.normalize(path.join(define.image_path, "c_s"))); app.on('activate', async function () { // On macOS it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. if (BrowserWindow.getAllWindows().length === 0) { mainWindow = createWindow('ShowMessage', null) } }) }) // Quit when all windows are closed, except on macOS. There, it's common // for applications and their menu bar to stay active until the user quits // explicitly with Cmd + Q. app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit() } }) SettingIpc(); ImageGenerateIpc(); WritingIpc(); VideoGenerateIpc(); TranslateIpc(); GptIpc(); SdIpc(); MjIpc(); MainIpc(createWindow); OriginalImageGenerateIpc(); GlobalIpc(); ImageIpc(); ipcMain.handle('dark-mode:toggle', (event, value) => { if (value) { nativeTheme.themeSource = value; } else { nativeTheme.themeSource = "system"; } return nativeTheme.shouldUseDarkColors }) // In this file you can include the rest of your app"s specific main process // code. You can also put them in separate files and require them here. ipcMain.handle(DEFINE_STRING.GET_SETTING_Dafault_DATA, async (event) => { return await InitData(global); }) ipcMain.handle(DEFINE_STRING.GET_DRAFT_FILE_LIST, async (event) => { let res = await func.getDraftFileList(); return res; }) ipcMain.handle(DEFINE_STRING.SELECT_FOLDER, async (event, value = null) => { let po = ['openDirectory']; if (value && !isEmpty(value.multi)) { po.push('multiSelections'); } let { filePaths } = await dialog.showOpenDialog({ properties: po, defaultPath: value && !isEmpty(value.defaultPath) ? value.defaultPath : "" }) return filePaths; }) ipcMain.handle(DEFINE_STRING.SELECT_FILE, async (event, value) => { try { let { filePaths } = await dialog.showOpenDialog({ properties: ['openFile'], filters: [ { name: "fileName", extensions: value } ] }) return { code: 1, value: filePaths[0] } } catch (error) { return { code: 0, message: `Error Message ${error}` } } }) ipcMain.handle(DEFINE_STRING.GET_DRAFT_TEXT_STYLE, async (event, value) => { let res = await func.getDraftTextStyle(value); return res; }) ipcMain.handle(DEFINE_STRING.GET_TEXT_STYLE_LIST, async (event) => { let res = await func.getClipSetting("text_style"); return res; }) ipcMain.handle(DEFINE_STRING.GET_FRIENDLY_REMINDER_LIST, async (event) => { let res = await func.getClipSetting("friendly_reminder_setting"); return res; }) ipcMain.handle(DEFINE_STRING.GET_FRIENDLY_REMINDER_DRAFT, async (event, value) => { let res = await func.GetDraftFriendlyReminder(value); return res; }) ipcMain.handle(DEFINE_STRING.ADD_DRAFT, async (event, value) => { let res = await func.addDraft(value); return res; }) // 获取当前版本 ipcMain.handle(DEFINE_STRING.GET_VERSION, async (event) => { // 获取当前电脑的显卡信息 let da = await graphics(); for (let i = 0; i < da.controllers.length; i++) { // 获取第一个英伟达或者是AMD的显卡信息 const element = da.controllers[i]; if (element.vendor.startsWith("NVIDIA")) { global.gpu = element; global.gpu.type = "NVIDIA"; break; } else if (element.vendor.startsWith("AMD") || element.vendor.startsWith("Advanced")) { global.gpu = element; global.gpu.type = "AMD"; break; } else { global.gpu = { name: "OTHER" }; global.gpu.type = "OTHER"; } } return version + " " + (global.gpu?.name ? global.gpu.name : ""); }); // 监听保存SD配置 ipcMain.handle(DEFINE_STRING.SAVE_SD_CONFIG, async (event, value) => await func.SaveSDConfig(value)) // 监听保存生成视频的简单配置 ipcMain.handle(DEFINE_STRING.SAVE_GENERAL_SETTING, async (event, value) => await func.SaveGeneralSetting(value)); // 获取当前的视频合成配置信息 ipcMain.handle(DEFINE_STRING.GET_VIDEO_CONFIG_MESSAGE, async (event) => await func.GetVideoConfigMessage()); // 监听保存字幕的是指信息 ipcMain.handle(DEFINE_STRING.SAVE_ASS_CONFIG, async (event, value) => await func.SaveAssConfig(value)); // 监听获取当前系统安装的字体 ipcMain.handle(DEFINE_STRING.GET_SYSTEM_INSTALL_FONTNAME, async (event) => await func.GetSystemInstallFontName()); // 监听删除视频配置任务(删除指定ID的值) ipcMain.handle(DEFINE_STRING.DELETE_VIDEO_CONFIG, async (event, value) => await func.DeleteVideoConfig(value)); // 监听添加生图任务信息 ipcMain.handle(DEFINE_STRING.ADD_IMAGE_TASK_LIST, async (event, value) => await func.AddImageTask(value)); // 监听删除生成图片列表中的信息 ipcMain.handle(DEFINE_STRING.DELETE_IMAGE_TASK_LIST, async (event, value) => await func.DeleteImageTaskList(value)); // 监听获取加密的机械码任务 ipcMain.handle(DEFINE_STRING.GET_MACHINE_ID, async (event, value) => await func.GetMachineId()); // 监听获取不想要的提示词任务 ipcMain.handle(DEFINE_STRING.GET_BAD_PROMPT, async (event) => await func.GetBadPrompt()); // 保存不想要的提示词 ipcMain.handle(DEFINE_STRING.SAVE_BAD_PROMPT, async (event, value) => await func.SaveBadPrompt(value)); // 一键删除不想要的值 ipcMain.handle(DEFINE_STRING.DELETE_BAD_PROMPT, async (event) => await func.DeleteBadPrompt()); // 监听反推任务 ipcMain.handle(DEFINE_STRING.PUSH_BACK_PROMPT, async (event) => await func.PushBackPrompt()); // 打开GPT购买界面 ipcMain.on(DEFINE_STRING.OPEN_GPT_BUY_URL, async (event, value) => await func.openGptBuyUrl(value)); // 监听打开任意网站的任务 ipcMain.on(DEFINE_STRING.OPEN_URL, async (event, value) => await func.OpenUrl(value)); // 监听抽帧任务 ipcMain.handle(DEFINE_STRING.GET_FRAME, async (event, value) => await func.getFrame(value)); // 监听获取ADtailer列表的任务 ipcMain.handle(DEFINE_STRING.GET_ADETAILER_LIST, async (event) => await func.GetADetailerList()); // 监听保存ADtailer数据 ipcMain.handle(DEFINE_STRING.SAVE_DETAILER_CONFIG, async (event, value) => await func.SaveADetailerConfig(value)); // 分镜识别。语音识别 ipcMain.handle(DEFINE_STRING.START_STORY_BOARDING, async (event, value) => await func.StartStoryboarding(value)); // 保存试用结束时间 ipcMain.on(DEFINE_STRING.SAVE_TRIAL_END_TIME, (event, value) => { global.endTime = value.endTime; global.permissions = value.permissions; }); // 获取当前机器的权限 ipcMain.handle(DEFINE_STRING.GET_PERMISSION, async (event) => { return { code: 1, endTime: global.endTime, permissions: global.permissions } }) // 试用文件资源打开指定的文件夹 ipcMain.on(DEFINE_STRING.OPEN_FOLDER, (event, value) => shell.openPath(path.join(global.config.project_path, "tmp/" + value))); // 监听字幕的保存 ipcMain.handle(DEFINE_STRING.SAVE_NEW_WORD, async (event, value) => { return await func.SaveNewWord(value); }) /** * 监听字幕对齐任务,通过前端传过来的数据 */ ipcMain.handle(DEFINE_STRING.ALIGN_DRAFT_IMG_TO_TEXT, async (event, value) => { return await func.alginDraftImgToText(value); }) /** * 监听单张重绘任务 */ ipcMain.handle(DEFINE_STRING.RE_GENERATE_IAMGE_ONE, async (event, value) => { console.log(value[0]); let newWindow = global.newWindow.filter(item => item.id == value[0]); let res = await func.ReGenerateImageOne(newWindow, value) return res; }) /** * 监听文件夹高清任务 */ ipcMain.handle(DEFINE_STRING.IMPROVE_IMAGE_RESOULTION, async (event, value) => { let res = await imageGenerate.ImproveResolution(value); return res; }) /** * 监听刷新窗口的事件 */ ipcMain.handle(DEFINE_STRING.REFRASH_IMAGWE_DATA, async (event, value) => { console.log(value) let newWindow = global.newWindow.filter(item => item.id == value[0]); let img_dir = path.join(global.config.project_path, "tmp/" + value[1]); let res = await imageGenerate.getFolderImageList(newWindow, img_dir, true); return res; }) // 监听打开全局窗口事件 ipcMain.on(DEFINE_STRING.SHOW_GLOABAL_MESSAGE_DIALOG, (event, value) => { global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, value) }) /** * 监听一个窗口,返回窗口创建成功后需要的基础数据 */ ipcMain.on(DEFINE_STRING.SHOW_NEW_WINDOW, async (event, value) => { let newW = createWindow(value[0], value[1]); }) // 监听程序关闭 ipcMain.on(DEFINE_STRING.QUIT_APP, (event) => { app.quit(); }) /** * 监听图片对齐任务 */ ipcMain.on(DEFINE_STRING.ALIGN_DRAFT_IMG, async (event, value) => { func.alignDraftImage(mainWindow, value) })