Add PWA support
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
<link rel="icon" type="image/png" sizes="16x16" href="/logo_16.png" />
|
<link rel="icon" type="image/png" sizes="16x16" href="/logo_16.png" />
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/logo_32.png" />
|
<link rel="icon" type="image/png" sizes="32x32" href="/logo_32.png" />
|
||||||
<link rel="icon" type="image/png" sizes="256x256" href="/logo_256.png" />
|
<link rel="icon" type="image/png" sizes="256x256" href="/logo_256.png" />
|
||||||
|
<link rel="manifest" href="manifest.json" />
|
||||||
<meta name="description" content="An AI frontend for both light and core users.">
|
<meta name="description" content="An AI frontend for both light and core users.">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Tilt+Prism&family=Yellowtail&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Tilt+Prism&family=Yellowtail&display=swap" rel="stylesheet">
|
||||||
|
|||||||
63
manifest.json
Normal file
63
manifest.json
Normal file
@@ -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"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
}
|
||||||
BIN
public/logo_192.png
Normal file
BIN
public/logo_192.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.3 KiB |
BIN
public/logo_512.png
Normal file
BIN
public/logo_512.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
30
public/sw.js
30
public/sw.js
@@ -35,6 +35,36 @@ self.addEventListener('fetch', (event) => {
|
|||||||
}
|
}
|
||||||
case "init":{
|
case "init":{
|
||||||
event.respondWith(new Response("v2"))
|
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: {
|
default: {
|
||||||
event.respondWith(new Response(
|
event.respondWith(new Response(
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { PngChunk } from "./pngChunk"
|
|||||||
import type { OnnxModelFiles } from "./process/transformers"
|
import type { OnnxModelFiles } from "./process/transformers"
|
||||||
import { CharXReader, CharXWriter } from "./process/processzip"
|
import { CharXReader, CharXWriter } from "./process/processzip"
|
||||||
import { Capacitor } from "@capacitor/core"
|
import { Capacitor } from "@capacitor/core"
|
||||||
|
import { exportModule, readModule, type RisuModule } from "./process/modules"
|
||||||
|
|
||||||
export const hubURL = "https://sv.risuai.xyz"
|
export const hubURL = "https://sv.risuai.xyz"
|
||||||
|
|
||||||
@@ -65,6 +66,7 @@ async function importCharacterProcess(f:{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(f.name.endsWith('charx')){
|
if(f.name.endsWith('charx')){
|
||||||
console.log('reading charx')
|
console.log('reading charx')
|
||||||
alertStore.set({
|
alertStore.set({
|
||||||
@@ -80,11 +82,18 @@ async function importCharacterProcess(f:{
|
|||||||
alertError(language.errors.noData)
|
alertError(language.errors.noData)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const card = JSON.parse(cardData)
|
const card:CharacterCardV3 = JSON.parse(cardData)
|
||||||
if(CCardLib.character.check(card) !== 'v3'){
|
if(CCardLib.character.check(card) !== 'v3'){
|
||||||
alertError(language.errors.noData)
|
alertError(language.errors.noData)
|
||||||
return
|
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)
|
await importCharacterCardSpec(card, undefined, 'normal', reader.assets)
|
||||||
let db = get(DataBase)
|
let db = get(DataBase)
|
||||||
return db.characters.length - 1
|
return db.characters.length - 1
|
||||||
@@ -133,7 +142,7 @@ async function importCharacterProcess(f:{
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if(chunk.key.startsWith('chara-ext-asset_')){
|
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 + ')' )
|
alertWait('Loading... (Reading Asset ' + assetIndex + ')' )
|
||||||
const assetData = Buffer.from(chunk.value, 'base64')
|
const assetData = Buffer.from(chunk.value, 'base64')
|
||||||
const assetId = await saveAsset(assetData)
|
const assetId = await saveAsset(assetData)
|
||||||
@@ -304,7 +313,7 @@ export async function characterURLImport() {
|
|||||||
db.modules.push(importData)
|
db.modules.push(importData)
|
||||||
setDatabase(db)
|
setDatabase(db)
|
||||||
alertNormal(language.successImport)
|
alertNormal(language.successImport)
|
||||||
SettingsMenuIndex.set(1)
|
SettingsMenuIndex.set(14)
|
||||||
settingsOpen.set(true)
|
settingsOpen.set(true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -315,11 +324,90 @@ export async function characterURLImport() {
|
|||||||
name: 'imported.risupreset',
|
name: 'imported.risupreset',
|
||||||
data: importData
|
data: importData
|
||||||
})
|
})
|
||||||
SettingsMenuIndex.set(14)
|
SettingsMenuIndex.set(1)
|
||||||
settingsOpen.set(true)
|
settingsOpen.set(true)
|
||||||
return
|
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')
|
const b64encoded = Buffer.from(await convertImage(rData)).toString('base64')
|
||||||
assetIndex++
|
assetIndex++
|
||||||
card.data.extensions.risuai.emotions[i][1] = `__asset:${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')
|
const b64encoded = Buffer.from(await convertImage(rData)).toString('base64')
|
||||||
assetIndex++
|
assetIndex++
|
||||||
card.data.extensions.risuai.additionalAssets[i][1] = `__asset:${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')
|
const b64encoded = Buffer.from(rData).toString('base64')
|
||||||
assetIndex++
|
assetIndex++
|
||||||
card.data.extensions.risuai.vits[key] = `__asset:${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'){
|
if(type === 'json'){
|
||||||
@@ -923,7 +1011,7 @@ export async function exportCharacterCard(char:character, type:'png'|'json'|'cha
|
|||||||
if(type === 'png'){
|
if(type === 'png'){
|
||||||
const b64encoded = Buffer.from(await convertImage(rData)).toString('base64')
|
const b64encoded = Buffer.from(await convertImage(rData)).toString('base64')
|
||||||
card.data.assets[i].uri = `__asset:${assetIndex}`
|
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'){
|
else if(type === 'json'){
|
||||||
const b64encoded = Buffer.from(await convertImage(rData)).toString('base64')
|
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'){
|
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)))
|
await writer.write("card.json", Buffer.from(JSON.stringify(card, null, 4)))
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
|||||||
@@ -27,7 +27,12 @@ export interface RisuModule{
|
|||||||
namespace?:string
|
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 apb = new AppendableBuffer()
|
||||||
const writeLength = (len:number) => {
|
const writeLength = (len:number) => {
|
||||||
const lenbuf = Buffer.alloc(4)
|
const lenbuf = Buffer.alloc(4)
|
||||||
@@ -76,8 +81,90 @@ export async function exportModule(module:RisuModule){
|
|||||||
|
|
||||||
writeByte(0) //end of file
|
writeByte(0) //end of file
|
||||||
|
|
||||||
await downloadFile(module.name + '.risum', apb.buffer)
|
if(saveData){
|
||||||
alertNormal(language.successExport)
|
await downloadFile(module.name + '.risum', apb.buffer)
|
||||||
|
}
|
||||||
|
if(alertEnd){
|
||||||
|
alertNormal(language.successExport)
|
||||||
|
}
|
||||||
|
|
||||||
|
return apb.buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function readModule(buf:Buffer):Promise<RisuModule> {
|
||||||
|
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(){
|
export async function importModule(){
|
||||||
@@ -90,78 +177,7 @@ export async function importModule(){
|
|||||||
if(f.name.endsWith('.risum')){
|
if(f.name.endsWith('.risum')){
|
||||||
try {
|
try {
|
||||||
const buf = Buffer.from(fileData)
|
const buf = Buffer.from(fileData)
|
||||||
let pos = 0
|
const module = await readModule(buf)
|
||||||
|
|
||||||
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()
|
|
||||||
db.modules.push(module)
|
db.modules.push(module)
|
||||||
setDatabase(db)
|
setDatabase(db)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ export class CharXReader{
|
|||||||
assetPromises:Promise<void>[] = []
|
assetPromises:Promise<void>[] = []
|
||||||
excludedFiles:string[] = []
|
excludedFiles:string[] = []
|
||||||
cardData:string|undefined
|
cardData:string|undefined
|
||||||
|
moduleData:Uint8Array|undefined
|
||||||
constructor(){
|
constructor(){
|
||||||
this.unzip = new fflate.Unzip()
|
this.unzip = new fflate.Unzip()
|
||||||
this.unzip.register(fflate.UnzipInflate)
|
this.unzip.register(fflate.UnzipInflate)
|
||||||
@@ -98,6 +99,9 @@ export class CharXReader{
|
|||||||
else if(file.name === 'card.json'){
|
else if(file.name === 'card.json'){
|
||||||
this.cardData = new TextDecoder().decode(assetData)
|
this.cardData = new TextDecoder().decode(assetData)
|
||||||
}
|
}
|
||||||
|
else if(file.name === 'module.risum'){
|
||||||
|
this.moduleData = assetData
|
||||||
|
}
|
||||||
else{
|
else{
|
||||||
this.assetPromises.push((async () => {
|
this.assetPromises.push((async () => {
|
||||||
const assetId = await saveAsset(assetData)
|
const assetId = await saveAsset(assetData)
|
||||||
|
|||||||
Reference in New Issue
Block a user