예제 #1
0
        private async Task ReadLog(string logLink)
        {
            using var typing = Context.Channel.EnterTypingState();

            var logMatch = FFLogsUtils.LogLinkToIdRegex.Match(logLink);

            if (!logMatch.Success)
            {
                await ReplyAsync("That doesn't look like a log link!");

                return;
            }

            var logId = logMatch.Value;
            var req   = FFLogsUtils.BuildLogRequest(logId);
            var res   = (await FFLogsAPI.MakeGraphQLRequest <LogInfo>(req)).Content.Data.ReportInfo;

            if (res == null)
            {
                await ReplyAsync("That log is private; please make it unlisted or public.");

                return;
            }

            var encounters = res.Fights
                             .Where(f => f.Kill != null && f.FriendlyPlayers != null);
            var originalUsers = res.MasterData.Actors
                                .Where(a => a.Server != null)
                                .ToList();
            var members        = Context.Guild.Users;
            var potentialUsers = originalUsers.ToDictionary(a => a.Id, a => a)
                                 .Select(kvp => new KeyValuePair <int, PotentialDbUser>(kvp.Key, new PotentialDbUser
            {
                Name  = kvp.Value.Name,
                World = kvp.Value.Server,
                User  = Db.Users.FirstOrDefault(u => string.Equals(u.Name, kvp.Value.Name, StringComparison.InvariantCultureIgnoreCase) &&
                                                string.Equals(u.World, kvp.Value.Server, StringComparison.InvariantCultureIgnoreCase)),
            }))
                                 .Select(async kvp =>
            {
                var(id, potentialUser) = kvp;
                await RegisterUser(members, potentialUser);
                return(new KeyValuePair <int, DiscordXIVUser>(id, potentialUser.User));
            })
                                 .ToList();
            // We can't cleanly go from a KeyValuePair<int, Task<DiscordXIVUser>>
            // to a KeyValuePair<int, DiscordXIVUser>, so let's break it up into
            // multiple queries.
            var users = (await Task.WhenAll(potentialUsers))
                        .Where(kvp => kvp.Value != null)
                        .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);;
            var missedUsers = new List <LogInfo.ReportDataWrapper.ReportData.Report.Master.Actor>();

            var addedAny = false;

            foreach (var encounter in encounters)
            {
                var roleName = encounter.Name;
                if (roleName == "The Queen's Guard")
                {
                    roleName = "Queen's Guard";
                }
                roleName += " Progression";
                var role = Context.Guild.Roles.FirstOrDefault(r => r.Name == roleName);
                if (role == null)
                {
                    Log.Error("Role {RoleName} does not exist!", roleName);
                    continue;
                }

                var contingentRoles = DelubrumProgressionRoles.GetContingentRoles(role.Id)
                                      .Select(r => Context.Guild.GetRole(r))
                                      .ToList();

                var killRole = Context.Guild.GetRole(DelubrumProgressionRoles.GetKillRole(role.Name));

                foreach (var id in encounter.FriendlyPlayers)
                {
                    if (!users.ContainsKey(id))
                    {
                        var actor = originalUsers.Find(a => a.Id == id);
                        if (actor != null)
                        {
                            missedUsers.Add(actor);
                        }
                        continue;
                    }

                    var user = Context.Guild.GetUser(users[id].DiscordId);
                    if (user == null || user.HasRole(806362589134454805))
                    {
                        continue;
                    }

                    if (killRole.Id == 806362589134454805 && encounter.Kill == true)
                    {
                        addedAny = true;

                        // Remove all contingent roles (this is bodge and should be refactored)
                        foreach (var progRole in contingentRoles)
                        {
                            Log.Information("Checking role {RoleName} on user {User}", progRole.Name, user);
                            if (user.HasRole(progRole))
                            {
                                await user.RemoveRoleAsync(progRole);

                                Log.Information("Removed role {RoleName} from user {User}", progRole.Name, user);
                            }
                        }

                        // Give everyone the clear role if they cleared DRS
                        Log.Information("Checking role {RoleName} on user {User}", killRole.Name, user);
                        if (!user.HasRole(killRole))
                        {
                            await user.AddRoleAsync(killRole);

                            Log.Information("Added role {RoleName} to {User}", killRole.Name, user);
                        }
                    }
                    else
                    {
                        // Give all contingent roles as well as the clear role for the fight
                        foreach (var progRole in contingentRoles)
                        {
                            Log.Information("Checking role {RoleName} on user {User}", progRole.Name, user);
                            if (!user.HasRole(progRole))
                            {
                                addedAny = true;
                                await user.AddRoleAsync(progRole);

                                Log.Information("Added role {RoleName} to user {User}", progRole.Name, user);
                            }
                        }

                        if (encounter.Kill == true)
                        {
                            Log.Information("Checking role {RoleName} on user {User}", killRole.Name, user);
                            if (!user.HasRole(killRole))
                            {
                                addedAny = true;
                                await user.AddRoleAsync(killRole);

                                Log.Information("Added role {RoleName} to {User}", killRole.Name, user);
                            }
                        }
                    }
                }
            }

            if (addedAny)
            {
                await ReplyAsync("Roles added!");
            }
            else
            {
                await ReplyAsync("No roles to add.");
            }

            if (missedUsers.Any())
            {
                await ReplyAsync($"Missed users: ```{missedUsers.Select(a => $"({a.Server}) {a.Name}").Distinct().Aggregate("", (agg, next) => agg + $"{next}\n") + "```"}\nThey may need to re-register with `~iam`.");
            }
        }
예제 #2
0
        public async Task AddDelubrumProgRoleAsync([Remainder] string args)
        {
            var isFFLogs = FFLogsUtils.IsLogLink(args);

            Log.Information($"FFLogs link provided: {isFFLogs}");

            if (isFFLogs)
            {
                await ReadLog(args);

                return;
            }

            var executor = Context.Guild.GetUser(Context.User.Id);

            if (!executor.HasRole(DelubrumProgressionRoles.Executor, Context) &&
                !executor.HasRole(579916868035411968, Context) && // or Mentor
                !executor.GuildPermissions.KickMembers)    // or can kick users
            {
                Log.Information("User does not have roler role.");
                var res = await ReplyAsync($"{Context.User.Mention}, you don't have the roler role!");

                await Task.Delay(5000);

                await res.DeleteAsync();

                return;
            }

            var words = args.Split(' ');

            var members = words
                          .Where(w => w.StartsWith('<'))
                          .Select(idStr => RegexSearches.NonNumbers.Replace(idStr, ""))
                          .Select(ulong.Parse)
                          .Select(id => Context.Guild.GetUser(id) ?? (IGuildUser)Context.Client.Rest.GetGuildUserAsync(Context.Guild.Id, id).GetAwaiter().GetResult());

            var roleName = string.Join(' ', words.Where(w => !w.StartsWith('<')));

            roleName = RegexSearches.UnicodeApostrophe.Replace(roleName, "'");

            roleName = roleName.Trim();
            var role = Context.Guild.Roles.FirstOrDefault(r =>
                                                          string.Equals(r.Name.ToLowerInvariant(), roleName.ToLowerInvariant(), StringComparison.InvariantCultureIgnoreCase));

            if (role == null)
            {
                Log.Information("Role name invalid.");
                var res = await ReplyAsync($"{Context.User.Mention}, no role by that name exists! Make sure you spelled it correctly.");

                await Task.Delay(5000);

                await res.DeleteAsync();

                return;
            }

            if (!DelubrumProgressionRoles.Roles.Keys.Contains(role.Id))
            {
                Log.Information("Role key invalid.");
                return;
            }
            var contingentRoles = DelubrumProgressionRoles.GetContingentRoles(role.Id)
                                  .Select(Context.Guild.GetRole)
                                  .ToList();

            await Task.WhenAll(members
                               .Select(m =>
            {
                try
                {
                    return(m.AddRolesAsync(contingentRoles.Where(r => !m.MemberHasRole(r, Context))));
                }
                catch (Exception e)
                {
                    Log.Error(e, "Failed to add roles to user {User}.", m.ToString());
                    return(Task.CompletedTask);
                }
            }));

            await ReplyAsync("Roles added!");
        }