예제 #1
0
        public async Task Announce(CommandContext ctx, [Description("The channel to announce in.")] DiscordChannel channel, [Description("The message to announce.")] string message)
        {
            if (!channel.PermissionsFor(ctx.Member).HasFlag(Permissions.SendMessages))
            {
                throw new ChecksFailedException(ctx.Command, ctx,
                                                new[] { new RequireUserPermissionsAttribute(Permissions.SendMessages) });
            }

            if (!channel.PermissionsFor(ctx.Guild.Members[ctx.Client.CurrentUser.Id]).HasFlag(Permissions.SendMessages))
            {
                throw new ChecksFailedException(ctx.Command, ctx,
                                                new[] { new RequireBotPermissionsAttribute(Permissions.SendMessages) });
            }

            await channel.SendMessageAsync(new DiscordEmbedBuilder()
            {
                Title       = "📢 Announcement",
                Description = message,
                Color       = DiscordColor.Blue,
                Author      = new DiscordEmbedBuilder.EmbedAuthor()
                {
                    IconUrl = ctx.User.AvatarUrl,
                    Name    = ctx.Member.Nickname
                }
            });
        }
예제 #2
0
        private static Task CheckGameFansAsync(DiscordClient client, DiscordChannel channel, DiscordMessage message)
        {
            var bot = client.GetMember(channel.Guild, client.CurrentUser);
            var ch  = channel.IsPrivate ? channel.Users.FirstOrDefault(u => u.Id != client.CurrentUser.Id)?.Username + "'s DM" : "#" + channel.Name;

            if (!channel.PermissionsFor(bot).HasPermission(Permissions.AddReactions))
            {
                Config.Log.Debug($"No permissions to react in {ch}");
                return(Task.CompletedTask);
            }

            var mood = client.GetEmoji(":sqvat:", "😒");

            if (message.Reactions.Any(r => r.Emoji == mood && r.IsMe))
            {
                return(Task.CompletedTask);
            }

            var reactionMsg = string.Concat(message.Reactions.Select(r => TextMap.TryGetValue(r.Emoji, out var txt) ? txt : " ")).Trim();

            if (string.IsNullOrEmpty(reactionMsg))
            {
                return(Task.CompletedTask);
            }

            Config.Log.Debug($"Emoji text: {reactionMsg} (in {ch})");
            return(Task.CompletedTask);
        }
예제 #3
0
        async Task NotifyDeleteAsync(DiscordMessage message, DiscordGuild guild)
        {
            if (guild == null)
            {
                return;
            }
            string content;

            content = message.Content ?? "(Message too old...)";
            if (content.Length == 0)
            {
                content = "(Empty)";
            }
            DiscordChannel channel = (await guild.GetChannelsAsync()).First(c => c.Name == "logs");

            if (channel != null)
            {
                Permissions permissions = channel.PermissionsFor(guild.CurrentMember);
                if ((permissions & Permissions.SendMessages) != 0)
                {
                    DiscordEmbedBuilder embedBuilder = MakeDeleteMessageEmbed(message, content);
                    await channel.SendMessageAsync(embed : embedBuilder.Build()).ConfigureAwait(false);
                }
            }
        }
예제 #4
0
        async Task NotifyModifyAsync(DiscordMessage before, DiscordMessage after, DiscordGuild guild)
        {
            string content;

            content = before?.Content ?? "(메세지가 너무 오래되었습니다...)";
            if (content.Length == 0)
            {
                content = "(Empty)";
            }
            if (content == after.Content)
            {
                return;
            }
            DiscordChannel channel = (await guild.GetChannelsAsync()).First(c => c.Name == "logs");

            if (channel != null)
            {
                Permissions permissions = channel.PermissionsFor(guild.CurrentMember);
                if ((permissions & Permissions.SendMessages) != 0)
                {
                    DiscordEmbedBuilder embedBuilder = MakeModifyMessageEmbed(after, content);
                    await channel.SendMessageAsync(embed : embedBuilder.Build()).ConfigureAwait(false);
                }
            }
        }
예제 #5
0
        public ChannelViewModel(DiscordChannel channel, WindowHandle window)
        {
            if (channel.Type == ChannelType.Voice)
            {
                throw new InvalidOperationException("Unable to create a view model for a voice chanel"); // no op this
            }
            _windowHandle       = window;
            _strings            = ResourceLoader.GetForCurrentView("ChannelPage");
            _loadSemaphore      = new SemaphoreSlim(1, 1);
            _context            = SynchronizationContext.Current;
            _typingCancellation = new ConcurrentDictionary <ulong, CancellationTokenSource>();
            _typingLastSent     = DateTime.Now - TimeSpan.FromSeconds(10);

            _channel     = channel;
            _currentUser = channel.Guild?.CurrentMember ?? App.Discord.CurrentUser;
            _messages    = new ObservableCollection <DiscordMessage>();

            App.Discord.TypingStarted  += OnTypingStarted;
            App.Discord.MessageCreated += OnMessageCreated;
            App.Discord.MessageDeleted += OnMessageDeleted;
            App.Discord.ChannelUpdated += OnChannelUpdated;
            App.Discord.Resumed        += OnResumed;

            TypingUsers = new ObservableCollection <DiscordUser>();
            FileUploads = new ObservableCollection <FileUploadModel>();
            FileUploads.CollectionChanged += (o, e) =>
            {
                InvokePropertyChanged(nameof(DisplayUploadSize));
                InvokePropertyChanged(nameof(UploadProgressBarValue));
                InvokePropertyChanged(nameof(CanSend));
                InvokePropertyChanged(nameof(UploadInfoForeground));
                InvokePropertyChanged(nameof(CanUpload));
                InvokePropertyChanged(nameof(ShowUploads));
            };

            if (channel.Guild != null)
            {
                Permissions = _channel.PermissionsFor(channel.Guild.CurrentMember);
            }
            else
            {
                Permissions = Permissions.Administrator;
            }

            _slowModeTimer = new DispatcherTimer()
            {
                Interval = TimeSpan.FromMilliseconds(1 / 30)
            };
            _slowModeTimer.Tick += (o, e) =>
            {
                SlowModeTimeout = Math.Max(0, PerUserRateLimit - (DateTimeOffset.Now - _messageLastSent).TotalMilliseconds);
                InvokePropertyChanged(nameof(ShowSlowModeTimeout));
                if (SlowModeTimeout == 0)
                {
                    InvokePropertyChanged(nameof(CanSend));
                    _slowModeTimer.Stop();
                }
            };
        }
        public async Task SetChannel(CommandContext ctx, DiscordChannel channel = null)
        {
            if (ctx.Member.PermissionsIn(ctx.Channel).HasPermission(Permissions.Administrator) || Bot.BotOwnerIds.Contains(ctx.User.Id))
            {
                if (channel == null)
                {
                    channel = ctx.Channel;
                }
                if (channel.Type == DSharpPlus.ChannelType.Text)
                {
                    var member = await ctx.Guild.GetMemberAsync(ctx.Client.CurrentUser.Id);

                    //TODO BROKEN, WAIT FOR DSHARPPLUS TO FIX THIS GARBAGE
                    var perm = channel.PermissionsFor(member);
                    var requiredPermissions = new Permissions[] {
                        Permissions.ReadMessageHistory,
                        Permissions.SendMessages,
                        Permissions.AddReactions,
                        Permissions.UseExternalEmojis,
                        Permissions.EmbedLinks,
                        Permissions.AccessChannels,
                    };
                    foreach (var p in requiredPermissions)
                    {
                        if (!perm.HasPermission(p))
                        {
                            await ctx.RespondAsync($"I'm missing some permissions to work there! I need these permissions to work properly\n{string.Join("\n", requiredPermissions.Select(x => x.ToPermissionString()))}");

                            return;
                        }
                    }
                    var guild = Bot.GuildOptions.Find(x => x.Id == ctx.Guild.Id);
                    if (guild == null)
                    {
                        guild = new GuildOption {
                            Id = ctx.Guild.Id
                        };
                    }
                    guild.Channel = channel.Id;
                    try {
                        DB.Upsert(GuildOption.DBName, GuildOption.TableName, guild);
                        Bot.UpdateGuildOptions();
                        await ctx.RespondAsync($"👌 New default channel is now {guild.GetChannel()}");
                    } catch (System.Exception ex) {
                        Logger.Error(ex);
                    }
                }
                else
                {
                    await ctx.RespondAsync("Seems like I can't post messages, or add reactions in that channel!");

                    return;
                }
            }
            else
            {
                await ctx.RespondAsync("This command can only be used by server admins.");
            }
        }
        public async Task ScheduleGuildEvent(
            CommandContext context,
            [Description("The channel to announce the event in")]
            DiscordChannel announcementChannel,
            [Description("The role to announce the event to")]
            DiscordRole role,
            [Description("The date to schedule the event for")]
            [RemainingText]
            string datetimeString
            )
        {
            using IBotAccessProvider provider = this.accessBuilder.Build();

            if (!context.User.TryGetDateTimeZone(provider, this.timeZoneProvider, out DateTimeZone schedulerTimeZone))
            {
                await context.RespondAsync(StringConstants.NoTimeZoneErrorMessage);

                return;
            }

            DiscordMember botMember = await context.Guild.GetMemberAsync(context.Client.CurrentUser.Id);

            if (!announcementChannel.PermissionsFor(botMember).HasPermission(Permissions.SendMessages | Permissions.MentionEveryone))
            {
                await context.RespondAsync($"{context.Member.Mention}, I don't have permission to send messages and mention `@everyone` in that channel.");

                return;
            }

            LocalDateTime datetime = Recognizers.RecognizeDateTime(datetimeString, DateTimeV2Type.DateTime)
                                     .First().Values.Select(value => (LocalDateTime)value.Value).OrderBy(key => key).First();
            DiscordMessage msg = await context.RespondAsync($":wave: Hi, {context.User.Mention}! You want to schedule an event for {datetime:g} in your timezone?");

            InteractivityExtension interactivity = context.Client.GetInteractivity();
            Reaction reaction = await interactivity.AddAndWaitForYesNoReaction(msg, context.User);

            if (reaction != Reaction.Yes)
            {
                return;
            }

            DiscordEmbedBuilder scheduleEmbedBase = new DiscordEmbedBuilder()
                                                    .WithTitle("Select an event by typing: <event number>")
                                                    .WithColor(context.Member.Color);

            GuildEvent selectedEvent = await SelectPredefinedEvent(context, provider, msg, interactivity, scheduleEmbedBase);

            Instant      eventDateTime = datetime.InZoneStrictly(schedulerTimeZone).ToInstant();
            DiscordEmbed embed         = new DiscordEmbedBuilder()
                                         .WithAuthor(context.Member.DisplayName, iconUrl: context.Member.AvatarUrl)
                                         .WithDescription(selectedEvent.EventDesc)
                                         .WithTitle(selectedEvent.EventName)
                                         .Build();
            await msg.ModifyAsync($"You have scheduled the following event for {datetime:g} in your time zone to be output in the {announcementChannel.Mention} channel.", embed : embed);

            this.ScheduleEventsForRole(context, announcementChannel, provider, selectedEvent, eventDateTime, role);
        }
예제 #8
0
        private async Task AddReminderAsync(CommandContext ctx, TimeSpan timespan, DiscordChannel channel,
                                            string message, bool repeat = false)
        {
            if (string.IsNullOrWhiteSpace(message))
            {
                throw new InvalidCommandUsageException("Missing time or repeat string.");
            }

            if (message.Length > 250)
            {
                throw new InvalidCommandUsageException("Message must be shorter than 250 characters.");
            }

            if (!(channel is null) && !channel.PermissionsFor(ctx.Member).HasPermission(Permissions.AccessChannels | Permissions.SendMessages))
            {
                throw new CommandFailedException("You cannot send reminder to that channel!");
            }

            if (channel is null && await ctx.Client.CreateDmChannelAsync(ctx.User.Id) is null)
            {
                throw new CommandFailedException("I cannot send DMs to you, please enable it so that I can remind you.");
            }

            bool privileged;

            using (DatabaseContext db = this.Database.CreateContext())
                privileged = db.PrivilegedUsers.Any(u => u.UserId == ctx.User.Id);

            if (!ctx.Client.CurrentApplication.Owners.Any(o => o.Id == ctx.User.Id) && !privileged)
            {
                if (timespan < TimeSpan.Zero || timespan.TotalMinutes < 1 || timespan.TotalDays > 31)
                {
                    throw new InvalidCommandUsageException("Time span cannot be less than 1 minute or greater than 31 days.");
                }
                if (this.Shared.RemindExecuters.TryGetValue(ctx.User.Id, out ConcurrentDictionary <int, SavedTaskExecutor> texecs) && texecs.Count >= 20)
                {
                    throw new CommandFailedException("You cannot have more than 20 reminders scheduled!");
                }
            }

            DateTimeOffset when = DateTimeOffset.Now + timespan;

            var task = new SendMessageTaskInfo(channel?.Id ?? 0, ctx.User.Id, message, when, repeat, timespan);
            await SavedTaskExecutor.ScheduleAsync(this.Shared, this.Database, ctx.Client, task);

            if (repeat)
            {
                await this.InformAsync(ctx, StaticDiscordEmoji.AlarmClock, $"I will repeatedly remind {channel?.Mention ?? "you"} every {Formatter.Bold(timespan.Humanize(4, minUnit: TimeUnit.Second))} to:\n\n{message}", important : false);
            }
            else
            {
                await this.InformAsync(ctx, StaticDiscordEmoji.AlarmClock, $"I will remind {channel?.Mention ?? "you"} in {Formatter.Bold(timespan.Humanize(4, minUnit: TimeUnit.Second))} ({when.ToUtcTimestamp()}) to:\n\n{message}", important : false);
            }
        }
예제 #9
0
        public static bool ChannelHasPermission(DiscordChannel channel, Permissions permission)
        {
            DiscordMember member = channel.Guild.CurrentMember;

            if (member == null)
            {
                Logger.Debug("CurrentMember was false when evaluating channel permissions for channel " + channel.Name);
                return(false);
            }

            return(channel.PermissionsFor(member).HasPermission(permission));
        }
예제 #10
0
        private async Task NotifyLogAsync(DiscordEmbed embed, DiscordGuild guild)
        {
            DiscordChannel channel = (await guild.GetChannelsAsync()).First(c => c.Name == "logs");

            if (channel != null)
            {
                Permissions permissions = channel.PermissionsFor(guild.CurrentMember);
                if ((permissions & Permissions.SendMessages) != 0)
                {
                    await channel.SendMessageAsync(embed : embed).ConfigureAwait(false);
                }
            }
        }
예제 #11
0
        public static async Task GuildCreateEventHandlerAsync(TheGodfatherBot bot, GuildCreateEventArgs e)
        {
            LogExt.Information(bot.GetId(e.Guild.Id), "Joined {NewGuild}", e.Guild);

            if (bot.Services.GetRequiredService <BlockingService>().IsGuildBlocked(e.Guild.Id))
            {
                LogExt.Information(bot.GetId(e.Guild.Id), "{Guild} is blocked. Leaving...", e.Guild);
                await e.Guild.LeaveAsync();

                return;
            }

            IReadOnlyCollection <DiscordMember> members = await e.Guild.GetAllMembersAsync();

            int botCount = members.Where(m => m.IsBot).Count();

            if (botCount > 25 || (members.Count - botCount < 0))
            {
                LogExt.Information(bot.GetId(e.Guild.Id), "{Guild} is most likely a bot farm. Leaving and blocking...", e.Guild);
                await e.Guild.LeaveAsync();

                await bot.Services.GetRequiredService <BlockingService>().BlockGuildAsync(e.Guild.Id, "Bot farm");

                return;
            }

            await bot.Services.GetRequiredService <GuildConfigService>().RegisterGuildAsync(e.Guild.Id);

            DiscordChannel defChannel = e.Guild.GetDefaultChannel();

            if (!defChannel.PermissionsFor(e.Guild.CurrentMember).HasPermission(Permissions.SendMessages))
            {
                return;
            }

            string prefix = bot.Services.GetRequiredService <BotConfigService>().CurrentConfiguration.Prefix;
            string owners = bot.Client.CurrentApplication.Owners.Select(o => o.ToDiscriminatorString()).Humanize(", ");
            await defChannel.EmbedAsync(
                $"{Formatter.Bold("Thank you for adding me!")}\n\n" +
                $"{Emojis.SmallBlueDiamond} The default prefix for commands is {Formatter.Bold(prefix)}, but it can be changed " +
                $"via {Formatter.Bold("prefix")} command.\n" +
                $"{Emojis.SmallBlueDiamond} I advise you to run the configuration wizard for this guild in order to quickly configure " +
                $"functions like logging, notifications etc. The wizard can be invoked using {Formatter.Bold("config setup")} command.\n" +
                $"{Emojis.SmallBlueDiamond} You can use the {Formatter.Bold("help")} command as a guide, though it is recommended to " +
                $"read the documentation @ https://github.com/ivan-ristovic/the-godfather \n" +
                $"{Emojis.SmallBlueDiamond} If you have any questions or problems, feel free to use the {Formatter.Bold("report")} " +
                $"command in order to send a message to the bot owners ({owners}). Alternatively, you can create an issue on " +
                $"GitHub or join WorldMafia Discord server for quick support (https://worldmafia.net/discord)."
                , Emojis.Wave
                );
        }
예제 #12
0
        // We funnel all "permissions from DiscordMember" calls through here
        // This way we can ensure we do the read permission correction everywhere
        private static Permissions PermissionsInGuild(DiscordChannel channel, DiscordMember member)
        {
            ValidateCachedRoles(member);
            var permissions = channel.PermissionsFor(member);

            // This method doesn't account for channels without read permissions
            // If we don't have read permissions in the channel, we don't have *any* permissions
            if ((permissions & Permissions.AccessChannels) != Permissions.AccessChannels)
            {
                return(Permissions.None);
            }

            return(permissions);
        }
예제 #13
0
        public async Task SayCommand(CommandContext ctx,
                                     [Description("Channel to send the message in")] DiscordChannel channel,
                                     [Description("Text to send")][RemainingText] string text)
        {
            if (channel.GuildId != ctx.Guild.Id)
            {
                return;
            }
            if (!(channel.PermissionsFor(ctx.Member).HasPermission(Permissions.ManageMessages) || ctx.Member.Id.ToString() == Configuration["Owner"]))
            {
                throw new UserError("You don't have permission to do that");
            }
            await channel.SendMessageAsync(text);

            try { await ctx.Message.DeleteAsync(); } catch { }
        }
예제 #14
0
        public static bool ChannelHasPermission(DiscordChannel channel, Permissions permission)
        {
            if (channel as DiscordDmChannel != null)
            {
                return(true);                                     // Assume permission is given for DMs
            }
            DiscordMember member = channel.Guild.CurrentMember;

            if (member == null)
            {
                Logger.Debug("CurrentMember was null when evaluating channel permissions for channel " + channel.Name);
                return(false);
            }

            return(channel.PermissionsFor(member).HasPermission(permission));
        }
예제 #15
0
        private async Task RegisterRoyalRoadFictionAsync(CommandContext context, DiscordChannel announcementChannel, DiscordRole?announcementRole, bool pingEveryone, bool pingNoOne, string royalroadUrl)
        {
            if (!announcementChannel.PermissionsFor(context.Guild.CurrentMember).HasFlag(DSharpPlus.Permissions.SendMessages | DSharpPlus.Permissions.EmbedLinks))
            {
                await context.RespondAsync($"{context.Member.Mention}, the channel provided doesn't let me send messages. Please try again after you have set permissions such that I can send messages in that channel.");

                return;
            }

            NovelInfo fictionInfo = await this.GetNovelInfoFromUrl(context, royalroadUrl);

            // Register the channel and role
            DbResult <GuildNovelRegistration> registerResult = await this.mediator.Send(
                new GuildNovelRegistrations.Add(
                    context.Guild.Id,
                    announcementChannel.Id,
                    pingEveryone,
                    pingNoOne,
                    announcementRole?.Id,
                    fictionInfo.Id,
                    null,
                    false
                    )
                );

            if (!registerResult.TryGetValue(out GuildNovelRegistration? gnr))
            {
                await context.RespondAsync("The registration of the novel failed.");

                throw new Exception("Novel registration failed");
            }

            string content = new StringBuilder()
                             .Append($"I have registered  \"{fictionInfo.Name}\" updates to be output in {announcementChannel.Mention} ")
                             .Append(gnr.PingEveryone ? "for @everyone" : "")
                             .Append(gnr.PingNoOne ? "for everyone but without any ping" : "")
                             .Append(gnr.RoleId != null ? $"for members with the {announcementRole!.Mention} role" : "")
                             .ToString();

            await new DiscordMessageBuilder()
            .WithContent(content)
            .WithAllowedMentions(Mentions.None)
            .SendAsync(context.Channel);
        }
예제 #16
0
        public static async Task GuildCreateEventHandlerAsync(TheGodfatherShard shard, GuildCreateEventArgs e)
        {
            shard.Log(LogLevel.Info, $"Joined guild: {e.Guild.ToString()}");

            await RegisterGuildAsync(shard.SharedData, shard.Database, e.Guild.Id);

            DiscordChannel defChannel = e.Guild.GetDefaultChannel();

            if (!defChannel.PermissionsFor(e.Guild.CurrentMember).HasPermission(Permissions.SendMessages))
            {
                return;
            }

            await defChannel.EmbedAsync(
                $"{Formatter.Bold("Thank you for adding me!")}\n\n" +
                $"{StaticDiscordEmoji.SmallBlueDiamond} The default prefix for commands is {Formatter.Bold(shard.SharedData.BotConfiguration.DefaultPrefix)}, but it can be changed using {Formatter.Bold("prefix")} command.\n" +
                $"{StaticDiscordEmoji.SmallBlueDiamond} I advise you to run the configuration wizard for this guild in order to quickly configure functions like logging, notifications etc. The wizard can be invoked using {Formatter.Bold("guild config setup")} command.\n" +
                $"{StaticDiscordEmoji.SmallBlueDiamond} You can use the {Formatter.Bold("help")} command as a guide, though it is recommended to read the documentation @ https://github.com/ivan-ristovic/the-godfather \n" +
                $"{StaticDiscordEmoji.SmallBlueDiamond} If you have any questions or problems, feel free to use the {Formatter.Bold("report")} command in order to send a message to the bot owners ({string.Join(", ", e.Client.CurrentApplication.Owners.Select(o => $"{o.Username}#{o.Discriminator}"))}). Alternatively, you can create an issue on GitHub or join WorldMafia Discord server for quick support (https://discord.me/worldmafia)."
                , StaticDiscordEmoji.Wave
                );
        }
 /// <summary>Whether the bot has the permission to perform an action in the given chanel.</summary>
 public static bool BotCan(this DiscordChannel channel, Permissions permission)
 {
     return(channel.Guild is null
         ? DmPermissions.HasFlag(permission)
         : channel.PermissionsFor(channel.Guild.CurrentMember).HasFlag(permission));
 }
예제 #18
0
        /// <summary>
        /// Fire this after receiving a message from the web bridge.
        /// Current actions supported: Send, Delete
        /// </summary>
        /// <param name="message">The message coming from the SignalR hub.</param>
        /// <returns>The task representing the message's processing status.</returns>
        public async Task IngestSignalR(BridgeMessage message)
        {
            if (!Ready)
            {
                throw new NullReferenceException("Guild not found.");
            }

            if (message.SignalRMessage.Action == "NewMessage")
            {
                DiscordChannel bridgeChannel = await this.discordClient.GetChannelAsync(ChannelId);

                DiscordMember guildMember = await bridgeChannel.Guild.GetMemberAsync(message.UserId);

                NewMessage newMessage = message.SignalRMessage as NewMessage;

                MatchCollection colonEmotes       = Regex.Matches(newMessage.Content, @":[a-zA-Z0-9_~]+:(?!\d+)");
                string          translatedContent = newMessage.Content;
                List <string>   translatedEmotes  = new List <string>(colonEmotes.Count);

                foreach (Match colonEmote in colonEmotes)
                {
                    if (translatedEmotes.Contains(colonEmote.Value))
                    {
                        break;
                    }

                    try
                    {
                        DiscordEmoji emote = DiscordEmoji.FromName(discordClient, colonEmote.Value);
                        if (emote.Id == 0)
                        {
                            translatedContent = translatedContent.Replace(colonEmote.Value, emote.Name);
                        }
                        else if (emote.IsAnimated)
                        {
                            translatedContent = translatedContent.Replace(colonEmote.Value, $"<a:{emote.Name}:{emote.Id}>");
                        }
                        else if (!emote.IsAnimated)
                        {
                            translatedContent = translatedContent.Replace(colonEmote.Value, $"<:{emote.Name}:{emote.Id}>");
                        }

                        translatedEmotes.Add(colonEmote.Value);
                    }
                    catch
                    {
                        // The emote doesn't exist on the target server, or it's been deleted.
                        // Just do nothing (don't attempt to translate it)
                    }
                }

                if (guildMember == null)
                {
                    throw new UnauthorizedAccessException("Not in Discord guild.");
                }
                else
                {
                    await webhookClient.Webhooks[0].ExecuteAsync(new DiscordWebhookBuilder()
                    {
                        Content   = translatedContent,
                        Username  = guildMember.DisplayName,
                        AvatarUrl = guildMember.AvatarUrl,
                        IsTTS     = false
                    });
                }
            }
            else if (message.SignalRMessage.Action == "DeleteMessage")
            {
                DiscordChannel bridgeChannel = await this.discordClient.GetChannelAsync(ChannelId);

                DiscordMember guildMember = await bridgeChannel.Guild.GetMemberAsync(message.UserId);

                if (guildMember == null)
                {
                    return;
                }

                if (bridgeChannel.PermissionsFor(guildMember).HasPermission(Permissions.ManageMessages))
                {
                    DiscordMessage delMessage = await bridgeChannel.GetMessageAsync(ulong.Parse(message.SignalRMessage.MessageId));

                    await delMessage.DeleteAsync();

                    return;
                }

                // Nothing to do, user doesn't have permission to delete the message.
                return;
            }
            else
            {
                throw new InvalidOperationException("Undefined action.");
            }
        }
예제 #19
0
        /// <summary>
        /// Create a VoiceNext connection for the specified channel.
        /// </summary>
        /// <param name="channel">Channel to connect to.</param>
        /// <returns>VoiceNext connection for this channel.</returns>
        public async Task <VoiceNextConnection> ConnectAsync(DiscordChannel channel)
        {
            if (channel.Type != ChannelType.Voice)
            {
                throw new ArgumentException(nameof(channel), "Invalid channel specified; needs to be voice channel");
            }

            if (channel.Guild == null)
            {
                throw new ArgumentException(nameof(channel), "Invalid channel specified; needs to be guild channel");
            }

            if (!channel.PermissionsFor(channel.Guild.CurrentMember).HasPermission(Permissions.UseVoice))
            {
                throw new InvalidOperationException("You need UseVoice permission to connect to this voice channel");
            }

            var gld = channel.Guild;

            if (ActiveConnections.ContainsKey(gld.Id))
            {
                throw new InvalidOperationException("This guild already has a voice connection");
            }

            var vstut = new TaskCompletionSource <VoiceStateUpdateEventArgs>();
            var vsrut = new TaskCompletionSource <VoiceServerUpdateEventArgs>();

            this.VoiceStateUpdates[gld.Id]  = vstut;
            this.VoiceServerUpdates[gld.Id] = vsrut;

            var vsd = new VoiceDispatch
            {
                OpCode  = 4,
                Payload = new VoiceStateUpdatePayload
                {
                    GuildId   = gld.Id,
                    ChannelId = channel.Id,
                    Deafened  = false,
                    Muted     = false
                }
            };
            var vsj = JsonConvert.SerializeObject(vsd, Formatting.None);

            await(channel.Discord as DiscordClient)._webSocketClient.SendMessageAsync(vsj).ConfigureAwait(false);

            var vstu = await vstut.Task.ConfigureAwait(false);

            var vstup = new VoiceStateUpdatePayload
            {
                SessionId = vstu.SessionId,
                UserId    = vstu.User.Id
            };
            var vsru = await vsrut.Task.ConfigureAwait(false);

            var vsrup = new VoiceServerUpdatePayload
            {
                Endpoint = vsru.Endpoint,
                GuildId  = vsru.Guild.Id,
                Token    = vsru.VoiceToken
            };

            var vnc = new VoiceNextConnection(this.Client, gld, channel, this.Configuration, vsrup, vstup);

            vnc.VoiceDisconnected += this.Vnc_VoiceDisconnected;
            await vnc.ConnectAsync().ConfigureAwait(false);

            await vnc.WaitForReadyAsync().ConfigureAwait(false);

            this.ActiveConnections[gld.Id] = vnc;
            return(vnc);
        }
예제 #20
0
파일: Tools.cs 프로젝트: eclipseanu/WamBot
 internal static bool CanSendMessages(DiscordGuild g, DiscordChannel c)
 {
     return(c.PermissionsFor(g.CurrentMember).HasPermission(Permissions.SendMessages));
 }
예제 #21
0
        public MainGUI()
        {
            Application.Init();
            Toplevel top = Application.Top;

            // Creates a menubar, the item "New" has a help menu.
            menu = new MenuBar(new[] {
                new MenuBarItem("_File",
                                new[] {
                    new MenuItem("_Quit",
                                 "",
                                 () => {
                        top.Running = false;
                    }),
                    new MenuItem("_Save",
                                 "",
                                 () => {                                                               /*Todo*/
                    })
                })
            });
            top.Add(menu);

            // Creates the top-level window to show
            mainWin = new Window(Program.Config.Nickname)
            {
                X = 0,
                Y = 1,                 // Leave one row for the toplevel menu

                // By using Dim.Fill(), it will automatically resize without manual intervention
                Width  = Dim.Fill(),
                Height = Dim.Fill()
            };
            top.Add(mainWin);
            chanListWin = new Window("Channel List")
            {
                X      = 0,
                Y      = 0,
                Width  = Dim.Percent(25),
                Height = Dim.Fill()
            };
            serverListView = new ListView {
                X             = 0,
                Y             = 0,
                Width         = Dim.Fill(),
                Height        = Dim.Percent(50),
                AllowsMarking = true,
                CanFocus      = true
            };
            chanListView = new ListView {
                X             = 0,
                Y             = Pos.Bottom(serverListView) + 1,
                Width         = Dim.Fill(),
                Height        = Dim.Fill(1),
                AllowsMarking = true,
                CanFocus      = true
            };
            serverListView.SelectedChanged += () => {
                for (int i = 0; i < servers.Count; i++)
                {
                    if (serverListView.Source.IsMarked(i))
                    {
                        if (selectedServer != i)
                        {
                            selectedServer = i;
                            for (int i2 = 0; i2 < servers.Count; i2++)
                            {
                                bool mark = selectedServer == i2;
                                serverListView.Source.SetMark(i2, mark);
                            }

                            UpdateChannels();
                            return;
                        }
                    }
                }
            };
            chanListView.SelectedChanged += () => {
                for (int i = 0; i < channels.Count; i++)
                {
                    if (chanListView.Source.IsMarked(i))
                    {
                        if (selectedChannel != i)
                        {
                            selectedChannel = i;
                            for (int i2 = 0; i2 < channels.Count; i2++)
                            {
                                bool mark = selectedChannel == i2;
                                chanListView.Source.SetMark(i2, mark);
                            }

                            UpdateLogs();
                            return;
                        }
                    }
                }
            };
            chanListWin.Add(serverListView);
            chanListWin.Add(chanListView);
            mainWin.Add(chanListWin);
            messagesWin = new Window("Message Log")
            {
                X      = Pos.Right(chanListWin),
                Y      = 0,
                Width  = Dim.Fill(),
                Height = Dim.Fill()
            };
            mainWin.Add(messagesWin);
            messagesListView = new ListView {
                X      = 0,
                Y      = 0,
                Width  = Dim.Fill(),
                Height = Dim.Fill(1)
            };
            //TimeSpan periodTimeSpan = TimeSpan.FromMilliseconds(200);
            Application.MainLoop.AddIdle(UpdateData);
            messagesWin.Add(messagesListView);
            messagesTextField = new EnterTextField("")
            {
                X      = 0,
                Y      = Pos.Bottom(messagesListView),
                Width  = Dim.Fill(),
                Height = 1
            };
            messagesTextField.Changed += async(_, __) => {
                if (selectedServer == 0)
                {
                    return;
                }

                if (messagesTextField.Text.IsEmpty)
                {
                    return;
                }

                if (LinkedChannels[selectedChannel] is LinkedDiscordChannel linkedDiscordChannel)
                {
                    DiscordChannel discordChannel = linkedDiscordChannel;
                    if ((discordChannel.PermissionsFor(discordChannel.Guild.CurrentMember) & Permissions.SendMessages) != 0)
                    {
                        await discordChannel.TriggerTypingAsync();
                    }
                    else
                    {
                        messagesTextField.Text = ustring.Empty;
                    }
                }
            };
            messagesTextField.TextEnter += OnMessage;
            messagesWin.Add(messagesTextField);
            top.SetFocus(messagesTextField);
            Colors.Base.Focus  = Attribute.Make(Color.Black, Color.BrightRed);
            Colors.Base.Normal = Attribute.Make(Color.Red, Color.Black);
        }
예제 #22
0
        public async Task SetupAsync(CommandContext ctx,
                                     [Description("Channel to direct pinned messages to")] DiscordChannel channel,
                                     [Description("The URL of the webhook to use, including a token (optional)")] Uri webhookUrl = null)
        {
            if (!ctx.Guild.Channels.ContainsKey(channel.Id))
            {
                await ctx.RespondAsync("Are you trying to migrate pins across servers?? That ain't gonna fly, kid.");

                return;
            }

            var info = await _database.FindAsync <GuildInfo>((long)ctx.Guild.Id);

            if (info != null)
            {
                // TODO: prompt to reconfigure/setup
                _logger.LogError("Unable to setup pins in {0} because it is already setup.", ctx.Guild);
                await ctx.RespondAsync("Pinned message redireciton is already enabled in this server!");

                return;
            }

            var perms = channel.PermissionsFor(ctx.Guild.CurrentMember);

            if (!perms.HasPermission(Permissions.ManageWebhooks) && webhookUrl == null)
            {
                _logger.LogError("Unable to setup pins in {0} due to lack of permissions.", ctx.Guild);
                await ctx.RespondAsync("I can't setup pins without a Webhook URL or permission to manage webhooks! Sorry!");

                return;
            }

            DiscordWebhook hook;

            if (webhookUrl != null)
            {
                try
                {
                    hook = await _webhookClient.AddWebhookAsync(webhookUrl);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Failed to fetch webhook from URL.");
                    await ctx.RespondAsync("The Webhook URL you specified was invalid!");

                    return;
                }
            }
            else
            {
                hook = await channel.CreateWebhookAsync("GAiA Pins", reason : $"Pinned Message redirection setup by @{ctx.User.Username}#{ctx.User.Discriminator} ({ctx.User.Id})");

                _webhookClient.AddWebhook(hook);
            }

            var guild = new GuildInfo()
            {
                Id = (long)ctx.Guild.Id, WebhookId = (long)hook.Id, WebhookToken = hook.Token, PinsChannelId = (long)channel.Id
            };

            _database.Add(guild);

            await _database.SaveChangesAsync();

            await ctx.RespondAsync(
                "Pinned messages are now setup for this server!\n" +
                "To migrate pins, use `p;migrate`, and to configure further, use `p;configure`.\n" +
                "Disable at any time with `p;disable`.");
        }
예제 #23
0
 public static bool ChannelHasPermission(DiscordChannel channel, Permissions permission)
 {
     return(channel.PermissionsFor(channel.Guild.CurrentMember).HasPermission(permission));
 }
예제 #24
0
        private bool HavePermission(Permissions perm, DiscordChannel inChannel = null, DiscordGuild inGuild = null)
        {
            inGuild ??= Guild;
            var roles = inGuild.CurrentMember.Roles.ToArray();

            return(roles.Any(role => role.Permissions.HasPermission(Permissions.Administrator)
                             ||
                             role.Permissions.HasPermission(perm)) && (inChannel == null || (inChannel.PermissionsFor(inGuild.CurrentMember) & perm) != 0));
        }