113 lines
3.5 KiB
C#
113 lines
3.5 KiB
C#
using Newtonsoft.Json;
|
|
using System.Net;
|
|
using TaskFactory = Utils.TaskFactory;
|
|
|
|
namespace BiblioTech.Rewards
|
|
{
|
|
public interface IDiscordRoleController
|
|
{
|
|
Task GiveRewards(GiveRewardsCommand rewards);
|
|
}
|
|
|
|
public class RewardsApi
|
|
{
|
|
private readonly HttpListener listener = new HttpListener();
|
|
private readonly TaskFactory taskFactory = new TaskFactory();
|
|
private readonly IDiscordRoleController roleController;
|
|
private CancellationTokenSource cts = new CancellationTokenSource();
|
|
|
|
public RewardsApi(IDiscordRoleController roleController)
|
|
{
|
|
this.roleController = roleController;
|
|
}
|
|
|
|
public void Start()
|
|
{
|
|
cts = new CancellationTokenSource();
|
|
listener.Prefixes.Add($"http://*:31080/");
|
|
listener.Start();
|
|
taskFactory.Run(ConnectionDispatcher, nameof(ConnectionDispatcher));
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
listener.Stop();
|
|
cts.Cancel();
|
|
taskFactory.WaitAll();
|
|
}
|
|
|
|
private void ConnectionDispatcher()
|
|
{
|
|
while (!cts.Token.IsCancellationRequested)
|
|
{
|
|
var wait = listener.GetContextAsync();
|
|
wait.Wait(cts.Token);
|
|
if (wait.IsCompletedSuccessfully)
|
|
{
|
|
taskFactory.Run(() =>
|
|
{
|
|
var context = wait.Result;
|
|
try
|
|
{
|
|
HandleConnection(context).Wait();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Program.Log.Error("Exception during HTTP handler: " + ex);
|
|
}
|
|
// Whatever happens, everything's always OK.
|
|
context.Response.StatusCode = 200;
|
|
context.Response.OutputStream.Close();
|
|
}, nameof(HandleConnection));
|
|
}
|
|
}
|
|
}
|
|
|
|
private async Task HandleConnection(HttpListenerContext context)
|
|
{
|
|
using var reader = new StreamReader(context.Request.InputStream);
|
|
var content = reader.ReadToEnd();
|
|
|
|
if (content == "Ping")
|
|
{
|
|
using var writer = new StreamWriter(context.Response.OutputStream);
|
|
writer.Write("Pong");
|
|
return;
|
|
}
|
|
|
|
if (!content.StartsWith("{")) return;
|
|
var rewards = JsonConvert.DeserializeObject<GiveRewardsCommand>(content);
|
|
if (rewards != null)
|
|
{
|
|
AttachUsers(rewards);
|
|
await ProcessRewards(rewards);
|
|
}
|
|
}
|
|
|
|
private void AttachUsers(GiveRewardsCommand rewards)
|
|
{
|
|
foreach (var reward in rewards.Rewards)
|
|
{
|
|
reward.Users = reward.UserAddresses.Select(GetUserFromAddress).Where(u => u != null).Cast<UserData>().ToArray();
|
|
}
|
|
}
|
|
|
|
private UserData? GetUserFromAddress(string address)
|
|
{
|
|
try
|
|
{
|
|
return Program.UserRepo.GetUserDataForAddress(new GethPlugin.EthAddress(address));
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private async Task ProcessRewards(GiveRewardsCommand rewards)
|
|
{
|
|
await roleController.GiveRewards(rewards);
|
|
}
|
|
}
|
|
}
|