Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Duke Nukem Forever #49

Closed
vini1264 opened this issue Jul 31, 2022 · 17 comments
Closed

Support for Duke Nukem Forever #49

vini1264 opened this issue Jul 31, 2022 · 17 comments
Labels
game Game specific ue2

Comments

@vini1264
Copy link

vini1264 commented Jul 31, 2022

Hi, i saw this library for UnrealScripts and i would like to ask if it's possible to add support for decompiling Duke Nukem Forever .u scripts. I'm asking this because right now there's an ongoing project aiming to restore the level editor of the release version, the project is progressing really well and it already features a script compiler, but the actual script editing is missing, so would be nice to have a way to decompile DNF .u scripts. Here's the Github repo of the DNF 2011 Editor restoration:

https://github.com/jmarshall23/DNF-reimposition

@EliotVU
Copy link
Owner

EliotVU commented Aug 2, 2022

I'm not sure, isn't this Engine derivation heavily modified? Well I guess it depends on how much they modified the package's format. However I've tried one of the map .dnf files found in the rep you linked, which opened fine without any issues, so that's at least promising :)

I would need some .u files and the game's Core.dll to reverse the format, though I'm not promising anything.

@EliotVU EliotVU added game Game specific ue2 labels Aug 2, 2022
@jmarshall23
Copy link

jmarshall23 commented Aug 2, 2022

Hey Eliot,

I'm the author of the above repo, I have a pretty usable editor for Duke Nukem Forever. Core.dll in DNF was moved into Engine.dll which is in the depot linked above.

As an aside it would be awesome if we could get DNF .u scripts decompiled it would really open DNF 2011 modding :)

-Justin

@DaZombieKiller
Copy link
Contributor

@EliotVU DNF merges Core.dll and Render.dll into Engine.dll, so it's all in one big binary. Keep in mind that the Engine.dll the game ships with has CEG applied to it, which can complicate things if you intend to run or hook code inside it, but there is a version of the dll available with that removed. The actual package format is still very close to stock, and you can even get type information (functions do not decompile properly, of course) in UE explorer if the native tables from UDK are used.

Here is a CEG-free Engine.dll, and a few of the .u files (they are normally packaged inside a MegaPackage.dat blob): DNF.zip

@EliotVU
Copy link
Owner

EliotVU commented Aug 2, 2022

Thanks! It does indeed seem to be very close to the standard format :)

EliotVU added a commit that referenced this issue Aug 2, 2022
@EliotVU
Copy link
Owner

EliotVU commented Aug 2, 2022

Progress thus far:
image
However functions are still gibberish (for the most part).

@EliotVU
Copy link
Owner

EliotVU commented Aug 3, 2022

It's starting to look almost readable :)

function Weapon PickNextWeapon(Weapon PrimaryWeapons[4])
{
    local Weapon NextWeapon;
    local int DesiredIndex, i, ActualIndex;

    // End:0x16
    if(UnresolvedNativeFunction_129(Weapon, none))
    {
        DesiredIndex = 0;        
    }
    else
    {
        i = 0;
        J0x1D:

        // End:0x5E [Loop If]
        if(UnresolvedNativeFunction_169(i, 4))
        {
            // End:0x54
            if(UnresolvedNativeFunction_129(Weapon, PrimaryWeapons[i]))
            {
                DesiredIndex = UnresolvedNativeFunction_164(UnresolvedNativeFunction_165(i, 1), 4);
                // [Explicit Break]
                goto J0x5E;
            }
            UnresolvedNativeFunction_182(i);
            // [Loop Continue]
            goto J0x1D;
        }
    }
    J0x5E:

    // End:0x84
    if(UnresolvedNativeFunction_129(PrimaryWeapons[DesiredIndex], none))
    {
        NextWeapon = PrimaryWeapons[DesiredIndex];        
    }
    else
    {
        i = 0;
        J0x8B:

        // End:0xDD [Loop If]
        if(UnresolvedNativeFunction_169(i, 4))
        {
            ActualIndex = UnresolvedNativeFunction_164(UnresolvedNativeFunction_165(i, DesiredIndex), 4);
            // End:0xD3
            if(UnresolvedNativeFunction_129(PrimaryWeapons[ActualIndex], none))
            {
                NextWeapon = PrimaryWeapons[ActualIndex];
                // [Explicit Break]
                goto J0xDD;
            }
            UnresolvedNativeFunction_182(i);
            // [Loop Continue]
            goto J0x8B;
        }
    }
    J0xDD:

    return NextWeapon;
    return;
}

@DaZombieKiller
Copy link
Contributor

Nice! You got that going impressively fast. If you want some more samples but don't own the game, the demo version of DNF is available for download here. You'll need to use my tool or Noesis to extract MegaPackage.dat and get the .u files out.

@EliotVU
Copy link
Owner

EliotVU commented Aug 5, 2022

@DaZombieKiller Thanks, I'll check it out.

@JoshSocial np, you're welcome!

DNF's is fully decompilable now:

function Weapon PickNextWeapon(Weapon PrimaryWeapons[4])
{
    local Weapon NextWeapon;
    local int DesiredIndex, i, ActualIndex;

    // End:0x16
    if(Weapon == none)
    {
        DesiredIndex = 0;        
    }
    else
    {
        i = 0;
        J0x1D:

        // End:0x5E [Loop If]
        if(i < 4)
        {
            // End:0x54
            if(Weapon == PrimaryWeapons[i])
            {
                DesiredIndex = (i + 1) % 4;
                // [Explicit Break]
                goto J0x5E;
            }
            ++ i;
            // [Loop Continue]
            goto J0x1D;
        }
    }
    J0x5E:

    // End:0x84
    if(PrimaryWeapons[DesiredIndex] != none)
    {
        NextWeapon = PrimaryWeapons[DesiredIndex];        
    }
    else
    {
        i = 0;
        J0x8B:

        // End:0xDD [Loop If]
        if(i < 4)
        {
            ActualIndex = (i + DesiredIndex) % 4;
            // End:0xD3
            if(PrimaryWeapons[ActualIndex] != none)
            {
                NextWeapon = PrimaryWeapons[ActualIndex];
                // [Explicit Break]
                goto J0xDD;
            }
            ++ i;
            // [Loop Continue]
            goto J0x8B;
        }
    }
    J0xDD:

    return NextWeapon;
    return;
}

DNF has also extended UnrealScript's features (or at least how it's compiled), those features have also been implemented, but however the syntax is likely off!

@DaZombieKiller
Copy link
Contributor

Wow, I never thought I'd see the day. Awesome work!

DNF has also extended UnrealScript's features (or at least how it's compiled), those features have also been implemented, but however the syntax is likely off!

As far as I can tell the UnrealScript compiler is still intact within the libraries, how complex do you think it would be to recover the intended syntax through that without needing to reverse engineer the entire parser?

@jmarshall23
Copy link

Great work! Never thought I would see this happen. I hate to ask but would it be possible to get a binary of this with UE-Explorer?

@EliotVU
Copy link
Owner

EliotVU commented Aug 7, 2022

@DaZombieKiller I've looked abit at the Editor.dll but couldn't retrieve the names, they are imported from the DNCommon.dll. Nor the did the parser code that handles the "vect" constant seem to have any other names (which I did assume based on the existence of the VectorX/Y/Z tokens). Oh well they might be out there somewhere but it's not something I'll be looking into a.t.m.

@EliotVU
Copy link
Owner

EliotVU commented Aug 7, 2022

@jmarshall23 I will, but the current UELib 'develop' branch is incompatible with the current release of UE Explorer, I've tried to merge them to a compatible branch but no success. Therefor the release is currently blocked until the next release of UE Explorer.

I'll try to get a preview build ready to release in this thread asap.

@EliotVU
Copy link
Owner

EliotVU commented Aug 12, 2022

p.s. Some property tags fail to decompile, such as arrays of UObjects, among some other types. I'll fix these first if possible (i.e. not dependent on package linking)

@jmarshall23
Copy link

That would awesome if we could those working! I have the DNF 2011 UnrealScript compiler completely working, right now I have it so it can build my new mod uc package only, because the decompiled stuff isn't compilable yet, but we've be able to do some cool stuff just using the decompiled scripts as reference:

https://github.com/jmarshall23/DNF-reimposition/tree/main/dnModIce/Classes

Like we've been able to create a new console class and fully re-enable the dev console. We've been able to make new monsters as well.

It would be really awesome if we were able to get the scripts to a point were they could just be recompiled, that would really open the door to some cool stuff.

@EliotVU
Copy link
Owner

EliotVU commented Aug 22, 2022

@jmarshall23 Great stuff! Yes that would be awesome, I'm not sure if this will ever reach a 100% without any manual editing, but we're getting close here!

p.s. https://github.com/UE-Explorer/UE-Explorer/releases/tag/Release-DNF_Preview

@DaZombieKiller
Copy link
Contributor

DaZombieKiller commented Jun 27, 2024

I've been looking into DNF a bit more recently, and I just wanted to mention that the unknown specifier mentioned here is FUNC_Exec | FUNC_DevExec. FUNC_DevExec prevents an exec function from being invokable through the console unless the game is a development build.

I should also note that while DNF inherits UE2's implementation of delegates, some of the values are a bit different. FUNC_Delegate in DNF is actually 0x400000 rather than 0x100000 for example.

Expression token 0x37 also appears to be something other than UE2's EX_DynArrayLength, it is undefined in the 2001 source so I don't have an authoritative name for it. I am not sure what its purpose is yet, but (EDIT: Ah, from checking more recent UELib code I see you've already figured that one out: EX_DebugInfo, another thing inherited from UE2 with a different value.)

@EliotVU
Copy link
Owner

EliotVU commented Aug 13, 2024

Closing this one with #85, it's gotten stale, and support for DNF has been out for a while now even if it's not perfect.

Feel free to open a new issue for any particular issue with DNF.

@EliotVU EliotVU closed this as completed Aug 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
game Game specific ue2
Projects
None yet
Development

No branches or pull requests

5 participants
@EliotVU @DaZombieKiller @jmarshall23 @vini1264 and others