Beispiel #1
0
        public async Task AddAsync(RiftActiveEvent activeEvent, CancellationToken ct = default)
        {
            await using var context = new RiftContext();
            await context.ActiveEvents.AddAsync(activeEvent, ct);

            await context.SaveChangesAsync(ct);
        }
Beispiel #2
0
        public async Task RemoveAsync(int id)
        {
            var activeEvent = new RiftActiveEvent
            {
                Id = id
            };

            await using var context = new RiftContext();
            context.ActiveEvents.Remove(activeEvent);
            await context.SaveChangesAsync();
        }
Beispiel #3
0
        public async Task StartAsync(RiftEvent dbEvent, ulong startedById)
        {
            if (dbEvent is null)
            {
                RiftBot.Log.Warning("Wrong event name, skipping execution.");
                return;
            }

            var msg = await messageService.GetMessageFromApi(dbEvent.MessageId);

            if (msg is null)
            {
                RiftBot.Log.Warning("Wrong event message ID, skipping execution.");
                return;
            }

            var dbSharedReward = await DB.Rewards.GetAsync(dbEvent.SharedRewardId);

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

            if (!IonicHelper.GetEmote(213672490491314176, "smite", out var smite))
            {
                RiftBot.Log.Warning("No event emote, skipping execution.");
                return;
            }

            var activeGiveaway = new RiftActiveEvent
            {
                EventName = dbEvent.Name,
                MessageId = dbEvent.MessageId,
                StartedBy = startedById == 0u ? IonicHelper.Client.CurrentUser.Id : startedById,
                StartedAt = DateTime.UtcNow,
                DueTime   = DateTime.UtcNow + dbEvent.Duration,
            };

            var formattedMsg = await messageService.FormatMessageAsync(msg, new FormatData(startedById));

            var eventMessage = await messageService.SendMessageAsync(formattedMsg, Settings.ChannelId.Monsters).ConfigureAwait(false);

            activeGiveaway.ChannelMessageId = eventMessage.Id;

            await DB.ActiveEvents.AddAsync(activeGiveaway).ConfigureAwait(false);

            await eventMessage.AddReactionAsync(smite);

            await ScheduleTimerToClosestActiveAsync().ConfigureAwait(false);
        }
Beispiel #4
0
        async Task FinishAsync(RiftActiveEvent expiredEvent)
        {
            var eventLogString = $"ID {expiredEvent.Id.ToString()} \"{expiredEvent.EventName}\"";
            var dbEvent        = await DB.Events.GetAsync(expiredEvent.EventName);

            if (dbEvent is null)
            {
                RiftBot.Log.Error($"Could not finish event {eventLogString}: {nameof(RiftEvent)} is null!");
                return;
            }

            if (!IonicHelper.GetTextChannel(Settings.App.MainGuildId, Settings.ChannelId.Monsters, out var channel))
            {
                RiftBot.Log.Error($"Could not finish event {eventLogString}: Event channel is null!");
                return;
            }

            var message = (IUserMessage)await channel.GetMessageAsync(expiredEvent.ChannelMessageId);

            if (message is null)
            {
                RiftBot.Log.Error($"Could not finish event {eventLogString}: Event message is null! Deleted?");
                return;
            }

            if (!IonicHelper.GetEmote(213672490491314176ul, "smite", out var emote))
            {
                RiftBot.Log.Error($"Could not finish event {eventLogString}: 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 event {eventLogString}: Unable to get reactions.");
                return;
            }

            var dbReward = await DB.Rewards.GetAsync(dbEvent.SharedRewardId);

            if (dbReward is null)
            {
                RiftBot.Log.Error($"Could not finish event {eventLogString}: " +
                                  $"Unable to get reward ID {dbEvent.SharedRewardId.ToString()}.");
                return;
            }

            var participants = reactions
                               .Where(x => !x.IsBot && x.Id != IonicHelper.Client.CurrentUser.Id)
                               .Select(x => x.Id)
                               .ToArray();

            if (participants.Length == 0)
            {
                await LogEventAsync(dbEvent.Name, null, "No reward provided ", expiredEvent.StartedBy,
                                    expiredEvent.StartedAt, dbEvent.Duration);

                await DB.ActiveEvents.RemoveAsync(expiredEvent.Id);

                RiftBot.Log.Error($"Could not finish event {eventLogString}: No participants.");
                return;
            }

            RiftReward specialReward   = null;
            var        specialWinnerId = 0ul;

            if (dbEvent.HasSpecialReward)
            {
                specialReward = await DB.Rewards.GetAsync(dbEvent.SpecialRewardId);

                if (specialReward is null)
                {
                    RiftBot.Log.Error($"Could not finish event {eventLogString}: " +
                                      $"Unable to get special reward ID {dbEvent.SharedRewardId.ToString()}.");
                    return;
                }

                specialWinnerId = participants.Random();

                var specReward = specialReward.ToRewardBase();
                await rewardService.DeliverToAsync(specialWinnerId, specReward);
            }

            var reward = dbReward.ToRewardBase();

            foreach (var userId in participants)
            {
                await rewardService.DeliverToAsync(userId, reward);
            }

            await DB.ActiveEvents.RemoveAsync(expiredEvent.Id);

            var eventType = (EventType)dbEvent.Type;

            foreach (var participant in participants)
            {
                switch (eventType)
                {
                case EventType.Normal:
                    NormalMonstersKilled?.Invoke(
                        null, new NormalMonstersKilledEventArgs(participant, 1u));
                    break;

                case EventType.Rare:
                    RareMonstersKilled?.Invoke(
                        null, new RareMonstersKilledEventArgs(participant, 1u));
                    break;

                case EventType.Epic:
                    EpicMonstersKilled?.Invoke(
                        null, new EpicMonstersKilledEventArgs(participant, 1u));
                    break;
                }
            }

            var log = new RiftEventLog
            {
                Name = dbEvent.Name,
                ParticipantsAmount = (uint)participants.Length,
                Reward             = "No reward provided",
                StartedBy          = expiredEvent.StartedBy,
                StartedAt          = expiredEvent.StartedAt,
                Duration           = dbEvent.Duration,
                FinishedAt         = DateTime.UtcNow,
                SpecialWinnerId    = specialWinnerId
            };

            await messageService.SendMessageAsync("event-finished", Settings.ChannelId.Monsters, new FormatData(expiredEvent.StartedBy)
            {
                EventData = new EventData
                {
                    Log    = log,
                    Stored = dbEvent,
                }
            });

            if (dbEvent.HasSpecialReward)
            {
                await messageService.SendMessageAsync("event-finished-special", Settings.ChannelId.Monsters, new FormatData(specialWinnerId)
                {
                    Reward = specialReward.ToRewardBase()
                });
            }

            await LogEventAsync(log).ConfigureAwait(false);
        }