public override async Task <CommandResult> RunCommand(string[] args, CommandContext context) { try { if (context.Author is DiscordMember memb) { DiscordVoiceState state = memb?.VoiceState; if (state != null) { //if (Program.ConnectionModel != null) //{ return(await RunVoiceCommand(args, context, Program.ConnectionModel)); //} //else //{ // await context.ReplyAsync("I'm not actually connected in here! F**k off!"); //} } else { await context.ReplyAsync("You'll need to connect to voice before you can do that!"); } } else { await context.ReplyAsync("I can only leave voice channels within guilds, sorry!"); } } catch (TaskCanceledException) { } catch (OperationCanceledException) { } catch (InvalidOperationException) { } return(CommandResult.Empty); }
public DUser(CommandContext ctx, Boolean FullSetup = false, ulong VoiceChn = 0) { if (!FullSetup) { Setup(ctx.Channel.Id, 0, ctx.Member.Id, ctx.Member.Guild.Id); } else { DiscordChannel chn = null; try { if (VoiceChn == 0) { DiscordVoiceState vstat = ctx.Member.VoiceState; if (vstat.Channel == null && chn == null) { // they did not specify a channel and are not in one } else { chn = vstat.Channel; } } else { Task <DiscordChannel> t = Program.discord.GetChannelAsync(VoiceChn); t.Wait(); chn = t.Result; } }catch (Exception e) { Utils.Log(e.Message + ":" + e.StackTrace, LogType.Error); } ulong CnhID = (chn == null) ? 394488303161704448 : chn.Id; Setup(ctx.Channel.Id, CnhID, ctx.Member.Id, ctx.Channel.Guild.Id, ctx.Command.ToString(), ctx.Message.Content.Split(' '), null); } }
public async Task ConnectAsync(CommandContext ctx, [Description("Channel.")] DiscordChannel channel = null) { VoiceNextExtension vnext = ctx.Client.GetVoiceNext(); if (vnext == null) { throw new CommandFailedException("VNext is not enabled or configured."); } VoiceNextConnection vnc = vnext.GetConnection(ctx.Guild); if (vnc != null) { throw new CommandFailedException("Already connected in this guild."); } DiscordVoiceState vstat = ctx.Member?.VoiceState; if ((vstat == null || vstat.Channel == null) && channel == null) { throw new CommandFailedException("You are not in a voice channel."); } if (channel == null) { channel = vstat.Channel; } vnc = await vnext.ConnectAsync(channel); await this.InformAsync(ctx, StaticDiscordEmoji.Headphones, $"Connected to {Formatter.Bold(channel.Name)}.", important : false); }
public void OnVoiceStateUpdated(DiscordVoiceState voiceState) { foreach (var e in voice) { e.OnVoiceStateUpdated(voiceState); } }
public async Task Join(CommandContext ctx, DiscordChannel chn = null) { _vnext = ctx.Client.GetVoiceNext(); if (_vnext == null) { await ctx.RespondAsync(":x: VNext is not enabled or configured."); return; } VoiceNextConnection vnc = _vnext.GetConnection(ctx.Guild); if (vnc != null) { await ctx.RespondAsync("Already connected."); return; } DiscordVoiceState vstat = ctx.Member?.VoiceState; if (vstat?.Channel == null && chn == null) { await ctx.RespondAsync("You are not in a voice channel."); return; } if (chn == null) { chn = vstat.Channel; } await chn.ConnectAsync(); await ctx.RespondAsync($"Connected to `{chn.Name}`"); }
public async Task Hawk(CommandContext ctx, DiscordMember member, bool debug = false) { //if (debug && ctx.Guild.OwnerId == ctx.Member.Id) //{ // string debugDict = string.Empty; // foreach(var hn in ConfigLoader.Config.HawkDict) // { // debugDict = debugDict + hn.ToString() + "\n"; // } // await ctx.Member.SendMessageAsync(debugDict); //} // Get Hawk Nest Id ulong serverHawkNest = await FindChannel(ctx, "Hawk Nest"); //make sure user is in a voice channel DiscordVoiceState vState = null; var vstates = ctx.Guild.VoiceStates; if (vstates.TryGetValue(member.Id, out vState) && vState.Channel != null) { try { await JoinVCChannel(ctx, vState.Channel).ConfigureAwait(false); await PlayCommand(ctx, "hawk.mp3").ConfigureAwait(false); await member.ModifyAsync(m => { m.VoiceChannel = ctx.Guild.GetChannel(serverHawkNest); }).ConfigureAwait(false); await LeaveVCChannel(ctx); } catch (AggregateException ex) { await ctx.Member.SendMessageAsync($"There was an exception encountered when trying to hawk {member.Username}" + $"\n{ex.Message}\n{ex.StackTrace}\n{ex.Data.ToString()}") .ConfigureAwait(false); return; } catch (Exception ex) { await ctx.Member.SendMessageAsync($"There was an exception encountered when trying to hawk {member.Username}" + $"\n{ex.Message}\n{ex.StackTrace}\n{ex.Data.Values.ToString()}") .ConfigureAwait(false); return; } } else { return; } }
public override Task <CommandResult> RunCommand(string[] args, CommandContext context) { try { string evalExePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Tools", "WamBotVoiceProcess.exe"); if (File.Exists(evalExePath)) { if (context.Author is DiscordMember memb) { DiscordVoiceState state = memb.VoiceState; if (state != null) { if (!RunningConnections.TryGetValue(memb.Guild.Id, out Process connection)) { Process evalProcess = new Process(); evalProcess.StartInfo.FileName = evalExePath; evalProcess.StartInfo.Arguments = $"{context.Guild.Id} " + $"{state.Channel.Id} " + $"{context.Channel.Id} " + $"\"{Path.Combine(Directory.GetCurrentDirectory(), "config.json")}\""; evalProcess.StartInfo.UseShellExecute = false; RunningConnections[memb.Guild.Id] = evalProcess; evalProcess.Start(); evalProcess.WaitForExit(); RunningConnections.Remove(memb.Guild.Id); } else { return(Task.FromResult <CommandResult>("I'm already connected to voice in here! F**k off!")); } } else { return(Task.FromResult <CommandResult>("You'll need to connect to voice before you can do that!")); } } else { return(Task.FromResult <CommandResult>("I can only join voice channels within guilds, sorry!")); } } else { return(Task.FromResult <CommandResult>("Voice is currently not available as required executables are missing. Sorry!")); } } catch (TaskCanceledException) { } catch (OperationCanceledException) { } catch (InvalidOperationException) { } return(Task.FromResult(CommandResult.Empty)); }
public async Task GetScreenShareLink(CommandContext ctx, [Description("chat name."), RemainingText] DiscordChannel chn = null) { DiscordVoiceState vstat = ctx.Member?.VoiceState; if (vstat?.Channel == null && chn == null) { await ctx.RespondAsync("You are not in a voice channel."); return; } if (chn == null) { chn = vstat.Channel; } await ctx.RespondAsync($"https://discordapp.com/channels/{chn.GuildId}/{chn.Id}"); }
public async Task JoinVocal(CommandContext commandContext, DiscordChannel channel = null) { VoiceNextClient voiceNext = commandContext.Client.GetVoiceNextClient(); if (voiceNext == null) { await commandContext.RespondAsync("voiceNext == null;"); return; } VoiceNextConnection voiceConnection = voiceNext.GetConnection(commandContext.Guild); if (voiceConnection != null) { await commandContext.RespondAsync("already connected"); return; } else { await commandContext.RespondAsync("bug bug bug"); } DiscordVoiceState voiceState = commandContext.Member.VoiceState; if (voiceState.Channel == null && channel == null) { await commandContext.RespondAsync("you're not in a voice channel"); return; } if (channel == null) { channel = voiceState.Channel; } await commandContext.RespondAsync($"Connected to {channel.Name}"); voiceConnection = await voiceNext.ConnectAsync(channel); }
/// <summary> /// Handles updating the cache list of members connected to voice channels, as well as updating the voice state. /// </summary> void UpdateMemberVoiceState(DiscordVoiceState newState) { // Save previous state DiscordVoiceState previousState = cache.GuildVoiceStates[newState.GuildId, newState.UserId]; // Update cache with new state cache.GuildVoiceStates[newState.GuildId, newState.UserId] = newState; // If previously in a voice channel that differs from the new channel (or no longer in a channel), // then remove this user from the voice channel user list. if (previousState != null && previousState.ChannelId.HasValue && previousState.ChannelId != newState.ChannelId) { shard.Voice.RemoveUserFromVoiceChannel(previousState.ChannelId.Value, newState.UserId); } // If user is now in a voice channel, add them to the user list. if (newState.ChannelId.HasValue) { shard.Voice.AddUserToVoiceChannel(newState.ChannelId.Value, newState.UserId); } }
async Task HandleVoiceStateUpdateEvent(DiscordApiData data) { Snowflake?guildId = data.GetSnowflake("guild_id"); if (guildId.HasValue) // Only guild voice channels are supported so far. { Snowflake userId = data.GetSnowflake("user_id").Value; // Update the voice state DiscordVoiceState voiceState = new DiscordVoiceState(guildId.Value, data); UpdateMemberVoiceState(voiceState); // If this voice state belongs to the current bot, // then we need to notify the connection of the session ID. if (userId == shard.UserId) { DiscordVoiceConnection connection; if (shard.Voice.TryGetVoiceConnection(guildId.Value, out connection)) { if (voiceState.ChannelId.HasValue) { // Notify the connection of the new state await connection.OnVoiceStateUpdated(voiceState).ConfigureAwait(false); } else if (connection.IsConnected) { // The user has left the channel, so make sure they are disconnected. await connection.DisconnectAsync().ConfigureAwait(false); } } } // Fire event OnVoiceStateUpdated?.Invoke(this, new VoiceStateEventArgs(shard, voiceState)); } else { throw new NotImplementedException("Non-guild voice channels are not supported yet."); } }
public async Task Join(CommandContext ctx, DiscordChannel chn = null) { VoiceNextExtension vnext = ctx.Client.GetVoiceNext(); if (vnext == null) { await ctx.RespondAsync("Plugin não está habilitado!"); return; } var vnc = vnext.GetConnection(ctx.Guild); if (vnc != null) { await ctx.RespondAsync("Já estou conectado em um canal de voz."); return; } DiscordVoiceState stats = ctx.Member?.VoiceState; if (stats?.Channel == null && chn == null) { await ctx.RespondAsync("Você precisa entrar ou especificar um canal de voz"); return; } if (chn == null) { chn = stats.Channel; } // connect await vnext.ConnectAsync(chn); return; }
internal VoiceStateEventArgs(DiscordVoiceState state) { State = state; }
void HandleGuildCreateEvent(DiscordApiData data) { Snowflake guildId = data.GetSnowflake("id").Value; bool wasUnavailable = !cache.IsGuildAvailable(guildId); // Update guild MutableGuild mutableGuild; if (!cache.Guilds.TryGetValue(guildId, out mutableGuild)) { mutableGuild = new MutableGuild(guildId, http); cache.Guilds[guildId] = mutableGuild; } mutableGuild.Update(data); // Ensure the cache guildId list contains this guild (it uses a hashset so don't worry about duplicates). cache.AddGuildId(guildId); // GUILD_CREATE specifics // Update metadata cache.GuildMetadata[guildId] = new DiscordGuildMetadata(data); // Deserialize members cache.GuildMembers.Clear(guildId); IList <DiscordApiData> membersArray = data.GetArray("members"); for (int i = 0; i < membersArray.Count; i++) { DiscordApiData memberData = membersArray[i]; DiscordApiData userData = memberData.Get("user"); Snowflake userId = userData.GetSnowflake("id").Value; MutableUser user; if (!cache.Users.TryGetValue(userId, out user)) { user = new MutableUser(userId, false, http); cache.Users[userId] = user; } user.Update(userData); MutableGuildMember member; if (!cache.GuildMembers.TryGetValue(guildId, userId, out member)) { member = new MutableGuildMember(user, guildId, http); cache.GuildMembers[guildId, userId] = member; } member.Update(memberData); } // Deserialize channels cache.ClearGuildChannels(guildId); IList <DiscordApiData> channelsArray = data.GetArray("channels"); for (int i = 0; i < channelsArray.Count; i++) { DiscordApiData channelData = channelsArray[i]; DiscordChannelType channelType = (DiscordChannelType)channelData.GetInteger("type"); DiscordGuildChannel channel = null; if (channelType == DiscordChannelType.GuildText) { channel = new DiscordGuildTextChannel(http, channelData, guildId); } else if (channelType == DiscordChannelType.GuildVoice) { channel = new DiscordGuildVoiceChannel(http, channelData, guildId); } else if (channelType == DiscordChannelType.GuildCategory) { channel = new DiscordGuildCategoryChannel(http, channelData, guildId); } if (channel != null) { cache.AddGuildChannel(channel); } } // Deserialize voice states cache.GuildVoiceStates.Clear(guildId); IList <DiscordApiData> voiceStatesArray = data.GetArray("voice_states"); for (int i = 0; i < voiceStatesArray.Count; i++) { DiscordVoiceState state = new DiscordVoiceState(guildId, voiceStatesArray[i]); UpdateMemberVoiceState(state); } // Deserialize presences cache.GuildPresences.Clear(guildId); IList <DiscordApiData> presencesArray = data.GetArray("presences"); for (int i = 0; i < presencesArray.Count; i++) { // Presence's in GUILD_CREATE do not contain full user objects, // so don't attempt to update them here. DiscordApiData presenceData = presencesArray[i]; Snowflake userId = presenceData.LocateSnowflake("user.id").Value; cache.GuildPresences[guildId, userId] = new DiscordUserPresence(userId, presenceData); } // Mark the guild as available cache.SetGuildAvailability(guildId, true); // Fire event if (wasUnavailable) { OnGuildAvailable?.Invoke(this, new GuildEventArgs(shard, mutableGuild.ImmutableEntity)); } else { OnGuildCreated?.Invoke(this, new GuildEventArgs(shard, mutableGuild.ImmutableEntity)); } }
private void VoiceStateUpdateMedia(BaseDiscordClient client, Embed embed, VoiceStateUpdateEventArgs voiceStateUpdateEventArgs, DiscordVoiceState before, DiscordVoiceState after) { var actionLog = string.Empty; var actionEmbed = string.Empty; var stateChanged = false; var acceptedEmoji = DiscordEmoji.FromGuildEmote(client, EmojiLibrary.Accepted); var deniedEmoji = DiscordEmoji.FromGuildEmote(client, EmojiLibrary.Denied); if (before.IsSelfDeafened != after.IsSelfDeafened) { stateChanged = true; var from = before.IsSelfDeafened ? acceptedEmoji : deniedEmoji; var to = after.IsSelfDeafened ? acceptedEmoji : deniedEmoji; actionLog = $"'self deafened' from {before.IsSelfDeafened.ToString()} to {after.IsSelfDeafened.ToString()}"; actionEmbed = $"{Formatter.InlineCode("Self Deafened")} state has been updated from {from} to {to}"; } if (before.IsSelfMuted != after.IsSelfMuted) { stateChanged = true; var from = before.IsSelfMuted ? acceptedEmoji : deniedEmoji; var to = after.IsSelfMuted ? acceptedEmoji : deniedEmoji; var status = before.IsSelfDeafened != after.IsServerDeafened ? "Self Muted and Deafened" : "Self Muted"; actionLog = $"'{status.ToLower()}' from {before.IsSelfMuted.ToString()} to {after.IsSelfMuted.ToString()}"; actionEmbed = $"{Formatter.InlineCode(status)} state has been updated from {from} to {to}"; } if (before.IsServerDeafened != after.IsServerDeafened) { stateChanged = true; var from = before.IsServerDeafened ? acceptedEmoji : deniedEmoji; var to = after.IsServerDeafened ? acceptedEmoji : deniedEmoji; actionLog = $"'server deafened' from {before.IsServerDeafened.ToString()} to {after.IsServerDeafened.ToString()}"; actionEmbed = $"{Formatter.InlineCode("Server Deafened")} state has been updated from {from} to {to}"; } if (before.IsServerMuted != after.IsServerMuted) { stateChanged = true; var from = before.IsServerMuted ? acceptedEmoji : deniedEmoji; var to = after.IsServerMuted ? acceptedEmoji : deniedEmoji; actionLog = $"'server muted' from {before.IsServerMuted.ToString()} to {after.IsServerMuted.ToString()}"; actionEmbed = $"{Formatter.InlineCode("Server Muted")} state has been updated from {from} to {to}"; } if (before.IsSuppressed != after.IsSuppressed) { stateChanged = true; var from = before.IsSuppressed ? acceptedEmoji : deniedEmoji; var to = after.IsSuppressed ? acceptedEmoji : deniedEmoji; actionLog = $"'suppressed' from {before.IsSuppressed.ToString()} to {after.IsSuppressed.ToString()}"; actionEmbed = $"{Formatter.InlineCode("Suppressed")} state has been updated from {from} to {to}"; } // Todo: IsSelfStream and IsSelfVideo (waiting for upcoming lib update) if (stateChanged) { embed.Title = $"{DiscordEmoji.FromGuildEmote(client, EmojiLibrary.Update)} Member state updated"; embed.Description = actionEmbed; this.logger.Information($"Voice state of the user '{voiceStateUpdateEventArgs.User.GetUsertag()}' ({voiceStateUpdateEventArgs.User.Id}) has been updated {actionLog.ToLowerInvariant()} in the channel '{voiceStateUpdateEventArgs.Channel.Name}' ({voiceStateUpdateEventArgs.Channel.Id}) on the guild '{voiceStateUpdateEventArgs.Guild.Name}' ({voiceStateUpdateEventArgs.Guild.Id})."); } }
/// <summary> /// Gets the internal "SessionId" property value of the specified <paramref name="voiceState"/>. /// </summary> /// <param name="voiceState">the instance</param> /// <returns>the "SessionId" value</returns> public static string GetSessionId(this DiscordVoiceState voiceState) => (string)_sessionIdProperty.GetValue(voiceState);
private async void ExecuteCommand(KeyValuePair <string, Tuple <BaseModule, ILog, MethodInfo> > Command, MessageEventArgs e, string @params) { try { log.Debug(string.Format(Resources.Culture, Resources.ResourceManager.GetString("ExecutingCommand", Resources.Culture), Command.Key, string.IsNullOrEmpty(@params) ? Resources.ResourceManager.GetString("NoParams", Resources.Culture) : @params)); Stopwatch st = new Stopwatch(); st.Start(); MethodInfo method = Command.Value.Item3; CommandAttribute attr = method.GetCustomAttribute <CommandAttribute>(); List <object> parameters = new List <object>(); foreach (ParameterInfo info in method.GetParameters()) { Type t = info.ParameterType; if (parameters.Exists(p => p.GetType().Equals(t))) { Command.Value.Item2.Error(string.Format(Resources.Culture, Resources.ResourceManager.GetString("UsingDuplicateParam", Resources.Culture), info.Name, info.ParameterType.Name)); return; } DiscordVoiceConnection connection = null; if (attr.NeedsVoice) { DiscordGuildTextChannel channel = shard.Cache.GetGuildTextChannel(e.Message.ChannelId); if (channel == null) { channel = await client.GetChannel <DiscordGuildTextChannel>(e.Message.ChannelId).ConfigureAwait(true); log.Debug(Resources.ResourceManager.GetString("HadToLoadGuild", Resources.Culture)); } DiscordVoiceState voiceState = shard.Cache.GetVoiceState(channel.GuildId, e.Message.Author.Id); if (voiceState.ChannelId.HasValue) { connection = shard.Voice.CreateOrGetConnection(channel.GuildId); if (connection.IsValid && !connection.IsConnected && !connection.IsConnecting) { await connection.ConnectAsync(voiceState.ChannelId.Value, startDeaf : true).ConfigureAwait(true); log.Debug(string.Format(Resources.Culture, Resources.ResourceManager.GetString("ConnectedToVoiceChannel", Resources.Culture), voiceState.ChannelId.Value, Guilds.FirstOrDefault(g => g.Id == channel.GuildId))); } } else { return; } } switch (t.Name) { case "ICoreHandler": { if (!attr.NeedsHandler) { Command.Value.Item2.Warn(string.Format(Resources.Culture, Resources.ResourceManager.GetString("UsingUnflaggedParam", Resources.Culture), info.Name, info.ParameterType.Name)); } parameters.Add(this); break; } case "Message": { if (!attr.NeedsMessage) { Command.Value.Item2.Warn(string.Format(Resources.Culture, Resources.ResourceManager.GetString("UsingUnflaggedParam", Resources.Culture), info.Name, info.ParameterType.Name)); } Message message = new Message(e.Message.Id, e.Message.ChannelId.Id, e.Message.Author.Id); if (attr.NeedsVoice) { message.HasSound += Message_HasSound; } parameters.Add(message); break; } case "String": { if (!attr.HasParams) { Command.Value.Item2.Warn(string.Format(Resources.Culture, Resources.ResourceManager.GetString("UsingUnflaggedParam", Resources.Culture), info.Name, info.ParameterType.Name)); } parameters.Add(@params); break; } default: { Command.Value.Item2.Error(string.Format(Resources.Culture, Resources.ResourceManager.GetString("UsingUnknownParam", Resources.Culture), info.Name, info.ParameterType.Name)); return; } } } await Task.Run(() => { try { if (Command.Value.Item3.IsStatic) { Command.Value.Item3.Invoke(null, parameters.ToArray()); } else { Command.Value.Item3.Invoke(Command.Value.Item1, parameters.ToArray()); } } catch (InvalidOperationException ex) { Command.Value.Item2.Error(ex.InnerException.ToString()); } }).ConfigureAwait(true); st.Stop(); log.Debug(string.Format(Resources.Culture, Resources.ResourceManager.GetString("RanCommand", Resources.Culture), Command.Key, st.Elapsed.ToString("s\\.f", Resources.Culture))); } catch (Exception ex) { log.Error(ex); throw; } }
internal VoiceStateEventArgs(Shard shard, DiscordVoiceState state) : base(shard) { VoiceState = state; }