Example #1
0
    /// <summary>
    /// Updates the user's current nickname based on their character.
    /// </summary>
    /// <param name="guildID">The ID of the guild the user is on.</param>
    /// <param name="userID">The ID of the discord user.</param>
    /// <param name="ct">The cancellation token in use.</param>
    /// <returns>A modification result which may or may not have succeeded.</returns>
    private async Task <Result> UpdateUserNickname
    (
        Snowflake guildID,
        Snowflake userID,
        CancellationToken ct = default
    )
    {
        var getUser = await _users.GetOrRegisterUserAsync(userID, ct);

        if (!getUser.IsSuccess)
        {
            return(Result.FromError(getUser));
        }

        var getServer = await _servers.GetOrRegisterServerAsync(guildID, ct);

        if (!getServer.IsSuccess)
        {
            return(Result.FromError(getServer));
        }

        var user   = getUser.Entity;
        var server = getServer.Entity;

        var getMember = await _guildAPI.GetGuildMemberAsync(guildID, userID, ct);

        if (!getMember.IsSuccess)
        {
            return(Result.FromError(getMember));
        }

        var member = getMember.Entity;

        if (!member.User.IsDefined(out var discordUser))
        {
            throw new InvalidOperationException();
        }

        string newNick;
        var    getNewCharacter = await _characters.GetCurrentCharacterAsync(user, server, ct);

        if (getNewCharacter.IsSuccess)
        {
            var newCharacter = getNewCharacter.Entity;
            newNick = newCharacter.Nickname.IsNullOrWhitespace()
                ? discordUser.Username
                : newCharacter.Nickname;
        }
        else
        {
            newNick = member.User.Value.Username;
        }

        var modifyNickname = await _guildAPI.ModifyGuildMemberAsync(guildID, userID, newNick, ct : ct);

        if (modifyNickname.IsSuccess)
        {
            return(modifyNickname);
        }

        if (modifyNickname.Error is RestResultError <RestError> rre)
        {
            return(rre.Error.Code is not DiscordError.MissingPermission
                ? modifyNickname
                : Result.FromSuccess()); // squelch missing permission errors
        }

        if (modifyNickname.Error is not HttpResultError hre)
        {
            return(modifyNickname);
        }

        if (hre.StatusCode is not HttpStatusCode.Forbidden)
        {
            return(modifyNickname);
        }

        return(new UserError
               (
                   "I'm forbidden from setting the user's nickname - typically, this means the target was the " +
                   "server owner. This is a Discord limitation, and can't be fixed."
               ));
    }