using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; using System.Web; using System.Web.Script.Serialization; namespace AnotherReplayReader { internal sealed class IPAndPlayer { public static string SimpleIPToString(uint ip) { return $"{ip / 256 / 256 / 256}.{ip / 256 / 256 % 256}.{ip / 256 % 256}.{ip % 256}"; } public uint IP { get => _ip; set { _ip = value; IPString = SimpleIPToString(_ip); } } public string IPString { get; private set; } public string ID { get => _id; set { _id = value; _pinyin = _id.ToPinyin(); } } public string PinyinID => _pinyin; private uint _ip; private string _id; private string _pinyin; } internal class PlayerIdentity { public bool IsUsable => IsListUsable(_list); private Cache _cache; private volatile IReadOnlyDictionary _list; public PlayerIdentity(Cache cache) { _cache = cache; Fetch(); try { var stored = _cache.GetOrDefault("pt", string.Empty); if (string.IsNullOrWhiteSpace(stored)) { return; } var bytes = Convert.FromBase64String(stored); var id = Encoding.UTF8.GetBytes(Auth.ID); var data = Encoding.UTF8.GetString(bytes.Select((x, i) => (byte)(x ^ id[i % id.Length])).ToArray()); var serializer = new JavaScriptSerializer(); var cachedTable = serializer.Deserialize>(data); if (cachedTable == null) { _list = null; return; } var converted = cachedTable.ToDictionary(x => x.IP, x => x.ID); converted[0] = "【没有网络连接,正在使用上次保存的数据】"; _list = converted; } catch { } } public static bool IsListUsable(IReadOnlyDictionary list) { return list != null && list.Count != 0; } public Task Fetch() { return Task.Run(() => { try { var key = HttpUtility.UrlEncode(Auth.GetKey()); var request = WebRequest.Create($"https://lanyi.altervista.org/playertable/playertable.php?do=getTable&key={key}"); using (var stream = request.GetResponse().GetResponseStream()) using (var reader = new StreamReader(stream)) { var response = reader.ReadToEnd(); var serializer = new JavaScriptSerializer(); var temp = serializer.Deserialize>(response); if (temp == null) { _list = null; return; } var converted = temp.ToDictionary(x => x.IP, x => x.ID); _list = converted; var bytes = Encoding.UTF8.GetBytes(serializer.Serialize(temp)); var id = Encoding.UTF8.GetBytes(Auth.ID); var base64 = Convert.ToBase64String(bytes.Select((x, i) => (byte)(x ^ id[i % id.Length])).ToArray()); _cache.Set("pt", base64); } } catch { } }); } public List AsSortedList() { var list = _list; if (!IsListUsable(list)) { return new List(); } return _list.Select((kv) => new IPAndPlayer { IP = kv.Key, ID = kv.Value }).OrderBy(x => x.IP).ToList(); } public string GetRealName(uint ip) { var list = _list; if (!IsListUsable(list)) { return string.Empty; } if (ip == 0) { return string.Empty; } if (!list.TryGetValue(ip, out var name)) { return string.Empty; } return name; } public string FormatRealName(uint ip) { var name = GetRealName(ip); if (string.IsNullOrEmpty(name)) { name = IPAndPlayer.SimpleIPToString(ip); } return $"({name})"; } public string QueryRealNameAndIP(uint ip) { var list = _list; if (!IsListUsable(list)) { return string.Empty; } if (ip == 0) { return string.Empty; } var name = list.TryGetValue(ip, out var realName) ? realName + "," : string.Empty; return name + IPAndPlayer.SimpleIPToString(ip); } } }