public static UnityParser DeployCollect(UnityParser parser, object[] animatorEditors, object[] singleAssets) { HashSet <Component> collection = new HashSet <Component>(); if (animatorEditors != null) { AnimatorEditor[] editors = Utility.Convert <AnimatorEditor>(animatorEditors); foreach (AnimatorEditor animEditor in editors) { Collect(animEditor, collection); } } if (singleAssets != null) { long[] singles = Utility.Convert <long>(singleAssets); foreach (long pathID in singles) { Component asset = parser.Cabinet.LoadComponent(pathID); collection.Add(asset); } } collection.Remove(null); UnityParser p = new UnityParser(parser); p.Cabinet.Components.AddRange(collection); p.Cabinet.Components.Sort ( delegate(Component a, Component b) { return(a.pathID.CompareTo(b.pathID)); } ); p.InitTextures(); if (parser.Cabinet.Bundle != null) { parser.Cabinet.Bundle.Clone(p.Cabinet); } return(p); }
public static bool ApplyMod(UnityParser parser, UnityParser modParser, bool saveOriginals) { UnityParser originals = new UnityParser(parser); long firstNewPathID = -1; for (int i = 0; i < modParser.Cabinet.Components.Count; i++) { long pathID = modParser.Cabinet.Components[i].pathID; Component comp; if (parser.Cabinet.findComponent.TryGetValue(pathID, out comp)) { originals.Cabinet.Components.Add(comp); originals.Cabinet.findComponent.Add(comp.pathID, comp); } else { if (firstNewPathID < 0) { firstNewPathID = pathID; } originals.Cabinet.Components.Add(modParser.Cabinet.Components[i]); originals.Cabinet.findComponent.Add(pathID, modParser.Cabinet.Components[i]); } } Match m = Regex.Match(modParser.FilePath, @"(--*\d+)\.", RegexOptions.CultureInvariant); int idx = m.Success ? m.Groups[1].Index : modParser.FilePath.Length; string originalsName = modParser.FilePath.Substring(0, idx) + "-org-" + firstNewPathID + Path.GetExtension(parser.FilePath); if (File.Exists(originalsName)) { Report.ReportLog(Path.GetFileName(modParser.FilePath) + " has already been applied."); return(false); } if (saveOriginals) { originals.InitTextures(); originals.WriteArchive(originalsName, false, null, false, true, true); } bool success = true; Stream stream = modParser.Uncompressed == null?File.OpenRead(modParser.FilePath) : modParser.Uncompressed; try { m = Regex.Match(modParser.FilePath, @"-(-*\d+)\.", RegexOptions.CultureInvariant); if (!m.Success || !long.TryParse(m.Groups[1].Value, out firstNewPathID)) { Report.ReportLog("Warning! Mod filename \"" + Path.GetFileName(modParser.FilePath) + "\" is malformed or lies in a folder with a confusing name."); firstNewPathID = -1; } List <KeyValuePair <string, AssetInfo> > srcContainer = null; for (int i = 0; i < modParser.Cabinet.Components.Count; i++) { Component src = modParser.Cabinet.Components[i]; NotLoaded asset = src as NotLoaded; if (asset != null) { src = modParser.Cabinet.LoadComponent(stream, i, asset); } if (firstNewPathID == -1 || src.pathID < firstNewPathID) { Component dest = parser.Cabinet.findComponent[src.pathID]; if (dest.classID() == src.classID()) { if (src.classID() == UnityClassID.AssetBundle) { srcContainer = ((AssetBundle)src).m_Container; } else { parser.Cabinet.ReplaceSubfile(dest, src); } if (parser.Cabinet.Bundle != null) { switch (src.classID()) { case UnityClassID.Animator: parser.Cabinet.Bundle.RegisterForUpdate(((Animator)src).m_GameObject.asset); break; case UnityClassID.MeshRenderer: case UnityClassID.SkinnedMeshRenderer: case UnityClassID.Material: case UnityClassID.Shader: case UnityClassID.Texture2D: parser.Cabinet.Bundle.RegisterForUpdate(src); break; } } } else { Report.ReportLog("Unexpected asset in " + Path.GetFileName(parser.FilePath) + " with PathID=" + src.pathID + " was not replaced."); success = false; } } else { parser.Cabinet.ReplaceSubfile(-1, src, null); if (parser.Cabinet.Bundle != null) { switch (src.classID()) { case UnityClassID.TextAsset: case UnityClassID.Material: case UnityClassID.MonoBehaviour: case UnityClassID.Shader: case UnityClassID.Texture2D: parser.Cabinet.Bundle.AddComponent(src); break; } } } } if (parser.Cabinet.Bundle != null && modParser.Cabinet.Bundle != null) { for (int j = 0; j < srcContainer.Count;) { var firstEntry = srcContainer[j++]; Component firstAsset = ((NotLoaded)firstEntry.Value.asset.asset).replacement; if (firstAsset == null) { continue; } if (parser.Cabinet.Bundle.FindComponent(firstEntry.Key, firstEntry.Value.asset.asset.classID()) == null) { List <Component> entries = new List <Component>(); entries.Add(firstAsset); while (j < srcContainer.Count && srcContainer[j].Key == firstEntry.Key && srcContainer[j].Value.preloadIndex == firstEntry.Value.preloadIndex) { Component asset = ((NotLoaded)srcContainer[j++].Value.asset.asset).replacement; entries.Add(asset); } parser.Cabinet.Bundle.AddComponents(firstEntry.Key, entries); } else { parser.Cabinet.Bundle.RegisterForUpdate(firstAsset); } } Unity3dEditor editor = new Unity3dEditor(modParser); foreach (Animator vAnim in editor.VirtualAnimators) { Component gameObj = parser.Cabinet.findComponent[vAnim.m_GameObject.asset.pathID]; parser.Cabinet.Bundle.AddComponent(gameObj); } } } finally { if (stream != parser.Uncompressed) { stream.Close(); stream.Dispose(); } } return(success); }