Skip to content

Commit

Permalink
Finish 1.5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
EliotVU committed Apr 7, 2024
2 parents 3e78754 + d4aca85 commit 63d07b7
Show file tree
Hide file tree
Showing 15 changed files with 158 additions and 31 deletions.
9 changes: 4 additions & 5 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ name: Build .NET Framework and Publish to NuGet
on:
workflow_dispatch:
push:
tags:
- 'release-*'
- 'hotfix-*'
tags:
- '^[0-9]+\.[0-9]+\.[0-9]+$'

jobs:
build:
Expand All @@ -18,13 +17,13 @@ jobs:
uses: microsoft/[email protected]

- name: Setup NuGet
uses: NuGet/setup-nuget@v1
uses: NuGet/setup-nuget@v2

- name: Restore dependencies
run: nuget restore src/Eliot.UELib.csproj

- name: Build
run: msbuild src/Eliot.UELib.csproj -t:rebuild -property:Configuration=Publish
run: msbuild src/Eliot.UELib.csproj -t:rebuild -property:Configuration=Remease

- name: Publish Eliot.UELib
uses: alirezanet/[email protected]
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
with:
# Legacy versions not supported? :(
# 5.0 will likely not work yet due legacy dependencies...
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# [1.5.0](https://github.com/EliotVU/Unreal-Library/releases/tag/1.5.0)

* 1ef135d Improved support for A Hat in Time (UE3), contributed by @Un-Drew

# [1.4.0](https://github.com/EliotVU/Unreal-Library/releases/tag/1.4.0)

Notable changes that affect UnrealScript output:
Expand Down
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,18 @@ Its main purpose is to decompile the UnrealScript byte-code to its original sour

It accomplishes this by reading the necessary Unreal data classes such as:

UObject, UField, UConst, UEnum, UProperty, UStruct, UFunction, UState,
UClass, UTextBuffer, UMetaData, UFont, USound, UPackage
UObject, UField, UConst, UEnum, UProperty, UStruct, UFunction, UState, UClass,
UTextBuffer, UMetaData, UPackage

Classes such as UStruct, UState, UClass, and UFunction contain the UnrealScript byte-code which we can deserialize in order to re-construct the byte-codes to its original UnrealScript source.

Additionally UELib is also capable of deserializing of many more data classes such as:

UFont, USound, UPalette, UTexture,
UTexture2D, UTexture2DDynamic, UTexture2DComposite, UTexture3D,
UTextureCube, UTextureFlipBook, UTextureMovie
UPrimitive, UPolys

## How to use

To use this library you will need [.NET Framework 4.8](https://dotnet.microsoft.com/en-us/download/dotnet-framework/net48) (The library will move to .NET 6 or higher at version 2.0)
Expand Down Expand Up @@ -178,6 +185,7 @@ This is a table of games that are confirmed to be compatible with the current st
| Orcs Must Die! Unchained | 20430 | 870/000 | |
| Gal\*Gun: Double Peace | 10897 | 871/000 | |
| [Might & Magic Heroes VII](https://en.wikipedia.org/wiki/Might_%26_Magic_Heroes_VII) | 12161 | 868/004 | (Signature and custom features are not supported)
| A Hat in Time | 12097 | 877-893/005 | |
| Shadow Complex Remastered | 10897 | 893/001 | |
| Soldier Front 2 | 6712 | 904/009 | |
| Rise of the Triad | 10508 | Unknown | |
Expand Down
2 changes: 2 additions & 0 deletions src/Branch/DefaultEngineBranch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,8 @@ protected override TokenMap BuildTokenMap(UnrealPackage linker)
tokenMap[0x4F] = typeof(LocalVariableToken<bool>);
tokenMap[0x50] = typeof(LocalVariableToken<UObject>);
tokenMap[0x51] = typeof(LocalVariableToken<dynamic>);

tokenMap[0x5B] = typeof(ByteConstToken);
break;
#endif
#if BIOSHOCK
Expand Down
22 changes: 21 additions & 1 deletion src/Core/Classes/Props/UPropertyDecompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,22 @@ public string FormatFlags()
output += "serializetext ";
copyFlags &= ~(ulong)Flags.PropertyFlagsLO.SerializeText;
}

#if AHIT
if (Package.Build == UnrealPackage.GameBuild.BuildName.AHIT)
{
if (HasPropertyFlag(Flags.PropertyFlagsHO.AHIT_Serialize))
{
output += "serialize ";
copyFlags &= ~(ulong)Flags.PropertyFlagsHO.AHIT_Serialize << 32;
}
if (HasPropertyFlag(Flags.PropertyFlagsLO.AHIT_Bitwise))
{
output += "bitwise ";
copyFlags &= ~(ulong)Flags.PropertyFlagsLO.AHIT_Bitwise;
}
}
#endif
}

if ((PropertyFlags & (ulong)Flags.PropertyFlagsLO.Native) != 0)
Expand Down Expand Up @@ -393,7 +409,11 @@ public string FormatFlags()
}
}

if ((PropertyFlags & (ulong)Flags.PropertyFlagsLO.EdFindable) != 0)
if ((PropertyFlags & (ulong)Flags.PropertyFlagsLO.EdFindable) != 0
#if AHIT
&& Package.Build != UnrealPackage.GameBuild.BuildName.AHIT
#endif
)
{
copyFlags &= ~(ulong)Flags.PropertyFlagsLO.EdFindable;
output += "edfindable ";
Expand Down
10 changes: 10 additions & 0 deletions src/Core/Classes/UClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,16 @@ protected override void Deserialize()
Record(nameof(classGeneratedBy), classGeneratedBy);
}
#endif

#if AHIT
if (Package.Build == UnrealPackage.GameBuild.BuildName.AHIT && _Buffer.Version >= 878)
{
// AHIT auto-generates a list of unused function names for its optional interface functions.
// Seems to have been added in 878, during the modding beta between 1.Nov.17 and 6.Jan.18.
DeserializeGroup("UnusedOptionalInterfaceFunctions");
}
#endif

if (!Package.IsConsoleCooked() && !Package.Build.Flags.HasFlag(BuildFlags.XenonCooked))
{
if (_Buffer.Version >= 603 && _Buffer.UE4Version < 113
Expand Down
14 changes: 14 additions & 0 deletions src/Core/Classes/UClassDecompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,20 @@ private string FormatFlags()
}
#endif

#if AHIT
if (Package.Build == UnrealPackage.GameBuild.BuildName.AHIT)
{
if ((ClassFlags & (uint)Flags.ClassFlags.AHIT_AlwaysLoaded) != 0)
{
output += "\r\n\tAlwaysLoaded";
}
if ((ClassFlags & (uint)Flags.ClassFlags.AHIT_IterOptimized) != 0)
{
output += "\r\n\tIterationOptimized";
}
}
#endif

output += FormatNameGroup("classgroup", ClassGroups);
output += FormatNameGroup("autoexpandcategories", AutoExpandCategories);
output += FormatNameGroup("autocollapsecategories", AutoCollapseCategories);
Expand Down
35 changes: 34 additions & 1 deletion src/Core/Classes/UFunctionDecompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,34 @@ private string FormatFlags()
{
output += "noexport ";
}

#if AHIT
if (Package.Build == UnrealPackage.GameBuild.BuildName.AHIT)
{
if (HasFunctionFlag(Flags.FunctionFlags.AHIT_Optional))
{
output += "optional "; // optional interface functions use this.
}

if (HasFunctionFlag(Flags.FunctionFlags.AHIT_Multicast))
{
output += "multicast ";
}

if (HasFunctionFlag(Flags.FunctionFlags.AHIT_NoOwnerRepl))
{
output += "NoOwnerReplication ";
}
}
#endif

// FIXME: Version, added with one of the later UDK builds.
if (Package.Version >= 500)
if (Package.Version >= 500
#if AHIT
// For AHIT, don't write these K2 specifiers, since they overlap with its custom flags.
&& Package.Build != UnrealPackage.GameBuild.BuildName.AHIT
#endif
)
{
if (HasFunctionFlag(Flags.FunctionFlags.K2Call))
{
Expand Down Expand Up @@ -212,6 +237,14 @@ private string FormatFlags()
output += "function ";
}

#if AHIT
// Needs to be after function/event/operator/etc.
if (Package.Build == UnrealPackage.GameBuild.BuildName.AHIT && HasFunctionFlag(Flags.FunctionFlags.AHIT_EditorOnly))
{
output += "editoronly ";
}
#endif

return output;
}

Expand Down
2 changes: 2 additions & 0 deletions src/Core/Classes/UStruct.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ public partial class UStruct : UField
//protected uint _CodePosition;

public long ScriptOffset { get; private set; }
public int ScriptSize { get; private set; }

public UByteCodeDecompiler ByteCodeManager;

Expand Down Expand Up @@ -233,6 +234,7 @@ protected override void Deserialize()
}

_Buffer.ConformRecordPosition();
ScriptSize = (int)(_Buffer.Position - ScriptOffset);
#if DNF
if (Package.Build == UnrealPackage.GameBuild.BuildName.DNF)
{
Expand Down
23 changes: 12 additions & 11 deletions src/Core/Tokens/ContextTokens.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,32 +110,33 @@ public override void Deserialize(IUnrealStream stream)
Debug.Assert(Struct != null);
}
#endif
// TODO: Corrigate version. Definitely didn't exist in Roboblitz(369)
if (stream.Version > 369)
// TODO: Corrigate version. Definitely didn't exist in Roboblitz(369), first seen in MOHA(421).
if (stream.Version > 374)
{
Struct = stream.ReadObject<UStruct>();
Decompiler.AlignObjectSize();
Debug.Assert(Struct != null);
#if MKKE
if (Package.Build != UnrealPackage.GameBuild.BuildName.MKKE)
if (Package.Build == UnrealPackage.GameBuild.BuildName.MKKE)
{
#endif
// Copy?
stream.ReadByte();
Decompiler.AlignSize(sizeof(byte));
#if MKKE
goto skipToNext;
}
#endif
// Copy?
stream.ReadByte();
Decompiler.AlignSize(sizeof(byte));
}
// TODO: Corrigate version. Definitely didn't exist in MKKE(472), first seen in SWG(486).
if (stream.Version > 472)

// TODO: Corrigate version. Definitely didn't exist in MKKE(472), first seen in FFOW(433).
if (stream.Version >= 433)
{
// Modification?
stream.ReadByte();
Decompiler.AlignSize(sizeof(byte));
}

skipToNext:

// Pre-Context
DeserializeNext();
}
Expand Down
9 changes: 5 additions & 4 deletions src/Eliot.UELib.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<DefineConstants>DECOMPILE;BINARYMETADATA;Forms;UE1;UE2;UE3;UE4;VENGEANCE;SWAT4;UNREAL2;INFINITYBLADE;BORDERLANDS2;GOW2;APB;SPECIALFORCE2;XIII;SINGULARITY;THIEF_DS;DEUSEX_IW;BORDERLANDS;MIRRORSEDGE;BIOSHOCK;HAWKEN;UT;DISHONORED;REMEMBERME;ALPHAPROTOCOL;VANGUARD;TERA;MKKE;TRANSFORMERS;XCOM2;DD2;DCUO;AA2;SPELLBORN;BATMAN;MOH;ROCKETLEAGUE;DNF;LSGAME;UNDYING;HP;DEVASTATION;SPLINTERCELL</DefineConstants>
<DefineConstants>DECOMPILE;BINARYMETADATA;Forms;UE1;UE2;UE3;UE4;VENGEANCE;SWAT4;UNREAL2;INFINITYBLADE;BORDERLANDS2;GOW2;APB;SPECIALFORCE2;XIII;SINGULARITY;THIEF_DS;DEUSEX_IW;BORDERLANDS;MIRRORSEDGE;BIOSHOCK;HAWKEN;UT;DISHONORED;REMEMBERME;ALPHAPROTOCOL;VANGUARD;TERA;MKKE;TRANSFORMERS;XCOM2;DD2;DCUO;AA2;SPELLBORN;BATMAN;MOH;ROCKETLEAGUE;DNF;LSGAME;UNDYING;HP;DEVASTATION;SPLINTERCELL;AHIT</DefineConstants>
<TargetFramework>net48</TargetFramework>
<OutputType>Library</OutputType>
<RootNamespace>UELib</RootNamespace>
Expand Down Expand Up @@ -32,6 +32,7 @@
<CodeAnalysisRuleSet>GlobalizationRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<DebugType>none</DebugType>
<DefineConstants>$(DefineConstants);TRACE;</DefineConstants>
<UseVSHostingProcess>true</UseVSHostingProcess>
Expand Down Expand Up @@ -70,10 +71,9 @@
</ItemGroup>
<ProjectExtensions></ProjectExtensions>
<PropertyGroup>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<AssemblyName>Eliot.UELib</AssemblyName>
<PackageId>$(AssemblyName)</PackageId>
<Version>$(VersionPrefix)1.4.0</Version>
<Version>$(VersionPrefix)1.5.0</Version>
<Authors>EliotVU</Authors>
<Title>$(AssemblyName)</Title>
<PackageDescription>UnrealScript decompiler library for Unreal package files (.upk, .u, .uasset; etc), with support for Unreal Engine 1, 2, and 3.</PackageDescription>
Expand All @@ -86,5 +86,6 @@
<EnableNETAnalyzers>True</EnableNETAnalyzers>
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
<AnalysisLevel>latest-recommended</AnalysisLevel>
<PackageReleaseNotes>Improved support for A Hat in Time (UE3)</PackageReleaseNotes>
</PropertyGroup>
</Project>
6 changes: 3 additions & 3 deletions src/Engine/Types/Poly.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public TResult Accept<TResult>(IVisitor<TResult> visitor)
public void Deserialize(IUnrealStream stream)
{
// Always 16
int numVertices = stream.Version < (uint)PackageObjectLegacyVersion.FixedVerticesToArrayFromPoly
int verticesCount = stream.Version < (uint)PackageObjectLegacyVersion.FixedVerticesToArrayFromPoly
? stream.ReadIndex()
: -1;

Expand All @@ -89,7 +89,7 @@ public void Deserialize(IUnrealStream stream)
}
else
{
stream.ReadArray(out Vertex, numVertices);
stream.ReadArray(out Vertex, verticesCount);
}

PolyFlags = stream.ReadUInt32();
Expand Down Expand Up @@ -170,4 +170,4 @@ public void Serialize(IUnrealStream stream)
throw new NotImplementedException();
}
}
}
}
17 changes: 17 additions & 0 deletions src/UnrealFlags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,12 @@ public enum FunctionFlags : ulong
K2Call = 0x04000000U,
K2Override = 0x08000000U,
K2Pure = 0x10000000U,
#if AHIT
AHIT_Multicast = 0x04000000U,
AHIT_NoOwnerRepl = 0x08000000U,
AHIT_Optional = 0x10000000U,
AHIT_EditorOnly = 0x20000000U,
#endif
}

/// <summary>
Expand Down Expand Up @@ -424,6 +430,9 @@ public enum FunctionFlags : ulong

EditInline = 0x04000000U,
EdFindable = 0x08000000U,
#if AHIT
AHIT_Bitwise = 0x08000000U,
#endif
EditInlineUse = 0x10000000U,
Deprecated = 0x20000000U,

Expand Down Expand Up @@ -472,6 +481,9 @@ public enum FunctionFlags : ulong
// GAP!
CrossLevelPassive = 0x00001000U,
CrossLevelActive = 0x00002000U,
#if AHIT
AHIT_Serialize = 0x00004000U,
#endif
#if BIOSHOCK
BIOINF_Unk1 = 0x00080000U,

Expand Down Expand Up @@ -530,6 +542,11 @@ public enum StateFlags : uint
CollapseCategories = 0x00002000U,
ExportStructs = 0x00004000U, // @Removed(UE3 in early but not latest)

#if AHIT
AHIT_AlwaysLoaded = 0x00008000U,
AHIT_IterOptimized = 0x00010000U,
#endif

Instanced = 0x00200000U, // @Removed(UE3)
HideDropDown = 0x00400000U, // @Redefined(UE3, HasComponents), @Moved(UE3, HideDropDown2)
ParseConfig = 0x01000000U, // @Redefined(UE3, Deprecated)
Expand Down
Loading

0 comments on commit 63d07b7

Please sign in to comment.