Beispiel #1
0
        public static async Task FleetDeleteOnVoiceStateUpdated(DiscordClient client, VoiceStateUpdateEventArgs e)
        {
            //Проверка на пустые рейды
            if (e.Before != null && e.Before.Channel != null)
            {
                var leftChannel = e.Before.Channel;

                //Пользователь вышел из автоматически созданных каналов рейда
                if (leftChannel.Parent.Name.StartsWith("Рейд") &&
                    leftChannel.ParentId != Bot.BotSettings.FleetCategory &&
                    !leftChannel.Users.Contains(e.User))
                {
                    //Проверка всех каналов рейда на присутствие в них игроков
                    var fleetIsEmpty = leftChannel.Parent.Children
                                       .Where(x => x.Type == ChannelType.Voice)
                                       .Where(x => x.Users.Count() > 0)
                                       .Count() == 0;

                    //Проверка если каналы рейдов были недавно созданы (5 минут и более)
                    var isNotNew = DateTime.Now - leftChannel.Parent.CreationTimestamp > TimeSpan.FromMinutes(5);

                    //Удаляем каналы и категорию
                    if (fleetIsEmpty && isNotNew)
                    {
                        await FleetLogging.LogFleetDeletionAsync(client, e.Guild, leftChannel.Parent);

                        foreach (var emptyChannel in leftChannel.Parent.Children.Where(x => x.Type == ChannelType.Voice))
                        {
                            try
                            {
                                await emptyChannel.DeleteAsync();
                            }
                            catch (NotFoundException) { }
                        }

                        await leftChannel.Parent.DeleteAsync();
                    }
                }
            }
        }
Beispiel #2
0
        public async Task CreateFleet(CommandContext ctx,
                                      [Description("Количество кораблей [1 - 5]")] int nShips,
                                      [Description("Слоты на корабле [2 - 25]")] int slots,
                                      [RemainingText, Description("Название рейда")] string notes = "добра и позитива")
        {
            notes = notes.Substring(0, Math.Min(notes.Length, 25));

            if (nShips < 1 || nShips > 6 ||
                slots < 2 || slots > 25)
            {
                await ctx.RespondAsync($"{Bot.BotSettings.ErrorEmoji} Недопустимые параметры рейда!");

                return;
            }

            //Проверка на капитана или модератора
            var pollNeeded = !ctx.Member.Roles.Contains(ctx.Guild.GetRole(Bot.BotSettings.FleetCaptainRole)) && !Bot.IsModerator(ctx.Member);

            var pollSucceded = false;

            var moscowTime = DateTime.Now;
            var timeOfDay  = moscowTime.ToString("HH:mm");

            var fleetCreationMessage = await ctx.Guild.GetChannel(Bot.BotSettings.FleetCreationChannel).
                                       SendMessageAsync($"**Дата рейда**: {moscowTime:dd\\/MM} \n" +
                                                        $"**Время начала**: {timeOfDay} \n" +
                                                        $"**Количество кораблей**: {nShips} \n" +
                                                        $"**Примечание**: {notes} \n\n" +
                                                        $"***Создатель рейда**: {ctx.Member.Mention}*");

            if (pollNeeded)
            {
                var pollTIme = new TimeSpan(0, 2, 0);

                //Эмоции голосования
                var emoji = DiscordEmoji.FromName(ctx.Client, ":white_check_mark:");

                var interactivity = ctx.Client.GetInteractivity();

                //Подсчёт нужных голосов - 50% + 1 голосов
                var votesNeeded = Math.Round((nShips * slots - 1) * 0.5 + 1, MidpointRounding.AwayFromZero);

                //Embed голосования
                var embed = new DiscordEmbedBuilder
                {
                    Title       = $"Голосование за создание рейда!",
                    Description = "Все проголосовавшие должны находиться в Общем канале рейда."
                };

                embed.WithFooter($"Голосование закончится через {Utility.FormatTimespan(pollTIme)}. Нужно {votesNeeded} голос(а).");

                await fleetCreationMessage.ModifyAsync(embed : embed.Build());

                //Добавляем реакции к сообщению
                await fleetCreationMessage.CreateReactionAsync(emoji);

                //Собираем данные
                var pollResult = await interactivity.CollectReactionsAsync(fleetCreationMessage, pollTIme);

                //Обработка результатов
                var votedUsers = await fleetCreationMessage.GetReactionsAsync(emoji);

                //Чистим реакции
                await fleetCreationMessage.DeleteAllReactionsAsync();

                //Каст из DiscordUser в DiscordMember для проверки активного канала
                var votedMembers = new List <DiscordMember>();
                foreach (var votedUser in votedUsers)
                {
                    votedMembers.Add(await ctx.Guild.GetMemberAsync(votedUser.Id));
                }

                var votesCount = votedMembers.Where(x => x.VoiceState?.Channel.Id == Bot.BotSettings.FleetLobby).Count();

                //Результат
                var resultEmbed = new DiscordEmbedBuilder
                {
                    Title = $"Голосование окончено! Голосов за: {votesCount}"
                };

                if (votesCount >= votesNeeded)
                {
                    resultEmbed.WithDescription($"{Bot.BotSettings.OkEmoji} Каналы рейда создаются.");
                    resultEmbed.WithFooter("Результаты голосования будут удалены через 30 секунд.");
                    resultEmbed.WithColor(new DiscordColor("00FF00"));
                    pollSucceded = true;
                }
                else
                {
                    resultEmbed.WithDescription($"{Bot.BotSettings.ErrorEmoji} Недостаточно голосов.");
                    resultEmbed.WithFooter("Сообщение будет удалено через 30 секунд.");
                    resultEmbed.WithColor(new DiscordColor("FF0000"));
                }

                await fleetCreationMessage.DeleteAllReactionsAsync();

                await fleetCreationMessage.ModifyAsync(embed : resultEmbed.Build());
            }

            //Если капитан или голосование успешное
            if (pollNeeded == false || (pollNeeded && pollSucceded))
            {
                var rootFleetCategory = ctx.Guild.GetChannel(Bot.BotSettings.FleetCategory);

                var fleetCategory = await rootFleetCategory.CloneAsync();

                await fleetCategory.AddOverwriteAsync(ctx.Guild.EveryoneRole, deny : Permissions.AccessChannels);

                await fleetCategory.ModifyAsync(x =>
                {
                    x.Name     = $"Рейд {notes}";
                    x.Position = rootFleetCategory.Position + 1;
                });

                var textChannel = await ctx.Guild.CreateChannelAsync($"рейд-{notes}", ChannelType.Text, fleetCategory);

                await ctx.Guild.CreateChannelAsync($"бронь-инвайты-{notes}", ChannelType.Text, fleetCategory);

                await ctx.Guild.CreateChannelAsync($"Общий - {notes}", ChannelType.Voice, fleetCategory, bitrate : Bot.BotSettings.Bitrate, userLimit : nShips *slots);

                nShips = nShips == 1 ? 0 : nShips; //Пропускаем в случае одного корабля, нужен только общий голосовой
                for (int i = 1; i <= nShips; i++)
                {
                    await ctx.Guild.CreateChannelAsync($"Рейд {i} - {notes}", ChannelType.Voice, fleetCategory, bitrate : Bot.BotSettings.Bitrate, userLimit : slots + 1);
                }

                await ctx.Guild.GetAuditLogsAsync(1); //Костыль, каналы в категории не успевают обновляться и последний канал не учитывается

                try
                {
                    //Отправка заготовленного сообщения в текстовый канал
                    var message = await ctx.Guild.GetChannel(Bot.BotSettings.FleetCaptainsChannel).GetMessageAsync(Bot.BotSettings.FleetShortCodexMessage);

                    message = await textChannel.SendMessageAsync(message.Content);

                    await message.ModifyEmbedSuppressionAsync(true);
                }
                catch (NullReferenceException)
                {
                    //Не удалось найти заготовленное сообщение, пропускаем
                }

                //Отправляем в лог рейдов сообщение о создании рейда
                await FleetLogging.LogFleetCreationAsync(ctx.Guild, ctx.Member, ctx.Guild.GetChannel(fleetCategory.Id));
            }

            //Чистим голосование после создания рейда
            if (pollNeeded || pollSucceded)
            {
                Thread.Sleep(30000);
                if (pollSucceded)
                {
                    await fleetCreationMessage.ModifyEmbedSuppressionAsync(true);
                }
                else
                {
                    await fleetCreationMessage.DeleteAsync();
                }
            }
        }