├── .gitignore
├── CoDLUIDecompiler.sln
├── CoDLUIDecompiler
├── App.config
├── CoDLUIDecompiler.csproj
├── Games
│ ├── BlackOps2.cs
│ ├── BlackOps3.cs
│ ├── Ghosts.cs
│ └── WorldWar2.cs
├── Lua
│ ├── Datatype.cs
│ ├── LuaCondition.cs
│ ├── LuaConstant.cs
│ ├── LuaFile.cs
│ ├── LuaFunction.cs
│ ├── LuaInstruction.cs
│ ├── LuaOpCode.cs
│ └── LuaRegister.cs
├── LuaRipper
│ ├── Games
│ │ ├── AdvancedWarfare.cs
│ │ ├── BlackOps2.cs
│ │ ├── BlackOps3.cs
│ │ ├── BlackOps4.cs
│ │ ├── Ghosts.cs
│ │ ├── InfiniteWarfare.cs
│ │ ├── ModernWarfareRM.cs
│ │ └── WorldWarII.cs
│ └── MemoryLoading.cs
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
└── Util
│ └── PhilLibX
│ ├── ByteUtil.cs
│ ├── IO
│ ├── IOExtensions.cs
│ ├── MemoryUtil.cs
│ └── ProcessReader.cs
│ ├── MathUtilities.cs
│ ├── NativeMethods.cs
│ └── Printer.cs
├── LICENSE
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Mono auto generated files
17 | mono_crash.*
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Dd]ebugPublic/
22 | [Rr]elease/
23 | [Rr]eleases/
24 | x64/
25 | x86/
26 | [Aa][Rr][Mm]/
27 | [Aa][Rr][Mm]64/
28 | bld/
29 | [Bb]in/
30 | [Oo]bj/
31 | [Ll]og/
32 |
33 | # Visual Studio 2015/2017 cache/options directory
34 | .vs/
35 | # Uncomment if you have tasks that create the project's static files in wwwroot
36 | #wwwroot/
37 |
38 | # Visual Studio 2017 auto generated files
39 | Generated\ Files/
40 |
41 | # MSTest test Results
42 | [Tt]est[Rr]esult*/
43 | [Bb]uild[Ll]og.*
44 |
45 | # NUnit
46 | *.VisualState.xml
47 | TestResult.xml
48 | nunit-*.xml
49 |
50 | # Build Results of an ATL Project
51 | [Dd]ebugPS/
52 | [Rr]eleasePS/
53 | dlldata.c
54 |
55 | # Benchmark Results
56 | BenchmarkDotNet.Artifacts/
57 |
58 | # .NET Core
59 | project.lock.json
60 | project.fragment.lock.json
61 | artifacts/
62 |
63 | # StyleCop
64 | StyleCopReport.xml
65 |
66 | # Files built by Visual Studio
67 | *_i.c
68 | *_p.c
69 | *_h.h
70 | *.ilk
71 | *.meta
72 | *.obj
73 | *.iobj
74 | *.pch
75 | *.pdb
76 | *.ipdb
77 | *.pgc
78 | *.pgd
79 | *.rsp
80 | *.sbr
81 | *.tlb
82 | *.tli
83 | *.tlh
84 | *.tmp
85 | *.tmp_proj
86 | *_wpftmp.csproj
87 | *.log
88 | *.vspscc
89 | *.vssscc
90 | .builds
91 | *.pidb
92 | *.svclog
93 | *.scc
94 |
95 | # Chutzpah Test files
96 | _Chutzpah*
97 |
98 | # Visual C++ cache files
99 | ipch/
100 | *.aps
101 | *.ncb
102 | *.opendb
103 | *.opensdf
104 | *.sdf
105 | *.cachefile
106 | *.VC.db
107 | *.VC.VC.opendb
108 |
109 | # Visual Studio profiler
110 | *.psess
111 | *.vsp
112 | *.vspx
113 | *.sap
114 |
115 | # Visual Studio Trace Files
116 | *.e2e
117 |
118 | # TFS 2012 Local Workspace
119 | $tf/
120 |
121 | # Guidance Automation Toolkit
122 | *.gpState
123 |
124 | # ReSharper is a .NET coding add-in
125 | _ReSharper*/
126 | *.[Rr]e[Ss]harper
127 | *.DotSettings.user
128 |
129 | # JustCode is a .NET coding add-in
130 | .JustCode
131 |
132 | # TeamCity is a build add-in
133 | _TeamCity*
134 |
135 | # DotCover is a Code Coverage Tool
136 | *.dotCover
137 |
138 | # AxoCover is a Code Coverage Tool
139 | .axoCover/*
140 | !.axoCover/settings.json
141 |
142 | # Visual Studio code coverage results
143 | *.coverage
144 | *.coveragexml
145 |
146 | # NCrunch
147 | _NCrunch_*
148 | .*crunch*.local.xml
149 | nCrunchTemp_*
150 |
151 | # MightyMoose
152 | *.mm.*
153 | AutoTest.Net/
154 |
155 | # Web workbench (sass)
156 | .sass-cache/
157 |
158 | # Installshield output folder
159 | [Ee]xpress/
160 |
161 | # DocProject is a documentation generator add-in
162 | DocProject/buildhelp/
163 | DocProject/Help/*.HxT
164 | DocProject/Help/*.HxC
165 | DocProject/Help/*.hhc
166 | DocProject/Help/*.hhk
167 | DocProject/Help/*.hhp
168 | DocProject/Help/Html2
169 | DocProject/Help/html
170 |
171 | # Click-Once directory
172 | publish/
173 |
174 | # Publish Web Output
175 | *.[Pp]ublish.xml
176 | *.azurePubxml
177 | # Note: Comment the next line if you want to checkin your web deploy settings,
178 | # but database connection strings (with potential passwords) will be unencrypted
179 | *.pubxml
180 | *.publishproj
181 |
182 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
183 | # checkin your Azure Web App publish settings, but sensitive information contained
184 | # in these scripts will be unencrypted
185 | PublishScripts/
186 |
187 | # NuGet Packages
188 | *.nupkg
189 | # NuGet Symbol Packages
190 | *.snupkg
191 | # The packages folder can be ignored because of Package Restore
192 | **/[Pp]ackages/*
193 | # except build/, which is used as an MSBuild target.
194 | !**/[Pp]ackages/build/
195 | # Uncomment if necessary however generally it will be regenerated when needed
196 | #!**/[Pp]ackages/repositories.config
197 | # NuGet v3's project.json files produces more ignorable files
198 | *.nuget.props
199 | *.nuget.targets
200 |
201 | # Microsoft Azure Build Output
202 | csx/
203 | *.build.csdef
204 |
205 | # Microsoft Azure Emulator
206 | ecf/
207 | rcf/
208 |
209 | # Windows Store app package directories and files
210 | AppPackages/
211 | BundleArtifacts/
212 | Package.StoreAssociation.xml
213 | _pkginfo.txt
214 | *.appx
215 | *.appxbundle
216 | *.appxupload
217 |
218 | # Visual Studio cache files
219 | # files ending in .cache can be ignored
220 | *.[Cc]ache
221 | # but keep track of directories ending in .cache
222 | !?*.[Cc]ache/
223 |
224 | # Others
225 | ClientBin/
226 | ~$*
227 | *~
228 | *.dbmdl
229 | *.dbproj.schemaview
230 | *.jfm
231 | *.pfx
232 | *.publishsettings
233 | orleans.codegen.cs
234 |
235 | # Including strong name files can present a security risk
236 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
237 | #*.snk
238 |
239 | # Since there are multiple workflows, uncomment next line to ignore bower_components
240 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
241 | #bower_components/
242 |
243 | # RIA/Silverlight projects
244 | Generated_Code/
245 |
246 | # Backup & report files from converting an old project file
247 | # to a newer Visual Studio version. Backup files are not needed,
248 | # because we have git ;-)
249 | _UpgradeReport_Files/
250 | Backup*/
251 | UpgradeLog*.XML
252 | UpgradeLog*.htm
253 | ServiceFabricBackup/
254 | *.rptproj.bak
255 |
256 | # SQL Server files
257 | *.mdf
258 | *.ldf
259 | *.ndf
260 |
261 | # Business Intelligence projects
262 | *.rdl.data
263 | *.bim.layout
264 | *.bim_*.settings
265 | *.rptproj.rsuser
266 | *- [Bb]ackup.rdl
267 | *- [Bb]ackup ([0-9]).rdl
268 | *- [Bb]ackup ([0-9][0-9]).rdl
269 |
270 | # Microsoft Fakes
271 | FakesAssemblies/
272 |
273 | # GhostDoc plugin setting file
274 | *.GhostDoc.xml
275 |
276 | # Node.js Tools for Visual Studio
277 | .ntvs_analysis.dat
278 | node_modules/
279 |
280 | # Visual Studio 6 build log
281 | *.plg
282 |
283 | # Visual Studio 6 workspace options file
284 | *.opt
285 |
286 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
287 | *.vbw
288 |
289 | # Visual Studio LightSwitch build output
290 | **/*.HTMLClient/GeneratedArtifacts
291 | **/*.DesktopClient/GeneratedArtifacts
292 | **/*.DesktopClient/ModelManifest.xml
293 | **/*.Server/GeneratedArtifacts
294 | **/*.Server/ModelManifest.xml
295 | _Pvt_Extensions
296 |
297 | # Paket dependency manager
298 | .paket/paket.exe
299 | paket-files/
300 |
301 | # FAKE - F# Make
302 | .fake/
303 |
304 | # CodeRush personal settings
305 | .cr/personal
306 |
307 | # Python Tools for Visual Studio (PTVS)
308 | __pycache__/
309 | *.pyc
310 |
311 | # Cake - Uncomment if you are using it
312 | # tools/**
313 | # !tools/packages.config
314 |
315 | # Tabs Studio
316 | *.tss
317 |
318 | # Telerik's JustMock configuration file
319 | *.jmconfig
320 |
321 | # BizTalk build output
322 | *.btp.cs
323 | *.btm.cs
324 | *.odx.cs
325 | *.xsd.cs
326 |
327 | # OpenCover UI analysis results
328 | OpenCover/
329 |
330 | # Azure Stream Analytics local run output
331 | ASALocalRun/
332 |
333 | # MSBuild Binary and Structured Log
334 | *.binlog
335 |
336 | # NVidia Nsight GPU debugger configuration file
337 | *.nvuser
338 |
339 | # MFractors (Xamarin productivity tool) working folder
340 | .mfractor/
341 |
342 | # Local History for Visual Studio
343 | .localhistory/
344 |
345 | # BeatPulse healthcheck temp database
346 | healthchecksdb
347 |
348 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
349 | MigrationBackup/
350 |
351 | # Ionide (cross platform F# VS Code tools) working folder
352 | .ionide/
353 |
354 | .idea
--------------------------------------------------------------------------------
/CoDLUIDecompiler.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.28307.329
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CoDLUIDecompiler", "CoDLUIDecompiler\CoDLUIDecompiler.csproj", "{086385A5-BA10-468D-87FA-5C00FFC55EC3}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {086385A5-BA10-468D-87FA-5C00FFC55EC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {086385A5-BA10-468D-87FA-5C00FFC55EC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {086385A5-BA10-468D-87FA-5C00FFC55EC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {086385A5-BA10-468D-87FA-5C00FFC55EC3}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {8493A899-A6CA-4ED8-A330-B59EBF5002BD}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/CoDLUIDecompiler.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {086385A5-BA10-468D-87FA-5C00FFC55EC3}
8 | Exe
9 | CoDLUIDecompiler
10 | CoDLUIDecompiler
11 | v4.7.2
12 | 512
13 | true
14 | true
15 |
16 |
17 |
18 | AnyCPU
19 | true
20 | full
21 | false
22 | bin\Debug\
23 | DEBUG;TRACE
24 | prompt
25 | 4
26 | false
27 |
28 |
29 | x64
30 | pdbonly
31 | true
32 | bin\Release\
33 | TRACE
34 | prompt
35 | 4
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/Games/BlackOps2.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace CoDLUIDecompiler
8 | {
9 | class BlackOps2
10 | {
11 | public static Dictionary OPCodeTable = new Dictionary()
12 | {
13 | // Same opcode table as bo3, they just dont have the shift left, right and bitwise operators
14 | { 0, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD },
15 | { 1, LuaOpCode.OpCodes.HKS_OPCODE_TEST },
16 | { 2, LuaOpCode.OpCodes.HKS_OPCODE_CALL_I },
17 | { 3, LuaOpCode.OpCodes.HKS_OPCODE_CALL_C },
18 | { 4, LuaOpCode.OpCodes.HKS_OPCODE_EQ },
19 | { 5, LuaOpCode.OpCodes.HKS_OPCODE_EQ_BK },
20 | { 6, LuaOpCode.OpCodes.HKS_OPCODE_GETGLOBAL },
21 | { 7, LuaOpCode.OpCodes.HKS_OPCODE_MOVE },
22 | { 8, LuaOpCode.OpCodes.HKS_OPCODE_SELF },
23 | { 9, LuaOpCode.OpCodes.HKS_OPCODE_RETURN },
24 | { 10, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE_S },
25 | { 11, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE_N },
26 | { 12, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE },
27 | { 13, LuaOpCode.OpCodes.HKS_OPCODE_LOADBOOL },
28 | { 14, LuaOpCode.OpCodes.HKS_OPCODE_TFORLOOP },
29 | { 15, LuaOpCode.OpCodes.HKS_OPCODE_SETFIELD },
30 | { 16, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_S },
31 | { 17, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_S_BK },
32 | { 18, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_N },
33 | { 19, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_N_BK },
34 | { 20, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE },
35 | { 21, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_BK },
36 | { 22, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_I },
37 | { 23, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_C },
38 | { 24, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_M },
39 | { 25, LuaOpCode.OpCodes.HKS_OPCODE_LOADK },
40 | { 26, LuaOpCode.OpCodes.HKS_OPCODE_LOADNIL },
41 | { 27, LuaOpCode.OpCodes.HKS_OPCODE_SETGLOBAL },
42 | { 28, LuaOpCode.OpCodes.HKS_OPCODE_JMP },
43 | { 29, LuaOpCode.OpCodes.HKS_OPCODE_CALL_M },
44 | { 30, LuaOpCode.OpCodes.HKS_OPCODE_CALL },
45 | { 31, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_INDEX },
46 | { 32, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_NEWINDEX },
47 | { 33, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_SELF },
48 | { 34, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_INDEX_LITERAL },
49 | { 35, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_NEWINDEX_LITERAL },
50 | { 36, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_SELF_LITERAL },
51 | { 37, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL },
52 | { 38, LuaOpCode.OpCodes.HKS_OPCODE_GETUPVAL },
53 | { 39, LuaOpCode.OpCodes.HKS_OPCODE_SETUPVAL },
54 | { 40, LuaOpCode.OpCodes.HKS_OPCODE_ADD },
55 | { 41, LuaOpCode.OpCodes.HKS_OPCODE_ADD_BK },
56 | { 42, LuaOpCode.OpCodes.HKS_OPCODE_SUB },
57 | { 43, LuaOpCode.OpCodes.HKS_OPCODE_SUB_BK },
58 | { 44, LuaOpCode.OpCodes.HKS_OPCODE_MUL },
59 | { 45, LuaOpCode.OpCodes.HKS_OPCODE_MUL_BK },
60 | { 46, LuaOpCode.OpCodes.HKS_OPCODE_DIV },
61 | { 47, LuaOpCode.OpCodes.HKS_OPCODE_DIV_BK },
62 | { 48, LuaOpCode.OpCodes.HKS_OPCODE_MOD },
63 | { 49, LuaOpCode.OpCodes.HKS_OPCODE_MOD_BK },
64 | { 50, LuaOpCode.OpCodes.HKS_OPCODE_POW },
65 | { 51, LuaOpCode.OpCodes.HKS_OPCODE_POW_BK },
66 | { 52, LuaOpCode.OpCodes.HKS_OPCODE_NEWTABLE },
67 | { 53, LuaOpCode.OpCodes.HKS_OPCODE_UNM },
68 | { 54, LuaOpCode.OpCodes.HKS_OPCODE_NOT },
69 | { 55, LuaOpCode.OpCodes.HKS_OPCODE_LEN },
70 | { 56, LuaOpCode.OpCodes.HKS_OPCODE_LT },
71 | { 57, LuaOpCode.OpCodes.HKS_OPCODE_LT_BK },
72 | { 58, LuaOpCode.OpCodes.HKS_OPCODE_LE },
73 | { 59, LuaOpCode.OpCodes.HKS_OPCODE_LE_BK },
74 | { 60, LuaOpCode.OpCodes.HKS_OPCODE_CONCAT },
75 | { 61, LuaOpCode.OpCodes.HKS_OPCODE_TESTSET },
76 | { 62, LuaOpCode.OpCodes.HKS_OPCODE_FORPREP },
77 | { 63, LuaOpCode.OpCodes.HKS_OPCODE_FORLOOP },
78 | { 64, LuaOpCode.OpCodes.HKS_OPCODE_SETLIST },
79 | { 65, LuaOpCode.OpCodes.HKS_OPCODE_CLOSE },
80 | { 66, LuaOpCode.OpCodes.HKS_OPCODE_CLOSURE },
81 | { 67, LuaOpCode.OpCodes.HKS_OPCODE_VARARG },
82 | { 68, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_I_R1 },
83 | { 69, LuaOpCode.OpCodes.HKS_OPCODE_CALL_I_R1 },
84 | { 70, LuaOpCode.OpCodes.HKS_OPCODE_SETUPVAL_R1 },
85 | { 71, LuaOpCode.OpCodes.HKS_OPCODE_TEST_R1 },
86 | { 72, LuaOpCode.OpCodes.HKS_OPCODE_NOT_R1 },
87 | { 73, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD_R1 },
88 | { 74, LuaOpCode.OpCodes.HKS_OPCODE_SETFIELD_R1 },
89 | { 75, LuaOpCode.OpCodes.HKS_OPCODE_NEWSTRUCT },
90 | { 76, LuaOpCode.OpCodes.HKS_OPCODE_DATA },
91 | { 77, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTN },
92 | { 78, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTI },
93 | { 79, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOT },
94 | { 80, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTS },
95 | { 81, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTMT },
96 | { 82, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPE },
97 | { 83, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPES },
98 | { 84, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOT },
99 | { 85, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOTMT },
100 | { 86, LuaOpCode.OpCodes.HKS_OPCODE_SELFSLOT },
101 | { 87, LuaOpCode.OpCodes.HKS_OPCODE_SELFSLOTMT },
102 | { 88, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD_MM },
103 | { 89, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPE_D },
104 | { 90, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOT_D },
105 | { 91, LuaOpCode.OpCodes.HKS_OPCODE_GETGLOBAL_MEM },
106 | { 92, LuaOpCode.OpCodes.HKS_OPCODE_MAX },
107 | };
108 |
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/Games/BlackOps3.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace CoDLUIDecompiler
8 | {
9 | class BlackOps3
10 | {
11 | public static Dictionary OPCodeTable = new Dictionary()
12 | {
13 | { 0, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD },
14 | { 1, LuaOpCode.OpCodes.HKS_OPCODE_TEST },
15 | { 2, LuaOpCode.OpCodes.HKS_OPCODE_CALL_I },
16 | { 3, LuaOpCode.OpCodes.HKS_OPCODE_CALL_C },
17 | { 4, LuaOpCode.OpCodes.HKS_OPCODE_EQ },
18 | { 5, LuaOpCode.OpCodes.HKS_OPCODE_EQ_BK },
19 | { 6, LuaOpCode.OpCodes.HKS_OPCODE_GETGLOBAL },
20 | { 7, LuaOpCode.OpCodes.HKS_OPCODE_MOVE },
21 | { 8, LuaOpCode.OpCodes.HKS_OPCODE_SELF },
22 | { 9, LuaOpCode.OpCodes.HKS_OPCODE_RETURN },
23 | { 10, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE_S },
24 | { 11, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE_N },
25 | { 12, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE },
26 | { 13, LuaOpCode.OpCodes.HKS_OPCODE_LOADBOOL },
27 | { 14, LuaOpCode.OpCodes.HKS_OPCODE_TFORLOOP },
28 | { 15, LuaOpCode.OpCodes.HKS_OPCODE_SETFIELD },
29 | { 16, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_S },
30 | { 17, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_S_BK },
31 | { 18, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_N },
32 | { 19, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_N_BK },
33 | { 20, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE },
34 | { 21, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_BK },
35 | { 22, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_I },
36 | { 23, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_C },
37 | { 24, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_M },
38 | { 25, LuaOpCode.OpCodes.HKS_OPCODE_LOADK },
39 | { 26, LuaOpCode.OpCodes.HKS_OPCODE_LOADNIL },
40 | { 27, LuaOpCode.OpCodes.HKS_OPCODE_SETGLOBAL },
41 | { 28, LuaOpCode.OpCodes.HKS_OPCODE_JMP },
42 | { 29, LuaOpCode.OpCodes.HKS_OPCODE_CALL_M },
43 | { 30, LuaOpCode.OpCodes.HKS_OPCODE_CALL },
44 | { 31, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_INDEX },
45 | { 32, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_NEWINDEX },
46 | { 33, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_SELF },
47 | { 34, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_INDEX_LITERAL },
48 | { 35, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_NEWINDEX_LITERAL },
49 | { 36, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_SELF_LITERAL },
50 | { 37, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL },
51 | { 38, LuaOpCode.OpCodes.HKS_OPCODE_GETUPVAL },
52 | { 39, LuaOpCode.OpCodes.HKS_OPCODE_SETUPVAL },
53 | { 40, LuaOpCode.OpCodes.HKS_OPCODE_ADD },
54 | { 41, LuaOpCode.OpCodes.HKS_OPCODE_ADD_BK },
55 | { 42, LuaOpCode.OpCodes.HKS_OPCODE_SUB },
56 | { 43, LuaOpCode.OpCodes.HKS_OPCODE_SUB_BK },
57 | { 44, LuaOpCode.OpCodes.HKS_OPCODE_MUL },
58 | { 45, LuaOpCode.OpCodes.HKS_OPCODE_MUL_BK },
59 | { 46, LuaOpCode.OpCodes.HKS_OPCODE_DIV },
60 | { 47, LuaOpCode.OpCodes.HKS_OPCODE_DIV_BK },
61 | { 48, LuaOpCode.OpCodes.HKS_OPCODE_MOD },
62 | { 49, LuaOpCode.OpCodes.HKS_OPCODE_MOD_BK },
63 | { 50, LuaOpCode.OpCodes.HKS_OPCODE_POW },
64 | { 51, LuaOpCode.OpCodes.HKS_OPCODE_POW_BK },
65 | { 52, LuaOpCode.OpCodes.HKS_OPCODE_NEWTABLE },
66 | { 53, LuaOpCode.OpCodes.HKS_OPCODE_UNM },
67 | { 54, LuaOpCode.OpCodes.HKS_OPCODE_NOT },
68 | { 55, LuaOpCode.OpCodes.HKS_OPCODE_LEN },
69 | { 56, LuaOpCode.OpCodes.HKS_OPCODE_LT },
70 | { 57, LuaOpCode.OpCodes.HKS_OPCODE_LT_BK },
71 | { 58, LuaOpCode.OpCodes.HKS_OPCODE_LE },
72 | { 59, LuaOpCode.OpCodes.HKS_OPCODE_LE_BK },
73 | { 60, LuaOpCode.OpCodes.HKS_OPCODE_SHIFT_LEFT },
74 | { 61, LuaOpCode.OpCodes.HKS_OPCODE_SHIFT_LEFT_BK },
75 | { 62, LuaOpCode.OpCodes.HKS_OPCODE_SHIFT_RIGHT },
76 | { 63, LuaOpCode.OpCodes.HKS_OPCODE_SHIFT_RIGHT_BK },
77 | { 64, LuaOpCode.OpCodes.HKS_OPCODE_BITWISE_AND },
78 | { 65, LuaOpCode.OpCodes.HKS_OPCODE_BITWISE_AND_BK },
79 | { 66, LuaOpCode.OpCodes.HKS_OPCODE_BITWISE_OR },
80 | { 67, LuaOpCode.OpCodes.HKS_OPCODE_BITWISE_OR_BK },
81 | { 68, LuaOpCode.OpCodes.HKS_OPCODE_CONCAT },
82 | { 69, LuaOpCode.OpCodes.HKS_OPCODE_TESTSET },
83 | { 70, LuaOpCode.OpCodes.HKS_OPCODE_FORPREP },
84 | { 71, LuaOpCode.OpCodes.HKS_OPCODE_FORLOOP },
85 | { 72, LuaOpCode.OpCodes.HKS_OPCODE_SETLIST },
86 | { 73, LuaOpCode.OpCodes.HKS_OPCODE_CLOSE },
87 | { 74, LuaOpCode.OpCodes.HKS_OPCODE_CLOSURE },
88 | { 75, LuaOpCode.OpCodes.HKS_OPCODE_VARARG },
89 | { 76, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_I_R1 },
90 | { 77, LuaOpCode.OpCodes.HKS_OPCODE_CALL_I_R1 },
91 | { 78, LuaOpCode.OpCodes.HKS_OPCODE_SETUPVAL_R1 },
92 | { 79, LuaOpCode.OpCodes.HKS_OPCODE_TEST_R1 },
93 | { 80, LuaOpCode.OpCodes.HKS_OPCODE_NOT_R1 },
94 | { 81, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD_R1 },
95 | { 82, LuaOpCode.OpCodes.HKS_OPCODE_SETFIELD_R1 },
96 | { 83, LuaOpCode.OpCodes.HKS_OPCODE_NEWSTRUCT },
97 | { 84, LuaOpCode.OpCodes.HKS_OPCODE_DATA },
98 | { 85, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTN },
99 | { 86, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTI },
100 | { 87, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOT },
101 | { 88, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTS },
102 | { 89, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTMT },
103 | { 90, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPE },
104 | { 91, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPES },
105 | { 92, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOT },
106 | { 93, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOTMT },
107 | { 94, LuaOpCode.OpCodes.HKS_OPCODE_SELFSLOT },
108 | { 95, LuaOpCode.OpCodes.HKS_OPCODE_SELFSLOTMT },
109 | { 96, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD_MM },
110 | { 97, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPE_D },
111 | { 98, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOT_D },
112 | { 99, LuaOpCode.OpCodes.HKS_OPCODE_GETGLOBAL_MEM },
113 | { 100, LuaOpCode.OpCodes.HKS_OPCODE_MAX },
114 | };
115 |
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/Games/Ghosts.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace CoDLUIDecompiler
8 | {
9 | class Ghosts
10 | {
11 | public static Dictionary OPCodeTable = new Dictionary()
12 | {
13 | // https://pastebin.com/4PhxeMjm
14 | { 0, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD },
15 | { 1, LuaOpCode.OpCodes.HKS_OPCODE_TEST },
16 | { 2, LuaOpCode.OpCodes.HKS_OPCODE_CALL_I },
17 | { 3, LuaOpCode.OpCodes.HKS_OPCODE_CALL_C },
18 | { 4, LuaOpCode.OpCodes.HKS_OPCODE_EQ },
19 | { 5, LuaOpCode.OpCodes.HKS_OPCODE_EQ_BK },
20 | { 6, LuaOpCode.OpCodes.HKS_OPCODE_GETGLOBAL },
21 | { 7, LuaOpCode.OpCodes.HKS_OPCODE_MOVE },
22 | { 8, LuaOpCode.OpCodes.HKS_OPCODE_SELF },
23 | { 9, LuaOpCode.OpCodes.HKS_OPCODE_RETURN },
24 | { 10, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE_S },
25 | { 11, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE_N },
26 | { 12, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE },
27 | { 13, LuaOpCode.OpCodes.HKS_OPCODE_LOADBOOL },
28 | { 14, LuaOpCode.OpCodes.HKS_OPCODE_TFORLOOP },
29 | { 15, LuaOpCode.OpCodes.HKS_OPCODE_SETFIELD },
30 | { 16, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_S },
31 | { 17, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_S_BK },
32 | { 18, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_N },
33 | { 19, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_N_BK },
34 | { 20, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE },
35 | { 21, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_BK },
36 | { 22, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_I },
37 | { 23, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_C },
38 | { 24, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_M },
39 | { 25, LuaOpCode.OpCodes.HKS_OPCODE_LOADK },
40 | { 26, LuaOpCode.OpCodes.HKS_OPCODE_LOADNIL },
41 | { 27, LuaOpCode.OpCodes.HKS_OPCODE_SETGLOBAL },
42 | { 28, LuaOpCode.OpCodes.HKS_OPCODE_JMP },
43 | { 29, LuaOpCode.OpCodes.HKS_OPCODE_CALL_M },
44 | { 30, LuaOpCode.OpCodes.HKS_OPCODE_CALL },
45 | { 31, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_INDEX },
46 | { 32, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_NEWINDEX },
47 | { 33, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_SELF },
48 | { 34, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_INDEX_LITERAL },
49 | { 35, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_NEWINDEX_LITERAL },
50 | { 36, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_SELF_LITERAL },
51 | { 37, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL },
52 | { 38, LuaOpCode.OpCodes.HKS_OPCODE_GETUPVAL },
53 | { 39, LuaOpCode.OpCodes.HKS_OPCODE_SETUPVAL },
54 | { 40, LuaOpCode.OpCodes.HKS_OPCODE_ADD },
55 | { 41, LuaOpCode.OpCodes.HKS_OPCODE_ADD_BK },
56 | { 42, LuaOpCode.OpCodes.HKS_OPCODE_SUB },
57 | { 43, LuaOpCode.OpCodes.HKS_OPCODE_SUB_BK },
58 | { 44, LuaOpCode.OpCodes.HKS_OPCODE_MUL },
59 | { 45, LuaOpCode.OpCodes.HKS_OPCODE_MUL_BK },
60 | { 46, LuaOpCode.OpCodes.HKS_OPCODE_DIV },
61 | { 47, LuaOpCode.OpCodes.HKS_OPCODE_DIV_BK },
62 | { 48, LuaOpCode.OpCodes.HKS_OPCODE_MOD },
63 | { 49, LuaOpCode.OpCodes.HKS_OPCODE_MOD_BK },
64 | { 50, LuaOpCode.OpCodes.HKS_OPCODE_POW },
65 | { 51, LuaOpCode.OpCodes.HKS_OPCODE_POW_BK },
66 | { 52, LuaOpCode.OpCodes.HKS_OPCODE_NEWTABLE },
67 | { 53, LuaOpCode.OpCodes.HKS_OPCODE_UNM },
68 | { 54, LuaOpCode.OpCodes.HKS_OPCODE_NOT },
69 | { 55, LuaOpCode.OpCodes.HKS_OPCODE_LEN },
70 | { 56, LuaOpCode.OpCodes.HKS_OPCODE_LT },
71 | { 57, LuaOpCode.OpCodes.HKS_OPCODE_LT_BK },
72 | { 58, LuaOpCode.OpCodes.HKS_OPCODE_LE },
73 | { 59, LuaOpCode.OpCodes.HKS_OPCODE_LE_BK },
74 | { 60, LuaOpCode.OpCodes.HKS_OPCODE_CONCAT },
75 | { 61, LuaOpCode.OpCodes.HKS_OPCODE_TESTSET },
76 | { 62, LuaOpCode.OpCodes.HKS_OPCODE_FORPREP },
77 | { 63, LuaOpCode.OpCodes.HKS_OPCODE_FORLOOP },
78 | { 64, LuaOpCode.OpCodes.HKS_OPCODE_SETLIST },
79 | { 65, LuaOpCode.OpCodes.HKS_OPCODE_CLOSE },
80 | { 66, LuaOpCode.OpCodes.HKS_OPCODE_CLOSURE },
81 | { 67, LuaOpCode.OpCodes.HKS_OPCODE_VARARG },
82 | { 68, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_I_R1 },
83 | { 69, LuaOpCode.OpCodes.HKS_OPCODE_CALL_I_R1 },
84 | { 70, LuaOpCode.OpCodes.HKS_OPCODE_SETUPVAL_R1 },
85 | { 71, LuaOpCode.OpCodes.HKS_OPCODE_TEST_R1 },
86 | { 72, LuaOpCode.OpCodes.HKS_OPCODE_NOT_R1 },
87 | { 73, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD_R1 },
88 | { 74, LuaOpCode.OpCodes.HKS_OPCODE_SETFIELD_R1 },
89 | { 75, LuaOpCode.OpCodes.HKS_OPCODE_NEWSTRUCT },
90 | { 76, LuaOpCode.OpCodes.HKS_OPCODE_DATA },
91 | { 77, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTN },
92 | { 78, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTI },
93 | { 79, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOT },
94 | { 80, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTS },
95 | { 81, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTMT },
96 | { 82, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPE },
97 | { 83, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPES },
98 | { 84, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOT },
99 | { 85, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOTMT },
100 | { 86, LuaOpCode.OpCodes.HKS_OPCODE_SELFSLOT },
101 | { 87, LuaOpCode.OpCodes.HKS_OPCODE_SELFSLOTMT },
102 | { 88, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD_MM },
103 | { 89, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPE_D },
104 | { 90, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOT_D },
105 | { 91, LuaOpCode.OpCodes.HKS_OPCODE_GETGLOBAL_MEM },
106 | { 92, LuaOpCode.OpCodes.HKS_OPCODE_DELETE },
107 | { 93, LuaOpCode.OpCodes.HKS_OPCODE_DELETE_BK },
108 | { 94, LuaOpCode.OpCodes.HKS_OPCODE_MAX },
109 | };
110 |
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/Games/WorldWar2.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace CoDLUIDecompiler
8 | {
9 | class WorldWar2
10 | {
11 | public static Dictionary OPCodeTable = new Dictionary()
12 | {
13 | // Same opcode table as bo3, they just dont have the shift left, right and bitwise operators
14 | { 0, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD },
15 | { 1, LuaOpCode.OpCodes.HKS_OPCODE_TEST },
16 | { 2, LuaOpCode.OpCodes.HKS_OPCODE_CALL_I },
17 | { 3, LuaOpCode.OpCodes.HKS_OPCODE_CALL_C },
18 | { 4, LuaOpCode.OpCodes.HKS_OPCODE_EQ },
19 | { 5, LuaOpCode.OpCodes.HKS_OPCODE_EQ_BK },
20 | { 6, LuaOpCode.OpCodes.HKS_OPCODE_GETGLOBAL },
21 | { 7, LuaOpCode.OpCodes.HKS_OPCODE_MOVE },
22 | { 8, LuaOpCode.OpCodes.HKS_OPCODE_SELF },
23 | { 9, LuaOpCode.OpCodes.HKS_OPCODE_RETURN },
24 | { 10, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE_S },
25 | { 11, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE_N },
26 | { 12, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE },
27 | { 13, LuaOpCode.OpCodes.HKS_OPCODE_LOADBOOL },
28 | { 14, LuaOpCode.OpCodes.HKS_OPCODE_TFORLOOP },
29 | { 15, LuaOpCode.OpCodes.HKS_OPCODE_SETFIELD },
30 | { 16, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_S },
31 | { 17, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_S_BK },
32 | { 18, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_N },
33 | { 19, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_N_BK },
34 | { 20, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE },
35 | { 21, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_BK },
36 | { 22, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_I },
37 | { 23, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_C },
38 | { 24, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_M },
39 | { 25, LuaOpCode.OpCodes.HKS_OPCODE_LOADK },
40 | { 26, LuaOpCode.OpCodes.HKS_OPCODE_LOADNIL },
41 | { 27, LuaOpCode.OpCodes.HKS_OPCODE_SETGLOBAL },
42 | { 28, LuaOpCode.OpCodes.HKS_OPCODE_JMP },
43 | { 29, LuaOpCode.OpCodes.HKS_OPCODE_CALL_M },
44 | { 30, LuaOpCode.OpCodes.HKS_OPCODE_CALL },
45 | { 31, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_INDEX },
46 | { 32, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_NEWINDEX },
47 | { 33, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_SELF },
48 | { 34, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_INDEX_LITERAL },
49 | { 35, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_NEWINDEX_LITERAL },
50 | { 36, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_SELF_LITERAL },
51 | { 37, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL },
52 | { 38, LuaOpCode.OpCodes.HKS_OPCODE_GETUPVAL },
53 | { 39, LuaOpCode.OpCodes.HKS_OPCODE_SETUPVAL },
54 | { 40, LuaOpCode.OpCodes.HKS_OPCODE_ADD },
55 | { 41, LuaOpCode.OpCodes.HKS_OPCODE_ADD_BK },
56 | { 42, LuaOpCode.OpCodes.HKS_OPCODE_SUB },
57 | { 43, LuaOpCode.OpCodes.HKS_OPCODE_SUB_BK },
58 | { 44, LuaOpCode.OpCodes.HKS_OPCODE_MUL },
59 | { 45, LuaOpCode.OpCodes.HKS_OPCODE_MUL_BK },
60 | { 46, LuaOpCode.OpCodes.HKS_OPCODE_DIV },
61 | { 47, LuaOpCode.OpCodes.HKS_OPCODE_DIV_BK },
62 | { 48, LuaOpCode.OpCodes.HKS_OPCODE_MOD },
63 | { 49, LuaOpCode.OpCodes.HKS_OPCODE_MOD_BK },
64 | { 50, LuaOpCode.OpCodes.HKS_OPCODE_POW },
65 | { 51, LuaOpCode.OpCodes.HKS_OPCODE_POW_BK },
66 | { 52, LuaOpCode.OpCodes.HKS_OPCODE_NEWTABLE },
67 | { 53, LuaOpCode.OpCodes.HKS_OPCODE_UNM },
68 | { 54, LuaOpCode.OpCodes.HKS_OPCODE_NOT },
69 | { 55, LuaOpCode.OpCodes.HKS_OPCODE_LEN },
70 | { 56, LuaOpCode.OpCodes.HKS_OPCODE_LT },
71 | { 57, LuaOpCode.OpCodes.HKS_OPCODE_LT_BK },
72 | { 58, LuaOpCode.OpCodes.HKS_OPCODE_LE },
73 | { 59, LuaOpCode.OpCodes.HKS_OPCODE_LE_BK },
74 | { 60, LuaOpCode.OpCodes.HKS_OPCODE_CONCAT },
75 | { 61, LuaOpCode.OpCodes.HKS_OPCODE_TESTSET },
76 | { 62, LuaOpCode.OpCodes.HKS_OPCODE_FORPREP },
77 | { 63, LuaOpCode.OpCodes.HKS_OPCODE_FORLOOP },
78 | { 64, LuaOpCode.OpCodes.HKS_OPCODE_SETLIST },
79 | { 65, LuaOpCode.OpCodes.HKS_OPCODE_CLOSE },
80 | { 66, LuaOpCode.OpCodes.HKS_OPCODE_CLOSURE },
81 | { 67, LuaOpCode.OpCodes.HKS_OPCODE_VARARG },
82 | { 68, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_I_R1 },
83 | { 69, LuaOpCode.OpCodes.HKS_OPCODE_CALL_I_R1 },
84 | { 70, LuaOpCode.OpCodes.HKS_OPCODE_SETUPVAL_R1 },
85 | { 71, LuaOpCode.OpCodes.HKS_OPCODE_TEST_R1 },
86 | { 72, LuaOpCode.OpCodes.HKS_OPCODE_NOT_R1 },
87 | { 73, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD_R1 },
88 | { 74, LuaOpCode.OpCodes.HKS_OPCODE_SETFIELD_R1 },
89 | { 75, LuaOpCode.OpCodes.HKS_OPCODE_NEWSTRUCT },
90 | { 76, LuaOpCode.OpCodes.HKS_OPCODE_DATA },
91 | { 77, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTN },
92 | { 78, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTI },
93 | { 79, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOT },
94 | { 80, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTS },
95 | { 81, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTMT },
96 | { 82, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPE },
97 | { 83, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPES },
98 | { 84, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOT },
99 | { 85, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOTMT },
100 | { 86, LuaOpCode.OpCodes.HKS_OPCODE_SELFSLOT },
101 | { 87, LuaOpCode.OpCodes.HKS_OPCODE_SELFSLOTMT },
102 | { 88, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD_MM },
103 | { 89, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPE_D },
104 | { 90, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOT_D },
105 | { 91, LuaOpCode.OpCodes.HKS_OPCODE_GETGLOBAL_MEM },
106 | { 92, LuaOpCode.OpCodes.HKS_OPCODE_MAX },
107 | };
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/Lua/Datatype.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace CoDLUIDecompiler
8 | {
9 | class Datatype
10 | {
11 | public string Name;
12 | public int Id;
13 | public int Unk;
14 |
15 | public enum Type
16 | {
17 | Nil,
18 | Boolean,
19 | LightUserData,
20 | Number,
21 | String,
22 | Table,
23 | Function,
24 | UserData,
25 | Thread,
26 | IFunction,
27 | CFunction,
28 | UI64,
29 | Struct,
30 | XHash
31 | }
32 |
33 | public Datatype(int ID, int Unk, string Name)
34 | {
35 | this.Name = Name;
36 | this.Id = ID;
37 | this.Unk = Unk;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/Lua/LuaCondition.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace CoDLUIDecompiler
8 | {
9 | class LuaCondition
10 | {
11 | public int line;
12 |
13 | public enum Type
14 | {
15 | If,
16 | For,
17 | Foreach,
18 | While,
19 | DoWhile,
20 | Else,
21 | End,
22 | }
23 |
24 | public enum Prefix
25 | {
26 | none,
27 | and,
28 | or
29 | }
30 |
31 | public Type type;
32 |
33 | public Prefix prefix;
34 |
35 | public LuaCondition master;
36 |
37 | public LuaCondition(int line, Type type, Prefix prefix = Prefix.none, LuaCondition master = null)
38 | {
39 | this.line = line;
40 | this.type = type;
41 | this.prefix = prefix;
42 | this.master = master;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/Lua/LuaConstant.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace CoDLUIDecompiler
8 | {
9 | class LuaConstant
10 | {
11 | public Datatype.Type type;
12 | public string value;
13 |
14 |
15 | public string getString()
16 | {
17 | if (this.type == Datatype.Type.String && this.value != "nil")
18 | return "\"" + this.value + "\"";
19 | else
20 | return this.value;
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/Lua/LuaFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.IO;
5 | using System.Reflection;
6 | using PhilLibX.IO;
7 |
8 | namespace CoDLUIDecompiler
9 | {
10 | class LuaFile
11 | {
12 | public BinaryReader inputReader;
13 | public StreamWriter outputWriter;
14 |
15 | private byte luaVersion;
16 | private byte compilerVersion;
17 | private byte endianness;
18 | private byte sizeOfInt;
19 | private byte sizeOfSizeT;
20 | private byte sizeOfIntruction;
21 | private byte sizeOfLuaNumber;
22 | private byte integralFlag;
23 | private byte gameByte;
24 | private int dataTypeCount;
25 |
26 | public Dictionary OPCodeTable;
27 |
28 | private Datatype[] Datatypes;
29 |
30 | public SupportedGames Game;
31 |
32 | public enum SupportedGames
33 | {
34 | BlackOps2,
35 | BlackOps3,
36 | WorldWar2,
37 | }
38 |
39 | public LuaFile(string filePath)
40 | {
41 | this.inputReader = new BinaryReader(new FileStream(filePath, FileMode.Open));
42 | // Make sure its a valid lua file by reading the header
43 | if (!this.readHeader())
44 | {
45 | this.inputReader.Close();
46 | return;
47 | }
48 | this.outputWriter = new StreamWriter(filePath + "dec");
49 | this.outputWriter.WriteLine("-- Decompiled with CoDLUIDecompiler by JariK\n");
50 | this.LoadGame();
51 | this.readInitFunction();
52 | this.outputWriter.Close();
53 | }
54 |
55 | public bool readHeader()
56 | {
57 | if (this.inputReader.BaseStream.Length < 5 || this.inputReader.ReadBytes(4).Equals(new byte[] { 0x1B, 0x4C, 0x75, 0x61 }))
58 | {
59 | Console.WriteLine("Lua file invalid");
60 | return false;
61 | }
62 | // Jump 9 bytes
63 | this.luaVersion = this.inputReader.ReadByte();
64 | this.compilerVersion = this.inputReader.ReadByte();
65 | this.endianness = this.inputReader.ReadByte();
66 | this.sizeOfInt = this.inputReader.ReadByte();
67 | this.sizeOfSizeT = this.inputReader.ReadByte();
68 | this.sizeOfIntruction = this.inputReader.ReadByte();
69 | this.sizeOfLuaNumber = this.inputReader.ReadByte();
70 | this.integralFlag = this.inputReader.ReadByte();
71 | this.gameByte = this.inputReader.ReadByte();
72 |
73 | byte Unk = this.inputReader.ReadByte();
74 | // Get the datatypes count
75 | this.dataTypeCount = this.inputReader.ReadInt32();
76 | this.Datatypes = new Datatype[this.dataTypeCount];
77 | // Read all the datatypes
78 | for (int i = 0; i < this.dataTypeCount; i++)
79 | {
80 | this.Datatypes[i] = new Datatype(
81 | this.inputReader.ReadInt32(),
82 | this.inputReader.ReadInt32(),
83 | this.inputReader.ReadNullTerminatedString()
84 | );
85 | }
86 | return true;
87 | }
88 |
89 | public void LoadGame()
90 | {
91 | this.OPCodeTable = BlackOps3.OPCodeTable;
92 | this.Game = SupportedGames.BlackOps3;
93 | if (this.compilerVersion == 0xD)
94 | {
95 | this.OPCodeTable = BlackOps2.OPCodeTable;
96 | this.Game = SupportedGames.BlackOps2;
97 | }
98 | else if (this.gameByte == 3)
99 | {
100 | // OPCode table is the same for IW but
101 | // Same opcodetable as bo2 but has some structure differences
102 | this.OPCodeTable = WorldWar2.OPCodeTable;
103 | this.Game = SupportedGames.WorldWar2;
104 | }
105 | if (this.compilerVersion == 0xD && this.gameByte == 3)
106 | {
107 | this.OPCodeTable = WorldWar2.OPCodeTable;
108 | this.Game = SupportedGames.WorldWar2;
109 | }
110 | }
111 |
112 | public void readInitFunction()
113 | {
114 | new LuaFunction(this, 0, true).decompile();
115 | }
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/Lua/LuaFunction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using PhilLibX.IO;
7 |
8 | namespace CoDLUIDecompiler
9 | {
10 | class LuaFunction
11 | {
12 | public int upValsCount;
13 | public int parameterCount;
14 | public int registerCount;
15 | public int instructionCount;
16 | public int constantCount;
17 | public int subFunctionCount;
18 |
19 | public bool usesVarArg;
20 |
21 | private LuaFile luaFile;
22 |
23 | public LuaInstruction[] Instructions;
24 | public List Upvalues;
25 | public LuaConstant[] Constants;
26 | public LuaRegister[] Registers;
27 | public LuaFunction[] SubFunctions;
28 |
29 | public List tablePositions;
30 |
31 | public List endPositions;
32 | public List elsePositions;
33 | public string orCondition;
34 |
35 | public List conditions;
36 |
37 | public bool isInitFunction;
38 | public LuaFunction superFunction;
39 | public int tabLevel;
40 | public int instructionPtr;
41 | public LuaInstruction currentInstruction;
42 |
43 | public string newName;
44 |
45 | public long startPosition;
46 | public long endPosition;
47 | public BinaryReader inputReader;
48 | public StreamWriter outputWriter;
49 |
50 | public LuaFunction(LuaFile luaFile, int tabLevel = 0, bool IsInitFunction = false, LuaFunction SuperFunction = null)
51 | {
52 | this.inputReader = luaFile.inputReader;
53 | this.outputWriter = luaFile.outputWriter;
54 | this.luaFile = luaFile;
55 | this.tabLevel = tabLevel;
56 | this.isInitFunction = IsInitFunction;
57 | this.superFunction = SuperFunction;
58 | this.startPosition = this.inputReader.BaseStream.Position;
59 | // Read the header
60 | this.readHeader();
61 | // Read all instructions
62 | this.readInstructions();
63 | // Read all constants
64 | this.readConstants();
65 | // read the footer
66 | this.readFooter();
67 | // read the sub functions
68 | this.readSubFunctions();
69 | }
70 |
71 | private void readHeader()
72 | {
73 | this.upValsCount = this.inputReader.ReadInt32();
74 | this.Upvalues = new List();
75 | this.parameterCount = this.inputReader.ReadInt32();
76 | int flags = inputReader.ReadByte();
77 | if (flags != 0)
78 | {
79 | this.usesVarArg = true;
80 | }
81 | this.registerCount = this.inputReader.ReadInt32();
82 | this.instructionCount = this.inputReader.ReadInt32();
83 |
84 | // Some unknown bytes (BO3 and BO4) almost 0
85 | if(this.luaFile.Game != LuaFile.SupportedGames.BlackOps2)
86 | {
87 | int weirdint = this.inputReader.ReadInt32();
88 | }
89 |
90 | // Add extra bytes to make it line up
91 | int extra = 4 - ((int)this.inputReader.BaseStream.Position % 4);
92 | if (extra > 0 && extra < 4)
93 | this.inputReader.ReadBytes(extra);
94 |
95 | this.conditions = new List();
96 | this.tablePositions = new List();
97 | this.endPositions = new List();
98 | this.elsePositions = new List();
99 | this.orCondition = "";
100 | }
101 |
102 | private void readFooter()
103 | {
104 | int unkInt = this.inputReader.ReadInt32();
105 | if (luaFile.Game != LuaFile.SupportedGames.WorldWar2)
106 | {
107 | float unkFloat = this.inputReader.ReadSingle();
108 | }
109 |
110 | this.subFunctionCount = this.inputReader.ReadInt32();
111 | this.endPosition = this.inputReader.BaseStream.Position;
112 | }
113 |
114 | private void readInstructions()
115 | {
116 | // Create array for instructions
117 | this.Instructions = new LuaInstruction[this.instructionCount];
118 | // Go through all instructions
119 | for (int i = 0; i < this.instructionCount; i++)
120 | {
121 | // Making a new instruction
122 | LuaInstruction instruction = new LuaInstruction(this);
123 | // Reading the values attached to the instruction
124 | // A = 8 bits
125 | // B = 9 bits
126 | // C = 8 bits
127 | // OpCode = 7 bits
128 | instruction.A = this.inputReader.ReadByte();
129 |
130 | int cValue = this.inputReader.ReadByte();
131 | byte bValue = this.inputReader.ReadByte();
132 | if (GetBit(bValue, 0) == 1)
133 | cValue += 256;
134 | instruction.C = cValue;
135 |
136 | instruction.B = bValue >> 1;
137 | byte flagsB = this.inputReader.ReadByte();
138 | if (GetBit(flagsB, 0) == 1)
139 | instruction.B += 128;
140 |
141 | instruction.Bx = (instruction.B * 512) + instruction.C;
142 | instruction.sBx = instruction.Bx - 65536 + 1;
143 |
144 | if(this.luaFile.OPCodeTable.TryGetValue(flagsB >> 1, out LuaOpCode.OpCodes opcode))
145 | {
146 | instruction.OpCode = opcode;
147 | }
148 | else
149 | {
150 | instruction.OpCode = LuaOpCode.OpCodes.HKS_OPCODE_UNK;
151 | }
152 |
153 | // Add to array
154 | this.Instructions[i] = instruction;
155 | }
156 | }
157 |
158 | private void readConstants()
159 | {
160 | this.constantCount = this.inputReader.ReadInt32();
161 | // Create array for constants
162 | this.Constants = new LuaConstant[this.constantCount];
163 | // Go through all constants
164 | for (int i = 0; i < this.constantCount; i++)
165 | {
166 | // Make a new constant object
167 | LuaConstant constant = new LuaConstant();
168 | // Read the type of constant
169 | constant.type = (Datatype.Type)this.inputReader.ReadByte();
170 | // Check if its a constant we can read
171 | switch (constant.type)
172 | {
173 | case Datatype.Type.Nil:
174 | constant.value = "nil";
175 | break;
176 | case Datatype.Type.Boolean:
177 | constant.value = (this.inputReader.ReadByte() == 1) ? "true" : "false";
178 | break;
179 | case Datatype.Type.Number:
180 | constant.value = this.inputReader.ReadSingle().ToString("0.000000");
181 | break;
182 | case Datatype.Type.String:
183 | int stringLength = this.inputReader.ReadInt32();
184 | if(this.luaFile.Game != LuaFile.SupportedGames.BlackOps2)
185 | {
186 | int unkInt = this.inputReader.ReadInt32();
187 | }
188 | constant.value = this.inputReader.ReadNullTerminatedString();
189 | break;
190 | case Datatype.Type.XHash:
191 | // TODO : Add support for switch to string
192 | constant.value = String.Format("0x{0:X}", this.inputReader.ReadUInt64() & 0xFFFFFFFFFFFFFFF);
193 | break;
194 | default:
195 | constant.value = "Unknown constant type";
196 | break;
197 | }
198 | // Add it to the array
199 | this.Constants[i] = constant;
200 | }
201 | }
202 |
203 | private void readSubFunctions()
204 | {
205 | this.SubFunctions = new LuaFunction[this.subFunctionCount];
206 | for (int i = 0; i < this.subFunctionCount; i++)
207 | {
208 | SubFunctions[i] = new LuaFunction(this.luaFile, this.tabLevel + 1, false, this);
209 | }
210 | }
211 |
212 | public void decompile(int tabLevel = 0, bool inline = false)
213 | {
214 | #if DEBUG
215 | this.writeLine(String.Format("-- OP Count: 0x{0:X}", this.instructionCount));
216 | this.writeLine(String.Format("-- Constant Count: 0x{0:X}", this.constantCount));
217 | this.writeLine(String.Format("-- Registers Count: 0x{0:X}", this.registerCount));
218 | this.writeLine(String.Format("-- UpValue Count: 0x{0:X}", this.upValsCount));
219 | this.writeLine(String.Format("-- SubFuncs Count: 0x{0:X}", this.subFunctionCount));
220 | #endif
221 |
222 | FindWhileLoops();
223 | FindDoWhileLoops();
224 | FindIfStatements();
225 | FindForEachLoops();
226 |
227 | for (int i = 0; i < this.instructionCount; i++)
228 | {
229 | this.Instructions[i].visited = false;
230 | }
231 |
232 | this.tabLevel = tabLevel;
233 | this.Registers = new LuaRegister[this.registerCount];
234 | for (int i = 0; i < this.registerCount; i++)
235 | {
236 | this.Registers[i] = new LuaRegister(i);
237 | }
238 |
239 | // Write the function header if it isnt the init function
240 | if (!this.isInitFunction)
241 | {
242 | // Look if we have a inline function
243 | if (inline)
244 | {
245 | outputWriter.Write("function (");
246 | }
247 | else if (this.newName == null)
248 | {
249 | write("local function " + String.Format("__FUNC_{0:X}_", this.startPosition) + "(", -1);
250 | }
251 | else
252 | {
253 | write("function " + this.newName + "(", -1);
254 | }
255 | int argIndex = 0, fixedIndex = 0;
256 | while (argIndex < this.parameterCount)
257 | {
258 | if (this.Upvalues.Contains("arg" + fixedIndex))
259 | {
260 | fixedIndex++;
261 | continue;
262 | }
263 | this.Registers[argIndex].initialze("arg" + fixedIndex);
264 | outputWriter.Write(((argIndex > 0) ? ", " : "") + "arg" + fixedIndex++);
265 | argIndex++;
266 | }
267 | if (this.usesVarArg)
268 | {
269 | if (this.parameterCount > 0)
270 | outputWriter.Write(", ");
271 | outputWriter.Write("...");
272 | }
273 | outputWriter.Write(")\n");
274 | }
275 |
276 | this.instructionPtr = 0;
277 | while (this.instructionPtr < this.instructionCount)
278 | {
279 | try
280 | {
281 | currentInstruction = this.Instructions[instructionPtr];
282 |
283 | if(HasCondition() || currentInstruction.visited == true)
284 | {
285 | nextInstruction();
286 | continue;
287 | }
288 | if(LuaOpCode.OPCodeFunctions.TryGetValue(currentInstruction.OpCode, out Func func))
289 | {
290 | func(this);
291 | }
292 | else
293 | {
294 | this.writeLine(String.Format("Unhandled OpCode: {0} ({1}, {2}, {3}, 0x{4:X})",
295 | currentInstruction.OpCode,
296 | currentInstruction.A,
297 | currentInstruction.B,
298 | currentInstruction.C,
299 | (int)currentInstruction.OpCode));
300 | }
301 | foreach (LuaCondition condition in this.conditions)
302 | {
303 | if (condition.line == this.instructionPtr)
304 | {
305 | if (condition.type == LuaCondition.Type.End)
306 | {
307 | this.tabLevel--;
308 | this.writeLine("end");
309 | }
310 | else if (condition.type == LuaCondition.Type.Else)
311 | {
312 | this.writeLine("else", -1);
313 | }
314 | }
315 | }
316 | }
317 | catch(Exception e)
318 | {
319 | Console.WriteLine("Error @ " + this.instructionPtr + ": " + e.Message + " & " + this.Instructions[instructionPtr].OpCode);
320 | }
321 | nextInstruction();
322 | }
323 |
324 | // Add an ending to the function
325 | if (!this.isInitFunction)
326 | {
327 | writeLine("end", -1);
328 | this.outputWriter.WriteLine();
329 | }
330 | }
331 |
332 | public bool HasCondition()
333 | {
334 | foreach(LuaCondition condition in this.conditions)
335 | {
336 | if(condition.line == this.instructionPtr && condition.prefix == LuaCondition.Prefix.none)
337 | {
338 | if(condition.type == LuaCondition.Type.Else || condition.type == LuaCondition.Type.End)
339 | {
340 | continue;
341 | }
342 |
343 | if (condition.type == LuaCondition.Type.Foreach)
344 | {
345 | int baseVal = this.Instructions[this.instructionPtr + this.currentInstruction.C + 2].A + 3;
346 | this.Registers[baseVal].value = "index" + baseVal;
347 | this.Registers[baseVal + 1].value = "value" + (baseVal + 1);
348 | this.writeLine(String.Format("for {0},{1} in {2}, {3}, {4} do",
349 | this.Registers[baseVal].value,
350 | this.Registers[baseVal + 1].value,
351 | this.Registers[baseVal - 3].value,
352 | this.Registers[baseVal - 2].value,
353 | this.Registers[baseVal - 1].value));
354 | this.tabLevel++;
355 | continue;
356 | }
357 |
358 | string expression = BuildExpression(condition);
359 | if(condition.type == LuaCondition.Type.If)
360 | {
361 | this.writeLine(String.Format("if {0} then", expression));
362 | this.tabLevel++;
363 | }
364 | else if(condition.type == LuaCondition.Type.DoWhile)
365 | {
366 | this.writeLine(String.Format("until {0}", expression));
367 | }
368 | return true;
369 | }
370 | }
371 | return false;
372 | }
373 |
374 | public string BuildExpression(LuaCondition masterCondition)
375 | {
376 | string Expression = ProcessInstructionReturnString();
377 | nextInstruction();
378 | int ChildExpressions = 0;
379 | foreach (LuaCondition condition in this.conditions)
380 | {
381 | if(condition.master == masterCondition)
382 | {
383 | ChildExpressions++;
384 | }
385 | }
386 | while(ChildExpressions > 0 && this.instructionPtr < this.instructionCount)
387 | {
388 | bool done = false;
389 | currentInstruction = this.Instructions[instructionPtr];
390 | foreach (LuaCondition condition in this.conditions)
391 | {
392 | if (condition.master == masterCondition && condition.line == this.instructionPtr)
393 | {
394 | Expression += String.Format(" {0} ", condition.prefix);
395 | Expression += ProcessInstructionReturnString();
396 | ChildExpressions--;
397 | done = true;
398 | }
399 | }
400 | if (!done)
401 | {
402 | ProcessInstructionReturnString();
403 | }
404 | nextInstruction();
405 |
406 | }
407 | return Expression;
408 | }
409 |
410 | public string ProcessInstructionReturnString()
411 | {
412 | if (LuaOpCode.OPCodeFunctions.TryGetValue(currentInstruction.OpCode, out Func func))
413 | {
414 | return func(this);
415 | }
416 | else
417 | {
418 | return (String.Format("Unhandled OpCode: {0} ({1}, {2}, {3}, 0x{4:X})",
419 | currentInstruction.OpCode,
420 | currentInstruction.A,
421 | currentInstruction.B,
422 | currentInstruction.C,
423 | (int)currentInstruction.OpCode));
424 | }
425 | }
426 |
427 | public void FindWhileLoops()
428 | {
429 | for(int i = 0; i < this.instructionCount; i++)
430 | {
431 | if(this.Instructions[i].OpCode == LuaOpCode.OpCodes.HKS_OPCODE_JMP)
432 | {
433 | if(this.Instructions[i].sBx < 0 && i + this.Instructions[i].sBx >= 0)
434 | {
435 | if(LuaOpCode.isConditionOPCode(this, i + this.Instructions[i].sBx + 1))
436 | {
437 | this.Instructions[i].visited = true;
438 | }
439 | }
440 | }
441 | }
442 | }
443 |
444 | public void FindDoWhileLoops()
445 | {
446 | for (int i = 0; i < this.instructionCount; i++)
447 | {
448 | if (this.Instructions[i].OpCode == LuaOpCode.OpCodes.HKS_OPCODE_JMP && this.Instructions[i].visited == false)
449 | {
450 | if (this.Instructions[i].sBx < 0 && i + this.Instructions[i].sBx >= 0)
451 | {
452 | if (LuaOpCode.isConditionOPCode(this, i - 1))
453 | {
454 | this.Instructions[i].visited = true;
455 | }
456 | }
457 | }
458 | }
459 | }
460 |
461 | public void FindIfStatements()
462 | {
463 | int lines = -1;
464 | LuaCondition master = null;
465 | for (int i = 0; i < this.instructionCount; i++)
466 | {
467 | if (this.Instructions[i].OpCode == LuaOpCode.OpCodes.HKS_OPCODE_JMP && this.Instructions[i].visited == false)
468 | {
469 | // Make sure the skip goes forward
470 | if (this.Instructions[i].sBx >= 0)
471 | {
472 | if (LuaOpCode.isConditionOPCode(this, i - 1))
473 | {
474 | // Skip the while loops
475 | if (this.Instructions[i + this.Instructions[i].sBx].OpCode == LuaOpCode.OpCodes.HKS_OPCODE_JMP && this.Instructions[i + this.Instructions[i].sBx].sBx < 0)
476 | {
477 | continue;
478 | }
479 | // OR statement
480 | if(lines == 0)
481 | {
482 | this.conditions.Add(new LuaCondition(i - 1, LuaCondition.Type.If, LuaCondition.Prefix.or, master));
483 | this.Instructions[i].visited = true;
484 | lines--;
485 | continue;
486 | }
487 | // and statement
488 | if(lines == this.Instructions[i].sBx)
489 | {
490 | this.conditions.Add(new LuaCondition(i - 1, LuaCondition.Type.If, LuaCondition.Prefix.and, master));
491 | this.Instructions[i].visited = true;
492 | lines--;
493 | continue;
494 | }
495 | master = new LuaCondition(i - 1, LuaCondition.Type.If, LuaCondition.Prefix.none);
496 | this.conditions.Add(master);
497 | lines = this.Instructions[i].sBx;
498 | this.Instructions[i].visited = true;
499 | }
500 | }
501 | }
502 | lines--;
503 | }
504 | List newConditions = new List();
505 | foreach (LuaCondition condition in this.conditions)
506 | {
507 | if(condition.master == null)
508 | {
509 | LuaCondition lastSon = condition;
510 | foreach (LuaCondition conditionSon in this.conditions)
511 | {
512 | if(conditionSon.master == condition)
513 | {
514 | if(conditionSon.prefix == LuaCondition.Prefix.or)
515 | {
516 | if (this.Instructions[lastSon.line].A == 1)
517 | this.Instructions[lastSon.line].A = 0;
518 | else
519 | this.Instructions[lastSon.line].A = 1;
520 | }
521 | lastSon = conditionSon;
522 | }
523 | }
524 | int skipLines = this.Instructions[lastSon.line + 1].sBx;
525 | if(this.Instructions[lastSon.line + 1 + skipLines].OpCode == LuaOpCode.OpCodes.HKS_OPCODE_JMP)
526 | {
527 | newConditions.Add(new LuaCondition(lastSon.line + 1 + skipLines, LuaCondition.Type.Else));
528 | int skipElseLines = this.Instructions[lastSon.line + 1 + skipLines].sBx;
529 | newConditions.Add(new LuaCondition(lastSon.line + 1 + skipLines + skipElseLines, LuaCondition.Type.End));
530 | }
531 | else
532 | {
533 | newConditions.Add(new LuaCondition(lastSon.line + 1 + skipLines, LuaCondition.Type.End));
534 | }
535 | }
536 | }
537 | foreach (LuaCondition condition in newConditions)
538 | {
539 | this.conditions.Add(condition);
540 | }
541 | }
542 |
543 | public void FindForEachLoops()
544 | {
545 | for (int i = 0; i < this.instructionCount; i++)
546 | {
547 | if (this.Instructions[i].OpCode == LuaOpCode.OpCodes.HKS_OPCODE_JMP && this.Instructions[i].visited == false)
548 | {
549 | if (this.Instructions[i].sBx < 0)
550 | {
551 | if(this.Instructions[i - 1].OpCode == LuaOpCode.OpCodes.HKS_OPCODE_TFORLOOP)
552 | {
553 | this.Instructions[i].visited = true;
554 |
555 | this.conditions.Add(new LuaCondition(i + this.Instructions[i].sBx, LuaCondition.Type.Foreach));
556 | this.conditions.Add(new LuaCondition(i, LuaCondition.Type.End));
557 | }
558 | }
559 | }
560 | }
561 | }
562 |
563 | public void nextInstruction()
564 | {
565 | this.instructionPtr++;
566 | }
567 |
568 | public void writeLine(string text, int extra = 0)
569 | {
570 | for (int i = 0; i < this.tabLevel + extra + this.endPositions.Count + this.tablePositions.Count; i++)
571 | {
572 | this.outputWriter.Write("\t");
573 | }
574 | this.outputWriter.Write(text + "\n");
575 | }
576 |
577 | public void write(string text, int extra = 0)
578 | {
579 | for (int i = 0; i < this.tabLevel + extra + this.endPositions.Count + this.tablePositions.Count; i++)
580 | {
581 | this.outputWriter.Write("\t");
582 | }
583 | this.outputWriter.Write(text);
584 | }
585 |
586 | private static byte GetBit(long input, int bit)
587 | {
588 | return (byte)((input >> bit) & 1);
589 | }
590 | }
591 | }
592 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/Lua/LuaInstruction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace CoDLUIDecompiler
8 | {
9 | class LuaInstruction
10 | {
11 | public byte A;
12 | public int B;
13 | public int C;
14 | public LuaOpCode.OpCodes OpCode;
15 | public int Bx;
16 | public int sBx;
17 | public bool visited = false;
18 |
19 | private LuaFunction function;
20 |
21 | public LuaInstruction(LuaFunction function)
22 | {
23 | this.function = function;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/Lua/LuaOpCode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using PhilLibX.IO;
7 |
8 | namespace CoDLUIDecompiler
9 | {
10 | class LuaOpCode
11 | {
12 | public enum OpCodes : byte
13 | {
14 | HKS_OPCODE_GETFIELD,
15 | HKS_OPCODE_TEST,
16 | HKS_OPCODE_CALL_I,
17 | HKS_OPCODE_CALL_C,
18 | HKS_OPCODE_EQ,
19 | HKS_OPCODE_EQ_BK,
20 | HKS_OPCODE_GETGLOBAL,
21 | HKS_OPCODE_MOVE,
22 | HKS_OPCODE_SELF,
23 | HKS_OPCODE_RETURN,
24 | HKS_OPCODE_GETTABLE_S,
25 | HKS_OPCODE_GETTABLE_N,
26 | HKS_OPCODE_GETTABLE,
27 | HKS_OPCODE_LOADBOOL,
28 | HKS_OPCODE_TFORLOOP,
29 | HKS_OPCODE_SETFIELD,
30 | HKS_OPCODE_SETTABLE_S,
31 | HKS_OPCODE_SETTABLE_S_BK,
32 | HKS_OPCODE_SETTABLE_N,
33 | HKS_OPCODE_SETTABLE_N_BK,
34 | HKS_OPCODE_SETTABLE,
35 | HKS_OPCODE_SETTABLE_BK,
36 | HKS_OPCODE_TAILCALL_I,
37 | HKS_OPCODE_TAILCALL_C,
38 | HKS_OPCODE_TAILCALL_M,
39 | HKS_OPCODE_LOADK,
40 | HKS_OPCODE_LOADNIL,
41 | HKS_OPCODE_SETGLOBAL,
42 | HKS_OPCODE_JMP,
43 | HKS_OPCODE_CALL_M,
44 | HKS_OPCODE_CALL,
45 | HKS_OPCODE_INTRINSIC_INDEX,
46 | HKS_OPCODE_INTRINSIC_NEWINDEX,
47 | HKS_OPCODE_INTRINSIC_SELF,
48 | HKS_OPCODE_INTRINSIC_INDEX_LITERAL,
49 | HKS_OPCODE_INTRINSIC_NEWINDEX_LITERAL,
50 | HKS_OPCODE_INTRINSIC_SELF_LITERAL,
51 | HKS_OPCODE_TAILCALL,
52 | HKS_OPCODE_GETUPVAL,
53 | HKS_OPCODE_SETUPVAL,
54 | HKS_OPCODE_ADD,
55 | HKS_OPCODE_ADD_BK,
56 | HKS_OPCODE_SUB,
57 | HKS_OPCODE_SUB_BK,
58 | HKS_OPCODE_MUL,
59 | HKS_OPCODE_MUL_BK,
60 | HKS_OPCODE_DIV,
61 | HKS_OPCODE_DIV_BK,
62 | HKS_OPCODE_MOD,
63 | HKS_OPCODE_MOD_BK,
64 | HKS_OPCODE_POW,
65 | HKS_OPCODE_POW_BK,
66 | HKS_OPCODE_NEWTABLE,
67 | HKS_OPCODE_UNM,
68 | HKS_OPCODE_NOT,
69 | HKS_OPCODE_LEN,
70 | HKS_OPCODE_LT,
71 | HKS_OPCODE_LT_BK,
72 | HKS_OPCODE_LE,
73 | HKS_OPCODE_LE_BK,
74 | HKS_OPCODE_SHIFT_LEFT,
75 | HKS_OPCODE_SHIFT_LEFT_BK,
76 | HKS_OPCODE_SHIFT_RIGHT,
77 | HKS_OPCODE_SHIFT_RIGHT_BK,
78 | HKS_OPCODE_BITWISE_AND,
79 | HKS_OPCODE_BITWISE_AND_BK,
80 | HKS_OPCODE_BITWISE_OR,
81 | HKS_OPCODE_BITWISE_OR_BK,
82 | HKS_OPCODE_CONCAT,
83 | HKS_OPCODE_TESTSET,
84 | HKS_OPCODE_FORPREP,
85 | HKS_OPCODE_FORLOOP,
86 | HKS_OPCODE_SETLIST,
87 | HKS_OPCODE_CLOSE,
88 | HKS_OPCODE_CLOSURE,
89 | HKS_OPCODE_VARARG,
90 | HKS_OPCODE_TAILCALL_I_R1,
91 | HKS_OPCODE_CALL_I_R1,
92 | HKS_OPCODE_SETUPVAL_R1,
93 | HKS_OPCODE_TEST_R1,
94 | HKS_OPCODE_NOT_R1,
95 | HKS_OPCODE_GETFIELD_R1,
96 | HKS_OPCODE_SETFIELD_R1,
97 | HKS_OPCODE_NEWSTRUCT,
98 | HKS_OPCODE_DATA,
99 | HKS_OPCODE_SETSLOTN,
100 | HKS_OPCODE_SETSLOTI,
101 | HKS_OPCODE_SETSLOT,
102 | HKS_OPCODE_SETSLOTS,
103 | HKS_OPCODE_SETSLOTMT,
104 | HKS_OPCODE_CHECKTYPE,
105 | HKS_OPCODE_CHECKTYPES,
106 | HKS_OPCODE_GETSLOT,
107 | HKS_OPCODE_GETSLOTMT,
108 | HKS_OPCODE_SELFSLOT,
109 | HKS_OPCODE_SELFSLOTMT,
110 | HKS_OPCODE_GETFIELD_MM,
111 | HKS_OPCODE_CHECKTYPE_D,
112 | HKS_OPCODE_GETSLOT_D,
113 | HKS_OPCODE_GETGLOBAL_MEM,
114 | HKS_OPCODE_MAX,
115 | HKS_OPCODE_DELETE,
116 | HKS_OPCODE_DELETE_BK,
117 | HKS_OPCODE_UNK,
118 | }
119 |
120 |
121 | public static Dictionary> OPCodeFunctions =
122 | new Dictionary>()
123 | {
124 | {LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD, OP_GetField},
125 | {LuaOpCode.OpCodes.HKS_OPCODE_TEST, OP_Test},
126 | {LuaOpCode.OpCodes.HKS_OPCODE_CALL_I, OP_Call_I},
127 | {LuaOpCode.OpCodes.HKS_OPCODE_EQ, OP_Eq},
128 | {LuaOpCode.OpCodes.HKS_OPCODE_EQ_BK, OP_EqBk},
129 | {LuaOpCode.OpCodes.HKS_OPCODE_GETGLOBAL, OP_GetGlobal},
130 | {LuaOpCode.OpCodes.HKS_OPCODE_MOVE, OP_Move},
131 | {LuaOpCode.OpCodes.HKS_OPCODE_SELF, OP_Self},
132 | {LuaOpCode.OpCodes.HKS_OPCODE_RETURN, OP_Return},
133 | {LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE_S, OP_GetTableS},
134 | {LuaOpCode.OpCodes.HKS_OPCODE_LOADBOOL, OP_LoadBool},
135 | {LuaOpCode.OpCodes.HKS_OPCODE_TFORLOOP, OP_TForLoop},
136 | {LuaOpCode.OpCodes.HKS_OPCODE_SETFIELD, OP_SetField},
137 | {LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_S, OP_SetTableS},
138 | {LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_S_BK, OP_SetTableSBk},
139 | {LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_I, OP_TailCallI},
140 | {LuaOpCode.OpCodes.HKS_OPCODE_LOADK, OP_LoadK},
141 | {LuaOpCode.OpCodes.HKS_OPCODE_LOADNIL, OP_LoadNil},
142 | {LuaOpCode.OpCodes.HKS_OPCODE_SETGLOBAL, OP_SetGlobal},
143 | {LuaOpCode.OpCodes.HKS_OPCODE_JMP, OP_Jmp},
144 | {LuaOpCode.OpCodes.HKS_OPCODE_GETUPVAL, OP_GetUpVal},
145 | {LuaOpCode.OpCodes.HKS_OPCODE_SETUPVAL, OP_SetUpVal},
146 | {LuaOpCode.OpCodes.HKS_OPCODE_ADD, OP_Add},
147 | {LuaOpCode.OpCodes.HKS_OPCODE_ADD_BK, OP_AddBk},
148 | {LuaOpCode.OpCodes.HKS_OPCODE_SUB, OP_Sub},
149 | {LuaOpCode.OpCodes.HKS_OPCODE_SUB_BK, OP_SubBk},
150 | {LuaOpCode.OpCodes.HKS_OPCODE_MUL, OP_Mul},
151 | {LuaOpCode.OpCodes.HKS_OPCODE_MUL_BK, OP_MulBk},
152 | {LuaOpCode.OpCodes.HKS_OPCODE_DIV, OP_Div},
153 | {LuaOpCode.OpCodes.HKS_OPCODE_DIV_BK, OP_DivBk},
154 | {LuaOpCode.OpCodes.HKS_OPCODE_MOD, OP_Mod},
155 | {LuaOpCode.OpCodes.HKS_OPCODE_MOD_BK, OP_ModBk},
156 | {LuaOpCode.OpCodes.HKS_OPCODE_POW, OP_Pow},
157 | {LuaOpCode.OpCodes.HKS_OPCODE_POW_BK, OP_PowBk},
158 | {LuaOpCode.OpCodes.HKS_OPCODE_NEWTABLE, OP_NewTable},
159 | {LuaOpCode.OpCodes.HKS_OPCODE_UNM, OP_Unm},
160 | {LuaOpCode.OpCodes.HKS_OPCODE_NOT, OP_Not},
161 | {LuaOpCode.OpCodes.HKS_OPCODE_LEN, OP_Len},
162 | {LuaOpCode.OpCodes.HKS_OPCODE_LT, OP_Lt},
163 | {LuaOpCode.OpCodes.HKS_OPCODE_LT_BK, OP_LtBk},
164 | {LuaOpCode.OpCodes.HKS_OPCODE_LE, OP_Le},
165 | {LuaOpCode.OpCodes.HKS_OPCODE_LE_BK, OP_LeBk},
166 | {LuaOpCode.OpCodes.HKS_OPCODE_SHIFT_LEFT, OP_ShiftLeft},
167 | {LuaOpCode.OpCodes.HKS_OPCODE_SHIFT_LEFT_BK, OP_ShiftLeftBk},
168 | {LuaOpCode.OpCodes.HKS_OPCODE_SHIFT_RIGHT, OP_ShiftRight},
169 | {LuaOpCode.OpCodes.HKS_OPCODE_SHIFT_RIGHT_BK, OP_ShiftRightBk},
170 | {LuaOpCode.OpCodes.HKS_OPCODE_BITWISE_AND, OP_BitWiseAnd},
171 | {LuaOpCode.OpCodes.HKS_OPCODE_BITWISE_AND_BK, OP_BitWiseAndBk},
172 | {LuaOpCode.OpCodes.HKS_OPCODE_BITWISE_OR, OP_BitWiseOr},
173 | {LuaOpCode.OpCodes.HKS_OPCODE_BITWISE_OR_BK, OP_BitWiseOrBk},
174 | {LuaOpCode.OpCodes.HKS_OPCODE_CONCAT, OP_ConCat},
175 | { LuaOpCode.OpCodes.HKS_OPCODE_TESTSET, OP_TestSet},
176 | {LuaOpCode.OpCodes.HKS_OPCODE_FORPREP, OP_ForPrep},
177 | {LuaOpCode.OpCodes.HKS_OPCODE_FORLOOP, OP_ForLoop},
178 | {LuaOpCode.OpCodes.HKS_OPCODE_SETLIST, OP_SetList},
179 | {LuaOpCode.OpCodes.HKS_OPCODE_CLOSE, OP_Close},
180 | {LuaOpCode.OpCodes.HKS_OPCODE_CLOSURE, OP_Closure},
181 | {LuaOpCode.OpCodes.HKS_OPCODE_VARARG, OP_VarArg},
182 | {LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_I_R1, OP_TailCallI},
183 | {LuaOpCode.OpCodes.HKS_OPCODE_CALL_I_R1, OP_Call_I},
184 | {LuaOpCode.OpCodes.HKS_OPCODE_TEST_R1, OP_Test},
185 | {LuaOpCode.OpCodes.HKS_OPCODE_NOT_R1, OP_Not},
186 | {LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD_R1, OP_GetField},
187 | {LuaOpCode.OpCodes.HKS_OPCODE_SETFIELD_R1, OP_SetField},
188 | {LuaOpCode.OpCodes.HKS_OPCODE_DATA, OP_Data},
189 | {LuaOpCode.OpCodes.HKS_OPCODE_GETGLOBAL_MEM, OP_GetGlobal},
190 | };
191 |
192 | public static string OP_GetField(LuaFunction function)
193 | {
194 | function.Registers[function.currentInstruction.A].value =
195 | function.Registers[function.currentInstruction.B].value + "." +
196 | function.Constants[function.currentInstruction.C].value;
197 | #if DEBUG
198 | function.writeLine(String.Format("-- r({0}) = r({1}).field({2}) // {3}",
199 | function.currentInstruction.A,
200 | function.currentInstruction.B,
201 | function.currentInstruction.C,
202 | function.Registers[function.currentInstruction.A].value));
203 | #endif
204 | return "";
205 | }
206 |
207 | public static string OP_Test(LuaFunction function)
208 | {
209 | return String.Format("{0}{1}",
210 | (function.currentInstruction.C == 1) ? "not " : "",
211 | function.Registers[function.currentInstruction.A].value);
212 | }
213 |
214 | public static string OP_Call_I(LuaFunction function)
215 | {
216 | string funcName = function.Registers[function.currentInstruction.A].value;
217 |
218 | int parameterCount = function.currentInstruction.B - 1;
219 | int returnValueCount = function.currentInstruction.C - 1;
220 | string parametersString = "";
221 |
222 | // Setting up the parameter string
223 | // Check if b >= 1
224 | // if it is, there are b - 1 parameters
225 | if (parameterCount > 0)
226 | {
227 | byte startIndex = 1;
228 | // If the functions gets called on something, we want to use 1 parameter less
229 | if (!(funcName.Contains(":") && parameterCount == 1))
230 | {
231 | if (funcName.Contains(":"))
232 | {
233 | startIndex = 2;
234 | }
235 |
236 | parametersString += function.Registers[function.currentInstruction.A + startIndex].value;
237 | for (int j = function.currentInstruction.A + startIndex + 1;
238 | j <= function.currentInstruction.A + parameterCount;
239 | j++)
240 | {
241 | parametersString += ", " + function.Registers[j].value;
242 | }
243 | }
244 | }
245 | // If b is 0
246 | // parameters range from a + 1 to the top of the stack
247 | else if (parameterCount < 0)
248 | {
249 | byte startIndex = 1;
250 | if (funcName.Contains(":"))
251 | {
252 | startIndex = 2;
253 | }
254 |
255 | parametersString += function.Registers[function.currentInstruction.A + startIndex].value;
256 | for (int j = function.currentInstruction.A + startIndex + 1;
257 | j <= function.Instructions[function.instructionPtr - 1].A;
258 | j++)
259 | {
260 | parametersString += ", " + function.Registers[j].value;
261 | }
262 | }
263 |
264 | // Setting up the return values
265 | // Check if c >= 1
266 | // if it is, there are c - 1 return values
267 | if (returnValueCount > 0)
268 | {
269 | string returnVars = function.Registers[function.currentInstruction.A].makeLocalVariable();
270 | for (int i = function.currentInstruction.A + 1;
271 | i < function.currentInstruction.A + returnValueCount;
272 | i++)
273 | {
274 | returnVars += ", " + function.Registers[i].makeLocalVariable();
275 | function.Registers[i].isInitialized = true;
276 | }
277 |
278 | function.writeLine(String.Format("{0}{1} = {2}({3})",
279 | (!function.Registers[function.currentInstruction.A].isInitialized) ? "local " : "",
280 | returnVars,
281 | funcName,
282 | parametersString));
283 | function.Registers[function.currentInstruction.A].isInitialized = true;
284 | for (int i = function.currentInstruction.A + 1;
285 | i < function.currentInstruction.A + returnValueCount;
286 | i++)
287 | {
288 | function.Registers[i].isInitialized = true;
289 | }
290 | }
291 | // We dont have return values
292 | else
293 | {
294 | if (function.Instructions[function.instructionPtr + 1].OpCode == OpCodes.HKS_OPCODE_CALL_I ||
295 | function.Instructions[function.instructionPtr + 1].OpCode == OpCodes.HKS_OPCODE_CALL_I_R1)
296 | {
297 | function.Registers[function.currentInstruction.A].value = funcName + "(" + parametersString + ")";
298 | return "";
299 | }
300 |
301 | function.writeLine(String.Format("{1}({2})",
302 | (returnValueCount == -1) ? "return " : "", // if c = 0 it returns the value straight away
303 | funcName,
304 | parametersString));
305 | }
306 |
307 | return "";
308 | }
309 |
310 | public static string OP_Eq(LuaFunction function)
311 | {
312 | return DoCondition(function, "==", "~=");
313 | }
314 |
315 | public static string OP_EqBk(LuaFunction function)
316 | {
317 | return DoConditionBk(function, "==", "~=");
318 | }
319 |
320 | public static string OP_GetGlobal(LuaFunction function)
321 | {
322 | function.Registers[function.currentInstruction.A]
323 | .changeTo(function.Constants[function.currentInstruction.Bx], true);
324 | function.Registers[function.currentInstruction.A].globalValue = true;
325 | #if DEBUG
326 | function.writeLine(String.Format("-- r({0}) = g[{1}] // {2}",
327 | function.currentInstruction.A,
328 | function.currentInstruction.Bx,
329 | function.Constants[function.currentInstruction.Bx].value));
330 | #endif
331 | return "";
332 | }
333 |
334 | public static string OP_Move(LuaFunction function)
335 | {
336 | function.Registers[function.currentInstruction.A].value =
337 | function.Registers[function.currentInstruction.B].value;
338 | #if DEBUG
339 | function.writeLine(String.Format("-- r({0}) = r({1}) // {2}",
340 | function.currentInstruction.A,
341 | function.currentInstruction.B,
342 | function.Registers[function.currentInstruction.A].value));
343 | #endif
344 | return "";
345 | }
346 |
347 | public static string OP_Self(LuaFunction function)
348 | {
349 | string cValue;
350 | if (function.currentInstruction.C > 255)
351 | {
352 | function.Registers[function.currentInstruction.A].value =
353 | function.Registers[function.currentInstruction.B].value + ":" +
354 | function.Constants[function.currentInstruction.C - 256].value;
355 | #if DEBUG
356 | function.writeLine(String.Format("-- r({0}) = r({1}):c[{2}] // {3}",
357 | function.currentInstruction.A,
358 | function.currentInstruction.B,
359 | function.currentInstruction.C - 256,
360 | function.Registers[function.currentInstruction.A].value));
361 | #endif
362 | }
363 | else
364 | {
365 | function.Registers[function.currentInstruction.A].value =
366 | function.Registers[function.currentInstruction.B].value + ":" +
367 | function.Registers[function.currentInstruction.C].value;
368 | #if DEBUG
369 | function.writeLine(String.Format("-- r({0}) = r({1}):r({2}) // {3}",
370 | function.currentInstruction.A,
371 | function.currentInstruction.B,
372 | function.currentInstruction.C,
373 | function.Registers[function.currentInstruction.A].value));
374 | #endif
375 | }
376 |
377 | function.Registers[function.currentInstruction.A].type = Datatype.Type.Function;
378 | return "";
379 | }
380 |
381 | public static string OP_Return(LuaFunction function)
382 | {
383 | // we dont want to write return at the end of every function, only if it actually does something
384 | // Also skip it if the previous opcode was a tailcall
385 | if (function.instructionPtr == function.instructionCount - 1 || (function.instructionPtr >= 1) &&
386 | (function.Instructions[function.instructionPtr - 1].OpCode == OpCodes.HKS_OPCODE_TAILCALL_I || function.Instructions[function.instructionPtr - 1].OpCode == OpCodes.HKS_OPCODE_TAILCALL_I_R1))
387 | {
388 | #if DEBUG
389 | function.writeLine("-- return");
390 | #endif
391 | return "";
392 | }
393 |
394 | string returns = "";
395 | if (function.currentInstruction.B > 1)
396 | {
397 | returns += function.Registers[function.currentInstruction.A].value;
398 | for (int i = function.currentInstruction.A + 1;
399 | i <= function.currentInstruction.A + function.currentInstruction.B - 2;
400 | i++)
401 | {
402 | returns += ", " + function.Registers[i];
403 | }
404 | }
405 |
406 | function.writeLine("return " + returns);
407 | return "";
408 | }
409 |
410 | public static string OP_GetTableS(LuaFunction function)
411 | {
412 | string cValue = getCValue(function);
413 | function.Registers[function.currentInstruction.A].value =
414 | function.Registers[function.currentInstruction.B].value + "[" + cValue + "]";
415 | #if DEBUG
416 | function.writeLine(String.Format("-- r({0}) = r({1})[{2}] // {3}",
417 | function.currentInstruction.A,
418 | function.currentInstruction.B,
419 | (function.currentInstruction.C > 255) ? String.Format("c[{0}]", function.currentInstruction.C - 256) : String.Format("r({0})", function.currentInstruction.C),
420 | function.Registers[function.currentInstruction.A].value));
421 | #endif
422 | return "";
423 | }
424 |
425 | public static string OP_LoadBool(LuaFunction function)
426 | {
427 | if (function.currentInstruction.B == 0)
428 | function.Registers[function.currentInstruction.A].value = "false";
429 | else
430 | function.Registers[function.currentInstruction.A].value = "true";
431 | function.Registers[function.currentInstruction.A].type = Datatype.Type.Boolean;
432 | #if DEBUG
433 | function.writeLine(String.Format("-- r({0}) = {1}{2}",
434 | function.currentInstruction.A,
435 | function.Registers[function.currentInstruction.A].value,
436 | (function.currentInstruction.C == 1) ? " // skip next opcode" : ""));
437 | #endif
438 | return "";
439 | }
440 |
441 | public static string OP_TForLoop(LuaFunction function)
442 | {
443 | return "";
444 | }
445 |
446 | public static string OP_SetField(LuaFunction function)
447 | {
448 | string cValue = getCValue(function);
449 | function.writeLine(String.Format("{0}.{1} = {2}",
450 | function.Registers[function.currentInstruction.A].value,
451 | function.Constants[function.currentInstruction.B].value,
452 | cValue
453 | ));
454 | return "";
455 | }
456 |
457 | public static string OP_SetTableS(LuaFunction function)
458 | {
459 | string cValue = getCValue(function);
460 | function.writeLine(String.Format("{0}[{1}] = {2}",
461 | function.Registers[function.currentInstruction.A].value,
462 | function.Registers[function.currentInstruction.B].value,
463 | cValue
464 | ));
465 | return "";
466 | }
467 |
468 | public static string OP_SetTableSBk(LuaFunction function)
469 | {
470 | string cValue = getCValue(function);
471 | function.writeLine(String.Format("{0}[{1}] = {2}",
472 | function.Registers[function.currentInstruction.A].value,
473 | function.Constants[function.currentInstruction.B].getString(),
474 | cValue
475 | ));
476 | return "";
477 | }
478 |
479 | public static string OP_TailCallI(LuaFunction function)
480 | {
481 | string funcName = function.Registers[function.currentInstruction.A].value;
482 |
483 | int parameterCount = function.currentInstruction.B - 1;
484 | string parametersString = "";
485 |
486 |
487 | // Setting up the parameter string
488 | // Check if b >= 1
489 | // if it is, there are b - 1 parameters
490 | if (parameterCount > 0)
491 | {
492 |
493 | byte startIndex = 1;
494 | // If the functions gets called on something, we want to use 1 parameter less
495 | if (!(funcName.Contains(":") && parameterCount == 1))
496 | {
497 | if (funcName.Contains(":"))
498 | {
499 | startIndex = 2;
500 | }
501 |
502 |
503 | parametersString += function.Registers[function.currentInstruction.A + startIndex].value;
504 | for (int j = function.currentInstruction.A + startIndex + 1;
505 | j <= function.currentInstruction.A + parameterCount;
506 | j++)
507 | {
508 | parametersString += ", " + function.Registers[j].value;
509 | }
510 | }
511 | }
512 | // If b is 0
513 | // parameters range from a + 1 to the top of the stack
514 | else if (parameterCount < 0)
515 | {
516 | byte startIndex = 1;
517 | if (funcName.Contains(":"))
518 | {
519 | startIndex = 2;
520 | }
521 |
522 | parametersString += function.Registers[function.currentInstruction.A + startIndex].value;
523 | for (int j = function.currentInstruction.A + startIndex + 1;
524 | j <= function.Instructions[function.instructionPtr - 1].A;
525 | j++)
526 | {
527 | parametersString += ", " + function.Registers[j].value;
528 | }
529 | }
530 | function.writeLine(String.Format("return {0}({1})",
531 | funcName,
532 | parametersString));
533 |
534 | return "";
535 | }
536 |
537 | public static string OP_LoadK(LuaFunction function)
538 | {
539 | function.Registers[function.currentInstruction.A]
540 | .changeTo(function.Constants[function.currentInstruction.Bx].getString());
541 | #if DEBUG
542 | function.writeLine(String.Format("-- r({0}) = c[{1}] // {2}",
543 | function.currentInstruction.A,
544 | function.currentInstruction.Bx,
545 | function.Registers[function.currentInstruction.A].value));
546 | #endif
547 | return "";
548 | }
549 |
550 | public static string OP_LoadNil(LuaFunction function)
551 | {
552 | for (int i = function.currentInstruction.A; i <= (function.currentInstruction.B); i++)
553 | {
554 | function.Registers[i].value = "nil";
555 | function.Registers[i].type = Datatype.Type.Nil;
556 | }
557 | #if DEBUG
558 | if (function.currentInstruction.B > function.currentInstruction.A)
559 | function.writeLine(String.Format("-- r({0} to {1}) inclusive = nil", function.currentInstruction.A, function.currentInstruction.B));
560 | else
561 | function.writeLine(String.Format("-- r({0}) = nil", function.currentInstruction.A));
562 | #endif
563 | return "";
564 | }
565 |
566 | public static string OP_SetGlobal(LuaFunction function)
567 | {
568 | function.writeLine(String.Format("{0} = {1}",
569 | function.Constants[function.currentInstruction.Bx].value,
570 | function.Registers[function.currentInstruction.A].value
571 | ));
572 | return "";
573 | }
574 |
575 | public static string OP_Jmp(LuaFunction function)
576 | {
577 | #if DEBUG
578 | function.writeLine(String.Format("-- skip the next [{0}] opcodes // advance {0} lines",
579 | function.currentInstruction.sBx));
580 | #endif
581 | return "";
582 | }
583 |
584 | public static string OP_GetUpVal(LuaFunction function)
585 | {
586 | #if DEBUG
587 | function.writeLine(String.Format("-- r({0}) = upval({1}) // {2}",
588 | function.currentInstruction.A,
589 | function.currentInstruction.B,
590 | function.Upvalues[function.currentInstruction.B]));
591 | #endif
592 | function.Registers[function.currentInstruction.A].value = function.Upvalues[function.currentInstruction.B];
593 | return "";
594 | }
595 |
596 | public static string OP_SetUpVal(LuaFunction function)
597 | {
598 | #if DEBUG
599 | function.writeLine(String.Format("-- upval({0}) = r({1}) // {2}",
600 | function.currentInstruction.B,
601 | function.currentInstruction.A,
602 | function.Registers[function.currentInstruction.A].value));
603 | #endif
604 | function.Upvalues[function.currentInstruction.B] = function.Registers[function.currentInstruction.A].value;
605 | return "";
606 | }
607 |
608 | public static string OP_Add(LuaFunction function)
609 | {
610 | return DoOperator(function, "+");
611 | }
612 |
613 | public static string OP_AddBk(LuaFunction function)
614 | {
615 | return DoOperatorBK(function, "+");
616 | }
617 |
618 | public static string OP_Sub(LuaFunction function)
619 | {
620 | return DoOperator(function, "-");
621 | }
622 |
623 | public static string OP_SubBk(LuaFunction function)
624 | {
625 | return DoOperatorBK(function, "-");
626 | }
627 |
628 | public static string OP_Mul(LuaFunction function)
629 | {
630 | return DoOperator(function, "*");
631 | }
632 |
633 | public static string OP_MulBk(LuaFunction function)
634 | {
635 | return DoOperatorBK(function, "*");
636 | }
637 |
638 | public static string OP_Div(LuaFunction function)
639 | {
640 | return DoOperator(function, "/");
641 | }
642 |
643 | public static string OP_DivBk(LuaFunction function)
644 | {
645 | return DoOperatorBK(function, "/");
646 | }
647 |
648 | public static string OP_Mod(LuaFunction function)
649 | {
650 | return DoOperator(function, "%");
651 | }
652 |
653 | public static string OP_ModBk(LuaFunction function)
654 | {
655 | return DoOperatorBK(function, "%");
656 | }
657 |
658 | public static string OP_Pow(LuaFunction function)
659 | {
660 | return DoOperator(function, "^");
661 | }
662 |
663 | public static string OP_PowBk(LuaFunction function)
664 | {
665 | return DoOperatorBK(function, "^");
666 | }
667 |
668 | public static string OP_NewTable(LuaFunction function)
669 | {
670 | if (function.currentInstruction.B == 0 && function.currentInstruction.C == 0)
671 | {
672 | function.Registers[function.currentInstruction.A].value = "{}";
673 | function.Registers[function.currentInstruction.A].type = Datatype.Type.Table;
674 | return "";
675 | }
676 |
677 | function.Registers[function.currentInstruction.A].makeLocalVariable();
678 | function.writeLine(String.Format("{0}{1} = {2}",
679 | (!function.Registers[function.currentInstruction.A].isInitialized) ? "local " : "",
680 | function.Registers[function.currentInstruction.A].value, "{}"
681 | ));
682 | function.Registers[function.currentInstruction.A].isInitialized = true;
683 | function.Registers[function.currentInstruction.A].globalValue = false;
684 | return "";
685 | }
686 |
687 | public static string OP_Unm(LuaFunction function)
688 | {
689 | function.Registers[function.currentInstruction.A].value =
690 | "-" + function.Registers[function.currentInstruction.B].value;
691 | return "";
692 | }
693 |
694 | public static string OP_Not(LuaFunction function)
695 | {
696 | function.Registers[function.currentInstruction.A].value =
697 | "(not " + function.Registers[function.currentInstruction.A].value + ")";
698 | return "";
699 | }
700 |
701 | public static string OP_Len(LuaFunction function)
702 | {
703 | function.Registers[function.currentInstruction.A].value =
704 | "#" + function.Registers[function.currentInstruction.A].value;
705 | return "";
706 | }
707 |
708 | public static string OP_Lt(LuaFunction function)
709 | {
710 | return DoCondition(function, "<", ">=");
711 | }
712 |
713 | public static string OP_LtBk(LuaFunction function)
714 | {
715 | return DoConditionBk(function, "<", ">=");
716 | }
717 |
718 | public static string OP_Le(LuaFunction function)
719 | {
720 | return DoCondition(function, "<=", ">");
721 | }
722 |
723 | public static string OP_LeBk(LuaFunction function)
724 | {
725 | return DoConditionBk(function, "<=", ">");
726 | }
727 |
728 | public static string OP_ShiftLeft(LuaFunction function)
729 | {
730 | return DoOperator(function, "<<");
731 | }
732 |
733 | public static string OP_ShiftLeftBk(LuaFunction function)
734 | {
735 | return DoOperatorBK(function, "<<");
736 | }
737 |
738 | public static string OP_ShiftRight(LuaFunction function)
739 | {
740 | return DoOperator(function, ">>");
741 | }
742 |
743 | public static string OP_ShiftRightBk(LuaFunction function)
744 | {
745 | return DoOperatorBK(function, ">>");
746 | }
747 |
748 | public static string OP_BitWiseAnd(LuaFunction function)
749 | {
750 | return DoOperator(function, "&");
751 | }
752 |
753 | public static string OP_BitWiseAndBk(LuaFunction function)
754 | {
755 | return DoOperatorBK(function, "&");
756 | }
757 |
758 | public static string OP_BitWiseOr(LuaFunction function)
759 | {
760 | return DoOperator(function, "|");
761 | }
762 |
763 | public static string OP_BitWiseOrBk(LuaFunction function)
764 | {
765 | return DoOperatorBK(function, "|");
766 | }
767 |
768 | public static string OP_ConCat(LuaFunction function)
769 | {
770 | string output = "(" + function.Registers[function.currentInstruction.B].value;
771 | string registers = "r(" + function.currentInstruction.B + ")";
772 | for (int i = function.currentInstruction.B + 1; i <= function.currentInstruction.C; i++)
773 | {
774 | output += " .. " + function.Registers[i].value;
775 | registers += "..r(" + i + ")";
776 | }
777 | output += ")";
778 | function.Registers[function.currentInstruction.A].value = output;
779 | #if DEBUG
780 | function.writeLine(String.Format("-- r({0}) = {1} // {2}",
781 | function.currentInstruction.A,
782 | registers,
783 | function.Registers[function.currentInstruction.A].value));
784 | #endif
785 | return "";
786 | }
787 |
788 | public static string OP_TestSet(LuaFunction function)
789 | {
790 | // TODO: Check this cuz idk if this is right for the second value
791 | function.Registers[function.currentInstruction.A].value = String.Format("({0} {1} {2})",
792 | function.Registers[function.currentInstruction.B].value,
793 | function.currentInstruction.B == 0 ? "and" : "or",
794 | function.Registers[function.currentInstruction.B + 1].value);
795 | #if DEBUG
796 | function.writeLine(String.Format("-- r({0}) = {1}",
797 | function.currentInstruction.A,
798 | function.Registers[function.currentInstruction.A].value));
799 | #endif
800 | return "";
801 | }
802 |
803 | public static string OP_ForPrep(LuaFunction function)
804 | {
805 | function.Registers[function.currentInstruction.A + 3].value = "index" + function.currentInstruction.A;
806 | function.writeLine(String.Format("for {0}={1}, {2}, {3} do",
807 | function.Registers[function.currentInstruction.A + 3].value,
808 | function.Registers[function.currentInstruction.A].value,
809 | function.Registers[function.currentInstruction.A + 1].value,
810 | function.Registers[function.currentInstruction.A + 2].value));
811 | function.tabLevel++;
812 | return "";
813 | }
814 |
815 | public static string OP_ForLoop(LuaFunction function)
816 | {
817 | function.tabLevel--;
818 | function.writeLine("end");
819 | return "";
820 | }
821 |
822 | public static string OP_SetList(LuaFunction function)
823 | {
824 | string tableString = "{";
825 | if (function.currentInstruction.B > 0)
826 | {
827 | tableString += function.Registers[function.currentInstruction.A + 1].value;
828 | if (function.currentInstruction.B > 1)
829 | {
830 | for (int j = function.currentInstruction.A + 2; j <= function.currentInstruction.A + function.currentInstruction.B; j++)
831 | {
832 | tableString += ", " + function.Registers[j].value;
833 | }
834 | }
835 | }
836 | tableString += "}";
837 |
838 | function.writeLine(String.Format("{0} = {1}",
839 | function.Registers[function.currentInstruction.A].value,
840 | tableString
841 | ));
842 | return "";
843 | }
844 |
845 | public static string OP_Close(LuaFunction function)
846 | {
847 | function.Registers[function.currentInstruction.A].value = "";
848 | return "";
849 | }
850 |
851 | public static string OP_Closure(LuaFunction function)
852 | {
853 | // Setting up all the upvalues
854 | int i = function.instructionPtr + 1;
855 | while(i < function.instructionCount && function.Instructions[i].OpCode == OpCodes.HKS_OPCODE_DATA)
856 | {
857 | if (function.Instructions[i].A == 1)
858 | {
859 | function.SubFunctions[function.currentInstruction.Bx].Upvalues.Add(function.Registers[function.Instructions[i].C].value);
860 | }
861 | else if (function.Instructions[i].A == 2)
862 | {
863 | function.SubFunctions[function.currentInstruction.Bx].Upvalues.Add(function.Upvalues[function.Instructions[i].C]);
864 | }
865 | else
866 | {
867 | Console.WriteLine("Closuse extra arg error: " + function.Instructions[i].A);
868 | }
869 | i++;
870 | }
871 | // Put the name in the register
872 | function.Registers[function.currentInstruction.A].value = String.Format("__FUNC_{0:X}_", function.SubFunctions[function.currentInstruction.Bx].startPosition);
873 | function.Registers[function.currentInstruction.A].type = Datatype.Type.Function;
874 |
875 | if ((function.Instructions[function.instructionPtr + 1].OpCode == OpCodes.HKS_OPCODE_SETFIELD || function.Instructions[function.instructionPtr + 1].OpCode == OpCodes.HKS_OPCODE_SETFIELD_R1) && function.Registers[function.Instructions[function.instructionPtr + 1].A].globalValue)
876 | {
877 | function.SubFunctions[function.currentInstruction.Bx].newName = String.Format("{0}.{1}",
878 | function.Registers[function.Instructions[function.instructionPtr + 1].A].value,
879 | function.Constants[function.Instructions[function.instructionPtr + 1].B].value
880 | );
881 | function.nextInstruction();
882 | }
883 | else if (function.Instructions[function.instructionPtr + 1].OpCode == OpCodes.HKS_OPCODE_SETGLOBAL)
884 | {
885 | function.SubFunctions[function.currentInstruction.Bx].newName = function.Constants[function.Instructions[function.instructionPtr + 1].Bx].value;
886 | function.nextInstruction();
887 | }
888 | // Move to the new functions
889 | long oldPos = function.inputReader.BaseStream.Position;
890 | function.inputReader.Seek(function.SubFunctions[function.currentInstruction.Bx].startPosition, SeekOrigin.Begin);
891 | // Start the function
892 | function.SubFunctions[function.currentInstruction.Bx].decompile(function.tabLevel + function.endPositions.Count + function.tablePositions.Count + 1);
893 | // move back
894 | function.inputReader.Seek(oldPos, SeekOrigin.Begin);
895 | return "";
896 | }
897 |
898 | public static string OP_VarArg(LuaFunction function)
899 | {
900 | function.Registers[function.currentInstruction.A].value = "...";
901 | return "";
902 | }
903 |
904 | public static string OP_Data(LuaFunction function)
905 | {
906 | return "";
907 | }
908 |
909 | public static string getCValue(LuaFunction function)
910 | {
911 | if (function.currentInstruction.C > 255)
912 | {
913 | return function.Constants[function.currentInstruction.C - 256].getString();
914 | }
915 | else
916 | {
917 | return function.Registers[function.currentInstruction.C].value;
918 | }
919 | }
920 |
921 | public static string DoOperator(LuaFunction function, string oper)
922 | {
923 | string cValue = getCValue(function);
924 | function.Registers[function.currentInstruction.A].value = String.Format("({0} {1} {2})",
925 | function.Registers[function.currentInstruction.B].value,
926 | oper,
927 | cValue);
928 | return "";
929 | }
930 |
931 | public static string DoOperatorBK(LuaFunction function, string oper)
932 | {
933 | function.Registers[function.currentInstruction.A].value = String.Format("({0} {1} {2})",
934 | function.Constants[function.currentInstruction.B].value,
935 | oper,
936 | function.Registers[function.currentInstruction.C].value);
937 | return "";
938 | }
939 |
940 | private static string DoCondition(LuaFunction function, string oper, string operFalse)
941 | {
942 | string cValue = getCValue(function);
943 | return String.Format("{0} {1} {2}",
944 | function.Registers[function.currentInstruction.B].value,
945 | (function.currentInstruction.A == 0) ? oper : operFalse,
946 | cValue);
947 | }
948 |
949 | private static string DoConditionBk(LuaFunction function, string oper, string operFalse)
950 | {
951 | return String.Format("{0} {1} {2}",
952 | function.Constants[function.currentInstruction.B].value,
953 | (function.currentInstruction.A == 0) ? oper : operFalse,
954 | function.Registers[function.currentInstruction.C].value);
955 | }
956 |
957 | public static bool isConditionOPCode(LuaFunction function, int ptr)
958 | {
959 | OpCodes OpCode = function.Instructions[ptr].OpCode;
960 | if (OpCode == OpCodes.HKS_OPCODE_EQ || OpCode == OpCodes.HKS_OPCODE_EQ_BK || OpCode == OpCodes.HKS_OPCODE_LE || OpCode == OpCodes.HKS_OPCODE_LE_BK ||
961 | OpCode == OpCodes.HKS_OPCODE_LT || OpCode == OpCodes.HKS_OPCODE_LT_BK || OpCode == OpCodes.HKS_OPCODE_TEST || OpCode == OpCodes.HKS_OPCODE_TEST_R1)
962 | return true;
963 | return false;
964 | }
965 | }
966 | }
967 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/Lua/LuaRegister.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace CoDLUIDecompiler
8 | {
9 | class LuaRegister
10 | {
11 | public string value = "";
12 | public int index;
13 | public Datatype.Type type;
14 | public bool globalValue = false;
15 | public bool isInitialized = false;
16 |
17 | public LuaRegister(int index)
18 | {
19 | this.isInitialized = false;
20 | this.index = index;
21 | this.globalValue = false;
22 | }
23 |
24 | public void changeTo(LuaConstant constant, bool isGlobal = false)
25 | {
26 | this.globalValue = isGlobal;
27 | this.value = constant.value;
28 |
29 | this.type = constant.type;
30 | }
31 |
32 | public void changeTo(string value)
33 | {
34 | this.value = value;
35 | }
36 |
37 | public string makeLocalVariable()
38 | {
39 | this.value = "registerVal" + this.index;
40 | return this.value;
41 | }
42 |
43 | public void initialze(string value)
44 | {
45 | this.value = value;
46 | this.isInitialized = true;
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/LuaRipper/Games/AdvancedWarfare.cs:
--------------------------------------------------------------------------------
1 | using PhilLibX;
2 | using PhilLibX.IO;
3 | using System;
4 | using System.IO;
5 | using System.Diagnostics;
6 | using System.Collections.Generic;
7 | using System.Runtime.InteropServices;
8 |
9 | namespace CoDLUIDecompiler.LuaRipper
10 | {
11 | class AdvancedWarfare
12 | {
13 | public struct LuaFile
14 | {
15 | ///
16 | /// Asset Name Hash
17 | ///
18 | public long NamePtr { get; set; }
19 |
20 | ///
21 | /// Data Size
22 | ///
23 | public Int32 DataSize { get; set; }
24 | public Int32 DataSize2 { get; set; }
25 |
26 | ///
27 | /// Asset Hash
28 | ///
29 | public long startLocation { get; set; }
30 | }
31 |
32 | public static void ExportLuaFIles(ProcessReader reader, long assetPoolsAddress, long assetSizesAddress, string gameType)
33 | {
34 | // Found the game
35 | Console.WriteLine("Found supported game: Call of Duty: Advanced Warfare");
36 |
37 | // Validate by XModel Name
38 | if (reader.ReadNullTerminatedString(reader.ReadInt64(reader.ReadInt64(assetPoolsAddress + 0x38) + 8)) == "fx")
39 | {
40 | var AssetPoolOffset = reader.ReadStruct(assetPoolsAddress + (8 * 59));
41 | var poolSize = reader.ReadStruct(assetSizesAddress + (4 * 59));
42 |
43 | Directory.CreateDirectory("s1_luafiles");
44 |
45 | int filesExported = 0;
46 |
47 | for (int i = 0; i < poolSize; i++)
48 | {
49 | var data = reader.ReadStruct(AssetPoolOffset + 8 + (i * 24));
50 |
51 | if (!(data.DataSize != 0 && data.DataSize2 == 2))
52 | continue;
53 |
54 | filesExported++;
55 |
56 | var RawData = reader.ReadBytes(data.startLocation, data.DataSize);
57 |
58 | string exportName = Path.Combine("s1_luafiles", reader.ReadNullTerminatedString(data.NamePtr));
59 |
60 | if (File.Exists(exportName) && new FileInfo(exportName).Length == data.DataSize)
61 | continue;
62 |
63 | Directory.CreateDirectory(Path.GetDirectoryName(exportName));
64 |
65 | File.WriteAllBytes(exportName, RawData);
66 | }
67 |
68 | Console.WriteLine("Exported {0} files", filesExported);
69 | }
70 | else
71 | {
72 | Console.WriteLine("Unsupported version of game found");
73 | }
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/LuaRipper/Games/BlackOps2.cs:
--------------------------------------------------------------------------------
1 | using PhilLibX;
2 | using PhilLibX.IO;
3 | using System;
4 | using System.IO;
5 | using System.Diagnostics;
6 | using System.Collections.Generic;
7 | using System.Runtime.InteropServices;
8 |
9 | namespace CoDLUIDecompiler.LuaRipper
10 | {
11 | class BlackOps2
12 | {
13 | ///
14 | /// LuaFile Asset
15 | ///
16 | public struct LuaFile
17 | {
18 | ///
19 | /// Asset Name Hash
20 | ///
21 | public UInt32 NamePtr { get; set; }
22 |
23 | ///
24 | /// Data Size
25 | ///
26 | public Int32 AssetSize { get; set; }
27 |
28 | ///
29 | /// Raw Data Pointer
30 | ///
31 | public Int32 RawDataPtr { get; set; }
32 | }
33 |
34 | public static void ExportLuaFIles(ProcessReader reader, long assetPoolsAddress, long assetSizesAddress, string gameType)
35 | {
36 | // Found the game
37 | Console.WriteLine("Found supported game: Call of Duty: Black Ops 2");
38 |
39 | // Validate by XModel Name
40 | if (reader.ReadNullTerminatedString(reader.ReadInt32(reader.ReadInt32(assetPoolsAddress + 0x14) + 4)) == "defaultvehicle")
41 | {
42 | var AssetPoolOffset = reader.ReadStruct(assetPoolsAddress + (4 * 41)) + 4;
43 | var poolSize = reader.ReadStruct(assetSizesAddress + (4 * 41));
44 |
45 | Directory.CreateDirectory("t6_luafiles");
46 |
47 | int filesExported = 0;
48 |
49 | for (int i = 0; i < poolSize; i++)
50 | {
51 | var data = reader.ReadStruct(AssetPoolOffset + (i * 12));
52 |
53 | if (!(data.AssetSize != 0))
54 | continue;
55 |
56 | filesExported++;
57 | var RawData = reader.ReadBytes(data.RawDataPtr, data.AssetSize);
58 |
59 | string exportName = Path.Combine("t6_luafiles", reader.ReadNullTerminatedString(data.NamePtr));
60 |
61 | if (Path.GetExtension(exportName) != ".lua" || File.Exists(exportName) && new FileInfo(exportName).Length == data.AssetSize)
62 | continue;
63 | Directory.CreateDirectory(Path.GetDirectoryName(exportName));
64 |
65 | File.WriteAllBytes(exportName, RawData);
66 | }
67 |
68 | Console.WriteLine("Exported {0} files", filesExported);
69 | }
70 | else
71 | {
72 | Console.WriteLine("Unsupported version of game found");
73 | }
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/LuaRipper/Games/BlackOps3.cs:
--------------------------------------------------------------------------------
1 | using PhilLibX;
2 | using PhilLibX.IO;
3 | using System;
4 | using System.IO;
5 | using System.Diagnostics;
6 | using System.Collections.Generic;
7 | using System.Runtime.InteropServices;
8 |
9 | namespace CoDLUIDecompiler.LuaRipper
10 | {
11 | class BlackOps3
12 | {
13 | public struct AssetPool
14 | {
15 | ///
16 | /// A pointer to the asset pool
17 | ///
18 | public long PoolPointer { get; set; }
19 |
20 | ///
21 | /// Entry Size
22 | ///
23 | public int AssetSize { get; set; }
24 |
25 | ///
26 | /// Max Asset Count/Pool Size
27 | ///
28 | public int PoolSize { get; set; }
29 |
30 | ///
31 | /// Null Padding
32 | ///
33 | public int Padding { get; set; }
34 |
35 | ///
36 | /// Numbers of Assets in this Pool
37 | ///
38 | public int AssetCount { get; set; }
39 |
40 | ///
41 | /// Next Free Header/Slot
42 | ///
43 | public long NextSlot { get; set; }
44 | }
45 |
46 | ///
47 | /// LuaFile Asset
48 | ///
49 | public struct LuaFile
50 | {
51 | ///
52 | /// Asset Name Hash
53 | ///
54 | public long NamePtr { get; set; }
55 |
56 | ///
57 | /// Data Size
58 | ///
59 | public Int32 AssetSize { get; set; }
60 |
61 | ///
62 | /// Raw Data Pointer
63 | ///
64 | public long RawDataPtr { get; set; }
65 | }
66 |
67 | public static void ExportLuaFIles(ProcessReader reader, long assetPoolsAddress, long assetSizesAddress, string gameType)
68 | {
69 | // Found the game
70 | Console.WriteLine("Found supported game: Call of Duty: Black Ops 3");
71 |
72 | // Get Base Address for ASLR and Scans
73 | long baseAddress = reader.GetBaseAddress();
74 |
75 | // Validate by XModel Name
76 | if (reader.ReadNullTerminatedString(reader.ReadInt64(reader.ReadInt64(baseAddress + assetPoolsAddress + 0x80))) == "void")
77 | {
78 | AssetPool LuaPoolData = reader.ReadStruct(baseAddress + assetPoolsAddress + 0x20 * 47);
79 |
80 | long address = LuaPoolData.PoolPointer;
81 | long endAddress = LuaPoolData.PoolSize * LuaPoolData.AssetSize + address;
82 |
83 | Directory.CreateDirectory("t7_luafiles");
84 | int filesExported = 0;
85 |
86 | for (int i = 0; i < LuaPoolData.PoolSize; i++)
87 | {
88 | var data = reader.ReadStruct(address + (i * LuaPoolData.AssetSize));
89 |
90 | if (!(data.AssetSize != 0))
91 | continue;
92 |
93 | filesExported++;
94 | var RawData = reader.ReadBytes(data.RawDataPtr, data.AssetSize);
95 |
96 | string exportName = Path.Combine("t7_luafiles", reader.ReadNullTerminatedString(data.NamePtr));
97 |
98 | if (Path.GetExtension(exportName) != ".lua" || File.Exists(exportName) && new FileInfo(exportName).Length == data.AssetSize)
99 | continue;
100 | Directory.CreateDirectory(Path.GetDirectoryName(exportName));
101 |
102 | File.WriteAllBytes(exportName, RawData);
103 | }
104 |
105 | Console.WriteLine("Exported {0} files", filesExported);
106 | }
107 | else
108 | {
109 | Console.WriteLine("Unsupported version of game found");
110 | }
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/LuaRipper/Games/BlackOps4.cs:
--------------------------------------------------------------------------------
1 | using PhilLibX;
2 | using PhilLibX.IO;
3 | using System;
4 | using System.IO;
5 | using System.Diagnostics;
6 | using System.Collections.Generic;
7 | using System.Runtime.InteropServices;
8 |
9 | namespace CoDLUIDecompiler.LuaRipper
10 | {
11 | class BlackOps4
12 | {
13 | ///
14 | /// Asset Pool Data
15 | ///
16 | public struct AssetPool
17 | {
18 | ///
19 | /// A pointer to the asset pool
20 | ///
21 | public long PoolPointer { get; set; }
22 |
23 | ///
24 | /// Entry Size
25 | ///
26 | public int AssetSize { get; set; }
27 |
28 | ///
29 | /// Max Asset Count/Pool Size
30 | ///
31 | public int PoolSize { get; set; }
32 |
33 | ///
34 | /// Null Padding
35 | ///
36 | public int Padding { get; set; }
37 |
38 | ///
39 | /// Numbers of Assets in this Pool
40 | ///
41 | public int AssetCount { get; set; }
42 |
43 | ///
44 | /// Next Free Header/Slot
45 | ///
46 | public long NextSlot { get; set; }
47 | }
48 |
49 | ///
50 | /// LuaFile Asset
51 | ///
52 | public struct LuaFile
53 | {
54 | ///
55 | /// Asset Name Hash
56 | ///
57 | public long Hash { get; set; }
58 |
59 | ///
60 | /// Asset Hash
61 | ///
62 | public ulong NullPointer { get; set; }
63 |
64 | ///
65 | /// Data Size
66 | ///
67 | public Int32 DataSize { get; set; }
68 |
69 | ///
70 | /// Asset Hash
71 | ///
72 | public Int32 UnknownHash1 { get; set; }
73 |
74 | ///
75 | /// Data startLocation
76 | ///
77 | public long startLocation { get; set; }
78 | }
79 |
80 | public static void ExportLuaFIles(ProcessReader reader, long assetPoolsAddress, long assetSizesAddress, string gameType)
81 | {
82 | // Found the game
83 | Console.WriteLine("Found supported game: Call of Duty: Black Ops 4");
84 |
85 | // Get Base Address for ASLR and Scans
86 | long baseAddress = reader.GetBaseAddress();
87 |
88 | // Validate by XModel Name
89 | if (reader.ReadUInt64(reader.ReadStruct(baseAddress + assetPoolsAddress + 0x20 * 0x4).PoolPointer) == 0x04647533e968c910)
90 | {
91 | AssetPool LuaPoolData = reader.ReadStruct(baseAddress + assetPoolsAddress + 0x20 * 0x67);
92 |
93 | long address = LuaPoolData.PoolPointer;
94 | long endAddress = LuaPoolData.PoolSize * LuaPoolData.AssetSize + address;
95 |
96 | Directory.CreateDirectory("t8_luafiles");
97 | int filesExported = 0;
98 | for (int i = 0; i < LuaPoolData.PoolSize; i++)
99 | {
100 | var data = reader.ReadStruct(address + (i * LuaPoolData.AssetSize));
101 |
102 | if (data.NullPointer != 0 || data.Hash == 0)
103 | continue;
104 | if (data.Hash >= address && data.Hash <= endAddress)
105 | continue;
106 |
107 | filesExported++;
108 | var RawData = reader.ReadBytes(data.startLocation, data.DataSize);
109 | ulong assetHash = (ulong)data.Hash & 0xFFFFFFFFFFFFFFF;
110 | string HashString, fileName;
111 | //if (!Program.AssetNameCache.Entries.TryGetValue(assetHash, out HashString))
112 | fileName = String.Format("t8_luafiles\\LuaFile_{0:x}.lua", assetHash);
113 | //else
114 | //fileName = String.Format("t8_luafiles\\{0}.lua", HashString);
115 | if (File.Exists(fileName) && new FileInfo(fileName).Length == data.DataSize)
116 | continue;
117 | File.WriteAllBytes(fileName, RawData);
118 | }
119 |
120 | Console.WriteLine("Exported {0} files", filesExported);
121 | }
122 | else
123 | {
124 | Console.WriteLine("Unsupported version of game found");
125 | }
126 | }
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/LuaRipper/Games/Ghosts.cs:
--------------------------------------------------------------------------------
1 | using PhilLibX;
2 | using PhilLibX.IO;
3 | using System;
4 | using System.IO;
5 | using System.Diagnostics;
6 | using System.Collections.Generic;
7 | using System.Runtime.InteropServices;
8 |
9 | namespace CoDLUIDecompiler.LuaRipper
10 | {
11 | class Ghosts
12 | {
13 | public struct LuaFile
14 | {
15 | ///
16 | /// Asset Name Hash
17 | ///
18 | public long NamePtr { get; set; }
19 |
20 | ///
21 | /// Data Size
22 | ///
23 | public Int32 DataSize { get; set; }
24 | public Int32 DataSize2 { get; set; }
25 |
26 | ///
27 | /// Asset Hash
28 | ///
29 | public long startLocation { get; set; }
30 | }
31 |
32 | public static void ExportLuaFIles(ProcessReader reader, long assetPoolsAddress, long assetSizesAddress, string gameType)
33 | {
34 | // Found the game
35 | Console.WriteLine("Found supported game: Call of Duty: Ghosts");
36 |
37 | // Validate by XModel Name
38 | if (reader.ReadNullTerminatedString(reader.ReadInt64(reader.ReadInt64(assetPoolsAddress + 0x20) + 8)) == "void")
39 | {
40 | var AssetPoolOffset = reader.ReadStruct(assetPoolsAddress + (8 * 54));
41 | var poolSize = reader.ReadStruct(assetSizesAddress + (4 * 54));
42 |
43 | Directory.CreateDirectory("iw6_luafiles");
44 |
45 | int filesExported = 0;
46 |
47 | for (int i = 0; i < poolSize; i++)
48 | {
49 | var data = reader.ReadStruct(AssetPoolOffset + 8 + (i * 24));
50 |
51 | if (!(data.DataSize != 0 && data.DataSize2 == 2))
52 | continue;
53 |
54 | filesExported++;
55 |
56 | var RawData = reader.ReadBytes(data.startLocation, data.DataSize);
57 |
58 | string exportName = Path.Combine("iw6_luafiles", reader.ReadNullTerminatedString(data.NamePtr));
59 |
60 | if (File.Exists(exportName) && new FileInfo(exportName).Length == data.DataSize)
61 | continue;
62 |
63 | Directory.CreateDirectory(Path.GetDirectoryName(exportName));
64 |
65 | File.WriteAllBytes(exportName, RawData);
66 | }
67 |
68 | Console.WriteLine("Exported {0} files", filesExported);
69 | }
70 | else
71 | {
72 | Console.WriteLine("Unsupported version of game found");
73 | }
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/LuaRipper/Games/InfiniteWarfare.cs:
--------------------------------------------------------------------------------
1 | using PhilLibX;
2 | using PhilLibX.IO;
3 | using System;
4 | using System.IO;
5 | using System.Diagnostics;
6 | using System.Collections.Generic;
7 | using System.Runtime.InteropServices;
8 |
9 | namespace CoDLUIDecompiler.LuaRipper
10 | {
11 | class InfiniteWarfare
12 | {
13 | ///
14 | /// LuaFile Asset
15 | ///
16 | public struct LuaFile
17 | {
18 | ///
19 | /// Asset Name Hash
20 | ///
21 | public long NamePtr { get; set; }
22 |
23 | ///
24 | /// Data Size
25 | ///
26 | public Int32 DataSize { get; set; }
27 | public Int32 DataSize2 { get; set; }
28 |
29 | ///
30 | /// Asset Hash
31 | ///
32 | public long startLocation { get; set; }
33 | }
34 |
35 | public static void ExportLuaFIles(ProcessReader reader, long assetPoolsAddress, long assetSizesAddress, string gameType)
36 | {
37 | // Found the game
38 | Console.WriteLine("Found supported game: Call of Duty: Infinite Warfare");
39 |
40 | // Validate by XModel Name
41 | if (reader.ReadNullTerminatedString(reader.ReadInt64(reader.ReadInt64(assetPoolsAddress + 0x40) + 8)) == "viewmodel_default")
42 | {
43 | var AssetPoolOffset = reader.ReadStruct(assetPoolsAddress + (8 * 59));
44 | var poolSize = reader.ReadStruct(assetSizesAddress + (4 * 59));
45 |
46 | Directory.CreateDirectory("iw7_luafiles");
47 |
48 | int filesExported = 0;
49 |
50 | for (int i = 0; i < poolSize; i++)
51 | {
52 | var data = reader.ReadStruct(AssetPoolOffset + 8 + (i * 24));
53 |
54 | if (!(data.DataSize != 0 && data.DataSize2 == 2))
55 | continue;
56 |
57 | filesExported++;
58 |
59 | var RawData = reader.ReadBytes(data.startLocation, data.DataSize);
60 |
61 | string exportName = Path.Combine("iw7_luafiles", reader.ReadNullTerminatedString(data.NamePtr));
62 |
63 | if (File.Exists(exportName) && new FileInfo(exportName).Length == data.DataSize)
64 | continue;
65 |
66 | Directory.CreateDirectory(Path.GetDirectoryName(exportName));
67 |
68 | File.WriteAllBytes(exportName, RawData);
69 | }
70 |
71 | Console.WriteLine("Exported {0} files", filesExported);
72 | }
73 | else
74 | {
75 | Console.WriteLine("Unsupported version of game found");
76 | }
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/LuaRipper/Games/ModernWarfareRM.cs:
--------------------------------------------------------------------------------
1 | using PhilLibX;
2 | using PhilLibX.IO;
3 | using System;
4 | using System.IO;
5 | using System.Diagnostics;
6 | using System.Collections.Generic;
7 | using System.Runtime.InteropServices;
8 |
9 | namespace CoDLUIDecompiler.LuaRipper
10 | {
11 | class ModernWarfareRM
12 | {
13 | public struct LuaFile
14 | {
15 | ///
16 | /// Asset Name Hash
17 | ///
18 | public long NamePtr { get; set; }
19 |
20 | ///
21 | /// Data Size
22 | ///
23 | public Int32 DataSize { get; set; }
24 | public Int32 DataSize2 { get; set; }
25 |
26 | ///
27 | /// Asset Hash
28 | ///
29 | public long startLocation { get; set; }
30 | }
31 |
32 | public static void ExportLuaFIles(ProcessReader reader, long assetPoolsAddress, long assetSizesAddress, string gameType)
33 | {
34 | // Found the game
35 | Console.WriteLine("Found supported game: Call of Duty: Modern Warfare Remastered");
36 |
37 | // Get Base Address for ASLR and Scans
38 | long baseAddress = reader.GetBaseAddress();
39 |
40 | // Validate by XModel Name
41 | if (reader.ReadNullTerminatedString(reader.ReadInt64(reader.ReadInt64(baseAddress + assetPoolsAddress + 0x38) + 8)) == "fx")
42 | {
43 | var AssetPoolOffset = reader.ReadStruct(baseAddress + assetPoolsAddress + (8 * 61));
44 | var poolSize = reader.ReadStruct(baseAddress + assetSizesAddress + (4 * 61));
45 |
46 | Directory.CreateDirectory("h1_luafiles");
47 |
48 | int filesExported = 0;
49 | for (int i = 0; i < poolSize; i++)
50 | {
51 | var data = reader.ReadStruct(AssetPoolOffset + 8 + (i * 24));
52 |
53 | if (!(data.DataSize != 0 && data.DataSize2 == 2))
54 | continue;
55 |
56 | filesExported++;
57 |
58 | var RawData = reader.ReadBytes(data.startLocation, data.DataSize);
59 |
60 | string exportName = Path.Combine("h1_luafiles", reader.ReadNullTerminatedString(data.NamePtr));
61 |
62 | if (File.Exists(exportName) && new FileInfo(exportName).Length == data.DataSize)
63 | continue;
64 |
65 | Directory.CreateDirectory(Path.GetDirectoryName(exportName));
66 |
67 | File.WriteAllBytes(exportName, RawData);
68 | }
69 |
70 | Console.WriteLine("Exported {0} files", filesExported);
71 | }
72 | else
73 | {
74 | Console.WriteLine("Unsupported version of game found");
75 | }
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/LuaRipper/Games/WorldWarII.cs:
--------------------------------------------------------------------------------
1 | using PhilLibX;
2 | using PhilLibX.IO;
3 | using System;
4 | using System.IO;
5 | using System.Diagnostics;
6 | using System.Collections.Generic;
7 | using System.Runtime.InteropServices;
8 |
9 | namespace CoDLUIDecompiler.LuaRipper
10 | {
11 | class WorldWarII
12 | {
13 | ///
14 | /// LuaFile Asset
15 | ///
16 | public struct LuaFile
17 | {
18 | ///
19 | /// Asset Name Hash
20 | ///
21 | public long NamePtr { get; set; }
22 |
23 | ///
24 | /// Data Size
25 | ///
26 | public Int32 DataSize { get; set; }
27 | public Int32 DataSize2 { get; set; }
28 |
29 | ///
30 | /// Asset Hash
31 | ///
32 | public long startLocation { get; set; }
33 | }
34 |
35 | public static void ExportLuaFIles(ProcessReader reader, long assetPoolsAddress, long assetSizesAddress, string gameType)
36 | {
37 | // Found the game
38 | Console.WriteLine("Found supported game: Call of Duty: World War II");
39 |
40 | // Validate by XModel Name
41 | if (reader.ReadNullTerminatedString(reader.ReadInt64(reader.ReadInt64(reader.GetBaseAddress() + assetPoolsAddress + 0x50) + 8)) == "empty_model")
42 | {
43 | // Get Base Address for ASLR and Scans
44 | long baseAddress = reader.GetBaseAddress();
45 |
46 | var AssetPoolOffset = reader.ReadStruct(baseAddress + assetPoolsAddress + (8 * 69));
47 | var poolSize = reader.ReadStruct(AssetPoolOffset + 4 * 69);
48 |
49 | Directory.CreateDirectory("s2_luafiles");
50 |
51 | int filesExported = 0;
52 |
53 | for (int i = 0; i < poolSize; i++)
54 | {
55 | var data = reader.ReadStruct(AssetPoolOffset + 8 + (i * 24));
56 |
57 | if (!(data.DataSize != 0 && data.DataSize2 == 2))
58 | continue;
59 |
60 | filesExported++;
61 | var RawData = reader.ReadBytes(data.startLocation, data.DataSize);
62 |
63 | string exportName = Path.Combine("s2_luafiles", reader.ReadNullTerminatedString(data.NamePtr));
64 |
65 | if (File.Exists(exportName) && new FileInfo(exportName).Length == data.DataSize)
66 | continue;
67 | Directory.CreateDirectory(Path.GetDirectoryName(exportName));
68 |
69 | File.WriteAllBytes(exportName, RawData);
70 | }
71 |
72 | Console.WriteLine("Exported {0} files", filesExported);
73 | }
74 | else
75 | {
76 | Console.WriteLine("Unsupported version of game found");
77 | }
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/LuaRipper/MemoryLoading.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.IO;
5 | using System.Reflection;
6 | using PhilLibX;
7 | using PhilLibX.IO;
8 |
9 | namespace CoDLUIDecompiler
10 | {
11 | ///
12 | /// Game Definition (AssetDB Address, Sizes Address, Game Type ID (MP, SP, ZM, etc.), Export Method
13 | ///
14 | using GameDefinition = Tuple>;
15 |
16 | class MemoryLoading
17 | {
18 | static readonly Dictionary Games = new Dictionary()
19 | {
20 | // Call of Duty: Black Ops 2
21 | { "t6zm", new GameDefinition(0xD41240, 0xD40E80, "zm", LuaRipper.BlackOps2.ExportLuaFIles) },
22 | { "t6mp", new GameDefinition(0xD4B340, 0xD4AF80, "mp", LuaRipper.BlackOps2.ExportLuaFIles) },
23 | { "t6sp", new GameDefinition(0xBD46B8, 0xBD42F8, "sp", LuaRipper.BlackOps2.ExportLuaFIles) },
24 | // Call of Duty: Ghosts
25 | { "iw6mp64_ship", new GameDefinition(0x1409E4F20, 0x1409E4E20, "mp", LuaRipper.Ghosts.ExportLuaFIles) },
26 | { "iw6sp64_ship", new GameDefinition(0x14086DCB0, 0x14086DBB0, "sp", LuaRipper.Ghosts.ExportLuaFIles) },
27 | // Call of Duty: Advanced Warfare
28 | { "s1_mp64_ship", new GameDefinition(0x1409B40D0, 0x1409B4B90, "mp", LuaRipper.AdvancedWarfare.ExportLuaFIles) },
29 | { "s1_sp64_ship", new GameDefinition(0x140804690, 0x140804140, "sp", LuaRipper.AdvancedWarfare.ExportLuaFIles) },
30 | // Call of Duty: Black Ops 3
31 | { "BlackOps3", new GameDefinition(0x93FA290, 0x4D4F100, "core", LuaRipper.BlackOps3.ExportLuaFIles) },
32 | // Call of Duty: Infinite Warfare
33 | { "iw7_ship", new GameDefinition(0x1414663D0, 0x141466290, "core", LuaRipper.InfiniteWarfare.ExportLuaFIles) },
34 | // Call of Duty: Modern Warfare Remastered
35 | { "h1_mp64_ship", new GameDefinition(0x10B4460, 0x10B3C80, "mp", LuaRipper.ModernWarfareRM.ExportLuaFIles) },
36 | { "h1_sp64_ship", new GameDefinition(0xEC9FB0, 0xEC97D0, "sp", LuaRipper.ModernWarfareRM.ExportLuaFIles) },
37 | // Call of Duty: World War II
38 | { "s2_mp64_ship", new GameDefinition(0xC05370, 0xC05370, "mp", LuaRipper.WorldWarII.ExportLuaFIles) },
39 | { "s2_sp64_ship", new GameDefinition(0x9483F0, 0xBCC5E0, "sp", LuaRipper.WorldWarII.ExportLuaFIles) },
40 | // Call of Duty: Black Ops 4
41 | { "BlackOps4", new GameDefinition(0x88788D0, 0x74FDED0, "core", LuaRipper.BlackOps4.ExportLuaFIles) },
42 | };
43 |
44 | ///
45 | /// Looks for matching game and loads BSP from it
46 | ///
47 | public static void LoadGame()
48 | {
49 | try
50 | {
51 | // Get all processes
52 | var processes = Process.GetProcesses();
53 |
54 | // Loop through them, find match
55 | foreach (var process in processes)
56 | {
57 | // Check for it in dictionary
58 | if (Games.TryGetValue(process.ProcessName, out var game))
59 | {
60 | // Export it
61 | game.Item4(new ProcessReader(process), game.Item1, game.Item2, game.Item3);
62 |
63 | // Done
64 | return;
65 | }
66 | }
67 |
68 | // Failed
69 | Console.WriteLine("Failed to find a supported game, please ensure one of them is running.");
70 | }
71 | catch (Exception e)
72 | {
73 | Console.WriteLine("An unhandled exception has occured:");
74 | Console.WriteLine(e);
75 | }
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.IO;
5 | using System.Threading.Tasks;
6 |
7 | namespace CoDLUIDecompiler
8 | {
9 | class Program
10 | {
11 | static void Main(string[] args)
12 | {
13 | Console.WriteLine("CoD LUI Decompiler by JariK");
14 | string[] files = new string[1];
15 | if (args.Length == 0)
16 | {
17 | MemoryLoading.LoadGame();
18 | Console.WriteLine("Give the folder that you want to decompile: ");
19 | string folder = Console.ReadLine();
20 | //folder = @"../Debug";
21 | if (Directory.Exists(folder))
22 | {
23 | files = Directory.GetFiles(folder, "*.lua*", SearchOption.AllDirectories);
24 | }
25 | }
26 | else
27 | {
28 | files = args.Where(x => (Path.GetExtension(x) == ".lua" || Path.GetExtension(x) == ".luac") && File.Exists(x)).ToArray();
29 | }
30 | foreach (string fileName in files)
31 | {
32 | if (Path.GetExtension(fileName) != ".lua" && Path.GetExtension(fileName) != ".luac")
33 | {
34 | continue;
35 | }
36 | Console.WriteLine("Decompiling file: " + Path.GetFileName(fileName));
37 | new LuaFile(fileName);
38 |
39 | }
40 | Console.ReadLine();
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("CoDLUIDecompiler")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("CoDLUIDecompiler")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("086385a5-ba10-468d-87fa-5c00ffc55ec3")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/Util/PhilLibX/ByteUtil.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------
2 | // PhilLibX - My Utility Library
3 | // Copyright(c) 2018 Philip/Scobalula
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | // ------------------------------------------------------------------------
23 | // File: ByteUtil.cs
24 | // Author: Philip/Scobalula
25 | // Description: Utilities for working with Bytes and Bits
26 | using System.Collections.Generic;
27 | using System.Text;
28 |
29 | namespace PhilLibX
30 | {
31 | ///
32 | /// Utilities for working with Bytes and Bits
33 | ///
34 | public class ByteUtil
35 | {
36 | ///
37 | /// Reads a null terminated string from a byte array
38 | ///
39 | /// Byte Array input
40 | /// Start Index
41 | /// Resulting string
42 | public static string ReadNullTerminatedString(byte[] input, int startIndex)
43 | {
44 | List result = new List();
45 |
46 | for (int i = startIndex; i < input.Length && input[i] != 0; i++)
47 | result.Add(input[i]);
48 |
49 | return Encoding.ASCII.GetString(result.ToArray());
50 | }
51 |
52 | ///
53 | /// Returns the value of the bit in the given integer
54 | ///
55 | /// Integer Input
56 | /// Position
57 | /// Result
58 | public static byte GetBit(long input, int bit)
59 | {
60 | return (byte)((input >> bit) & 1);
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/Util/PhilLibX/IO/IOExtensions.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------
2 | // PhilLibX - My Utility Library
3 | // Copyright(c) 2018 Philip/Scobalula
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | // ------------------------------------------------------------------------
23 | // File: IO/IOExtensions.cs
24 | // Author: Philip/Scobalula
25 | // Description: IO Utilities/Extensions for reading null terminated strings, scanning files, etc.
26 | using System;
27 | using System.Collections.Generic;
28 | using System.IO;
29 | using System.Text;
30 |
31 | namespace PhilLibX.IO
32 | {
33 | ///
34 | /// IO Utilities/Extensions
35 | ///
36 | static class IOExtensions
37 | {
38 | ///
39 | /// Reads a string terminated by a null byte
40 | ///
41 | /// Read String
42 | public static string ReadNullTerminatedString(this BinaryReader br, int maxSize = -1)
43 | {
44 | // Create String Builder
45 | StringBuilder str = new StringBuilder();
46 | // Current Byte Read
47 | int byteRead;
48 | // Size of String
49 | int size = 0;
50 | // Loop Until we hit terminating null character
51 | while ((byteRead = br.BaseStream.ReadByte()) != 0x0 && size++ != maxSize)
52 | str.Append(Convert.ToChar(byteRead));
53 | // Ship back Result
54 | return str.ToString();
55 | }
56 |
57 | ///
58 | /// Reads a string of fixed size
59 | ///
60 | /// Size of string in bytes
61 | /// Read String
62 | public static string ReadFixedString(this BinaryReader br, int numBytes)
63 | {
64 | // Purge Null Bytes and Return
65 | return Encoding.ASCII.GetString(br.ReadBytes(numBytes)).TrimEnd('\0');
66 | }
67 |
68 | ///
69 | /// Sets the position of the Base Stream
70 | ///
71 | ///
72 | /// Offset to seek to.
73 | /// Seek Origin
74 | public static void Seek(this BinaryReader br, long offset, SeekOrigin seekOrigin)
75 | {
76 | // Set stream position
77 | br.BaseStream.Seek(offset, seekOrigin);
78 | }
79 |
80 | ///
81 | /// Finds occurences of a string in the stream
82 | ///
83 | /// Reader to use for scanning
84 | /// String Needle to search for
85 | /// Stops at first result
86 | /// Resulting offsets
87 | public static long[] FindString(this BinaryReader br, string needle, bool firstOccurence = false)
88 | {
89 | // Convert to bytes and scan
90 | return br.FindBytes(Encoding.ASCII.GetBytes(needle), firstOccurence);
91 | }
92 |
93 | ///
94 | /// Finds occurences of bytes in the stream
95 | ///
96 | /// Reader to use for scanning
97 | /// Byte Array Needle to search for
98 | /// Stops at first result
99 | /// Resulting offsets
100 | public static long[] FindBytes(this BinaryReader br, byte[] needle, bool firstOccurence = false)
101 | {
102 | // List of offsets in file.
103 | List offsets = new List();
104 |
105 | // Buffer
106 | byte[] buffer = new byte[1048576];
107 |
108 | // Bytes Read
109 | int bytesRead = 0;
110 |
111 | // Starting Offset
112 | long readBegin = br.BaseStream.Position;
113 |
114 | // Needle Index
115 | int needleIndex = 0;
116 |
117 | // Byte Array Index
118 | int bufferIndex = 0;
119 |
120 | // Read chunk of file
121 | while ((bytesRead = br.BaseStream.Read(buffer, 0, buffer.Length)) != 0)
122 | {
123 | // Loop through byte array
124 | for (bufferIndex = 0; bufferIndex < bytesRead; bufferIndex++)
125 | {
126 | // Check if current bytes match
127 | if (needle[needleIndex] == buffer[bufferIndex])
128 | {
129 | // Increment
130 | needleIndex++;
131 |
132 | // Check if we have a match
133 | if (needleIndex == needle.Length)
134 | {
135 | // Add Offset
136 | offsets.Add(readBegin + bufferIndex + 1 - needle.Length);
137 |
138 | // Reset Index
139 | needleIndex = 0;
140 |
141 | // If only first occurence, end search
142 | if (firstOccurence)
143 | return offsets.ToArray();
144 | }
145 | }
146 | else
147 | {
148 | // Reset Index
149 | needleIndex = 0;
150 | }
151 | }
152 | // Set next offset
153 | readBegin += bytesRead;
154 | }
155 | // Return offsets as an array
156 | return offsets.ToArray();
157 | }
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/Util/PhilLibX/IO/MemoryUtil.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------
2 | // PhilLibX - My Utility Library
3 | // Copyright(c) 2018 Philip/Scobalula
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | // ------------------------------------------------------------------------
23 | // File: IO/MemoryUtil.cs
24 | // Author: Philip/Scobalula
25 | // Description: Utilities for Reading Process Memory
26 | using System;
27 | using System.Collections.Generic;
28 | using System.Runtime.InteropServices;
29 | using System.Text;
30 |
31 | namespace PhilLibX.IO
32 | {
33 | ///
34 | /// Utilities for Reading Process Memory
35 | ///
36 | public class MemoryUtil
37 | {
38 | ///
39 | /// Required to read memory in a process using ReadProcessMemory.
40 | ///
41 | public const int ProcessVMRead = 0x0010;
42 |
43 | ///
44 | /// Required to write to memory in a process using WriteProcessMemory.
45 | ///
46 | public const int ProcessVMWrite = 0x0020;
47 |
48 | ///
49 | /// Reads bytes from a Processes Memory and returns a byte array of read data.
50 | ///
51 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process.
52 | /// The address of the data to be read.
53 | /// The number of bytes to be read from the specified process.
54 | /// Bytes read
55 | public static byte[] ReadBytes(IntPtr processHandle, long address, int numBytes)
56 | {
57 | // Resulting buffer
58 | byte[] buffer = new byte[numBytes];
59 | // Request ReadProcessMemory
60 | NativeMethods.ReadProcessMemory((int)processHandle, address, buffer, buffer.Length, out int bytesRead);
61 | // Return result
62 | return buffer;
63 | }
64 |
65 | ///
66 | /// Reads a 64Bit Integer from a Processes Memory
67 | ///
68 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process.
69 | /// The address of the data to be read.
70 | /// Resulting Data
71 | public static long ReadInt64(IntPtr processHandle, long address)
72 | {
73 | return BitConverter.ToInt64(ReadBytes(processHandle, address, 8), 0);
74 | }
75 |
76 | ///
77 | /// Reads an unsigned 64Bit Integer from a Processes Memory
78 | ///
79 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process.
80 | /// The address of the data to be read.
81 | /// Resulting Data
82 | public static ulong ReadUInt64(IntPtr processHandle, long address)
83 | {
84 | return BitConverter.ToUInt64(ReadBytes(processHandle, address, 8), 0);
85 | }
86 |
87 | ///
88 | /// Reads a 32Bit Integer from a Processes Memory
89 | ///
90 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process.
91 | /// The address of the data to be read.
92 | /// Resulting Data
93 | public static int ReadInt32(IntPtr processHandle, long address)
94 | {
95 | return BitConverter.ToInt32(ReadBytes(processHandle, address, 4), 0);
96 | }
97 |
98 | ///
99 | /// Reads an unsigned 32Bit Integer from a Processes Memory
100 | ///
101 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process.
102 | /// The address of the data to be read.
103 | /// Resulting Data
104 | public static uint ReadUInt32(IntPtr processHandle, long address)
105 | {
106 | return BitConverter.ToUInt32(ReadBytes(processHandle, address, 4), 0);
107 | }
108 |
109 | ///
110 | /// Reads a 16Bit Integer from a Processes Memory
111 | ///
112 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process.
113 | /// The address of the data to be read.
114 | /// Resulting Data
115 | public static short ReadInt16(IntPtr processHandle, long address)
116 | {
117 | return BitConverter.ToInt16(ReadBytes(processHandle, address, 4), 0);
118 | }
119 |
120 | ///
121 | /// Reads an unsigned 16Bit Integer from a Processes Memory
122 | ///
123 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process.
124 | /// The address of the data to be read.
125 | /// Resulting Data
126 | public static ushort ReadUInt16(IntPtr processHandle, long address)
127 | {
128 | return BitConverter.ToUInt16(ReadBytes(processHandle, address, 2), 0);
129 | }
130 |
131 | ///
132 | /// Reads a 4 byte single precision floating point number from a Processes Memory
133 | ///
134 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process.
135 | /// The address of the data to be read.
136 | /// Resulting Data
137 | public static float ReadSingle(IntPtr processHandle, long address)
138 | {
139 | return BitConverter.ToSingle(ReadBytes(processHandle, address, 2), 0);
140 | }
141 |
142 | ///
143 | /// Reads an 8 byte double precision floating point number from a Processes Memory
144 | ///
145 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process.
146 | /// The address of the data to be read.
147 | /// Resulting Data
148 | public static double ReadDouble(IntPtr processHandle, long address)
149 | {
150 | return BitConverter.ToDouble(ReadBytes(processHandle, address, 8), 0);
151 | }
152 |
153 | ///
154 | /// Reads a string from a processes' memory terminated by a null byte.
155 | ///
156 | /// Process Handle Pointer
157 | /// Memory Address
158 | /// Buffer Read Size
159 | /// Resulting String
160 | public static string ReadNullTerminatedString(IntPtr processHandle, long address, int bufferSize = 0xFF)
161 | {
162 | List result = new List();
163 |
164 | byte[] buffer = ReadBytes(processHandle, address, bufferSize);
165 |
166 | while (true)
167 | {
168 | for (int i = 0; i < buffer.Length; i++)
169 | {
170 | if (buffer[i] == 0x0)
171 | return Encoding.ASCII.GetString(result.ToArray());
172 |
173 | result.Add(buffer[i]);
174 | }
175 |
176 | buffer = ReadBytes(processHandle, address += bufferSize, bufferSize);
177 | }
178 | }
179 |
180 | ///
181 | /// Reads a struct from a Processes Memory
182 | ///
183 | /// Struct Type
184 | /// Process Handle Pointer
185 | /// Memory Address
186 | /// Resulting Struct
187 | public static T ReadStruct(IntPtr processHandle, long address)
188 | {
189 | byte[] data = ReadBytes(processHandle, address, Marshal.SizeOf());
190 | GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
191 | T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
192 | handle.Free();
193 | return theStructure;
194 | }
195 |
196 | ///
197 | /// Searches for bytes in a processes memory.
198 | ///
199 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process.
200 | /// Byte Sequence to scan for.
201 | /// Address to start the search at.
202 | /// Address to end the search at.
203 | /// Byte Buffer Size
204 | /// If we should stop the search at the first result.
205 | ///
206 | public static long[] FindBytes(IntPtr processHandle, byte?[] needle, long startAddress, long endAddress, bool firstMatch = false, int bufferSize = 0xFFFF)
207 | {
208 | List results = new List();
209 | long searchAddress = startAddress;
210 |
211 | int needleIndex = 0;
212 | int bufferIndex = 0;
213 |
214 | while (true)
215 | {
216 | try
217 | {
218 | byte[] buffer = ReadBytes(processHandle, searchAddress, bufferSize);
219 |
220 | for (bufferIndex = 0; bufferIndex < buffer.Length; bufferIndex++)
221 | {
222 | if (needle[needleIndex] == null)
223 | {
224 | needleIndex++;
225 | continue;
226 | }
227 |
228 | if (needle[needleIndex] == buffer[bufferIndex])
229 | {
230 | needleIndex++;
231 |
232 | if (needleIndex == needle.Length)
233 | {
234 | results.Add(searchAddress + bufferIndex - needle.Length + 1);
235 |
236 | if (firstMatch)
237 | return results.ToArray();
238 |
239 | needleIndex = 0;
240 | }
241 | }
242 | else
243 | {
244 | needleIndex = 0;
245 | }
246 | }
247 | }
248 | catch
249 | {
250 | break;
251 | }
252 |
253 | searchAddress += bufferSize;
254 |
255 | if (searchAddress > endAddress)
256 | break;
257 | }
258 |
259 | return results.ToArray();
260 | }
261 | }
262 | }
263 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/Util/PhilLibX/IO/ProcessReader.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------
2 | // PhilLibX - My Utility Library
3 | // Copyright(c) 2018 Philip/Scobalula
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | // ------------------------------------------------------------------------
23 | // File: IO/ProcessReader.cs
24 | // Author: Philip/Scobalula
25 | // Description: A class to help with reading the memory of other processes.
26 | using System;
27 | using System.Diagnostics;
28 |
29 | namespace PhilLibX.IO
30 | {
31 | ///
32 | /// A class to help with reading the memory of other processes.
33 | ///
34 | public class ProcessReader
35 | {
36 | ///
37 | /// Internal Process Property
38 | ///
39 | private Process _Process { get; set; }
40 |
41 | ///
42 | /// Internal Handle Property
43 | ///
44 | private IntPtr _Handle { get; set; }
45 |
46 | ///
47 | /// Active Process
48 | ///
49 | public Process ActiveProcess
50 | {
51 | get { return _Process; }
52 | set
53 | {
54 | _Process = value;
55 | _Handle = NativeMethods.OpenProcess(MemoryUtil.ProcessVMRead, false, _Process.Id);
56 | }
57 | }
58 |
59 | ///
60 | /// Active Process Handle
61 | ///
62 | public IntPtr Handle { get { return _Handle; } }
63 |
64 | ///
65 | /// Initalizes a Process Reader with a Process
66 | ///
67 | public ProcessReader(Process process)
68 | {
69 | ActiveProcess = process;
70 | }
71 |
72 | ///
73 | /// Reads bytes from the Processes Memory
74 | ///
75 | /// The address of the data to be read.
76 | /// The number of bytes to be read.
77 | /// Bytes read
78 | public byte[] ReadBytes(long address, int numBytes)
79 | {
80 | return MemoryUtil.ReadBytes(Handle, address, numBytes);
81 | }
82 |
83 | ///
84 | /// Reads 64Bit Integer from the Processes Memory
85 | ///
86 | /// The address of the data to be read.
87 | /// Resulting Data
88 | public long ReadInt64(long address)
89 | {
90 | return MemoryUtil.ReadInt64(Handle, address);
91 | }
92 |
93 | ///
94 | /// Reads an unsigned 64Bit Integer from the Processes Memory
95 | ///
96 | /// The address of the data to be read.
97 | /// Resulting Data
98 | public ulong ReadUInt64(long address)
99 | {
100 | return MemoryUtil.ReadUInt64(Handle, address);
101 | }
102 |
103 | ///
104 | /// Reads 32Bit Integer from the Processes Memory
105 | ///
106 | /// The address of the data to be read.
107 | /// Resulting Data
108 | public int ReadInt32(long address)
109 | {
110 | return MemoryUtil.ReadInt32(Handle, address);
111 | }
112 |
113 | ///
114 | /// Reads 32Bit Integer from the Processes Memory
115 | ///
116 | /// The address of the data to be read.
117 | /// Resulting Data
118 | public uint ReadUInt32(long address)
119 | {
120 | return MemoryUtil.ReadUInt32(Handle, address);
121 | }
122 |
123 | ///
124 | /// Reads a 16Bit Integer from the Processes Memory
125 | ///
126 | /// The address of the data to be read.
127 | /// Resulting Data
128 | public short ReadInt16(long address)
129 | {
130 | return MemoryUtil.ReadInt16(Handle, address);
131 | }
132 |
133 | ///
134 | /// Reads an unsigned 16Bit Integer from the Processes Memory
135 | ///
136 | /// The address of the data to be read.
137 | /// Resulting Data
138 | public ushort ReadUInt16(long address)
139 | {
140 | return MemoryUtil.ReadUInt16(Handle, address);
141 | }
142 |
143 | ///
144 | /// Reads a 4 byte single precision floating point number from the Processes Memory
145 | ///
146 | /// The address of the data to be read.
147 | /// Resulting Data
148 | public float ReadSingle(long address)
149 | {
150 | return MemoryUtil.ReadSingle(Handle, address);
151 | }
152 |
153 | ///
154 | /// Reads an 8 byte double precision floating point number from the Processes Memory
155 | ///
156 | /// The address of the data to be read.
157 | /// Resulting Data
158 | public double ReadDouble(long address)
159 | {
160 | return MemoryUtil.ReadDouble(Handle, address);
161 | }
162 |
163 | ///
164 | /// Reads a string from the processes' memory terminated by a null byte.
165 | ///
166 | /// Memory Address
167 | /// Buffer Read Size
168 | /// Resulting String
169 | public string ReadNullTerminatedString(long address, int bufferSize = 0xFF)
170 | {
171 | return MemoryUtil.ReadNullTerminatedString(Handle, address, bufferSize);
172 | }
173 |
174 | ///
175 | /// Reads a struct from the Processes Memory
176 | ///
177 | /// Struct Type
178 | /// Memory Address
179 | /// Resulting Struct
180 | public T ReadStruct(long address)
181 | {
182 | return MemoryUtil.ReadStruct(Handle, address);
183 | }
184 |
185 | ///
186 | /// Searches for bytes in the Processes Memory
187 | ///
188 | /// Byte Sequence to scan for.
189 | /// Address to start the search at.
190 | /// Address to end the search at.
191 | /// If we should stop the search at the first result.
192 | /// Byte Buffer Size
193 | /// Results
194 | public long[] FindBytes(byte?[] needle, long startAddress, long endAddress, bool firstMatch = false, int bufferSize = 0xFFFF)
195 | {
196 | return MemoryUtil.FindBytes(Handle, needle, startAddress, endAddress, firstMatch, bufferSize);
197 | }
198 |
199 | ///
200 | /// Gets the Active Processes' Base Address
201 | ///
202 | /// Base Address of the Active Process
203 | public long GetBaseAddress()
204 | {
205 | return (long)ActiveProcess?.MainModule.BaseAddress;
206 | }
207 |
208 | ///
209 | /// Gets the size of the Main Module Size
210 | ///
211 | /// Main Module Size
212 | public long GetModuleMemorySize()
213 | {
214 | return (long)ActiveProcess?.MainModule.ModuleMemorySize;
215 | }
216 | }
217 | }
218 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/Util/PhilLibX/MathUtilities.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------
2 | // PhilLibX - My Utility Library
3 | // Copyright(c) 2018 Philip/Scobalula
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | // ------------------------------------------------------------------------
23 | // File: MathUtilities.cs
24 | // Author: Philip/Scobalula
25 | // Description: Mathematic Utilities
26 | using System;
27 |
28 | namespace PhilLibX
29 | {
30 | ///
31 | /// Mathematic Utilities
32 | ///
33 | public class MathUtilities
34 | {
35 | ///
36 | /// Clamps Value to a range.
37 | ///
38 | /// Value to Clamp
39 | /// Max value
40 | /// Min value
41 | /// Clamped Value
42 | public static T Clamp(T value, T max, T min) where T : IComparable
43 | {
44 | return value.CompareTo(min) < 0 ? min : value.CompareTo(max) > 0 ? max : value;
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/Util/PhilLibX/NativeMethods.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------
2 | // PhilLibX - My Utility Library
3 | // Copyright(c) 2018 Philip/Scobalula
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | // ------------------------------------------------------------------------
23 | // File: NativeMethods.cs
24 | // Author: Philip/Scobalula
25 | // Description: Native/Unmanaged Methods (DLLs required for certain components)
26 | using System;
27 | using System.Runtime.InteropServices;
28 |
29 | namespace PhilLibX
30 | {
31 | ///
32 | /// Description: Native/Unmanaged Methods (DLLs required for certain components)
33 | ///
34 | internal class NativeMethods
35 | {
36 | ///
37 | /// Oodle Library Path
38 | ///
39 | private const string OodleLibraryPath = "oo2core_6_win64";
40 |
41 |
42 | ///
43 | /// Reads data from an area of memory in a specified process. The entire area to be read must be accessible or the operation fails.
44 | ///
45 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process.
46 | /// A pointer to the base address in the specified process from which to read. Before any data transfer occurs, the system verifies that all data in the base address and memory of the specified size is accessible for read access, and if it is not accessible the function fails.
47 | /// A pointer to a buffer that receives the contents from the address space of the specified process.
48 | /// The number of bytes to be read from the specified process.
49 | /// A pointer to a variable that receives the number of bytes transferred into the specified buffer.
50 | ///
51 | [DllImport("kernel32.dll", SetLastError = true)]
52 | public static extern bool ReadProcessMemory
53 | (
54 | int hProcess,
55 | long lpBaseAddress,
56 | byte[] lpBuffer,
57 | int nSize,
58 | out int lpNumberOfBytesRead
59 | );
60 |
61 | ///
62 | /// Opens an existing local process object.
63 | ///
64 | /// The access to the process object. This access right is checked against the security descriptor for the process. This parameter can be one or more of the process access rights. If the caller has enabled the SeDebugPrivilege privilege, the requested access is granted regardless of the contents of the security descriptor.
65 | /// If this value is TRUE, processes created by this process will inherit the handle. Otherwise, the processes do not inherit this handle.
66 | /// The identifier of the local process to be opened.
67 | ///
68 | [DllImport("kernel32.dll")]
69 | public static extern IntPtr OpenProcess
70 | (
71 | int dwDesiredAccess,
72 | bool bInheritHandle,
73 | int dwProcessId
74 | );
75 |
76 | ///
77 | /// Oodle64 Decompression Method
78 | ///
79 | [DllImport(OodleLibraryPath, CallingConvention = CallingConvention.Cdecl)]
80 | public static extern long OodleLZ_Decompress(byte[] buffer, long bufferSize, byte[] result, long outputBufferSize, int a, int b, int c, long d, long e, long f, long g, long h, long i, int ThreadModule);
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/CoDLUIDecompiler/Util/PhilLibX/Printer.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------
2 | // PhilLibX - My Utility Library
3 | // Copyright(c) 2018 Philip/Scobalula
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | // ------------------------------------------------------------------------
23 | // File: Printer.cs
24 | // Author: Philip/Scobalula
25 | // Description: Class to Print stuff to the Console with more swag 🖨️
26 | using System;
27 |
28 | namespace PhilLibX
29 | {
30 | ///
31 | /// Class to Print stuff to the Console with more swag 🖨️
32 | ///
33 | public class Printer
34 | {
35 | ///
36 | /// Prefix Padding
37 | ///
38 | private static int PrefixPadding = 12;
39 |
40 | ///
41 | /// Prefix Color
42 | ///
43 | private static ConsoleColor PrefixColor = ConsoleColor.Blue;
44 |
45 | ///
46 | /// Sets Prefix Padding
47 | ///
48 | /// Padding Size
49 | public static void SetPrefixPadding(int padding)
50 | {
51 | PrefixPadding = padding;
52 | }
53 |
54 | ///
55 | /// Sets the Console Prefix Color
56 | ///
57 | /// Background Color for Prefix
58 | public static void SetPrefixBackgroundColor(ConsoleColor color)
59 | {
60 | PrefixColor = color;
61 | }
62 |
63 | ///
64 | /// Writes a line to the console with optional BackGround
65 | ///
66 | /// Value to print
67 | /// Value to prefix
68 | /// Prefix Padding
69 | /// Background Color
70 | /// Prefix Background Color
71 | public static void WriteLine(object prefix = null, object value = null, ConsoleColor backgroundColor = ConsoleColor.Black)
72 | {
73 | // Check if we even have a prefix, if not just do a normal print
74 | if(prefix != null)
75 | {
76 | Console.BackgroundColor = PrefixColor;
77 | Console.Write(" {0}", prefix.ToString().PadRight(PrefixPadding));
78 | Console.ResetColor();
79 | Console.Write("│ ");
80 | }
81 | Console.BackgroundColor = backgroundColor;
82 | Console.WriteLine("{0}", value);
83 | Console.ResetColor();
84 | }
85 |
86 | ///
87 | /// Writes to the console with optional BackGround
88 | ///
89 | /// Value to print
90 | /// Value to prefix
91 | /// Prefix Padding
92 | /// Background Color
93 | /// Prefix Background Color
94 | public static void Write(object prefix = null, object value = null, ConsoleColor backgroundColor = ConsoleColor.Black)
95 | {
96 | // Check if we even have a prefix, if not just do a normal print
97 | if (prefix != null)
98 | {
99 | Console.BackgroundColor = ConsoleColor.DarkBlue;
100 | Console.Write(" {0}", prefix.ToString().PadRight(PrefixPadding));
101 | Console.ResetColor();
102 | Console.Write("│ ");
103 | }
104 | Console.BackgroundColor = backgroundColor;
105 | Console.Write("{0}", value);
106 | Console.ResetColor();
107 | }
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 JariK
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Overview
2 | [](https://github.com/JariKCoding/CoDLUIDecompiler/) [](https://discord.gg/yU2Pje6)
3 |
4 | **CoDLUIDecompiler** is a lua decompiler for Havok Scripts from various Call Of Duty games. It's main purpose is to provide access to scripts that Treyarch did not provide in the Call of Duty: Black Ops III Mod Tools and to give greater insight into how Treyarch and the other studios achieved certain things, rebuild menus from the game, etc.
5 |
6 | Supports following games out of the box: **BlackOps2**, **BlackOps3**, **BlackOps4**, **Ghosts**, **AdvancedWarfare**, **InfiniteWarfare**, **ModernWarfareRemastered** and **WorldWar2**
7 |
8 | ### What is it GOOD for?
9 |
10 | - Rebuild widgets and menus from games
11 | - Learn the LUI framework
12 |
13 | ### What is it BAD for?
14 |
15 | - Decompiling big blocks of code that is used for functionality
16 |
17 | ### What can be improved
18 |
19 | - Condition/Loop detection
20 |
21 | ### How to Use
22 |
23 | - To decompile a couple/a single file(s) just drop it on the .exe
24 | - To decompile whole folders open the program and give it the path
25 |
26 | ### How to get the lua files
27 |
28 | - Run the game you want to rip the files from
29 | - Open the program and it will export all files
30 |
31 | ## Download
32 |
33 | The latest version can be found on the [Releases Page](https://github.com/JariKCoding/CoDLUIDecompiler/releases).
34 |
35 | ## Requirements
36 |
37 | * Windows 7 x86 and above
38 | * .NET Framework 4.7.2
39 |
40 | ## Credits
41 |
42 | - DTZxPorter - Original lua disassembler to find the basics
43 | - Scobalula - Utilities and general help
44 |
45 | ## License
46 |
47 | CoDLUIDecompiler is licensed under the MIT license and its source code is free to use and modify. CoDLUIDecompiler comes with NO warranty, any damages caused are solely the responsibility of the user. See the LICENSE file for more information.
48 |
--------------------------------------------------------------------------------