mirror of
https://github.com/nitezs/sub2clash.git
synced 2024-12-24 11:14:41 -05:00
fix
This commit is contained in:
parent
2339b7d256
commit
429788a19f
@ -8,12 +8,12 @@
|
|||||||
| proxy | string | sub/proxy 至少有一项存在 | - | 节点分享链接(可以输入多个,用 `,` 分隔) |
|
| proxy | string | sub/proxy 至少有一项存在 | - | 节点分享链接(可以输入多个,用 `,` 分隔) |
|
||||||
| refresh | bool | 否 | `false` | 强制刷新配置(默认缓存 5 分钟) |
|
| refresh | bool | 否 | `false` | 强制刷新配置(默认缓存 5 分钟) |
|
||||||
| template | string | 否 | - | 外部模板链接或内部模板名称 |
|
| template | string | 否 | - | 外部模板链接或内部模板名称 |
|
||||||
| ruleProvider | string | 否 | - | 格式 `[Behavior,Url,Group,Prepend,Name],[Behavior,Url,Group,Prepend,Name]...`,其中 `Group` 是该规则集所走的策略组名,`Prepend` 为 bool 类型,如果为 `true` 规则将被添加到规则列表顶部,否则添加到规则列表底部(会调整到MATCH规则之前) |
|
| ruleProvider | string | 否 | - | 格式 `[Behavior,Url,Group,Prepend,Name],[Behavior,Url,Group,Prepend,Name]...`,其中 `Group` 是该规则集使用的策略组名,`Prepend` 为 bool 类型,如果为 `true` 规则将被添加到规则列表顶部,否则添加到规则列表底部(会调整到MATCH规则之前) |
|
||||||
| rule | string | 否 | - | 格式 `[Rule,Prepend],[Rule,Prepend]...`,其中 `Prepend` 为 bool 类型,如果为 `true` 规则将被添加到规则列表顶部,否则添加到规则列表底部(会调整到MATCH规则之前) |
|
| rule | string | 否 | - | 格式 `[Rule,Prepend],[Rule,Prepend]...`,其中 `Prepend` 为 bool 类型,如果为 `true` 规则将被添加到规则列表顶部,否则添加到规则列表底部(会调整到MATCH规则之前) |
|
||||||
| autoTest | bool | 否 | `false` | 国家策略组是否自动测速 |
|
| autoTest | bool | 否 | `false` | 国家策略组是否自动测速 |
|
||||||
| lazy | bool | 否 | `false` | 自动测速是否启用 lazy |
|
| lazy | bool | 否 | `false` | 自动测速是否启用 lazy |
|
||||||
| sort | string | 否 | `nameasc` | 国家策略组排序策略,可选值 `nameasc`、`namedesc`、`sizeasc`、`sizedesc` |
|
| sort | string | 否 | `nameasc` | 国家策略组排序策略,可选值 `nameasc`、`namedesc`、`sizeasc`、`sizedesc` |
|
||||||
| replace | string | 否 | - | 通过正则表达式重命名节点,格式 `[ReplaceKey,ReplaceTo]` |
|
| replace | string | 否 | - | 通过正则表达式重命名节点,格式 `[<ReplaceKey>,<ReplaceTo>],[<ReplaceKey>,<ReplaceTo>]...` |
|
||||||
| remove | string | 否 | - | 通过正则表达式删除节点 |
|
| remove | string | 否 | - | 通过正则表达式删除节点 |
|
||||||
|
|
||||||
# `/short`
|
# `/short`
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
### 模板
|
### 模板
|
||||||
|
|
||||||
可以通过变脸自定义模板中的策略组代理节点
|
可以通过变量自定义模板中的策略组代理节点
|
||||||
解释的不太清楚,可以参考下方默认模板
|
解释的不太清楚,可以参考下方默认模板
|
||||||
|
|
||||||
- `<all>` 为添加所有节点
|
- `<all>` 为添加所有节点
|
||||||
|
@ -89,6 +89,10 @@ func BuildSub(clashType model.ClashType, query validator.SubValidator, template
|
|||||||
proxyList = append(proxyList, sub.Proxies...)
|
proxyList = append(proxyList, sub.Proxies...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 添加自定义节点
|
||||||
|
if len(query.Proxies) != 0 {
|
||||||
|
proxyList = append(proxyList, utils.ParseProxy(query.Proxies...)...)
|
||||||
|
}
|
||||||
// 去重
|
// 去重
|
||||||
proxies := make(map[string]*model.Proxy)
|
proxies := make(map[string]*model.Proxy)
|
||||||
for i := range proxyList {
|
for i := range proxyList {
|
||||||
@ -105,38 +109,57 @@ func BuildSub(clashType model.ClashType, query validator.SubValidator, template
|
|||||||
}
|
}
|
||||||
names[proxyList[i].Name] = true
|
names[proxyList[i].Name] = true
|
||||||
}
|
}
|
||||||
// 删除节点、改名
|
// 删除节点
|
||||||
if strings.TrimSpace(query.Remove) != "" {
|
if strings.TrimSpace(query.Remove) != "" {
|
||||||
|
newProxyList := make([]model.Proxy, 0, len(proxyList))
|
||||||
|
for i := range proxyList {
|
||||||
removeReg, err := regexp.Compile(query.Remove)
|
removeReg, err := regexp.Compile(query.Remove)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Logger.Debug("remove regexp compile failed", zap.Error(err))
|
logger.Logger.Debug("remove regexp compile failed", zap.Error(err))
|
||||||
return nil, errors.New("remove 参数非法: " + err.Error())
|
return nil, errors.New("remove 参数非法: " + err.Error())
|
||||||
}
|
}
|
||||||
replaceReg, err := regexp.Compile(query.ReplaceKey)
|
// 删除匹配到的节点
|
||||||
if err != nil {
|
|
||||||
logger.Logger.Debug("replace regexp compile failed", zap.Error(err))
|
|
||||||
return nil, errors.New("replaceName 参数非法: " + err.Error())
|
|
||||||
}
|
|
||||||
newProxyList := make([]model.Proxy, 0, len(proxyList))
|
|
||||||
for i := range proxyList {
|
|
||||||
if removeReg.MatchString(proxyList[i].Name) {
|
if removeReg.MatchString(proxyList[i].Name) {
|
||||||
continue // 如果匹配到要删除的元素,跳过该元素,不添加到新切片中
|
continue // 如果匹配到要删除的元素,跳过该元素,不添加到新切片中
|
||||||
}
|
}
|
||||||
if replaceReg.MatchString(proxyList[i].Name) {
|
|
||||||
proxyList[i].Name = replaceReg.ReplaceAllString(proxyList[i].Name, query.ReplaceTo)
|
|
||||||
}
|
|
||||||
newProxyList = append(newProxyList, proxyList[i]) // 将要保留的元素添加到新切片中
|
newProxyList = append(newProxyList, proxyList[i]) // 将要保留的元素添加到新切片中
|
||||||
}
|
}
|
||||||
proxyList = newProxyList
|
proxyList = newProxyList
|
||||||
}
|
}
|
||||||
|
// 重命名
|
||||||
|
if len(query.ReplaceKeys) != 0 {
|
||||||
|
// 创建重命名正则表达式
|
||||||
|
replaceRegs := make([]*regexp.Regexp, 0, len(query.ReplaceKeys))
|
||||||
|
for _, v := range query.ReplaceKeys {
|
||||||
|
replaceReg, err := regexp.Compile(v)
|
||||||
|
if err != nil {
|
||||||
|
logger.Logger.Debug("replace regexp compile failed", zap.Error(err))
|
||||||
|
return nil, errors.New("replace 参数非法: " + err.Error())
|
||||||
|
}
|
||||||
|
replaceRegs = append(replaceRegs, replaceReg)
|
||||||
|
}
|
||||||
|
for i := range proxyList {
|
||||||
|
// 重命名匹配到的节点
|
||||||
|
for j, v := range replaceRegs {
|
||||||
|
if err != nil {
|
||||||
|
logger.Logger.Debug("replace regexp compile failed", zap.Error(err))
|
||||||
|
return nil, errors.New("replaceName 参数非法: " + err.Error())
|
||||||
|
}
|
||||||
|
if v.MatchString(proxyList[i].Name) {
|
||||||
|
proxyList[i].Name = v.ReplaceAllString(
|
||||||
|
proxyList[i].Name, query.ReplaceTo[j],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// trim
|
||||||
|
for i := range proxyList {
|
||||||
|
proxyList[i].Name = strings.TrimSpace(proxyList[i].Name)
|
||||||
|
}
|
||||||
// 将新增节点都添加到临时变量 t 中,防止策略组排序错乱
|
// 将新增节点都添加到临时变量 t 中,防止策略组排序错乱
|
||||||
var t = &model.Subscription{}
|
var t = &model.Subscription{}
|
||||||
utils.AddProxy(t, query.AutoTest, query.Lazy, clashType, proxyList...)
|
utils.AddProxy(t, query.AutoTest, query.Lazy, clashType, proxyList...)
|
||||||
// 处理自定义代理
|
|
||||||
utils.AddProxy(
|
|
||||||
t, query.AutoTest, query.Lazy, clashType,
|
|
||||||
utils.ParseProxy(query.Proxies...)...,
|
|
||||||
)
|
|
||||||
// 排序策略组
|
// 排序策略组
|
||||||
switch query.Sort {
|
switch query.Sort {
|
||||||
case "sizeasc":
|
case "sizeasc":
|
||||||
|
@ -182,24 +182,15 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Rename -->
|
<!-- Rename -->
|
||||||
<div class="form-group mb-3">
|
<div class="form-group mb-3" id="replaceGroup">
|
||||||
<label for="replaceKey">替换节点名称:</label>
|
<label>节点名称替换:</label>
|
||||||
<div class="input-group mb-2">
|
<button
|
||||||
<input
|
class="btn btn-primary mb-1 btn-xs"
|
||||||
class="form-control"
|
onclick="addReplace()"
|
||||||
type="text"
|
type="button"
|
||||||
name="replace"
|
>
|
||||||
id="replaceKey"
|
+
|
||||||
placeholder="原字符串(正则表达式)"
|
</button>
|
||||||
/>
|
|
||||||
<input
|
|
||||||
class="form-control"
|
|
||||||
type="text"
|
|
||||||
name="replace"
|
|
||||||
id="replaceTo"
|
|
||||||
placeholder="替换为"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
@ -285,6 +276,17 @@
|
|||||||
return div;
|
return div;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createReplace() {
|
||||||
|
const div = document.createElement("div");
|
||||||
|
div.classList.add("input-group", "mb-2");
|
||||||
|
div.innerHTML = `
|
||||||
|
<input type="text" class="form-control" name="replace" placeholder="原字符串(正则表达式)">
|
||||||
|
<input type="text" class="form-control" name="replace" placeholder="替换为(可为空)">
|
||||||
|
<button type="button" class="btn btn-danger" onclick="removeElement(this)">删除</button>
|
||||||
|
`;
|
||||||
|
return div;
|
||||||
|
}
|
||||||
|
|
||||||
function createRule() {
|
function createRule() {
|
||||||
const div = document.createElement("div");
|
const div = document.createElement("div");
|
||||||
div.classList.add("input-group", "mb-2");
|
div.classList.add("input-group", "mb-2");
|
||||||
@ -307,6 +309,11 @@
|
|||||||
document.getElementById("ruleGroup").appendChild(div);
|
document.getElementById("ruleGroup").appendChild(div);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addReplace() {
|
||||||
|
const div = createReplace();
|
||||||
|
document.getElementById("replaceGroup").appendChild(div);
|
||||||
|
}
|
||||||
|
|
||||||
function removeElement(button) {
|
function removeElement(button) {
|
||||||
button.parentElement.remove();
|
button.parentElement.remove();
|
||||||
}
|
}
|
||||||
@ -429,15 +436,20 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取替换节点名称的正则表达式
|
// 获取替换节点名称的正则表达式
|
||||||
const replaceKey = document.getElementById("replaceKey").value;
|
let replaceList = [];
|
||||||
const replaceTo = document.getElementById("replaceTo").value;
|
const replaces = document.getElementsByName("replace");
|
||||||
if (replaceKey.trim() !== "" && replaceTo.trim() !== "") {
|
for (let i = 0; i < replaces.length / 2; i++) {
|
||||||
queryParams.push(
|
let replaceStr = `<${replaces[i * 2].value}>`;
|
||||||
`replace=[${encodeURIComponent(replaceKey)},${encodeURIComponent(
|
let replaceTo = `<${replaces[i * 2 + 1].value}>`;
|
||||||
replaceTo,
|
if (replaceStr.trim() === "") {
|
||||||
)}]`,
|
alert("重命名设置中存在空值,请检查后重试!");
|
||||||
);
|
return "";
|
||||||
}
|
}
|
||||||
|
replaceList.push(`[${replaceStr},${replaceTo}]`);
|
||||||
|
}
|
||||||
|
queryParams.push(
|
||||||
|
`replace=${encodeURIComponent(replaceList.join(","))}`,
|
||||||
|
);
|
||||||
|
|
||||||
return `${endpoint}?${queryParams.join("&")}`;
|
return `${endpoint}?${queryParams.join("&")}`;
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,8 @@ type SubValidator struct {
|
|||||||
Sort string `form:"sort" binding:""`
|
Sort string `form:"sort" binding:""`
|
||||||
Remove string `form:"remove" binding:""`
|
Remove string `form:"remove" binding:""`
|
||||||
Replace string `form:"replace" binding:""`
|
Replace string `form:"replace" binding:""`
|
||||||
ReplaceKey string `form:"replaceKey" binding:""`
|
ReplaceKeys []string `form:"-" binding:""`
|
||||||
ReplaceTo string `form:"replaceString" binding:""`
|
ReplaceTo []string `form:"-" binding:""`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RuleProviderStruct struct {
|
type RuleProviderStruct struct {
|
||||||
@ -140,12 +140,16 @@ func ParseQuery(c *gin.Context) (SubValidator, error) {
|
|||||||
query.Rules = nil
|
query.Rules = nil
|
||||||
}
|
}
|
||||||
if strings.TrimSpace(query.Replace) != "" {
|
if strings.TrimSpace(query.Replace) != "" {
|
||||||
replace := strings.Split(strings.Trim(query.Replace, "[]"), ",")
|
reg := regexp.MustCompile(`\[<(.*?)>,<(.*?)>\]`)
|
||||||
if len(replace) != 2 {
|
replaces := reg.FindAllStringSubmatch(query.Replace, -1)
|
||||||
|
for i := range replaces {
|
||||||
|
length := len(replaces[i])
|
||||||
|
if length != 3 {
|
||||||
return SubValidator{}, errors.New("参数错误: replace 格式错误")
|
return SubValidator{}, errors.New("参数错误: replace 格式错误")
|
||||||
}
|
}
|
||||||
query.ReplaceKey = replace[0]
|
query.ReplaceKeys = append(query.ReplaceKeys, replaces[i][1])
|
||||||
query.ReplaceTo = replace[1]
|
query.ReplaceTo = append(query.ReplaceTo, replaces[i][2])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return query, nil
|
return query, nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user