using SHN;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using System.Timers;

using DiscordSharp;
using DiscordSharp.Objects;

namespace GameLog_Monitor
{
    internal enum Class
    {
        Fighter = 1,
        CleverFighter = 2,
        Warrior = 3,
        Gladiator = 4,
        Knight = 5,
        Cleric = 6,
        HighCleric = 7,
        Paladin = 8,
        HolyKnight = 9,
        Guardian = 10,
        Archer = 11,
        HawkArcher = 12,
        Scout = 13,
        SharpShooter = 14,
        Ranger = 15,
        Mage = 16,
        WizMage = 17,
        Enchanter = 18,
        Warlock = 19,
        Wizard = 20,
        Trickster = 21,
        Gambit = 22,
        Renegade = 23,
        Spectre = 24,
        Reaper = 25
    }

    internal class Program
    {
        private static DiscordClient Discord;
        private static Dictionary<Int32, String> ItemNames = new Dictionary<Int32, String>();
        private static Dictionary<Int32, String> MobNames = new Dictionary<Int32, String>();
        private static Dictionary<Int32, String> SkillNames = new Dictionary<Int32, String>();

        private static SqlConnectionStringBuilder ConnectionBuilder;
        private static SqlConnection Connection;

        private static Int64 LastReadID = 0;
        private static Int64 LastReadItemKey = 0;
        private static Dictionary<Int32, Byte> AdminLevels = new Dictionary<Int32, Byte>();
        private static Dictionary<Int32, Dictionary<Int64, Byte>> EquipedItems = new Dictionary<Int32, Dictionary<Int64, Byte>>();

        private static Timer GameLogTimer;
        private static Timer AdminTimer;
        private static Timer ItemTimer;
        private static Timer EquipTimer;

        #region Config

        private static String DataSource = "NS3049262\\SQLEXPRESS";
        private static String Password = "T8ppWeCdRsK55p5nquJd";
        private static String UserID = "sa";

        private static String Character = "OCYA_Character";
        private static String GameLog = "OCYA_GameLog";

        #endregion

        private static void Main()
        {
            Console.Title = "GameLog Monitor :: Kobalt :: 2016";

            Discord = new DiscordClient("MjIxNzc0ODgxMTkxMTAwNDE2.Cqzvew.dS40P4p1vJ2s8AqoBqaX6yFBbp8", true);
            Discord.ClientPrivateInformation.Email = "OcyaOnline@gmail.com";
            Discord.ClientPrivateInformation.Password = "QkZ6PZOJo0gjPJf4UEnq";

            Discord.SendLoginRequest();
            Discord.Connect();

            Discord.Connected += (Sender, Args) => // Client is connected to Discord
            {
                Discord.UpdateCurrentGame("the server logs!", false);

                SHNFile ItemInfo = new SHNFile(String.Format("{0}\\ItemInfo.shn", AppDomain.CurrentDomain.BaseDirectory));
                ItemInfo.SHNEncoding = Encoding.ASCII;
                ItemInfo.Read();

                foreach (DataRow Row in ItemInfo.Table.Rows)
                {
                    try { ItemNames.Add(Convert.ToInt32(Row[0]), Convert.ToString(Row[2])); }
                    catch { }
                }

                SHNFile MobInfo = new SHNFile(String.Format("{0}\\MobInfo.shn", AppDomain.CurrentDomain.BaseDirectory));
                MobInfo.SHNEncoding = Encoding.ASCII;
                MobInfo.Read();

                foreach (DataRow Row in MobInfo.Table.Rows)
                {
                    try { MobNames.Add(Convert.ToInt32(Row[0]), Convert.ToString(Row[2])); }
                    catch { }
                }

                SHNFile ActiveSkill = new SHNFile(String.Format("{0}\\ActiveSkill.shn", AppDomain.CurrentDomain.BaseDirectory));
                ActiveSkill.SHNEncoding = Encoding.ASCII;
                ActiveSkill.Read();

                foreach (DataRow Row in ActiveSkill.Table.Rows)
                {
                    try { SkillNames.Add(Convert.ToInt32(Row[0]), Convert.ToString(Row[2])); }
                    catch { }
                }

                ConnectionBuilder = new SqlConnectionStringBuilder();
                ConnectionBuilder.DataSource = DataSource;
                ConnectionBuilder.MultipleActiveResultSets = true;
                ConnectionBuilder.Password = Password;
                ConnectionBuilder.UserID = UserID;

                Connection = new SqlConnection();
                Connection.ConnectionString = ConnectionBuilder.ConnectionString;

                try { Connection.Open(); }
                catch { }

                using (var Command = Connection.CreateCommand())
                {
                    Command.CommandText = String.Format("SELECT TOP 1 nLogNo FROM {0}..tGameLog ORDER BY nLogNo DESC", GameLog);

                    LastReadID = Convert.ToInt64(Command.ExecuteScalar());

                    Command.CommandText = String.Format("SELECT TOP 1 nItemKey FROM {0}..tItem ORDER BY nItemKey DESC", Character);

                    LastReadItemKey = Convert.ToInt64(Command.ExecuteScalar());

                    Command.CommandText = String.Format("SELECT nCharNo, nAdminLevel FROM {0}..tCharacter WHERE nAdminLevel >= 1 AND bDeleted = '0'", Character);

                    using (var Reader = Command.ExecuteReader())
                    {
                        while (Reader.Read())
                        {
                            try { AdminLevels.Add(Convert.ToInt32(Reader["nCharNo"]), Convert.ToByte(Reader["nAdminLevel"])); }
                            catch { }
                        }

                        Reader.Close();
                    }

                    Command.CommandText = String.Format("SELECT nItemKey, nStorageType, nOwner FROM {0}..tItem WHERE nStorageType = '8' OR nStorageType = '9'", Character);

                    using (var Reader = Command.ExecuteReader())
                    {
                        while (Reader.Read())
                        {
                            if (!EquipedItems.ContainsKey(Convert.ToInt32(Reader["nOwner"]))) { EquipedItems.Add(Convert.ToInt32(Reader["nOwner"]), new Dictionary<Int64, Byte>()); }

                            EquipedItems[Convert.ToInt32(Reader["nOwner"])].Add(Convert.ToInt64(Reader["nItemKey"]), Convert.ToByte(Reader["nStorageType"]));
                        }
                    }
                }

                GameLogTimer = new Timer();
                GameLogTimer.AutoReset = true;
                GameLogTimer.Elapsed += GameLogTimer_Elapsed;
                GameLogTimer.Interval = 100;
                GameLogTimer.Start();

                AdminTimer = new Timer();
                AdminTimer.AutoReset = true;
                AdminTimer.Elapsed += AdminTimer_Elapsed;
                AdminTimer.Interval = 1000;
                AdminTimer.Start();

                ItemTimer = new Timer();
                ItemTimer.AutoReset = true;
                ItemTimer.Elapsed += ItemTimer_Elapsed;
                ItemTimer.Interval = 1000;
                ItemTimer.Start();

                EquipTimer = new Timer();
                EquipTimer.AutoReset = true;
                EquipTimer.Elapsed += EquipTimer_Elapsed;
                EquipTimer.Interval = 100;
                EquipTimer.Start();
            };

            while (true) { Console.ReadLine(); }
        }

        private static void GameLogTimer_Elapsed(Object Sender, ElapsedEventArgs Args)
        {
            DiscordChannel Channel = Discord.GetChannelByName("whatshappeningingame");

            GameLogTimer.Stop();

            using (var Command = Connection.CreateCommand())
            {
                try { Connection.Open(); }
                catch { }

                Dictionary<Int32, String> CharacterNames = new Dictionary<Int32, String>();

                Command.CommandText = String.Format("SELECT nCharNo, sID FROM {0}..tCharacter", Character);

                using (var Reader = Command.ExecuteReader())
                {
                    while (Reader.Read())
                    {
                        try { CharacterNames.Add(Convert.ToInt32(Reader["nCharNo"]), Convert.ToString(Reader["sID"])); }
                        catch { }
                    }

                    Reader.Close();
                }

                Command.CommandText = String.Format("SELECT * FROM {0}..tGameLog WHERE nLogNo > {1}", GameLog, LastReadID);

                using (var Reader = Command.ExecuteReader())
                {
                    while (Reader.Read())
                    {
                        try
                        {
                            switch (Convert.ToInt32(Reader["nType"]))
                            {
                                case 10:
                                    {
                                        Console.ForegroundColor = ConsoleColor.Green;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} Logged in.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])]));

                                        break;
                                    }
                                case 11:
                                    {
                                        Console.ForegroundColor = ConsoleColor.Red;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} Logged out.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])]));

                                        break;
                                    }
                                case 15:
                                    {
                                        Console.ForegroundColor = ConsoleColor.DarkCyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} went to {2}. X: {3}. Y: {4}.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])], Reader["sMap"], Reader["nMapX"], Reader["nMapY"]));

                                        break;
                                    }
                                case 17:
                                    {
                                        Console.ForegroundColor = ConsoleColor.DarkCyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} was created.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])]));

                                        break;
                                    }
                                case 18:
                                    {
                                        Console.ForegroundColor = ConsoleColor.DarkCyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} was deleted.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])]));

                                        break;
                                    }
                                case 30:
                                    {
                                        Console.ForegroundColor = ConsoleColor.DarkCyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} leveled up to {2}.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])], Reader["nInt1"]));

                                        break;
                                    }
                                case 41:
                                    {
                                        Console.ForegroundColor = ConsoleColor.DarkCyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} killed {2} at {3}. X: {4}. Y: {5}.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])], CharacterNames[(Convert.ToInt32(Reader["nTargetCharNo"]))], Reader["sMap"], Reader["nMapX"], Reader["nMapY"]));

                                        break;
                                    }
                                case 50:
                                    {
                                        Console.ForegroundColor = ConsoleColor.DarkCyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} learned skill {2}.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])], SkillNames[Convert.ToInt32(Reader["nInt1"])]));

                                        break;
                                    }
                                case 74:
                                    {
                                        Console.ForegroundColor = ConsoleColor.Cyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} traded {2} ({3}) to {4}. Amount: {5}.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])], ItemNames[Convert.ToInt32(Reader["nTargetID"])], Reader["nItemKey"], CharacterNames[(Convert.ToInt32(Reader["nTargetCharNo"]))], Reader["nInt1"]));

                                        break;
                                    }
                                case 82:
                                    {
                                        Console.ForegroundColor = ConsoleColor.DarkCyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} enchanted {2} by {3}. Old enchant level: {4}. New enchant level: {5}.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])], Reader["nItemKey"], Convert.ToInt32(Reader["nInt2"]) - Convert.ToInt32(Reader["nInt1"]), Convert.ToInt32(Reader["nInt1"]), Convert.ToInt32(Reader["nInt2"])));

                                        break;
                                    }
                                case 87:
                                    {
                                        Console.ForegroundColor = ConsoleColor.Cyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} took {2} from {3} ({4}). New stack amount: {5}. New item key: {6}.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])], Convert.ToInt32(Reader["nInt2"]), ItemNames[Convert.ToInt32(Reader["nTargetID"])], Reader["nItemKey"], Reader["nInt1"], Reader["nBigint1"]));

                                        break;
                                    }
                                case 89:
                                    {
                                        Console.ForegroundColor = ConsoleColor.Cyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} used {2} ({3}). Left with: {4}.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])], ItemNames[Convert.ToInt32(Reader["nInt1"])], Reader["nItemKey"], Reader["nInt2"]));

                                        break;
                                    }
                                case 91:
                                    {
                                        Console.ForegroundColor = ConsoleColor.Cyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} bought {2} ({3}) from {4}. Amount: {5}. Price: {6}. New balance: {7}.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])], ItemNames[Convert.ToInt32(Reader["nTargetID"])], Reader["nItemKey"], CharacterNames[Convert.ToInt32(Reader["nTargetCharNo"])], Reader["nInt1"], Reader["nInt2"], Reader["nBigint1"]));

                                        break;
                                    }
                                case 92:
                                    {
                                        Console.ForegroundColor = ConsoleColor.Cyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} sold {2} ({3}) to {4}. Amount: {5}. Price: {6}. New balance: {7}.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])], ItemNames[Convert.ToInt32(Reader["nTargetID"])], Reader["nItemKey"], CharacterNames[Convert.ToInt32(Reader["nTargetCharNo"])], Reader["nInt1"], Reader["nInt2"], Reader["nBigint1"]));

                                        break;
                                    }
                                case 94:
                                    {
                                        Console.ForegroundColor = ConsoleColor.Cyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} despoited {2} into storage. New balance: {3}.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])], Reader["nInt1"], Reader["nBigint1"]));

                                        break;
                                    }
                                case 95:
                                    {
                                        Console.ForegroundColor = ConsoleColor.Cyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} withdrew {2} from storage. New balance: {3}.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])], Reader["nInt1"], Reader["nBigint1"]));

                                        break;
                                    }
                                case 96:
                                    {
                                        Console.ForegroundColor = ConsoleColor.Cyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} received {2} from {3}. New balance: {4}.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])], Reader["nBigint1"], CharacterNames[Convert.ToInt32(Reader["nInt1"])], Reader["nItemKey"]));

                                        break;
                                    }
                                case 97:
                                    {
                                        Console.ForegroundColor = ConsoleColor.Cyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} paid {2} to {3}. New balance: {4}.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])], Reader["nBigint1"], CharacterNames[Convert.ToInt32(Reader["nInt1"])], Reader["nItemKey"]));

                                        break;
                                    }
                                case 140:
                                    {
                                        Console.ForegroundColor = ConsoleColor.DarkCyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} created guild {2} ({3}).", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])], Reader["sMap"], Reader["nTargetID"]));

                                        break;
                                    }
                                case 510:
                                    {
                                        Console.ForegroundColor = ConsoleColor.Cyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} picked up {2} ({3}).", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])], ItemNames[Convert.ToInt32(Reader["nTargetID"])], Reader["nItemKey"]));

                                        break;
                                    }
                                case 511:
                                    {
                                        Console.ForegroundColor = ConsoleColor.DarkCyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} dropped {2} ({3}).", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])], ItemNames[Convert.ToInt32(Reader["nTargetID"])], Reader["nItemKey"]));

                                        break;
                                    }
                                case 512:
                                    {
                                        Console.ForegroundColor = ConsoleColor.DarkCyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} bought {2} ({3}) from NPC. Price: {4}.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])], ItemNames[Convert.ToInt32(Reader["nTargetID"])], Reader["nItemKey"], Reader["nInt3"]));

                                        break;
                                    }
                                case 513:
                                    {
                                        Console.ForegroundColor = ConsoleColor.DarkCyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} sold {2} ({3}) to NPC. Price: {4}.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])], ItemNames[Convert.ToInt32(Reader["nTargetID"])], Reader["nItemKey"], Reader["nInt3"]));

                                        break;
                                    }
                                case 600:
                                    {
                                        Console.ForegroundColor = ConsoleColor.DarkCyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} accepeted {2} proposal.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nTargetCharNo"])], CharacterNames[Convert.ToInt32(Reader["nCharNo"])]));

                                        break;
                                    }
                                case 910:
                                    {
                                        Console.ForegroundColor = ConsoleColor.Cyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} was spawned at {2}. X: {3}. Y: {4}.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), MobNames[Convert.ToInt32(Reader["nTargetCharNo"])], Reader["sMap"], Reader["nMapX"], Reader["nMapY"]));

                                        break;
                                    }
                                case 911:
                                    {
                                        Console.ForegroundColor = ConsoleColor.Cyan;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} was near {2} when it was killed at {3}. X: {4}. Y: {5}.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nCharNo"])], MobNames[Convert.ToInt32(Reader["nTargetCharNo"])], Reader["sMap"], Reader["nMapX"], Reader["nMapY"]));

                                        break;
                                    }
                            }
                        }
                        catch { }

                        LastReadID = Convert.ToInt64(Reader["nLogNo"]);

                        System.Threading.Thread.Sleep(100);
                    }

                    Reader.Close();
                }
            }

            GameLogTimer.Start();
        }

        private static void ItemTimer_Elapsed(Object Sender, ElapsedEventArgs Args)
        {
            DiscordChannel Channel = Discord.GetChannelByName("whatshappeningingame");

            ItemTimer.Stop();

            using (var Command = Connection.CreateCommand())
            {
                try { Connection.Open(); }
                catch { }

                Dictionary<Int32, String> CharacterNames = new Dictionary<Int32, String>();

                Command.CommandText = String.Format("SELECT nCharNo, sID FROM {0}..tCharacter", Character);

                using (var Reader = Command.ExecuteReader())
                {
                    while (Reader.Read())
                    {
                        try { CharacterNames.Add(Convert.ToInt32(Reader["nCharNo"]), Convert.ToString(Reader["sID"])); }
                        catch { }
                    }

                    Reader.Close();
                }

                Command.CommandText = String.Format("SELECT * FROM {0}..tItem WHERE nItemKey > {1} AND nStorageType = '9'", Character, LastReadItemKey);

                using (var Reader = Command.ExecuteReader())
                {
                    while (Reader.Read())
                    {
                        try
                        {
                            Console.ForegroundColor = ConsoleColor.DarkCyan;
                            Channel.SendMessage(String.Format("[{0}] :: A new {1} was created. Item Key: {2}. Character Name: {3}. Slot: {4}.", Convert.ToDateTime(Reader["dDate"]).ToString("MM/dd/yyyy || HH:mm"), ItemNames[Convert.ToInt32(Reader["nItemID"])], Reader["nItemKey"], CharacterNames[Convert.ToInt32(Reader["nOwner"])], Reader["nStorage"]));

                            LastReadItemKey = Convert.ToInt64(Reader["nItemKey"]);
                        }
                        catch { }

                        System.Threading.Thread.Sleep(100);
                    }
                }
            }

            ItemTimer.Start();
        }

        private static void AdminTimer_Elapsed(Object Sender, ElapsedEventArgs Args)
        {
            DiscordChannel Channel = Discord.GetChannelByName("whatshappeningingame");

            AdminTimer.Stop();

            using (var Command = Connection.CreateCommand())
            {
                try { Connection.Open(); }
                catch { }

                Command.CommandText = String.Format("SELECT nCharNo, sID, nAdminLevel FROM {0}..tCharacter WHERE nAdminLevel >= 1 AND bDeleted = '0'", Character);

                using (var Reader = Command.ExecuteReader())
                {
                    while (Reader.Read())
                    {
                        try
                        {
                            if (!AdminLevels.ContainsKey(Convert.ToInt32(Reader["nCharNo"])))
                            {
                                Console.ForegroundColor = ConsoleColor.Blue;
                                Channel.SendMessage(String.Format("[{0}] :: {1} has gained admin level. Admin Level: {2}.", Convert.ToDateTime(DateTime.Now).ToString("MM/dd/yyyy || HH:mm"), Reader["sID"], Reader["nAdminLevel"]));

                                AdminLevels.Add(Convert.ToInt32(Reader["nCharNo"]), Convert.ToByte(Reader["nAdminLevel"]));
                            }
                            else if (AdminLevels[Convert.ToInt32(Reader["nCharNo"])] != Convert.ToInt32(Reader["nAdminLevel"]))
                            {
                                Console.ForegroundColor = ConsoleColor.Blue;
                                Channel.SendMessage(String.Format("[{0}] :: {1}s admin level has been changed. Old Admin Level: {2}. Admin Level: {3}.", Convert.ToDateTime(DateTime.Now).ToString("MM/dd/yyyy || HH:mm"), Reader["sID"], AdminLevels[Convert.ToInt32(Reader["nCharNo"])], Reader["nAdminLevel"]));

                                AdminLevels[Convert.ToInt32(Reader["nCharNo"])] = Convert.ToByte(Reader["nAdminLevel"]);
                            }
                        }
                        catch { }

                        System.Threading.Thread.Sleep(100);
                    }

                    Reader.Close();
                }
            }

            AdminTimer.Start();
        }

        private static void EquipTimer_Elapsed(Object Sender, ElapsedEventArgs Args)
        {
            DiscordChannel Channel = Discord.GetChannelByName("whatshappeningingame");

            EquipTimer.Stop();

            using (var Command = Connection.CreateCommand())
            {

                Dictionary<Int32, String> CharacterNames = new Dictionary<Int32, String>();
                Dictionary<Int32, Byte> CharacterLevels = new Dictionary<Int32, Byte>();
                Dictionary<Int32, Byte> CharacterClasses = new Dictionary<Int32, Byte>();

                Command.CommandText = String.Format("SELECT nCharNo, sID, nLevel FROM {0}..tCharacter", Character);

                using (var Reader = Command.ExecuteReader())
                {
                    while (Reader.Read())
                    {
                        try
                        {
                            CharacterNames.Add(Convert.ToInt32(Reader["nCharNo"]), Convert.ToString(Reader["sID"]));
                            CharacterLevels.Add(Convert.ToInt32(Reader["nCharNo"]), Convert.ToByte(Reader["nLevel"]));
                        }
                        catch { }
                    }

                    Reader.Close();
                }

                Command.CommandText = String.Format("SELECT nCharNo, nClass FROM {0}..tCharacterShape", Character);

                using (var Reader = Command.ExecuteReader())
                {
                    while (Reader.Read())
                    {
                        try { CharacterClasses.Add(Convert.ToInt32(Reader["nCharNo"]), Convert.ToByte(Reader["nClass"])); }
                        catch { }
                    }
                }

                Command.CommandText = String.Format("SELECT nItemKey, nStorageType, nOwner, nStorage, nItemID FROM {0}..tItem WHERE nStorageType = '8' OR nStorageType = '9'", Character);

                using (var Reader = Command.ExecuteReader())
                {
                    while (Reader.Read())
                    {
                        try
                        {
                            if (!EquipedItems.ContainsKey(Convert.ToInt32(Reader["nOwner"]))) { EquipedItems.Add(Convert.ToInt32(Reader["nOwner"]), new Dictionary<Int64, Byte>()); }

                            if (!EquipedItems[Convert.ToInt32(Reader["nOwner"])].ContainsKey(Convert.ToInt64(Reader["nItemKey"])))
                            {
                                if (Convert.ToByte(Reader["nStorageType"]) == 8)
                                {
                                    Console.ForegroundColor = ConsoleColor.Gray;
                                    Channel.SendMessage(String.Format("[{0}] :: {1} ({2}) [{3}] equiped {4}. Item Key: {5}. Slot: {6}.", DateTime.Now.ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nOwner"])], CharacterLevels[Convert.ToInt32(Reader["nOwner"])], (Class)CharacterClasses[Convert.ToInt32(Reader["nOwner"])], ItemNames[Convert.ToInt32(Reader["nItemID"])], Reader["nItemKey"], Reader["nStorage"]));

                                    EquipedItems[Convert.ToInt32(Reader["nOwner"])].Add(Convert.ToInt64(Reader["nItemKey"]), 8);
                                }
                                else { EquipedItems[Convert.ToInt32(Reader["nOwner"])].Add(Convert.ToInt64(Reader["nItemKey"]), 9); }
                            }
                            else
                            {
                                if (EquipedItems[Convert.ToInt32(Reader["nOwner"])][Convert.ToInt64(Reader["nItemKey"])] != Convert.ToByte(Reader["nStorageType"]))
                                {
                                    if (Convert.ToByte(Reader["nStorageType"]) == 8)
                                    {
                                        Console.ForegroundColor = ConsoleColor.Gray;
                                        Channel.SendMessage(String.Format("[{0}] :: {1} ({2}) [{3}] equiped {4}. Item Key: {5}. Slot: {6}.", DateTime.Now.ToString("MM/dd/yyyy || HH:mm"), CharacterNames[Convert.ToInt32(Reader["nOwner"])], CharacterLevels[Convert.ToInt32(Reader["nOwner"])], (Class)CharacterClasses[Convert.ToInt32(Reader["nOwner"])], ItemNames[Convert.ToInt32(Reader["nItemID"])], Reader["nItemKey"], Reader["nStorage"]));

                                        EquipedItems[Convert.ToInt32(Reader["nOwner"])][Convert.ToInt64(Reader["nItemKey"])] = 8;
                                    }
                                    else { EquipedItems[Convert.ToInt32(Reader["nOwner"])][Convert.ToInt64(Reader["nItemKey"])] = 9; }
                                }
                            }
                        }
                        catch { }

                        System.Threading.Thread.Sleep(100);
                    }

                    Reader.Close();
                }
            }

            EquipTimer.Start();
        }
    }
}
