iFactory.Godot/Artists/Scripts/License/LicenseService.cs

127 lines
3.8 KiB
C#
Raw Permalink Normal View History

2023-09-21 03:49:27 +08:00
using Godot;
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Web;
using BITKit;
using BITKit.Auth;
using BITKit.Net.Http;
using Cysharp.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Environment = System.Environment;
using HttpClient = System.Net.Http.HttpClient;
namespace IDIS.License;
public class LicenseBin
{
public DateTime ExpirationDate=DateTime.Now;
public string Token;
}
public partial class LicenseService : EntityComponent,IAuthService
{
private static readonly HttpClient _httpClient = new();
[Export] private string _requestAuthorizeUrl;
[Export] private string _revokeAuthorizeUrl;
public bool IsAuthorized { get;private set; }
public bool IsAuthorizing { get;private set; }
public event Action<string> OnAuthorize;
public event Action<string> OnAuthorized;
public event Action<string> UnAuthorize;
public event Action<string> OnAuthorizeFailure;
private CancellationTokenSource _cancellationTokenSource;
private CancellationToken _cancellationToken=>_cancellationTokenSource.Token;
private IHttpListenerService _httpListenerService;
private readonly string path = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"iFactory",
"License.bin"
);
public override void BuildService(IServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<IAuthService>(this);
}
public override void _EnterTree()
{
_cancellationTokenSource = new CancellationTokenSource();
}
public override void _ExitTree()
{
_cancellationTokenSource.Cancel();
}
public override void OnAwake()
{
_httpListenerService = Entity.ServiceProvider.GetRequiredService<IHttpListenerService>();
_httpListenerService.OnRequest += OnRequest;
}
public override void OnStart()
{
BIT4Log.Log<LicenseService>("准备文件中,二进制授权文件路径:"+path);
if (IsAuthorized || IsAuthorizing) return;
if (File.Exists(path) is false) return;
var json = File.ReadAllText(path);
var licenseBin = JsonConvert.DeserializeObject<LicenseBin>(json);
if(licenseBin.ExpirationDate<DateTime.Now) return;
AuthorizeAsync(licenseBin.Token).Forget();
}
private HttpContent OnRequest(HttpListenerRequest arg)
{
2023-09-23 23:01:39 +08:00
//if (arg.HttpMethod is not "POST" or not "OPTIONS") return new StringContent(ContextModel.Error("Method Not Allowed"));
var sr = new StreamReader(arg.InputStream);
var token = sr.ReadToEnd();
2023-09-21 03:49:27 +08:00
AuthorizeAsync(token).Forget();
2023-09-23 23:01:39 +08:00
return new StringContent(ContextModel.Get(true));
2023-09-21 03:49:27 +08:00
}
public async UniTask AuthorizeAsync(string token)
{
OnAuthorize?.Invoke(token);
2023-09-23 23:01:39 +08:00
var response = await _httpClient.PostAsync(_requestAuthorizeUrl,new StringContent( JsonConvert.SerializeObject(token),Encoding.UTF8, "application/json"), _cancellationToken);
2023-09-21 03:49:27 +08:00
var message = await response.Content.ReadAsStringAsync(_cancellationToken);
if (response.IsSuccessStatusCode)
{
OnAuthorized?.Invoke(message);
BIT4Log.Log<IAuthService>($"授权成功:{message}");
var licenseBin = new LicenseBin
{
2023-09-23 23:01:39 +08:00
Token = token,
2023-09-21 03:49:27 +08:00
ExpirationDate = DateTime.Now.AddDays(7)
};
PathHelper.EnsureDirectoryCreated(path);
await File.WriteAllTextAsync(path, JsonConvert.SerializeObject(licenseBin), _cancellationToken);
IsAuthorized = true;
}
else
{
OnAuthorizeFailure?.Invoke(message);
2023-09-23 23:01:39 +08:00
BIT4Log.Log<IAuthService>($"当前Token:{token}");
2023-09-21 03:49:27 +08:00
BIT4Log.Log<IAuthService>($"授权失败:{message}");
}
}
public UniTask CancelAuthorizationAsync()
{
if (IsAuthorized is false)
{
throw new InvalidOperationException("未授权");
}
var url = _revokeAuthorizeUrl.Replace("{x}",_requestAuthorizeUrl);
UnAuthorize?.Invoke("取消授权");
IsAuthorized = false;
_httpClient.PostAsync(url, new StringContent(""), _cancellationToken).AsUniTask().Forget();
return UniTask.CompletedTask;
}
}