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