AnotherReplayReader/PlayerIdentity.cs
2021-04-23 00:56:08 +02:00

160 lines
4.8 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.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);
}
}
}