public void initPropConfig(ContentManager content, String PropConfigFile) { var doc = XDocument.Load(PropConfigFile); var Props = doc.Element("Props").Elements("Prop"); var Doors = doc.Element("Props").Elements("Door"); var Potions = doc.Element("Props").Elements("Potion"); var Keys = doc.Element("Props").Elements("Key"); var WeaponItems = doc.Element("Props").Elements("Weapon"); String PropClass; Texture2D PropTexture; int PropWidth; int PropHeight; String DoorClass; Texture2D DoorTexture; int DoorWidth; int DoorHeight; String PotionClass; Texture2D PotionTexture; int PotionWidth; int PotionHeight; int PotionRestore; String KeyClass; Texture2D KeyTexture; int KeyWidth; int KeyHeight; String WeaponClass; Texture2D WeaponTexture; int WeaponX; int WeaponY; int WeaponWidth; int WeaponHeight; int texWidth; int texHeight; foreach (XElement Prop in Props) { PropClass = Prop.Attribute("className").Value; PropTexture = content.Load <Texture2D>(Prop.Attribute("texture").Value); PropWidth = int.Parse(Prop.Attribute("width").Value); PropHeight = int.Parse(Prop.Attribute("height").Value); texWidth = int.Parse(Prop.Attribute("texWidth").Value); texHeight = int.Parse(Prop.Attribute("texHeight").Value); this.PropPrototypes[PropClass] = new Prop(PropTexture, PropWidth, PropHeight, texWidth, texHeight); this.PropPrototypes[PropClass].className = PropClass; } foreach (XElement Door in Doors) { DoorClass = Door.Attribute("className").Value; DoorTexture = content.Load <Texture2D>(Door.Attribute("texture").Value); DoorWidth = int.Parse(Door.Attribute("width").Value); DoorHeight = int.Parse(Door.Attribute("height").Value); texWidth = int.Parse(Door.Attribute("texWidth").Value); texHeight = int.Parse(Door.Attribute("texHeight").Value); this.DoorPrototypes[DoorClass] = new Door(DoorTexture, DoorWidth, DoorHeight, texWidth, texHeight); this.DoorPrototypes[DoorClass].className = DoorClass; } foreach (XElement Potion in Potions) { PotionClass = Potion.Attribute("className").Value; PotionTexture = content.Load <Texture2D>(Potion.Attribute("texture").Value); PotionWidth = int.Parse(Potion.Attribute("width").Value); PotionHeight = int.Parse(Potion.Attribute("height").Value); texWidth = int.Parse(Potion.Attribute("texWidth").Value); texHeight = int.Parse(Potion.Attribute("texHeight").Value); PotionRestore = int.Parse(Potion.Attribute("restore").Value); this.PotionPrototypes[PotionClass] = new Potion(PotionTexture, PotionWidth, PotionHeight, texWidth, texHeight, PotionRestore); this.PotionPrototypes[PotionClass].className = PotionClass; } foreach (XElement Key in Keys) { KeyClass = Key.Attribute("className").Value; KeyTexture = content.Load <Texture2D>(Key.Attribute("texture").Value); KeyWidth = int.Parse(Key.Attribute("width").Value); KeyHeight = int.Parse(Key.Attribute("height").Value); texWidth = int.Parse(Key.Attribute("texWidth").Value); texHeight = int.Parse(Key.Attribute("texHeight").Value); this.KeyPrototypes[KeyClass] = new Key(KeyTexture, KeyWidth, KeyHeight, texWidth, texHeight); this.KeyPrototypes[KeyClass].className = KeyClass; } foreach (XElement Weapon in WeaponItems) { WeaponClass = Weapon.Attribute("className").Value; WeaponTexture = content.Load <Texture2D>(Weapon.Attribute("texture").Value); WeaponX = int.Parse(Weapon.Attribute("offsetX").Value); WeaponY = int.Parse(Weapon.Attribute("offsetY").Value); WeaponWidth = int.Parse(Weapon.Attribute("width").Value); WeaponHeight = int.Parse(Weapon.Attribute("height").Value); texWidth = int.Parse(Weapon.Attribute("texWidth").Value); texHeight = int.Parse(Weapon.Attribute("texHeight").Value); this.WeaponItemPrototypes[WeaponClass] = new WeaponItem(WeaponTexture, WeaponClass, WeaponWidth, WeaponHeight, WeaponX, WeaponY, texWidth, texHeight); } }
void OnMessageReceived(byte[] RawMessage) { try { string Message = Encoding.Unicode.GetString(RawMessage); XElement xMsg = XElement.Parse(Message, LoadOptions.PreserveWhitespace); if (xMsg.Name.LocalName == "Connect-Terminal") { try { string Domain = xMsg.Attribute("Domain").Value; string UserName = xMsg.Attribute("UserName").Value; string Password = xMsg.Attribute("Password").Value; lock (ProcessLock) { // Remove any processes which have exited so that instead of reattaching we launch a new one... List <string> ToRemove = new List <string>(); foreach (var kvp in Processes) { var TheProcess = kvp.Value; if (TheProcess.CommandPrompt == null || !TheProcess.CommandPrompt.IsStillRunning) { ToRemove.Add(kvp.Key); } } foreach (string Key in ToRemove) { Processes.Remove(Key); } // Next check if we have this process already open, referenced by full username... string FullUserName; if (Domain.Length > 0) { FullUserName = Domain + "\\" + UserName; } else { FullUserName = UserName; } if (Processes.ContainsKey(FullUserName)) { CredentialValidation.ValidateUser(Domain, UserName, Password); ConnectedProcess = Processes[FullUserName]; if (!ConsoleApi.AttachConsole((uint)ConnectedProcess.CommandPrompt.ProcessId)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } if (Conin != null) { Conin.Dispose(); Conin = null; } Conin = new ConsoleInput(); if (CT != null) { CT.Dispose(); CT = null; } CT = new ConsoleTracker(); string XmlMsg = "<Terminal-Connected Reconnected=\"true\" full-user-name=\"" + FullUserName + "\" />"; byte[] RawMsg = Encoding.Unicode.GetBytes(XmlMsg); SendMessage(NetworkStream, RawMsg); } else { ConnectedProcess = new SlaveProcess(); try { #if DEBUG && ShowCmdWindow ConnectedProcess.Start(Domain, UserName, Password, IsLocalProvider); #else ConnectedProcess.Start(Domain, UserName, Password, false); #endif Processes.Add(FullUserName, ConnectedProcess); Thread.Sleep(2500); // TODO: WaitForInputIdle() would be preferred and more robust. //ConnectedProcess.CommandPrompt.WaitForInputIdle(15000); if (!ConnectedProcess.CommandPrompt.IsStillRunning) { throw new Exception("Newly launched terminal appears to have exited immediately or never actually launched."); } if (!ConsoleApi.AttachConsole((uint)ConnectedProcess.CommandPrompt.ProcessId)) { this.Log.WriteLine("AttachConsole() failed.", Severity.Debug); throw new Win32Exception(Marshal.GetLastWin32Error()); } this.Log.WriteLine("Console attached.", Severity.Debug); if (Conin != null) { Conin.Dispose(); Conin = null; } Conin = new ConsoleInput(); if (CT != null) { CT.Dispose(); CT = null; } CT = new ConsoleTracker(); this.Log.WriteLine("Console established without errors.", Severity.Debug); } finally { if (ConnectedProcess.CommandPrompt.DebugLog.Length > 0) { this.Log.WriteLine(ConnectedProcess.CommandPrompt.DebugLog.ToString(), Severity.Debug); string XmlMsg = "<Debug>" + ConnectedProcess.CommandPrompt.DebugLog.ToString() + "</Debug>"; byte[] RawMsg = Encoding.Unicode.GetBytes(XmlMsg); SendMessage(NetworkStream, RawMsg); ConnectedProcess.CommandPrompt.DebugLog.Clear(); } } { string XmlMsg = "<Terminal-Connected Reconnected=\"false\" full-user-name=\"" + FullUserName + "\" />"; byte[] RawMsg = Encoding.Unicode.GetBytes(XmlMsg); SendMessage(NetworkStream, RawMsg); } } } } catch (Exception ex) { string EncodedText = System.Convert.ToBase64String(Encoding.Unicode.GetBytes(ex.ToString() + "\n")); string XmlMsg = "<Error>" + EncodedText + "</Error>"; byte[] RawMsg = Encoding.Unicode.GetBytes(XmlMsg); SendMessage(NetworkStream, RawMsg); } } if (xMsg.Name.LocalName == "Console-Input") { // TODO: This xml format isn't very efficient. Could at least string it all into one array of INPUT_RECORDs. List <ConsoleApi.KEY_EVENT_RECORD> Keys = new List <ConsoleApi.KEY_EVENT_RECORD>(); foreach (var Key in xMsg.Elements()) { if (Key.Name != "Key") { throw new FormatException("Expected <Key> objects in <Console-Input>"); } ConsoleApi.KEY_EVENT_RECORD KER = new ConsoleApi.KEY_EVENT_RECORD(); KER.bKeyDown = Boolean.Parse(Key.Attribute("down").Value); KER.dwControlKeyState = (ConsoleApi.ControlKeyState)UInt32.Parse(Key.Attribute("ctrl").Value); KER.UnicodeChar = (char)UInt32.Parse(Key.Attribute("char").Value); KER.wRepeatCount = UInt16.Parse(Key.Attribute("repeat").Value); KER.wVirtualKeyCode = UInt16.Parse(Key.Attribute("key").Value); KER.wVirtualScanCode = UInt16.Parse(Key.Attribute("scan").Value); Keys.Add(KER); } //byte[] Raw = System.Convert.FromBase64String(xMsg.Value); //string Msg = Encoding.Unicode.GetString(Raw); lock (ProcessLock) { if (ConnectedProcess != null) { StringBuilder Text = new StringBuilder(); foreach (var Key in Keys) { Text.Append(Key.UnicodeChar); } //Debug.WriteLine("Writing to console as input: '" + Text + "'"); ConsoleApi.INPUT_RECORD[] irs = new ConsoleApi.INPUT_RECORD[1]; ConsoleApi.INPUT_RECORD ir = new ConsoleApi.INPUT_RECORD(); ir.EventType = (ushort)ConsoleApi.EventTypes.KEY_EVENT; foreach (var Key in Keys) { ir.KeyEvent = Key; irs[0] = ir; Conin.Write(irs); } //Thread.Sleep(50); //CT.DebugWholeConsole(); } } } if (xMsg.Name.LocalName == "Reload-Console") { lock (ProcessLock) CT.PendingReload = true; } } catch (Exception ex) { Debug.Write("Exception detected in SlaveCore.OnMessageReceived(): " + ex.ToString()); throw ex; } }