Exemplo n.º 1
0
        public async Task AddAsync(RiftGiveawayLog log)
        {
            await using var context = new RiftContext();
            await context.GiveawayLogs.AddAsync(log);

            await context.SaveChangesAsync();
        }
Exemplo n.º 2
0
        static async Task LogGiveawayAsync(string name, ulong[] winners, ulong[] participants, string rewardPlain,
                                           ulong startedBy, DateTime startedAt, TimeSpan duration)
        {
            var log = new RiftGiveawayLog
            {
                Name         = name,
                Winners      = winners,
                Participants = participants,
                Reward       = rewardPlain,
                StartedBy    = startedBy,
                StartedAt    = startedAt,
                Duration     = duration,
                FinishedAt   = DateTime.UtcNow,
            };

            await LogGiveawayAsync(log);
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
 static async Task LogGiveawayAsync(RiftGiveawayLog log)
 {
     await DB.GiveawayLogs.AddAsync(log);
 }
Exemplo n.º 5
0
        public async Task StartTicketGiveawayAsync(int rewardId, ulong startedBy)
        {
            var dbReward = await DB.Rewards.GetAsync(rewardId);

            if (dbReward is null)
            {
                RiftBot.Log.Warning("Wrong reward ID, skipping execution.");
                return;
            }

            var reward = dbReward.ToRewardBase();

            var usersWithTickets = await DB.Inventory.GetAsync(x => x.Tickets >= 1);

            if (usersWithTickets is null || usersWithTickets.Count == 0)
            {
                RiftBot.Log.Warning("No users with tickets, skipping execution.");
                return;
            }

            RiftBot.Log.Information($"Ticket giveaway started for {usersWithTickets.Count.ToString()}, reward ID {rewardId.ToString()}.");

            var removeInv = new InventoryData {
                Tickets = 1u
            };

            var userList = usersWithTickets.ToList();
            var winnerId = 0ul;

            do
            {
                if (userList.Count == 0)
                {
                    RiftBot.Log.Warning("No users on server participated, skipping execution.");
                    return;
                }

                var winner = userList.Random();
                winnerId = winner.UserId;
                userList.Remove(winner);
            } while (!IonicHelper.GetGuildUserById(Settings.App.MainGuildId, winnerId, out var sgUser));

            foreach (var userInventory in usersWithTickets)
            {
                await DB.Inventory.RemoveAsync(userInventory.UserId, removeInv); // very slow on tunneled db connection
            }

            await rewardService.DeliverToAsync(winnerId, reward);

            await messageService.SendMessageAsync("giveaway-ticket-success", Settings.ChannelId.Chat, new FormatData(startedBy)
            {
                Giveaway = new GiveawayData
                {
                    TicketGiveaway = new TicketGiveaway
                    {
                        ParticipantsCount = usersWithTickets.Count,
                        WinnerId          = winnerId
                    }
                },
                Reward = reward
            });

            var log = new RiftGiveawayLog
            {
                Name         = "Ticket Giveaway",
                Winners      = new[] { winnerId },
                Participants = usersWithTickets.Select(x => x.UserId).ToArray(),
                Reward       = "No reward provided",
                StartedBy    = startedBy,
                StartedAt    = DateTime.Now,
                Duration     = TimeSpan.Zero,
                FinishedAt   = DateTime.UtcNow,
            };

            await DB.GiveawayLogs.AddAsync(log);
        }