namespace ServiceLib.Models.Entities; [Serializable] public class ProfileItem { private ProtocolExtraItem? _protocolExtraCache; private TransportExtraItem? _transportExtraCache; public ProfileItem() { IndexId = string.Empty; ConfigType = EConfigType.VMess; ConfigVersion = 4; Subid = string.Empty; Address = string.Empty; Port = 0; Password = string.Empty; Username = string.Empty; Network = string.Empty; Remarks = string.Empty; StreamSecurity = string.Empty; AllowInsecure = string.Empty; } #region function public string GetSummary() { var summary = $"[{ConfigType.ToString()}] "; if (IsComplex()) { summary += $"[{CoreType.ToString()}]{Remarks}"; } else { var arrAddr = Address.Contains(':') ? Address.Split(':') : Address.Split('.'); var addr = arrAddr.Length switch { > 2 => $"{arrAddr.First()}***{arrAddr.Last()}", > 1 => $"***{arrAddr.Last()}", _ => Address }; summary += $"{Remarks}({addr}:{Port})"; } return summary; } public List? GetAlpn() { return Alpn.IsNullOrEmpty() ? null : Utils.String2List(Alpn); } public string GetNetwork() { if (Network.IsNullOrEmpty() || !Global.Networks.Contains(Network)) { return Global.DefaultNetwork; } return Network.TrimEx(); } public bool IsComplex() { return ConfigType.IsComplexType(); } public bool IsValid() { if (IsComplex() || ConfigType == EConfigType.Outbound) { return true; } if (Address.IsNullOrEmpty() || Port is <= 0 or >= 65536) { return false; } switch (ConfigType) { case EConfigType.VMess: if (Password.IsNullOrEmpty() || !Utils.IsGuidByParse(Password)) { return false; } break; case EConfigType.VLESS: if (Password.IsNullOrEmpty() || (!Utils.IsGuidByParse(Password) && Password.Length > 30)) { return false; } if (!Global.Flows.Contains(GetProtocolExtra().Flow ?? string.Empty)) { return false; } break; case EConfigType.Shadowsocks: if (Password.IsNullOrEmpty()) { return false; } if (string.IsNullOrEmpty(GetProtocolExtra().SsMethod) || !Global.SsSecuritiesInSingbox.Contains(GetProtocolExtra().SsMethod)) { return false; } break; } if ((ConfigType is EConfigType.VLESS or EConfigType.Trojan) && StreamSecurity == Global.StreamSecurityReality && PublicKey.IsNullOrEmpty()) { return false; } return true; } public ProtocolExtraItem GetProtocolExtra() { return _protocolExtraCache ??= JsonUtils.Deserialize(ProtoExtra) ?? new ProtocolExtraItem(); } public void SetProtocolExtra(ProtocolExtraItem extraItem) { _protocolExtraCache = extraItem; ProtoExtra = JsonUtils.Serialize(extraItem, false); } public TransportExtraItem GetTransportExtra() { return _transportExtraCache ??= JsonUtils.Deserialize(TransportExtra) ?? new TransportExtraItem(); } public void SetTransportExtra(TransportExtraItem transportExtra) { _transportExtraCache = transportExtra; TransportExtra = JsonUtils.Serialize(transportExtra, false); } public bool GetAllowInsecure() { return AllowInsecure == Global.StringTrue; } #endregion function [PrimaryKey] public string IndexId { get; set; } public EConfigType ConfigType { get; set; } public ECoreType? CoreType { get; set; } public int ConfigVersion { get; set; } public string Subid { get; set; } public bool IsSub { get; set; } = true; public int? PreSocksPort { get; set; } public bool DisplayLog { get; set; } = true; public string Remarks { get; set; } public string Address { get; set; } public int Port { get; set; } public string Password { get; set; } public string Username { get; set; } public string Network { get; set; } [Obsolete("Use TransportExtra.RawHeaderType/XhttpMode/GrpcMode/KcpHeaderType instead.")] public string HeaderType { get; set; } [Obsolete("Use TransportExtra.Host/GrpcAuthority instead.")] public string RequestHost { get; set; } [Obsolete("Use TransportExtra.Path/GrpcServiceName/KcpSeed instead.")] public string Path { get; set; } public string StreamSecurity { get; set; } public string AllowInsecure { get; set; } public string Sni { get; set; } public string Alpn { get; set; } = string.Empty; public string Fingerprint { get; set; } public string PublicKey { get; set; } public string ShortId { get; set; } public string SpiderX { get; set; } public string Mldsa65Verify { get; set; } [Obsolete("Use TransportExtra.XhttpExtra instead.")] public string Extra { get; set; } public bool? MuxEnabled { get; set; } public string Cert { get; set; } public string CertSha { get; set; } public string EchConfigList { get; set; } public string VerifyPeerCertByName { get; set; } public string Finalmask { get; set; } public string ProtoExtra { get; set; } public string TransportExtra { get; set; } [Obsolete("Use ProtocolExtraItem.Ports instead.")] public string Ports { get; set; } [Obsolete("Use ProtocolExtraItem.AlterId instead.")] public int AlterId { get; set; } [Obsolete("Use ProtocolExtraItem.Flow instead.")] public string Flow { get; set; } [Obsolete("Use ProfileItem.Password instead.")] public string Id { get; set; } [Obsolete("Use ProtocolExtraItem.xxx instead.")] public string Security { get; set; } }