140 lines
No EOL
3.4 KiB
C#
140 lines
No EOL
3.4 KiB
C#
#nullable disable
|
|
using Ellie.Common.ModuleBehaviors;
|
|
using Ellie.Db;
|
|
using Ellie.Modules.Games.Common;
|
|
using Ellie.Services.Database.Models;
|
|
|
|
namespace Ellie.Modules.Games.Services;
|
|
|
|
public class PollService : IExecOnMessage
|
|
{
|
|
public ConcurrentDictionary<ulong, PollRunner> ActivePolls { get; } = new();
|
|
|
|
public int Priority
|
|
=> 5;
|
|
|
|
private readonly DbService _db;
|
|
private readonly IBotStrings _strs;
|
|
private readonly IEmbedBuilderService _eb;
|
|
|
|
public PollService(DbService db, IBotStrings strs, IEmbedBuilderService eb)
|
|
{
|
|
_db = db;
|
|
_strs = strs;
|
|
_eb = eb;
|
|
|
|
using var uow = db.GetDbContext();
|
|
ActivePolls = uow.Set<Poll>().GetAllPolls()
|
|
.ToDictionary(x => x.GuildId,
|
|
x =>
|
|
{
|
|
var pr = new PollRunner(db, x);
|
|
pr.OnVoted += Pr_OnVoted;
|
|
return pr;
|
|
})
|
|
.ToConcurrent();
|
|
}
|
|
|
|
public Poll CreatePoll(ulong guildId, ulong channelId, string input)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(input) || !input.Contains(";"))
|
|
return null;
|
|
var data = input.Split(';');
|
|
if (data.Length < 3)
|
|
return null;
|
|
|
|
var col = new IndexedCollection<PollAnswer>(data.Skip(1)
|
|
.Select(x => new PollAnswer
|
|
{
|
|
Text = x
|
|
}));
|
|
|
|
return new()
|
|
{
|
|
Answers = col,
|
|
Question = data[0],
|
|
ChannelId = channelId,
|
|
GuildId = guildId,
|
|
Votes = new()
|
|
};
|
|
}
|
|
|
|
public bool StartPoll(Poll p)
|
|
{
|
|
var pr = new PollRunner(_db, p);
|
|
if (ActivePolls.TryAdd(p.GuildId, pr))
|
|
{
|
|
using (var uow = _db.GetDbContext())
|
|
{
|
|
uow.Set<Poll>().Add(p);
|
|
uow.SaveChanges();
|
|
}
|
|
|
|
pr.OnVoted += Pr_OnVoted;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public Poll StopPoll(ulong guildId)
|
|
{
|
|
if (ActivePolls.TryRemove(guildId, out var pr))
|
|
{
|
|
pr.OnVoted -= Pr_OnVoted;
|
|
|
|
using var uow = _db.GetDbContext();
|
|
uow.RemovePoll(pr.Poll.Id);
|
|
uow.SaveChanges();
|
|
|
|
return pr.Poll;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private async Task Pr_OnVoted(IUserMessage msg, IGuildUser usr)
|
|
{
|
|
var toDelete = await msg.Channel.SendConfirmAsync(_eb,
|
|
_strs.GetText(strs.poll_voted(Format.Bold(usr.ToString())), usr.GuildId));
|
|
toDelete.DeleteAfter(5);
|
|
try
|
|
{
|
|
await msg.DeleteAsync();
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
|
|
public async Task<bool> ExecOnMessageAsync(IGuild guild, IUserMessage msg)
|
|
{
|
|
if (guild is null)
|
|
return false;
|
|
|
|
if (!ActivePolls.TryGetValue(guild.Id, out var poll))
|
|
return false;
|
|
|
|
try
|
|
{
|
|
var voted = await poll.TryVote(msg);
|
|
|
|
if (voted)
|
|
{
|
|
Log.Information("User {UserName} [{UserId}] voted in a poll on {GuildName} [{GuildId}] server",
|
|
msg.Author.ToString(),
|
|
msg.Author.Id,
|
|
guild.Name,
|
|
guild.Id);
|
|
}
|
|
|
|
return voted;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Warning(ex, "Error voting");
|
|
}
|
|
|
|
return false;
|
|
}
|
|
} |