diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1893b893..e68f3a0b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,13 +1,62 @@
+# [1.4.0](https://github.com/EliotVU/Unreal-Library/releases/tag/1.4.0)
+
+Notable changes that affect UnrealScript output:
+
+* Improved decompilation output of string and decimal literals.
+* 5141285c Improved decompilation of delegate assignments (in a T3D context)
+* 6d889c87 Added decompilation of optional parameter assignments e.g. `function MyFunction(option bool A = true);`.
+* e55cfce0 Fixed decompilation with arrays of bools
+
+Notable changes that affect support of games:
+
+General deserialization fixes that affect all of UE1, UE2, and UE3 builds, as well as more specifically:
+
+* 13460cca Support for Battleborn
+* 4aff61fa Support for Duke Nukem Forever (2011)
+* bce38c4f Support for Tom Clancy's Splinter Cell
+* 809edaad Support for Harry Potter (UE1) data class {USound}
+* b3e1489d Support for Devastation (UE2, 2003)
+* 4780771a Support for Clive Barker's Undying (UE1) data classes {UClass, UTextBuffer, UPalette, USound}
+* 01772a83 Support for Lemony Snicket's A Series of Unfortunate Events data class {UProperty}
+* c4c1978d Fixed support for Dungeon Defenders 2 (versions 687-688/111-117)
+* 86538e5d Fixed support for Vanguard: Saga of Heroes
+* eb82dba5 Fixed support for Rocket League (version 868/003)
+* 6ed6ed74 Fixed support for Hawken (version 860/002)
+* b4b79773 Fixed ResizeStringToken for UE1 builds
+* 3653f8e1 Fixed ReturnToken and BeginFunctionToken for UE1 builds (with a package version of 61)
+* 9a659549 Fixed deserialization of Heritages for UE1 builds (with a package version older than 68)
+
+Notable changes that affect various data structures:
+
+* Improved detection of UComponent objects and class types.
+* ea3c1aa5 Support for UE4 .uasset packages (earlier builds only)
+* e37b8a12 Support for class {UTexture}, f1b74af1 {UPrimitive, UTexture2D and its derivatives} (UE3)
+* aa5ca861 Support for classes: {UFont, UMultiFont}
+* ab290b6c Support for types {UPolys, FPoly}
+* 02bea77b Support for types {FUntypedBulkData} (UE3) and {TLazyArray} (UE1, UE2)
+* 94e02927 Support for structures: {FPointRegion, FCoords, FPlane, FScale, FSphere, FRotator, FVector, FGuid, FBox, FLinearColor, FMatrix, FQuat, FRange, FRangeVector, FVector2D, FVector4}
+* 09c76240 Support for class {USoundGroup} (UE2.5)
+
+**Support for the data types listed above have only been implemented for the standard structure that Epic Games uses**
+
# [1.3.1](https://github.com/EliotVU/Unreal-Library/releases/tag/1.3.1)
+Notable changes back-ported from 'develop' version 1.4.0:
+
+* Added support for various data structures: FColor; and data class UBitmapMaterial (UE2)
+
* Improved support for Batman series
* Improved support for Transformers series
-* Fixed the decompilation of UnrealScript casting byte-codes that were swapped i.e. `InterfaceToBool` with `InterfaceToObject`.
-* Fixed a missing package version check in UStateFrame (this affected some object classes that are usually found in map package files).
-* Added the capability to override the interpreted version for packages of builds that are auto-detected.
+* e8308284 Fixed decompilation of primitive castings for UE1 builds
+* ffaca763 Fixed decompilation of interface castings i.e. `InterfaceToBool` with `InterfaceToObject` (UE3).
+* 3317e06a Fixed a missing package version check in UStateFrame (this affected some object classes that are usually found in map package files).
+
+* 42783b16 Added the capability to override the interpreted version for packages of builds that are auto-detected.
# [1.3.0](https://github.com/EliotVU/Unreal-Library/releases/tag/1.3.0.0)
+Notable changes:
+
* Support for Vengeance which includes BioShock 1 & 2, Swat4, and Tribes: Vengeance
* Support for Batman series (to the release branch, incomplete)
* Support for Thief: Deadly Shadows and Deus Ex: Invisible War
diff --git a/src/BinaryMetaData.cs b/src/BinaryMetaData.cs
index 4ce39a94..afec15e6 100644
--- a/src/BinaryMetaData.cs
+++ b/src/BinaryMetaData.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Diagnostics;
using UELib.Annotations;
@@ -37,6 +38,14 @@ public struct BinaryField : IUnrealDecompilable
///
public long Size { get; set; }
+ [Obsolete("Use Field")]
+ public string Name => Field;
+
+ [Obsolete("Use Value")]
+ public object Tag => Value;
+
+ [Obsolete("Use Offset")] public int Position => (int)Offset;
+
///
/// Decompiles and returns the output of @Tag.
///
@@ -57,20 +66,20 @@ public string Decompile()
///
/// Adds a new field to the @Fields stack.
///
- /// Name of the field
- /// Value of the field
- /// Position in bytes where the field is read from
+ /// Name of the field
+ /// Value of the field
+ /// Position in bytes where the field is read from
/// Size in bytes of the field
- public void AddField(string name, object tag, long position, long size)
+ public void AddField(string field, object value, long offset, long size)
{
- Debug.Assert(size > 0, $"Size of field {name} at {position} cannot be less than 1");
+ //Debug.Assert(size > 0, $"Size of field {field} at {offset} cannot be less than 1");
Fields.Push
(
new BinaryField
{
- Field = name,
- Value = tag,
- Offset = position,
+ Field = field,
+ Value = value,
+ Offset = offset,
Size = size
}
);
diff --git a/src/Branch/DefaultEngineBranch.cs b/src/Branch/DefaultEngineBranch.cs
index 13ca5b28..3054c87b 100644
--- a/src/Branch/DefaultEngineBranch.cs
+++ b/src/Branch/DefaultEngineBranch.cs
@@ -128,34 +128,34 @@ public DefaultEngineBranch(BuildGeneration generation) : base(generation)
public override void Setup(UnrealPackage linker)
{
SetupEnumPackageFlags(linker);
- EnumFlagsMap.Add(typeof(PackageFlags), PackageFlags);
+ EnumFlagsMap.Add(typeof(PackageFlag), PackageFlags);
}
protected virtual void SetupEnumPackageFlags(UnrealPackage linker)
{
- PackageFlags[(int)Flags.PackageFlags.AllowDownload] = (uint)PackageFlagsDefault.AllowDownload;
- PackageFlags[(int)Flags.PackageFlags.ClientOptional] = (uint)PackageFlagsDefault.ClientOptional;
- PackageFlags[(int)Flags.PackageFlags.ServerSideOnly] = (uint)PackageFlagsDefault.ServerSideOnly;
+ PackageFlags[(int)Flags.PackageFlag.AllowDownload] = (uint)PackageFlagsDefault.AllowDownload;
+ PackageFlags[(int)Flags.PackageFlag.ClientOptional] = (uint)PackageFlagsDefault.ClientOptional;
+ PackageFlags[(int)Flags.PackageFlag.ServerSideOnly] = (uint)PackageFlagsDefault.ServerSideOnly;
#if UE1
// FIXME: Version
if (linker.Version > 61 && linker.Version <= 69) // <= UT99
- PackageFlags[(int)Flags.PackageFlags.Encrypted] = (uint)PackageFlagsUE1.Encrypted;
+ PackageFlags[(int)Flags.PackageFlag.Encrypted] = (uint)PackageFlagsUE1.Encrypted;
#endif
#if UE2
if (linker.Build == BuildGeneration.UE2_5)
- PackageFlags[(int)Flags.PackageFlags.Official] = (uint)PackageFlagsUE2.Official;
+ PackageFlags[(int)Flags.PackageFlag.Official] = (uint)PackageFlagsUE2.Official;
#endif
#if UE3
// Map the new PackageFlags, but the version is nothing but a guess!
if (linker.Version >= 180)
{
if (linker.Version >= UnrealPackage.PackageFileSummary.VCookerVersion)
- PackageFlags[(int)Flags.PackageFlags.Cooked] = (uint)PackageFlagsUE3.Cooked;
+ PackageFlags[(int)Flags.PackageFlag.Cooked] = (uint)PackageFlagsUE3.Cooked;
- PackageFlags[(int)Flags.PackageFlags.ContainsMap] = (uint)PackageFlagsUE3.ContainsMap;
- PackageFlags[(int)Flags.PackageFlags.ContainsDebugData] = (uint)PackageFlagsUE3.ContainsDebugData;
- PackageFlags[(int)Flags.PackageFlags.ContainsScript] = (uint)PackageFlagsUE3.ContainsScript;
- PackageFlags[(int)Flags.PackageFlags.StrippedSource] = (uint)PackageFlagsUE3.StrippedSource;
+ PackageFlags[(int)Flags.PackageFlag.ContainsMap] = (uint)PackageFlagsUE3.ContainsMap;
+ PackageFlags[(int)Flags.PackageFlag.ContainsDebugData] = (uint)PackageFlagsUE3.ContainsDebugData;
+ PackageFlags[(int)Flags.PackageFlag.ContainsScript] = (uint)PackageFlagsUE3.ContainsScript;
+ PackageFlags[(int)Flags.PackageFlag.StrippedSource] = (uint)PackageFlagsUE3.StrippedSource;
}
#endif
}
diff --git a/src/Branch/EngineBranch.cs b/src/Branch/EngineBranch.cs
index 141b4bbc..a4977e7c 100644
--- a/src/Branch/EngineBranch.cs
+++ b/src/Branch/EngineBranch.cs
@@ -32,7 +32,7 @@ public abstract class EngineBranch
///
public readonly Dictionary EnumFlagsMap = new Dictionary();
- protected readonly ulong[] PackageFlags = new ulong[(int)Flags.PackageFlags.Max];
+ protected readonly ulong[] PackageFlags = new ulong[(int)Flags.PackageFlag.Max];
public EngineBranch()
{
diff --git a/src/Branch/UE2/AA2/CryptoDecoder.AA2.cs b/src/Branch/UE2/AA2/CryptoDecoder.AA2.cs
index b46f63ad..58df0ed3 100644
--- a/src/Branch/UE2/AA2/CryptoDecoder.AA2.cs
+++ b/src/Branch/UE2/AA2/CryptoDecoder.AA2.cs
@@ -3,7 +3,7 @@
namespace UELib.Branch.UE2.AA2
{
- // TODO: Re-implement as a BaseStream wrapper (in UELib 2.0)
+ // TODO: Re-implement as a BaseStream wrapper
public class CryptoDecoderAA2 : IBufferDecoder
{
public void PreDecode(IUnrealStream stream)
diff --git a/src/Branch/UE4/EngineBranch.UE4.cs b/src/Branch/UE4/EngineBranch.UE4.cs
index 81d0bb41..7d549af5 100644
--- a/src/Branch/UE4/EngineBranch.UE4.cs
+++ b/src/Branch/UE4/EngineBranch.UE4.cs
@@ -41,20 +41,20 @@ public EngineBranchUE4() : base(BuildGeneration.UE4)
public override void Setup(UnrealPackage linker)
{
SetupEnumPackageFlags(linker);
- EnumFlagsMap.Add(typeof(PackageFlags), PackageFlags);
+ EnumFlagsMap.Add(typeof(PackageFlag), PackageFlags);
}
protected virtual void SetupEnumPackageFlags(UnrealPackage linker)
{
- PackageFlags[(int)Flags.PackageFlags.ClientOptional] =
+ PackageFlags[(int)Flags.PackageFlag.ClientOptional] =
(uint)DefaultEngineBranch.PackageFlagsDefault.ClientOptional;
- PackageFlags[(int)Flags.PackageFlags.ServerSideOnly] =
+ PackageFlags[(int)Flags.PackageFlag.ServerSideOnly] =
(uint)DefaultEngineBranch.PackageFlagsDefault.ServerSideOnly;
- PackageFlags[(int)Flags.PackageFlags.EditorOnly] = (uint)PackageFlagsUE4.EditorOnly;
- PackageFlags[(int)Flags.PackageFlags.Cooked] = (uint)PackageFlagsUE4.Cooked;
- PackageFlags[(int)Flags.PackageFlags.UnversionedProperties] = (uint)PackageFlagsUE4.UnversionedProperties;
- PackageFlags[(int)Flags.PackageFlags.ReloadingForCooker] = (uint)PackageFlagsUE4.ReloadingForCooker;
- PackageFlags[(int)Flags.PackageFlags.FilterEditorOnly] = (uint)PackageFlagsUE4.FilterEditorOnly;
+ PackageFlags[(int)Flags.PackageFlag.EditorOnly] = (uint)PackageFlagsUE4.EditorOnly;
+ PackageFlags[(int)Flags.PackageFlag.Cooked] = (uint)PackageFlagsUE4.Cooked;
+ PackageFlags[(int)Flags.PackageFlag.UnversionedProperties] = (uint)PackageFlagsUE4.UnversionedProperties;
+ PackageFlags[(int)Flags.PackageFlag.ReloadingForCooker] = (uint)PackageFlagsUE4.ReloadingForCooker;
+ PackageFlags[(int)Flags.PackageFlag.FilterEditorOnly] = (uint)PackageFlagsUE4.FilterEditorOnly;
}
protected override void SetupSerializer(UnrealPackage linker)
diff --git a/src/Core/Classes/Props/UPropertyDecompiler.cs b/src/Core/Classes/Props/UPropertyDecompiler.cs
index 1512d92f..4e14c173 100644
--- a/src/Core/Classes/Props/UPropertyDecompiler.cs
+++ b/src/Core/Classes/Props/UPropertyDecompiler.cs
@@ -505,7 +505,9 @@ public string FormatFlags()
return string.Empty;
}
- return output;
+ // alright...
+ //return "/*" + UnrealMethods.FlagToString( PropertyFlags ) + "*/ " + output;
+ return copyFlags != 0 ? "/*" + UnrealMethods.FlagToString(copyFlags) + "*/ " + output : output;
}
}
}
diff --git a/src/Core/Classes/UClassDecompiler.cs b/src/Core/Classes/UClassDecompiler.cs
index 0bbfd90e..4530b7e5 100644
--- a/src/Core/Classes/UClassDecompiler.cs
+++ b/src/Core/Classes/UClassDecompiler.cs
@@ -78,25 +78,25 @@ public override string Decompile()
return content;
}
- [Obsolete]
+ [Obsolete("Deprecated", true)]
public string GetDependencies()
{
throw new NotImplementedException();
}
- [Obsolete]
+ [Obsolete("Deprecated", true)]
private string GetImports()
{
throw new NotImplementedException();
}
- [Obsolete]
+ [Obsolete("Deprecated", true)]
public string GetStats()
{
throw new NotImplementedException();
}
- protected override string FormatHeader()
+ public override string FormatHeader()
{
string output = (IsClassInterface() ? "interface " : "class ") + Name;
string metaData = DecompileMeta();
diff --git a/src/Core/Classes/UClassNode.cs b/src/Core/Classes/UClassNode.cs
new file mode 100644
index 00000000..5df25a36
--- /dev/null
+++ b/src/Core/Classes/UClassNode.cs
@@ -0,0 +1,42 @@
+#if Forms
+using System.Windows.Forms;
+
+namespace UELib.Core
+{
+ public partial class UClass
+ {
+ protected override void InitNodes(TreeNode node)
+ {
+ _ParentNode = AddSectionNode(node, nameof(UClass));
+ AddSimpleObjectNode(_ParentNode, Within, "Within", Within != null ? Within.GetImageName() : "");
+
+ var classFlagsNode = AddTextNode(_ParentNode, $"Class Flags:{UnrealMethods.FlagToString(ClassFlags)}");
+ classFlagsNode.ToolTipText = UnrealMethods.FlagsListToString(
+ UnrealMethods.FlagsToList(typeof(Flags.ClassFlags), ClassFlags)
+ );
+
+ base.InitNodes(_ParentNode);
+ }
+
+ protected override void AddChildren(TreeNode node)
+ {
+ base.AddChildren(node);
+ AddObjectListNode(node, "States", States, nameof(UState));
+ }
+
+ public override string GetImageName()
+ {
+ if (IsClassInterface())
+ {
+ return "Interface";
+ }
+ if (IsClassWithin())
+ {
+ return "UClass-Within";
+ }
+
+ return base.GetImageName();
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Core/Classes/UEnumDecompiler.cs b/src/Core/Classes/UEnumDecompiler.cs
index 66645134..d9ed305f 100644
--- a/src/Core/Classes/UEnumDecompiler.cs
+++ b/src/Core/Classes/UEnumDecompiler.cs
@@ -20,7 +20,7 @@ public override string Decompile()
UnrealConfig.PrintEndBracket() + ";";
}
- protected virtual string FormatHeader()
+ public override string FormatHeader()
{
return $"enum {Name}{DecompileMeta()}";
}
diff --git a/src/Core/Classes/UFieldNode.cs b/src/Core/Classes/UFieldNode.cs
new file mode 100644
index 00000000..16672d3d
--- /dev/null
+++ b/src/Core/Classes/UFieldNode.cs
@@ -0,0 +1,17 @@
+#if Forms
+using System.Windows.Forms;
+
+namespace UELib.Core
+{
+ public partial class UField
+ {
+ protected override void InitNodes(TreeNode node)
+ {
+ _ParentNode = AddSectionNode(node, nameof(UField));
+ AddSimpleObjectNode(_ParentNode, Super, "SuperField", Super != null ? Super.GetImageName() : "");
+ AddSimpleObjectNode(_ParentNode, NextField, "NextField", NextField != null ? NextField.GetImageName() : "");
+ base.InitNodes(_ParentNode);
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Core/Classes/UFunctionDecompiler.cs b/src/Core/Classes/UFunctionDecompiler.cs
index 9588f33f..d4ff6bdd 100644
--- a/src/Core/Classes/UFunctionDecompiler.cs
+++ b/src/Core/Classes/UFunctionDecompiler.cs
@@ -215,7 +215,7 @@ private string FormatFlags()
return output;
}
- protected override string FormatHeader()
+ public override string FormatHeader()
{
var output = string.Empty;
// static function (string?:) Name(Parms)...
diff --git a/src/Core/Classes/UFunctionNode.cs b/src/Core/Classes/UFunctionNode.cs
new file mode 100644
index 00000000..7f3efa48
--- /dev/null
+++ b/src/Core/Classes/UFunctionNode.cs
@@ -0,0 +1,65 @@
+#if Forms
+using System.Windows.Forms;
+
+namespace UELib.Core
+{
+ public partial class UFunction
+ {
+ protected override void InitNodes(TreeNode node)
+ {
+ node.ToolTipText = FormatHeader();
+ _ParentNode = AddSectionNode(node, nameof(UFunction));
+
+ var funcFlagsNode = AddTextNode(_ParentNode, $"FunctionFlags:{UnrealMethods.FlagToString(FunctionFlags)}");
+ funcFlagsNode.ToolTipText =
+ UnrealMethods.FlagsListToString(UnrealMethods.FlagsToList(typeof(Flags.FunctionFlags), FunctionFlags));
+
+ if (RepOffset > 0)
+ {
+ AddTextNode(_ParentNode, $"Replication Offset:{RepOffset}");
+ }
+
+ base.InitNodes(_ParentNode);
+ }
+
+ protected override void AddChildren(TreeNode node)
+ {
+ base.AddChildren(node);
+ AddObjectListNode(node, "Parameters", Params, nameof(UProperty));
+ AddObjectListNode(node, "Locals", Locals, nameof(UProperty));
+ }
+
+ public override string GetImageName()
+ {
+ var name = string.Empty;
+ if (HasFunctionFlag(Flags.FunctionFlags.Event))
+ {
+ name = "Event";
+ }
+ else if (HasFunctionFlag(Flags.FunctionFlags.Delegate))
+ {
+ name = "Delegate";
+ }
+ else if (HasFunctionFlag(Flags.FunctionFlags.Operator))
+ {
+ name = "Operator";
+ }
+
+ if (name != string.Empty)
+ {
+ if (IsProtected())
+ {
+ return $"{name}-Protected";
+ }
+ if (IsPrivate())
+ {
+ return $"{name}-Private";
+ }
+ return name;
+ }
+
+ return base.GetImageName();
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Core/Classes/UObject.cs b/src/Core/Classes/UObject.cs
index 57a0f013..cbf2ac11 100644
--- a/src/Core/Classes/UObject.cs
+++ b/src/Core/Classes/UObject.cs
@@ -670,7 +670,7 @@ public virtual void PostInitialize()
{
}
- [Obsolete]
+ [Obsolete("Deprecated", true)]
public virtual void InitializeImports()
{
throw new NotImplementedException();
diff --git a/src/Core/Classes/UObjectDecompiler.cs b/src/Core/Classes/UObjectDecompiler.cs
index 8ce188e2..31f505fd 100644
--- a/src/Core/Classes/UObjectDecompiler.cs
+++ b/src/Core/Classes/UObjectDecompiler.cs
@@ -37,6 +37,11 @@ public virtual string Decompile()
$"// Reference: {Class.Name}'{GetOuterGroup()}'";
}
+ public virtual string FormatHeader()
+ {
+ return GetReferencePath();
+ }
+
protected string DecompileProperties()
{
if (Properties == null || Properties.Count == 0)
diff --git a/src/Core/Classes/UObjectNode.cs b/src/Core/Classes/UObjectNode.cs
new file mode 100644
index 00000000..d28cde71
--- /dev/null
+++ b/src/Core/Classes/UObjectNode.cs
@@ -0,0 +1,134 @@
+#if Forms
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace UELib.Core
+{
+ public partial class UObject
+ {
+ protected TreeNode _ParentNode;
+ public bool HasInitializedNodes;
+
+ public void InitializeNodes(TreeNode node)
+ {
+ if (HasInitializedNodes)
+ return;
+
+ node.ToolTipText = FormatHeader();
+ InitNodes(node);
+ AddChildren(node);
+ PostAddChildren(node);
+
+ node.ImageKey = GetImageName();
+ node.SelectedImageKey = node.ImageKey;
+ HasInitializedNodes = true;
+ }
+
+ public virtual string GetImageName()
+ {
+ return GetType().IsSubclassOf(typeof(UProperty))
+ ? nameof(UProperty)
+ : this is UScriptStruct
+ ? nameof(UStruct)
+ : GetType().Name;
+ }
+
+ protected virtual void InitNodes(TreeNode node)
+ {
+ _ParentNode = AddSectionNode(node, nameof(UObject));
+ var flagNode = AddTextNode(_ParentNode, $"ObjectFlags:{UnrealMethods.FlagToString(_ObjectFlags)}");
+ flagNode.ToolTipText = UnrealMethods.FlagsListToString(
+ UnrealMethods.FlagsToList(typeof(Flags.ObjectFlagsLO), typeof(Flags.ObjectFlagsHO), _ObjectFlags)
+ );
+
+ AddTextNode(_ParentNode, $"Size:{ExportTable.SerialSize}");
+ AddTextNode(_ParentNode, $"Offset:{ExportTable.SerialOffset}");
+ }
+
+ protected virtual void AddChildren(TreeNode node)
+ {
+ }
+
+ protected virtual void PostAddChildren(TreeNode node)
+ {
+ }
+
+ protected static TreeNode AddSectionNode(TreeNode p, string n)
+ {
+ var nn = new TreeNode(n) { ImageKey = "Extend" };
+ nn.SelectedImageKey = nn.ImageKey;
+ p.Nodes.Add(nn);
+ return nn;
+ }
+
+ protected static TreeNode AddTextNode(TreeNode p, string n)
+ {
+ var nn = new TreeNode(n) { ImageKey = "Info" };
+ nn.SelectedImageKey = nn.ImageKey;
+ p.Nodes.Add(nn);
+ return nn;
+ }
+
+ protected static ObjectNode AddObjectNode(TreeNode parentNode, UObject unrealObject, string imageName = "")
+ {
+ if (unrealObject == null)
+ return null;
+
+ var objN = new ObjectNode(unrealObject) { Text = unrealObject.Name };
+ unrealObject.InitializeNodes(objN);
+ if (imageName != string.Empty)
+ {
+ objN.ImageKey = imageName;
+ objN.SelectedImageKey = imageName;
+ }
+
+ if (unrealObject.DeserializationState.HasFlag(ObjectState.Errorlized))
+ {
+ objN.ForeColor = System.Drawing.Color.Red;
+ }
+
+ parentNode.Nodes.Add(objN);
+ return objN;
+ }
+
+ protected static ObjectNode AddSimpleObjectNode(TreeNode parentNode, UObject unrealObject, string text,
+ string imageName = "")
+ {
+ if (unrealObject == null)
+ return null;
+
+ var objN = new ObjectNode(unrealObject) { Text = $"{text}:{unrealObject.Name}" };
+ if (imageName != string.Empty)
+ {
+ objN.ImageKey = imageName;
+ objN.SelectedImageKey = imageName;
+ }
+
+ parentNode.Nodes.Add(objN);
+ return objN;
+ }
+
+ protected static ObjectListNode AddObjectListNode
+ (
+ TreeNode parentNode,
+ string title,
+ IList objects,
+ string imageName = "TreeView"
+ ) where T : UObject
+ {
+ if (objects == null || !objects.Any())
+ return null;
+
+ var listNode = new ObjectListNode(imageName) { Text = title };
+ foreach (var obj in objects)
+ {
+ AddObjectNode(listNode, obj, obj.GetType().Name);
+ }
+
+ parentNode.Nodes.Add(listNode);
+ return listNode;
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Core/Classes/UPackageNode.cs b/src/Core/Classes/UPackageNode.cs
new file mode 100644
index 00000000..5d471f2e
--- /dev/null
+++ b/src/Core/Classes/UPackageNode.cs
@@ -0,0 +1,12 @@
+#if Forms
+namespace UELib.Core
+{
+ public partial class UPackage
+ {
+ public override string GetImageName()
+ {
+ return "Library";
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Core/Classes/UPropertyNode.cs b/src/Core/Classes/UPropertyNode.cs
new file mode 100644
index 00000000..7850ad64
--- /dev/null
+++ b/src/Core/Classes/UPropertyNode.cs
@@ -0,0 +1,47 @@
+#if Forms
+using System.Windows.Forms;
+
+namespace UELib.Core
+{
+ public partial class UProperty
+ {
+ protected override void InitNodes(TreeNode node)
+ {
+ _ParentNode = AddSectionNode(node, nameof(UProperty));
+ var propertyFlagsNode = AddTextNode(_ParentNode,
+ $"Property Flags:{UnrealMethods.FlagToString(PropertyFlags)}"
+ );
+ propertyFlagsNode.ToolTipText = UnrealMethods.FlagsListToString(UnrealMethods.FlagsToList(
+ typeof(Flags.PropertyFlagsLO),
+ typeof(Flags.PropertyFlagsHO), PropertyFlags)
+ );
+
+ if (RepOffset > 0)
+ {
+ AddTextNode(_ParentNode, $"Replication Offset:{RepOffset}");
+ }
+
+ base.InitNodes(_ParentNode);
+ }
+
+ public override string GetImageName()
+ {
+ if (HasPropertyFlag(Flags.PropertyFlagsLO.ReturnParm))
+ {
+ return "ReturnValue";
+ }
+
+ string which = base.GetImageName();
+ if (IsProtected())
+ {
+ return $"{which}-Protected";
+ }
+ if (IsPrivate())
+ {
+ return $"{which}-Private";
+ }
+ return which;
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Core/Classes/UStateDecompiler.cs b/src/Core/Classes/UStateDecompiler.cs
index df7172c5..3128e066 100644
--- a/src/Core/Classes/UStateDecompiler.cs
+++ b/src/Core/Classes/UStateDecompiler.cs
@@ -55,7 +55,7 @@ private string GetEdit()
return HasStateFlag(Flags.StateFlags.Editable) ? "()" : string.Empty;
}
- protected override string FormatHeader()
+ public override string FormatHeader()
{
var output = $"{GetAuto()}{GetSimulated()}state{GetEdit()} {Name}";
if (Super != null && Super.Name != Name
diff --git a/src/Core/Classes/UStateNode.cs b/src/Core/Classes/UStateNode.cs
new file mode 100644
index 00000000..429fe249
--- /dev/null
+++ b/src/Core/Classes/UStateNode.cs
@@ -0,0 +1,29 @@
+#if Forms
+using System.Windows.Forms;
+
+namespace UELib.Core
+{
+ public partial class UState
+ {
+ protected override void InitNodes(TreeNode node)
+ {
+ _ParentNode = AddSectionNode(node, nameof(UState));
+
+ if (GetType() == typeof(UState))
+ {
+ var stateFlagsNode = AddTextNode(_ParentNode, $"State Flags:{UnrealMethods.FlagToString(_StateFlags)}");
+ stateFlagsNode.ToolTipText =
+ UnrealMethods.FlagsListToString(UnrealMethods.FlagsToList(typeof(Flags.StateFlags), _StateFlags));
+ }
+
+ base.InitNodes(_ParentNode);
+ }
+
+ protected override void AddChildren(TreeNode node)
+ {
+ base.AddChildren(node);
+ AddObjectListNode(node, "Functions", Functions, nameof(UFunction));
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Core/Classes/UStructDecompiler.cs b/src/Core/Classes/UStructDecompiler.cs
index 76dfbd75..82fbb1ba 100644
--- a/src/Core/Classes/UStructDecompiler.cs
+++ b/src/Core/Classes/UStructDecompiler.cs
@@ -49,7 +49,7 @@ public override string Decompile()
return content + UnrealConfig.PrintEndBracket() + ";";
}
- protected virtual string FormatHeader()
+ public override string FormatHeader()
{
var output = $"struct {FormatFlags()}{Name}{(Super != null ? $" {FormatExtends()} {Super.Name}" : string.Empty)}";
string metaData = DecompileMeta();
diff --git a/src/Core/Classes/UStructNode.cs b/src/Core/Classes/UStructNode.cs
new file mode 100644
index 00000000..70edf9e3
--- /dev/null
+++ b/src/Core/Classes/UStructNode.cs
@@ -0,0 +1,76 @@
+#if Forms
+using System.Collections.Generic;
+using System.Windows.Forms;
+
+namespace UELib.Core
+{
+ public partial class UStruct
+ {
+ protected override void InitNodes(TreeNode node)
+ {
+ _ParentNode = AddSectionNode(node, nameof(UStruct));
+ if (IsPureStruct())
+ {
+ var sFlagsNode = AddTextNode(_ParentNode, $"Struct Flags:{UnrealMethods.FlagToString(StructFlags)}");
+ sFlagsNode.ToolTipText =
+ UnrealMethods.FlagsListToString(UnrealMethods.FlagsToList(typeof(Flags.StructFlags), StructFlags));
+ }
+
+ AddTextNode(_ParentNode, $"Script Size:{DataScriptSize}");
+ base.InitNodes(_ParentNode);
+ }
+
+ protected override void AddChildren(TreeNode node)
+ {
+ if (ScriptText != null)
+ {
+ AddObjectNode(node, ScriptText, nameof(UObject));
+ }
+
+ if (CppText != null)
+ {
+ AddObjectNode(node, CppText, nameof(UObject));
+ }
+
+ if (ProcessedText != null)
+ {
+ AddObjectNode(node, ProcessedText, nameof(UObject));
+ }
+
+ var children = new List();
+ for (var child = Children; child != null; child = child.NextField)
+ {
+ children.Insert(0, child);
+ }
+ AddObjectListNode(node, "Children", children, nameof(UObject));
+ AddObjectListNode(node, "Constants", Constants, nameof(UConst));
+ AddObjectListNode(node, "Enumerations", Enums, nameof(UEnum));
+ AddObjectListNode(node, "Structures", Structs, nameof(UStruct));
+ // Not if the upper class is a function; UFunction adds locals and parameters instead
+ if (GetType() != typeof(UFunction))
+ {
+ AddObjectListNode(node, "Variables", Variables, nameof(UProperty));
+ }
+ }
+
+ protected override void PostAddChildren(TreeNode node)
+ {
+ if (Properties == null || Properties.Count <= 0)
+ return;
+
+ var defNode = new ObjectListNode
+ {
+ Text = "Default Values",
+ ImageKey = "UDefaultProperty",
+ SelectedImageKey = "UDefaultProperty"
+ };
+ node.Nodes.Add(defNode);
+ foreach (var def in Properties)
+ {
+ var objN = new DefaultObjectNode(def) { Text = def.Name };
+ defNode.Nodes.Add(objN);
+ }
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Core/Tables/UExportTableItem.cs b/src/Core/Tables/UExportTableItem.cs
index cda305d0..7bc7a608 100644
--- a/src/Core/Tables/UExportTableItem.cs
+++ b/src/Core/Tables/UExportTableItem.cs
@@ -25,6 +25,7 @@ public int ClassIndex
get => _ClassIndex;
set => _ClassIndex = value;
}
+
[CanBeNull]
public UObjectTableItem Class => Owner.GetIndexTable(ClassIndex);
@@ -54,9 +55,14 @@ public int ArchetypeIndex
}
[CanBeNull]
public UObjectTableItem Archetype => Owner.GetIndexTable(_ArchetypeIndex);
+
+ [Obsolete("Use Class"), Browsable(false)] public UObjectTableItem ClassTable => Owner.GetIndexTable(_ClassIndex);
+
+ [Obsolete]
+ protected override int __ClassIndex => _ClassIndex;
- [Obsolete, Browsable(false)] public UObjectTableItem SuperTable => Owner.GetIndexTable(_SuperIndex);
- [Obsolete, Browsable(false)]
+ [Obsolete("Use Super"), Browsable(false)] public UObjectTableItem SuperTable => Owner.GetIndexTable(_SuperIndex);
+ [Obsolete("Use Super?.ObjectName"), Browsable(false)]
public string SuperName
{
get
@@ -66,8 +72,8 @@ public string SuperName
}
}
- [Obsolete, Browsable(false)] public UObjectTableItem ArchetypeTable => Owner.GetIndexTable(_ArchetypeIndex);
- [Obsolete, Browsable(false)]
+ [Obsolete("Use Archetype"), Browsable(false)] public UObjectTableItem ArchetypeTable => Owner.GetIndexTable(_ArchetypeIndex);
+ [Obsolete("Use Archetype?.ObjectName"), Browsable(false)]
public string ArchetypeName
{
get
@@ -296,6 +302,12 @@ public override string ToString()
return $"{ObjectName}({Index}{1})";
}
+ [Obsolete("Use ToString()")]
+ public string ToString(bool v)
+ {
+ return ToString();
+ }
+
public static explicit operator int(UExportTableItem item)
{
return item.Index;
diff --git a/src/Core/Tables/UGenerationTableItem.cs b/src/Core/Tables/UGenerationTableItem.cs
index 8e74cfe9..8389467c 100644
--- a/src/Core/Tables/UGenerationTableItem.cs
+++ b/src/Core/Tables/UGenerationTableItem.cs
@@ -1,3 +1,4 @@
+using System;
using UELib.Annotations;
namespace UELib
@@ -27,6 +28,13 @@ public int NetObjectCount
set => _NetObjectCount = value;
}
+ [Obsolete]
+ public object ExportsCount => ExportCount;
+ [Obsolete]
+ public object NamesCount => NameCount;
+ [Obsolete]
+ public object NetObjectsCount => NetObjectCount;
+
public const int VNetObjectsCount = 322;
public void Serialize(IUnrealStream stream)
diff --git a/src/Core/Tables/UImportTableItem.cs b/src/Core/Tables/UImportTableItem.cs
index 0d531c6a..5d09a02a 100644
--- a/src/Core/Tables/UImportTableItem.cs
+++ b/src/Core/Tables/UImportTableItem.cs
@@ -1,3 +1,4 @@
+using System;
using UELib.Core;
namespace UELib
@@ -25,6 +26,9 @@ public UName ClassName
set => _ClassName = value;
}
+ [Obsolete] protected override string __ClassName => _ClassName;
+ [Obsolete] protected override int __ClassIndex => (int)_ClassName;
+
#endregion
public void Serialize(IUnrealStream stream)
@@ -53,6 +57,12 @@ public override string ToString()
return $"{ObjectName}({-(Index + 1)})";
}
+ [Obsolete("Use ToString()")]
+ public string ToString(bool v)
+ {
+ return ToString();
+ }
+
public static explicit operator int(UImportTableItem item)
{
return -item.Index;
diff --git a/src/Core/Tables/UObjectTableItem.cs b/src/Core/Tables/UObjectTableItem.cs
index 6c8e028b..c863d024 100644
--- a/src/Core/Tables/UObjectTableItem.cs
+++ b/src/Core/Tables/UObjectTableItem.cs
@@ -42,11 +42,11 @@ public int OuterIndex
}
[Obsolete, Browsable(false)] public UNameTableItem ObjectTable => Owner.Names[(int)_ObjectName];
- [Obsolete, Browsable(false)] public UObjectTableItem ClassTable => null;
+ [Obsolete("Use UExportTableItem.Class"), Browsable(false)] public UObjectTableItem ClassTable => Owner.GetIndexTable(ClassIndex);
[Obsolete, Browsable(false)] public UObjectTableItem OuterTable => Owner.GetIndexTable(OuterIndex);
public UObjectTableItem Outer => Owner.GetIndexTable(_OuterIndex);
- [Obsolete, Browsable(false)]
+ [Obsolete("Use Outer?.ObjectName"), Browsable(false)]
public string OuterName
{
get
@@ -56,6 +56,18 @@ public string OuterName
}
}
+ [Obsolete("Use UExportTableItem.ClassIndex"), Browsable(false)]
+ public int ClassIndex => __ClassIndex;
+
+ [Obsolete]
+ protected virtual int __ClassIndex => 0;
+
+ [Obsolete("Use Class?.ObjectName or UImportTableItem.ClassName"), Browsable(false)]
+ public string ClassName => __ClassName;
+
+ [Obsolete]
+ protected virtual string __ClassName => "";
+
#endregion
public IEnumerable EnumerateOuter()
diff --git a/src/Eliot.UELib.csproj b/src/Eliot.UELib.csproj
index 2cb974ec..4b414b9a 100644
--- a/src/Eliot.UELib.csproj
+++ b/src/Eliot.UELib.csproj
@@ -64,6 +64,9 @@
6.0.0
+
+
+
Eliot.UELib.nuspec
diff --git a/src/Engine/Classes/UPolys.cs b/src/Engine/Classes/UPolys.cs
index 804a8828..8f7c9df7 100644
--- a/src/Engine/Classes/UPolys.cs
+++ b/src/Engine/Classes/UPolys.cs
@@ -28,7 +28,7 @@ protected override void Deserialize()
base.Deserialize();
// Faster serialization for cooked packages, no don't have to check for the package's version here.
- if (Package.Summary.PackageFlags.HasFlag(PackageFlags.Cooked))
+ if (Package.Summary.PackageFlags.HasFlag(PackageFlag.Cooked))
{
ElementOwner = _Buffer.ReadObject();
Record(nameof(ElementOwner), ElementOwner);
diff --git a/src/ObjectNodes.cs b/src/ObjectNodes.cs
new file mode 100644
index 00000000..15b82396
--- /dev/null
+++ b/src/ObjectNodes.cs
@@ -0,0 +1,81 @@
+#if Forms
+using System;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.Text;
+using System.Windows.Forms;
+
+namespace UELib.Core
+{
+ [Serializable]
+ [System.Runtime.InteropServices.ComVisible(false)]
+ public class ObjectNode : TreeNode, IDecompilableObject
+ {
+ public IUnrealDecompilable Object { get; private set; }
+
+ public ObjectNode(IUnrealDecompilable objectRef)
+ {
+ Object = objectRef;
+ }
+
+ protected ObjectNode(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
+ info.AddValue(Text, Object);
+ }
+
+ public virtual string Decompile()
+ {
+ try
+ {
+ UDecompilingState.ResetTabs();
+ return Object.Decompile();
+ }
+ catch (Exception e)
+ {
+ return string.Format
+ (
+ "An exception of type \"{0}\" occurred while decompiling {1}.\r\nDetails:\r\n{2}",
+ e.GetType().Name, Text, e
+ );
+ }
+ }
+ }
+
+ [System.Runtime.InteropServices.ComVisible(false)]
+ public class DefaultObjectNode : ObjectNode
+ {
+ public DefaultObjectNode(IUnrealDecompilable objectRef) : base(objectRef)
+ {
+ ImageKey = nameof(UDefaultProperty);
+ SelectedImageKey = ImageKey;
+ }
+ }
+
+ [System.Runtime.InteropServices.ComVisible(false)]
+ public sealed class ObjectListNode : TreeNode, IUnrealDecompilable
+ {
+ public ObjectListNode()
+ {
+ ImageKey = "TreeView";
+ SelectedImageKey = ImageKey;
+ }
+
+ public ObjectListNode(string imageName)
+ {
+ ImageKey = imageName;
+ SelectedImageKey = imageName;
+ }
+
+ public string Decompile()
+ {
+ var output = new StringBuilder();
+ foreach (var node in Nodes.OfType())
+ {
+ output.AppendLine(node.Decompile());
+ }
+
+ return output.ToString();
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/UnrealConfig.cs b/src/UnrealConfig.cs
index 078a5a70..ef625d82 100644
--- a/src/UnrealConfig.cs
+++ b/src/UnrealConfig.cs
@@ -23,6 +23,15 @@ public static class UnrealConfig
public static string PreEndBracket = "\r\n{0}";
public static string Indention = "\t";
+ [Obsolete]
+ public enum CookedPlatform
+ {
+ PC,
+ Console
+ }
+
+ [Obsolete]
+ public static CookedPlatform Platform;
public static Dictionary> VariableTypes;
#endregion
@@ -37,4 +46,4 @@ public static string PrintEndBracket()
return $"{string.Format(PreEndBracket, UDecompilingState.Tabs)}{ScriptConstants.EndBracket}";
}
}
-}
+}
\ No newline at end of file
diff --git a/src/UnrealFlags.cs b/src/UnrealFlags.cs
index 2dac174b..7300a041 100644
--- a/src/UnrealFlags.cs
+++ b/src/UnrealFlags.cs
@@ -75,7 +75,7 @@ public override string ToString()
///
///
///
- public enum PackageFlags
+ public enum PackageFlag
{
AllowDownload,
ClientOptional,
@@ -104,6 +104,103 @@ public enum PackageFlags
Max,
}
+ [Obsolete("Use the normalized PackageFlag instead")]
+ [Flags]
+ public enum PackageFlags : uint
+ {
+ // 028A0009 : A cooked and compressed package
+ // 00280009 : A cooked package
+ // 00020001 : A ordinary package
+
+ ///
+ /// UEX: Whether clients are allowed to download the package from the server.
+ /// UE4: Displaced by "NewlyCreated"
+ ///
+ AllowDownload = 0x00000001U,
+
+ ///
+ /// Whether clients can skip downloading the package but still able to join the server.
+ ///
+ ClientOptional = 0x00000002U,
+
+ ///
+ /// Only necessary to load on the server.
+ ///
+ ServerSideOnly = 0x00000004U,
+
+ BrokenLinks = 0x00000008U, // @Redefined(UE3, Cooked)
+
+ ///
+ /// The package is cooked.
+ ///
+ Cooked = 0x00000008U, // @Redefined
+
+ ///
+ /// ???
+ /// <= UT
+ ///
+ Unsecure = 0x00000010U,
+
+ ///
+ /// The package is encrypted.
+ /// <= UT
+ /// Also attested in file UT2004/Packages.MD5 but it is not encrypted.
+ ///
+ Encrypted = 0x00000020U,
+
+#if UE4
+ EditorOnly = 0x00000040U,
+ UnversionedProperties = 0x00002000U,
+#endif
+
+ ///
+ /// Clients must download the package.
+ ///
+ Need = 0x00008000U,
+
+ ///
+ /// Unknown flags
+ /// - 0x20000000 -- Probably means the package contains Content(Meshes, Textures)
+ ///
+ ///
+
+ /// Package holds map data.
+ ContainsMap = 0x00020000U,
+
+ ///
+ /// Package contains classes.
+ ///
+ ContainsScript = 0x00200000U,
+
+ ///
+ /// The package was build with -Debug
+ ///
+ ContainsDebugData = 0x00400000U,
+
+ Imports = 0x00800000U,
+
+ Compressed = 0x02000000U,
+ FullyCompressed = 0x04000000U,
+
+ ///
+ /// Whether package has metadata exported(anything related to the editor).
+ ///
+ NoExportsData = 0x20000000U,
+
+ ///
+ /// Package's source is stripped.
+ /// UE4: Same as ReloadingForCooker?
+ ///
+ Stripped = 0x40000000U,
+#if UE4
+ FilterEditorOnly = 0x80000000U,
+#endif
+ Protected = 0x80000000U,
+#if TRANSFORMERS
+ HMS_XmlFormat = 0x80000000U,
+#endif
+ }
+
[Flags]
public enum CompressionFlags : uint
{
diff --git a/src/UnrealInterfaces.cs b/src/UnrealInterfaces.cs
index 11eeb844..a3d34af0 100644
--- a/src/UnrealInterfaces.cs
+++ b/src/UnrealInterfaces.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.IO;
using UELib.Annotations;
using UELib.Core;
@@ -17,6 +18,18 @@ public interface IUnrealDecompilable
string Decompile();
}
+ ///
+ /// This class has a reference to an object and are both decompilable.
+ ///
+ [Obsolete]
+ public interface IDecompilableObject : IUnrealDecompilable
+ {
+ ///
+ /// The decompileable object that will be decompiled when this object's Decompile() function is called.
+ ///
+ IUnrealDecompilable Object { get; }
+ }
+
///
/// This class has a stream reference.
///
@@ -112,6 +125,15 @@ public interface IUnrealExportable
void SerializeExport(string desiredExportExtension, Stream exportStream);
}
+ public static class IUnrealExportableImplementation
+ {
+ [Obsolete("Use CanExport()")]
+ public static bool CompatableExport(this IUnrealExportable exportable)
+ {
+ return exportable.CanExport();
+ }
+ }
+
///
/// This class is replicable.
///
diff --git a/src/UnrealMethods.cs b/src/UnrealMethods.cs
index d875e681..97ad0e61 100644
--- a/src/UnrealMethods.cs
+++ b/src/UnrealMethods.cs
@@ -1,7 +1,11 @@
using System;
+using System.Collections.Generic;
+using System.Linq;
namespace UELib
{
+ #region Exceptions
+
[Serializable]
public class UnrealException : Exception
{
@@ -21,39 +25,174 @@ public UnrealException(string message, Exception innerException) : base(message,
[Serializable]
public class DeserializationException : UnrealException
{
+ [NonSerialized] private readonly string _Output;
+
public DeserializationException()
{
+ _Output = "DeserializationException";
+ }
+
+ public DeserializationException(string output) : base(output)
+ {
+ _Output = output;
}
- public DeserializationException(string message) : base(message)
+ public override string ToString()
{
+ return _Output + "\r\n" + base.ToString();
}
}
[Serializable]
- public class DecompilationException : UnrealException
+ public class DecompilingCastException : DeserializationException
+ {
+ }
+
+ [Serializable]
+ public class DecompilingHeaderException : UnrealException
{
- public DecompilationException()
+ [NonSerialized] private readonly string _Output;
+
+ public DecompilingHeaderException()
{
+ _Output = "DecompilingHeaderException";
}
- public DecompilationException(string message) : base(message)
+ public DecompilingHeaderException(string output)
+ {
+ _Output = output;
+ }
+
+ public override string ToString()
+ {
+ return _Output + "\r\n" + base.ToString();
+ }
+ }
+
+ [Serializable]
+ public class CookedPackageException : UnrealException
+ {
+ public CookedPackageException() : base("The package is cooked")
+ {
+ }
+ }
+
+ [Serializable]
+ public class DecompressPackageException : UnrealException
+ {
+ public DecompressPackageException() : base("Failed to decompress this package")
+ {
+ }
+ }
+
+ [Serializable]
+ public class OccurredWhileException : UnrealException
+ {
+ public OccurredWhileException(string postMessage) : base("An exception occurred while " + postMessage)
+ {
+ }
+ }
+
+ [Serializable]
+ public class DeserializingObjectsException : OccurredWhileException
+ {
+ public DeserializingObjectsException() : base("deserializing objects")
{
}
}
- [Obsolete]
- public class DeserializingObjectsException : UnrealException
+ [Serializable]
+ public class ImportingObjectsException : OccurredWhileException
{
+ public ImportingObjectsException() : base("importing objects")
+ {
+ }
}
- [Obsolete]
- public class ImportingObjectsException : UnrealException
+ [Serializable]
+ public class LinkingObjectsException : OccurredWhileException
{
+ public LinkingObjectsException() : base("linking objects")
+ {
+ }
}
- [Obsolete]
- public class LinkingObjectsException : UnrealException
+ #endregion
+
+ #region Static Methods
+
+ ///
+ /// Provides static methods for formating flags.
+ ///
+ [Obsolete("Use .ToString() on the target enum instead.")]
+ public static class UnrealMethods
{
+ public static string FlagsListToString(List flagsList)
+ {
+ var output = string.Empty;
+ foreach (string s in flagsList)
+ {
+ output += s + (s != flagsList.Last() ? "\n" : string.Empty);
+ }
+
+ return output;
+ }
+
+ public static List FlagsToList(Type flagEnum, uint flagsDWORD)
+ {
+ var flagsList = new List();
+ var flagValues = Enum.GetValues(flagEnum);
+ foreach (uint flag in flagValues)
+ {
+ if ((flagsDWORD & flag) != flag)
+ continue;
+
+ string eName = Enum.GetName(flagEnum, flag);
+ if (flagsList.Contains(eName))
+ continue;
+
+ flagsList.Add($"0x{flag:X8}:{eName}");
+ }
+
+ return flagsList;
+ }
+
+ public static List FlagsToList(Type flagEnum, ulong flagsDWORD)
+ {
+ var flagsList = new List();
+ var flagValues = Enum.GetValues(flagEnum);
+ foreach (ulong flag in flagValues)
+ {
+ if ((flagsDWORD & flag) != flag)
+ continue;
+
+ string eName = Enum.GetName(flagEnum, flag);
+ if (flagsList.Contains(eName))
+ continue;
+
+ flagsList.Add($"0x{flag:X8}:{eName}");
+ }
+
+ return flagsList;
+ }
+
+ public static List FlagsToList(Type flagEnum, Type flagEnum2, ulong flagsQWORD)
+ {
+ var list = FlagsToList(flagEnum, flagsQWORD);
+ list.AddRange(FlagsToList(flagEnum2, flagsQWORD >> 32));
+ return list;
+ }
+
+ public static string FlagToString(uint flags)
+ {
+ return $"0x{$"{flags:X4}".PadLeft(8, '0')}";
+ }
+
+ public static string FlagToString(ulong flags)
+ {
+ return $"{FlagToString((uint)(flags >> 32))}-{FlagToString((uint)flags)}";
+ }
}
+
+ #endregion
}
\ No newline at end of file
diff --git a/src/UnrealPackage.cs b/src/UnrealPackage.cs
index 34142f28..5a1f9f23 100644
--- a/src/UnrealPackage.cs
+++ b/src/UnrealPackage.cs
@@ -775,11 +775,13 @@ public struct PackageFileSummary : IUnrealSerializableClass
public uint UE4Version;
public uint UE4LicenseeVersion;
- public UnrealFlags PackageFlags;
+ public UnrealFlags PackageFlags;
+ [Obsolete]
private const int VHeaderSize = 249;
public int HeaderSize;
+ [Obsolete]
private const int VFolderName = 269;
///
@@ -799,6 +801,7 @@ public struct PackageFileSummary : IUnrealSerializableClass
///
public UArray Heritages;
+ [Obsolete]
private const int VDependsOffset = 415;
public int DependsOffset;
@@ -808,29 +811,39 @@ public struct PackageFileSummary : IUnrealSerializableClass
private PackageFileEngineVersion PackageEngineVersion;
private PackageFileEngineVersion PackageCompatibleEngineVersion;
+ [Obsolete]
private const int VEngineVersion = 245;
- public int EngineVersion;
+
+ [Obsolete]
public const int VCookerVersion = 277;
+
+ public int EngineVersion;
public int CookerVersion;
+ [Obsolete]
private const int VCompression = 334;
public uint CompressionFlags;
public UArray CompressedChunks;
+ [Obsolete]
private const int VPackageSource = 482;
public uint PackageSource;
+ [Obsolete]
private const int VAdditionalPackagesToCook = 516;
public UArray AdditionalPackagesToCook;
+ [Obsolete]
private const int VImportExportGuidsOffset = 623;
public int ImportExportGuidsOffset;
public int ImportGuidsCount;
public int ExportGuidsCount;
+ [Obsolete]
private const int VThumbnailTableOffset = 584;
public int ThumbnailTableOffset;
+ [Obsolete]
private const int VTextureAllocations = 767;
public int GatherableTextDataCount;
@@ -844,7 +857,6 @@ public struct PackageFileSummary : IUnrealSerializableClass
public UGuid PersistentGuid;
public UGuid OwnerPersistentGuid;
- // In UELib 2.0 we pass the version to the Archives instead.
private void SetupBuild(UnrealPackage package)
{
// Auto-detect
@@ -995,7 +1007,7 @@ public void Deserialize(IUnrealStream stream)
FolderName = stream.ReadText();
}
- PackageFlags = stream.ReadFlags32();
+ PackageFlags = stream.ReadFlags32();
Console.WriteLine("Package Flags:" + PackageFlags);
#if HAWKEN
if (stream.Package.Build == GameBuild.BuildName.Hawken &&
@@ -1107,7 +1119,7 @@ public void Deserialize(IUnrealStream stream)
#endif
#if DD2
// No version check found in the .exe
- if (stream.Package.Build == GameBuild.BuildName.DD2 && PackageFlags.HasFlag(Flags.PackageFlags.Cooked))
+ if (stream.Package.Build == GameBuild.BuildName.DD2 && PackageFlags.HasFlag(PackageFlag.Cooked))
stream.Skip(4);
#endif
if (stream.Version >= VThumbnailTableOffset)
@@ -1280,7 +1292,7 @@ public void Deserialize(IUnrealStream stream)
}
#if ROCKETLEAGUE
if (stream.Package.Build == GameBuild.BuildName.RocketLeague
- && PackageFlags.HasFlag(Flags.PackageFlags.Cooked))
+ && PackageFlags.HasFlag(PackageFlag.Cooked))
{
int garbageSize = stream.ReadInt32();
Debug.WriteLine(garbageSize, "GarbageSize");
@@ -1302,19 +1314,21 @@ public void Deserialize(IUnrealStream stream)
///
public bool IsBigEndianEncoded { get; }
+ [Obsolete]
public const int VSIZEPREFIXDEPRECATED = 64;
+
+ [Obsolete]
public const int VINDEXDEPRECATED = 178;
- ///
- /// DLLBind(Name)
- ///
+ [Obsolete]
public const int VDLLBIND = 655;
- ///
- /// New class modifier "ClassGroup(Name[,Name])"
- ///
+ [Obsolete]
public const int VCLASSGROUP = 789;
+ [Obsolete]
+ public const int VCOOKEDPACKAGES = 277;
+
public uint Version => Summary.Version;
///
@@ -1422,7 +1436,7 @@ public void Deserialize(IUnrealStream stream)
[PublicAPI] public NativesTablePackage NTLPackage;
- [Obsolete("See UPackageStream.Decoder")]
+ [Obsolete("See UPackageStream.Decoder", true)]
public IBufferDecoder Decoder;
#endregion
@@ -1686,7 +1700,7 @@ public void InitializeExportObjects(InitFlags initFlags = InitFlags.All)
/// Constructs all import objects.
///
/// If TRUE initialize all constructed objects.
- [PublicAPI]
+ [Obsolete("Pending deprecation")]
public void InitializeImportObjects(bool initialize = true)
{
Objects = new List(Imports.Count);
@@ -1712,6 +1726,7 @@ public void InitializePackage(InitFlags initFlags = InitFlags.All)
return;
}
+ ConstructObjects();
if ((initFlags & InitFlags.Deserialize) == 0)
return;
@@ -2091,30 +2106,30 @@ public UObject FindObjectByGroup(string objectGroup)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsConsoleCooked()
{
- return Summary.PackageFlags.HasFlag(Flags.PackageFlags.Cooked)
+ return Summary.PackageFlags.HasFlag(PackageFlag.Cooked)
&& CookerPlatform == BuildPlatform.Console;
}
///
- /// Checks whether this package is marked with @flag.
+ /// Checks whether this package is marked with @flags.
///
- /// The enum @flag to test.
+ /// The enum @flag to test.
/// Whether this package is marked with @flag.
- [Obsolete]
- public bool HasPackageFlag(PackageFlags flag)
+ [Obsolete("See Summary.PackageFlags.HasFlag")]
+ public bool HasPackageFlag(PackageFlags flags)
{
- return (PackageFlags & (uint)flag) != 0;
+ return Summary.PackageFlags.HasFlags((uint)flags);
}
///
- /// Checks whether this package is marked with @flag.
+ /// Checks whether this package is marked with @flags.
///
- /// The uint @flag to test
+ /// The uint @flag to test
/// Whether this package is marked with @flag.
- [Obsolete]
- public bool HasPackageFlag(uint flag)
+ [Obsolete("See Summary.PackageFlags.HasFlag")]
+ public bool HasPackageFlag(uint flags)
{
- return (PackageFlags & flag) != 0;
+ return (PackageFlags & flags) != 0;
}
///
@@ -2124,7 +2139,7 @@ public bool HasPackageFlag(uint flag)
[Obsolete]
public bool IsCooked()
{
- return Summary.PackageFlags.HasFlag(Flags.PackageFlags.Cooked);
+ return Summary.PackageFlags.HasFlag(PackageFlag.Cooked);
}
///
@@ -2134,7 +2149,7 @@ public bool IsCooked()
[Obsolete]
public bool IsMap()
{
- return Summary.PackageFlags.HasFlag(Flags.PackageFlags.ContainsMap);
+ return Summary.PackageFlags.HasFlag(PackageFlag.ContainsMap);
}
///
@@ -2144,7 +2159,7 @@ public bool IsMap()
[Obsolete]
public bool IsScript()
{
- return Summary.PackageFlags.HasFlag(Flags.PackageFlags.ContainsScript);
+ return Summary.PackageFlags.HasFlag(PackageFlag.ContainsScript);
}
///
@@ -2154,7 +2169,7 @@ public bool IsScript()
[Obsolete]
public bool IsDebug()
{
- return Summary.PackageFlags.HasFlag(Flags.PackageFlags.ContainsDebugData);
+ return Summary.PackageFlags.HasFlag(PackageFlag.ContainsDebugData);
}
///
@@ -2164,7 +2179,7 @@ public bool IsDebug()
[Obsolete]
public bool IsStripped()
{
- return Summary.PackageFlags.HasFlag(Flags.PackageFlags.StrippedSource);
+ return Summary.PackageFlags.HasFlag(PackageFlag.StrippedSource);
}
///
@@ -2174,13 +2189,13 @@ public bool IsStripped()
[Obsolete]
public bool IsEncrypted()
{
- return Summary.PackageFlags.HasFlag(Flags.PackageFlags.Encrypted);
+ return Summary.PackageFlags.HasFlag(PackageFlag.Encrypted);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool ContainsEditorData()
{
- return Summary.UE4Version > 0 && !Summary.PackageFlags.HasFlag(Flags.PackageFlags.FilterEditorOnly);
+ return Summary.UE4Version > 0 && !Summary.PackageFlags.HasFlag(PackageFlag.FilterEditorOnly);
}
#region IBuffered
diff --git a/src/UnrealStream.cs b/src/UnrealStream.cs
index 7cf8006a..e0657f2e 100644
--- a/src/UnrealStream.cs
+++ b/src/UnrealStream.cs
@@ -685,7 +685,7 @@ public void Record(string varName, object varObject = null)
///
/// Methods that shouldn't be duplicated between UObjectStream and UPackageStream.
///
- [Obsolete("Don't use directly, in 2.0 these are implemented once in a single shared IUnrealStream")]
+ [Obsolete("Pending deprecation")]
public static class UnrealStreamImplementations
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]