diff --git a/src/Branch/PackageObjectLegacyVersion.cs b/src/Branch/PackageObjectLegacyVersion.cs index e5fe178d..b685566f 100644 --- a/src/Branch/PackageObjectLegacyVersion.cs +++ b/src/Branch/PackageObjectLegacyVersion.cs @@ -5,7 +5,7 @@ namespace UELib.Branch public enum PackageObjectLegacyVersion { Undefined = 0, - + /// /// This is one particular update with A LOT of general package changes. /// @@ -73,9 +73,14 @@ public enum PackageObjectLegacyVersion // FIXME: Version EnumTagNameAddedToBytePropertyTag = UE3, + ObjectFlagsSizeChangedToULong = 195, + ArchetypeAddedToExports = 220, + // 227 according to the GoW client FixedVerticesToArrayFromPoly = 227, + SerialSizeConditionRemoved = 249, + // Thanks to @https://www.gildor.org/ for reverse-engineering the lazy-loader version changes. LazyLoaderFlagsAddedToLazyArray = 251, StorageSizeAddedToLazyArray = 254, @@ -86,7 +91,7 @@ public enum PackageObjectLegacyVersion // -- albeit the exact nature is not clear // -- whether if this indicates the addition of such an ObjectFlag or just the conditional test. ClassDefaultCheckAddedToTemplateName = 267, - + ComponentGuidDeprecated = 273, /// diff --git a/src/Core/Classes/UObject.cs b/src/Core/Classes/UObject.cs index cbf2ac11..8625943f 100644 --- a/src/Core/Classes/UObject.cs +++ b/src/Core/Classes/UObject.cs @@ -57,6 +57,11 @@ public partial class UObject : object, IAcceptable, IContainsTable, IBinaryData, [CanBeNull] public UObject Outer => Package.GetIndexObject(Table.OuterIndex); + [CanBeNull] + public UObject Archetype => ExportTable != null + ? Package.GetIndexObject(ExportTable.ArchetypeIndex) + : null; + /// /// The object's index represented as a table index. /// diff --git a/src/Core/Classes/UObjectDecompiler.cs b/src/Core/Classes/UObjectDecompiler.cs index e4416cb2..430dd559 100644 --- a/src/Core/Classes/UObjectDecompiler.cs +++ b/src/Core/Classes/UObjectDecompiler.cs @@ -14,14 +14,28 @@ public virtual string Decompile() BeginDeserializing(); } + string output = $"// Reference: {GetReferencePath()}\r\n"; + if (ImportTable != null) { - return $"// Cannot decompile import {Name}"; + return output + $"\r\n{UDecompilingState.Tabs}// Cannot decompile an imported object"; + } + + output += UDecompilingState.Tabs; + output += $"begin object name={Name}"; + // If null then we have a new sub-object (not an override) + if (Archetype == null) + { + Debug.Assert(Class != null); + output += $" class={Class.GetReferencePath()}"; + } + else + { + // Commented out, too noisy but useful. + //output += $" /*archetype={Archetype.GetReferencePath()}*/"; } + output += "\r\n"; - Debug.Assert(Class != null); - string output = $"begin object name={Name} class={Class.Name}" + - "\r\n"; UDecompilingState.AddTabs(1); try { @@ -32,9 +46,8 @@ public virtual string Decompile() UDecompilingState.RemoveTabs(1); } - return $"{output}{UDecompilingState.Tabs}end object" + - $"\r\n{UDecompilingState.Tabs}" + - $"// Reference: {Class.Name}'{GetOuterGroup()}'"; + return $"{output}" + + $"{UDecompilingState.Tabs}end object"; } public virtual string FormatHeader() diff --git a/src/Core/Tables/UExportTableItem.cs b/src/Core/Tables/UExportTableItem.cs index 7cd80bd0..faea694e 100644 --- a/src/Core/Tables/UExportTableItem.cs +++ b/src/Core/Tables/UExportTableItem.cs @@ -12,11 +12,9 @@ namespace UELib /// public sealed class UExportTableItem : UObjectTableItem, IUnrealSerializableClass { - private const int VArchetype = 220; + [Obsolete] public const int VObjectFlagsToULONG = 195; - private const int VSerialSizeConditionless = 249; - #region Serialized Members private int _ClassIndex; @@ -121,15 +119,15 @@ public void Serialize(IUnrealStream stream) stream.Write(_SuperIndex); stream.Write(OuterIndex); stream.Write(ObjectName); - if (stream.Version >= VArchetype) + if (stream.Version >= (uint)PackageObjectLegacyVersion.ArchetypeAddedToExports) { _ArchetypeIndex = stream.ReadInt32(); } - stream.Write(stream.Version >= VObjectFlagsToULONG + stream.Write(stream.Version >= (uint)PackageObjectLegacyVersion.ObjectFlagsSizeChangedToULong ? ObjectFlags : (uint)ObjectFlags); stream.WriteIndex(SerialSize); // Assumes SerialSize has been updated to @Object's buffer size. - if (SerialSize > 0 || stream.Version >= VSerialSizeConditionless) + if (SerialSize > 0 || stream.Version >= (uint)PackageObjectLegacyVersion.SerialSizeConditionRemoved) { // SerialOffset has to be set and written after this object has been serialized. stream.WriteIndex(SerialOffset); // Assumes the same as @SerialSize comment. @@ -155,7 +153,7 @@ public void Deserialize(IUnrealStream stream) } #endif ObjectName = stream.ReadNameReference(); - if (stream.Version >= VArchetype) + if (stream.Version >= (uint)PackageObjectLegacyVersion.ArchetypeAddedToExports) { _ArchetypeIndex = stream.ReadInt32(); } @@ -176,14 +174,14 @@ public void Deserialize(IUnrealStream stream) } #endif ObjectFlags = stream.ReadUInt32(); - if (stream.Version >= VObjectFlagsToULONG) + if (stream.Version >= (uint)PackageObjectLegacyVersion.ObjectFlagsSizeChangedToULong) { ObjectFlags = (ObjectFlags << 32) | stream.ReadUInt32(); } streamSerialSize: SerialSize = stream.ReadIndex(); - if (SerialSize > 0 || stream.Version >= VSerialSizeConditionless) + if (SerialSize > 0 || stream.Version >= (uint)PackageObjectLegacyVersion.SerialSizeConditionRemoved) { #if ROCKETLEAGUE // FIXME: Can't change SerialOffset to 64bit due UE Explorer.