public async Task AddAsync(RiftActiveGiveaway giveaway) { await using var context = new RiftContext(); await context.ActiveGiveaways.AddAsync(giveaway); await context.SaveChangesAsync(); }
public async Task RemoveAsync(int id) { var giveaway = new RiftActiveGiveaway { Id = id }; await using var context = new RiftContext(); context.ActiveGiveaways.Remove(giveaway); await context.SaveChangesAsync(); }
async Task FinishGiveawayAsync(RiftActiveGiveaway expiredGiveaway) { var dbGiveaway = await DB.Giveaways.GetAsync(expiredGiveaway.GiveawayName); var giveawayData = $"ID {expiredGiveaway.Id.ToString()} \"{expiredGiveaway.GiveawayName}\""; if (dbGiveaway is null) { RiftBot.Log.Error($"Could not finish giveaway {giveawayData}: {nameof(RiftGiveaway)} is null!"); return; } if (!IonicHelper.GetTextChannel(Settings.App.MainGuildId, Settings.ChannelId.Chat, out var channel)) { RiftBot.Log.Error($"Could not finish giveaway {giveawayData}: Giveaway channel is null!"); return; } var message = (IUserMessage)await channel.GetMessageAsync(expiredGiveaway.ChannelMessageId); if (message is null) { RiftBot.Log.Error($"Could not finish giveaway {giveawayData}: Giveaway message is null! Deleted?"); return; } if (!IonicHelper.GetEmote(403616665603932162, "giveaway", out var emote)) { RiftBot.Log.Error($"Could not finish giveaway {giveawayData}: Emote is null! Deleted?"); return; } // Reaction amount is limited by discord itself. // See https://discordapp.com/developers/docs/resources/channel#get-reactions var reactions = await message.GetReactionUsersAsync(emote, 100).FlattenAsync(); if (reactions is null) { RiftBot.Log.Error($"Could not finish giveaway {giveawayData}: Unable to get reactions."); return; } var dbReward = await DB.Rewards.GetAsync(dbGiveaway.RewardId); if (dbReward is null) { RiftBot.Log.Error($"Could not finish giveaway {giveawayData}: " + $"Unable to get reward ID {dbGiveaway.RewardId.ToString()}."); return; } var reward = dbReward.ToRewardBase(); var participants = reactions .Where(x => !x.IsBot && x.Id != IonicHelper.Client.CurrentUser.Id) .Select(x => x.Id) .ToArray(); if (participants.Length == 0) { await LogGiveawayAsync(dbGiveaway.Name, null, null, "No reward provided", expiredGiveaway.StartedBy, expiredGiveaway.StartedAt, dbGiveaway.Duration); await DB.ActiveGiveaways.RemoveAsync(expiredGiveaway.Id); RiftBot.Log.Error($"Could not finish giveaway {giveawayData}: No participants."); return; } var winners = new ulong[dbGiveaway.WinnersAmount]; if (participants.Length < dbGiveaway.WinnersAmount) { RiftBot.Log.Error($"Could not finish giveaway {giveawayData}: " + $"Not enough participants: only {participants.Length.ToString()} of minimum {dbGiveaway.WinnersAmount.ToString()}"); return; } if (participants.Length == dbGiveaway.WinnersAmount) { Array.Copy(participants, winners, dbGiveaway.WinnersAmount); } else { ulong winnerId; for (var i = 0; i < dbGiveaway.WinnersAmount; i++) { do { winnerId = participants.Random(); } while (winners.Contains(winnerId)); winners[i] = winnerId; } } foreach (var winner in winners) { await rewardService.DeliverToAsync(winner, reward); } await DB.ActiveGiveaways.RemoveAsync(expiredGiveaway.Id); foreach (var participant in participants) { GiveawaysParticipated?.Invoke(null, new GiveawaysParticipatedEventArgs(participant)); } var log = new RiftGiveawayLog { Name = dbGiveaway.Name, Winners = winners, Participants = participants, Reward = "No reward provided", StartedBy = expiredGiveaway.StartedBy, StartedAt = expiredGiveaway.StartedAt, Duration = dbGiveaway.Duration, FinishedAt = DateTime.UtcNow, }; await messageService.SendMessageAsync("giveaway-finished", Settings.ChannelId.Chat, new FormatData(expiredGiveaway.StartedBy) { Giveaway = new GiveawayData { Log = log, Stored = dbGiveaway, }, Reward = reward }); await LogGiveawayAsync(log).ConfigureAwait(false); }
public async Task StartGiveawayAsync(string name, ulong startedById) { if (string.IsNullOrWhiteSpace(name)) { RiftBot.Log.Warning("Empty giveaway name, skipping execution."); return; } var giveaway = await DB.Giveaways.GetAsync(name); if (giveaway is null) { RiftBot.Log.Warning("Wrong giveaway name, skipping execution."); return; } var msg = await messageService.GetMessageFromApi(giveaway.MessageId); if (msg is null) { RiftBot.Log.Warning("Wrong giveaway message ID, skipping execution."); return; } var dbReward = await DB.Rewards.GetAsync(giveaway.RewardId); if (dbReward is null) { RiftBot.Log.Warning("Wrong giveaway reward ID, skipping execution."); return; } var reward = dbReward.ToRewardBase(); if (!IonicHelper.GetEmote(403616665603932162, "giveaway", out var smite)) { RiftBot.Log.Warning("No giveaway emote, skipping execution."); return; } var activeGiveaway = new RiftActiveGiveaway { GiveawayName = giveaway.Name, MessageId = giveaway.MessageId, StartedBy = startedById == 0u ? IonicHelper.Client.CurrentUser.Id : startedById, StartedAt = DateTime.UtcNow, DueTime = DateTime.UtcNow + giveaway.Duration, }; var formattedMsg = await messageService.FormatMessageAsync( msg, new FormatData(startedById) { Giveaway = new GiveawayData { Stored = giveaway }, Reward = reward }); var giveawayMessage = await messageService.SendMessageAsync(formattedMsg, Settings.ChannelId.Chat).ConfigureAwait(false); activeGiveaway.ChannelMessageId = giveawayMessage.Id; await DB.ActiveGiveaways.AddAsync(activeGiveaway).ConfigureAwait(false); await giveawayMessage.AddReactionAsync(smite); await ScheduleTimerToClosest().ConfigureAwait(false); }