Added Polls and locking raids if not enough users are signed up
needs testing
This commit is contained in:
parent
32af72a262
commit
ccb276a265
14 changed files with 289 additions and 8 deletions
|
@ -8,6 +8,12 @@
|
|||
public static readonly int RaidEditPowerLevel = Roles.Moderator.PowerLevel;
|
||||
public const int REMOVE_MAYBE_MINUTES = 15;
|
||||
|
||||
public static class Polls
|
||||
{
|
||||
public const string YES = "yes";
|
||||
public const string NO = "no";
|
||||
}
|
||||
|
||||
public static class Roles
|
||||
{
|
||||
public static readonly RoleConstant User = new RoleConstant("user", 20);
|
||||
|
|
|
@ -306,8 +306,15 @@ namespace Lieb.Data
|
|||
|
||||
public static ApiRaid ConvertRaid(Raid raid)
|
||||
{
|
||||
string title = raid.Title;
|
||||
if (raid.SignUps.Count < raid.MinUsers
|
||||
&& raid.MinUserDeadLineUTC.UtcDateTime > DateTimeOffset.UtcNow)
|
||||
{
|
||||
title = $"The raid was canceled because of not enough sign ups.\n\n{raid.Title}";
|
||||
}
|
||||
|
||||
ApiRaid apiRaid = new ApiRaid(){
|
||||
Title = raid.Title,
|
||||
Title = title,
|
||||
Description = raid.Description,
|
||||
Guild = raid.Guild,
|
||||
Organizer = raid.Organizer,
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using Lieb.Models;
|
||||
using Lieb.Models.GuildWars2;
|
||||
using Lieb.Models.GuildWars2.Raid;
|
||||
using Lieb.Models.Poll;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Lieb.Data
|
||||
|
@ -26,6 +27,9 @@ namespace Lieb.Data
|
|||
public DbSet<RaidSignUp> RaidSignUps { get; set; }
|
||||
public DbSet<DiscordRaidMessage> DiscordRaidMessages { get; set; }
|
||||
public DbSet<DiscordSettings> DiscordSettings { get; set; }
|
||||
public DbSet<Poll> Polls { get; set; }
|
||||
public DbSet<PollOption> PollOptions { get; set; }
|
||||
public DbSet<PollAnswer> PollAnswers { get; set; }
|
||||
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
|
@ -43,6 +47,9 @@ namespace Lieb.Data
|
|||
modelBuilder.Entity<RaidSignUp>().ToTable("RaidSignUp");
|
||||
modelBuilder.Entity<DiscordRaidMessage>().ToTable("DiscordRaidMessage");
|
||||
modelBuilder.Entity<DiscordSettings>().ToTable("DiscordSettings");
|
||||
modelBuilder.Entity<Poll>().ToTable("Poll");
|
||||
modelBuilder.Entity<PollOption>().ToTable("PollOption");
|
||||
modelBuilder.Entity<PollAnswer>().ToTable("PollAnswer");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
113
Lieb/Data/PollService.cs
Normal file
113
Lieb/Data/PollService.cs
Normal file
|
@ -0,0 +1,113 @@
|
|||
using Lieb.Models.GuildWars2.Raid;
|
||||
using Lieb.Models.Poll;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
|
||||
namespace Lieb.Data
|
||||
{
|
||||
public class PollService
|
||||
{
|
||||
private readonly IDbContextFactory<LiebContext> _contextFactory;
|
||||
private readonly DiscordService _discordService;
|
||||
public PollService(IDbContextFactory<LiebContext> contextFactory, DiscordService discordService)
|
||||
{
|
||||
_contextFactory = contextFactory;
|
||||
_discordService = discordService;
|
||||
}
|
||||
|
||||
public Poll GetPoll(int pollId)
|
||||
{
|
||||
using var context = _contextFactory.CreateDbContext();
|
||||
Poll? poll = context.Polls
|
||||
.Include(p => p.Options)
|
||||
.Include(p => p.Answers)
|
||||
.FirstOrDefault(p => p.PollId == pollId);
|
||||
|
||||
if (poll != null) return poll;
|
||||
|
||||
return new Poll();
|
||||
}
|
||||
|
||||
public List<Poll> GetPollsByRaidId(int raidId)
|
||||
{
|
||||
using var context = _contextFactory.CreateDbContext();
|
||||
return context.Polls
|
||||
.Include(p => p.Options)
|
||||
.Include(p => p.Answers)
|
||||
.Where(p => p.RaidId == raidId).ToList();
|
||||
}
|
||||
|
||||
public async Task<int> CreatePoll(string question, List<string> options, int raidId)
|
||||
{
|
||||
using var context = _contextFactory.CreateDbContext();
|
||||
Raid? raid = context.Raids
|
||||
.Include(r => r.SignUps)
|
||||
.FirstOrDefault(r => r.RaidId == raidId);
|
||||
|
||||
if (raid == null) return 0;
|
||||
List<ulong> users = raid.SignUps.Where(s => s.LiebUserId != null).Select(s => (ulong)s.LiebUserId).ToList();
|
||||
return await CreatePoll(question, options, users, raidId);
|
||||
}
|
||||
|
||||
public async Task<int> CreatePoll(string question, List<string> options, List<ulong> users, int? raidId = null)
|
||||
{
|
||||
Poll poll = new Poll()
|
||||
{
|
||||
Question = question,
|
||||
RaidId = raidId
|
||||
};
|
||||
foreach(string option in options)
|
||||
{
|
||||
poll.Options.Add(new PollOption()
|
||||
{
|
||||
Name = option
|
||||
});
|
||||
}
|
||||
foreach(ulong user in users)
|
||||
{
|
||||
poll.Answers.Add(new PollAnswer()
|
||||
{
|
||||
UserId = user
|
||||
});
|
||||
}
|
||||
|
||||
using var context = _contextFactory.CreateDbContext();
|
||||
context.Polls.Add(poll);
|
||||
await context.SaveChangesAsync();
|
||||
return poll.PollId;
|
||||
}
|
||||
|
||||
public async Task DeletePoll(int pollId)
|
||||
{
|
||||
using var context = _contextFactory.CreateDbContext();
|
||||
Poll? poll = context.Polls
|
||||
.Include(p => p.Options)
|
||||
.Include(p => p.Answers)
|
||||
.FirstOrDefault(p => p.PollId == pollId);
|
||||
|
||||
if(poll == null) return;
|
||||
|
||||
context.PollOptions.RemoveRange(poll.Options);
|
||||
context.PollAnswers.RemoveRange(poll.Answers);
|
||||
await context.SaveChangesAsync();
|
||||
|
||||
poll.Options.Clear();
|
||||
poll.Answers.Clear();
|
||||
context.Polls.Remove(poll);
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task UpdateAnswer(int pollId, int pollOptionId, ulong userId)
|
||||
{
|
||||
using var context = _contextFactory.CreateDbContext();
|
||||
Poll? poll = context.Polls
|
||||
.Include(p => p.Answers)
|
||||
.FirstOrDefault(p => p.PollId == pollId && p.Answers.Where(a => a.UserId == userId).Any());
|
||||
|
||||
if (poll == null) return;
|
||||
|
||||
PollAnswer answer = poll.Answers.First(a => a.UserId == userId);
|
||||
answer.PollOptionId = pollOptionId;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
using Lieb.Models;
|
||||
using Lieb.Models.GuildWars2;
|
||||
using Lieb.Models.GuildWars2.Raid;
|
||||
using Lieb.Models.Poll;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Lieb.Data
|
||||
|
@ -9,11 +10,13 @@ namespace Lieb.Data
|
|||
{
|
||||
private readonly IDbContextFactory<LiebContext> _contextFactory;
|
||||
private readonly DiscordService _discordService;
|
||||
private readonly PollService _pollService;
|
||||
|
||||
public RaidService(IDbContextFactory<LiebContext> contextFactory, DiscordService discordService)
|
||||
public RaidService(IDbContextFactory<LiebContext> contextFactory, DiscordService discordService, PollService pollService)
|
||||
{
|
||||
_contextFactory = contextFactory;
|
||||
_discordService = discordService;
|
||||
_pollService = pollService;
|
||||
}
|
||||
|
||||
public List<Raid> GetRaids()
|
||||
|
@ -444,6 +447,7 @@ namespace Lieb.Data
|
|||
errorMessage = string.Empty;
|
||||
using var context = _contextFactory.CreateDbContext();
|
||||
Raid? raid = context.Raids
|
||||
.Include(r => r.SignUps)
|
||||
.AsNoTracking()
|
||||
.FirstOrDefault(r => r.RaidId == raidId);
|
||||
if(raid == null)
|
||||
|
@ -451,6 +455,14 @@ namespace Lieb.Data
|
|||
errorMessage = "Raid not found.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (raid.SignUps.Count < raid.MinUsers
|
||||
&& raid.MinUserDeadLineUTC.UtcDateTime > DateTimeOffset.UtcNow)
|
||||
{
|
||||
errorMessage = $"The raid was canceled because of not enough sign ups.";
|
||||
return false;
|
||||
}
|
||||
|
||||
LiebUser? user = context.LiebUsers
|
||||
.Include(u => u.RoleAssignments)
|
||||
.ThenInclude(a => a.LiebRole)
|
||||
|
@ -670,5 +682,49 @@ namespace Lieb.Data
|
|||
await context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task CheckMinUsers()
|
||||
{
|
||||
using var context = _contextFactory.CreateDbContext();
|
||||
List<Raid> raids = context.Raids
|
||||
.Include(r => r.SignUps)
|
||||
.Where(r => r.SignUps.Count < r.MinUsers && r.MinUserPollId == null).ToList();
|
||||
foreach (Raid raid in raids.Where(r => r.MinUserDeadLineUTC < DateTimeOffset.UtcNow && r.StartTimeUTC > DateTimeOffset.UtcNow))
|
||||
{
|
||||
raid.MinUserPollId = await _pollService.CreatePoll(
|
||||
"The raid has not the required users, do you want to raid anyway?",
|
||||
new List<string>() {Constants.Polls.YES, Constants.Polls.NO }, raid.RaidId);
|
||||
await context.SaveChangesAsync();
|
||||
await _discordService.PostRaidMessage(raid.RaidId);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task CheckMinUserPollResult()
|
||||
{
|
||||
using var context = _contextFactory.CreateDbContext();
|
||||
List<Raid> raids = context.Raids
|
||||
.Include(r => r.SignUps)
|
||||
.Where(r => r.SignUps.Count < r.MinUsers && r.MinUserPollId != null).ToList();
|
||||
foreach (Raid raid in raids.Where(r => r.MinUserDeadLineUTC < DateTimeOffset.UtcNow && r.StartTimeUTC > DateTimeOffset.UtcNow))
|
||||
{
|
||||
Poll poll = _pollService.GetPoll(raid.MinUserPollId.Value);
|
||||
|
||||
if (poll.Answers.Count == 0) continue;
|
||||
if (poll.Answers.Where(a => a.PollOptionId == null).Any()) continue;
|
||||
|
||||
int noOptionId = poll.Options.First(o => o.Name == Constants.Polls.NO).PollOptionId;
|
||||
if(poll.Answers.Where(a => a.PollOptionId == noOptionId).Any())
|
||||
{
|
||||
await _discordService.SendMessageToRaidUsers("The raid is canceled.", raid);
|
||||
}
|
||||
else
|
||||
{
|
||||
raid.MinUsers = 0;
|
||||
await context.SaveChangesAsync();
|
||||
await _discordService.SendMessageToRaidUsers("The raid will take place. Signing up is allowed again.", raid);
|
||||
await _discordService.PostRaidMessage(raid.RaidId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,8 @@ namespace Lieb.Data
|
|||
.GetRequiredService<RaidService>();
|
||||
await raidService.SendReminders();
|
||||
await raidService.RemoveMaybes();
|
||||
await raidService.CheckMinUsers();
|
||||
await raidService.CheckMinUserPollResult();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue