GithubHelp home page GithubHelp logo

orvid / champollion Goto Github PK

View Code? Open in Web Editor NEW
100.0 13.0 20.0 630 KB

A PEX to Papyrus Decompiler for Skyrim, Fallout 4 and Starfield

License: GNU Lesser General Public License v3.0

C++ 97.47% Batchfile 0.46% CMake 2.07%

champollion's Introduction

Champollion

Champollion is a decompiler for the Papyrus script language used in Skyrim, Fallout 4, Fallout 76, and Starfield. It aims to produce a Papyrus Script file (.psc) from a .pex binary file. The decompiled script should recompile to a functionally equivalent PEX binary.

Usage

Champollion is a CLI-only program.

Parameters

Champollion <files or directories> [-p <output directory>] [-a [<assembly directory>]] [-c] [-t]

Short Long Description
-p output directory --psc output directory Set the output directory, where Champollion will write the decompiled files
-a [assembly directory] --asm [assembly directory] Champollion will write an assembly version of the PEX file in the given directory, if one. The assembly file is an human readable version of the content of the PEX file
-c --comment The decompiled file will be annotated with the assembly instruction corresponding to the decompiled code lines.
-t --threaded Champollion will parallelize the decompilation. It is useful when decompiling a directory containing many PEX files.
-r --recursive Recursively scan specified directory(s) for pex files to decompile
-s --recreate-subdirs Recreates directory structure for script in root of output directory (Fallout 4 only, default false)
-e --header Write header to decompiled psc file
-g --trace Trace the decompilation and output results to rebuild log
--no-dump-tree Do not dump tree for each node during decompilation tracing (requires --trace)
--debug-funcs Decompile inoperative debug and compiler-generated functions (default false)
--no-debug-line Do not comment with debug info line numbers on script lines (default false)
-i --print-info Print header info from the specified PEX file(s) and exit
--print-compile-time Print the compile time of the script in format of {filename}: {time_integer} and exit
-v --verbose Verbose output
-V --version Output version number
-h --help Print help message

Build Dependencies

  • Boost (installable through vcpkg)
  • CMake
  • A C++17 compiler (for Windows you need at least Visual Studio 2019)

Copyright

Copyright (c) 2022 Nikita Lita

Copyright (c) 2015 Orvid King

Copyright (c) 2013 Paul-Henry Perrin

See LICENSE for the LGPL V3 license.

champollion's People

Contributors

fireundubh avatar infomaniac50 avatar nikitalita avatar orvid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

champollion's Issues

Ensure that Array_GetAllMatchingStructs is correct

Array_GetAllMatchingStructs was added a while back because it was in Fallout76, and the person who added it said that they had no idea how it worked. As far as I know, Fallout76 never released the script sources for any of the scripts, so we had no way of verifying what the syntax is. So, we should ensure we have the correct syntax for this in addition to the new guards opcodes for Starfield.

complex expressions problem

program have problems with bracket:
f = (a + b) - (c+ d)
decompile like
f = a + b - c+ d

this easy example. For real example need decompile difficult script, like _frost_exposuresystem from Frosfall. After decompilling and compilling this script not work correct.

Champollion truncates .psc

From the forums: I'm hitting a bug where compiling a script and decompiling it again truncates the .psc. I think it's Champollion, and the .pex from Caprica is correct (judging by file size).

Steps to reproduce:
Decompile workshopscript.pex
Add a Debug.Trace("Stuff", 0) call (at line 315, but shouldn't matter. Do it early)
Compile the edited .psc
Decompile the resulting .pex
Truncates mid-variable name at line 443.

Starfield decompile error with script compiled with Caprica

Script compiled with Caprica v0.3.0
Papryrus VM error: warning: Assigning None to a non-object variable named "::temp1"
Attempted decompiled with Champollion v1.3.2 but got error Orphaned nodes in GetActionControl from instruction 14 to 14

Line (568) in question from the script is: lkItem.Activate( akLooter, False )

Not sure what other information I can provide.

Attached zip contains the script (source and compiled).
LootFunctions.zip

Champollion not decompiling floats correctly.

Posted on Nexus: https://www.nexusmods.com/skyrimspecialedition/mods/75248?tab=bugs&BH=0

I observed the new Champollion that you added isn't decompiling floats correctly on my end. They are decompiled as integers in the scripts and throw errors soon after in the process as the papyrus compiler tries to build.

I fixed it by switching out the Champollion with another in nexus. Namely this one: https://www.nexusmods.com/skyrim/mods/35307

EDIT: I couldnt obtain the error output because the compiler never crashes and indefinitely hangs accumulating memory in the background.

Tag Fallout4's custom events

Find a way to tag Fallout4's custom events
From #7 :

If a better analysis is needed, it would be worth extending that to FO4's custom events, as they are not currently recorded anywhere in the pex, so you just have to find what places manually invoke the custom event and make sure to emit that event.

Fix Event tagging

We currently determine whether or not to flag events based on whether or not they start with "On". This can lead to non-event functions being tagged as events, such as "OnlyDoIf". We need to implement proper analysis on whether or not a function is an event for both skyrim and fallout4.

Potential to upload as a DLL for ESLify Everything

Hello nikitalita been a while.

I am writing today to ask if you could upload a separate version of Champollion as a just a DLL, preferably with a .pdb, without converting it to a executable.

I am try to solve the ESLify Everything false positive virus flag that prevents me from uploading ESLify Everything to the Nexus. I only have a few potential solutions but this is the most promising to me.

Failing for compiling Papyrus script using ELSifyEverything

Here's a manual list of issues I'm seeing when trying to recompile with the tool.

(base) PS E:> cd '.\SteamLibrary\steamapps\common\Skyrim Special Edition\Papyrus Compiler'
(base) PS E:\SteamLibrary\steamapps\common\Skyrim Special Edition\Papyrus Compiler> .\PapyrusCompiler.exe "D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ChangedScripts" -q -f="TESV_Papyrus_Flags.flg" -a -i="D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts" -o="F:\Skyrim Special Edition - Latest Build\mods\ESLify Everything - Outputs\Scripts"
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts\SKI_ConfigBase.psc(10,30): no viable alternative at input '_currentPage'
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts\SKI_ConfigBase.psc(14,32): no viable alternative at input '_textBuf'
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts\SKI_ConfigBase.psc(14,41): required (...)+ loop did not match anything at input 'AutoReadOnly'
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts\SKI_ConfigBase.psc(14,9): Unknown user flag _textBuf
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(642,15): UnregisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(691,7): SendModEvent is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(692,7): UnregisterForAnimationEvent is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(697,9): UnregisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(701,9): UnregisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(705,9): UnregisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(709,9): UnregisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(713,9): UnregisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1322,7): UnregisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1323,7): UnregisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1324,7): UnregisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1325,7): UnregisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1326,7): UnregisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1328,9): RegisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1331,9): RegisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1334,9): RegisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1337,9): RegisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1340,9): RegisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1408,7): SendModEvent is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1538,7): UnregisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1539,7): UnregisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1540,7): UnregisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1541,7): UnregisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1549,13): SendModEvent is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1552,13): SendModEvent is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1556,15): SendModEvent is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1597,19): RegisterForSingleUpdate is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1601,19): RegisterForSingleUpdate is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1622,13): SendModEvent is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1624,11): RegisterForAnimationEvent is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1639,9): RegisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1642,9): RegisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1645,9): RegisterForKey is not a function or does not exist
D:\Modding Tools\SSEEdit\SSEEdit 4.0.4\ESLifyEverything\ExtractedBSAModData\Source\Scripts_snskyuiconfig.psc(1648,9): RegisterForKey is not a function or does not exist
No output generated for _sndlcquestscript.psc, compilation failed.

Precedence while casting bug

Apparent bug.

Compiling the following statement:
Float x = 1000.00 / (y as Float * 60.0)
And then de-compiling yields source without the parentheses:
Float x = 1000.00 / y as Float * 60.0

So, if y==6, you get 10,000 instead of 2.7778

I haven't tested to see if this just happens when converting ints to floats or if it's wrong for every divide/multiply.
This was seen with the executable from the Nexus Skyrim mod page https://www.nexusmods.com/skyrim/mods/35307.

Skyrim event functions, named events, instead of function. Causing Papyrus Compiler to not compile it.

What this decompiles FISSFactory into:


;-- Functions ---------------------------------------

FISSInterface Function getFISS() Global
  Return Game.GetFormFromFile(4804, "fiss.esp") as FISSInterface
EndFunction

; Skipped compiler generated GetState

Event onEndState()
{ Event received when this state is switched away from }
  ; Empty function
EndEvent

; Skipped compiler generated GotoState

Event onBeginState()
{ Event received when this state is switched to }
  ; Empty function
EndEvent

What the original Champollion decompiles into:

scriptName fissfactory

;-- Properties --------------------------------------

;-- Variables ---------------------------------------

;-- Functions ---------------------------------------

FISSInterface function getFISS() global

	return game.GetFormFromFile(2048, "FISS.esp") as FISSInterface
endFunction

; Skipped compiler generated GotoState

function onBeginState()
{Event received when this state is switched to}

	; Empty function
endFunction

; Skipped compiler generated GetState

function onEndState()
{Event received when this state is switched away from}

	; Empty function
endFunction

The original Champollion decompiles it into its original source code, minus comments. the capitalization isn't a problem.
I have a long command line for Papyrus Compiler because its automated in ESLify Everything.

C:\Steam\steamapps\common\Skyrim Special Edition\Papyrus Compiler>PapyrusCompiler.exe "C:\Modding\SkyrimSE\ESLifyEveryth
ing\ESLifyEverything\bin\Personal\net6.0\ChangedScripts" -q -f="TESV_Papyrus_Flags.flg" -a -i="C:\Modding\SkyrimSE\ESLif
yEverything\ESLifyEverything\bin\Personal\net6.0\ExtractedBSAModData\Source\Scripts" -o="E:\SkyrimMods\MO2\mods\ESLify E
verything\Scripts"
C:\Modding\SkyrimSE\ESLifyEverything\ESLifyEverything\bin\Personal\net6.0\ExtractedBSAModData\Source\Scripts\fissfactory
.psc(14,0): no viable alternative at input 'EndEvent'
C:\Modding\SkyrimSE\ESLifyEverything\ESLifyEverything\bin\Personal\net6.0\ExtractedBSAModData\Source\Scripts\fissfactory
.psc(21,0): no viable alternative at input 'EndEvent'
No output generated for fissfactory.psc, compilation failed.

Changing "Event" and "EndEvent" to "Function" and "EndFunction" fixes the issue but its necessary in all of the scripts

Skyrim just uses the function identifier instead of Event for events.

I am hoping to switch ESLify Everything to using this instead of the original Champollion.

Version number

Using Champollion.v1.3.0.zip
champollion.exe --version reports v1.2.2

Invalid String Index

When trying to use Champollion to decompile a pex file from Starfield I'm getting an Invalid String Index error for every file.

Freezing while trying to decompile custom .pex

I was trying to decompile the script attached to OCDecorator out of curiosity, and Champollion froze. No crash or error message. Not sure if this is an issue with Champollion or the script, or if you're planning to support custom .pex, so I'll leave this here for you to decide if you want to deal with it.

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.