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); } }