diff --git a/Tools/BiblioTech/Rewards/RewardContext.cs b/Tools/BiblioTech/Rewards/RewardContext.cs new file mode 100644 index 0000000..d05d5f6 --- /dev/null +++ b/Tools/BiblioTech/Rewards/RewardContext.cs @@ -0,0 +1,102 @@ +using Discord.WebSocket; +using Discord; +using DiscordRewards; + +namespace BiblioTech.Rewards +{ + public class RewardContext + { + private readonly Dictionary users; + private readonly Dictionary roles; + private readonly SocketTextChannel? rewardsChannel; + + public RewardContext(Dictionary users, Dictionary roles, SocketTextChannel? rewardsChannel) + { + this.users = users; + this.roles = roles; + this.rewardsChannel = rewardsChannel; + } + + public async Task ProcessGiveRewardsCommand(UserReward[] rewards) + { + foreach (var rewardCommand in rewards) + { + if (roles.ContainsKey(rewardCommand.RewardCommand.RewardId)) + { + var role = roles[rewardCommand.RewardCommand.RewardId]; + await ProcessRewardCommand(role, rewardCommand); + } + else + { + Program.Log.Error($"RoleID not found on guild: {rewardCommand.RewardCommand.RewardId}"); + } + } + } + + private async Task ProcessRewardCommand(RoleReward role, UserReward reward) + { + foreach (var user in reward.Users) + { + await GiveReward(role, user); + } + } + + private async Task GiveReward(RoleReward role, UserData user) + { + if (!users.ContainsKey(user.DiscordId)) + { + Program.Log.Log($"User by id '{user.DiscordId}' not found."); + return; + } + + var guildUser = users[user.DiscordId]; + + var alreadyHas = guildUser.RoleIds.ToArray(); + var logMessage = $"Giving reward '{role.SocketRole.Id}' to user '{user.DiscordId}'({user.Name})[" + + $"alreadyHas:{string.Join(",", alreadyHas.Select(a => a.ToString()))}]: "; + + + if (alreadyHas.Any(r => r == role.Reward.RoleId)) + { + logMessage += "Already has role"; + Program.Log.Log(logMessage); + return; + } + + await GiveRole(guildUser, role.SocketRole); + await SendNotification(role, user, guildUser); + await Task.Delay(1000); + logMessage += "Role given. Notification sent."; + Program.Log.Log(logMessage); + } + + private async Task GiveRole(IGuildUser user, SocketRole role) + { + try + { + Program.Log.Log($"Giving role {role.Name}={role.Id} to user {user.DisplayName}"); + await user.AddRoleAsync(role); + } + catch (Exception ex) + { + Program.Log.Error($"Failed to give role '{role.Name}' to user '{user.DisplayName}': {ex}"); + } + } + + private async Task SendNotification(RoleReward reward, UserData userData, IGuildUser user) + { + try + { + if (userData.NotificationsEnabled && rewardsChannel != null) + { + var msg = reward.Reward.Message.Replace(RewardConfig.UsernameTag, $"<@{user.Id}>"); + await rewardsChannel.SendMessageAsync(msg); + } + } + catch (Exception ex) + { + Program.Log.Error($"Failed to notify user '{user.DisplayName}' about role '{reward.SocketRole.Name}': {ex}"); + } + } + } +} diff --git a/Tools/BiblioTech/Rewards/RoleDriver.cs b/Tools/BiblioTech/Rewards/RoleDriver.cs index 2478f52..182dbf8 100644 --- a/Tools/BiblioTech/Rewards/RoleDriver.cs +++ b/Tools/BiblioTech/Rewards/RoleDriver.cs @@ -1,6 +1,7 @@ using Discord; using Discord.WebSocket; using DiscordRewards; +using Newtonsoft.Json; namespace BiblioTech.Rewards { @@ -22,6 +23,8 @@ namespace BiblioTech.Rewards public async Task GiveRewards(GiveRewardsCommand rewards) { + Program.Log.Log($"Processing rewards command: '{JsonConvert.SerializeObject(rewards)}'"); + var guild = GetGuild(); // We load all role and user information first, // so we don't ask the server for the same info multiple times. @@ -35,6 +38,7 @@ namespace BiblioTech.Rewards private async Task> LoadAllUsers(SocketGuild guild) { + Program.Log.Log("Loading all users:"); var result = new Dictionary(); var users = guild.GetUsersAsync(); await foreach (var ulist in users) @@ -42,6 +46,8 @@ namespace BiblioTech.Rewards foreach (var u in ulist) { result.Add(u.Id, u); + var roleIds = string.Join(",", u.RoleIds.Select(r => r.ToString()).ToArray()); + Program.Log.Log($" > {u.Id}({u.DisplayName}) has [{roleIds}]"); } } return result; @@ -96,7 +102,10 @@ namespace BiblioTech.Rewards { try { - return Program.UserRepo.GetUserDataForAddress(new GethPlugin.EthAddress(address)); + var userData = Program.UserRepo.GetUserDataForAddress(new GethPlugin.EthAddress(address)); + if (userData != null) Program.Log.Log($"User '{userData.Name}' was looked up."); + else Program.Log.Log($"Lookup for user was unsuccessful. EthAddress: '{address}'"); + return userData; } catch (Exception ex) { @@ -140,85 +149,4 @@ namespace BiblioTech.Rewards public RewardUsersCommand RewardCommand { get; } public UserData[] Users { get; } } - - public class RewardContext - { - private readonly Dictionary users; - private readonly Dictionary roles; - private readonly SocketTextChannel? rewardsChannel; - - public RewardContext(Dictionary users, Dictionary roles, SocketTextChannel? rewardsChannel) - { - this.users = users; - this.roles = roles; - this.rewardsChannel = rewardsChannel; - } - - public async Task ProcessGiveRewardsCommand(UserReward[] rewards) - { - foreach (var rewardCommand in rewards) - { - if (roles.ContainsKey(rewardCommand.RewardCommand.RewardId)) - { - var role = roles[rewardCommand.RewardCommand.RewardId]; - await ProcessRewardCommand(role, rewardCommand); - } - } - } - - private async Task ProcessRewardCommand(RoleReward role, UserReward reward) - { - foreach (var user in reward.Users) - { - await GiveReward(role, user); - } - } - - private async Task GiveReward(RoleReward role, UserData user) - { - if (!users.ContainsKey(user.DiscordId)) - { - Program.Log.Log($"User by id '{user.DiscordId}' not found."); - return; - } - - var guildUser = users[user.DiscordId]; - - var alreadyHas = guildUser.RoleIds.ToArray(); - if (alreadyHas.Any(r => r == role.Reward.RoleId)) return; - - await GiveRole(guildUser, role.SocketRole); - await SendNotification(role, user, guildUser); - await Task.Delay(1000); - } - - private async Task GiveRole(IGuildUser user, SocketRole role) - { - try - { - Program.Log.Log($"Giving role {role.Name}={role.Id} to user {user.DisplayName}"); - await user.AddRoleAsync(role); - } - catch (Exception ex) - { - Program.Log.Error($"Failed to give role '{role.Name}' to user '{user.DisplayName}': {ex}"); - } - } - - private async Task SendNotification(RoleReward reward, UserData userData, IGuildUser user) - { - try - { - if (userData.NotificationsEnabled && rewardsChannel != null) - { - var msg = reward.Reward.Message.Replace(RewardConfig.UsernameTag, $"<@{user.Id}>"); - await rewardsChannel.SendMessageAsync(msg); - } - } - catch (Exception ex) - { - Program.Log.Error($"Failed to notify user '{user.DisplayName}' about role '{reward.SocketRole.Name}': {ex}"); - } - } - } }