diff --git a/src/ts/parser.ts b/src/ts/parser.ts
index 540dead0..b20fd357 100644
--- a/src/ts/parser.ts
+++ b/src/ts/parser.ts
@@ -1,10 +1,12 @@
import DOMPurify from 'isomorphic-dompurify';
import showdown from 'showdown';
-import { DataBase, type character, type groupChat } from './storage/database';
+import { DataBase, type Database, type character, type groupChat } from './storage/database';
import { getFileSrc } from './storage/globalApi';
import { processScript, processScriptFull } from './process/scripts';
import { get } from 'svelte/store';
import css from '@adobe/css-tools'
+import { selectedCharID } from './stores';
+import { calcString } from './process/infunctions';
const convertor = new showdown.Converter({
simpleLineBreaks: true,
@@ -238,4 +240,215 @@ function wppParser(data:string){
});
return characterDetails;
+}
+
+const rgx = /(?:{{|<)(.+?)(?:}}|>)/gm
+export function risuChatParser(da:string, arg:{
+ chatID?:number
+ db?:Database
+ chara?:string|character
+} = {}):string{
+ const chatID = arg.chatID ?? -1
+ const db = arg.db ?? get(DataBase)
+ return da.replace(rgx, (v, p1:string) => {
+ const lowerCased = p1.toLocaleLowerCase()
+ switch(lowerCased){
+ case 'previous_char_chat':{
+ if(chatID !== -1){
+ const selchar = db.characters[get(selectedCharID)]
+ const chat = selchar.chats[selchar.chatPage]
+ let pointer = chatID - 1
+ while(pointer >= 0){
+ if(chat.message[pointer].role === 'char'){
+ return chat.message[pointer].data
+ }
+ pointer--
+ }
+ return selchar.firstMsgIndex === -1 ? selchar.firstMessage : selchar.alternateGreetings[selchar.firstMsgIndex]
+ }
+ return ''
+ }
+ case 'previous_user_chat':{
+ if(chatID !== -1){
+ const selchar = db.characters[get(selectedCharID)]
+ const chat = selchar.chats[selchar.chatPage]
+ let pointer = chatID - 1
+ while(pointer >= 0){
+ if(chat.message[pointer].role === 'user'){
+ return chat.message[pointer].data
+ }
+ pointer--
+ }
+ return selchar.firstMsgIndex === -1 ? selchar.firstMessage : selchar.alternateGreetings[selchar.firstMsgIndex]
+ }
+ return ''
+ }
+ case 'char':
+ case 'bot':{
+ const chara = arg.chara
+ if(chara){
+ if(typeof(chara) === 'string'){
+ return chara
+ }
+ else{
+ return chara.name
+ }
+ }
+ let selectedChar = get(selectedCharID)
+ let currentChar = db.characters[selectedChar]
+ return currentChar.name
+ }
+ case 'user':{
+ return db.username
+ }
+ case 'personality':
+ case 'char_persona':{
+ const argChara = arg.chara
+ const chara = (argChara && typeof(argChara) !== 'string') ? argChara : (db.characters[get(selectedCharID)])
+ if(chara.type === 'group'){
+ return ""
+ }
+ return chara.personality
+ }
+ case 'persona':
+ case 'user_persona':{
+ const argChara = arg.chara
+ const chara = (argChara && typeof(argChara) !== 'string') ? argChara : (db.characters[get(selectedCharID)])
+ if(chara.type === 'group'){
+ return ""
+ }
+ return chara.personality
+ }
+ case 'ujb':
+ case 'global_note':{
+ return db.globalNote
+ }
+ case 'chat_index':{
+ return chatID.toString()
+ }
+ case 'blank':
+ case 'none':{
+ return ''
+ }
+ }
+ const arra = p1.split("::")
+ if(arra.length > 1){
+ const v = arra[1]
+ switch(arra[0]){
+ case 'getvar':{
+ const d =getVarChat(chatID)
+ return d[v] ?? "[Null]"
+ }
+ case 'calc':{
+ return calcString(v).toString()
+ }
+ case 'addvar':
+ case 'setvar':{
+ return ''
+ }
+ case 'button':{
+ return ``
+ }
+ case 'risu':{
+ return `
`
+ }
+ }
+ }
+ if(p1.startsWith('random')){
+ if(p1.startsWith('random::')){
+ const randomIndex = Math.floor(Math.random() * (arra.length - 1)) + 1
+ return arra[randomIndex]
+ }
+ else{
+ const arr = p1.split(/\:|\,/g)
+ const randomIndex = Math.floor(Math.random() * (arr.length - 1)) + 1
+ return arr[randomIndex]
+ }
+ }
+ return v
+ })
+}
+
+
+function getVarChat(targetIndex = -1){
+ const db = get(DataBase)
+ const selchar = db.characters[get(selectedCharID)]
+ const chat = selchar.chats[selchar.chatPage]
+ let i =0;
+ if(targetIndex === -1 || targetIndex >= chat.message.length){
+ targetIndex = chat.message.length - 1
+ }
+ let vars:{[key:string]:string} = {}
+ let rules:{
+ key:string
+ rule:string
+ arg:string
+ }[] = []
+ const fm = selchar.firstMsgIndex === -1 ? selchar.firstMessage : selchar.alternateGreetings[selchar.firstMsgIndex]
+ const rg = /(\{\{setvar::(.+?)::(.+?)\}\})/gu
+ const rg2 = /(\{\{addvar::(.+?)::(.+?)\}\})/gu
+ const rg3 = /(\{\{varrule_(.+?)::(.+?)::(.+?)\}\})/gu
+ function process(text:string){
+ const m = text.matchAll(rg)
+ for(const a of m){
+ if(a.length === 4){
+ vars[a[2]] = a[3]
+ }
+ }
+ const m2 = text.matchAll(rg2)
+ for(const a of m2){
+ if(a.length === 4){
+ vars[a[2]] = (parseInt(vars[a[2]]) + parseInt(a[3])).toString()
+ }
+ }
+ const m3 = text.matchAll(rg3)
+ for(const a of m3){
+ if(a.length === 5){
+ rules.push({
+ key: a[3],
+ rule: a[2],
+ arg: a[4]
+ })
+ }
+ }
+ }
+ process(fm)
+ while( i <= targetIndex ){
+ process(chat.message[i].data)
+ i += 1
+ }
+
+ for(const rule of rules){
+ if(vars[rule.key] === undefined){
+ continue
+ }
+ switch(rule.rule){
+ case "max":{
+ if(parseInt(vars[rule.key]) > parseInt(rule.arg)){
+ vars[rule.key] = rule.arg
+ }
+ break
+ }
+ case "min":{
+ if(parseInt(vars[rule.key]) > parseInt(rule.arg)){
+ vars[rule.key] = rule.arg
+ }
+ break
+ }
+ case 'overflow':{
+ const exArg = rule.arg.split(":")
+ let rv = parseInt(vars[rule.key])
+ const val = parseInt(exArg[0])
+ const tg = exArg[1]
+
+ if(isNaN(val) || isNaN(rv)){
+ break
+ }
+
+ vars[tg] = (Math.floor(rv / val)).toString()
+ vars[rule.key] = (Math.floor(rv % val)).toString()
+ }
+ }
+ }
+ return vars
}
\ No newline at end of file
diff --git a/src/ts/process/scripts.ts b/src/ts/process/scripts.ts
index 5ca89ca3..e9f7fe36 100644
--- a/src/ts/process/scripts.ts
+++ b/src/ts/process/scripts.ts
@@ -4,8 +4,8 @@ import { DataBase, setDatabase, type character, type customscript, type groupCha
import { downloadFile } from "../storage/globalApi";
import { alertError, alertNormal } from "../alert";
import { language } from "src/lang";
-import { findCharacterbyId, selectSingleFile } from "../util";
-import { calcString } from "./infunctions";
+import { selectSingleFile } from "../util";
+import { risuChatParser as risuChatParserOrg } from "../parser";
const dreg = /{{data}}/g
const randomness = /\|\|\|/g
@@ -144,212 +144,4 @@ export function processScriptFull(char:character|groupChat, data:string, mode:Sc
const rgx = /(?:{{|<)(.+?)(?:}}|>)/gm
-export function risuChatParser(da:string, arg:{
- chatID?:number
- db?:Database
- chara?:string|character
-} = {}):string{
- const chatID = arg.chatID ?? -1
- const db = arg.db ?? get(DataBase)
- return da.replace(rgx, (v, p1:string) => {
- const lowerCased = p1.toLocaleLowerCase()
- switch(lowerCased){
- case 'previous_char_chat':{
- if(chatID !== -1){
- const selchar = db.characters[get(selectedCharID)]
- const chat = selchar.chats[selchar.chatPage]
- let pointer = chatID - 1
- while(pointer >= 0){
- if(chat.message[pointer].role === 'char'){
- return chat.message[pointer].data
- }
- pointer--
- }
- return selchar.firstMsgIndex === -1 ? selchar.firstMessage : selchar.alternateGreetings[selchar.firstMsgIndex]
- }
- return ''
- }
- case 'previous_user_chat':{
- if(chatID !== -1){
- const selchar = db.characters[get(selectedCharID)]
- const chat = selchar.chats[selchar.chatPage]
- let pointer = chatID - 1
- while(pointer >= 0){
- if(chat.message[pointer].role === 'user'){
- return chat.message[pointer].data
- }
- pointer--
- }
- return selchar.firstMsgIndex === -1 ? selchar.firstMessage : selchar.alternateGreetings[selchar.firstMsgIndex]
- }
- return ''
- }
- case 'char':
- case 'bot':{
- const chara = arg.chara
- if(chara){
- if(typeof(chara) === 'string'){
- return chara
- }
- else{
- return chara.name
- }
- }
- let selectedChar = get(selectedCharID)
- let currentChar = db.characters[selectedChar]
- return currentChar.name
- }
- case 'user':{
- return db.username
- }
- case 'personality':
- case 'char_persona':{
- const argChara = arg.chara
- const chara = (argChara && typeof(argChara) !== 'string') ? argChara : (db.characters[get(selectedCharID)])
- if(chara.type === 'group'){
- return ""
- }
- return chara.personality
- }
- case 'persona':
- case 'user_persona':{
- const argChara = arg.chara
- const chara = (argChara && typeof(argChara) !== 'string') ? argChara : (db.characters[get(selectedCharID)])
- if(chara.type === 'group'){
- return ""
- }
- return chara.personality
- }
- case 'ujb':
- case 'global_note':{
- return db.globalNote
- }
- case 'chat_index':{
- return chatID.toString()
- }
- case 'blank':
- case 'none':{
- return ''
- }
- }
- const arra = p1.split("::")
- if(arra.length > 1){
- const v = arra[1]
- switch(arra[0]){
- case 'getvar':{
- const d =getVarChat(chatID)
- return d[v] ?? "[Null]"
- }
- case 'calc':{
- return calcString(v).toString()
- }
- case 'addvar':
- case 'setvar':{
- return ''
- }
- case 'button':{
- return ``
- }
- case 'risu':{
- return `
`
- }
- }
- }
- if(p1.startsWith('random')){
- if(p1.startsWith('random::')){
- const randomIndex = Math.floor(Math.random() * (arra.length - 1)) + 1
- return arra[randomIndex]
- }
- else{
- const arr = p1.split(/\:|\,/g)
- const randomIndex = Math.floor(Math.random() * (arr.length - 1)) + 1
- return arr[randomIndex]
- }
- }
- return v
- })
-}
-
-
-export function getVarChat(targetIndex = -1){
- const db = get(DataBase)
- const selchar = db.characters[get(selectedCharID)]
- const chat = selchar.chats[selchar.chatPage]
- let i =0;
- if(targetIndex === -1 || targetIndex >= chat.message.length){
- targetIndex = chat.message.length - 1
- }
- let vars:{[key:string]:string} = {}
- let rules:{
- key:string
- rule:string
- arg:string
- }[] = []
- const fm = selchar.firstMsgIndex === -1 ? selchar.firstMessage : selchar.alternateGreetings[selchar.firstMsgIndex]
- const rg = /(\{\{setvar::(.+?)::(.+?)\}\})/gu
- const rg2 = /(\{\{addvar::(.+?)::(.+?)\}\})/gu
- const rg3 = /(\{\{varrule_(.+?)::(.+?)::(.+?)\}\})/gu
- function process(text:string){
- const m = text.matchAll(rg)
- for(const a of m){
- if(a.length === 4){
- vars[a[2]] = a[3]
- }
- }
- const m2 = text.matchAll(rg2)
- for(const a of m2){
- if(a.length === 4){
- vars[a[2]] = (parseInt(vars[a[2]]) + parseInt(a[3])).toString()
- }
- }
- const m3 = text.matchAll(rg3)
- for(const a of m3){
- if(a.length === 5){
- rules.push({
- key: a[3],
- rule: a[2],
- arg: a[4]
- })
- }
- }
- }
- process(fm)
- while( i <= targetIndex ){
- process(chat.message[i].data)
- i += 1
- }
-
- for(const rule of rules){
- if(vars[rule.key] === undefined){
- continue
- }
- switch(rule.rule){
- case "max":{
- if(parseInt(vars[rule.key]) > parseInt(rule.arg)){
- vars[rule.key] = rule.arg
- }
- break
- }
- case "min":{
- if(parseInt(vars[rule.key]) > parseInt(rule.arg)){
- vars[rule.key] = rule.arg
- }
- break
- }
- case 'overflow':{
- const exArg = rule.arg.split(":")
- let rv = parseInt(vars[rule.key])
- const val = parseInt(exArg[0])
- const tg = exArg[1]
-
- if(isNaN(val) || isNaN(rv)){
- break
- }
-
- vars[tg] = (Math.floor(rv / val)).toString()
- vars[rule.key] = (Math.floor(rv % val)).toString()
- }
- }
- }
- return vars
-}
\ No newline at end of file
+export const risuChatParser = risuChatParserOrg
\ No newline at end of file
diff --git a/src/ts/storage/globalApi.ts b/src/ts/storage/globalApi.ts
index c6a206a6..971e84a5 100644
--- a/src/ts/storage/globalApi.ts
+++ b/src/ts/storage/globalApi.ts
@@ -662,9 +662,10 @@ export async function globalFetch(url:string, arg:{plainFetchForce?:boolean,body
}
} catch (error) {
addFetchLog(daText, false)
+ let errorMsg = (daText.startsWith('