using System; using System.IO; using System.Linq; using System.Threading; using System.Windows.Forms; using System.Data.SqlClient; using System.Collections.Generic; using FilterAPI; namespace FilterItemWatcher { internal static class Program { public static Authentication Auth; public static Database SQL; private static List ItemIDs = new List(); private static List ExistingItems = new List(); private static List WrittennItemKeys = new List(); private static Boolean CheckerIsDone = true; private static void Main(String[] Args) { AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; Program.Auth = new Authentication(); Program.SQL = new Database(Program.Auth); Console.Title = String.Format("{0} Filter [Item Watcher] :: Aeris.NET :: 2017/2018", Program.Auth.ConfigValues["ServerName"]); foreach (String Line in File.ReadAllLines(String.Format("{0}ItemIDs.txt", AppDomain.CurrentDomain.BaseDirectory))) { ItemIDs.Add(Convert.ToUInt16(Line)); } Thread NewThread = new Thread(delegate () { while (true) { if (CheckerIsDone) { RunChecker(); } Thread.Sleep(50); } }); NewThread.Start(); } private static void CurrentDomain_UnhandledException(Object Sender, UnhandledExceptionEventArgs Args) { File.WriteAllLines(String.Format("{0}{1}Crash.txt", AppDomain.CurrentDomain.BaseDirectory, AppDomain.CurrentDomain.FriendlyName.Replace(".exe", "")), new String[] { ((Exception)Args.ExceptionObject).ToString() }); } private static void RunChecker() { CheckerIsDone = false; try { using (SqlCommand Command = Program.SQL.Connection.CreateCommand()) { Dictionary sIDs = new Dictionary(); Command.CommandText = String.Format("SELECT nCharNo, sID FROM {0}..tCharacter WHERE bDeleted = '0'", Program.Auth.ConfigValues["CharacterDB"]); using (SqlDataReader Reader = Command.ExecuteReader()) { while (Reader.Read()) { sIDs.Add(Convert.ToInt32(Reader["nCharNo"]), Convert.ToString(Reader["sID"])); } } String IDCommand = "WHERE "; foreach (UInt16 ItemID in ItemIDs) { IDCommand += String.Format("nItemID = '{0}' OR ", ItemID); } IDCommand = IDCommand.TrimEnd(" OR ".ToCharArray()); Command.CommandText = String.Format("SELECT nItemKey, nOwner, nItemID, dDate FROM {0}..tItem {1}", Program.Auth.ConfigValues["CharacterDB"], IDCommand); using (SqlDataReader Reader = Command.ExecuteReader()) { while (Reader.Read()) { if (ExistingItems.Where(nItemKey => nItemKey.nItemKey == Convert.ToUInt64(Reader["nItemKey"])).FirstOrDefault() == null) { ExistingItems.Add(new Item { nItemKey = Convert.ToUInt64(Reader["nItemKey"]), nOwner = Convert.ToInt32(Reader["nOwner"]), nItemID = Convert.ToUInt16(Reader["nItemID"]), dDate = Convert.ToDateTime(Reader["dDate"]) }); } } } foreach (Item ExistingItem in ExistingItems.ToArray()) { Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..tItem WHERE nItemKey = '{1}'", Program.Auth.ConfigValues["CharacterDB"], ExistingItem.nItemKey); if (Convert.ToInt32(Command.ExecuteScalar()) == 0) { Thread.Sleep(230); Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..tGameLog WHERE (nType = '69' OR nType = '89' OR nType = '511') AND nItemKey = '{1}'", Program.Auth.ConfigValues["GameLogDB"], ExistingItem.nItemKey); if (sIDs.ContainsKey(ExistingItem.nOwner) && Convert.ToInt32(Command.ExecuteScalar()) == 0) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("[{0}] :: {1}'s item was deleted, but was never destoryed/used/dropped. nItemKey: {2}. nItemID: {3}. nCharNo: {4}.", DateTime.Now.ToString("HH:mm:ss"), sIDs[ExistingItem.nOwner], ExistingItem.nItemKey, ExistingItem.nItemID, ExistingItem.nOwner); WrittennItemKeys.Add(ExistingItem.nItemKey); } ExistingItems.Remove(ExistingItem); } else { Command.CommandText = String.Format("SELECT TOP 1 nOptionData FROM {0}..tItemOptions WHERE nItemKey = '{1}' AND nOptionType = '1001'", Program.Auth.ConfigValues["CharacterDB"], ExistingItem.nItemKey); Int64 nOptionData = Convert.ToInt64(Command.ExecuteScalar()); if (nOptionData != 0 && !WrittennItemKeys.Contains(ExistingItem.nItemKey)) { Console.ForegroundColor = ConsoleColor.Magenta; Console.WriteLine("[{0}] :: {1}'s item has value that isn't 0, it is set to \"{2}\". nItemKey: {3}. nItemID: {4}. nCharNo: {5}.", DateTime.Now.ToString("HH:mm:ss"), sIDs[ExistingItem.nOwner], nOptionData, ExistingItem.nItemKey, ExistingItem.nItemID, ExistingItem.nOwner); WrittennItemKeys.Add(ExistingItem.nItemKey); } } } } } catch { } CheckerIsDone = true; } } public class Item { public UInt64 nItemKey { get; set; } public Int32 nOwner { get; set; } public UInt16 nItemID { get; set; } public DateTime dDate { get; set; } } }