Add More Placeholders for Customization
动机
当前模组的Responser和消息注入Formatter功能虽支持基础占位符 {pos},但缺乏动态信息(如时间、玩家状态等)。这限制了个性化回复的灵活性
描述
通过新增占位符,用户能更灵活地定制消息内容,减少手动输入重复信息的需求,提升自动化回复的实用性和趣味性。
如果可以,可以在系统中调用自定义的语言代码文件,并在占位符里面加入程序的输出。
例如
#include
...
printf("123");
...
建议的占位符举例 %systemTime% → 插入当前系统时间(如 14:30:45或带日期的 2025-10-10 14:30)。 %randomNum(min-max)% → 生成指定范围的随机数(如 %randomNum(1-100)%→ 42)。 %randomUnicode(min-max)% → 生成指定范围的Unicode编码字符(如 %randomUnicode(1000-10000)%→ \u4222或是䈢)。 %dimension% → 插入当前维度名称(如 主世界、下界)。 %playerHealth% → 插入玩家当前生命值(如 15.5❤️)。
其他信息
♥♥♥
我已经添加了除了randomUnicode以外的几个占位符,其中dimension在游戏内是没有本地化译名的,也就是说只能拿到minecraft:overworld 而不是 主世界。函数对照表
至于调用脚本,我说几点我的看法:
- 在 mod 内内嵌一个解释器(如Lua,Python等)并不现实,会使得 mod 的文件大小达到 MB 级别甚至几百 MB
- mod 直接未经审查地调用系统命令从各种角度看都不安全
- 我觉得,如果只是想要自定义函数(传参并拿到结果),走网络通信可能是最优解,后续我会添加一个可供网络通信的函数占位符,你可以在本地把你想要自定义的函数开放一个端口并做好路由(如
127.0.0.1:xxxxx/xxxxx)然后使用这个占位符去调用。
这些函数调用能不能在响应信息里面使用?
可以的
它会显示§6[Chat Tools] 试图自动响应失败:No group with name
这些更新还没发布呢,下一次版本更新就会有
okok👌
能不能把 时间戳 JSON 原文 都做进里面,可以放到网络里面去处理
okok
对了,by the way,你不必等到我发布新版本,如果你急着用,可以在 Actions 里下载工件,也可以顺带给我测测bug之类的(
彳亍
pattern:123mod(?正尖括号word反尖括号.*) message:{'http://localhost:8080/ {word}' | request} 会导致图片内的情况
是括号匹配的问题吧
引号不是这么用的 而且里面的word不用加大括号
{join("http://localhost:8080/",word) | request("GET")}
这个请求好像有点问题?
这个是我调试用的,它直接返回请求的路径

我输入下面这一条命令后
chattools给出了以下响应,说明它在非调试时访问的是此路径

但在实际响应中,回复的是这个
它可能和我服务器的健壮性有关,也可能访问的不是所看到的路径?
下面是我用curl命令运行的能够正常返回的命令

正常发出请求时的一段log `[09:32:07] [Render thread/INFO]: [System] [CHAT] admin悄悄地对你说:@间隔符k issue help命令无法正常显示
[09:32:07] [Render thread/INFO]: [ChatTools] Will respond within 50ms
[09:32:07] [Thread-138/INFO]: [ChatTools] Placeholder Engine Visiting "http://localhost:8080/admin/issue%20help命令无法正常显示" with method: GET
[09:32:07] [Thread-138/INFO]: [ChatTools] Respond to 反引号^(?
[09:32:07] [Render thread/INFO]: [System] [CHAT] Can't find player with this name!`
url编码请用encode_rfc3986(S),不要用replace(S,' ','%20')之类的。你先这样改改看看有没有效果
可以了🙏🙏
有两个以上消息同时接收到时不会做出响应
例如
P悄悄地对你说:123
正常返回
同时接收 ` P悄悄地对你说:123
B取得了进度[xxx] ` 不会按期返回
需要一个单独的issue吗
不用单独开issue 最近改了判断消息是不是由自己发出的方式,不知道是不是我改坏了,找时间我看看
这样能不能做一个关于原聊天json数据的函数占位符,交给网络处理
上一个commit加了呀 {unix_time_on_request} -> 创建响应请求时的 Unix 时间戳 {original_text_component} -> 接收到的文本组件 {original_text_raw} -> 接收到的文本字符串(未去除颜色代码) {original_text_string} -> 接收到的文本字符串(去除颜色代码) {object_data} -> 接收到的文本的对象数据
有没有那种能看到原json的占位符,比如click_action的
不太懂,object_data 和 original_text_component 都能看click_action吧
奥对,我刚用的sendtoclient,我看都没有extra,没事了
有两个以上消息同时接收到时不会做出响应
例如
P悄悄地对你说:123正常返回 同时接收 ` P悄悄地对你说:123B取得了进度[xxx] ` 不会按期返回
我知道了,你要把 最小等待时间 改成0(
我发现在游戏第一次调用Responder的网络功能时有概率堵塞线程(可能),造成游戏卡顿4-5秒,在之后的网络功能中不会出现此情况
复现不了( Responder应该会创建一个新线程才对,不会阻塞渲染进程的
出现了一个崩溃,貌似也无法复现,好像是小概率的?
日志
[23:35:05] [pool-15-thread-14/INFO]: [STDOUT]: World save took 0ms
[23:35:06] [Render thread/INFO]: [System] [CHAT] 回到上一个保存的地点 (Plot,5225,51,-6028)!
[23:35:10] [Render thread/INFO]: [System] [CHAT] 已设置飞行模式 Disabled ,被操作玩家 ? (Online).
[23:35:11] [Render thread/INFO]: [System] [CHAT] 已设置飞行模式 Enabled ,被操作玩家 ? (Online).
[23:35:11] [Render thread/INFO]: [System] [CHAT] 回到上一个保存的地点 (Plot,9974,55,-5033)!
[23:35:16] [Render thread/INFO]: Loaded 1093 advancements
[23:35:21] [Render thread/INFO]: Loaded 1093 advancements
[23:35:22] [pool-15-thread-16/INFO]: [STDOUT]: World save took 0ms
[23:35:30] [Render thread/WARN]: Ignoring player info update for unknown player ab617c5a-14bc-3d24-a00c-8e4c6c795ad0
[23:35:31] [ForkJoinPool.commonPool-worker-344/INFO]: [STDOUT]: Saving region 10,-12 to disk 隐私路径(Baritone模组世界cache储存)
[23:35:31] [pool-15-thread-5/INFO]: [STDOUT]: Saving region 19,-10 to disk 隐私路径(Baritone模组世界cache储存)
[23:35:31] [ForkJoinPool.commonPool-worker-344/INFO]: [STDOUT]: Saved region successfully
[23:35:31] [pool-15-thread-5/INFO]: [STDOUT]: Saved region successfully
[23:35:31] [pool-15-thread-5/INFO]: [STDOUT]: World save took 371ms
[23:35:51] [pool-15-thread-19/INFO]: [STDOUT]: World save took 0ms
[23:36:44] [pool-15-thread-39/INFO]: [STDOUT]: World save took 0ms
[23:36:49] [pool-15-thread-185/INFO]: [STDOUT]: World save took 0ms
[23:37:22] [pool-15-thread-163/INFO]: [STDOUT]: World save took 0ms
[23:37:40] [Render thread/INFO]: [System] [CHAT] 金钱: 2,512,100.21
[23:37:40] [Render thread/INFO]: [ChatTools] Will respond within 50ms
[23:37:40] [Thread-3451/INFO]: [ChatTools] Placeholder Engine Visiting "http://localhost:8081/api/bal/set/2,512,100.21" with
method: GET
[23:37:40] [Thread-3451/INFO]: [ChatTools] Respond to `^金钱: (?<value>.*?)$`, with message `/chattools send_to_client text "§7[§d§7] §e余额已设置为 2512100.21"`
[23:37:40] [Thread-3451/INFO]: [System] [CHAT] §7[§d§7] §e余额已设置为 2512100.21
[23:37:41] [Render thread/INFO]: [ChatLog.serialize] Saved the chat log containing 1229 messages and 142 sent messages to '隐私路径(\logs\chatlog.json)'
[23:37:42] [Render thread/ERROR]: Unreported exception thrown!
java.util.ConcurrentModificationException: null
at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:970) ~[?:?]
at java.util.LinkedList$ListItr.next(LinkedList.java:892) ~[?:?]
at java.util.Collection.removeIf(Collection.java:576) ~[?:?]
at net.minecraft.class_338.handler$ehi000$meteor-client$onAddMessage(class_338.java:2627) ~[client-intermediary.jar:?]
at net.minecraft.class_338.method_1815(class_338.java) ~[client-intermediary.jar:?]
at net.minecraft.class_338.method_44813(class_338.java:307) ~[client-intermediary.jar:?]
at net.minecraft.class_338.method_1817(class_338.java:300) ~[client-intermediary.jar:?]
at net.minecraft.class_408.cps$onSearchFieldUpdate(class_408.java:5245) ~[client-intermediary.jar:?]
at net.minecraft.class_342.method_1874(class_342.java:149) ~[client-intermediary.jar:?]
at net.minecraft.class_342.method_1883(class_342.java:255) ~[client-intermediary.jar:?]
at net.minecraft.class_342.method_1872(class_342.java:267) ~[client-intermediary.jar:?]
at net.minecraft.class_342.method_1852(class_342.java:103) ~[client-intermediary.jar:?]
at net.minecraft.class_408.handler$cdg000$chatpatches$cps$initSearchStuff(class_408.java:4668) ~[client-intermediary.jar:?]
at net.minecraft.class_408.method_25426(class_408.java:60) ~[client-intermediary.jar:?]
at net.minecraft.class_437.method_25423(class_437.java:427) ~[client-intermediary.jar:?]
at net.minecraft.class_310.method_1507(class_310.java:1079) ~[client-intermediary.jar:?]
at net.minecraft.class_310.method_29041(class_310.java:1041) ~[client-intermediary.jar:?]
at net.minecraft.class_310.method_1508(class_310.java:2030) ~[client-intermediary.jar:?]
at net.minecraft.class_310.method_1574(class_310.java:1880) ~[client-intermediary.jar:?]
at net.minecraft.class_310.method_1523(class_310.java:1180) ~[client-intermediary.jar:?]
at net.minecraft.class_310.method_1514(class_310.java:801) ~[client-intermediary.jar:?]
at net.minecraft.client.main.Main.main(Main.java:237) ~[1.19.4-Fabric%200.15.7.jar:?]
at net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:470) ~[fabric-loader-0.15.7.jar:?]
at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:74) ~[fabric-loader-0.15.7.jar:?]
at net.fabricmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:23) ~[fabric-loader-0.15.7.jar:?]
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[?:?]
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
at java.lang.reflect.Method.invoke(Method.java:568) ~[?:?]
at oolloo.jlw.Wrapper.invokeMain(Wrapper.java:112) ~[?:?]
at oolloo.jlw.Wrapper.main(Wrapper.java:105) ~[?:?]
[23:37:46] [Render thread/INFO]: [voicechat] Clearing audio channels
[23:37:46] [Render thread/INFO]: Saving
[23:37:47] [Render thread/INFO]: Saved in 236 milliseconds.
[23:37:47] [Render thread/INFO]: Xaero hud session finalized.
[23:37:47] [Render thread/INFO]: Finalizing world map session...
[23:37:47] [Thread-20/INFO]: World map force-cleaned!
[23:37:47] [Render thread/INFO]: World map session finalized.
[23:37:47] [Render thread/INFO]: Stopping JEI
[23:37:47] [Render thread/INFO]: Stopping JEI
[23:37:47] [Render thread/INFO]: Sending Runtime Unavailable...
[23:37:47] [Render thread/INFO]: Stopping JEI GUI
[23:37:47] [Render thread/INFO]: Sending Runtime Unavailable took 1.676 ms
[23:37:48] [Render thread/INFO]: ARRP register - before user
[23:37:48] [Render thread/INFO]: Found non-pack entry '隐私路径(aspx资源文件)', ignoring
[23:37:48] [Render thread/INFO]: Reloading ResourceManager: 模组列表), file/!!§l 资源包列表
[23:37:48] [Render thread/INFO]: closing rrp ebe:base_resources
[23:37:48] [Render thread/INFO]: ARRP register - before vanilla
[23:37:48] [Render thread/INFO]: ARRP register - after vanilla
[23:37:48] [Render thread/INFO]: [System] [CHAT] §7==== 储存的聊天记录 ====§r
[23:37:48] [Worker-Main-603/ERROR]: Invalid path in mod resource-pack xibaopp: xibaopp:sounds/README.md, ignoring
[23:37:48] [Render thread/INFO]: Stopping worker threads
[23:37:52] [Render thread/INFO]: [FastQuit] Exiting FastQuit.
或者可能是其他模组导致的崩溃?或者可以尝试使用线程安全集合
日志
报告文件部分信息:
java.util.ConcurrentModificationException
at java.base/java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:970)
at java.base/java.util.LinkedList$ListItr.next(LinkedList.java:892)
at java.base/java.util.Collection.removeIf(Collection.java:576)
at net.minecraft.class_338.handler$ehi000$meteor-client$onAddMessage(class_338.java:2627)
at net.minecraft.class_338.method_1815(class_338.java)
at net.minecraft.class_338.method_44813(class_338.java:307)
at net.minecraft.class_338.method_1817(class_338.java:300)
at net.minecraft.class_408.cps$onSearchFieldUpdate(class_408.java:5245)
at net.minecraft.class_342.method_1874(class_342.java:149)
at net.minecraft.class_342.method_1883(class_342.java:255)
at net.minecraft.class_342.method_1872(class_342.java:267)
at net.minecraft.class_342.method_1852(class_342.java:103)
at net.minecraft.class_408.handler$cdg000$chatpatches$cps$initSearchStuff(class_408.java:4668)
at net.minecraft.class_408.method_25426(class_408.java:60)
at net.minecraft.class_437.method_25423(class_437.java:427)
at net.minecraft.class_310.method_1507(class_310.java:1079)
at net.minecraft.class_310.method_29041(class_310.java:1041)
at net.minecraft.class_310.method_1508(class_310.java:2030)
at net.minecraft.class_310.method_1574(class_310.java:1880)
at net.minecraft.class_310.method_1523(class_310.java:1180)
at net.minecraft.class_310.method_1514(class_310.java:801)
at net.minecraft.client.main.Main.main(Main.java:237)
at net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:470)
at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:74)
at net.fabricmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:23)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at oolloo.jlw.Wrapper.invokeMain(Wrapper.java:112)
at oolloo.jlw.Wrapper.main(Wrapper.java:105)
A detailed walkthrough of the error, its code path and all known details is as follows:
Head
Thread: Render thread
Stacktrace:
at java.base/java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:970)
at java.base/java.util.LinkedList$ListItr.next(LinkedList.java:892)
at java.base/java.util.Collection.removeIf(Collection.java:576)
at net.minecraft.class_338.handler$ehi000$meteor-client$onAddMessage(class_338.java:2627)
at net.minecraft.class_338.method_1815(class_338.java)
at net.minecraft.class_338.method_44813(class_338.java:307)
at net.minecraft.class_338.method_1817(class_338.java:300)
at net.minecraft.class_408.cps$onSearchFieldUpdate(class_408.java:5245)
at net.minecraft.class_342.method_1874(class_342.java:149)
at net.minecraft.class_342.method_1883(class_342.java:255)
at net.minecraft.class_342.method_1872(class_342.java:267)
at net.minecraft.class_342.method_1852(class_342.java:103)
at net.minecraft.class_408.handler$cdg000$chatpatches$cps$initSearchStuff(class_408.java:4668)
at net.minecraft.class_408.method_25426(class_408.java:60)
at net.minecraft.class_437.method_25423(class_437.java:427)
at net.minecraft.class_310.method_1507(class_310.java:1079)
at net.minecraft.class_310.method_29041(class_310.java:1041)
at net.minecraft.class_310.method_1508(class_310.java:2030)
Affected level
Details:
All players: 1 total; [class_746['KFCweek4'/1859593, l='ClientLevel', x=9973.66, y=74.00, z=-5027.65]]
Chunk stats: 1024, 109
Level dimension: minecraft:plot
Level spawn location: World: (22,51,28), Section: (at 6,3,12 in 1,3,1; chunk contains blocks 16,-64,16 to 31,319,31), Region:
(0,0; contains chunks 0,0 to 31,31, blocks 0,-64,0 to 511,319,511)
Level time: 1842070959 game time, 1837939902 day time
Server brand: Waterfall <- Purpur
Server type: Non-integrated multiplayer server
Stacktrace:
at net.minecraft.class_638.method_8538(class_638.java:455)
at net.minecraft.class_310.method_1587(class_310.java:2406)
at net.minecraft.class_310.method_1514(class_310.java:825)
at net.minecraft.client.main.Main.main(Main.java:237)
at net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:470)
at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:74)
at net.fabricmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:23)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at oolloo.jlw.Wrapper.invokeMain(Wrapper.java:112)
at oolloo.jlw.Wrapper.main(Wrapper.java:105)
此外日志里错误堆栈更浅层也提到了Chat Patches,也可以去向他们报告
装上chattools之后疑似收到服务器来的大聊天数据包后会被客户端强制阻断(我下载的不是最新版本,但是应该不会影响结果)