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 } }); }
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); }
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); } } }
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); } } }
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); }
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); } }
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)); }
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); } } }
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 ); }
// 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); }
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 { } }
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)); }
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); }
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)); }
/// <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."); } }
/// <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); }
internal static bool CanSendMessages(DiscordGuild g, DiscordChannel c) { return(c.PermissionsFor(g.CurrentMember).HasPermission(Permissions.SendMessages)); }
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); }
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`."); }
public static bool ChannelHasPermission(DiscordChannel channel, Permissions permission) { return(channel.PermissionsFor(channel.Guild.CurrentMember).HasPermission(permission)); }
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)); }