Compare commits

..

1 commit

Author SHA1 Message Date
DHR60
c9ed6c1ea8
Merge 4bf86665b7 into 5d6c5da9d9 2025-09-29 09:22:00 +00:00
7 changed files with 42 additions and 157 deletions

View file

@ -1087,8 +1087,6 @@ public static class ConfigHandler
profileItem.IndexId = Utils.GetGuid(false);
maxSort = ProfileExManager.Instance.GetMaxSort();
}
var groupType = profileItem.ConfigType == EConfigType.ProxyChain ? EConfigType.ProxyChain.ToString() : profileGroupItem.MultipleLoad.ToString();
profileItem.Address = $"{profileItem.CoreType}-{groupType}";
if (maxSort > 0)
{
ProfileExManager.Instance.SetSort(profileItem.IndexId, maxSort + 1);
@ -1196,10 +1194,10 @@ public static class ConfigHandler
var indexId = Utils.GetGuid(false);
var childProfileIndexId = Utils.List2String(selecteds.Select(p => p.IndexId).ToList());
var remark = subId.IsNullOrEmpty() ? string.Empty : $"{(await AppManager.Instance.GetSubItem(subId)).Remarks} ";
var remark = string.Empty;
if (coreType == ECoreType.Xray)
{
remark += multipleLoad switch
remark = multipleLoad switch
{
EMultipleLoad.LeastPing => ResUI.menuGenGroupMultipleServerXrayLeastPing,
EMultipleLoad.Fallback => ResUI.menuGenGroupMultipleServerXrayFallback,
@ -1211,7 +1209,7 @@ public static class ConfigHandler
}
else if (coreType == ECoreType.sing_box)
{
remark += multipleLoad switch
remark = multipleLoad switch
{
EMultipleLoad.LeastPing => ResUI.menuGenGroupMultipleServerSingBoxLeastPing,
EMultipleLoad.Fallback => ResUI.menuGenGroupMultipleServerSingBoxFallback,
@ -1224,6 +1222,7 @@ public static class ConfigHandler
CoreType = coreType,
ConfigType = EConfigType.PolicyGroup,
Remarks = remark,
Address = childProfileIndexId,
};
if (!subId.IsNullOrEmpty())
{

View file

@ -363,6 +363,8 @@ public partial class CoreConfigSingboxService(Config config)
await GenLog(singboxConfig);
await GenInbounds(singboxConfig);
await GenRouting(singboxConfig);
await GenExperimental(singboxConfig);
var groupRet = await GenGroupOutbound(parentNode, singboxConfig);
if (groupRet != 0)
@ -371,8 +373,6 @@ public partial class CoreConfigSingboxService(Config config)
return ret;
}
await GenRouting(singboxConfig);
await GenExperimental(singboxConfig);
await GenDns(null, singboxConfig);
await ConvertGeo2Ruleset(singboxConfig);
@ -416,10 +416,12 @@ public partial class CoreConfigSingboxService(Config config)
ret.Msg = ResUI.FailedGenDefaultConfiguration;
return ret;
}
singboxConfig.outbounds.RemoveAt(0);
await GenLog(singboxConfig);
await GenInbounds(singboxConfig);
await GenRouting(singboxConfig);
await GenExperimental(singboxConfig);
singboxConfig.outbounds.RemoveAt(0);
var groupRet = await GenGroupOutbound(parentNode, singboxConfig);
if (groupRet != 0)
@ -428,8 +430,6 @@ public partial class CoreConfigSingboxService(Config config)
return ret;
}
await GenRouting(singboxConfig);
await GenExperimental(singboxConfig);
await GenDns(null, singboxConfig);
await ConvertGeo2Ruleset(singboxConfig);

View file

@ -694,39 +694,6 @@ public partial class CoreConfigSingboxService
for (var i = 0; i < nodes.Count; i++)
{
var node = nodes[i];
if (node == null)
continue;
if (node.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain)
{
ProfileGroupItemManager.Instance.TryGet(node.IndexId, out var profileGroupItem);
if (profileGroupItem == null || profileGroupItem.ChildItems.IsNullOrEmpty())
{
continue;
}
var childProfiles = (await Task.WhenAll(
Utils.String2List(profileGroupItem.ChildItems)
.Where(p => !p.IsNullOrEmpty())
.Select(AppManager.Instance.GetProfileItem)
)).Where(p => p != null).ToList();
if (childProfiles.Count <= 0)
{
continue;
}
var childBaseTagName = $"{baseTagName}-{i + 1}";
var ret = node.ConfigType switch
{
EConfigType.PolicyGroup =>
await GenOutboundsList(childProfiles, singboxConfig, profileGroupItem.MultipleLoad, childBaseTagName),
EConfigType.ProxyChain =>
await GenChainOutboundsList(childProfiles, singboxConfig, childBaseTagName),
_ => throw new NotImplementedException()
};
if (ret == 0)
{
proxyTags.Add(childBaseTagName);
}
continue;
}
var server = await GenServer(node);
if (server is null)
{

View file

@ -114,6 +114,9 @@ public partial class CoreConfigV2rayService(Config config)
await GenLog(v2rayConfig);
await GenInbounds(v2rayConfig);
await GenRouting(v2rayConfig);
await GenDns(null, v2rayConfig);
await GenStatistic(v2rayConfig);
var groupRet = await GenGroupOutbound(parentNode, v2rayConfig);
if (groupRet != 0)
@ -122,15 +125,11 @@ public partial class CoreConfigV2rayService(Config config)
return ret;
}
await GenRouting(v2rayConfig);
await GenDns(null, v2rayConfig);
await GenStatistic(v2rayConfig);
var defaultBalancerTag = $"{Global.ProxyTag}{Global.BalancerTagSuffix}";
//add rule
var rules = v2rayConfig.routing.rules;
if (rules?.Count > 0 && ((v2rayConfig.routing.balancers?.Count ?? 0) > 0))
if (rules?.Count > 0)
{
var balancerTagSet = v2rayConfig.routing.balancers
.Select(b => b.tag)
@ -216,10 +215,13 @@ public partial class CoreConfigV2rayService(Config config)
ret.Msg = ResUI.FailedGenDefaultConfiguration;
return ret;
}
v2rayConfig.outbounds.RemoveAt(0);
await GenLog(v2rayConfig);
await GenInbounds(v2rayConfig);
await GenRouting(v2rayConfig);
await GenDns(null, v2rayConfig);
await GenStatistic(v2rayConfig);
v2rayConfig.outbounds.RemoveAt(0);
var groupRet = await GenGroupOutbound(parentNode, v2rayConfig);
if (groupRet != 0)
@ -228,10 +230,6 @@ public partial class CoreConfigV2rayService(Config config)
return ret;
}
await GenRouting(v2rayConfig);
await GenDns(null, v2rayConfig);
await GenStatistic(v2rayConfig);
ret.Success = true;
ret.Data = await ApplyFullConfigTemplate(v2rayConfig, true);

View file

@ -4,80 +4,32 @@ public partial class CoreConfigV2rayService
{
private async Task<int> GenObservatory(V2rayConfig v2rayConfig, EMultipleLoad multipleLoad, string baseTagName = Global.ProxyTag)
{
// Collect all existing subject selectors from both observatories
var subjectSelectors = new List<string>();
subjectSelectors.AddRange(v2rayConfig.burstObservatory?.subjectSelector ?? []);
subjectSelectors.AddRange(v2rayConfig.observatory?.subjectSelector ?? []);
// Case 1: exact match already exists -> nothing to do
if (subjectSelectors.Any(baseTagName.StartsWith))
return await Task.FromResult(0);
// Case 2: prefix match exists -> reuse it and move to the first position
var matched = subjectSelectors.FirstOrDefault(s => s.StartsWith(baseTagName));
if (matched is not null)
if (multipleLoad == EMultipleLoad.LeastPing)
{
baseTagName = matched;
if (v2rayConfig.burstObservatory?.subjectSelector?.Contains(baseTagName) == true)
var observatory = new Observatory4Ray
{
v2rayConfig.burstObservatory.subjectSelector.Remove(baseTagName);
v2rayConfig.burstObservatory.subjectSelector.Insert(0, baseTagName);
}
if (v2rayConfig.observatory?.subjectSelector?.Contains(baseTagName) == true)
{
v2rayConfig.observatory.subjectSelector.Remove(baseTagName);
v2rayConfig.observatory.subjectSelector.Insert(0, baseTagName);
}
return await Task.FromResult(0);
subjectSelector = [baseTagName],
probeUrl = AppManager.Instance.Config.SpeedTestItem.SpeedPingTestUrl,
probeInterval = "3m",
enableConcurrency = true,
};
v2rayConfig.observatory = observatory;
}
// Case 3: need to create or insert based on multipleLoad type
if (multipleLoad is EMultipleLoad.LeastLoad or EMultipleLoad.Fallback)
else if (multipleLoad is EMultipleLoad.LeastLoad or EMultipleLoad.Fallback)
{
if (v2rayConfig.burstObservatory is null)
var burstObservatory = new BurstObservatory4Ray
{
// Create new burst observatory with default ping config
v2rayConfig.burstObservatory = new BurstObservatory4Ray
subjectSelector = [baseTagName],
pingConfig = new()
{
subjectSelector = [baseTagName],
pingConfig = new()
{
destination = AppManager.Instance.Config.SpeedTestItem.SpeedPingTestUrl,
interval = "5m",
timeout = "30s",
sampling = 2,
}
};
}
else
{
v2rayConfig.burstObservatory.subjectSelector ??= new();
v2rayConfig.burstObservatory.subjectSelector.Add(baseTagName);
}
destination = AppManager.Instance.Config.SpeedTestItem.SpeedPingTestUrl,
interval = "5m",
timeout = "30s",
sampling = 2,
}
};
v2rayConfig.burstObservatory = burstObservatory;
}
else if (multipleLoad is EMultipleLoad.LeastPing)
{
if (v2rayConfig.observatory is null)
{
// Create new observatory with default probe config
v2rayConfig.observatory = new Observatory4Ray
{
subjectSelector = [baseTagName],
probeUrl = AppManager.Instance.Config.SpeedTestItem.SpeedPingTestUrl,
probeInterval = "3m",
enableConcurrency = true,
};
}
else
{
v2rayConfig.observatory.subjectSelector ??= new();
v2rayConfig.observatory.subjectSelector.Add(baseTagName);
}
}
return await Task.FromResult(0);
}

View file

@ -539,11 +539,9 @@ public partial class CoreConfigV2rayService
}
//add balancers
if (node.ConfigType == EConfigType.PolicyGroup)
{
await GenObservatory(v2rayConfig, profileGroupItem.MultipleLoad, baseTagName);
await GenBalancer(v2rayConfig, profileGroupItem.MultipleLoad, baseTagName);
}
await GenObservatory(v2rayConfig, profileGroupItem.MultipleLoad, baseTagName);
await GenBalancer(v2rayConfig, profileGroupItem.MultipleLoad, baseTagName);
}
catch (Exception ex)
{
@ -799,35 +797,6 @@ public partial class CoreConfigV2rayService
for (var i = 0; i < nodes.Count; i++)
{
var node = nodes[i];
if (node == null)
continue;
if (node.ConfigType is EConfigType.PolicyGroup or EConfigType.ProxyChain)
{
ProfileGroupItemManager.Instance.TryGet(node.IndexId, out var profileGroupItem);
if (profileGroupItem == null || profileGroupItem.ChildItems.IsNullOrEmpty())
{
continue;
}
var childProfiles = (await Task.WhenAll(
Utils.String2List(profileGroupItem.ChildItems)
.Where(p => !p.IsNullOrEmpty())
.Select(AppManager.Instance.GetProfileItem)
)).Where(p => p != null).ToList();
if (childProfiles.Count <= 0)
{
continue;
}
var childBaseTagName = $"{baseTagName}-{i + 1}";
var ret = node.ConfigType switch
{
EConfigType.PolicyGroup =>
await GenOutboundsListWithChain(childProfiles, v2rayConfig, childBaseTagName),
EConfigType.ProxyChain =>
await GenChainOutboundsList(childProfiles, v2rayConfig, childBaseTagName),
_ => throw new NotImplementedException()
};
continue;
}
var txtOutbound = EmbedUtils.GetEmbedText(Global.V2raySampleOutbound);
if (txtOutbound.IsNullOrEmpty())
{

View file

@ -195,12 +195,12 @@ public class AddGroupServerViewModel : MyReactiveObject
var childIndexIds = new List<string>();
foreach (var item in ChildItemsObs)
{
if (item.IndexId.IsNullOrEmpty())
if (!item.IndexId.IsNullOrEmpty())
{
continue;
childIndexIds.Add(item.IndexId);
}
childIndexIds.Add(item.IndexId);
}
SelectedSource.Address = Utils.List2String(childIndexIds);
var profileGroup = ProfileGroupItemManager.Instance.GetOrCreateAndMarkDirty(SelectedSource.IndexId);
profileGroup.ChildItems = Utils.List2String(childIndexIds);
profileGroup.MultipleLoad = PolicyGroupType switch