2022-08-15 23:55:44 +08:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
|
2022-12-06 15:50:17 +08:00
|
|
|
|
namespace MinecraftClient.Protocol.ProfileKey
|
2022-08-15 23:55:44 +08:00
|
|
|
|
{
|
|
|
|
|
|
public class PlayerKeyPair
|
|
|
|
|
|
{
|
|
|
|
|
|
public PublicKey PublicKey;
|
|
|
|
|
|
|
|
|
|
|
|
public PrivateKey PrivateKey;
|
|
|
|
|
|
|
|
|
|
|
|
public DateTime ExpiresAt;
|
|
|
|
|
|
|
|
|
|
|
|
public DateTime RefreshedAfter; // Todo: add a timer
|
|
|
|
|
|
|
2022-08-31 18:00:00 +08:00
|
|
|
|
private const string DataTimeFormat = "yyyy-MM-ddTHH:mm:ss.ffffffZ";
|
2022-08-15 23:55:44 +08:00
|
|
|
|
|
|
|
|
|
|
public PlayerKeyPair(PublicKey keyPublic, PrivateKey keyPrivate, string expiresAt, string refreshedAfter)
|
|
|
|
|
|
{
|
|
|
|
|
|
PublicKey = keyPublic;
|
|
|
|
|
|
PrivateKey = keyPrivate;
|
2022-09-04 10:50:49 +08:00
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
ExpiresAt = DateTime.ParseExact(expiresAt, DataTimeFormat, System.Globalization.CultureInfo.InvariantCulture).ToUniversalTime();
|
|
|
|
|
|
RefreshedAfter = DateTime.ParseExact(refreshedAfter, DataTimeFormat, System.Globalization.CultureInfo.InvariantCulture).ToUniversalTime();
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
ExpiresAt = DateTime.Parse(expiresAt).ToUniversalTime();
|
|
|
|
|
|
RefreshedAfter = DateTime.Parse(refreshedAfter).ToUniversalTime();
|
|
|
|
|
|
}
|
2022-08-15 23:55:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool NeedRefresh()
|
|
|
|
|
|
{
|
2022-10-02 18:31:08 +08:00
|
|
|
|
return DateTime.Now.ToUniversalTime() > RefreshedAfter;
|
2022-08-15 23:55:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool IsExpired()
|
|
|
|
|
|
{
|
2022-10-02 18:31:08 +08:00
|
|
|
|
return DateTime.Now.ToUniversalTime() > ExpiresAt;
|
2022-08-15 23:55:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public long GetExpirationMilliseconds()
|
|
|
|
|
|
{
|
|
|
|
|
|
DateTimeOffset timeOffset = new(ExpiresAt);
|
|
|
|
|
|
return timeOffset.ToUnixTimeMilliseconds();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public long GetExpirationSeconds()
|
|
|
|
|
|
{
|
|
|
|
|
|
DateTimeOffset timeOffset = new(ExpiresAt);
|
|
|
|
|
|
return timeOffset.ToUnixTimeSeconds();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static PlayerKeyPair FromString(string tokenString)
|
|
|
|
|
|
{
|
|
|
|
|
|
string[] fields = tokenString.Split(',');
|
|
|
|
|
|
|
|
|
|
|
|
if (fields.Length < 6)
|
|
|
|
|
|
throw new InvalidDataException("Invalid string format");
|
|
|
|
|
|
|
2022-10-02 18:31:08 +08:00
|
|
|
|
PublicKey publicKey = new(pemKey: fields[0].Trim(),
|
2022-08-15 23:55:44 +08:00
|
|
|
|
sig: fields[1].Trim(), sigV2: fields[2].Trim());
|
|
|
|
|
|
|
2022-10-02 18:31:08 +08:00
|
|
|
|
PrivateKey privateKey = new(pemKey: fields[3].Trim());
|
2022-08-15 23:55:44 +08:00
|
|
|
|
|
|
|
|
|
|
return new PlayerKeyPair(publicKey, privateKey, fields[4].Trim(), fields[5].Trim());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override string ToString()
|
|
|
|
|
|
{
|
2022-10-02 18:31:08 +08:00
|
|
|
|
List<string> datas = new();
|
2022-08-15 23:55:44 +08:00
|
|
|
|
datas.Add(Convert.ToBase64String(PublicKey.Key));
|
2022-08-24 12:37:22 +08:00
|
|
|
|
if (PublicKey.Signature == null)
|
2022-12-06 15:50:17 +08:00
|
|
|
|
datas.Add(string.Empty);
|
2022-08-24 12:37:22 +08:00
|
|
|
|
else
|
|
|
|
|
|
datas.Add(Convert.ToBase64String(PublicKey.Signature));
|
2022-08-15 23:55:44 +08:00
|
|
|
|
if (PublicKey.SignatureV2 == null)
|
2022-12-06 15:50:17 +08:00
|
|
|
|
datas.Add(string.Empty);
|
2022-08-15 23:55:44 +08:00
|
|
|
|
else
|
|
|
|
|
|
datas.Add(Convert.ToBase64String(PublicKey.SignatureV2));
|
|
|
|
|
|
datas.Add(Convert.ToBase64String(PrivateKey.Key));
|
|
|
|
|
|
datas.Add(ExpiresAt.ToString(DataTimeFormat));
|
|
|
|
|
|
datas.Add(RefreshedAfter.ToString(DataTimeFormat));
|
2022-12-06 15:50:17 +08:00
|
|
|
|
return string.Join(",", datas.ToArray());
|
2022-08-15 23:55:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|