using System.Net.Sockets; using System.Text.Json.Serialization; using Netch.Utils; namespace Netch.Models; public abstract class Server : ICloneable { /// /// 延迟 /// [JsonIgnore] public int Delay { get; private set; } = -1; /// /// 组 /// public string Group { get; set; } = Constants.DefaultGroup; /// /// 地址 /// public string Hostname { get; set; } = string.Empty; /// /// 端口 /// public ushort Port { get; set; } /// /// 倍率 /// public double Rate { get; } = 1.0; /// /// 备注 /// public string Remark { get; set; } = ""; /// /// 代理类型 /// [JsonPropertyOrder(int.MinValue)] public abstract string Type { get; } public object Clone() { return MemberwiseClone(); } /// /// 获取备注 /// /// 备注 public override string ToString() { var remark = string.IsNullOrWhiteSpace(Remark) ? $"{Hostname}:{Port}" : Remark; var shortName = ServerHelper.GetUtilByTypeName(Type).ShortName; return $"[{shortName}][{Group}] {remark}"; } public abstract string MaskedData(); /// /// 测试延迟 /// /// 延迟 public async Task PingAsync() { try { var destination = await DnsUtils.LookupAsync(Hostname); if (destination == null) return Delay = -2; var list = new Task[3]; for (var i = 0; i < 3; i++) { Task PingCoreAsync() { try { return Global.Settings.ServerTCPing ? Utils.Utils.TCPingAsync(destination, Port) : Utils.Utils.ICMPingAsync(destination); } catch (Exception) { return Task.FromResult(-4); } } list[i] = PingCoreAsync(); } var resTask = await Task.WhenAny(list[0], list[1], list[2]); return Delay = await resTask; } catch (Exception) { return Delay = -4; } } } public static class ServerExtension { public static async Task AutoResolveHostnameAsync(this Server server, AddressFamily inet = AddressFamily.Unspecified) { // ! MainController cached return (await DnsUtils.LookupAsync(server.Hostname, inet))!.ToString(); } public static bool IsInGroup(this Server server) { return server.Group is not Constants.DefaultGroup; } }