Exemplo n.º 1
0
        // ReSharper disable once UnusedMember.Global
        public async Task HandleColourSet([Summary("A full or shorthand hex code")]
                                          string hexCode = "help", string arg2 = "")
        {
            // TODO: add permissions check, feature independent
            // TODO: help commands, use subclasses?
            _logger.LogInformation("Handling colorme command call for user {User}", Context.User.ToString());

            if (hexCode == "help")
            {
                _logger.LogInformation("Sending help message for {User}", Context.User.ToString());
                await ReplyWithHelpMessageAsync();

                return;
            }

            var targetUserId = Context.User.Id;

            if (!string.IsNullOrWhiteSpace(arg2))
            {
                try
                {
                    var memberId   = Convert.ToUInt64(arg2);
                    var targetUser = Context.Guild.GetUser(memberId);
                    targetUserId = targetUser.Id;
                }
                catch (Exception ex)
                {
                    // TODO: clean up wording because other exceptions could throw
                    await ReplyAsync($"Unable to convert {arg2} to user ID");

                    _logger.LogWarning(ex, "Failed to convert an ID {Id} to ulong", arg2);
                    return;
                }

                if (!_administrationOptions.PermittedUserIds.Contains(Context.User.Id))
                {
                    await Context.Message.ReplyAsync("You don't have permission to do that!");

                    return;
                }
            }

            var generatedRoleName = RoleNameHelper.GetRoleNameFromUserId(targetUserId, _colorMeConfig.RolePrefix);

            _logger.LogInformation("Generated role name of {RoleName} for user {User}", generatedRoleName,
                                   Context.User.ToString());

            if (!HexColourHelper.TryGetColorFromHexString(hexCode, out var color))
            {
                _logger.LogWarning("User {User} entered invalid hex code {HexCode}", Context.User.ToString(), hexCode);
                await Context.Message.ReplyAsync($"Your hex code ``{hexCode}`` was invalid. Try something like #00FF00 or #abc");

                return;
            }

            _logger.LogInformation("Parsed hex code {HexCode} as RGB value ({R}, {G}, {B})", hexCode, color.R,
                                   color.G, color.B);

            // Set the colour of the role to the one specified by the user
            var roleColor = new Optional <Color>(new Color(color.R, color.G, color.B));

            // Attempt to resolve the role and create if it doesn't exist
            SocketRole?possibleResolvedRole;

            try
            {
                possibleResolvedRole = Context.Guild.Roles.SingleOrDefault(r => r.Name == generatedRoleName);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to fetch roles in guild {GuildId} due to " +
                                 "an unexpected error: {ExceptionMessage}", Context.Guild.Id, ex.Message);
                await Context.Message.ReplyAsync("Something went wrong when trying to find a role. Try this command again.");

                return;
            }

            if (possibleResolvedRole?.Color == roleColor.Value)
            {
                _logger.LogInformation("User {GuildUserId} already has the requested color {ColorHex}", targetUserId,
                                       hexCode);

                await Context.Message.ReplyAsync("You already have that color!");

                return;
            }

            _logger.LogInformation("Resolved role {RoleName} in guild {GuildId}", generatedRoleName, Context.Guild.Id);

            // Grab the user in the context of the guild
            // TODO: precache to prevent nulls
            var user = Context.Guild.GetUser(targetUserId);

            if (user == null)
            {
                _logger.LogError("Unable to find user with ID {UserId} in guild {GuildId}", targetUserId,
                                 Context.Guild.Id);
                await Context.Message.ReplyAsync("An error occured trying to find you in the guild user list. Try again or wait " +
                                                 "a minute for the list to complete");

                return;
            }

            // FIXME: this occasionally returns 0 when roles are present
            // Maybe lookup again after downloading guild stuff?
            var userTopRolePosition = user.Roles.Max(r => r.Position);

            _logger.LogInformation("Top role for GuildUser {GuildUserId} is at position {RolePosition}", user.Id,
                                   userTopRolePosition);

            IRole resolvedRole;

            try
            {
                resolvedRole = possibleResolvedRole ?? await CreateColorRoleAsync(Context.Guild, generatedRoleName);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to create a role in guild {GuildId} due to " +
                                 "an unexpected error: {ExceptionMessage}", Context.Guild.Id, ex.Message);
                await Context.Message.ReplyAsync("Something went wrong when trying to create your role. Try this command again.");

                return;
            }

            try {
                await resolvedRole.ModifyAsync(props =>
                {
                    props.Color       = roleColor;
                    props.Hoist       = false;
                    props.Mentionable = false;
                    props.Position    = userTopRolePosition + 1;
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to modify a role with ID {RoleId} in guild {GuildId} due to " +
                                 "an unexpected error: {ExceptionMessage}", resolvedRole.Id, Context.Guild.Id,
                                 ex.Message);
                await Context.Message.ReplyAsync("Something went wrong when trying to update your role. Try this command again.");

                return;
            }

            _logger.LogInformation("Updated color and role position for role {RoleName}", generatedRoleName);

            if (user.Roles.All(r => r.Name != resolvedRole.Name))
            {
                _logger.LogInformation("Adding role {RoleName} to user {UserID}", generatedRoleName, user.Id);

                try {
                    await user.AddRoleAsync(resolvedRole);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Failed to add role with ID {RoleId} to user {UserId} in guild {GuildId} due to " +
                                     "an unexpected error: {ExceptionMessage}", resolvedRole.Id, targetUserId,
                                     Context.Guild.Id, ex.Message);
                    await Context.Message.ReplyAsync("Something went wrong when trying to add your role. Try this command again.\n" +
                                                     $"If this issue persists then ask a mod to add you to this role: `{generatedRoleName}`");

                    return;
                }
            }

            try {
                await Context.Message.AddReactionAsync(new Emoji("\uD83D\uDC4D"));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to add reaction to message with with ID {MessageId}  in guild {GuildId} due to " +
                                 "an unexpected error: {ExceptionMessage}",
                                 Context.Message.Id, targetUserId, ex.Message);
                await Context.Message.ReplyAsync("You're now colorful!");

                return;
            }

            _logger.LogInformation("Successfully handled colorme command for user {User}", user.ToString());
        }
Exemplo n.º 2
0
        // ReSharper disable once UnusedMember.Global
        public async Task HandleColourRemove(string?subCommand = null)
        {
            _logger.LogInformation("Handling uncolorme command call for user {User}", Context.User.ToString());

            if (subCommand == "help")
            {
                _logger.LogInformation("Sending help message for {User}", Context.User.ToString());
                await ReplyWithHelpMessageAsync();

                return;
            }

            var generatedRoleName = RoleNameHelper.GetRoleNameFromUserId(Context.User.Id, _colorMeConfig.RolePrefix);

            _logger.LogInformation("Generated role name of {RoleName} for user {User}", generatedRoleName,
                                   Context.User.ToString());

            SocketRole?resolvedRole;

            try
            {
                resolvedRole = Context.Guild.Roles.SingleOrDefault(r => r.Name == generatedRoleName);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to get roles in guild {GuildId} due to " +
                                 "an unexpected error: {ExceptionMessage}", Context.Guild.Id, ex.Message);
                await Context.Message.ReplyAsync("Something went wrong when trying to update your role. Try this command again.");

                return;
            }

            if (resolvedRole == null)
            {
                _logger.LogWarning("User {User} did not have the role {RoleName} assigned to them",
                                   Context.User.ToString(), generatedRoleName);
                await Context.Message.ReplyAsync("You don't have a color; I can't remove something that doesn't exist!");

                return;
            }

            _logger.LogInformation("Deleting role {RoleName} for user {User}", generatedRoleName,
                                   Context.User.ToString());

            try {
                await resolvedRole.DeleteAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to delete a role with ID {RoleId} in guild {GuildId} due to " +
                                 "an unexpected error: {ExceptionMessage}",
                                 resolvedRole.Id, Context.Guild.Id, ex.Message);
                await Context.Message.ReplyAsync("Something went wrong when trying to update your role. Try this command again.");

                return;
            }

            _logger.LogInformation("Role {RoleName} deleted!", generatedRoleName);

            try {
                await Context.Message.AddReactionAsync(new Emoji("\uD83D\uDC4D"));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to add reaction to message with with ID {MessageId}  in guild {GuildId} due to " +
                                 "an unexpected error: {ExceptionMessage}",
                                 Context.Message.Id, Context.User.Id, ex.Message);
                await Context.Message.ReplyAsync("You're no longer colorful!");
            }
        }