Exemplo n.º 1
0
        /// <summary>
        ///     Удаление старых тикетов.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static async void CheckExpiredTicketsAsync(object sender, ElapsedEventArgs e)
        {
            Client.Logger.LogDebug(BotLoggerEvents.Timers, $"CheckExpiredTicketsAsync running");

            var expiredTickets = TicketSQL.GetClosedFor(TimeSpan.FromDays(2));

            var guild = Client.Guilds[Bot.BotSettings.Guild];

            foreach (var ticket in expiredTickets)
            {
                ticket.Status = TicketSQL.TicketStatus.Deleted;
                try
                {
                    await guild.GetChannel(ticket.ChannelId).DeleteAsync();
                }
                catch (NotFoundException) { }
            }
        }
Exemplo n.º 2
0
        public async Task Support(CommandContext ctx)
        {
            if (SupportBlacklistEntry.IsBlacklisted(ctx.User.Id))
            {
                await ctx.RespondAsync("Создание тикетов заблокировано. Свяжитесь с администрацией для выяснения");

                return;
            }

            DmMessageListener.DmHandled.Add(ctx.User);

            try
            {
                var guild = await ctx.Client.GetGuildAsync(Bot.BotSettings.Guild);


                //Создание эмбеда тикета и заполнение по шаблону
                var ticketEmbed = new DiscordEmbedBuilder
                {
                    Title       = "Sea of Thieves RU | Создание тикета",
                    Description = "Выберите категорию вашего запроса через реакцию‎\n‎",
                    Color       = new DiscordColor("#e67e22")
                };

                ticketEmbed.AddField($"{SupportEmoji[SupportType.Admin]} {SupportNames[SupportType.Admin]}", "Связь с администрацией, используйте только для **ВАЖНЫХ** вопросов", true);
                ticketEmbed.AddField($"{SupportEmoji[SupportType.Moderator]} {SupportNames[SupportType.Moderator]}", "Вопросы по поводу модерации, нарушений и так далее. (Отвечают модераторы и администраторы)", true);
                ticketEmbed.AddField($"{SupportEmoji[SupportType.Developer]} {SupportNames[SupportType.Developer]}", "По вопросам бота, сайта, техническим вопросам, помощь с командами и их ошибками.", true);
                ticketEmbed.AddField($"{SupportEmoji[SupportType.Donate]} {SupportNames[SupportType.Donate]}", "По вопросам рекламы и при проблемах с донатами.", true);
                ticketEmbed.AddField($"{SupportEmoji[SupportType.FleetCaptain]} {SupportNames[SupportType.FleetCaptain]}", "По вопросам рейдов и нарушений в рейдах. (Ошибки при выдаче роли -> к `Разработчикам`)", true);
                ticketEmbed.AddField($"{SupportEmoji[SupportType.Events]} {SupportNames[SupportType.Events]}", "По вопросам ивентов на сервере. Как игровых так и внутри сервера.", true);

                ticketEmbed.WithFooter("‎\n" +
                                       "При злоупотреблении системой тикетов вы будете заблокированы.\n" +
                                       "Дождитесь загрузки всех вариантов ответа. У вас есть минута на выбор варианта");

                var ticketMessage = await ctx.RespondAsync(embed : ticketEmbed.Build());

                var interactivity = ctx.Client.GetInteractivity();

                //Создаем предложенные реакции.
                foreach (var emoji in SupportEmoji.Values)
                {
                    await ticketMessage.CreateReactionAsync(DiscordEmoji.FromName(ctx.Client, emoji));

                    await Task.Delay(400);
                }

                //Шаблон закрытого тикета
                var errorEmbed = new DiscordEmbedBuilder()
                {
                    Title       = "Sea of Thieves RU | Создание тикета закрыто",
                    Description = "Произошла ошибка при создании тикета.",
                    Color       = new DiscordColor("#e74c3c"),
                };
                errorEmbed.WithThumbnail(guild.IconUrl);
                errorEmbed.WithTimestamp(DateTime.Now);

                //Ждем одну из предложенных реакций. (Минута времени)
                var em = await interactivity.WaitForReactionAsync(x => SupportEmoji.Values.Contains(x.Emoji.GetDiscordName()), ctx.User, TimeSpan.FromSeconds(60));

                if (!em.TimedOut)
                {
                    new Task(async() =>
                    {
                        foreach (var emoji in SupportEmoji.Values)
                        {
                            await ticketMessage.DeleteOwnReactionAsync(DiscordEmoji.FromName(ctx.Client, emoji));
                            await Task.Delay(400);
                        }
                    }).Start();

                    var selectedCategory = SupportEmoji.FirstOrDefault(x => x.Value == em.Result.Emoji.GetDiscordName()).Key;

                    //Успешное продолжение создания тикета
                    //Запрос описания проблемы
                    ticketEmbed = new DiscordEmbedBuilder
                    {
                        Title       = "Sea of Thieves RU | Ожидание вопроса",
                        Description = "Опишите ваш вопрос коротким сообщением.\n‎",
                        Color       = new DiscordColor("#e67e22")
                    };
                    ticketEmbed.WithThumbnail(guild.IconUrl);

                    ticketEmbed.AddField("Выбранная категория", $"{SupportEmoji[selectedCategory]} {SupportNames[selectedCategory]}", true);

                    ticketEmbed.WithFooter("‎\nУ вас есть 5 минут для ввода вопроса.");

                    await ticketMessage.ModifyAsync(embed : ticketEmbed.Build());

                    var emsg = await interactivity.WaitForMessageAsync(x => x.Author.Id == ctx.User.Id && !x.Content.StartsWith(Bot.BotSettings.Prefix), TimeSpan.FromMinutes(5));

                    if (!emsg.TimedOut)
                    {
                        //Запрос подтверждения тикета.
                        ticketEmbed = new DiscordEmbedBuilder(ticketEmbed)
                        {
                            Title       = "Sea of Thieves RU | Подтверждение тикета",
                            Description = "Подтвердите ваш тикет для отправки. \n" +
                                          "`✅ отправить` `❌ отменить` \n‎",
                            Color = new DiscordColor("#e67e22")
                        };

                        ticketEmbed.AddField("Вопрос", emsg.Result.Content, true);

                        ticketEmbed.WithFooter("‎\nДождитесь загрузки всех вариантов ответа. У вас есть минута на выбор варианта");

                        await ticketMessage.ModifyAsync(embed : ticketEmbed.Build());

                        //Реакции подтверждения
                        var yesEmoji = DiscordEmoji.FromName(ctx.Client, ":white_check_mark:");
                        var noEmoji  = DiscordEmoji.FromName(ctx.Client, ":x:");

                        await ticketMessage.CreateReactionAsync(yesEmoji);

                        await Task.Delay(400);

                        await ticketMessage.CreateReactionAsync(noEmoji);

                        //Ждем ответа на подтверждение
                        em = await interactivity.WaitForReactionAsync(x => x.Emoji == yesEmoji || x.Emoji == noEmoji, ctx.User, TimeSpan.FromSeconds(60));

                        if (!em.TimedOut)
                        {
                            await ticketMessage.DeleteOwnReactionAsync(yesEmoji);

                            await Task.Delay(400);

                            await ticketMessage.DeleteOwnReactionAsync(noEmoji);

                            if (em.Result.Emoji == yesEmoji)
                            {
                                //Создание канала для ответа
                                var supportChannel = await guild.CreateChannelAsync($"{DiscordEmoji.FromName(ctx.Client, SupportEmoji[selectedCategory])} {ctx.User.Username}", ChannelType.Text,
                                                                                    guild.GetChannel(Bot.BotSettings.SupportCategory));

                                //Выдача прав на канал
                                await supportChannel.AddOverwriteAsync(await guild.GetMemberAsync(ctx.User.Id), Permissions.AccessChannels);

                                switch (selectedCategory)
                                {
                                case SupportType.Admin:
                                case SupportType.Developer:
                                case SupportType.Donate:
                                    //Do nothing
                                    break;

                                case SupportType.Moderator:
                                case SupportType.Events:
                                    await supportChannel.AddOverwriteAsync(guild.GetRole(Bot.BotSettings.ModeratorsRole), Permissions.AccessChannels);

                                    break;

                                case SupportType.FleetCaptain:
                                    await supportChannel.AddOverwriteAsync(guild.GetRole(Bot.BotSettings.ModeratorsRole), Permissions.AccessChannels);

                                    await supportChannel.AddOverwriteAsync(guild.GetRole(Bot.BotSettings.FleetCaptainRole), Permissions.AccessChannels);

                                    break;
                                }

                                //Сохраняем в базу данных
                                var ticketData = TicketSQL.Create(supportChannel.Id, ctx.User.Id, ctx.Channel.Id, ticketMessage.Id,
                                                                  emsg.Result.Content, DateTime.Now, SupportNames[selectedCategory]);

                                //Обновляем тикет в лс
                                ticketEmbed = new DiscordEmbedBuilder(ticketEmbed)
                                {
                                    Description = "Тикет был создан.\n‎",
                                    Color       = new DiscordColor("#f1c40f")
                                };
                                ticketEmbed.WithFooter($"‎\nID: {ticketData.ChannelId}");
                                ticketEmbed.WithTimestamp(DateTime.Now);

                                await ticketMessage.ModifyAsync(embed : ticketEmbed.Build());

                                await ctx.RespondAsync($"Ваш запрос был отравлен. Ждите ответ в {supportChannel.Mention}.");

                                //Обновляем тикет для отправки в канал
                                ticketEmbed = new DiscordEmbedBuilder(ticketEmbed)
                                {
                                    Title       = "Sea of Thieves RU | Тикет",
                                    Description = "Ожидайте ответ на ваш запрос.\n‎"
                                }
                                .WithAuthor(ctx.User.ToString(), iconUrl: ctx.User.AvatarUrl)
                                .WithFooter($"‎\nID: {ticketData.ChannelId}");

                                var message = await supportChannel.SendMessageAsync($"Тикет от пользователя: {ctx.User.Mention}", embed : ticketEmbed.Build());

                                ticketData.MessageId = message.Id;
                            }
                            else
                            {
                                ticketEmbed = new DiscordEmbedBuilder(errorEmbed)
                                              .WithDescription("Тикет был отменён.");

                                await ticketMessage.ModifyAsync(embed : ticketEmbed.Build());
                            }
                        }
                        else
                        {
                            await ticketMessage.DeleteOwnReactionAsync(yesEmoji);

                            await Task.Delay(400);

                            await ticketMessage.DeleteOwnReactionAsync(noEmoji);

                            ticketEmbed = new DiscordEmbedBuilder(errorEmbed)
                                          .WithDescription("Время выбора истекло.");

                            await ticketMessage.ModifyAsync(embed : ticketEmbed.Build());
                        }
                    }
                    else
                    {
                        ticketEmbed = new DiscordEmbedBuilder(errorEmbed)
                                      .WithDescription("Время ввода вопроса истекло.");

                        await ticketMessage.ModifyAsync(embed : ticketEmbed.Build());
                    }
                }
                else
                {
                    new Task(async() =>
                    {
                        foreach (var emoji in SupportEmoji.Values)
                        {
                            await ticketMessage.DeleteOwnReactionAsync(DiscordEmoji.FromName(ctx.Client, emoji));
                            await Task.Delay(400);
                        }
                    }).Start();
                    ticketEmbed = new DiscordEmbedBuilder(errorEmbed)
                                  .WithDescription("Время выбора категории тикета истекло.");

                    await ticketMessage.ModifyAsync(embed : ticketEmbed.Build());
                }
                DmMessageListener.DmHandled.Remove(ctx.User);
            }
            catch (Exception)
            {
                DmMessageListener.DmHandled.Remove(ctx.User);
                throw;
            }
        }