-
-
Notifications
You must be signed in to change notification settings - Fork 86
Usage
Eliot edited this page Aug 5, 2022
·
3 revisions
var package = UnrealLoader.LoadPackage(@"C:\Path\Package.upk", System.IO.FileAccess.Read);
Console.WriteLine($"Version: {package.Summary.Version}");
Loading a package does not come with loaded objects by default, to do so we can call a helper method to initialize all objects:
// Initializes the registered classes, constructs and deserializes(loads) the package objects.
package.InitializePackage();
// Now we can iterate all loaded objects, but beware! This includes fake-import objects.
foreach (var obj in package.Objects)
{
Console.WriteLine($"Name: {obj.Name}");
Console.WriteLine($"Class: {obj.Class?.Name}");
Console.WriteLine($"Outer: {obj.Outer}");
}
By default the call to InitializePackage() class will register all compile-time defined UnrealClasses, but say we want to add support for an UnrealClass ourselves, then we'll have to register the specialized type before we initialize the package.
var package = UnrealLoader.LoadPackage(@"C:\Path\Package.upk", System.IO.FileAccess.Read);
if (package != null)
{
package.AddClassType("UTexture2D", typeof(UTexture2D));
package.InitializePackage();
}
The class:
// An implementation for the UTexture2D class introduced in Unreal Engine 3.
// This class's implementation is fictional and does not represent the actual object's format.
// This is only to be used as an example.
public class UTexture2D : UObject
{
public int SomeInteger;
/**
* When a package is being initialized (i.e. InitializePackage()) each object will be constructed and begin its deserialization process.
* In this function we can handle the deserialization of the particular object.
* A class-wide _Buffer property is accessible within this method, giving you access to the entire object's stream.
*/
protected override void Deserialize()
{
// All UnrealClasses inherit the UObject's format, this may contain data like ScriptProperties(read DefaultProperties).
base.Deserialize();
// Here we can handle the format that could be specific to UTexture2D.
SomeInteger = _Buffer.ReadInt32();
// Record the field information.
// This is a helper function to record the data that we just read, this data can then be displayed in the "Hex Viewer" in UE Explorer.
Record(nameof(SomeInteger), SomeInteger);
}
/** This function is how UE Explorer grabs the text-output of an object. */
public override string Decompile()
{
return $"Sucessfully decompiled! \n\r We got some non exciting data: {SomeInteger}";
}
}
Say we instead want to implement a custom UnrealClass as part of the library itself, thanks to C# attributes we can do so easily by adding the UnrealRegisterClass attribute to the class's declaration.
Like so:
[UnrealRegisterClass]
public class UTexture2D : UObject
{
}
Just make sure that the class (.cs) file is part of the UELib solution!
Assuming we have a loaded package with the particular object of our type.
var myTextureObj = package.FindObject<UTexture2D>("Name of the texture object");
if(myTextureObj != null)
{
// Ensure that the object has been loaded by invoking the deserialization process.
myTextureObj.BeginDeserializing();
var output = myTextureObj.Decompile();
Console.WriteLine(output);
Console.WriteLine($"SomeInteger: {myTextureObj.SomeInteger}");
}