public static int GetMemberLevel(DiscordMember member) { if (ShimakazeBot.IsUserShimaTeam(member.Id)) { return((int)ShimaConsts.UserPermissionLevel.SHIMA_TEAM); } int level = (int)ShimaConsts.UserPermissionLevel.DEFAULT; int currentLevel; member.Roles.ToList().ForEach(role => { currentLevel = GetLevel(role.Id, member.Guild.Id); if (currentLevel > (int)ShimaConsts.UserPermissionLevel.DEFAULT && currentLevel > level) { level = currentLevel; } }); currentLevel = GetLevel(member.Id, member.Guild.Id); if (currentLevel < (int)ShimaConsts.UserPermissionLevel.DEFAULT || currentLevel > level) { level = currentLevel; } return(level); }
public static async Task <JObject> HttpPost(string url, AuthenticationHeaderValue authentication = null) { if (string.IsNullOrWhiteSpace(url)) { return(null); } try { using (var requestMessage = new HttpRequestMessage(HttpMethod.Post, url)) { if (authentication != null) { requestMessage.Headers.Authorization = authentication; } requestMessage.Content = new StringContent("grant_type=client_credentials"); requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded"); var response = await Client.SendAsync(requestMessage); response.EnsureSuccessStatusCode(); string objectString = await response.Content.ReadAsStringAsync(); if (!objectString.StartsWith("{") && !objectString.EndsWith("}")) { objectString = $"{{\"data\":\"{objectString}\"}}"; } return(JObject.Parse(objectString)); } } catch (Exception e) { ShimakazeBot.SendToDebugRoom($"Http POST failed.\nURL: **{url}**\nError: **{e.Message}**"); return(null); } }
private Task LavalinkDisconnected(LavalinkNodeConnection lvn, NodeDisconnectedEventArgs e) { ShimakazeBot.SendToDebugRoom("Lavalink died."); // ShimakazeBot.lvn.LavalinkSocketErrored -= LavalinkErrored; //ShimakazeBot.lvn.Disconnected -= LavalinkDisconnected; //ShimakazeBot.lvn = null; return(Task.CompletedTask); }
private Task LavalinkErrored(LavalinkNodeConnection lvn, DSharpPlus.EventArgs.SocketErrorEventArgs e) { if (e.Exception.Message == "An attempt was made to transition a task to a final state when it had already completed.") { return(Task.CompletedTask); } ShimakazeBot.SendToDebugRoom($" Lavalink error:\n{e.Exception?.Message}"); return(Task.CompletedTask); }
public async Task LeaveServer(CommandContext ctx) { if (!ShimakazeBot.Client.CurrentApplication.Owners.Contains(ctx.User)) { await CTX.RespondSanitizedAsync(ctx, "Ok, I understand... I'm no longer wanted here. I'm sorry 😢\n*Runs away*"); } ShimakazeBot.SendToDebugRoom( $"Left **{ctx.Guild.Name}** ({ctx.Guild.Id}). Triggered by **{ctx.User.Username}** ({ctx.User.Id})"); await ctx.Guild.LeaveAsync(); }
public static int GetLevel(ulong userId, ulong guildId) { if (ShimakazeBot.IsUserShimaTeam(userId)) { return((int)ShimaConsts.UserPermissionLevel.SHIMA_TEAM); } if (ShimakazeBot.UserLevelList.ContainsKey(userId)) { return(GetUserLevel(ShimakazeBot.UserLevelList[userId].levelList, guildId)); } return((int)ShimaConsts.UserPermissionLevel.DEFAULT); }
private async Task DiscordSocketClosed(LavalinkGuildConnection lvc, WebSocketCloseEventArgs e) { if (e.Code == 4014) { return; } if (e.Code == 1001 || e.Code == 1006 || e.Code == 4000) { var track = lvc.CurrentState?.CurrentTrack; var time = lvc.CurrentState?.PlaybackPosition; var ch = lvc.Channel; await lvc.DisconnectAsync(); var newLvc = await ShimakazeBot.lvn.ConnectAsync(ch); if (track != null) { await newLvc.PlayAsync(track); if (time != null) { await newLvc.SeekAsync(time.Value); } } return; } string str = $"Discord socket closed:" + $"\n - Code: {e.Code}" + $"\n - Reason: {e.Reason}" + $"\n - Remote: {e.Remote}" + $"\n - Channel: {lvc?.Channel.Name} ({lvc?.Guild.Name})"; ShimakazeBot.SendToDebugRoom(str); return; }
private async Task UserPresenceUpdated(DiscordClient client, PresenceUpdateEventArgs e) { bool streamStatusChanged = false; bool startedStreaming = false; var activitiesBefore = e.PresenceBefore?.Activities; var activitiesAfter = e.PresenceAfter?.Activities; //check if status changed if (activitiesBefore?.FirstOrDefault(activity => activity.ActivityType == ActivityType.Streaming) != null) { if (activitiesAfter?.FirstOrDefault(activity => activity.ActivityType == ActivityType.Streaming) == null) { streamStatusChanged = true; } } else if (activitiesAfter?.FirstOrDefault(activity => activity.ActivityType == ActivityType.Streaming) != null) { if (activitiesBefore?.FirstOrDefault(activity => activity.ActivityType == ActivityType.Streaming) == null) { streamStatusChanged = true; startedStreaming = true; } } if (!streamStatusChanged) { return; } //get all configured guilds var filteredGuilds = ShimakazeBot.Client.Guilds.Where(guild => { return(ShimakazeBot.StreamingEnabledGuilds.ContainsKey(guild.Value.Id) || guild.Value.Roles.FirstOrDefault(role => role.Value.Name == "Now Streaming" ).Value != null); }); //filter ones for member and check perms string missingPerms = ""; filteredGuilds = filteredGuilds.Where(guild => { if (guild.Value.Members.ContainsKey(e.User.Id)) { if (Utils.MemberHasPermissions( guild.Value.Members[ShimakazeBot.Client.CurrentUser.Id], Permissions.ManageRoles)) { return(true); } else { missingPerms += $"{guild.Value.Name} (**{guild.Value.Id}**) - "; } } return(false); }); if (missingPerms.Length > 0) { ShimakazeBot.SendToDebugRoom("Shima is missing manage role perms for streaming in:" + $"\n{missingPerms}"); return; } //apply per guild foreach (var guild in filteredGuilds) { var role = ShimakazeBot.StreamingEnabledGuilds.ContainsKey(guild.Key) ? guild.Value.Roles[ShimakazeBot.StreamingEnabledGuilds[guild.Key]] : guild.Value.Roles.FirstOrDefault(guildRole => guildRole.Value.Name == "Now Streaming" ).Value; try { if (startedStreaming) { await guild.Value.Members[e.User.Id].GrantRoleAsync(role); } else { await guild.Value.Members[e.User.Id].RevokeRoleAsync(role); } } //if role is too high catch { ShimakazeBot.SendToDebugRoom($"Shima couldn't reach the streaming role {role.Name} " + $"in {guild.Value.Name} (**{guild.Value.Id}**)"); } } }
static async Task MainAsync(string[] args) { ShimakazeBot.Config = ShimaConfig.LoadConfig(); if (ShimakazeBot.Config.Equals(null) || (ShimakazeBot.Config.settings.liveToken == null && ShimakazeBot.Config.settings.testToken == null)) { throw new System.ArgumentNullException("", "Config ain't set up properly (:"); } ShimaLoggerFactory loggerFactory = new ShimaLoggerFactory(); loggerFactory.AddProvider(new ShimaLoggerProvider()); ShimakazeBot.Client = new DiscordClient(new DiscordConfiguration { Token = ShimakazeBot.Config.settings.isTest ? ShimakazeBot.Config.settings.testToken : ShimakazeBot.Config.settings.liveToken, TokenType = TokenType.Bot, MinimumLogLevel = LogLevel.Information, LoggerFactory = loggerFactory }); ShimakazeBot.DbCtx = new ShimaContext(); await ShimakazeBot.DbCtx.Database.MigrateAsync(); ShimakazeBot.FetchPrefixes(); ShimakazeBot.FetchStreamingRoles(); ShimakazeBot.FetchSelfAssignLimits(); ShimakazeBot.FetchPermissionLevels(); CommandsNextConfiguration commandConfig = new CommandsNextConfiguration { PrefixResolver = (msg) => { return(Task.Run(() => { var guild = msg.Channel.Guild; if (guild is null) { return msg.GetStringPrefixLength(ShimakazeBot.DefaultPrefix); } return msg.GetStringPrefixLength(ShimakazeBot.CustomPrefixes.ContainsKey(guild.Id) ? ShimakazeBot.CustomPrefixes[guild.Id] : ShimakazeBot.DefaultPrefix); })); } }; CommandsNextExtension commandsNextExtension = ShimakazeBot.Client.UseCommandsNext(commandConfig); commandsNextExtension.RegisterCommands <DebugCommands>(); commandsNextExtension.RegisterCommands <InfoCommands>(); commandsNextExtension.RegisterCommands <GeneralCommands>(); commandsNextExtension.RegisterCommands <FunCommands>(); commandsNextExtension.RegisterCommands <VoiceCommands>(); commandsNextExtension.RegisterCommands <CustomizationCommands>(); commandsNextExtension.RegisterCommands <ManagementCommands>(); commandsNextExtension.RegisterCommands <EventCommands>(); ShimakazeBot.Client.UseLavalink(); ShimakazeBot.events.LoadEvents(); await ShimakazeBot.Client.ConnectAsync(); await Task.Delay(-1); } }
private async Task PlayNextTrack(LavalinkGuildConnection lvc, TrackFinishEventArgs e) { if (e.Reason == TrackEndReason.Cleanup) { ShimakazeBot.SendToDebugRoom("Lavalink failed in **" + $"{e.Player.Guild.Name}** ({e.Player.Guild.Id}) - **" + $"{e.Player.Channel.Name}** ({e.Player.Channel.Id}) - song: " + e.Track.Title); ShimakazeBot.Client.Logger.Log(LogLevel.Warning, LogSources.PLAYLIST_NEXT_EVENT, $"{e.Reason} - playlist length at error: " + ShimakazeBot.playlists[e.Player.Guild].songRequests.Count); if (ShimakazeBot.playlists[e.Player.Guild].songRequests.Count > 0) { await ShimakazeBot.playlists[e.Player.Guild].songRequests[0].requestedChannel.SendMessageAsync( ShimakazeBot.playlists[e.Player.Guild].songRequests[0].requestMember.Mention + "Lavalink failed... Shima will leave the voice channel. " + "Don't worry your playlist has been saved. You can make her rejoin." + (ShimakazeBot.shouldSendToDebugRoom ? " The devs have been notified." : "")); await ForceLeave(e.Player.Guild); } return; } if (e.Reason == TrackEndReason.LoadFailed) { ShimakazeBot.Client.Logger.Log(LogLevel.Warning, LogSources.PLAYLIST_NEXT_EVENT, $"{e.Reason} - playlist length at error: " + ShimakazeBot.playlists[e.Player.Guild].songRequests.Count); } if (e.Reason == TrackEndReason.Replaced) { return; } if (ShimakazeBot.playlists[e.Player.Guild].songRequests.Count <= 0) { return; } if (ShimakazeBot.playlists[e.Player.Guild].loopCount > 0) { ShimakazeBot.playlists[e.Player.Guild].loopCount--; await e.Player.PlayAsync(e.Track); return; } ShimakazeBot.playlists[e.Player.Guild].songRequests.RemoveAt(0); ShimakazeBot.playlists[e.Player.Guild].voteSkip = null; ShimakazeBot.Client.Logger.Log(LogLevel.Information, LogSources.PLAYLIST_NEXT_EVENT, $"{e.Reason} - " + $"{ShimakazeBot.playlists[e.Player.Guild].songRequests.Count} " + $"songs remaining in {e.Player.Guild.Name}."); if (ShimakazeBot.playlists[e.Player.Guild].songRequests.Count > 0) { await e.Player.PlayAsync(ShimakazeBot.playlists[e.Player.Guild].songRequests.First().track); if (ShimakazeBot.CheckDebugMode(e.Player.Guild.Id)) { ShimakazeBot.Client.Logger.Log(LogLevel.Information, $"{LogSources.PLAYLIST_NEXT_EVENT} SupaDebug @{e.Player.Guild.Name}", "next track: " + ShimakazeBot.lvn.GetGuildConnection(e.Player.Guild)?.CurrentState?.CurrentTrack?.Title); } } return; }
public async Task Join(CommandContext ctx, bool reconnect = false) { DebugString debugResponse = new DebugString(); //db shit first var existingJoin = ShimakazeBot.DbCtx.GuildJoin.FirstOrDefault(p => p.GuildId == ctx.Guild.Id); if (existingJoin == null) { await ShimakazeBot.DbCtx.GuildJoin.AddAsync( new GuildJoin { GuildId = ctx.Guild.Id, ChannelId = ctx.Channel.Id }); } else { existingJoin.ChannelId = ctx.Channel.Id; ShimakazeBot.DbCtx.GuildJoin.Update(existingJoin); } await ShimakazeBot.DbCtx.SaveChangesAsync(); var lv = ctx.Client.GetLavalink(); debugResponse.AddWithDebug("Unable to get LavaLink", ctx, lv == null); if (ShimakazeBot.lvn == null) { try { var c = await lv.ConnectAsync(new LavalinkConfiguration { Password = ShimakazeBot.Config.lavalink.password, SocketEndpoint = new ConnectionEndpoint( ShimakazeBot.Config.lavalink.host, ShimakazeBot.Config.lavalink.port), RestEndpoint = new ConnectionEndpoint( ShimakazeBot.Config.lavalink.host, ShimakazeBot.Config.lavalink.port), SocketAutoReconnect = false, ResumeTimeout = 1 }); if (ShimakazeBot.lvn != null && !reconnect) { ShimakazeBot.lvn.ConnectedGuilds.ToList().ForEach(async g => { await ForceLeave(g.Value.Guild); }); ShimakazeBot.lvn.Disconnected -= LavalinkDisconnected; ShimakazeBot.lvn.LavalinkSocketErrored -= LavalinkErrored; ShimakazeBot.lvn = null; ShimakazeBot.Client.MessageReactionAdded -= VoteSkipUpdate; await Join(ctx, true); return; } ShimakazeBot.lvn = c; ShimakazeBot.lvn.Disconnected += LavalinkDisconnected; ShimakazeBot.lvn.LavalinkSocketErrored += LavalinkErrored; ShimakazeBot.Client.MessageReactionAdded += VoteSkipUpdate; } catch (Exception e) { if (e.Message == "Unable to connect to the remote server") { await CTX.RespondSanitizedAsync(ctx, "Lavalink is dead. Please try again in a few minutes."); } else { await CTX.RespondSanitizedAsync(ctx, $"**Unknown error.**\n{e}"); } throw; } } var lvc = ShimakazeBot.lvn.GetGuildConnection(ctx.Guild); debugResponse.AddWithDebug("LVC status: " + (lvc != null).ToString(), ctx); if (lvc != null) { await CTX.RespondSanitizedAsync(ctx, $"{debugResponse}Already connected in this guild."); return; } var chn = ctx.Member?.VoiceState?.Channel; if (chn == null) { await CTX.RespondSanitizedAsync(ctx, $"{debugResponse}You need to be in a voice channel."); return; } try { if (ShimakazeBot.CheckDebugMode(ctx.Guild.Id)) { await CTX.RespondSanitizedAsync(ctx, "attempting connectAsync to " + chn.Name); } await ShimakazeBot.lvn.ConnectAsync(chn).ConfigureAwait(false); debugResponse.AddWithDebug("Connection status after: " + (ShimakazeBot.lvn.GetGuildConnection(ctx.Guild) != null).ToString(), ctx); if (ShimakazeBot.lvn.GetGuildConnection(ctx.Guild) != null) { debugResponse.AddWithDebug(" - Is connected: " + ShimakazeBot.lvn.GetGuildConnection(ctx.Guild).IsConnected.ToString() + "\n - Channel: " + ShimakazeBot.lvn.GetGuildConnection(ctx.Guild).Channel.Name, ctx); } } catch (Exception e) { if (e.Message.Contains("The WebSocket is in an invalid state ('Aborted')")) { await CTX.RespondSanitizedAsync(ctx, "Lavalink is dead. Please try again in a few minutes." + $"\n{debugResponse}"); } else { await CTX.RespondSanitizedAsync(ctx, $"{debugResponse}\n**Unknown error**\n{e}"); } throw; } if (!ShimakazeBot.playlists.ContainsKey(ctx.Guild)) { ShimakazeBot.playlists.Add(ctx.Guild, new GuildPlayer()); debugResponse.AddWithDebug($"Playlist: **new** ({lvc != null})", ctx); } else { if (ShimakazeBot.playlists[ctx.Guild].songRequests.Count > 0) { lvc = ShimakazeBot.lvn.GetGuildConnection(ctx.Guild); await lvc.PlayAsync(ShimakazeBot.playlists[ctx.Guild].songRequests.First().track); } debugResponse.AddWithDebug("Playlist: " + $"**{ShimakazeBot.playlists[ctx.Guild].songRequests.Count} songs**", ctx); } ShimakazeBot.lvn.GetGuildConnection(ctx.Guild).PlaybackFinished += PlayNextTrack; ShimakazeBot.lvn.GetGuildConnection(ctx.Guild).DiscordWebSocketClosed += DiscordSocketClosed; if (!string.IsNullOrWhiteSpace(debugResponse.ToString()) || (!reconnect && !ctx.Message.Content.Substring(ctx.Prefix.Length).StartsWith("s"))) { await CTX.RespondSanitizedAsync(ctx, debugResponse + "Joined"); } }
public async Task Leave(CommandContext ctx, [RemainingText] string remainingText) { DebugString debugResponse = new DebugString(); var lv = ctx.Client.GetLavalink(); debugResponse.AddWithDebug("Unable to get LavaLink", ctx, lv == null); var lvc = ShimakazeBot.lvn?.GetGuildConnection(ctx.Guild); if (ShimakazeBot.lvn == null || lvc == null) { await CTX.RespondSanitizedAsync(ctx, $"{debugResponse}Not connected in this guild."); return; } debugResponse.AddWithDebug("Connection state before: " + "\n - Is connected: " + ShimakazeBot.lvn.GetGuildConnection(ctx.Guild).IsConnected.ToString() + "\n - Channel: " + ShimakazeBot.lvn.GetGuildConnection(ctx.Guild).Channel.Name, ctx); var chn = ctx.Member?.VoiceState?.Channel; if (chn == null) { await CTX.RespondSanitizedAsync(ctx, $"{debugResponse}You need to be in a voice channel."); return; } if (chn != lvc.Channel) { await CTX.RespondSanitizedAsync(ctx, $"{debugResponse}You need to be in the same voice channel."); return; } if (!string.IsNullOrWhiteSpace(remainingText)) { ShimakazeBot.playlists.Remove(ctx.Guild); debugResponse.AddWithDebug("Playlist: **removed**", ctx); } else { debugResponse.AddWithDebug("Playlist: " + (ShimakazeBot.playlists.ContainsKey(ctx.Guild) ? $"**{ShimakazeBot.playlists[ctx.Guild].songRequests.Count} songs**" : "**already removed**"), ctx); } lvc.PlaybackFinished -= PlayNextTrack; lvc.DiscordWebSocketClosed -= DiscordSocketClosed; await lvc.StopAsync(); await lvc.DisconnectAsync(); if (ShimakazeBot.CheckDebugMode(ctx.Guild.Id)) { if (lvc != null || ShimakazeBot.lvn != null) { debugResponse.AddWithDebug("lvn node endpoint after: " + ShimakazeBot.lvn.NodeEndpoint + "\nConnection state after: " + (ShimakazeBot.lvn.GetGuildConnection(ctx.Guild) != null).ToString(), ctx); if (ShimakazeBot.lvn.GetGuildConnection(ctx.Guild) != null) { debugResponse.AddWithDebug("\n - Is connected: " + ShimakazeBot.lvn.GetGuildConnection(ctx.Guild).IsConnected.ToString() + "\n - Channel: " + ShimakazeBot.lvn.GetGuildConnection(ctx.Guild).Channel.Name, ctx); } } await CTX.RespondSanitizedAsync(ctx, debugResponse + "Attempted leave."); } }
public static async Task <bool> SetLevel(ulong userId, ulong guildId, bool isRole, int level) { if (ShimakazeBot.IsUserShimaTeam(userId)) { return(false); } if (ShimakazeBot.UserLevelList.ContainsKey(userId)) { var levelItem = GetUserLevelItem(ShimakazeBot.UserLevelList[userId].levelList, guildId); if (levelItem != null) { if (level == levelItem.level) { return(false); } if (level == (int)ShimaConsts.UserPermissionLevel.DEFAULT) { //remove if (ShimakazeBot.UserLevelList[userId].levelList.Count > 1) { var deleteIndex = ShimakazeBot.UserLevelList[userId].levelList.FindIndex(del => del.guildId == guildId ); if (deleteIndex > -1) { ShimakazeBot.UserLevelList[userId].levelList.RemoveAt(deleteIndex); } } else { ShimakazeBot.UserLevelList.Remove(userId); } ShimakazeBot.DbCtx.UserPermissionLevel.RemoveRange( ShimakazeBot.DbCtx.UserPermissionLevel.Where(g => g.Id == levelItem.keyId)); await ShimakazeBot.DbCtx.SaveChangesAsync(); } else { //change ShimakazeBot.UserLevelList[userId].levelList.Find(c => c.guildId == guildId ).level = level; var userPerm = ShimakazeBot.DbCtx.UserPermissionLevel.First(g => g.Id == levelItem.keyId ); userPerm.Level = level; ShimakazeBot.DbCtx.UserPermissionLevel.Update(userPerm); await ShimakazeBot.DbCtx.SaveChangesAsync(); } } else { //add await ShimakazeBot.DbCtx.UserPermissionLevel.AddAsync(new UserPermissionLevel { UserId = userId, IsRole = isRole, GuildId = guildId, Level = level }); await ShimakazeBot.DbCtx.SaveChangesAsync(); int key = ShimakazeBot.DbCtx.UserPermissionLevel.ToList().Find(g => g.UserId == userId && g.GuildId == guildId).Id; if (guildId == ShimaConsts.GlobalLevelGuild) { ShimakazeBot.UserLevelList[userId].levelList.Insert(0, new UserLevels(key, guildId, level)); } else { ShimakazeBot.UserLevelList[userId].levelList.Add(new UserLevels(key, guildId, level)); } } } else { if (level == (int)ShimaConsts.UserPermissionLevel.DEFAULT) { return(false); } //add and add await ShimakazeBot.DbCtx.UserPermissionLevel.AddAsync(new UserPermissionLevel { UserId = userId, IsRole = isRole, GuildId = guildId, Level = level }); await ShimakazeBot.DbCtx.SaveChangesAsync(); int key = ShimakazeBot.DbCtx.UserPermissionLevel.ToList().Find(g => g.UserId == userId && g.GuildId == guildId).Id; ShimakazeBot.UserLevelList.Add(userId, new LevelListContainer(isRole, new List <UserLevels>() { new UserLevels(key, guildId, level) })); } return(true); }