Example #1
0
        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);
        }
Example #2
0
        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);
            }
        }
Example #3
0
        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);
        }
Example #4
0
 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();
        }
Example #6
0
        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);
        }
Example #7
0
        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;
        }
Example #8
0
        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}**)");
                }
            }
        }
Example #9
0
        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);
        }
    }
Example #10
0
        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;
        }
Example #11
0
        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");
            }
        }
Example #12
0
        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.");
            }
        }
Example #13
0
        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);
        }