mirror of
https://github.com/logos-storage/logos-storage-nim-cs-dist-tests.git
synced 2026-01-07 16:03:07 +00:00
135 lines
4.2 KiB
C#
135 lines
4.2 KiB
C#
using Discord;
|
|
using DiscordRewards;
|
|
using Logging;
|
|
|
|
namespace BiblioTech.Rewards
|
|
{
|
|
public class ChainActivityHandler
|
|
{
|
|
private readonly ILog log;
|
|
private readonly UserRepo repo;
|
|
private ActiveUserIds? previousIds = null;
|
|
|
|
public ChainActivityHandler(ILog log, UserRepo repo)
|
|
{
|
|
this.log = log;
|
|
this.repo = repo;
|
|
}
|
|
|
|
public async Task ProcessChainActivity(ActiveChainAddresses activeChainAddresses)
|
|
{
|
|
var activeUserIds = ConvertToUserIds(activeChainAddresses);
|
|
if (!HasChanged(activeUserIds)) return;
|
|
|
|
await GiveAndRemoveRoles(activeUserIds);
|
|
}
|
|
|
|
private async Task GiveAndRemoveRoles(ActiveUserIds activeUserIds)
|
|
{
|
|
await Program.RoleDriver.IterateUsersWithRoles(
|
|
(g, u, r) => OnUserWithRole(g, u, r, activeUserIds),
|
|
whenDone: g => GiveRolesToRemaining(g, activeUserIds),
|
|
Program.Config.ActiveClientRoleId,
|
|
Program.Config.ActiveHostRoleId);
|
|
}
|
|
|
|
private async Task OnUserWithRole(IRoleGiver giver, IUser user, ulong roleId, ActiveUserIds activeIds)
|
|
{
|
|
if (roleId == Program.Config.ActiveClientRoleId)
|
|
{
|
|
await CheckUserWithRole(user, activeIds.Clients, giver.RemoveActiveClient);
|
|
}
|
|
else if (roleId == Program.Config.ActiveHostRoleId)
|
|
{
|
|
await CheckUserWithRole(user, activeIds.Hosts, giver.RemoveActiveHost);
|
|
}
|
|
else
|
|
{
|
|
throw new Exception("Unknown roleId received!");
|
|
}
|
|
}
|
|
|
|
private async Task CheckUserWithRole(IUser user, List<ulong> activeUsers, Func<ulong, Task> removeActiveRole)
|
|
{
|
|
if (ShouldUserHaveRole(user, activeUsers))
|
|
{
|
|
activeUsers.Remove(user.Id);
|
|
}
|
|
else
|
|
{
|
|
await removeActiveRole(user.Id);
|
|
}
|
|
}
|
|
|
|
private bool ShouldUserHaveRole(IUser user, List<ulong> activeUsers)
|
|
{
|
|
return activeUsers.Any(id => id == user.Id);
|
|
}
|
|
|
|
private async Task GiveRolesToRemaining(IRoleGiver giver, ActiveUserIds ids)
|
|
{
|
|
foreach (var client in ids.Clients) await giver.GiveActiveClient(client);
|
|
foreach (var host in ids.Hosts) await giver.GiveActiveHost(host);
|
|
}
|
|
|
|
private bool HasChanged(ActiveUserIds activeUserIds)
|
|
{
|
|
if (previousIds == null)
|
|
{
|
|
previousIds = activeUserIds;
|
|
return true;
|
|
}
|
|
|
|
if (!IsEquivalent(previousIds.Hosts, activeUserIds.Hosts)) return true;
|
|
if (!IsEquivalent(previousIds.Clients, activeUserIds.Clients)) return true;
|
|
return false;
|
|
}
|
|
|
|
private static bool IsEquivalent(IEnumerable<ulong> a, IEnumerable<ulong> b)
|
|
{
|
|
return a.SequenceEqual(b);
|
|
}
|
|
|
|
private ActiveUserIds ConvertToUserIds(ActiveChainAddresses activeChainAddresses)
|
|
{
|
|
return new ActiveUserIds
|
|
(
|
|
hosts: Map(activeChainAddresses.Hosts),
|
|
clients: Map(activeChainAddresses.Clients)
|
|
);
|
|
}
|
|
|
|
private ulong[] Map(string[] ethAddresses)
|
|
{
|
|
var result = new List<ulong>();
|
|
foreach (var ethAddress in ethAddresses)
|
|
{
|
|
var userMaybe = repo.GetUserDataForAddressMaybe(new Utils.EthAddress(ethAddress));
|
|
if (userMaybe != null)
|
|
{
|
|
result.Add(userMaybe.DiscordId);
|
|
}
|
|
}
|
|
|
|
return result.Order().ToArray();
|
|
}
|
|
|
|
private void Log(string msg)
|
|
{
|
|
log.Log(msg);
|
|
}
|
|
|
|
private class ActiveUserIds
|
|
{
|
|
public ActiveUserIds(IEnumerable<ulong> hosts, IEnumerable<ulong> clients)
|
|
{
|
|
Hosts = hosts.ToList();
|
|
Clients = clients.ToList();
|
|
}
|
|
|
|
public List<ulong> Hosts { get; }
|
|
public List<ulong> Clients { get; }
|
|
}
|
|
}
|
|
}
|