2025-06-26 06:23:30 +00:00
|
|
|
using ReactiveUI;
|
2025-03-01 13:13:37 +00:00
|
|
|
using SQLite;
|
2023-01-01 11:42:01 +00:00
|
|
|
|
2025-04-02 03:44:23 +00:00
|
|
|
namespace ServiceLib.Models;
|
|
|
|
|
|
|
|
[Serializable]
|
2025-07-01 11:39:27 +00:00
|
|
|
public class ProfileItem : ReactiveObject
|
2023-01-01 11:42:01 +00:00
|
|
|
{
|
2025-04-02 03:44:23 +00:00
|
|
|
public ProfileItem()
|
2023-01-01 11:42:01 +00:00
|
|
|
{
|
2025-04-02 03:44:23 +00:00
|
|
|
IndexId = string.Empty;
|
|
|
|
ConfigType = EConfigType.VMess;
|
|
|
|
ConfigVersion = 2;
|
|
|
|
Address = string.Empty;
|
|
|
|
Port = 0;
|
|
|
|
Id = string.Empty;
|
|
|
|
AlterId = 0;
|
|
|
|
Security = string.Empty;
|
|
|
|
Network = string.Empty;
|
|
|
|
Remarks = string.Empty;
|
|
|
|
HeaderType = string.Empty;
|
|
|
|
RequestHost = string.Empty;
|
|
|
|
Path = string.Empty;
|
|
|
|
StreamSecurity = string.Empty;
|
|
|
|
AllowInsecure = string.Empty;
|
|
|
|
Subid = string.Empty;
|
|
|
|
Flow = string.Empty;
|
|
|
|
}
|
2023-01-01 11:42:01 +00:00
|
|
|
|
2025-04-02 03:44:23 +00:00
|
|
|
#region function
|
2023-04-14 12:49:36 +00:00
|
|
|
|
2025-04-02 03:44:23 +00:00
|
|
|
public string GetSummary()
|
|
|
|
{
|
|
|
|
var summary = $"[{(ConfigType).ToString()}] ";
|
2025-09-23 02:27:23 +00:00
|
|
|
if (IsComplex())
|
2023-01-01 11:42:01 +00:00
|
|
|
{
|
2025-09-06 12:12:04 +00:00
|
|
|
summary += $"[{CoreType.ToString()}]{Remarks}";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2025-09-23 02:27:23 +00:00
|
|
|
var arrAddr = Address.Contains(':') ? Address.Split(':') : Address.Split('.');
|
|
|
|
var addr = arrAddr.Length switch
|
|
|
|
{
|
|
|
|
> 2 => $"{arrAddr.First()}***{arrAddr.Last()}",
|
|
|
|
> 1 => $"***{arrAddr.Last()}",
|
|
|
|
_ => Address
|
|
|
|
};
|
2025-09-06 12:12:04 +00:00
|
|
|
summary += $"{Remarks}({addr}:{Port})";
|
|
|
|
}
|
2025-04-02 03:44:23 +00:00
|
|
|
return summary;
|
|
|
|
}
|
|
|
|
|
|
|
|
public List<string>? GetAlpn()
|
|
|
|
{
|
|
|
|
return Alpn.IsNullOrEmpty() ? null : Utils.String2List(Alpn);
|
|
|
|
}
|
2023-01-01 11:42:01 +00:00
|
|
|
|
2025-04-02 03:44:23 +00:00
|
|
|
public string GetNetwork()
|
|
|
|
{
|
|
|
|
if (Network.IsNullOrEmpty() || !Global.Networks.Contains(Network))
|
2023-01-01 11:42:01 +00:00
|
|
|
{
|
2025-04-02 03:44:23 +00:00
|
|
|
return Global.DefaultNetwork;
|
2023-01-01 11:42:01 +00:00
|
|
|
}
|
2025-04-02 03:44:23 +00:00
|
|
|
return Network.TrimEx();
|
|
|
|
}
|
2023-01-01 11:42:01 +00:00
|
|
|
|
2025-09-22 09:15:00 +00:00
|
|
|
public bool IsComplex()
|
|
|
|
{
|
|
|
|
return ConfigType is EConfigType.Custom or > EConfigType.Group;
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool IsValid()
|
|
|
|
{
|
|
|
|
if (IsComplex())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (Address.IsNullOrEmpty() || Port is <= 0 or >= 65536)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
switch (ConfigType)
|
|
|
|
{
|
|
|
|
case EConfigType.VMess:
|
|
|
|
if (Id.IsNullOrEmpty() || !Utils.IsGuidByParse(Id))
|
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EConfigType.VLESS:
|
|
|
|
if (Id.IsNullOrEmpty() || (!Utils.IsGuidByParse(Id) && Id.Length > 30))
|
|
|
|
return false;
|
|
|
|
if (!Global.Flows.Contains(Flow))
|
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EConfigType.Shadowsocks:
|
|
|
|
if (Id.IsNullOrEmpty())
|
|
|
|
return false;
|
|
|
|
if (string.IsNullOrEmpty(Security) || !Global.SsSecuritiesInSingbox.Contains(Security))
|
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((ConfigType is EConfigType.VLESS or EConfigType.Trojan)
|
|
|
|
&& StreamSecurity == Global.StreamSecurityReality
|
|
|
|
&& PublicKey.IsNullOrEmpty())
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2025-09-29 09:09:09 +00:00
|
|
|
public async Task<bool> HasCycle(HashSet<string> visited, HashSet<string> stack)
|
|
|
|
{
|
|
|
|
if (ConfigType < EConfigType.Group)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (stack.Contains(IndexId))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (visited.Contains(IndexId))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
visited.Add(IndexId);
|
|
|
|
stack.Add(IndexId);
|
|
|
|
|
|
|
|
if (ProfileGroupItemManager.Instance.TryGet(IndexId, out var group)
|
|
|
|
&& !group.ChildItems.IsNullOrEmpty())
|
|
|
|
{
|
|
|
|
var childProfiles = (await Task.WhenAll(
|
|
|
|
Utils.String2List(group.ChildItems)
|
|
|
|
.Where(p => !p.IsNullOrEmpty())
|
|
|
|
.Select(AppManager.Instance.GetProfileItem)
|
|
|
|
))
|
|
|
|
.Where(p => p != null)
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
foreach (var child in childProfiles)
|
|
|
|
{
|
|
|
|
if (await child.HasCycle(visited, stack))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
stack.Remove(IndexId);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2025-04-02 03:44:23 +00:00
|
|
|
#endregion function
|
2023-01-01 11:42:01 +00:00
|
|
|
|
2025-04-02 03:44:23 +00:00
|
|
|
[PrimaryKey]
|
|
|
|
public string IndexId { get; set; }
|
|
|
|
|
|
|
|
public EConfigType ConfigType { get; set; }
|
|
|
|
public int ConfigVersion { get; set; }
|
|
|
|
public string Address { get; set; }
|
|
|
|
public int Port { get; set; }
|
|
|
|
public string Ports { get; set; }
|
|
|
|
public string Id { get; set; }
|
|
|
|
public int AlterId { get; set; }
|
|
|
|
public string Security { get; set; }
|
|
|
|
public string Network { get; set; }
|
|
|
|
public string Remarks { get; set; }
|
|
|
|
public string HeaderType { get; set; }
|
|
|
|
public string RequestHost { get; set; }
|
|
|
|
public string Path { get; set; }
|
|
|
|
public string StreamSecurity { get; set; }
|
|
|
|
public string AllowInsecure { get; set; }
|
|
|
|
public string Subid { get; set; }
|
|
|
|
public bool IsSub { get; set; } = true;
|
|
|
|
public string Flow { get; set; }
|
|
|
|
public string Sni { get; set; }
|
|
|
|
public string Alpn { get; set; } = string.Empty;
|
|
|
|
public ECoreType? CoreType { get; set; }
|
|
|
|
public int? PreSocksPort { get; set; }
|
|
|
|
public string Fingerprint { get; set; }
|
|
|
|
public bool DisplayLog { get; set; } = true;
|
|
|
|
public string PublicKey { get; set; }
|
|
|
|
public string ShortId { get; set; }
|
|
|
|
public string SpiderX { get; set; }
|
2025-08-03 02:34:21 +00:00
|
|
|
public string Mldsa65Verify { get; set; }
|
2025-04-02 03:44:23 +00:00
|
|
|
public string Extra { get; set; }
|
2025-06-29 07:06:02 +00:00
|
|
|
public bool? MuxEnabled { get; set; }
|
2025-03-01 13:13:37 +00:00
|
|
|
}
|