diff --git a/DiscordBot/CommandHandlers/ModalHandler.cs b/DiscordBot/CommandHandlers/ModalHandler.cs index bbb384f..106adc1 100644 --- a/DiscordBot/CommandHandlers/ModalHandler.cs +++ b/DiscordBot/CommandHandlers/ModalHandler.cs @@ -65,6 +65,7 @@ namespace DiscordBot.CommandHandlers roleId = roleId }; await _httpService.SignUp(signUpExternal); + await modal.RespondAsync($"signed up {userName}", ephemeral: true); break; } } diff --git a/DiscordBot/CommandHandlers/SlashCommandHandler.cs b/DiscordBot/CommandHandlers/SlashCommandHandler.cs index 7abb167..a948178 100644 --- a/DiscordBot/CommandHandlers/SlashCommandHandler.cs +++ b/DiscordBot/CommandHandlers/SlashCommandHandler.cs @@ -97,6 +97,12 @@ namespace DiscordBot.CommandHandlers List roles = await _httpService.GetRoles(raidId, user.Id); if(await _httpService.DoesUserExist(user.Id)) { + Tuple signUpAllowed = await _httpService.IsSignUpAllowed(raidId, user.Id, true); + if(!signUpAllowed.Item1) + { + await command.RespondAsync(signUpAllowed.Item2, ephemeral: true); + return; + } await command.RespondAsync("Please choose a role.", components: SignUpMessage.buildMessage(roles, raidId, Constants.ComponentIds.SIGN_UP_BUTTON, false, user.Id) , ephemeral: true); } else @@ -117,6 +123,13 @@ namespace DiscordBot.CommandHandlers private async Task SignUpExternalUser(SocketSlashCommand command, int raidId, List roles) { + Tuple signUpAllowed = await _httpService.IsExternalSignUpAllowed(raidId); + if(!signUpAllowed.Item1) + { + await command.RespondAsync(signUpAllowed.Item2, ephemeral: true); + return; + } + var signUpSelect = new SelectMenuBuilder() .WithPlaceholder("Select an option") .WithCustomId($"{Constants.ComponentIds.SIGN_UP_EXTERNAL_DROP_DOWN}-{raidId}") diff --git a/DiscordBot/Services/HttpService.cs b/DiscordBot/Services/HttpService.cs index cf98c95..e1a72d9 100644 --- a/DiscordBot/Services/HttpService.cs +++ b/DiscordBot/Services/HttpService.cs @@ -37,11 +37,26 @@ namespace DiscordBot.Services return false; } - public async Task> IsSignUpAllowed(int raidId, ulong userId) + public async Task> IsSignUpAllowed(int raidId, ulong userId, bool ignoreRole = false) { var httpClient = _httpClientFactory.CreateClient(Constants.HTTP_CLIENT_NAME); - var httpResponseMessage = await httpClient.GetAsync($"DiscordBot/IsSignUpAllowed/{raidId}/{userId}"); + var httpResponseMessage = await httpClient.GetAsync($"DiscordBot/IsSignUpAllowed/{raidId}/{userId}/{ignoreRole}"); + + if (!httpResponseMessage.IsSuccessStatusCode) + { + ProblemDetails problemDetails = await httpResponseMessage.Content.ReadFromJsonAsync(_serializerOptions) ?? new ProblemDetails(); + string errorMessage = string.IsNullOrEmpty(problemDetails.Detail) ? string.Empty : problemDetails.Detail; + return new Tuple(false, errorMessage); + } + return new Tuple(true, string.Empty); + } + + public async Task> IsExternalSignUpAllowed(int raidId) + { + var httpClient = _httpClientFactory.CreateClient(Constants.HTTP_CLIENT_NAME); + + var httpResponseMessage = await httpClient.GetAsync($"DiscordBot/IsExternalSignUpAllowed/{raidId}"); if (!httpResponseMessage.IsSuccessStatusCode) { diff --git a/Lieb/Controllers/DiscordBotController.cs b/Lieb/Controllers/DiscordBotController.cs index 0f93490..3badc73 100644 --- a/Lieb/Controllers/DiscordBotController.cs +++ b/Lieb/Controllers/DiscordBotController.cs @@ -35,10 +35,21 @@ namespace Lieb.Controllers } [HttpGet] - [Route("[action]/{raidId}/{userId}")] - public ActionResult IsSignUpAllowed(int raidId, ulong userId) + [Route("[action]/{raidId}/{userId}/{ignoreRole}")] + public ActionResult IsSignUpAllowed(int raidId, ulong userId, bool ignoreRole) { - if(!_raidService.IsRaidSignUpAllowed(userId, raidId, out string errorMessage)) + if(!_raidService.IsRaidSignUpAllowed(userId, raidId, out string errorMessage, ignoreRole)) + { + return Problem(errorMessage); + } + return Ok(); + } + + [HttpGet] + [Route("[action]/{raidId}")] + public ActionResult IsExternalSignUpAllowed(int raidId) + { + if(!_raidService.IsExternalSignUpAllowed(raidId, out string errorMessage)) { return Problem(errorMessage); } diff --git a/Lieb/Data/DbInitializer.cs b/Lieb/Data/DbInitializer.cs index 5d9b3ba..2ee24a9 100644 --- a/Lieb/Data/DbInitializer.cs +++ b/Lieb/Data/DbInitializer.cs @@ -159,11 +159,11 @@ namespace Lieb.Data var signUps = new RaidSignUp[] { - new RaidSignUp{GuildWars2AccountId = linaith.GuildWars2AccountId, LiebUserId = users[0].Id, RaidRoleId = ele.RaidRoleId, RaidId = raid.RaidId, SignUpType = SignUpType.SignedUp }, - new RaidSignUp{GuildWars2AccountId = hierpiepts.GuildWars2AccountId, LiebUserId = users[1].Id, RaidRoleId = flexTest1.RaidRoleId, RaidId = raid.RaidId, SignUpType = SignUpType.SignedUp }, - new RaidSignUp{GuildWars2AccountId = bloodseeker.GuildWars2AccountId, LiebUserId = users[2].Id, RaidRoleId = flexTest2.RaidRoleId, RaidId = raid.RaidId, SignUpType = SignUpType.SignedUp }, - new RaidSignUp{GuildWars2AccountId = hierpiepts.GuildWars2AccountId, LiebUserId = users[1].Id, RaidRoleId = flexTest2.RaidRoleId, RaidId = raid.RaidId, SignUpType = SignUpType.Flex }, - new RaidSignUp{GuildWars2AccountId = bloodseeker.GuildWars2AccountId, LiebUserId = users[2].Id, RaidRoleId = flexTest3.RaidRoleId, RaidId = raid.RaidId, SignUpType = SignUpType.Flex } + new RaidSignUp(raid.RaidId, users[0].Id, linaith.GuildWars2AccountId, ele.RaidRoleId, SignUpType.SignedUp), + new RaidSignUp(raid.RaidId, users[1].Id, hierpiepts.GuildWars2AccountId, flexTest1.RaidRoleId, SignUpType.SignedUp), + new RaidSignUp(raid.RaidId, users[2].Id, bloodseeker.GuildWars2AccountId, flexTest2.RaidRoleId, SignUpType.SignedUp), + new RaidSignUp(raid.RaidId, users[1].Id, hierpiepts.GuildWars2AccountId, flexTest2.RaidRoleId, SignUpType.Flex), + new RaidSignUp(raid.RaidId, users[2].Id, bloodseeker.GuildWars2AccountId, flexTest3.RaidRoleId, SignUpType.Flex) }; context.RaidSignUps.AddRange(signUps); diff --git a/Lieb/Data/DiscordService.cs b/Lieb/Data/DiscordService.cs index 3808383..1267ff1 100644 --- a/Lieb/Data/DiscordService.cs +++ b/Lieb/Data/DiscordService.cs @@ -240,7 +240,7 @@ namespace Lieb.Data AccountName = signUp.GuildWars2Account.AccountName, Status = status, UserName = signUp.LiebUser.Name, - UserId = signUp.LiebUserId + UserId = signUp.LiebUserId.Value }); } } @@ -274,9 +274,9 @@ namespace Lieb.Data apiReminder.UserIds = new List(); foreach(RaidSignUp signUp in raid.SignUps) { - if(signUp.LiebUserId > 0) + if(signUp.LiebUserId.HasValue) { - apiReminder.UserIds.Add(signUp.LiebUserId); + apiReminder.UserIds.Add(signUp.LiebUserId.Value); } } return apiReminder; diff --git a/Lieb/Data/RaidRandomizerService.cs b/Lieb/Data/RaidRandomizerService.cs index 5461747..190f39f 100644 --- a/Lieb/Data/RaidRandomizerService.cs +++ b/Lieb/Data/RaidRandomizerService.cs @@ -104,9 +104,9 @@ namespace Lieb.Data Dictionary signedUpUsers= new Dictionary(); foreach (RaidSignUp signUp in raid.SignUps) { - if (signUp.GuildWars2Account.EquippedBuilds.Count > 0) + if (!signUp.IsExternalUser && signUp.GuildWars2Account.EquippedBuilds.Count > 0) { - signedUpUsers.Add(signUp.LiebUserId, signUp.GuildWars2Account.EquippedBuilds.ToList()[_random.Next(signUp.GuildWars2Account.EquippedBuilds.Count - 1)].GuildWars2Build); + signedUpUsers.Add(signUp.LiebUserId.Value, signUp.GuildWars2Account.EquippedBuilds.ToList()[_random.Next(signUp.GuildWars2Account.EquippedBuilds.Count - 1)].GuildWars2Build); } } BalanceRoles(raid, signedUpUsers); diff --git a/Lieb/Data/RaidService.cs b/Lieb/Data/RaidService.cs index 361313f..971f180 100644 --- a/Lieb/Data/RaidService.cs +++ b/Lieb/Data/RaidService.cs @@ -117,14 +117,7 @@ namespace Lieb.Data } else if (!signUps.Where(r => r.RaidRoleId == plannedRoleId).Any()) { - RaidSignUp signUp = new RaidSignUp() - { - GuildWars2AccountId = guildWars2AccountId, - RaidId = raidId, - LiebUserId = liebUserId, - RaidRoleId = plannedRoleId, - SignUpType = signUpType - }; + RaidSignUp signUp = new RaidSignUp(raidId, liebUserId, guildWars2AccountId, plannedRoleId, signUpType); string userName = context.LiebUsers.FirstOrDefault(l => l.Id == liebUserId)?.Name; context.RaidSignUps.Add(signUp); await context.SaveChangesAsync(); @@ -142,13 +135,7 @@ namespace Lieb.Data using var context = _contextFactory.CreateDbContext(); - RaidSignUp signUp = new RaidSignUp() - { - RaidId = raidId, - ExternalUserName = userName, - RaidRoleId = plannedRoleId, - SignUpType = signUpType - }; + RaidSignUp signUp = new RaidSignUp(raidId, userName, plannedRoleId, signUpType); context.RaidSignUps.Add(signUp); await context.SaveChangesAsync(); await LogSignUp(signUp, userName, signedUpByUserId); @@ -235,7 +222,14 @@ namespace Lieb.Data { signUp.RaidRoleId = plannedRoleId; signUp.SignUpType = signUpType; - await LogSignUp(signUp, signUp.LiebUser.Name); + if(signUp.IsExternalUser) + { + await LogSignUp(signUp, signUp.ExternalUserName); + } + else + { + await LogSignUp(signUp, signUp.LiebUser.Name); + } } context.SaveChanges(); if(postChanges) @@ -337,7 +331,7 @@ namespace Lieb.Data return false; } - public bool IsRaidSignUpAllowed(ulong liebUserId, int raidId, out string errorMessage) + public bool IsRaidSignUpAllowed(ulong liebUserId, int raidId, out string errorMessage, bool ignoreRole = false) { errorMessage = string.Empty; using var context = _contextFactory.CreateDbContext(); @@ -374,7 +368,7 @@ namespace Lieb.Data return false; } - if (!string.IsNullOrEmpty(raid.RequiredRole) + if (!ignoreRole && !string.IsNullOrEmpty(raid.RequiredRole) && !user.RoleAssignments.Where(a => a.LiebRole.RoleName == raid.RequiredRole).Any() && raid.FreeForAllTimeUTC.UtcDateTime > DateTimeOffset.UtcNow) { @@ -392,9 +386,37 @@ namespace Lieb.Data return true; } + public bool IsExternalSignUpAllowed(int raidId, out string errorMessage) + { + errorMessage = string.Empty; + using var context = _contextFactory.CreateDbContext(); + Raid? raid = context.Raids + .AsNoTracking() + .FirstOrDefault(r => r.RaidId == raidId); + if(raid == null) + { + errorMessage = "Raid not found."; + return false; + } + + if (raid.RaidType != RaidType.Planned) + { + errorMessage = "Random raids need an Account with equipped builds."; + return false; + } + + if(raid.EndTimeUTC < DateTimeOffset.UtcNow) + { + errorMessage = $"The raid already ended."; + return false; + } + + return true; + } + private async Task LogSignUp(RaidSignUp signUp, string userName, ulong signedUpBy = 0) { - ulong userId = signedUpBy > 0 ? signedUpBy : signUp.LiebUserId; + ulong userId = signedUpBy > 0 ? signedUpBy : signUp.LiebUserId.Value; RaidLog log = RaidLog.CreateSignUpLog(userId, signUp, userName); using var context = _contextFactory.CreateDbContext(); diff --git a/Lieb/Models/GuildWars2/Raid/RaidSignUp.cs b/Lieb/Models/GuildWars2/Raid/RaidSignUp.cs index 6a39310..ea94489 100644 --- a/Lieb/Models/GuildWars2/Raid/RaidSignUp.cs +++ b/Lieb/Models/GuildWars2/Raid/RaidSignUp.cs @@ -12,18 +12,39 @@ public class RaidSignUp { public int RaidSignUpId { get; set; } - public bool IsExternalUser {get { return LiebUserId == 0;}} + public bool IsExternalUser {get { return LiebUserId == null;}} public int RaidId { get; set; } - public ulong LiebUserId { get; set; } - public int GuildWars2AccountId { get; set; } + public ulong? LiebUserId { get; set; } + public int? GuildWars2AccountId { get; set; } public int RaidRoleId { get; set; } public string ExternalUserName {get; set;} = string.Empty; public SignUpType SignUpType { get; set; } public Raid Raid { get; set; } - public LiebUser LiebUser { get; set; } - public GuildWars2Account GuildWars2Account { get; set; } + public LiebUser? LiebUser { get; set; } + public GuildWars2Account? GuildWars2Account { get; set; } public RaidRole RaidRole { get; set; } + + public RaidSignUp(int raidId, ulong userId, int gw2AccountId, int roleId, SignUpType signUpType) + { + RaidId = raidId; + LiebUserId = userId; + GuildWars2AccountId = gw2AccountId; + RaidRoleId = roleId; + SignUpType = signUpType; + } + + public RaidSignUp(int raidId, string userName, int roleId, SignUpType signUpType) + { + RaidId = raidId; + RaidRoleId = roleId; + SignUpType = signUpType; + ExternalUserName = userName; + } + private RaidSignUp() + { + + } } }