コード例 #1
0
        public void LoadConnections()
        {
            PalantirDbContext Database = new PalantirDbContext();

            PalantirTethers = new List <Tether>();
            foreach (PalantirEntity palantirEntity in Database.Palantiri)
            {
                Tether        tether;
                ObservedGuild guild = JsonConvert.DeserializeObject <ObservedGuild>(palantirEntity.Palantir);
                if (Database.GuildSettings.Any(s => s.GuildID == guild.GuildID))
                {
                    tether = new Tether(guild, JsonConvert.DeserializeObject <GuildSettings>(Database.GuildSettings.FirstOrDefault(s => s.GuildID == guild.GuildID).Settings));
                }
                else
                {
                    tether = new Tether(guild);
                }
                PalantirTethers.Add(tether);
            }

            PalantirMembers = new List <Member>();
            foreach (MemberEntity memberEntity in Database.Members)
            {
                PalantirMembers.Add(JsonConvert.DeserializeObject <Member>(memberEntity.Member));
            }
            Database.Dispose();
        }
コード例 #2
0
ファイル: Drops.cs プロジェクト: toobeeh/Palantir
        private static int CalculateDropTimeoutSeconds()
        {
            PalantirDbContext context = new PalantirDbContext();

            List <string>     onlineIDs = new List <string>();
            PalantirDbContext dbcontext = new PalantirDbContext();

            dbcontext.Status.ToList().ForEach(status =>
            {
                string id = JsonConvert.DeserializeObject <PlayerStatus>(status.Status).PlayerMember.UserID;
                if (!onlineIDs.Contains(id))
                {
                    onlineIDs.Add(id);
                }
            });
            int count = onlineIDs.Count();

            context.Dispose();

            if (count <= 0)
            {
                count = 1;
            }
            int min = 600 / count;

            if (min < 30)
            {
                min = 30;
            }

            return((new Random()).Next(min, 4 * min));
        }
コード例 #3
0
        public async Task Execute(IJobExecutionContext context)
        {
            string[] logins = BubbleWallet.loginBubbleTicks.Distinct().ToArray();
            BubbleWallet.loginBubbleTicks = new List <string>();
            Dictionary <string, int> cache     = new Dictionary <string, int>();
            PalantirDbContext        dbcontext = new PalantirDbContext();

            try
            {
                foreach (string login in logins)
                {
                    MemberEntity member = dbcontext.Members.FirstOrDefault(s => s.Login == login);
                    if (JsonConvert.DeserializeObject <Member>(member.Member).Guilds.Count > 0)
                    {
                        member.Bubbles++;
                    }
                }
            }
            catch (Exception e) { Console.WriteLine(e.ToString()); }
            await dbcontext.SaveChangesAsync();

            foreach (MemberEntity member in dbcontext.Members)
            {
                cache.Add(member.Login.ToString(), member.Bubbles);
            }
            dbcontext.Dispose();
            BubbleWallet.BubbleCache = cache;
        }
コード例 #4
0
        public void UpdateMemberGuilds()
        {
            PalantirDbContext context = new PalantirDbContext();

            foreach (MemberEntity memberEntity in context.Members)
            {
                Member member = JsonConvert.DeserializeObject <Member>(memberEntity.Member);
                List <ObservedGuild> updatedGuilds = new List <ObservedGuild>();
                member.Guilds.ForEach((g) =>
                {
                    if (PalantirTethers.Count(t => t.PalantirEndpoint.ObserveToken == g.ObserveToken && t.PalantirEndpoint.GuildID == g.GuildID) > 0)
                    {
                        updatedGuilds.Add(
                            PalantirTethers.FirstOrDefault(t => t.PalantirEndpoint.ObserveToken == g.ObserveToken && t.PalantirEndpoint.GuildID == g.GuildID)
                            .PalantirEndpoint);
                    }
                });
                member.Guilds = updatedGuilds;
                if (updatedGuilds.Count > 0)
                {
                    memberEntity.Member = JsonConvert.SerializeObject(member);
                }
                else
                {
                    //MemberEntity rem = new MemberEntity();
                    //rem.Login = member.UserLogin;
                    //context.Members.Remove(rem);
                    //Console.WriteLine("Member " + member.UserName + " was removed.");
                    memberEntity.Member = JsonConvert.SerializeObject(member);
                    Console.WriteLine("Member " + member.UserName + " has no verified guilds.");
                }
            }
            context.SaveChanges();
            context.Dispose();
        }
コード例 #5
0
        public static bool IsEarlyUser(string login)
        {
            PalantirDbContext context = new PalantirDbContext();
            bool exists = context.BubbleTraces.Any(trace => trace.Date == "31/08/2020" && trace.Login == login);

            context.Dispose();
            return(exists);
        }
コード例 #6
0
        public MemberEntity GetMemberByLogin(string login)
        {
            PalantirDbContext context = new PalantirDbContext();
            MemberEntity      member  = context.Members.FirstOrDefault(m => m.Login == login);

            context.Dispose();
            return(member);
        }
コード例 #7
0
        public static List <SpritesEntity> GetEventSprites(int eventDropID)
        {
            PalantirDbContext    context = new PalantirDbContext();
            List <SpritesEntity> sprites = context.Sprites.Where(s => s.EventDropID == eventDropID).ToList();

            context.Dispose();
            return(sprites);
        }
コード例 #8
0
        public int GetFlagByMember(DiscordUser user)
        {
            PalantirDbContext context = new PalantirDbContext();
            MemberEntity      member  = context.Members.FirstOrDefault(m => m.Member.Contains(user.Id.ToString()));

            context.Dispose();
            return(member.Flag);
        }
コード例 #9
0
        public static int GlobalRanking(string login, bool drops = false)
        {
            PalantirDbContext context = new PalantirDbContext();
            int index = context.Members.ToList().Where(member => !(new PermissionFlag((byte)member.Flag).BubbleFarming)).OrderByDescending(member => drops ? member.Drops : member.Bubbles).Select(member => member.Login).ToList().IndexOf(login) + 1;

            context.Dispose();
            return(index);
        }
コード例 #10
0
        public static string FirstTrace(string login)
        {
            PalantirDbContext context = new PalantirDbContext();
            List <string>     dates   = context.BubbleTraces.Where(trace => trace.Login == login).Select(trace => trace.Date).ToList();

            context.Dispose();
            return(dates.Min(date => DateTime.Parse(date)).ToShortDateString());
        }
コード例 #11
0
        public List <MemberEntity> GetGuildMembers(string guildID)
        {
            PalantirDbContext   context = new PalantirDbContext();
            List <MemberEntity> members = context.Members.Where(m => m.Member.Contains(guildID)).ToList();

            context.Dispose();
            return(members);
        }
コード例 #12
0
        public static List <SpriteProperty> GetInventory(string login)
        {
            PalantirDbContext context         = new PalantirDbContext();
            string            inventoryString = context.Members.FirstOrDefault(m => m.Login == login).Sprites;

            context.Dispose();
            return(ParseSpriteInventory(inventoryString));
        }
コード例 #13
0
        public void SetFlagByID(string id, int flag)
        {
            PalantirDbContext context = new PalantirDbContext();
            MemberEntity      member  = context.Members.FirstOrDefault(m => m.Member.Contains(id));

            member.Flag = flag;
            context.SaveChanges();
            context.Dispose();
        }
コード例 #14
0
        public static List <Sprite> GetAvailableSprites()
        {
            List <Sprite>     sprites = new List <Sprite>();
            PalantirDbContext context = new PalantirDbContext();

            context.Sprites.ToList().ForEach(s => sprites.Add(new Sprite(s.Name, s.URL, s.Cost, s.ID, s.Special, s.EventDropID, s.Artist)));
            context.SaveChanges();
            context.Dispose();
            return(sprites);
        }
コード例 #15
0
        public static List <EventDropEntity> GetEventDrops(List <EventEntity> fromEvents = null)
        {
            PalantirDbContext      context = new PalantirDbContext();
            List <EventDropEntity> drops   = context.EventDrops.ToList();

            if (fromEvents is object)
            {
                drops = drops.Where(d => fromEvents.Any(e => e.EventID == d.EventID)).ToList();
            }
            context.Dispose();
            return(drops);
        }
コード例 #16
0
        public static List <EventEntity> GetEvents(bool active = true)
        {
            PalantirDbContext  context = new PalantirDbContext();
            List <EventEntity> events  = context.Events.ToList();

            if (active)
            {
                events = events.Where(e => Convert.ToDateTime(e.ValidFrom) <= DateTime.Now && Convert.ToDateTime(e.ValidFrom).AddDays(e.DayLength) >= DateTime.Now).ToList();
            }
            context.Dispose();
            return(events);
        }
コード例 #17
0
        public static int GetEventCredit(string login, int eventDropID)
        {
            PalantirDbContext context = new PalantirDbContext();
            int credit = 0;

            try {
                credit = context.EventCredits.FirstOrDefault(c => c.EventDropID == eventDropID && c.Login == login).Credit;
            }
            catch { }

            context.Dispose();
            return(credit);
        }
コード例 #18
0
        public static int GetDrops(string login)
        {
            PalantirDbContext context = new PalantirDbContext();
            MemberEntity      entity  = context.Members.FirstOrDefault(s => s.Login == login);
            int drops = 0;

            if (entity != null)
            {
                drops = entity.Drops;
            }
            context.SaveChanges();
            context.Dispose();

            return(drops);
        }
コード例 #19
0
        public double DatabaseReadTime(string id, int reads)
        {
            PalantirDbContext context = new PalantirDbContext();
            DateTime          now;
            double            time = 0;

            for (int i = 0; i < reads; i++)
            {
                now = DateTime.Now;
                context.Members.FirstOrDefault(m => m.Member.Contains(id));
                time += (DateTime.Now - now).TotalMilliseconds;
            }
            context.Dispose();
            return(time / reads);
        }
コード例 #20
0
        public static void AddSprite(Sprite sprite)
        {
            PalantirDbContext context = new PalantirDbContext();
            SpritesEntity     s       = new SpritesEntity();

            s.ID          = sprite.ID;
            s.Name        = sprite.Name;
            s.Special     = sprite.Special;
            s.URL         = sprite.URL;
            s.EventDropID = sprite.EventDropID;
            s.Cost        = sprite.Cost;
            s.Artist      = sprite.Artist;
            context.Sprites.Add(s);
            context.SaveChanges();
            context.Dispose();
        }
コード例 #21
0
        public static string GetLoginOfMember(string id)
        {
            PalantirDbContext context = new PalantirDbContext();
            string            login;

            try
            {
                login = context.Members.First(m => m.Member.Contains(id)).Login;
            }
            catch
            {
                throw new Exception("There is no palantir account connected with this discord account.\nCreate one by messaging Palantir `>login` in DM!");
            }
            context.Dispose();
            return(login);
        }
コード例 #22
0
        public static List <int> ParticipatedEvents(string login)
        {
            List <int>        events     = new List <int>();
            PalantirDbContext context    = new PalantirDbContext();
            List <int>        eventdrops = context.EventCredits.Where(credit => credit.Login == login).Select(credit => credit.EventDropID).ToList();

            eventdrops.ForEach(caughtdrop =>
            {
                int eventid = context.EventDrops.FirstOrDefault(drop => caughtdrop == drop.EventDropID).EventID;
                if (!events.Contains(eventid))
                {
                    events.Add(eventid);
                }
            });
            context.Dispose();
            return(events);
        }
コード例 #23
0
        public void AddMember(Member member)
        {
            PalantirDbContext Database = new PalantirDbContext();

            PalantirMembers.Add(member);

            // add to db
            MemberEntity entity = new MemberEntity();

            entity.Login   = member.UserLogin;
            entity.Member  = JsonConvert.SerializeObject(member);
            entity.Bubbles = 0;
            entity.Sprites = "";
            Database.Members.Add(entity);
            Database.SaveChanges();
            Database.Dispose();
        }
コード例 #24
0
        public void SavePalantiri(ObservedGuild guild)
        {
            bool newGuild = true;
            PalantirDbContext Database = new PalantirDbContext();

            // If guild of new palantir has already an active palantir, close tether, replace palantir and reopen tether
            PalantirTethers.ForEach((t) => {
                if (t.PalantirEndpoint.GuildID == guild.GuildID)
                {
                    string oldToken = t.PalantirEndpoint.ObserveToken;
                    // update tether
                    t.StopDataflow();
                    t.SetNewPalantirEndpoint(guild);
                    t.EstablishDataflow();
                    newGuild = false;

                    // Console.WriteLine("Change token from " + oldToken + " to " + guild.ObserveToken);
                    // update db entry
                    Database.Palantiri.Remove(Database.Palantiri.FirstOrDefault(p => p.Token == oldToken));
                    PalantirEntity entity = new PalantirEntity();
                    entity.Palantir       = JsonConvert.SerializeObject(guild);
                    entity.Token          = guild.ObserveToken;
                    Database.Palantiri.Add(entity);
                    Database.SaveChanges();
                }
            });

            if (newGuild)
            {
                // add tether
                Tether tether = new Tether(guild);
                tether.EstablishDataflow();
                PalantirTethers.Add(tether);

                // Add db entry
                PalantirEntity entity = new PalantirEntity();
                entity.Token    = guild.ObserveToken;
                entity.Palantir = JsonConvert.SerializeObject(guild);
                Database.Palantiri.Add(entity);
                Database.SaveChanges();
            }
            Database.Dispose();
            UpdateMemberGuilds();
        }
コード例 #25
0
        public static bool ChangeEventDropCredit(string login, int eventDropID, int difference)
        {
            PalantirDbContext context = new PalantirDbContext();
            EventCreditEntity credit  = context.EventCredits.FirstOrDefault(c => c.EventDropID == eventDropID && c.Login == login);

            if (credit is object)
            {
                try
                {
                    credit.Credit += difference;
                    context.SaveChanges();
                    context.Dispose();
                }
                catch (Exception e)
                {
                    context.Dispose();
                    Console.WriteLine("Error changing credits for " + login + ":\n" + e);
                    return(false);
                }
            }
            else if (difference > 0)
            {
                EventCreditEntity newCredit = new EventCreditEntity();
                newCredit.Login       = login;
                newCredit.EventDropID = eventDropID;
                newCredit.Credit      = difference;
                try
                {
                    context.EventCredits.Add(newCredit);
                    context.SaveChanges();
                    context.Dispose();
                }
                catch (Exception e)
                {
                    context.Dispose();
                    Console.WriteLine("Error changing credits for " + login + ":\n" + e);
                    return(false);
                }
            }

            return(true);
        }
コード例 #26
0
        public void RemovePalantiri(ObservedGuild guild)
        {
            // remove tether
            PalantirTethers.Remove(PalantirTethers.Find(t => t.PalantirEndpoint.ObserveToken == guild.ObserveToken));

            // remove palantir from db
            PalantirDbContext context = new PalantirDbContext();
            PalantirEntity    e       = context.Palantiri.FirstOrDefault(ptr => ptr.Token == guild.ObserveToken);

            context.Palantiri.Remove(e);
            try
            {
                context.SaveChanges();
            }
            catch (Exception ex) { Console.WriteLine(ex.ToString()); }
            context.Dispose();
            // restart string op = "sudo service palantir restart".Bash();
            //Environment.Exit(0);
            //UpdateMemberGuilds();
        }
コード例 #27
0
        public void UpdatePalantirSettings(Tether tether)
        {
            PalantirDbContext   context = new PalantirDbContext();
            GuildSettingsEntity entity  = context.GuildSettings.FirstOrDefault(s => s.GuildID == tether.PalantirEndpoint.GuildID);

            if (entity != null)
            {
                entity.Settings = JsonConvert.SerializeObject(tether.PalantirSettings);
                context.SaveChanges();
            }
            else
            {
                entity          = new GuildSettingsEntity();
                entity.GuildID  = tether.PalantirEndpoint.GuildID;
                entity.Settings = JsonConvert.SerializeObject(tether.PalantirSettings);
                context.GuildSettings.Add(entity);
                context.SaveChanges();
            }
            context.SaveChanges();
            context.Dispose();
        }
コード例 #28
0
        public static string SetInventory(List <SpriteProperty> sprites, string login)
        {
            string        inv       = "";
            List <Sprite> available = GetAvailableSprites();

            available.ForEach(s =>
            {
                if (sprites.Any(a => a.ID == s.ID))
                {
                    SpriteProperty found = sprites.FirstOrDefault(a => a.ID == s.ID);
                    inv += (found.Activated ? new string('.', found.Slot) : "") + s.ID + ",";
                }
            });
            inv = inv.Remove(inv.Length - 1);
            PalantirDbContext context = new PalantirDbContext();

            context.Members.FirstOrDefault(m => m.Login == login).Sprites = "0," + inv;
            context.SaveChanges();
            context.Dispose();
            return(inv);
        }
コード例 #29
0
        public static void SetOnlineSprite(string login, string lobbyKey, string lobbyPlayerID)
        {
            List <SpriteProperty> playersprites = GetInventory(login).Where(i => i.Activated).ToList();
            PalantirDbContext     context       = new PalantirDbContext();

            context.OnlineSprites.RemoveRange(context.OnlineSprites.Where(o => o.LobbyKey == lobbyKey && lobbyPlayerID == o.LobbyPlayerID));
            try
            {
                context.SaveChanges();
            }
            catch (Exception e) { //Console.WriteLine("Error deleting sprite:\n" + e);
            }
            foreach (SpriteProperty slot in playersprites)
            {
                OnlineSpritesEntity newsprite = new OnlineSpritesEntity();
                newsprite.LobbyKey      = lobbyKey;
                newsprite.LobbyPlayerID = lobbyPlayerID;
                newsprite.Date          = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss");
                newsprite.Sprite        = slot is object?slot.ID.ToString() : "0";

                newsprite.Slot = slot.Slot + 1;
                newsprite.ID   = lobbyKey + lobbyPlayerID + slot.Slot.ToString();
                context.OnlineSprites.Add(newsprite);
            }
            //OnlineSpritesEntity aprilf = new OnlineSpritesEntity();
            //aprilf.LobbyKey = lobbyKey;
            //aprilf.LobbyPlayerID = lobbyPlayerID;
            //aprilf.Date = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss");
            //aprilf.Sprite = (new Random()).Next(1,83).ToString();
            //aprilf.Slot = 1;
            //aprilf.ID = lobbyKey + lobbyPlayerID + "aprf";
            //context.OnlineSprites.Add(aprilf);
            try
            {
                context.SaveChanges();
            }
            catch (Exception e) { Console.WriteLine("Error writing sprite:\n" + e); }
            context.Dispose();
        }
コード例 #30
0
ファイル: Tether.cs プロジェクト: toobeeh/Palantir
        private string BuildLobbyContent()
        {
            //return "```Discord lobbies are currently under maintenance. \nThis can take up to 48 hours.\nSorry & see ya!```";
            string            message  = "";
            PalantirDbContext Database = new PalantirDbContext();

            List <Lobby>        Lobbies = new List <Lobby>();
            List <ReportEntity> reports = Database.Reports.Distinct().Where(r => r.ObserveToken == PalantirEndpoint.ObserveToken).ToList();

            List <PlayerStatus> OnlinePlayers = new List <PlayerStatus>();
            List <StatusEntity> playerstatus  = Database.Status.Distinct().ToList();

            reports.ForEach((r) =>
            {
                if (DateTime.ParseExact(r.Date, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture) > DateTime.UtcNow.AddSeconds(-8))
                {
                    try
                    {
                        //Console.WriteLine("Found report: " + r.LobbyID);
                        Lobbies.Add(JsonConvert.DeserializeObject <Lobby>(r.Report));
                    }
                    catch (Exception e) { Console.WriteLine(DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss") + " > Couldnt read lobby entry: " + e); };
                }
            });

            playerstatus.ForEach((p) =>
            {
                if (DateTime.ParseExact(p.Date, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture) > DateTime.UtcNow.AddSeconds(-8))
                {
                    try
                    {
                        OnlinePlayers.Add(JsonConvert.DeserializeObject <PlayerStatus>(p.Status));
                    }
                    catch (Exception e) { Console.WriteLine(DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss") + " > Couldnt read status file: " + e); };
                }
            });

            List <Lobby> GuildLobbies = new List <Lobby>();

            Lobbies.ForEach((l) =>
            {
                if (l.GuildID.ToString() == PalantirEndpoint.GuildID && l.ObserveToken == PalantirEndpoint.ObserveToken)
                {
                    GuildLobbies.Add(l);
                }
            });

            List <EventEntity> events = Events.GetEvents(true);

            if (events.Count <= 0)
            {
                message += "```arm\nNo event active :( Check upcoming events with '>upcoming'.\n‎As soon as an event is live, you can see details using '>event'.```\n\n";
            }
            else
            {
                message += "```arm\n" + events[0].EventName + ": \n" + events[0].Description + "\nView details with '>event'!```\n";
            }

            message += PalantirSettings.Header + "\n";
            if (PalantirSettings.ShowRefreshed)
            {
                message += "Refreshed: <t:" + DateTimeOffset.UtcNow.ToUnixTimeSeconds() + ":R> \n";                                //+ DateTime.UtcNow.AddHours(PalantirSettings.Timezone).ToShortTimeString() + " (UTC " + PalantirSettings.Timezone.ToString("+0;-#") + ")\n";
            }
            if (PalantirSettings.ShowToken)
            {
                message += "Server token: `" + PalantirEndpoint.ObserveToken + "`\n";
            }

            message += "\n";

            GuildLobbies.ForEach((l) =>
            {
                string lobby         = "";
                string lobbyUniqueID = l.ID;

                List <short> scores = new List <short>();
                foreach (Player p in l.Players)
                {
                    if (!scores.Contains(p.Score))
                    {
                        scores.Add(p.Score);
                    }
                }
                scores.Sort((a, b) => b.CompareTo(a));


                // get description if private
                string lobbyDescription = "";
                if (l.Private)
                {
                    string d;
                    string json = "";
                    try
                    {
                        json = Database.Lobbies.FirstOrDefault(lobbyEntity => lobbyEntity.LobbyID == l.ID).Lobby;
                        ProvidedLobby lobbyraw = JsonConvert.DeserializeObject <ProvidedLobby>(json);
                        d = lobbyraw.Description;
                        if (d.Length > 100)
                        {
                            d = d.Substring(0, 100);
                        }
                        if (d.Contains("#nojoin"))
                        {
                            l.Link = "Closed Private Game";
                        }
                        if (lobbyraw.Restriction == "restricted")
                        {
                            l.Link = "Restricted Private Game";
                        }
                        else if (lobbyraw.Restriction != "unrestricted" && PalantirEndpoint.GuildID != lobbyraw.Restriction)
                        {
                            l.Link = "Server-Restricted Private Game";
                        }
                    }
                    catch (Exception e) {
                        //Console.WriteLine(DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss") + " > Cant parse description: " + json);
                        d = "";
                    };

                    if (d != "")
                    {
                        lobbyDescription = "> `" + DSharpPlus.Formatter.Sanitize(d).Replace("`", "").Replace("\n", "") + "`\n";
                    }
                }

                // set id to index
                l.ID   = Convert.ToString(GuildLobbies.IndexOf(l) + 1);
                lobby += "> **#" + l.ID + "**    " + (PalantirSettings.ShowAnimatedEmojis ? Emojis[(new Random()).Next(Emojis.Count - 1)] : "") + "     " + l.Host + "   **|**  " + l.Language + "   **|**   Round " + l.Round + "   **|**   " + (l.Host == "skribbl.io" ? (l.Private ? "Private " + "\n> <" + l.Link + ">" : "Public") : "<" + l.Link + ">") + "\n> " + l.Players.Count + " Players \n";

                if (lobbyDescription != "")
                {
                    lobby += lobbyDescription.Replace("\\", "");
                }

                string players = "";
                string sender  = "```fix\n";
                foreach (Player player in l.Players)
                {
                    string login       = "";
                    PlayerStatus match = OnlinePlayers.FirstOrDefault(p => p.Status == "playing" && p.LobbyID == lobbyUniqueID && p.LobbyPlayerID == player.LobbyPlayerID && p.PlayerMember.Guilds.Count(g => g.GuildID == l.GuildID) > 0);
                    if (match != null)
                    {
                        player.Sender = true;
                        player.ID     = match.PlayerMember.UserID;
                        login         = match.PlayerMember.UserLogin;
                        if (l.Host == "skribbl.io")
                        {
                            try
                            {
                                BubbleWallet.AddBubble(login);
                            }
                            catch (Microsoft.Data.Sqlite.SqliteException e) // catch sql exceptions
                            {
                                if (e.SqliteErrorCode == 8)
                                {
                                    Console.WriteLine(DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss") + " > Locked DB. Skipped adding bubble for " + login);
                                }
                                else
                                {
                                    Console.WriteLine(DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss") + " > DB Error: " + e.SqliteErrorCode + ". Skipped adding bubble for " + login);
                                }
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine("Unhandled error adding Bubble for login " + login + " : \n" + e.ToString());
                            }
                            try
                            {
                                BubbleWallet.SetOnlineSprite(login, l.Key, player.LobbyPlayerID);
                            }
                            catch (Microsoft.Data.Sqlite.SqliteException e) // catch sql exceptions
                            {
                                if (e.SqliteErrorCode == 8)
                                {
                                    Console.WriteLine(DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss") + " > Locked DB. Skipped setting sprite for " + login);
                                }
                                else
                                {
                                    Console.WriteLine(DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss") + " > DB Error: " + e.SqliteErrorCode + ". Skipped setting sprite for " + login);
                                }
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine("Unhandled error setting Sprite for login " + login);
                            }
                        }
                    }

                    if (player.Sender)
                    {
                        string line = "";
                        line       += Formatter.Sanitize(player.Name).Replace("\\", "");
                        line       += new string(' ', (20 - player.Name.Length) < 0 ? 0 : (20 - player.Name.Length));
                        line       += player.Score + " pts";
                        if (player.Score != 0)
                        {
                            if (scores.IndexOf(player.Score) == 0)
                            {
                                line += " 🏆 ";
                            }
                            if (scores.IndexOf(player.Score) == 1)
                            {
                                line += " 🥈 ";
                            }
                            if (scores.IndexOf(player.Score) == 2)
                            {
                                line += " 🥉 ";
                            }
                        }
                        line += new string(' ', (32 - line.Length) < 0 ? 0 : (32 - line.Length));
                        string patronEmoji = "";
                        if (Program.Feanor.PatronEmojis.Count > 0 && Program.Feanor.PatronEmojis.Keys.Any(key => key == login))
                        {
                            patronEmoji = Program.Feanor.PatronEmojis[login];
                        }
                        if (patronEmoji.Length > 0)
                        {
                            line += "  " + patronEmoji + " ";
                        }
                        else if (l.Host == "skribbl.io")
                        {
                            line += "  🔮 " + BubbleWallet.GetBubbles(login) + " Bubbles";
                        }
                        line   += player.Drawing ? " 🖍 \n" : "\n";
                        sender += line;
                    }
                    else
                    {
                        if (player.Score != 0)
                        {
                            if (scores.IndexOf(player.Score) == 0)
                            {
                                players += " `🏆` ";
                            }
                            if (scores.IndexOf(player.Score) == 1)
                            {
                                players += " `🥈` ";
                            }
                            if (scores.IndexOf(player.Score) == 2)
                            {
                                players += " `🥉` ";
                            }
                        }
                        players += Formatter.Sanitize(player.Name);
                        players += (player.Drawing ? " 🖍, " : ", ");
                    }
                }
                if (players.Length > 0)
                {
                    players = players[0..^ 2];
                }