static bool Prefix(LoadableXmlAsset xmlAsset, ModContentPack mod) { if (xmlAsset.xmlDoc == null) { return(false); } XmlNodeList childNodes = xmlAsset.xmlDoc.DocumentElement.ChildNodes; foreach (XmlNode child in childNodes) { if (child.NodeType == XmlNodeType.Element) { XmlInheritance.TryRegister(child, mod); } } return(false); }
private static IEnumerable <UpdateFeatureDef> ResolveUpdateFeatureDefsFromNodes(IEnumerable <DefXMLNode> nodes) { // The following replicates most of the vanilla Def loading mechanism, albeit without patches. // Patch metadata has already been cleared, and parsing it again would add too much overhead. // Def resolution can't be offloaded to a worker thread, since XmlInheritance is not thread safe. var defNodes = nodes.ToArray(); // register for inheritance XmlInheritance.Clear(); foreach (var(modContent, node, _) in defNodes) { if (node != null && node.NodeType == XmlNodeType.Element) { XmlInheritance.TryRegister(node, modContent); } } XmlInheritance.Resolve(); // resolve defs from nodes var resolvedDefs = new List <UpdateFeatureDef>(); foreach (var(pack, node, asset) in defNodes) { try { var def = DirectXmlLoader.DefFromNode(node, asset) as UpdateFeatureDef; if (def != null) { def.modContentPack = pack; def.ResolveReferences(); resolvedDefs.Add(def); } } catch (Exception e) { HugsLibController.Logger.Error( $"Failed to parse UpdateFeatureDef from mod {pack.PackageIdPlayerFacing}:\n" + $"{GetExceptionChainMessage(e)}\n" + $"Context: {node?.OuterXml.ToStringSafe()}\n" + $"File: {asset?.FullFilePath.ToStringSafe()}\n" + $"Exception: {e}"); } } XmlInheritance.Clear(); return(resolvedDefs); }
static bool Prefix(XmlDocument xmlDoc, Dictionary <XmlNode, LoadableXmlAsset> assetlookup) { XmlNodeList childNodes = xmlDoc.DocumentElement.ChildNodes; foreach (XmlNode n in childNodes) { if (n.NodeType == XmlNodeType.Element) { LoadableXmlAsset loadableXmlAsset = assetlookup.TryGetValue(n, null); XmlInheritance.TryRegister(n, (loadableXmlAsset == null) ? null : loadableXmlAsset.mod); } } XmlInheritance.Resolve(); DefPackage defPackage = new DefPackage("Unknown", string.Empty); ModContentPack modContentPack = LoadedModManager.RunningMods.FirstOrFallback <ModContentPack>(); modContentPack.AddDefPackage(defPackage); IEnumerator enumerator = xmlDoc.DocumentElement.ChildNodes.GetEnumerator(); try { while (enumerator.MoveNext()) { XmlNode xmlNode = (XmlNode)enumerator.Current; LoadableXmlAsset loadableXmlAsset2 = assetlookup.TryGetValue(xmlNode, null); DefPackage defPackage2 = (loadableXmlAsset2 == null) ? defPackage : loadableXmlAsset2.defPackage; Def def = DirectXmlLoader.DefFromNode(xmlNode, loadableXmlAsset2); if (def != null) { def.modContentPack = ((loadableXmlAsset2 == null) ? modContentPack : loadableXmlAsset2.mod); defPackage2.AddDef(def); } } } finally { IDisposable disposable; if ((disposable = (enumerator as IDisposable)) != null) { disposable.Dispose(); } } return(false); }
private static IEnumerable <UpdateFeatureDef> LoadAndParseNewsFeatureDefs() { XmlInheritance.Clear(); // As we're moving the updates out of /Defs and into /News, we can no longer rely on the DefDatabase to magically // load all the UpdateFeatureDefs. Instead, we'll have to manually point the reader to the relevant folders. // Overall, we'll stick as much as we can to the vanilla def loading experience, albeit without patches. // Patch metadata has already been cleared, and parsing it again would add too much overhead. // First, gather all XML nodes that represent an UpdateFeatureDef, and remember where they came from // We can't parse them info defs on the spot, because there is inheritance to consider. var newsItemNodes = new List <(ModContentPack pack, XmlNode node, LoadableXmlAsset asset)>(); foreach (var modContentPack in LoadedModManager.RunningMods) { try { var modNewsXmlAssets = DirectXmlLoader.XmlAssetsInModFolder(modContentPack, UpdateFeatureDefFolder); foreach (var xmlAsset in modNewsXmlAssets) { var rootElement = xmlAsset.xmlDoc?.DocumentElement; if (rootElement != null) { foreach (var childNode in rootElement.ChildNodes.OfType <XmlNode>()) { newsItemNodes.Add((modContentPack, childNode, xmlAsset)); } } } } catch (Exception e) { HugsLibController.Logger.Error("Failed to load UpdateFeatureDefs for mod " + $"{modContentPack.PackageIdPlayerFacing}: {e}"); throw; } } // deal with inheritance foreach (var(modContent, node, _) in newsItemNodes) { if (node != null && node.NodeType == XmlNodeType.Element) { XmlInheritance.TryRegister(node, modContent); } } XmlInheritance.Resolve(); var parsedFeatureDefs = new List <UpdateFeatureDef>(); foreach (var(pack, node, asset) in newsItemNodes) { // parse defs try { var def = DirectXmlLoader.DefFromNode(node, asset) as UpdateFeatureDef; if (def != null) { def.modContentPack = pack; def.ResolveReferences(); parsedFeatureDefs.Add(def); } } catch (Exception e) { HugsLibController.Logger.Error($"Failed to parse UpdateFeatureDef from mod {pack.PackageIdPlayerFacing}:\n" + $"{GetExceptionChainMessage(e)}\n" + $"Context: {node?.OuterXml.ToStringSafe()}\n" + $"File: {asset?.FullFilePath.ToStringSafe()}\n" + $"Exception: {e}"); } } XmlInheritance.Clear(); return(parsedFeatureDefs); }