Exemple #1
0
    public async Task Verify([Remainder] string query)
    {
        using var setTyping = Context.Channel.EnterTypingState();

        var criteria = new VerifyCharacterCriteria()
        {
            Query   = query,
            GuildId = Context.Guild.Id,
            UserId  = Context.User.Id,
            Name    = Context.User.Username
        };

        var result = await _verifyCharacterManager.Process(criteria);

        switch (result.Status)
        {
        case Status.Verified:
            await Task.WhenAll(
                ReplyAsync($"Using Lodestone, I have verified you as a member of the **{result.FreeCompanyName}** Free Company, {result.Name}."),
                SetPermissions(result),
                SetUserName(result)
                );
            await ReplyAsync("Welcome to our Discord server! If you have any questions, please don't hesitate to ask.");

            return;

        case Status.NotVerified:
            await Task.WhenAll(
                ReplyAsync($"According to Lodestone, it appears that you are not a part of the {result.FreeCompanyName}. If you just joined the free company, it usually takes a day to update on Lodestone."),
                NotifyAdmin($"{Context.User.Mention} failed verification with '{query}'.")
                );

            return;

        case Status.CharacterAlreadyVerified:
            if (result.VerifiedUserId == Context.User.Id)
            {
                await ReplyAsync($"You've already been verified as {result.Name}! If you need help, please contact {Context.Guild.Owner.Mention}.");

                return;
            }

            await Task.WhenAll(
                ReplyAsync($"That character has already been associated with another user. I will notify the server's administrator."),
                NotifyAdmin($"{Context.User.Mention} tried verification with '{query}', but I've found that this character has already been associated with user <@{result.VerifiedUserId}>.")
                );

            return;

        case Status.FreeCompanyUndefined:
        default:
            await Task.WhenAll(
                ReplyAsync("It appears that this server is not set up to do character verification. I will notify the server's administrator."),
                NotifyAdmin($"A user used the verification command in your server but I'm not set up for it. Please use the `set` command, e.g. `{await GetPrefix()}set verify VerifiedRoleName FreeCompanyName` in your server.")
                );

            return;
        }
    }
    public async Task <VerifyCharacterResult> VerifyCharacter([FromBody] VerifyCharacterCriteria criteria)
    {
        var result = await _verifyCharacterManager.Process(criteria);

        if (result.Status != Status.Verified)
        {
            Response.StatusCode = (int)HttpStatusCode.BadRequest;
        }

        return(result);
    }
    public async Task <VerifyCharacterResult> Process(VerifyCharacterCriteria criteria)
    {
        _verifyCharacterValidator.ValidateAndThrow(criteria);

        // Get the guild options for free company definition.
        _logger.LogTrace("Getting guild options for guild {Id}.", criteria.GuildId);

        var guildOptionsQuery = new GetOptionsQuery()
        {
            GuildId = criteria.GuildId
        };

        var guildOptions = await _guildAccessor.GetOptions(guildOptionsQuery);

        if (guildOptions?.FreeCompany is null || guildOptions.VerifiedRoleId == 0)
        {
            _logger.LogDebug("Free Company options not defined for guild {Id}.", criteria.GuildId);

            return(new VerifyCharacterResult()
            {
                Status = Status.FreeCompanyUndefined
            });
        }

        var result = new VerifyCharacterResult()
        {
            FreeCompanyName = guildOptions.FreeCompany.Name,
            VerifiedRoleId  = guildOptions.VerifiedRoleId
        };

        // Parse the query into name/server.
        _logger.LogTrace("Parsing query: {Query}.", criteria.Query);

        var(name, _) = NameServerEngine.Parse(criteria.Query);

        // Search for the character.
        _logger.LogTrace("Searching for {CharacterName} on {ServerName}.", name, guildOptions.FreeCompany.Server);

        var searchQuery = new SearchCharacterQuery()
        {
            Name   = name,
            Server = guildOptions.FreeCompany.Server
        };

        var searchData = await _xivApiAccessor.SearchCharacter(searchQuery);

        var characterId = searchData.Results?.FirstOrDefault()?.Id;

        _logger.LogDebug("Got character Id {Id}.", characterId);

        if (characterId is null)
        {
            result.Status = Status.NotVerified;
            result.Name   = searchData.Results?.FirstOrDefault()?.Name;
            return(result);
        }

        // Check if character is already attached to a user.
        _logger.LogTrace("Checking database if {CharacterName} has already been tied to a user. CharacterId: {CharacterId}", name, characterId);

        var checkQuery = new SearchUserQuery()
        {
            CharacterId = characterId.Value
        };

        var user = await _userAccessor.SearchUser(checkQuery);

        if (user is object)
        {
            _logger.LogDebug("{CharacterName} ({CharacterId}) has already been tied to UserId {UserId}.", name, characterId, user.Id);
            result.Status         = Status.CharacterAlreadyVerified;
            result.Name           = searchData.Results?.FirstOrDefault()?.Name;
            result.VerifiedUserId = user.Id;
            return(result);
        }

        // Get the character.
        _logger.LogTrace("Getting character with Id {Id}.", characterId);

        var getQuery = new GetCharacterQuery()
        {
            Id = characterId.Value
        };

        var getData = await _xivApiAccessor.GetCharacter(getQuery);

        var characterFcId = getData?.Character?.FreeCompanyId;

        _logger.LogDebug("Got character Free Company Id {FcId}.", characterFcId);

        result.Name = getData?.Character?.Name;

        if (characterFcId != guildOptions.FreeCompany.Id)
        {
            result.Status = Status.NotVerified;
            _logger.LogDebug("{Name} failed verification. Character FC: {CFcId}. Guild FC: {FcId}", result.Name, characterFcId, guildOptions.FreeCompany.Id);
            return(result);
        }

        result.Status         = Status.Verified;
        result.VerifiedUserId = criteria.UserId;
        _logger.LogDebug("{Name} has been verified with Free Company Id {FcId}.", result.Name, guildOptions.FreeCompany.Id);

        // Save character-user map to database.
        _logger.LogDebug("Saving {Name} to database with User Id {UserId}.", result.Name, criteria.UserId);

        var dataUser = await _userAccessor.GetUser(criteria.UserId) ?? new()
        {
            Id = criteria.UserId
        };
        var mergedUser = dataUser.Merge(characterId.Value);

        mergedUser.Name = criteria.Name;
        mergedUser.Nicknames[criteria.GuildId] = result.Name ?? "";

        await _userAccessor.SaveUser(mergedUser);

        return(result);
    }
}