From 3ae2c11ca465196ef35dd02d8ae10baadf02be78 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Tue, 10 Sep 2024 22:09:58 +0900 Subject: [PATCH] Add PWA support --- index.html | 1 + manifest.json | 63 +++++++++++++ public/logo_192.png | Bin 0 -> 5459 bytes public/logo_512.png | Bin 0 -> 21113 bytes public/sw.js | 30 +++++++ src/ts/characterCards.ts | 120 +++++++++++++++++++++++-- src/ts/process/modules.ts | 166 +++++++++++++++++++---------------- src/ts/process/processzip.ts | 4 + 8 files changed, 300 insertions(+), 84 deletions(-) create mode 100644 manifest.json create mode 100644 public/logo_192.png create mode 100644 public/logo_512.png diff --git a/index.html b/index.html index 0459e154..972d7f37 100644 --- a/index.html +++ b/index.html @@ -5,6 +5,7 @@ + diff --git a/manifest.json b/manifest.json new file mode 100644 index 00000000..be6e8ca5 --- /dev/null +++ b/manifest.json @@ -0,0 +1,63 @@ +{ + "name": "RisuAI", + "icons": [ + { + "src": "logo_512.png", + "type": "image/png", + "sizes": "512x512" + }, + { + "src": "logo_192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo_16.png", + "type": "image/png", + "sizes": "16x16" + }, + { + "src": "logo_32.png", + "type": "image/png", + "sizes": "32x32" + }, + { + "src": "logo_256.png", + "type": "image/png", + "sizes": "256x256" + } + ], + "start_url": "/", + "display": "standalone", + "theme_color": "#4682B4", + "share_target": { + "action": "/receive-files/", + "method": "POST", + "enctype": "multipart/form-data", + "params": { + "files": [ + { + "name": "character", + "accept": [".charx"] + }, + { + "name": "preset", + "accept": [".risup"] + }, + { + "name": "module", + "accept": [".risum"] + } + ] + } + }, + "file_handlers": [ + { + "action": "/", + "accept": { + "application/octet-stream": [".charx", ".risup", ".risum"] + } + } + ] + +} \ No newline at end of file diff --git a/public/logo_192.png b/public/logo_192.png new file mode 100644 index 0000000000000000000000000000000000000000..17db294ebbeda36be7bfca84920237c70c5708d0 GIT binary patch literal 5459 zcmcIoXIB$Uu!hh=O(+t&fzXuRLPrQlkx--;MLJ0D9Si}aNtY^JktQG@D4j?zBGM5- z5eU*t==J8kzv12wvvc%4Fugu^vm*pe3>TQ{H{;oC7 zy@+Agn`k4er0_**}xzMv%a>}uCg zqpHP^w~S}%4Ef{V2|sWLK<+FLeuOX+A$V3ajI)>_x02R9&ke;IkSsd#}o8P zb?{+*P${huplkRYov6qhGt23jN}^y%@8IA?DvBvpyKzN9vfviu3$jVqikaLJD-)b) zI0H$vq*YFmxTGyc5%>PnfvzH-D0JoPR{d)Kb&k-|jDqVVJ+=O@YS8jYJ)4n)8|rA~ zsN!)jbJ~!sXcj{O!y@a7sIqRX*1Vdq7`ANjg>~ZPhCOF_jckORO0h0 z@n`T{)SRjPm1XifIb)lC{fYoojb>HaGv87@!^IT08TBXHtVv($ zoJTECadwbGuH7?VO7cD6FLwI;#Ll-oMQ_)^D!jL$%p&V^`>r`7Gc%J0At(FGV9uKJ zgU`AjhrSgzNV~=4rq}Nrf~>5?GYt4}auaXKvgow>B>|X5s|TTou%V`uVDgUu0F_DM zJud3a*5|YuOw1E7390w$@Bn}a?V6l(m)nNF_v~uE^3c!*;h@aN37FGrW9R*H=Goa*H#wcFo$}4iepuRHmoTn!G%i zr|(0ie{LsL`W5zV2%StF*vj!fC+*IJ^PDP@2*N_ruc_=+-IV2j@*@|*ksEA1;>v1v z$2|g;nIAa0QXaIe&+>n^2%=Ei z9!f4sOG-lV+OjX4S9=yztR6+>&hpwuoj>9&bJvR^Myf6@87aAQ=ccvzz8y0IYUa%1 zQbvmpNciMZgO6$Rs<9K(AA~)2=E&{e@_%>;?`|rK1BVlm{tN2NL3Jy4t@1&L8_mIr7q*F{S(e3C{r-=|_9i<%{iM=fr;≈$lro%^Xu% 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 E0I=i+`v3p{ literal 0 HcmV?d00001 diff --git a/public/logo_512.png b/public/logo_512.png new file mode 100644 index 0000000000000000000000000000000000000000..76306c27e2ea2fb9f00978a6a910180e32064e42 GIT binary patch literal 21113 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 XP`~=Sr?A0kCSV!qo879>MMVAwxj|BG literal 0 HcmV?d00001 diff --git a/public/sw.js b/public/sw.js index a94ac67d..ed1172cb 100644 --- a/public/sw.js +++ b/public/sw.js @@ -35,6 +35,36 @@ self.addEventListener('fetch', (event) => { } case "init":{ event.respondWith(new Response("v2")) + break + } + case 'share':{ + event.respondWith((async () => { + const formData = await event.request.formData(); + /** + * @type {File} + */ + const character = formData.get('character') + const preset = formData.get('preset') + const module = formData.get('module') + if(character){ + const buf = await character.arrayBuffer() + await registerCache(`/sw/share/character`, buf, true) + return Response.redirect("/#share_character", 303) + } + if(preset){ + const buf = await preset.arrayBuffer() + await registerCache(`/sw/share/preset`, buf, true) + return Response.redirect("/#share_preset", 303) + } + if(module){ + const buf = await module.arrayBuffer() + await registerCache(`/sw/share/module`, buf, true) + return Response.redirect("/#share_module", 303) + } + return Response.redirect("/", 303) + + })()) + break } default: { event.respondWith(new Response( diff --git a/src/ts/characterCards.ts b/src/ts/characterCards.ts index ffe37d8e..cffde8a4 100644 --- a/src/ts/characterCards.ts +++ b/src/ts/characterCards.ts @@ -14,6 +14,7 @@ import { PngChunk } from "./pngChunk" import type { OnnxModelFiles } from "./process/transformers" import { CharXReader, CharXWriter } from "./process/processzip" import { Capacitor } from "@capacitor/core" +import { exportModule, readModule, type RisuModule } from "./process/modules" export const hubURL = "https://sv.risuai.xyz" @@ -65,6 +66,7 @@ async function importCharacterProcess(f:{ } } + if(f.name.endsWith('charx')){ console.log('reading charx') alertStore.set({ @@ -80,11 +82,18 @@ async function importCharacterProcess(f:{ alertError(language.errors.noData) return } - const card = JSON.parse(cardData) + const card:CharacterCardV3 = JSON.parse(cardData) if(CCardLib.character.check(card) !== 'v3'){ alertError(language.errors.noData) return } + if(reader.moduleData){ + const md = await readModule(Buffer.from(reader.moduleData)) + card.data.extensions ??= {} + card.data.extensions.risuai ??= {} + card.data.extensions.risuai.triggerscript = md.trigger ?? [] + card.data.extensions.risuai.customScripts = md.regex ?? [] + } await importCharacterCardSpec(card, undefined, 'normal', reader.assets) let db = get(DataBase) return db.characters.length - 1 @@ -133,7 +142,7 @@ async function importCharacterProcess(f:{ continue } if(chunk.key.startsWith('chara-ext-asset_')){ - const assetIndex = (chunk.key.replace('chara-ext-asset_', '')) + const assetIndex = chunk.key.replace('chara-ext-asset_:', '').replace('chara-ext-asset_', '') alertWait('Loading... (Reading Asset ' + assetIndex + ')' ) const assetData = Buffer.from(chunk.value, 'base64') const assetId = await saveAsset(assetData) @@ -304,7 +313,7 @@ export async function characterURLImport() { db.modules.push(importData) setDatabase(db) alertNormal(language.successImport) - SettingsMenuIndex.set(1) + SettingsMenuIndex.set(14) settingsOpen.set(true) return } @@ -315,11 +324,90 @@ export async function characterURLImport() { name: 'imported.risupreset', data: importData }) - SettingsMenuIndex.set(14) + SettingsMenuIndex.set(1) settingsOpen.set(true) return - } + if(hash.startsWith('#share_character')){ + const data = await fetch("/sw/share/character") + if(data.status !== 200){ + return + } + const charx = new Uint8Array(await data.arrayBuffer()) + await importCharacterProcess({ + name: 'shared.charx', + data: charx + }) + } + if(hash.startsWith('#share_module')){ + const data = await fetch("/sw/share/module") + if(data.status !== 200){ + return + } + const module = new Uint8Array(await data.arrayBuffer()) + const md = await readModule(Buffer.from(module)) + md.id = v4() + const db = get(DataBase) + db.modules.push(md) + setDatabase(db) + alertNormal(language.successImport) + SettingsMenuIndex.set(14) + settingsOpen.set(true) + } + if(hash.startsWith('#share_preset')){ + const data = await fetch("/sw/share/preset") + if(data.status !== 200){ + return + } + const preset = new Uint8Array(await data.arrayBuffer()) + await importPreset({ + name: 'shared.risup', + data: preset + }) + SettingsMenuIndex.set(1) + settingsOpen.set(true) + } + if ("launchQueue" in window) { + const handleFiles = async (files:FileSystemFileHandle[]) => { + for(const f of files){ + const file = await f.getFile() + const data = new Uint8Array(await file.arrayBuffer()) + if(f.name.endsWith('.charx')){ + await importCharacterProcess({ + name: f.name, + data: data + }) + } + if(f.name.endsWith('.risupreset') || f.name.endsWith('.risup')){ + await importPreset({ + name: f.name, + data: data + }) + SettingsMenuIndex.set(1) + settingsOpen.set(true) + alertNormal(language.successImport) + } + if(f.name.endsWith('risum')){ + const md = await readModule(Buffer.from(data)) + md.id = v4() + const db = get(DataBase) + db.modules.push(md) + setDatabase(db) + alertNormal(language.successImport) + SettingsMenuIndex.set(14) + settingsOpen.set(true) + } + } + } + //@ts-ignore + window.launchQueue.setConsumer((launchParams) => { + if (launchParams.files && launchParams.files.length) { + const files = launchParams.files as FileSystemFileHandle[] + handleFiles(files) + } + }); + } + } @@ -850,7 +938,7 @@ export async function exportCharacterCard(char:character, type:'png'|'json'|'cha const b64encoded = Buffer.from(await convertImage(rData)).toString('base64') assetIndex++ card.data.extensions.risuai.emotions[i][1] = `__asset:${assetIndex}` - await writer.write("chara-ext-asset_" + assetIndex, b64encoded) + await writer.write("chara-ext-asset_:" + assetIndex, b64encoded) } } @@ -866,7 +954,7 @@ export async function exportCharacterCard(char:character, type:'png'|'json'|'cha const b64encoded = Buffer.from(await convertImage(rData)).toString('base64') assetIndex++ card.data.extensions.risuai.additionalAssets[i][1] = `__asset:${assetIndex}` - await writer.write("chara-ext-asset_" + assetIndex, b64encoded) + await writer.write("chara-ext-asset_:" + assetIndex, b64encoded) } } @@ -882,7 +970,7 @@ export async function exportCharacterCard(char:character, type:'png'|'json'|'cha const b64encoded = Buffer.from(rData).toString('base64') assetIndex++ card.data.extensions.risuai.vits[key] = `__asset:${assetIndex}` - await writer.write("chara-ext-asset_" + assetIndex, b64encoded) + await writer.write("chara-ext-asset_:" + assetIndex, b64encoded) } } if(type === 'json'){ @@ -923,7 +1011,7 @@ export async function exportCharacterCard(char:character, type:'png'|'json'|'cha if(type === 'png'){ const b64encoded = Buffer.from(await convertImage(rData)).toString('base64') card.data.assets[i].uri = `__asset:${assetIndex}` - await writer.write("chara-ext-asset_" + assetIndex, b64encoded) + await writer.write("chara-ext-asset_:" + assetIndex, b64encoded) } else if(type === 'json'){ const b64encoded = Buffer.from(await convertImage(rData)).toString('base64') @@ -1015,6 +1103,20 @@ export async function exportCharacterCard(char:character, type:'png'|'json'|'cha }) if(type === 'charx'){ + const md:RisuModule = { + name: `${char.name} Module`, + description: "Module for " + char.name, + id: v4(), + trigger: card.data.extensions.risuai.triggerscript ?? [], + regex: card.data.extensions.risuai.customScripts ?? [], + lorebook: char.globalLore ?? [], + } + delete card.data.extensions.risuai.triggerscript + delete card.data.extensions.risuai.customScripts + await writer.write("module.risum", await exportModule(md, { + alertEnd: false, + saveData: false + })) await writer.write("card.json", Buffer.from(JSON.stringify(card, null, 4))) } else{ diff --git a/src/ts/process/modules.ts b/src/ts/process/modules.ts index 0d4800a2..a7b9c198 100644 --- a/src/ts/process/modules.ts +++ b/src/ts/process/modules.ts @@ -27,7 +27,12 @@ export interface RisuModule{ namespace?:string } -export async function exportModule(module:RisuModule){ +export async function exportModule(module:RisuModule, arg:{ + alertEnd?:boolean + saveData?:boolean +} = {}){ + const alertEnd = arg.alertEnd ?? true + const saveData = arg.saveData ?? true const apb = new AppendableBuffer() const writeLength = (len:number) => { const lenbuf = Buffer.alloc(4) @@ -76,8 +81,90 @@ export async function exportModule(module:RisuModule){ writeByte(0) //end of file - await downloadFile(module.name + '.risum', apb.buffer) - alertNormal(language.successExport) + if(saveData){ + await downloadFile(module.name + '.risum', apb.buffer) + } + if(alertEnd){ + alertNormal(language.successExport) + } + + return apb.buffer +} + +export async function readModule(buf:Buffer):Promise { + let pos = 0 + + const readLength = () => { + const len = buf.readUInt32LE(pos) + pos += 4 + return len + } + const readByte = () => { + const byte = buf.readUInt8(pos) + pos += 1 + return byte + } + const readData = (len:number) => { + const data = buf.subarray(pos, pos + len) + pos += len + return data + } + + if(readByte() !== 111){ + console.error("Invalid magic number") + alertError(language.errors.noData) + return + } + if(readByte() !== 0){ //Version check + console.error("Invalid version") + alertError(language.errors.noData) + return + } + + const mainLen = readLength() + const mainData = readData(mainLen) + const main:{ + type:'risuModule' + module:RisuModule + } = JSON.parse(Buffer.from(await decodeRPack(mainData)).toString()) + + if(main.type !== 'risuModule'){ + console.error("Invalid module type") + alertError(language.errors.noData) + return + } + + let module = main.module + + let i = 0 + while(true){ + const mark = readByte() + if(mark === 0){ + break + } + if(mark !== 1){ + alertError(language.errors.noData) + return + } + const len = readLength() + const data = readData(len) + module.assets[i][1] = await saveAsset(Buffer.from(await decodeRPack(data))) + alertStore.set({ + type: 'wait', + msg: `Loading... (Adding Assets ${i} / ${module.assets.length})` + }) + if(!isTauri && !Capacitor.isNativePlatform() &&!isNodeServer){ + await sleep(100) + } + i++ + } + alertStore.set({ + type: 'none', + msg: '' + }) + + module.id = v4() + return module } export async function importModule(){ @@ -90,78 +177,7 @@ export async function importModule(){ if(f.name.endsWith('.risum')){ try { const buf = Buffer.from(fileData) - let pos = 0 - - const readLength = () => { - const len = buf.readUInt32LE(pos) - pos += 4 - return len - } - const readByte = () => { - const byte = buf.readUInt8(pos) - pos += 1 - return byte - } - const readData = (len:number) => { - const data = buf.subarray(pos, pos + len) - pos += len - return data - } - - if(readByte() !== 111){ - console.error("Invalid magic number") - alertError(language.errors.noData) - return - } - if(readByte() !== 0){ //Version check - console.error("Invalid version") - alertError(language.errors.noData) - return - } - - const mainLen = readLength() - const mainData = readData(mainLen) - const main:{ - type:'risuModule' - module:RisuModule - } = JSON.parse(Buffer.from(await decodeRPack(mainData)).toString()) - - if(main.type !== 'risuModule'){ - console.error("Invalid module type") - alertError(language.errors.noData) - return - } - - let module = main.module - - let i = 0 - while(true){ - const mark = readByte() - if(mark === 0){ - break - } - if(mark !== 1){ - alertError(language.errors.noData) - return - } - const len = readLength() - const data = readData(len) - module.assets[i][1] = await saveAsset(Buffer.from(await decodeRPack(data))) - alertStore.set({ - type: 'wait', - msg: `Loading... (Adding Assets ${i} / ${module.assets.length})` - }) - if(!isTauri && !Capacitor.isNativePlatform() &&!isNodeServer){ - await sleep(100) - } - i++ - } - alertStore.set({ - type: 'none', - msg: '' - }) - - module.id = v4() + const module = await readModule(buf) db.modules.push(module) setDatabase(db) return diff --git a/src/ts/process/processzip.ts b/src/ts/process/processzip.ts index a74d0c5f..a3f85f6d 100644 --- a/src/ts/process/processzip.ts +++ b/src/ts/process/processzip.ts @@ -81,6 +81,7 @@ export class CharXReader{ assetPromises:Promise[] = [] excludedFiles:string[] = [] cardData:string|undefined + moduleData:Uint8Array|undefined constructor(){ this.unzip = new fflate.Unzip() this.unzip.register(fflate.UnzipInflate) @@ -98,6 +99,9 @@ export class CharXReader{ else if(file.name === 'card.json'){ this.cardData = new TextDecoder().decode(assetData) } + else if(file.name === 'module.risum'){ + this.moduleData = assetData + } else{ this.assetPromises.push((async () => { const assetId = await saveAsset(assetData)