/// <summary> /// Raw updates a vessel in the dictionary and takes care of the locking in case we received another vessel message type /// </summary> public static void RawConfigNodeInsertOrUpdate(Guid vesselId, string vesselDataInConfigNodeFormat) { Task.Run(() => { lock (Semaphore.GetOrAdd(vesselId, new object())) { var vesselAsXml = ConfigNodeXmlParser.ConvertToXml(vesselDataInConfigNodeFormat); if (GeneralSettings.SettingsStore.ModControl) { var vesselParts = GetPartNames(vesselAsXml); if (vesselParts != null) { var bannedParts = vesselParts.Except(ModFileSystem.ModControl.AllowedParts); if (bannedParts.Any()) { LunaLog.Warning($"Received a vessel with BANNED parts! {vesselId}"); return; } } } VesselStoreSystem.CurrentVesselsInXmlFormat.AddOrUpdate(vesselId, vesselAsXml, (key, existingVal) => vesselAsXml); } }); }
/// <summary> /// Patches the scenario file with reputation data /// </summary> private static string UpdateScenarioWithTechnologyData(string scenarioData, TechNodeInfo techNode) { var document = new XmlDocument(); document.LoadXml(scenarioData); var configNodeData = Encoding.UTF8.GetString(techNode.Data, 0, techNode.NumBytes); var newNodeDoc = new XmlDocument(); newNodeDoc.LoadXml(ConfigNodeXmlParser.ConvertToXml(configNodeData)); var parentNode = document.SelectSingleNode($"/{ConfigNodeXmlParser.StartElement}"); if (parentNode != null) { var newTechXmlNode = newNodeDoc.SelectSingleNode($"/{ConfigNodeXmlParser.StartElement}/{ConfigNodeXmlParser.ParentNode}[@name='Tech']"); if (newTechXmlNode != null) { var importNode = document.ImportNode(newTechXmlNode, true); parentNode.AppendChild(importNode); } } return(document.ToIndentedString()); }
private static XmlNode DeserializeAndImportNode(byte[] data, int numBytes, XmlDocument docToImportTo) { var auxDoc = new XmlDocument(); auxDoc.LoadXml(ConfigNodeXmlParser.ConvertToXml(Encoding.UTF8.GetString(data, 0, numBytes))); var newXmlNode = auxDoc.SelectSingleNode($"/{ConfigNodeXmlParser.StartElement}"); return(newXmlNode == null ? null : docToImportTo.ImportNode(newXmlNode, true)); }
/// <summary> /// Raw updates a scenario in the dictionary /// </summary> public static void RawConfigNodeInsertOrUpdate(string scenarioModule, string scenarioDataInConfigNodeFormat) { Task.Run(() => { lock (Semaphore.GetOrAdd(scenarioModule, new object())) { var scenarioAsXml = ConfigNodeXmlParser.ConvertToXml(scenarioDataInConfigNodeFormat); ScenarioStoreSystem.CurrentScenariosInXmlFormat.AddOrUpdate(scenarioModule, scenarioAsXml, (key, existingVal) => scenarioAsXml); } }); }
/// <summary> /// Raw updates a vessel in the dictionary and takes care of the locking in case we received another vessel message type /// </summary> public static void RawConfigNodeInsertOrUpdate(Guid vesselId, string vesselDataInConfigNodeFormat) { Task.Run(() => { lock (Semaphore.GetOrAdd(vesselId, new object())) { var vesselAsXml = ConfigNodeXmlParser.ConvertToXml(vesselDataInConfigNodeFormat); VesselStoreSystem.CurrentVesselsInXmlFormat.AddOrUpdate(vesselId, vesselAsXml, (key, existingVal) => vesselAsXml); } }); }
private static void SwitchToXmlAndBack(string filePath) { if (!File.Exists(filePath)) { return; } var configNode = File.ReadAllText(filePath); var xml = ConfigNodeXmlParser.ConvertToXml(configNode); var backToConfigNode = ConfigNodeXmlParser.ConvertToConfigNode(xml); Assert.IsTrue(configNode.Equals(backToConfigNode), $"Error serializing config node. File: {Path.GetFileName(filePath)}"); }
/// <summary> /// Patches the scenario file with reputation data /// </summary> private static string UpdateScenarioWithTechnologyData(string scenarioData, TechNodeInfo techNode) { var document = new XmlDocument(); document.LoadXml(scenarioData); var configNodeData = Encoding.UTF8.GetString(techNode.Data, 0, techNode.NumBytes); var newNodeDoc = new XmlDocument(); newNodeDoc.LoadXml(ConfigNodeXmlParser.ConvertToXml(configNodeData)); var parentNode = document.SelectSingleNode($"/{ConfigNodeXmlParser.StartElement}"); if (parentNode != null) { var newTechXmlNode = newNodeDoc.SelectSingleNode($"/{ConfigNodeXmlParser.StartElement}/{ConfigNodeXmlParser.ParentNode}[@name='Tech']"); if (newTechXmlNode != null) { var existingNode = parentNode.SelectSingleNode($"/{ConfigNodeXmlParser.StartElement}/{ConfigNodeXmlParser.ParentNode}[@name='Tech']" + $@"/{ConfigNodeXmlParser.ValueNode}[@name='id' and text()=""{techNode.Id}""]" + $"/parent::{ConfigNodeXmlParser.ParentNode}[@name='Tech']"); if (existingNode != null) { var parts = newTechXmlNode.SelectNodes($"{ConfigNodeXmlParser.ValueNode}[@name='part']"); if (parts != null) { foreach (var part in parts.Cast <XmlNode>()) { var existingPart = existingNode.SelectSingleNode($@"{ConfigNodeXmlParser.ValueNode}[@name='part' and text()=""{part.InnerText}""]"); if (existingPart == null) { var importNode = document.ImportNode(part, true); existingNode.AppendChild(importNode); } } } } else { var importNode = document.ImportNode(newTechXmlNode, true); parentNode.AppendChild(importNode); } } } return(document.ToIndentedString()); }
public static void GenerateUniverse(string saveName) { var universeFolder = CommonUtil.CombinePaths(MainSystem.KspPath, "Universe"); if (Directory.Exists(universeFolder)) { Directory.Delete(universeFolder, true); } var saveFolder = CommonUtil.CombinePaths(SavesFolder, saveName); if (!Directory.Exists(saveFolder)) { LunaLog.Log($"[LMP]: Failed to generate a LMP universe for '{saveName}', Save directory doesn't exist"); LunaScreenMsg.PostScreenMessage($"Failed to generate a LMP universe for '{saveName}', Save directory doesn't exist", 5f, ScreenMessageStyle.UPPER_CENTER); return; } var persistentFile = CommonUtil.CombinePaths(saveFolder, "persistent.sfs"); if (!File.Exists(persistentFile)) { LunaLog.Log($"[LMP]: Failed to generate a LMP universe for '{saveName}', persistent.sfs doesn't exist"); LunaScreenMsg.PostScreenMessage($"Failed to generate a LMP universe for '{saveName}', persistent.sfs doesn't exist", 5f, ScreenMessageStyle.UPPER_CENTER); return; } Directory.CreateDirectory(universeFolder); var vesselFolder = CommonUtil.CombinePaths(universeFolder, "Vessels"); Directory.CreateDirectory(vesselFolder); var scenarioFolder = CommonUtil.CombinePaths(universeFolder, "Scenarios"); Directory.CreateDirectory(scenarioFolder); var kerbalFolder = CommonUtil.CombinePaths(universeFolder, "Kerbals"); Directory.CreateDirectory(kerbalFolder); //Load game data var persistentData = ConfigNode.Load(persistentFile); if (persistentData == null) { LunaLog.Log($"[LMP]: Failed to generate a LMP universe for '{saveName}', failed to load persistent data"); LunaScreenMsg.PostScreenMessage($"Failed to generate a LMP universe for '{saveName}', failed to load persistent data", 5f, ScreenMessageStyle.UPPER_CENTER); return; } var gameData = persistentData.GetNode("GAME"); if (gameData == null) { LunaLog.Log($"[LMP]: Failed to generate a LMP universe for '{saveName}', failed to load game data"); LunaScreenMsg.PostScreenMessage($"Failed to generate a LMP universe for '{saveName}', failed to load game data", 5f, ScreenMessageStyle.UPPER_CENTER); return; } //Save vessels var flightState = gameData.GetNode("FLIGHTSTATE"); if (flightState == null) { LunaLog.Log($"[LMP]: Failed to generate a LMP universe for '{saveName}', failed to load flight state data"); LunaScreenMsg.PostScreenMessage($"Failed to generate a LMP universe for '{saveName}', failed to load flight state data", 5f, ScreenMessageStyle.UPPER_CENTER); return; } var vesselNodes = flightState.GetNodes("VESSEL"); if (vesselNodes != null) { foreach (var cn in vesselNodes) { var vesselId = Common.ConvertConfigStringToGuidString(cn.GetValue("pid")); LunaLog.Log($"[LMP]: Saving vessel {vesselId}, Name: {cn.GetValue("name")}"); var xmlData = ConfigNodeXmlParser.ConvertToXml(Encoding.UTF8.GetString(ConfigNodeSerializer.Serialize(cn))); File.WriteAllText(CommonUtil.CombinePaths(vesselFolder, $"{vesselId}.xml"), xmlData); } } //Save scenario data var scenarioNodes = gameData.GetNodes("SCENARIO"); if (scenarioNodes != null) { foreach (var cn in scenarioNodes) { var scenarioName = cn.GetValue("name"); if (string.IsNullOrEmpty(scenarioName)) { continue; } LunaLog.Log($"[LMP]: Saving scenario: {scenarioName}"); var xmlData = ConfigNodeXmlParser.ConvertToXml(Encoding.UTF8.GetString(ConfigNodeSerializer.Serialize(cn))); File.WriteAllText(CommonUtil.CombinePaths(scenarioFolder, $"{scenarioName}.xml"), xmlData); } } //Save kerbal data var kerbalNodes = gameData.GetNode("ROSTER").GetNodes("KERBAL"); if (kerbalNodes != null) { foreach (var cn in kerbalNodes) { var kerbalName = cn.GetValue("name"); LunaLog.Log($"[LMP]: Saving kerbal: {kerbalName}"); cn.Save(CommonUtil.CombinePaths(kerbalFolder, $"{kerbalName}.txt")); } } LunaLog.Log($"[LMP]: Generated KSP_folder/Universe from {saveName}"); LunaScreenMsg.PostScreenMessage($"Generated KSP_folder/Universe from {saveName}", 5f, ScreenMessageStyle.UPPER_CENTER); }