AnotherReplayReader/PlayerIdentity.cs
2021-10-13 20:17:32 +02:00

185 lines
5.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<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 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);
}
}
}