dsh-pet-live2d-viola 1.1.2 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -100,6 +100,26 @@ DeepSeek Harness Web GUI 的 **Live2D 桌宠插件**,一台桌宠里可以切
100
100
  - 开关与范围是**两个独立字段**,所以关掉再打开会记住上次选的范围
101
101
  - 默认**关闭**。待机漂移本来只动身体不动脸,因为自己乱变的脸会覆盖你手动选的表情 —— 这是有意的默认值
102
102
 
103
+ ## 余额警告
104
+
105
+ 账户余额降到 **5、4、3、2、1 元**时,她会提醒你一次 —— **每跨过一档提醒一次**,同一档位不会重复。
106
+
107
+ 提醒内容是**一段完整反应**:气泡 + 动作 + 表情,播完恢复原来的表情。每个角色有三种,**随机播放一种**:
108
+
109
+ | 角色 | 三种反应 |
110
+ |---|---|
111
+ | 都子 | 没有忘记买什么吧? / 接下来一周注定要靠冷冻面包度日了 / 我现在已经学会适度克制了。 只是…… |
112
+ | 薇欧拉 | 就像烟花最后的闪耀 / 提问~ 火种燃尽之会怎么样呢~? / 好可怕~ |
113
+ | 由乃 | 为什么偏偏在这种关键时候……! / 至、至少……就一点也好…… / 不不不绝对不对 |
114
+
115
+ - 余额 = **充值余额 + 赠送余额**(赠送的也能花,漏掉会少算)
116
+ - 只算 **CNY** 钱包;USD 钱包是另一种货币,不折算进元
117
+ - **每 60 秒**读一次账户余额
118
+ - 桌宠启动时余额已经很低 → **不提醒**,因为那不是「刚刚发生的变化」
119
+ - 余额回到 5 元以上再降下来 → 会**重新提醒**
120
+ - 在 **设置 → 余额警告** 里可以关闭
121
+ - 关闭、未登录、或读不到余额时**完全静默**:不会把「读不到」当成 0 元
122
+
103
123
  ## 功能简介
104
124
 
105
125
  **右键 → 设置 → 功能简介** —— 只读面板,介绍当前人物的能力。
@@ -113,6 +133,7 @@ DeepSeek Harness Web GUI 的 **Live2D 桌宠插件**,一台桌宠里可以切
113
133
  | 待机动作数 | 本角色的待机池 |
114
134
  | 语音条数 | 点击 + 阶段反应 + 待机 + 下线 |
115
135
  | 随机模式 | 说明 + **当前是否开启及所选范围** |
136
+ | 余额警告 | 说明 + **当前是否开启**,能读到余额时附带「余额 ¥x.xx」 |
116
137
 
117
138
  ## 取景
118
139
 
@@ -0,0 +1 @@
1
+ {"Type":"Expression","FadeInTime":0.5,"FadeOutTime":1,"Parameters":[{"Id":"ParamEyeLOpen","Value":1,"Blend":"Multiply"},{"Id":"ParamEyeLSmile","Value":0,"Blend":"Add"},{"Id":"ParamEyeROpen","Value":1,"Blend":"Multiply"},{"Id":"ParamEyeRSmile","Value":0,"Blend":"Add"},{"Id":"ParameyelidL","Value":0,"Blend":"Add"},{"Id":"ParameyelidR","Value":0,"Blend":"Add"},{"Id":"ParamEyeBallX","Value":0,"Blend":"Add"},{"Id":"ParamEyeBallY","Value":0,"Blend":"Add"},{"Id":"ParamEyeLScsle","Value":0,"Blend":"Add"},{"Id":"ParamEyeRScsle","Value":0,"Blend":"Add"},{"Id":"ParamEyeLScsle2","Value":0,"Blend":"Add"},{"Id":"ParamEyeRScsle2","Value":0,"Blend":"Add"},{"Id":"ParamEyeLHighlight","Value":0,"Blend":"Add"},{"Id":"ParamEyeRHighlight","Value":0,"Blend":"Add"},{"Id":"ParamTear","Value":0,"Blend":"Add"},{"Id":"ParamTear2","Value":0,"Blend":"Add"},{"Id":"ParamEyeSiwaON","Value":0,"Blend":"Add"},{"Id":"ParamTears1","Value":0,"Blend":"Add"},{"Id":"ParamTears2","Value":0,"Blend":"Add"},{"Id":"ParamTears3","Value":0,"Blend":"Add"},{"Id":"ParamTears0","Value":0,"Blend":"Add"},{"Id":"ParamguruguruLR","Value":0,"Blend":"Add"},{"Id":"ParamwakuwakuLR2","Value":0,"Blend":"Add"},{"Id":"ParamwakuwakuLR3","Value":0,"Blend":"Add"},{"Id":"ParamBrowLY","Value":0.2800000011920929,"Blend":"Add"},{"Id":"ParamBrowLX","Value":0.6000000238418579,"Blend":"Add"},{"Id":"ParamBrowLAngle","Value":0.2199999988079071,"Blend":"Add"},{"Id":"ParamBrowLForm","Value":-0.75,"Blend":"Add"},{"Id":"ParamBrowRY","Value":0.28200000524520874,"Blend":"Add"},{"Id":"ParamBrowRX","Value":-0.328000009059906,"Blend":"Add"},{"Id":"ParamBrowRAngle","Value":0.21799999475479126,"Blend":"Add"},{"Id":"ParamBrowRForm","Value":-0.7459999918937683,"Blend":"Add"},{"Id":"Param_angry_eyebrows","Value":0,"Blend":"Add"},{"Id":"ParameyebrowsRON","Value":0,"Blend":"Add"},{"Id":"ParameyebrowsLON","Value":0,"Blend":"Add"},{"Id":"ParameyebrowscenterON","Value":0,"Blend":"Add"},{"Id":"ParameyebrowscenterPos","Value":0,"Blend":"Add"},{"Id":"Paramangry01","Value":0,"Blend":"Add"},{"Id":"Paramangry02","Value":0,"Blend":"Add"},{"Id":"Paramcry01sad01","Value":0,"Blend":"Add"},{"Id":"Paramblush","Value":0,"Blend":"Add"},{"Id":"Paramthinking01","Value":0,"Blend":"Add"},{"Id":"Paramanxiety01","Value":1,"Blend":"Add"},{"Id":"Parampanic","Value":0,"Blend":"Add"},{"Id":"Paramserious01","Value":0,"Blend":"Add"},{"Id":"Paramtired","Value":0,"Blend":"Add"},{"Id":"Paramwakuwaku","Value":0,"Blend":"Add"},{"Id":"Paramuturo","Value":0,"Blend":"Add"},{"Id":"Paramkime01","Value":0,"Blend":"Add"},{"Id":"Paramshock","Value":0,"Blend":"Add"},{"Id":"Paramzito","Value":0,"Blend":"Add"},{"Id":"Paramhutekusare","Value":0,"Blend":"Add"},{"Id":"Paramkegen","Value":0,"Blend":"Add"},{"Id":"Paramakire","Value":0,"Blend":"Add"},{"Id":"Paramcryangry","Value":0,"Blend":"Add"},{"Id":"Paramcryangry2","Value":0,"Blend":"Add"},{"Id":"Paramangry03","Value":0,"Blend":"Add"},{"Id":"Paramsad02","Value":0,"Blend":"Add"},{"Id":"Paramsmile04","Value":0,"Blend":"Add"},{"Id":"Paramblush2","Value":0,"Blend":"Add"},{"Id":"Paramwakuwaku01","Value":0,"Blend":"Add"},{"Id":"Paramwakuwaku02","Value":0,"Blend":"Add"},{"Id":"Paramguruguru","Value":0,"Blend":"Add"},{"Id":"Paramguruguru2","Value":0,"Blend":"Add"},{"Id":"Paramhitomi0","Value":0,"Blend":"Add"},{"Id":"ParameyeOFF","Value":0,"Blend":"Add"},{"Id":"ParamCheek","Value":0,"Blend":"Add"},{"Id":"ParamsweatON","Value":1,"Blend":"Add"},{"Id":"ParamsweatON3","Value":0,"Blend":"Add"},{"Id":"ParamsweatON2","Value":0,"Blend":"Add"},{"Id":"ParamAozameON","Value":0,"Blend":"Add"},{"Id":"ParamAozameON2","Value":0,"Blend":"Add"},{"Id":"exp_shadow01","Value":0,"Blend":"Add"},{"Id":"exp_cheekONOFF","Value":0,"Blend":"Add"},{"Id":"ParamNosePos","Value":0,"Blend":"Add"},{"Id":"Param7","Value":0,"Blend":"Add"},{"Id":"Param8","Value":0,"Blend":"Add"},{"Id":"Param16","Value":0,"Blend":"Add"},{"Id":"ParamEmo1","Value":0,"Blend":"Add"},{"Id":"ParamEmo2","Value":1,"Blend":"Add"},{"Id":"ParamEmo3","Value":0,"Blend":"Add"},{"Id":"ParamEmo4","Value":0,"Blend":"Add"},{"Id":"ParamMouthForm","Value":0,"Blend":"Add"},{"Id":"ParamMouthOpenY","Value":0,"Blend":"Add"},{"Id":"ParamMouthside","Value":0,"Blend":"Add"},{"Id":"ParamMouthupdawn","Value":0,"Blend":"Add"},{"Id":"Param9","Value":0,"Blend":"Add"},{"Id":"ParamMouthStrength","Value":0,"Blend":"Add"},{"Id":"ParamMouthStrength2","Value":0,"Blend":"Add"},{"Id":"ParamTeethON","Value":-1,"Blend":"Add"},{"Id":"ParamMouthSiwaON","Value":0,"Blend":"Add"},{"Id":"ParamMouthSiwaON2","Value":0,"Blend":"Add"},{"Id":"ParamTear3","Value":0,"Blend":"Add"},{"Id":"ParamMaruMouthOpen","Value":0,"Blend":"Add"},{"Id":"ParamMarublue","Value":0,"Blend":"Add"},{"Id":"ParamMarushame","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression01","Value":1,"Blend":"Add"},{"Id":"ParamMaruexpression02","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression00","Value":-1,"Blend":"Add"},{"Id":"ParamMaruexpression03","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression04","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression05","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression06","Value":1,"Blend":"Add"},{"Id":"ParamMaruexpression07","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression08","Value":0,"Blend":"Add"},{"Id":"Param17","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression09","Value":0,"Blend":"Add"},{"Id":"ParamMarusign01","Value":0,"Blend":"Add"},{"Id":"ParamMarusign01_1","Value":0,"Blend":"Add"},{"Id":"ParamMarusign01_2","Value":0,"Blend":"Add"},{"Id":"ParamMarusign02","Value":0,"Blend":"Add"},{"Id":"ParamMarusign02_1","Value":0,"Blend":"Add"},{"Id":"ParamMarusign02_2","Value":0,"Blend":"Add"},{"Id":"ParamMarusign03","Value":0,"Blend":"Add"},{"Id":"ParamMarusign03_1","Value":0,"Blend":"Add"},{"Id":"ParamMarusign04","Value":0,"Blend":"Add"},{"Id":"ParamMarusign04_1","Value":0,"Blend":"Add"},{"Id":"ParamMarusign04_2","Value":0,"Blend":"Add"},{"Id":"ParamMarusign05","Value":0,"Blend":"Add"},{"Id":"ParamMarusign05_1","Value":0,"Blend":"Add"},{"Id":"ParamMarusign05_2","Value":0,"Blend":"Add"},{"Id":"ParamMarusign05_3","Value":0,"Blend":"Add"},{"Id":"ParamMarusign06","Value":0,"Blend":"Add"},{"Id":"ParamMarusign06_1","Value":0,"Blend":"Add"},{"Id":"ParamMarusign06_2","Value":0,"Blend":"Add"},{"Id":"ParamMarusign06_3","Value":0,"Blend":"Add"}]}
@@ -0,0 +1 @@
1
+ {"Type":"Expression","FadeInTime":0.5,"FadeOutTime":1,"Parameters":[{"Id":"ParamEyeLOpen","Value":0,"Blend":"Multiply"},{"Id":"ParamEyeLSmile","Value":0,"Blend":"Add"},{"Id":"ParamEyeROpen","Value":0,"Blend":"Multiply"},{"Id":"ParamEyeRSmile","Value":0,"Blend":"Add"},{"Id":"ParameyelidL","Value":0,"Blend":"Add"},{"Id":"ParameyelidR","Value":0,"Blend":"Add"},{"Id":"ParamEyeBallX","Value":0,"Blend":"Add"},{"Id":"ParamEyeBallY","Value":0,"Blend":"Add"},{"Id":"ParamEyeLScsle","Value":0,"Blend":"Add"},{"Id":"ParamEyeRScsle","Value":0,"Blend":"Add"},{"Id":"ParamEyeLScsle2","Value":0,"Blend":"Add"},{"Id":"ParamEyeRScsle2","Value":0,"Blend":"Add"},{"Id":"ParamEyeLHighlight","Value":0,"Blend":"Add"},{"Id":"ParamEyeRHighlight","Value":0,"Blend":"Add"},{"Id":"ParamTear","Value":0,"Blend":"Add"},{"Id":"ParamTear2","Value":0,"Blend":"Add"},{"Id":"ParamEyeSiwaON","Value":0,"Blend":"Add"},{"Id":"ParamTears1","Value":0,"Blend":"Add"},{"Id":"ParamTears2","Value":0,"Blend":"Add"},{"Id":"ParamTears3","Value":0,"Blend":"Add"},{"Id":"ParamTears0","Value":0,"Blend":"Add"},{"Id":"ParamguruguruLR","Value":0,"Blend":"Add"},{"Id":"ParamwakuwakuLR2","Value":0,"Blend":"Add"},{"Id":"ParamwakuwakuLR3","Value":0,"Blend":"Add"},{"Id":"ParamBrowLY","Value":-0.20000000298023224,"Blend":"Add"},{"Id":"ParamBrowLX","Value":0,"Blend":"Add"},{"Id":"ParamBrowLAngle","Value":0.1899999976158142,"Blend":"Add"},{"Id":"ParamBrowLForm","Value":-0.800000011920929,"Blend":"Add"},{"Id":"ParamBrowRY","Value":-0.1979999989271164,"Blend":"Add"},{"Id":"ParamBrowRX","Value":0,"Blend":"Add"},{"Id":"ParamBrowRAngle","Value":0.1940000057220459,"Blend":"Add"},{"Id":"ParamBrowRForm","Value":-0.800000011920929,"Blend":"Add"},{"Id":"Param_angry_eyebrows","Value":0,"Blend":"Add"},{"Id":"ParameyebrowsRON","Value":0,"Blend":"Add"},{"Id":"ParameyebrowsLON","Value":0,"Blend":"Add"},{"Id":"ParameyebrowscenterON","Value":0,"Blend":"Add"},{"Id":"ParameyebrowscenterPos","Value":0,"Blend":"Add"},{"Id":"Paramangry01","Value":0,"Blend":"Add"},{"Id":"Paramangry02","Value":0,"Blend":"Add"},{"Id":"Paramcry01sad01","Value":1,"Blend":"Add"},{"Id":"Paramblush","Value":0,"Blend":"Add"},{"Id":"Paramthinking01","Value":0,"Blend":"Add"},{"Id":"Paramanxiety01","Value":0,"Blend":"Add"},{"Id":"Parampanic","Value":0,"Blend":"Add"},{"Id":"Paramserious01","Value":0,"Blend":"Add"},{"Id":"Paramtired","Value":0,"Blend":"Add"},{"Id":"Paramwakuwaku","Value":0,"Blend":"Add"},{"Id":"Paramuturo","Value":0,"Blend":"Add"},{"Id":"Paramkime01","Value":0,"Blend":"Add"},{"Id":"Paramshock","Value":0,"Blend":"Add"},{"Id":"Paramzito","Value":0,"Blend":"Add"},{"Id":"Paramhutekusare","Value":0,"Blend":"Add"},{"Id":"Paramkegen","Value":0,"Blend":"Add"},{"Id":"Paramakire","Value":0,"Blend":"Add"},{"Id":"Paramcryangry","Value":0,"Blend":"Add"},{"Id":"Paramcryangry2","Value":0,"Blend":"Add"},{"Id":"Paramangry03","Value":0,"Blend":"Add"},{"Id":"Paramsad02","Value":1,"Blend":"Add"},{"Id":"Paramsmile04","Value":0,"Blend":"Add"},{"Id":"Paramblush2","Value":0,"Blend":"Add"},{"Id":"Paramwakuwaku01","Value":0,"Blend":"Add"},{"Id":"Paramwakuwaku02","Value":0,"Blend":"Add"},{"Id":"Paramguruguru","Value":0,"Blend":"Add"},{"Id":"Paramguruguru2","Value":0,"Blend":"Add"},{"Id":"Paramhitomi0","Value":0,"Blend":"Add"},{"Id":"ParameyeOFF","Value":1,"Blend":"Add"},{"Id":"ParamCheek","Value":0,"Blend":"Add"},{"Id":"ParamsweatON","Value":0,"Blend":"Add"},{"Id":"ParamsweatON3","Value":0,"Blend":"Add"},{"Id":"ParamsweatON2","Value":0,"Blend":"Add"},{"Id":"ParamAozameON","Value":0,"Blend":"Add"},{"Id":"ParamAozameON2","Value":0,"Blend":"Add"},{"Id":"exp_shadow01","Value":0,"Blend":"Add"},{"Id":"exp_cheekONOFF","Value":0,"Blend":"Add"},{"Id":"ParamNosePos","Value":0,"Blend":"Add"},{"Id":"Param7","Value":0,"Blend":"Add"},{"Id":"Param8","Value":0,"Blend":"Add"},{"Id":"Param16","Value":0,"Blend":"Add"},{"Id":"ParamEmo1","Value":0,"Blend":"Add"},{"Id":"ParamEmo2","Value":0,"Blend":"Add"},{"Id":"ParamEmo3","Value":0,"Blend":"Add"},{"Id":"ParamEmo4","Value":0,"Blend":"Add"},{"Id":"ParamMouthForm","Value":-1,"Blend":"Add"},{"Id":"ParamMouthOpenY","Value":0,"Blend":"Add"},{"Id":"ParamMouthside","Value":0,"Blend":"Add"},{"Id":"ParamMouthupdawn","Value":0,"Blend":"Add"},{"Id":"Param9","Value":1,"Blend":"Add"},{"Id":"ParamMouthStrength","Value":0,"Blend":"Add"},{"Id":"ParamMouthStrength2","Value":0,"Blend":"Add"},{"Id":"ParamTeethON","Value":-1,"Blend":"Add"},{"Id":"ParamMouthSiwaON","Value":0,"Blend":"Add"},{"Id":"ParamMouthSiwaON2","Value":0,"Blend":"Add"},{"Id":"ParamTear3","Value":0,"Blend":"Add"},{"Id":"ParamMaruMouthOpen","Value":0,"Blend":"Add"},{"Id":"ParamMarublue","Value":1,"Blend":"Add"},{"Id":"ParamMarushame","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression01","Value":1,"Blend":"Add"},{"Id":"ParamMaruexpression02","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression00","Value":-1,"Blend":"Add"},{"Id":"ParamMaruexpression03","Value":1,"Blend":"Add"},{"Id":"ParamMaruexpression04","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression05","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression06","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression07","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression08","Value":0,"Blend":"Add"},{"Id":"Param17","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression09","Value":0,"Blend":"Add"},{"Id":"ParamMarusign01","Value":0,"Blend":"Add"},{"Id":"ParamMarusign01_1","Value":0,"Blend":"Add"},{"Id":"ParamMarusign01_2","Value":0,"Blend":"Add"},{"Id":"ParamMarusign02","Value":1,"Blend":"Add"},{"Id":"ParamMarusign02_1","Value":0,"Blend":"Add"},{"Id":"ParamMarusign02_2","Value":0,"Blend":"Add"},{"Id":"ParamMarusign03","Value":0,"Blend":"Add"},{"Id":"ParamMarusign03_1","Value":0,"Blend":"Add"},{"Id":"ParamMarusign04","Value":0,"Blend":"Add"},{"Id":"ParamMarusign04_1","Value":0,"Blend":"Add"},{"Id":"ParamMarusign04_2","Value":0,"Blend":"Add"},{"Id":"ParamMarusign05","Value":0,"Blend":"Add"},{"Id":"ParamMarusign05_1","Value":0,"Blend":"Add"},{"Id":"ParamMarusign05_2","Value":0,"Blend":"Add"},{"Id":"ParamMarusign05_3","Value":0,"Blend":"Add"},{"Id":"ParamMarusign06","Value":0,"Blend":"Add"},{"Id":"ParamMarusign06_1","Value":0,"Blend":"Add"},{"Id":"ParamMarusign06_2","Value":0,"Blend":"Add"},{"Id":"ParamMarusign06_3","Value":0,"Blend":"Add"}]}
@@ -0,0 +1 @@
1
+ {"Type":"Expression","FadeInTime":0.5,"FadeOutTime":1,"Parameters":[{"Id":"ParamEyeLOpen","Value":1,"Blend":"Multiply"},{"Id":"ParamEyeLSmile","Value":0,"Blend":"Add"},{"Id":"ParamEyeROpen","Value":1,"Blend":"Multiply"},{"Id":"ParamEyeRSmile","Value":0,"Blend":"Add"},{"Id":"ParameyelidL","Value":0,"Blend":"Add"},{"Id":"ParameyelidR","Value":0,"Blend":"Add"},{"Id":"ParamEyeBallX","Value":0,"Blend":"Add"},{"Id":"ParamEyeBallY","Value":0,"Blend":"Add"},{"Id":"ParamEyeLScsle","Value":0,"Blend":"Add"},{"Id":"ParamEyeRScsle","Value":0,"Blend":"Add"},{"Id":"ParamEyeLScsle2","Value":0,"Blend":"Add"},{"Id":"ParamEyeRScsle2","Value":0,"Blend":"Add"},{"Id":"ParamEyeLHighlight","Value":0,"Blend":"Add"},{"Id":"ParamEyeRHighlight","Value":0,"Blend":"Add"},{"Id":"ParamTear","Value":0,"Blend":"Add"},{"Id":"ParamTear2","Value":0,"Blend":"Add"},{"Id":"ParamEyeSiwaON","Value":0,"Blend":"Add"},{"Id":"ParamTears1","Value":0,"Blend":"Add"},{"Id":"ParamTears2","Value":0,"Blend":"Add"},{"Id":"ParamTears3","Value":0,"Blend":"Add"},{"Id":"ParamTears0","Value":0,"Blend":"Add"},{"Id":"ParamguruguruLR","Value":0,"Blend":"Add"},{"Id":"ParamwakuwakuLR2","Value":0,"Blend":"Add"},{"Id":"ParamwakuwakuLR3","Value":0,"Blend":"Add"},{"Id":"ParamBrowLY","Value":0.23999999463558197,"Blend":"Add"},{"Id":"ParamBrowLX","Value":0,"Blend":"Add"},{"Id":"ParamBrowLAngle","Value":0.30000001192092896,"Blend":"Add"},{"Id":"ParamBrowLForm","Value":0,"Blend":"Add"},{"Id":"ParamBrowRY","Value":0.24400000274181366,"Blend":"Add"},{"Id":"ParamBrowRX","Value":0,"Blend":"Add"},{"Id":"ParamBrowRAngle","Value":0.30000001192092896,"Blend":"Add"},{"Id":"ParamBrowRForm","Value":0,"Blend":"Add"},{"Id":"Param_angry_eyebrows","Value":1,"Blend":"Add"},{"Id":"ParameyebrowsRON","Value":0,"Blend":"Add"},{"Id":"ParameyebrowsLON","Value":0,"Blend":"Add"},{"Id":"ParameyebrowscenterON","Value":0,"Blend":"Add"},{"Id":"ParameyebrowscenterPos","Value":0,"Blend":"Add"},{"Id":"Paramangry01","Value":0,"Blend":"Add"},{"Id":"Paramangry02","Value":0,"Blend":"Add"},{"Id":"Paramcry01sad01","Value":0,"Blend":"Add"},{"Id":"Paramblush","Value":0,"Blend":"Add"},{"Id":"Paramthinking01","Value":0,"Blend":"Add"},{"Id":"Paramanxiety01","Value":0,"Blend":"Add"},{"Id":"Parampanic","Value":0,"Blend":"Add"},{"Id":"Paramserious01","Value":1,"Blend":"Add"},{"Id":"Paramtired","Value":0,"Blend":"Add"},{"Id":"Paramwakuwaku","Value":0,"Blend":"Add"},{"Id":"Paramuturo","Value":0,"Blend":"Add"},{"Id":"Paramkime01","Value":0,"Blend":"Add"},{"Id":"Paramshock","Value":0,"Blend":"Add"},{"Id":"Paramzito","Value":0,"Blend":"Add"},{"Id":"Paramhutekusare","Value":0,"Blend":"Add"},{"Id":"Paramkegen","Value":0,"Blend":"Add"},{"Id":"Paramakire","Value":0,"Blend":"Add"},{"Id":"Paramcryangry","Value":0,"Blend":"Add"},{"Id":"Paramcryangry2","Value":0,"Blend":"Add"},{"Id":"Paramangry03","Value":0,"Blend":"Add"},{"Id":"Paramsad02","Value":0,"Blend":"Add"},{"Id":"Paramsmile04","Value":0,"Blend":"Add"},{"Id":"Paramblush2","Value":0,"Blend":"Add"},{"Id":"Paramwakuwaku01","Value":0,"Blend":"Add"},{"Id":"Paramwakuwaku02","Value":0,"Blend":"Add"},{"Id":"Paramguruguru","Value":0,"Blend":"Add"},{"Id":"Paramguruguru2","Value":0,"Blend":"Add"},{"Id":"Paramhitomi0","Value":0,"Blend":"Add"},{"Id":"ParameyeOFF","Value":0,"Blend":"Add"},{"Id":"ParamCheek","Value":0,"Blend":"Add"},{"Id":"ParamsweatON","Value":1,"Blend":"Add"},{"Id":"ParamsweatON3","Value":0,"Blend":"Add"},{"Id":"ParamsweatON2","Value":0,"Blend":"Add"},{"Id":"ParamAozameON","Value":0,"Blend":"Add"},{"Id":"ParamAozameON2","Value":0,"Blend":"Add"},{"Id":"exp_shadow01","Value":0,"Blend":"Add"},{"Id":"exp_cheekONOFF","Value":0,"Blend":"Add"},{"Id":"ParamNosePos","Value":0,"Blend":"Add"},{"Id":"Param7","Value":0,"Blend":"Add"},{"Id":"Param8","Value":0,"Blend":"Add"},{"Id":"Param16","Value":0,"Blend":"Add"},{"Id":"ParamEmo1","Value":0,"Blend":"Add"},{"Id":"ParamEmo2","Value":0.30000001192092896,"Blend":"Add"},{"Id":"ParamEmo3","Value":0,"Blend":"Add"},{"Id":"ParamEmo4","Value":0,"Blend":"Add"},{"Id":"ParamMouthForm","Value":0,"Blend":"Add"},{"Id":"ParamMouthOpenY","Value":0,"Blend":"Add"},{"Id":"ParamMouthside","Value":0,"Blend":"Add"},{"Id":"ParamMouthupdawn","Value":0,"Blend":"Add"},{"Id":"Param9","Value":0,"Blend":"Add"},{"Id":"ParamMouthStrength","Value":0,"Blend":"Add"},{"Id":"ParamMouthStrength2","Value":0,"Blend":"Add"},{"Id":"ParamTeethON","Value":-1,"Blend":"Add"},{"Id":"ParamMouthSiwaON","Value":0,"Blend":"Add"},{"Id":"ParamMouthSiwaON2","Value":0,"Blend":"Add"},{"Id":"ParamTear3","Value":0,"Blend":"Add"},{"Id":"ParamMaruMouthOpen","Value":0,"Blend":"Add"},{"Id":"ParamMarublue","Value":0,"Blend":"Add"},{"Id":"ParamMarushame","Value":1,"Blend":"Add"},{"Id":"ParamMaruexpression01","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression02","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression00","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression03","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression04","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression05","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression06","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression07","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression08","Value":0,"Blend":"Add"},{"Id":"Param17","Value":0,"Blend":"Add"},{"Id":"ParamMaruexpression09","Value":0,"Blend":"Add"},{"Id":"ParamMarusign01","Value":0,"Blend":"Add"},{"Id":"ParamMarusign01_1","Value":0,"Blend":"Add"},{"Id":"ParamMarusign01_2","Value":0,"Blend":"Add"},{"Id":"ParamMarusign02","Value":0,"Blend":"Add"},{"Id":"ParamMarusign02_1","Value":0,"Blend":"Add"},{"Id":"ParamMarusign02_2","Value":0,"Blend":"Add"},{"Id":"ParamMarusign03","Value":0,"Blend":"Add"},{"Id":"ParamMarusign03_1","Value":0,"Blend":"Add"},{"Id":"ParamMarusign04","Value":0,"Blend":"Add"},{"Id":"ParamMarusign04_1","Value":0,"Blend":"Add"},{"Id":"ParamMarusign04_2","Value":0,"Blend":"Add"},{"Id":"ParamMarusign05","Value":0,"Blend":"Add"},{"Id":"ParamMarusign05_1","Value":0,"Blend":"Add"},{"Id":"ParamMarusign05_2","Value":0,"Blend":"Add"},{"Id":"ParamMarusign05_3","Value":0,"Blend":"Add"},{"Id":"ParamMarusign06","Value":0,"Blend":"Add"},{"Id":"ParamMarusign06_1","Value":0,"Blend":"Add"},{"Id":"ParamMarusign06_2","Value":0,"Blend":"Add"},{"Id":"ParamMarusign06_3","Value":0,"Blend":"Add"}]}
@@ -716,6 +716,18 @@
716
716
  {
717
717
  "Name": "exp_pair_jitome_maru_sad.exp3",
718
718
  "File": "Expressions/exp_pair_jitome_maru_sad.exp3.json"
719
+ },
720
+ {
721
+ "Name": "exp_pair_anxiety_maru_sad.exp3",
722
+ "File": "Expressions/exp_pair_anxiety_maru_sad.exp3.json"
723
+ },
724
+ {
725
+ "Name": "exp_pair_sad3_maru_pale2.exp3",
726
+ "File": "Expressions/exp_pair_sad3_maru_pale2.exp3.json"
727
+ },
728
+ {
729
+ "Name": "exp_pair_serious2_maru_shy.exp3",
730
+ "File": "Expressions/exp_pair_serious2_maru_shy.exp3.json"
719
731
  }
720
732
  ]
721
733
  },
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/lib/balance.js ADDED
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Balance warnings: read the account's wallet balance and report the band it has fallen into.
3
+ *
4
+ * The balance lives in the DSH account service, which only a Host consumer can read — so this runs on the host and the result
5
+ * reaches the client through the pet's own state, the same way a phase does.
6
+ *
7
+ * WHY A "BAND" AND NOT AN EVENT
8
+ * -----------------------------
9
+ * The client polls about twice a second and cannot be trusted to see every reading. So the host publishes a VALUE — the lowest
10
+ * threshold the balance has reached — rather than an event the client might miss. A deeper band than last time is a warning;
11
+ * the same band is nothing. A missed poll therefore costs a poll's delay, not the warning.
12
+ *
13
+ * `lastBand` only ever DEEPENS while the balance stays readable, so a balance parked on ¥5.00 reports 5 once and then stays
14
+ * quiet, and one that drops from ¥6.00 straight to ¥3.50 reports 3 — not 5, 4 and 3 in succession, none of which the user can
15
+ * still act on.
16
+ *
17
+ * NOTHING IS INVENTED WHEN THE BALANCE IS UNAVAILABLE
18
+ * --------------------------------------------------
19
+ * Signed out, an abstract service with no provider, or a failed query all mean "no number", and all report `undefined` rather
20
+ * than 0 — a 0 would mean "empty" and fire the lowest band as if the wallet really were drained.
21
+ * @module dsh-pet-live2d-viola/balance
22
+ */
23
+
24
+ /**
25
+ * The bands that warn, in yuan, LOWEST first.
26
+ *
27
+ * Order matters: {@link bandOf} walks this list and returns the lowest band the balance falls into, which is what makes a
28
+ * multi-band drop produce one warning instead of three.
29
+ */
30
+ export const BALANCE_THRESHOLDS = [1, 2, 3, 4, 5];
31
+
32
+ /** How often to read the balance. Slow on purpose — a wallet does not move between two polls. */
33
+ export const BALANCE_POLL_MS = 60_000;
34
+
35
+ /**
36
+ * Sum every CNY wallet, main and bonus.
37
+ *
38
+ * The bonus wallet is real spending power, so leaving it out would warn about money the account can still spend. Only CNY is
39
+ * summed: a USD wallet in the same account is a different currency, and adding its number to a yuan threshold is meaningless.
40
+ *
41
+ * @param wallets - the recharge wallets, from `balance.value`.
42
+ * @param bonusWallets - the granted wallets, from `balance.bonusWallets`.
43
+ * @returns the total in yuan, or undefined when there is no readable CNY wallet.
44
+ */
45
+ export function totalCny(wallets, bonusWallets) {
46
+ const all = [...(wallets ?? []), ...(bonusWallets ?? [])].filter((w) => w?.currency === "CNY");
47
+ if (all.length === 0) return undefined;
48
+ let sum = 0;
49
+ for (const wallet of all) {
50
+ const value = Number(wallet.balance);
51
+ // A wallet whose number will not parse makes the TOTAL unknowable; reporting a partial sum could name the wrong band.
52
+ if (!Number.isFinite(value)) return undefined;
53
+ sum += value;
54
+ }
55
+ return sum;
56
+ }
57
+
58
+ /**
59
+ * The threshold a balance has most recently crossed DOWNWARD.
60
+ *
61
+ * The rule, settled by measurement rather than by reasoning about loop direction (three attempts got the direction wrong):
62
+ *
63
+ * - the answer is the SMALLEST threshold that is still >= the balance — ¥4.90 → 5, ¥3.50 → 4, ¥1.50 → 2
64
+ * - a balance above every threshold has crossed none, so the answer is undefined
65
+ * - a balance below every threshold has crossed all of them; the answer floors at the deepest one, 1
66
+ *
67
+ * @param balance - the balance in yuan.
68
+ * @returns the crossed threshold, or undefined when the balance is above every one.
69
+ */
70
+ export function bandOf(balance) {
71
+ if (typeof balance !== "number" || !Number.isFinite(balance)) return undefined;
72
+ // Above every threshold: no line has been crossed yet.
73
+ const highest = Math.max(...BALANCE_THRESHOLDS);
74
+ if (balance > highest) return undefined;
75
+ const above = BALANCE_THRESHOLDS.filter((threshold) => threshold >= balance);
76
+ if (above.length > 0) return Math.min(...above);
77
+ // Below every threshold: all of them have been crossed, and the deepest is the one worth naming.
78
+ return Math.min(...BALANCE_THRESHOLDS);
79
+ }
80
+
81
+ /**
82
+ * Tracks the balance across readings and exposes the band that should be warned about.
83
+ *
84
+ * A class rather than a closure so the state can be inspected in a test without reaching through an event emitter.
85
+ */
86
+ export class BalanceWatcher {
87
+ constructor() {
88
+ /** The most recent balance, or undefined when it could not be read. */
89
+ this.current = undefined;
90
+ /**
91
+ * The lowest band reported so far, or undefined when the balance is above every band.
92
+ *
93
+ * The whole protocol with the client: it warns when this is present and deeper than the band it last showed.
94
+ */
95
+ this.lastBand = undefined;
96
+ /** True once a balance has been read, so the FIRST reading can be treated differently. */
97
+ this.seeded = false;
98
+ }
99
+
100
+ /**
101
+ * Apply one reading.
102
+ *
103
+ * @param balance - the balance in yuan, or undefined when it could not be read.
104
+ * @returns the band now in force, or undefined.
105
+ */
106
+ update(balance) {
107
+ if (typeof balance !== "number" || !Number.isFinite(balance)) {
108
+ /*
109
+ * An unreadable balance CLEARS the remembered band rather than holding it.
110
+ *
111
+ * Otherwise a signed-out interval followed by a sign-in with the same balance would be judged against a stale band
112
+ * and stay silent — the one case where the user most needs to be told, because they just came back.
113
+ */
114
+ this.current = undefined;
115
+ this.lastBand = undefined;
116
+ this.seeded = false;
117
+ return undefined;
118
+ }
119
+ this.current = balance;
120
+ const band = bandOf(balance);
121
+ if (band === undefined) {
122
+ // Back above every band, so a later drop warns again.
123
+ this.lastBand = undefined;
124
+ this.seeded = true;
125
+ return undefined;
126
+ }
127
+ /*
128
+ * The FIRST reading only records the band.
129
+ *
130
+ * Warning on it would fire once per pet start for a balance that was already low when the session began, which reads as
131
+ * the pet noticing a change that did not happen. A drop DURING the session is what the warning is for.
132
+ */
133
+ if (!this.seeded) {
134
+ this.seeded = true;
135
+ this.lastBand = band;
136
+ return this.lastBand;
137
+ }
138
+ /*
139
+ * Only a DEEPER band replaces it; the same band, or a shallower one, is nothing to say.
140
+ *
141
+ * "Deeper" means a SMALLER number — the bands are yuan amounts, so 3 is deeper than 4.
142
+ */
143
+ if (this.lastBand !== undefined && band >= this.lastBand) return this.lastBand;
144
+ this.lastBand = band;
145
+ return this.lastBand;
146
+ }
147
+ }