Skip to content

Commit eb544ec

Browse files
committed
docs: 06-mixin-script
1 parent 154a2bc commit eb544ec

File tree

5 files changed

+163
-3
lines changed

5 files changed

+163
-3
lines changed

.vitepress/config.mts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export default defineConfig({
2323
{ text: "运行原理", link: "/guide/03-how-it-works.md" },
2424
{ text: "插件系统", link: "/guide/04-plugins.md" },
2525
{ text: "计划任务系统", link: "/guide/05-tasks.md" },
26+
{ text: "混入与脚本", link: "/guide/06-mixin-script.md" },
2627
{ text: "使用技巧", link: "/guide/08-skills.md" },
2728
],
2829
},

guide/04-plugins.md

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
## 插件系统能够做什么?
88

9-
- 修改你的 APP 主题、语言,管理你的配置、订阅、规则组、内核。
9+
- 修改你的 APP 主题、语言,管理你的配置、订阅、规则集、内核。
1010

1111
- 对生成的配置进行修改、对订阅的结果进行修改。
1212

@@ -44,7 +44,7 @@
4444
- 1 运行中,推荐 onRun 方法中作为返回值
4545
- 2 已停止,推荐自定义菜单 Stop 方法中作为返回值
4646

47-
以下是一个示例
47+
以下是一个示例,包含了所有的钩子方法。
4848

4949
```javascript
5050
/**
@@ -63,6 +63,14 @@ const Stop = async () => {
6363
return 2; // 表示已经停止运行
6464
};
6565

66+
/**
67+
* 自定义菜单项:运行 - Start
68+
*/
69+
const Start = async () => {
70+
await StartMyProgram();
71+
return 1; // 表示插件正在运行中
72+
};
73+
6674
/**
6775
* 插件钩子:安装按钮 - onInstall
6876
*/
@@ -78,6 +86,45 @@ const onUninstall = async () => {
7886
await UninstallMyProgram();
7987
return 0; // 表示初始状态
8088
};
89+
90+
/**
91+
* 插件钩子:更新订阅时
92+
*/
93+
const onSubscribe = async (proxies, subscription) => {
94+
return proxies;
95+
};
96+
97+
/**
98+
* 插件钩子:生成配置时
99+
*/
100+
const onGenerate = async (config, profile) => {
101+
return config;
102+
};
103+
104+
/**
105+
* 插件钩子:启动APP时
106+
*/
107+
const onStartup = async () => {};
108+
109+
/**
110+
* 插件钩子:关闭APP时
111+
*/
112+
const onShutdown = async () => {};
113+
114+
/**
115+
* 插件钩子:APP就绪后
116+
*/
117+
const onReady = async () => {};
118+
119+
/**
120+
* 插件钩子:计划任务执行时
121+
*/
122+
const onTask = async () => {};
123+
124+
/**
125+
* 插件钩子:配置插件时
126+
*/
127+
const onConfigure = async (config, old) => {};
81128
```
82129

83130
## 插件编写规范
@@ -240,7 +287,7 @@ scheduledTasksStore.addScheduledTask(s: ScheduledTaskType)
240287

241288
![](/guide/resources/105_plugin_hub.png)
242289

243-
从插件中心添加的插件不建议修改元数据,也就是插件卡片右上角的【编辑】按钮,因为发布到插件中心的插件都是调试好的,该有哪些触发器就有哪些触发器,该有哪些菜单以及配置项也都是设计好的,有些会用户随意编辑这些插件,比如添加了源码里没有实现的触发器,就会导致插件执行失败。
290+
从插件中心添加的插件不建议修改元数据,也就是插件卡片右上角的【~~编辑~~】按钮(已改为`【开发】`),因为发布到插件中心的插件都是调试好的,该有哪些触发器就有哪些触发器,该有哪些菜单以及配置项也都是设计好的,有些会用户随意编辑这些插件,比如添加了源码里没有实现的触发器,就会导致插件执行失败。
244291

245292
那么为什么不限制编辑按钮呢?因为我们想把最大的权限交给用户,毕竟有些有想法的用户想对已有插件进行扩展,增加自己想要的功能,GUI 不会限制这部分用户。
246293

guide/06-mixin-script.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# 混入与脚本
2+
3+
在引入`混入``脚本`之前,类似的操作可以通过插件完成,实现方式是创建一个具有`生成配置时`的触发器,对生成的配置进行个性化修改,但这样做有一些不便:
4+
5+
- 1、作用于所有配置,如果仅修改部分配置则需要使用`if`来判断;
6+
7+
- 2、必须编写`JavaScript`代码来处理,对没有编程经验的人不友好;
8+
9+
`混入``脚本`解决了以上两个问题,它们和配置强绑定,仅作用于自身,既不会影响全部配置、也不需要编写`if``JavaScript`代码。
10+
11+
## 混入 - Mixin
12+
13+
混入的原理是使用`用户提供的配置``GUI生成的配置`进行合并处理,如果两个配置存在冲突,则可以使用`优先级`来指定最终的配置以哪一个为准。
14+
15+
![](/guide/resources/601_mixin.png)
16+
17+
示例:
18+
19+
1、GUI.for.Clash 示例,YAML 格式
20+
21+
```yaml
22+
mode: global
23+
ipv6: true
24+
mixed-port: 7890
25+
tun:
26+
enable: true
27+
stack: gVisor
28+
dns-hijack:
29+
- any:53
30+
dns:
31+
enable: true
32+
ipv6: true
33+
default-nameserver:
34+
- 223.5.5.5
35+
- 114.114.114.114
36+
```
37+
38+
2、GUI.for.SingBox 示例,JSON 格式
39+
40+
```json
41+
{
42+
"log": {
43+
"timestamp": false
44+
},
45+
"experimental": {
46+
"clash_api": {
47+
"external_controller": "127.0.0.1:20123",
48+
"default_mode": "global"
49+
},
50+
"cache_file": {
51+
"enabled": true,
52+
"store_fakeip": true
53+
}
54+
}
55+
}
56+
```
57+
58+
注意事项:混入操作不支持`数组合并`,只会取`用户提供的配置``GUI生成的配置`其一。如果想对数组进行操作,只能使用`脚本`
59+
60+
## 脚本 - `Script`
61+
62+
脚本的实现原理和插件的`onGenerate`钩子相同,GUI 会把`GUI生成的配置`通过参数`config`传入`onGenerate`方法,用户对`config`进行修改,然后返回最终的配置。
63+
64+
![](/guide/resources/602_script.png)
65+
66+
示例:
67+
68+
1、GUI.for.Clash 示例
69+
70+
```javascript
71+
const onGenerate = async (config) => {
72+
config.dns["default-nameserver"].unshift("223.5.5.5");
73+
config.dns["default-nameserver"].unshift("114.114.114.114");
74+
config.sniffer = {
75+
enable: false,
76+
"force-dns-mapping": true,
77+
"parse-pure-ip": true,
78+
"override-destination": false,
79+
sniff: {
80+
HTTP: {
81+
ports: [80, "8080-8880"],
82+
"override-destination": true,
83+
},
84+
TLS: {
85+
ports: [443, 8443],
86+
},
87+
QUIC: {
88+
ports: [443, 8443],
89+
},
90+
},
91+
"force-domain": ["+.v2ex.com"],
92+
"skip-domain": ["Mijia Cloud"],
93+
};
94+
return config;
95+
};
96+
```
97+
98+
2、GUI.for.SingBox 示例
99+
100+
```javascript
101+
const onGenerate = async (config) => {
102+
config.log.timestamp = false;
103+
config.experimental.clash_api.default_mode = "global";
104+
config.dns.servers.unshift({
105+
tag: "remote-dns-google",
106+
address: "tls://8.8.4.4",
107+
address_resolver: "remote-resolver-dns",
108+
detour: "🚀 Select",
109+
});
110+
return config;
111+
};
112+
```

guide/resources/601_mixin.png

59.7 KB
Loading

guide/resources/602_script.png

58.3 KB
Loading

0 commit comments

Comments
 (0)