160 lines
4.8 KiB
C#
160 lines
4.8 KiB
C#
using System;
|
||
using System.IO;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Net;
|
||
using System.Web;
|
||
using System.Web.Script.Serialization;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
|
||
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 { return _ip; }
|
||
set
|
||
{
|
||
_ip = value;
|
||
IPString = SimpleIPToString(_ip);
|
||
}
|
||
}
|
||
public string IPString { get; private set; }
|
||
public string ID { get; set; }
|
||
|
||
private uint _ip;
|
||
}
|
||
|
||
internal class PlayerIdentity
|
||
{
|
||
public bool IsUsable => IsListUsable(_list);
|
||
|
||
private Cache _cache;
|
||
private volatile IReadOnlyDictionary<uint, string> _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<List<IPAndPlayer>>(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<uint, string> 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<List<IPAndPlayer>>(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<IPAndPlayer> AsSortedList()
|
||
{
|
||
var list = _list;
|
||
|
||
if(!IsListUsable(list))
|
||
{
|
||
return new List<IPAndPlayer>();
|
||
}
|
||
|
||
return _list.Select((kv) => new IPAndPlayer { IP = kv.Key, ID = kv.Value }).OrderBy(x => x.IP).ToList();
|
||
}
|
||
|
||
public string QueryRealName(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 : 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);
|
||
}
|
||
}
|
||
}
|