namespace Remote_Control { public class CharThread { //Attached thread's PID info public PID ThreadPIDInfo; public static Dictionary PIDSessionDict = new Dictionary(); //Each instance of CharThread should hold a Character private Characters _myChar; //Should also have the thread crap it'll be using private Thread _charThread; //Instance private static CharThread _instance; //Array for splitting private static char[] _splitArr = " ".ToCharArray(); //bool for the stats display private static bool _isLaunched = false; //Constructor should take the char this will be holding public CharThread(Characters Character) { //Set our held character reference to whatever we're passed _myChar = Character; } //Private constructor used for singleton private CharThread() { } public static void StartCharacter(CharThread charRef) { /* CharThread._charThread = new Thread(new ParameterizedThreadStart(CharThread.Start)); CharThread._charThread.IsBackground = true; CharThread._charThread.Start(_myChar); */ charRef._charThread = new Thread(new ThreadStart(charRef.Start)); charRef._charThread.IsBackground = true; charRef._charThread.Start(); } public static void StopCharacter() { } //One public method to rule them all... private static void Start() { //Launch the session PID tempStruct = LaunchSession(_myChar); //Load extensions and apps LoadExtAndApps(tempStruct); } //Launch a session for our Character private static PID LaunchSession(Characters Character) { PID tempPID = default(PID); //If our character is a wow character... if (Character is WoWCharacter) { //May be error-ish if configuration isn't correct. //Start the process for an IS-session of WoW. System.Diagnostics.Process.Start(String.Format("{0} open {1} {2}", Config.ISfilePath, Config.WoWProfile, Config.WoWProfileName)); Main.OnLogEvent(CharThread.Instance, String.Format("CharThread.LaunchSession(): Launched {0} for {1}, {2}", Config.ISfilePath, Config.WoWProfile, Config.WoWProfileName)); } else if (Character is EVECharacter) { //Same as above, but for EVE System.Diagnostics.Process.Start(String.Format("{0}\\InnerSpace.exe", Config.ISfilePath), String.Format("open \"{1}\" \"{2}\"", Config.ISfilePath, Config.EVEProfileName, Config.EVEProfile)); Main.OnLogEvent(CharThread.Instance, String.Format("CharThread.LaunchSession(): Launched {0} for {1}, {2}", Config.ISfilePath, Config.EVEProfileName, Config.EVEProfile)); } _isLaunched = true; //Give the thread a breather to get running, 5 seconds sounds good Thread.Sleep(20000); List tempList = new List(); //Go through and add all IS processes detected to a temp list foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcessesByName("ExeFile")) { tempList.Add(p.Id); Main.OnLogEvent(CharThread.Instance, String.Format("CharThread.LaunchSession(): Added {0} ({1}) to tempList.", p.Id, p.ToString())); } //Check our temp list against known list for differences if (tempList.Count > MonitorThread.ListCount()) { //For every PID in the temp list... foreach (int i in tempList) { using (System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(i)) { //If our window is an IS session, is one of the valid game .exe files, and isn't in the pidlist... if (p.MainWindowTitle.Contains(" (Ctrl+Alt") && (p.ProcessName.Contains("ExeFile") || p.ToString().Contains("WoW.exe")) && !MonitorThread.ContainsID(p.Id)) { //we've found a session that needs added. string[] tempString = p.MainWindowTitle.Split(_splitArr); // Should grab the # from is2 and similar for the session # tempPID = new PID(p.Id, _myChar, int.Parse(tempString[0].Substring(2))); //Add a new PID to our list of things to monitor MonitorThread.AddToList(tempPID); ThreadPIDInfo = tempPID; //Make sure monitor is starting MonitorThread.StartMonitoring(); Main.OnLogEvent(CharThread.Instance, String.Format("CharThread.LaunchThread(): Adding process {0} ({1}) to list.", p.ProcessName, p.Id)); } } } } return tempPID; //We're launched. Move on to the next step. } //run, in a character's session, commands to load relevant ext's and apps private static void LoadExtAndApps(PID infoStruct) { //Temporary semi-stub //LavishScript.ExecuteCommand("relay {0} ext {1}", infoStruct.Session, "isxeve"); System.Diagnostics.Process.Start(String.Format("\"{0}\\{1}\"", Config.ISfilePath, "InnerSpace.exe"), String.Format("relay is{0} ext {1}", infoStruct.Session, "isxeve")); Main.OnLogEvent(CharThread.Instance, String.Format("CharThread.LoadExtAndApps(): Testing echo on is{0}", infoStruct.Session)); } //Singleton property public static CharThread Instance { get { if (_instance == null) _instance = new CharThread(); return _instance; } } //IsCharacterLaunched? public static bool IsLaunched { get { return _isLaunched; } } } public class MonitorThread { //Monitoring thread private static Thread _monitorThread; //dictionary of PIDs to watch private static List MonitorList = new List(); //killswitch for monitoring private static bool ShouldMonitor = false; //Singleton reg private static MonitorThread _instance; private MonitorThread() { } public static void AddToList(PID myPid) { MonitorList.Add(myPid); } public static void RemoveFromList(PID myPid) { MonitorList.Remove(myPid); } public static int ListCount() { return MonitorList.Count; } public static bool ContainsID(int ID) { foreach (PID p in MonitorList) { if (p.ID == ID) return true; } return false; } //Flip the switch on and start a thread for it public static void StartMonitoring() { if (ShouldMonitor == false) { Main.OnLogEvent(MonitorThread.Instance, "MonitorThread.Start(): Starting to monitor."); ShouldMonitor = true; _monitorThread = new Thread(new ThreadStart(MonitorThread.Monitor)); _monitorThread.IsBackground = true; _monitorThread.Start(); } } //flip the switch off, effectively ending the thread public static void StopMonitoring() { Main.OnLogEvent(MonitorThread.Instance, "MonitorThread.Stop(): Stopping!"); ShouldMonitor = false; _monitorThread.Join(); } //Do the monitoring private static void Monitor() { //While I should monitor... while (MonitorThread.ShouldMonitor) { //queue for changes to MonitorList Queue changeQueue = new Queue(); //de-stubify later foreach (PID pid in MonitorThread.MonitorList) { //If we can't find our process id, it's dead. try { System.Diagnostics.Process.GetProcessById(pid.ID); } catch (ArgumentException) { Main.OnLogEvent(MonitorThread.Instance, String.Format("MonitorThread.Monitor(): Lost {0}, re-launching", pid.ID)); //Start a new session for it CharThread tempChar = new CharThread(pid.Character); //Perform some cleanup by removing the old entry in the PID list changeQueue.Enqueue(pid); } } foreach (PID pid in changeQueue) { MonitorList.Remove(pid); } //Give our poor CPU some time off Thread.Sleep(1000); } } //Singleton instance public static MonitorThread Instance { get { if (_instance == null) _instance = new MonitorThread(); return _instance; } } } public struct PID { private int _id; private Characters _character; private int _session; #region constructors public PID(int id, Characters mychar, int session) { _id = id; _character = mychar; _session = session; } public PID(int id, int session) { _id = id; _character = null; _session = session; } #endregion #region properties public int ID { get { return _id; } set { _id = value; } } public Characters Character { get { return _character; } set { _character = value; } } public int Session { get { return _session; } set { _session = value; } } #endregion } }