diff --git a/BUILDING.md b/BUILDING.md new file mode 100644 index 0000000..11e03eb --- /dev/null +++ b/BUILDING.md @@ -0,0 +1,34 @@ +# Building + +Only Windows is supported at the moment, due to oodle. + +## Setup the environment + +* [FBX SDK 2020+](https://www.autodesk.com/developer-network/platform-technologies/fbx-sdk-2020-3) +* [vcpkg](https://vcpkg.io/) (for DirectXTex) + +**Add the FBX SDK install directory to an environment variable called** `FBXSDK_PATH` **e.g.** `C:\Program Files\Autodesk\FBX\FBX SDK\`**.** + +## Setup the project + +Clone the repository + +`git clone https://github.com/nblockbuster/MontevenDynamicExtractor.git` + +Follow the instructions to setup vcpkg [here](https://vcpkg.io/en/getting-started.html) + +Make sure to run the command `vcpkg install directxtex` to install DirectXTex, and `vcpkg integrate install` for Visual Studio to recognize it. + +#### Building the project + +Open `DestinyDynamicExtractor.sln`. You most likely want to build on the `Release` configuration. + +After it opens: + +`Build > Build Solution` + +### Post-Build + +After you build the solution, make sure to copy these files to the output directory: +* `oo2core_9_win64.dll` from your Destiny 2's `/bin/x64` directory +* `libfbxsdk.dll` from `//lib/vs2019/x64/release` \ No newline at end of file diff --git a/Debug/DestinyD.6c3dbec6.tlog/CL.command.1.tlog b/Debug/DestinyD.6c3dbec6.tlog/CL.command.1.tlog deleted file mode 100644 index ec9c80a..0000000 Binary files a/Debug/DestinyD.6c3dbec6.tlog/CL.command.1.tlog and /dev/null differ diff --git a/Debug/DestinyD.6c3dbec6.tlog/CL.read.1.tlog b/Debug/DestinyD.6c3dbec6.tlog/CL.read.1.tlog deleted file mode 100644 index 07b2ed1..0000000 Binary files a/Debug/DestinyD.6c3dbec6.tlog/CL.read.1.tlog and /dev/null differ diff --git a/Debug/DestinyD.6c3dbec6.tlog/CL.write.1.tlog b/Debug/DestinyD.6c3dbec6.tlog/CL.write.1.tlog deleted file mode 100644 index 2e212fe..0000000 Binary files a/Debug/DestinyD.6c3dbec6.tlog/CL.write.1.tlog and /dev/null differ diff --git a/Debug/DestinyD.6c3dbec6.tlog/DestinyDynamicExtractor.lastbuildstate b/Debug/DestinyD.6c3dbec6.tlog/DestinyDynamicExtractor.lastbuildstate deleted file mode 100644 index 8ded770..0000000 --- a/Debug/DestinyD.6c3dbec6.tlog/DestinyDynamicExtractor.lastbuildstate +++ /dev/null @@ -1,2 +0,0 @@ -PlatformToolSet=v142:VCToolArchitecture=Native32Bit:VCToolsVersion=14.28.29910:TargetPlatformVersion=10.0.19041.0: -Debug|Win32|C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\| diff --git a/Debug/DestinyD.6c3dbec6.tlog/link-cvtres.read.1.tlog b/Debug/DestinyD.6c3dbec6.tlog/link-cvtres.read.1.tlog deleted file mode 100644 index 46b134b..0000000 --- a/Debug/DestinyD.6c3dbec6.tlog/link-cvtres.read.1.tlog +++ /dev/null @@ -1 +0,0 @@ -ÿþ \ No newline at end of file diff --git a/Debug/DestinyD.6c3dbec6.tlog/link-cvtres.write.1.tlog b/Debug/DestinyD.6c3dbec6.tlog/link-cvtres.write.1.tlog deleted file mode 100644 index 46b134b..0000000 --- a/Debug/DestinyD.6c3dbec6.tlog/link-cvtres.write.1.tlog +++ /dev/null @@ -1 +0,0 @@ -ÿþ \ No newline at end of file diff --git a/Debug/DestinyD.6c3dbec6.tlog/link-rc.read.1.tlog b/Debug/DestinyD.6c3dbec6.tlog/link-rc.read.1.tlog deleted file mode 100644 index 46b134b..0000000 --- a/Debug/DestinyD.6c3dbec6.tlog/link-rc.read.1.tlog +++ /dev/null @@ -1 +0,0 @@ -ÿþ \ No newline at end of file diff --git a/Debug/DestinyD.6c3dbec6.tlog/link-rc.write.1.tlog b/Debug/DestinyD.6c3dbec6.tlog/link-rc.write.1.tlog deleted file mode 100644 index 46b134b..0000000 --- a/Debug/DestinyD.6c3dbec6.tlog/link-rc.write.1.tlog +++ /dev/null @@ -1 +0,0 @@ -ÿþ \ No newline at end of file diff --git a/Debug/DestinyD.6c3dbec6.tlog/link.command.1.tlog b/Debug/DestinyD.6c3dbec6.tlog/link.command.1.tlog deleted file mode 100644 index 46b134b..0000000 --- a/Debug/DestinyD.6c3dbec6.tlog/link.command.1.tlog +++ /dev/null @@ -1 +0,0 @@ -ÿþ \ No newline at end of file diff --git a/Debug/DestinyD.6c3dbec6.tlog/link.read.1.tlog b/Debug/DestinyD.6c3dbec6.tlog/link.read.1.tlog deleted file mode 100644 index 46b134b..0000000 --- a/Debug/DestinyD.6c3dbec6.tlog/link.read.1.tlog +++ /dev/null @@ -1 +0,0 @@ -ÿþ \ No newline at end of file diff --git a/Debug/DestinyD.6c3dbec6.tlog/link.write.1.tlog b/Debug/DestinyD.6c3dbec6.tlog/link.write.1.tlog deleted file mode 100644 index 46b134b..0000000 --- a/Debug/DestinyD.6c3dbec6.tlog/link.write.1.tlog +++ /dev/null @@ -1 +0,0 @@ -ÿþ \ No newline at end of file diff --git a/Debug/DestinyD.6c3dbec6.tlog/unsuccessfulbuild b/Debug/DestinyD.6c3dbec6.tlog/unsuccessfulbuild deleted file mode 100644 index e69de29..0000000 diff --git a/Debug/DestinyDynamicExtractor.log b/Debug/DestinyDynamicExtractor.log deleted file mode 100644 index 1ed2187..0000000 --- a/Debug/DestinyDynamicExtractor.log +++ /dev/null @@ -1,7 +0,0 @@ - dynamic.cpp - helpers.cpp - The contents of are available only with C++17 or later. - main.cpp - Generating Code... -helpers.obj : error LNK2019: unresolved external symbol "public: __thiscall Package::Package(class std::basic_string,class std::allocator >,class std::basic_string,class std::allocator >)" (??0Package@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@0@Z) referenced in function "class std::basic_string,class std::allocator > __cdecl getReferenceFromHash(class std::basic_string,class std::allocator >,class std::basic_string,class std::allocator >,class std::basic_string,class std::allocator >)" (?getReferenceFromHash@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@00@Z) -C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\Debug\DestinyDynamicExtractor.exe : fatal error LNK1120: 1 unresolved externals diff --git a/Debug/dynamic.obj b/Debug/dynamic.obj deleted file mode 100644 index 29b7c97..0000000 Binary files a/Debug/dynamic.obj and /dev/null differ diff --git a/Debug/helpers.obj b/Debug/helpers.obj deleted file mode 100644 index 753ae4c..0000000 Binary files a/Debug/helpers.obj and /dev/null differ diff --git a/Debug/main.obj b/Debug/main.obj deleted file mode 100644 index 7ba6314..0000000 Binary files a/Debug/main.obj and /dev/null differ diff --git a/Debug/vc142.idb b/Debug/vc142.idb deleted file mode 100644 index 52e6530..0000000 Binary files a/Debug/vc142.idb and /dev/null differ diff --git a/Debug/vc142.pdb b/Debug/vc142.pdb deleted file mode 100644 index beb9ee4..0000000 Binary files a/Debug/vc142.pdb and /dev/null differ diff --git a/DestinyDynamicExtractor.sln b/DestinyDynamicExtractor.sln new file mode 100644 index 0000000..6f79d59 --- /dev/null +++ b/DestinyDynamicExtractor.sln @@ -0,0 +1,44 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32825.248 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DestinyDynamicExtractor", "DestinyDynamicExtractor.vcxproj", "{1771395D-CA35-4F27-A717-167B8CE9B520}" + ProjectSection(ProjectDependencies) = postProject + {9C5C9FE9-448A-46F4-8A5F-CF5154149213} = {9C5C9FE9-448A-46F4-8A5F-CF5154149213} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DestinyUnpackerCPP", "DestinyUnpackerCPP\DestinyUnpackerCPP.vcxproj", "{9C5C9FE9-448A-46F4-8A5F-CF5154149213}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1771395D-CA35-4F27-A717-167B8CE9B520}.Debug|x64.ActiveCfg = Debug|x64 + {1771395D-CA35-4F27-A717-167B8CE9B520}.Debug|x64.Build.0 = Debug|x64 + {1771395D-CA35-4F27-A717-167B8CE9B520}.Debug|x86.ActiveCfg = Debug|Win32 + {1771395D-CA35-4F27-A717-167B8CE9B520}.Debug|x86.Build.0 = Debug|Win32 + {1771395D-CA35-4F27-A717-167B8CE9B520}.Release|x64.ActiveCfg = Release|x64 + {1771395D-CA35-4F27-A717-167B8CE9B520}.Release|x64.Build.0 = Release|x64 + {1771395D-CA35-4F27-A717-167B8CE9B520}.Release|x86.ActiveCfg = Release|Win32 + {1771395D-CA35-4F27-A717-167B8CE9B520}.Release|x86.Build.0 = Release|Win32 + {9C5C9FE9-448A-46F4-8A5F-CF5154149213}.Debug|x64.ActiveCfg = Debug|x64 + {9C5C9FE9-448A-46F4-8A5F-CF5154149213}.Debug|x64.Build.0 = Debug|x64 + {9C5C9FE9-448A-46F4-8A5F-CF5154149213}.Debug|x86.ActiveCfg = Debug|Win32 + {9C5C9FE9-448A-46F4-8A5F-CF5154149213}.Debug|x86.Build.0 = Debug|Win32 + {9C5C9FE9-448A-46F4-8A5F-CF5154149213}.Release|x64.ActiveCfg = Release|x64 + {9C5C9FE9-448A-46F4-8A5F-CF5154149213}.Release|x64.Build.0 = Release|x64 + {9C5C9FE9-448A-46F4-8A5F-CF5154149213}.Release|x86.ActiveCfg = Release|Win32 + {9C5C9FE9-448A-46F4-8A5F-CF5154149213}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E51A1EE2-3F45-4C81-A695-E4A76D61EEF5} + EndGlobalSection +EndGlobal diff --git a/DestinyDynamicExtractor.vcxproj b/DestinyDynamicExtractor.vcxproj index 591329e..b2856ee 100644 --- a/DestinyDynamicExtractor.vcxproj +++ b/DestinyDynamicExtractor.vcxproj @@ -5,6 +5,14 @@ Debug Win32 + + ReleaseDll + Win32 + + + ReleaseDll + x64 + Release Win32 @@ -39,6 +47,13 @@ true Unicode + + Application + false + v142 + true + Unicode + Application true @@ -46,12 +61,19 @@ Unicode - DynamicLibrary + Application false v142 true Unicode + + DynamicLibrary + false + v143 + true + Unicode + @@ -63,12 +85,18 @@ + + + + + + true @@ -76,13 +104,21 @@ false + + false + true false - C:\opencv\build\include;$(IncludePath) - C:\opencv\build\x64\vc15\lib;$(LibraryPath) + D:\opencv\opencv\build\include;$(IncludePath) + D:\opencv\opencv\build\x64\vc15\lib;$(LibraryPath) + + + false + D:\opencv\opencv\build\include;$(IncludePath) + D:\opencv\opencv\build\x64\vc15\lib;$(LibraryPath) @@ -113,21 +149,37 @@ true + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + Level3 true - _DEBUG;_CONSOLE;FBXSDK_SHARED;%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;FBXSDK_SHARED;%(PreprocessorDefinitions) true stdcpp17 - C:\Program Files\Autodesk\FBX\FBX SDK\2020.2\include;C:\Sarge\src;C:\opencv\build\include - MultiThreadedDLL + $(FBXSDK_PATH)\include;Sarge\src + MultiThreadedDebugDLL Console true - C:\Program Files\Autodesk\FBX\FBX SDK\2020.2\lib\vs2019\x64\debug;C:\Program Files\Autodesk\FBX\FBX SDK\2020.2\lib;C:\Program Files (x86)\Windows Kits\10\Lib;C:\Sarge\src;C:\opencv\build\x64\vc15\lib - C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\DestinyUnpackerCPP\x64\Debug\package.obj;C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\DestinyUnpackerCPP\x64\Debug\helpers.obj;C:\Program Files\Autodesk\FBX\FBX SDK\2020.2\lib\vs2019\x64\debug\libfbxsdk-md.lib;wininet.lib;opencv_world452d.lib;%(AdditionalDependencies) + $(FBXSDK_PATH)\lib\x64\debug;$(FBXSDK_PATH)\lib;C:\Program Files (x86)\Windows Kits\10\Lib;Sarge\src + $(OutDir)DestinyUnpackerCPP.lib;libfbxsdk-md.lib;wininet.lib;%(AdditionalDependencies) LIBMCT;%(IgnoreSpecificDefaultLibraries) true @@ -140,7 +192,27 @@ true NDEBUG;_CONSOLE;FBXSDK_SHARED;%(PreprocessorDefinitions) true - C:\Program Files\Autodesk\FBX\FBX SDK\2020.2\include;C:\Sarge\src;C:\opencv\build\include + $(FBXSDK_PATH)\include + stdcpp17 + + + Console + true + true + true + $(OutDir)DestinyUnpackerCPP.lib;libfbxsdk-md.lib;wininet.lib;%(AdditionalDependencies) + $(FBXSDK_PATH)\lib\x64\release;$(FBXSDK_PATH)\lib;Sarge\src;C:\Program Files (x86)\Windows Kits\10\Lib + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;FBXSDK_SHARED;%(PreprocessorDefinitions) + true + $(FBXSDK_PATH)\2020.3.2\include stdcpp17 @@ -148,8 +220,8 @@ true true true - C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\DestinyUnpackerCPP\x64\Release\package.obj;C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\DestinyUnpackerCPP\x64\Release\helpers.obj;C:\Program Files\Autodesk\FBX\FBX SDK\2020.2\lib\vs2019\x64\release\libfbxsdk-md.lib;wininet.lib;opencv_world452.lib;%(AdditionalDependencies) - C:\Program Files\Autodesk\FBX\FBX SDK\2020.2\lib\vs2019\x64\release;C:\Program Files\Autodesk\FBX\FBX SDK\2020.2\lib;C:\Program Files (x86)\Windows Kits\10\Lib;C:\Sarge\src;C:\opencv\build\x64\vc15\lib + $(OutDir)DestinyUnpackerCPP.lib;libfbxsdk-md.lib;wininet.lib;%(AdditionalDependencies) + $(FBXSDK_PATH)\2020.3.2\lib\vs2019\x64\release;$(FBXSDK_PATH)\2020.3.2\lib;C:\Program Files (x86)\Windows Kits\10\Lib;Sarge\src @@ -167,7 +239,6 @@ - diff --git a/DestinyDynamicExtractor.vcxproj.filters b/DestinyDynamicExtractor.vcxproj.filters index 6e497e8..e76d61a 100644 --- a/DestinyDynamicExtractor.vcxproj.filters +++ b/DestinyDynamicExtractor.vcxproj.filters @@ -74,9 +74,6 @@ Header Files - - Header Files - Header Files diff --git a/DestinyDynamicExtractor.vcxproj.user b/DestinyDynamicExtractor.vcxproj.user deleted file mode 100644 index 8607a76..0000000 --- a/DestinyDynamicExtractor.vcxproj.user +++ /dev/null @@ -1,11 +0,0 @@ - - - - -p "I:/SteamLibrary/steamapps/common/Destiny 2/packages" -o "C:/Users/monta/OneDrive/Destiny 2 Datamining/CPP/DestinyDataminingCPP/x64/Debug" -t -h 4198761575 - WindowsLocalDebugger - - - -p "I:/SteamLibrary/steamapps/common/Destiny 2/packages" -o "C:/Users/monta/OneDrive/Destiny 2 Datamining/CPP/DestinyDataminingCPP/x64/Release" -t -h 1046971209 - WindowsLocalDebugger - - \ No newline at end of file diff --git a/DestinyUnpackerCPP/DestinyUnpackerCPP.vcxproj b/DestinyUnpackerCPP/DestinyUnpackerCPP.vcxproj new file mode 100644 index 0000000..81bdf2c --- /dev/null +++ b/DestinyUnpackerCPP/DestinyUnpackerCPP.vcxproj @@ -0,0 +1,166 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {9c5c9fe9-448a-46f4-8a5f-cf5154149213} + DestinyUnpackerCPP + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + StaticLibrary + true + v142 + Unicode + + + StaticLibrary + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp17 + C:\openssl\include64;%(AdditionalIncludeDirectories) + + + Console + true + C:\openssl\lib64;%(AdditionalLibraryDirectories) + ws2_32.lib;libsslMT.lib;Crypt32.lib;libcryptoMT.lib;%(AdditionalDependencies) + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + %(AdditionalIncludeDirectories) + stdcpp17 + + + Console + true + C:\Program Files (x86)\Windows Kits\10\Lib;%(AdditionalLibraryDirectories) + %(AdditionalDependencies) + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp17 + + + Console + true + true + true + C:\Program Files (x86)\Windows Kits\10\Lib;%(AdditionalLibraryDirectories) + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DestinyUnpackerCPP/DestinyUnpackerCPP.vcxproj.filters b/DestinyUnpackerCPP/DestinyUnpackerCPP.vcxproj.filters new file mode 100644 index 0000000..7daf99f --- /dev/null +++ b/DestinyUnpackerCPP/DestinyUnpackerCPP.vcxproj.filters @@ -0,0 +1,39 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/DestinyUnpackerCPP/LICENSE b/DestinyUnpackerCPP/LICENSE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/DestinyUnpackerCPP/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/DestinyUnpackerCPP/helpers.cpp b/DestinyUnpackerCPP/helpers.cpp new file mode 100644 index 0000000..b1b5346 --- /dev/null +++ b/DestinyUnpackerCPP/helpers.cpp @@ -0,0 +1,64 @@ +#include "helpers.h" + +std::string uint16ToHexStr(uint16_t num) +{ + std::stringstream stream; + stream << std::hex << num; + std::string hexStr = stream.str(); + if (hexStr.size() % 4 != 0) + hexStr = std::string(4 - (hexStr.size() % 4), '0').append(hexStr); + return hexStr; +} + +std::string uint32ToHexStr(uint32_t num) +{ + std::stringstream stream; + stream << std::hex << swapUInt32Endianness(num); + std::string hexStr = stream.str(); + if (hexStr.size() % 8 != 0) + hexStr = std::string(8 - (hexStr.size() % 8), '0').append(hexStr); + return hexStr; +} + +uint32_t hexStrToUint16(std::string hash) +{ + return swapUInt16Endianness(std::stoul(hash, nullptr, 16)); +} + +uint32_t hexStrToUint32(std::string hash) +{ + return swapUInt32Endianness(std::stoul(hash, nullptr, 16)); +} + +uint64_t hexStrToUint64(std::string hash) +{ + return swapUInt64Endianness(std::stoull(hash, nullptr, 16)); +} + +uint16_t swapUInt16Endianness(uint16_t x) +{ + x = (x << 8) + (x >> 8); + return x; +} + +uint32_t swapUInt32Endianness(uint32_t x) +{ + x = (x >> 24) | + ((x << 8) & 0x00FF0000) | + ((x >> 8) & 0x0000FF00) | + (x << 24); + return x; +} + +uint64_t swapUInt64Endianness(uint64_t k) +{ + return ((k << 56) | + ((k & 0x000000000000FF00) << 40) | + ((k & 0x0000000000FF0000) << 24) | + ((k & 0x00000000FF000000) << 8) | + ((k & 0x000000FF00000000) >> 8) | + ((k & 0x0000FF0000000000) >> 24) | + ((k & 0x00FF000000000000) >> 40) | + (k >> 56) + ); +} \ No newline at end of file diff --git a/DestinyUnpackerCPP/helpers.h b/DestinyUnpackerCPP/helpers.h new file mode 100644 index 0000000..e2d82e9 --- /dev/null +++ b/DestinyUnpackerCPP/helpers.h @@ -0,0 +1,14 @@ +#pragma once +#include +#include +#include +#include + +std::string uint16ToHexStr(uint16_t num); +std::string uint32ToHexStr(uint32_t num); +uint16_t swapUInt16Endianness(uint16_t x); +uint32_t swapUInt32Endianness(uint32_t x); +uint64_t swapUInt64Endianness(uint64_t x); +uint32_t hexStrToUint16(std::string hash); +uint32_t hexStrToUint32(std::string hash); +uint64_t hexStrToUint64(std::string hash); \ No newline at end of file diff --git a/DestinyUnpackerCPP/main.cpp b/DestinyUnpackerCPP/main.cpp new file mode 100644 index 0000000..e3f6ecb --- /dev/null +++ b/DestinyUnpackerCPP/main.cpp @@ -0,0 +1,13 @@ +#include "main.h" +#include "helpers.h" +#include "package.h" + +int main() +{ + packagesPath = "I:/SteamLibrary/steamapps/common/Destiny 2/packages/"; + + Package Pkg("011f", packagesPath); + Pkg.Unpack(); + + return 0; +} \ No newline at end of file diff --git a/DestinyUnpackerCPP/main.h b/DestinyUnpackerCPP/main.h new file mode 100644 index 0000000..a35d331 --- /dev/null +++ b/DestinyUnpackerCPP/main.h @@ -0,0 +1,17 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include + + +bool getLatestPatchIDs_Str(std::vector& latestPackages, std::string packagesPath); +bool getLatestPatchIDs_Bin(std::vector& latestPackages, std::string packagesPath); +std::vector getLatestPatchIDs(std::string packagesPath); + +std::string packagesPath; + + diff --git a/DestinyUnpackerCPP/package.cpp b/DestinyUnpackerCPP/package.cpp new file mode 100644 index 0000000..243bd63 --- /dev/null +++ b/DestinyUnpackerCPP/package.cpp @@ -0,0 +1,637 @@ +#include "package.h" + + +const static unsigned char AES_KEY_0[16] = +{ + 0xD6, 0x2A, 0xB2, 0xC1, 0x0C, 0xC0, 0x1B, 0xC5, 0x35, 0xDB, 0x7B, 0x86, 0x55, 0xC7, 0xDC, 0x3B, +}; + +const static unsigned char AES_KEY_1[16] = +{ + 0x3A, 0x4A, 0x5D, 0x36, 0x73, 0xA6, 0x60, 0x58, 0x7E, 0x63, 0xE6, 0x76, 0xE4, 0x08, 0x92, 0xB5, +}; + +const int BLOCK_SIZE = 0x40000; + +Package::Package(std::string packageID, std::string pkgsPath) +{ + packagesPath = pkgsPath; + if (!std::filesystem::exists(packagesPath)) + { + printf("Package path given is invalid!"); + exit(1); + } + packagePath = getLatestPatchIDPath(packageID); +} + +std::string Package::getLatestPatchIDPath(std::string packageID) +{ + std::string fullPath = ""; + uint16_t patchID; + int largestPatchID = -1; + for (const std::filesystem::directory_entry& entry : std::filesystem::directory_iterator(packagesPath)) + { + fullPath = entry.path().u8string(); + if (fullPath.find(packageID) != std::string::npos) + { + patchID = std::stoi(fullPath.substr(fullPath.size() - 5, 1)); + if (patchID > largestPatchID) largestPatchID = patchID; + std::replace(fullPath.begin(), fullPath.end(), '\\', '/'); + packageName = fullPath.substr(0, fullPath.size() - 6); + packageName = packageName.substr(packageName.find_last_of('/')); + } + } + // Some strings are not covered, such as the bootstrap set so we need to do pkg checks + if (largestPatchID == -1) + { + FILE* patchPkg = nullptr; + uint16_t pkgID; + for (const std::filesystem::directory_entry& entry : std::filesystem::directory_iterator(packagesPath)) + { + fullPath = entry.path().u8string(); + + + errno_t status = fopen_s(&patchPkg, fullPath.c_str(), "rb"); + if (patchPkg == nullptr || status) exit(67); + fseek(patchPkg, 0x10, SEEK_SET); + fread((char*)&pkgID, 1, 2, patchPkg); + + if (packageID == uint16ToHexStr(pkgID)) + { + fseek(patchPkg, 0x30, SEEK_SET); + fread((char*)&patchID, 1, 2, patchPkg); + if (patchID > largestPatchID) largestPatchID = patchID; + std::replace(fullPath.begin(), fullPath.end(), '\\', '/'); + packageName = fullPath.substr(0, fullPath.size() - 6); + packageName = packageName.substr(packageName.find_last_of('/')); + } + fclose(patchPkg); + } + } + + return packagesPath + "/" + packageName + "_" + std::to_string(largestPatchID) + ".pkg"; +} + +bool Package::readHeader() +{ + // Package data + auto status = fopen_s(&pkgFile, packagePath.c_str(), "rb"); + if (status != 0) + { + return false; + } + fseek(pkgFile, 0x10, SEEK_SET); + fread((char*)&header.pkgID, 1, 2, pkgFile); + + fseek(pkgFile, 0x30, SEEK_SET); + fread((char*)&header.patchID, 1, 2, pkgFile); + + // Entry Table + fseek(pkgFile, 0x44, SEEK_SET); + fread((char*)&header.entryTableOffset, 1, 4, pkgFile); + + fseek(pkgFile, 0x60, SEEK_SET); + fread((char*)&header.entryTableSize, 1, 4, pkgFile); + + // Block Table + + fseek(pkgFile, 0x68, SEEK_SET); + fread((char*)&header.blockTableSize, 1, 4, pkgFile); + fread((char*)&header.blockTableOffset, 1, 4, pkgFile); + + // Hash64 Table + fseek(pkgFile, 0xB8, SEEK_SET); + fread((char*)&header.hash64TableSize, 1, 4, pkgFile); + fread((char*)&header.hash64TableOffset, 1, 4, pkgFile); + header.hash64TableOffset += 64; // relative offset + return true; +} + +void Package::getEntryTable() +{ + for (uint32_t i = header.entryTableOffset; i < header.entryTableOffset + header.entryTableSize * 16; i += 16) + { + Entry entry; + + // EntryA + uint32_t entryA; + fseek(pkgFile, i, SEEK_SET); + fread((char*)&entryA, 1, 4, pkgFile); + entry.reference = uint32ToHexStr(entryA); + + // EntryB + uint32_t entryB; + fread((char*)&entryB, 1, 4, pkgFile); + entry.numType = (entryB >> 9) & 0x7F; + entry.numSubType = (entryB >> 6) & 0x7; + + // EntryC + uint32_t entryC; + fread((char*)&entryC, 1, 4, pkgFile); + entry.startingBlock = entryC & 0x3FFF; + entry.startingBlockOffset = ((entryC >> 14) & 0x3FFF) << 4; + + // EntryD + uint32_t entryD; + fread((char*)&entryD, 1, 4, pkgFile); + entry.fileSize = (entryD & 0x3FFFFFF) << 4 | (entryC >> 28) & 0xF; + + entries.push_back(entry); + } +} + +void Package::getBlockTable() +{ + for (uint32_t i = header.blockTableOffset; i < header.blockTableOffset + header.blockTableSize * 48; i += 48) + { + Block block = { 0, 0, 0, 0, 0 }; + fseek(pkgFile, i, SEEK_SET); + fread((char*)&block.offset, 1, 4, pkgFile); + fread((char*)&block.size, 1, 4, pkgFile); + fread((char*)&block.patchID, 1, 2, pkgFile); + fread((char*)&block.bitFlag, 1, 2, pkgFile); + fseek(pkgFile, i + 0x20, SEEK_SET); + fread((char*)&block.gcmTag, 16, 1, pkgFile); + blocks.push_back(block); + } +} + +void Package::modifyNonce() +{ + // Nonce + nonce[0] ^= (header.pkgID >> 8) & 0xFF; + nonce[11] ^= header.pkgID & 0xFF; +} + +void Package::extractFiles() +{ + std::vector pkgPatchStreamPaths; + std::string outputPath = CUSTOM_DIR + "/output/" + uint16ToHexStr(header.pkgID); + std::filesystem::create_directories(outputPath); + // Initialising the required file streams + for (int i = 0; i <= header.patchID; i++) + { + std::string pkgPatchPath = packagePath; + pkgPatchPath[pkgPatchPath.size() - 5] = char(i + 48); + pkgPatchStreamPaths.push_back(pkgPatchPath); + std::cout << pkgPatchPath << "\n"; + } + // Extracting each entry to a file + for (int i = 0; i < entries.size(); i++) + { + Entry entry = entries[i]; + int currentBlockID = entry.startingBlock; + int blockCount = floor((entry.startingBlockOffset + entry.fileSize - 1) / BLOCK_SIZE); + if (entry.fileSize == 0) blockCount = 0; // Stupid check for weird C++ floor behaviour + int lastBlockID = currentBlockID + blockCount; + unsigned char* fileBuffer = new unsigned char[entry.fileSize]; + int currentBufferOffset = 0; + while (currentBlockID <= lastBlockID) + { + Block currentBlock = blocks[currentBlockID]; + + FILE* pFile; + fopen_s(&pFile, pkgPatchStreamPaths[currentBlock.patchID].c_str(), "rb"); + fseek(pFile, currentBlock.offset, SEEK_SET); + unsigned char* blockBuffer = new unsigned char[currentBlock.size]; + size_t result; + result = fread(blockBuffer, 1, currentBlock.size, pFile); + if (result != currentBlock.size) { fputs("Reading error", stderr); exit(3); } + + unsigned char* decryptBuffer = new unsigned char[currentBlock.size]; + unsigned char* decompBuffer = new unsigned char[BLOCK_SIZE]; + + if (currentBlock.bitFlag & 0x2) + decryptBlock(currentBlock, blockBuffer, decryptBuffer); + else + decryptBuffer = blockBuffer; + + if (currentBlock.bitFlag & 0x1) + decompressBlock(currentBlock, decryptBuffer, decompBuffer); + else + decompBuffer = decryptBuffer; + + if (currentBlockID == entry.startingBlock) + { + size_t cpySize; + if (currentBlockID == lastBlockID) + cpySize = entry.fileSize; + else + cpySize = BLOCK_SIZE - entry.startingBlockOffset; + memcpy(fileBuffer, decompBuffer + entry.startingBlockOffset, cpySize); + currentBufferOffset += cpySize; + } + else if (currentBlockID == lastBlockID) + { + memcpy(fileBuffer + currentBufferOffset, decompBuffer, entry.fileSize - currentBufferOffset); + } + else + { + memcpy(fileBuffer + currentBufferOffset, decompBuffer, BLOCK_SIZE); + currentBufferOffset += BLOCK_SIZE; + } + + fclose(pFile); + currentBlockID++; + delete[] decompBuffer; + } + + FILE* oFile; + std::string name = outputPath + "/" + uint16ToHexStr(header.pkgID) + "-" + uint16ToHexStr(i) + ".bin"; + fopen_s(&oFile, name.c_str(), "wb"); + fwrite(fileBuffer, entry.fileSize, 1, oFile); + fclose(oFile); + delete[] fileBuffer; + } +} + +// Bcrypt decryption implementation largely from Sir Kane's SourcePublic_v2.cpp, very mysterious +void Package::decryptBlock(Block block, unsigned char* blockBuffer, unsigned char*& decryptBuffer) +{ + BCRYPT_ALG_HANDLE hAesAlg; + NTSTATUS status; + status = BCryptOpenAlgorithmProvider(&hAesAlg, BCRYPT_AES_ALGORITHM, nullptr, 0); + status = BCryptSetProperty(hAesAlg, BCRYPT_CHAINING_MODE, (PUCHAR)BCRYPT_CHAIN_MODE_GCM, + sizeof(BCRYPT_CHAIN_MODE_GCM), 0); + + alignas(alignof(BCRYPT_KEY_DATA_BLOB_HEADER)) unsigned char keyData[sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + 16]; + BCRYPT_KEY_DATA_BLOB_HEADER* pHeader = (BCRYPT_KEY_DATA_BLOB_HEADER*)keyData; + pHeader->dwMagic = BCRYPT_KEY_DATA_BLOB_MAGIC; + pHeader->dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1; + pHeader->cbKeyData = 16; + memcpy(pHeader + 1, block.bitFlag & 0x4 ? AES_KEY_1 : AES_KEY_0, 16); + BCRYPT_KEY_HANDLE hAesKey; + + status = BCryptImportKey(hAesAlg, nullptr, BCRYPT_KEY_DATA_BLOB, &hAesKey, nullptr, 0, keyData, sizeof(keyData), 0); + ULONG decryptionResult; + BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO cipherModeInfo; + + BCRYPT_INIT_AUTH_MODE_INFO(cipherModeInfo); + + cipherModeInfo.pbTag = (PUCHAR)block.gcmTag; + cipherModeInfo.cbTag = 0x10; + cipherModeInfo.pbNonce = nonce; + cipherModeInfo.cbNonce = sizeof(nonce); + + status = BCryptDecrypt(hAesKey, (PUCHAR)blockBuffer, (ULONG)block.size, &cipherModeInfo, nullptr, 0, + (PUCHAR)decryptBuffer, (ULONG)block.size, &decryptionResult, 0); + if (status < 0)// && status != -1073700862) + printf("\nbcrypt decryption failed!"); + BCryptDestroyKey(hAesKey); + BCryptCloseAlgorithmProvider(hAesAlg, 0); + + delete[] blockBuffer; +} + +void Package::decompressBlock(Block block, unsigned char* decryptBuffer, unsigned char*& decompBuffer) +{ + int64_t result = ((OodleLZ64_DecompressDef)OodleLZ_Decompress)(decryptBuffer, block.size, decompBuffer, BLOCK_SIZE, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, 3); + if (result <= 0) + auto a = 0; + delete[] decryptBuffer; +} + +bool Package::initOodle() +{ + hOodleDll = LoadLibrary(L"oo2core_9_win64.dll"); + if (hOodleDll == nullptr) { + return false; + } + OodleLZ_Decompress = (int64_t)GetProcAddress(hOodleDll, "OodleLZ_Decompress"); + if (!OodleLZ_Decompress) printf("Failed to find Oodle compress/decompress functions in DLL!"); + return true; +} + +bool Package::Unpack() +{ + readHeader(); + if (!initOodle()) + { + printf("\nFailed to initialise oodle"); + return 1; + } + modifyNonce(); + getEntryTable(); + getBlockTable(); + fclose(pkgFile); + extractFiles(); + return 0; +} + +// Most efficient route to getting a single entry's reference +std::string Package::getEntryReference(std::string hash) +{ + // Entry index + uint32_t id = hexStrToUint32(hash) % 8192; + + // Entry offset + uint32_t entryTableOffset; + auto status = fopen_s(&pkgFile, packagePath.c_str(), "rb"); + if (status != 0) + { + printf("\nFailed to initialise pkg file, exiting...\n"); + std::cerr << hash << " " << packagePath.c_str() << std::endl << packagePath << std::endl << status << std::endl; + return ""; + //exit(status); + } + fseek(pkgFile, 0x44, SEEK_SET); + fread((char*)&entryTableOffset, 1, 4, pkgFile); + + // Getting reference + uint32_t entryA; + fseek(pkgFile, entryTableOffset + id * 16, SEEK_SET); + fread((char*)&entryA, 1, 4, pkgFile); + std::string reference = uint32ToHexStr(entryA); + fclose(pkgFile); + return reference; +} + +uint8_t Package::getEntryTypes(std::string hash, uint8_t &subType) +{ + // Entry index + uint32_t id = hexStrToUint32(hash) % 8192; + + // Entry offset + uint32_t entryTableOffset; + auto status = fopen_s(&pkgFile, packagePath.c_str(), "rb"); + if (status != 0) + { + std::cerr << "\nFailed to initialise pkg file, exiting: " << std::to_string(status) << '\n'; + std::cerr << hash << std::endl << packagePath; + return -1; + //exit(1); + } + fseek(pkgFile, 0x44, SEEK_SET); + fread((char*)&entryTableOffset, 1, 4, pkgFile); + + // Getting reference + // EntryB + uint32_t entryB; + fseek(pkgFile, entryTableOffset + id * 16 + 4, SEEK_SET); + fread((char*)&entryB, 1, 4, pkgFile); + uint8_t type = (entryB >> 9) & 0x7F; + subType = (entryB >> 6) & 0x7; + fclose(pkgFile); + return type; +} + +// This gets the minimum required data to pull out a single file from the game +unsigned char* Package::getEntryData(std::string hash, int& fileSize) +{ + // Entry index + uint32_t id = hexStrToUint32(hash) % 8192; + + // Header data + if (header.pkgID == 0) + { + bool status = readHeader(); + if (!status) return nullptr; + } + + if (id >= header.entryTableSize) return nullptr; + + Entry entry; + + // EntryC + uint32_t entryC; + fseek(pkgFile, header.entryTableOffset + id * 16 + 8, SEEK_SET); + fread((char*)&entryC, 1, 4, pkgFile); + entry.startingBlock = entryC & 0x3FFF; + entry.startingBlockOffset = ((entryC >> 14) & 0x3FFF) << 4; + + // EntryD + uint32_t entryD; + fread((char*)&entryD, 1, 4, pkgFile); + entry.fileSize = (entryD & 0x3FFFFFF) << 4 | (entryC >> 28) & 0xF; + fileSize = entry.fileSize; + + // Getting data to return + if (!initOodle()) + { + printf("\nFailed to initialise oodle, exiting..."); + exit(1); + } + modifyNonce(); + + unsigned char* buffer = getBufferFromEntry(entry); + fclose(pkgFile); + return buffer; +} + +std::unordered_map generateH64Table(std::string packagesPath) +{ + std::set pkgIDs; + std::unordered_map hash64Table; + + std::string path; + int status; + std::string fullPath; + std::string reducedPath; + uint16_t pkgIDBytes; + std::string pkgID; + FILE* pkgFile; + // Getting all packages + for (const auto& entry : std::filesystem::directory_iterator(packagesPath)) + { + path = entry.path().u8string(); + status = fopen_s(&pkgFile, path.c_str(), "rb"); + if (status) + { + std::cerr << "FAILED GETTING PACKAGES FOR H64 ERR1515: " << std::to_string(status); + exit(status); + } + fseek(pkgFile, 0x10, SEEK_SET); + fread((char*)&pkgIDBytes, 1, 2, pkgFile); + pkgID = uint16ToHexStr(pkgIDBytes); + pkgIDs.insert(pkgID); + fclose(pkgFile); + } + for (auto& pkgID : pkgIDs) + { + Package pkg = Package(pkgID, packagesPath); + status = fopen_s(&pkgFile, pkg.packagePath.c_str(), "rb"); + if (status) + { + if (status == 24) { + _setmaxstdio(2048); + status = fopen_s(&pkgFile, pkg.packagePath.c_str(), "rb"); + } + else { + std::cerr << "FAILED GETTING PACKAGES FOR H64 ERR5632: " << std::to_string(status); + exit(status); + } + } + // Hash64 Table + uint32_t hash64TableCount; + uint32_t hash64TableOffset; + fseek(pkgFile, 0xB8, SEEK_SET); + fread((char*)&hash64TableCount, 1, 4, pkgFile); + if (!hash64TableCount) continue; + fread((char*)&hash64TableOffset, 1, 4, pkgFile); + hash64TableOffset += 64 + 0x10; + + for (int i = hash64TableOffset; i < hash64TableOffset + hash64TableCount * 0x10; i += 0x10) + { + uint64_t h64Val; + fseek(pkgFile, i, SEEK_SET); + fread((char*)&h64Val, 1, 8, pkgFile); + uint32_t hVal; + fread((char*)&hVal, 1, 4, pkgFile); + hash64Table[h64Val] = hVal; + } + fclose(pkgFile); + } + return hash64Table; +} + +bool saveH64Table(std::unordered_map hash64Table) +{ + FILE* file; + int status = fopen_s(&file, "h64", "wb"); + if (status) + { + std::cerr << "FAILED WRITING H64 ERR5157: " << std::to_string(status); + exit(status); + } + if (file == NULL) return false; + for (auto& element : hash64Table) + { + fwrite(&element.first, 8, 1, file); + fwrite(&element.second, 4, 1, file); + } + fclose(file); + return true; +} + +std::unordered_map loadH64Table() +{ + std::unordered_map hash64Table; + FILE* file; + int status = fopen_s(&file, "h64", "rb"); + if (status) + { + std::cerr << "FAILED READING H64 ERR1231: " << std::to_string(status); + exit(status); + } + uint64_t h64Val; + uint32_t hVal; + fread(&h64Val, 8, 1, file); + size_t read = fread(&hVal, 4, 1, file); + hash64Table[h64Val] = hVal; + while (read) + { + fread(&h64Val, 8, 1, file); + read = fread(&hVal, 4, 1, file); + hash64Table[h64Val] = hVal; + } + fclose(file); + return hash64Table; +} + +// For batch extraction +std::vector Package::getAllFilesGivenRef(std::string reference) +{ + //uint32_t ref = hexStrToUint32(reference); + std::vector hashes; + + // Header data + bool status = readHeader(); + if (!status) return std::vector(); + + getEntryTable(); + for (int i = 0; i < entries.size(); i++) + { + Entry entry = entries[i]; + if (entry.reference == reference) + { + uint32_t a = header.pkgID * 8192; + uint32_t b = a + i + 2155872256; + hashes.push_back(uint32ToHexStr(b)); + } + } + + return hashes; +} + +unsigned char* Package::getBufferFromEntry(Entry entry) +{ + if (!entry.fileSize) return nullptr; + int blockCount = floor((entry.startingBlockOffset + entry.fileSize - 1) / BLOCK_SIZE); + + // Getting required block data + for (uint32_t i = header.blockTableOffset + entry.startingBlock * 48; i <= header.blockTableOffset + entry.startingBlock * 48 + blockCount * 48; i += 48) + { + Block block = { 0, 0, 0, 0, 0 }; + fseek(pkgFile, i, SEEK_SET); + fread((char*)&block.offset, 1, 4, pkgFile); + fread((char*)&block.size, 1, 4, pkgFile); + fread((char*)&block.patchID, 1, 2, pkgFile); + fread((char*)&block.bitFlag, 1, 2, pkgFile); + fseek(pkgFile, i + 0x20, SEEK_SET); + fread((char*)&block.gcmTag, 16, 1, pkgFile); + blocks.push_back(block); + } + + unsigned char* fileBuffer = new unsigned char[entry.fileSize]; + int currentBufferOffset = 0; + int currentBlockID = 0; + for (const Block& currentBlock : blocks) // & here is good as it captures by const reference, cheaper than by value + { + packagePath[packagePath.size() - 5] = currentBlock.patchID + 48; + FILE* pFile; + int status = fopen_s(&pFile, packagePath.c_str(), "rb"); + while (status) + { + status = fopen_s(&pFile, packagePath.c_str(), "rb"); + //std::cerr << "FAILED GETTING PACKAGE FOR BLOCK EXTRACT ERR9532 {PKG: " << packagePath << "}" << std::endl; + //std::cerr << status << std::endl; + //fclose(pFile); + //return new unsigned char[0]; + ////exit(status); + } + fseek(pFile, currentBlock.offset, SEEK_SET); + unsigned char* blockBuffer = new unsigned char[currentBlock.size]; + size_t result; + result = fread(blockBuffer, 1, currentBlock.size, pFile); + if (result != currentBlock.size) { fputs("Reading error", stderr); exit(3); } + + unsigned char* decryptBuffer = new unsigned char[currentBlock.size]; + unsigned char* decompBuffer = new unsigned char[BLOCK_SIZE]; + + if (currentBlock.bitFlag & 0x2) + decryptBlock(currentBlock, blockBuffer, decryptBuffer); + else + decryptBuffer = blockBuffer; + + if (currentBlock.bitFlag & 0x1) + decompressBlock(currentBlock, decryptBuffer, decompBuffer); + else + decompBuffer = decryptBuffer; + + if (currentBlockID == 0) + { + size_t cpySize; + if (currentBlockID == blockCount) + cpySize = entry.fileSize; + else + cpySize = BLOCK_SIZE - entry.startingBlockOffset; + memcpy(fileBuffer, decompBuffer + entry.startingBlockOffset, cpySize); + currentBufferOffset += cpySize; + } + else if (currentBlockID == blockCount) + { + memcpy(fileBuffer + currentBufferOffset, decompBuffer, entry.fileSize - currentBufferOffset); + } + else + { + memcpy(fileBuffer + currentBufferOffset, decompBuffer, BLOCK_SIZE); + currentBufferOffset += BLOCK_SIZE; + } + + fclose(pFile); + currentBlockID++; + delete[] decompBuffer; + } + blocks.clear(); + return fileBuffer; +} diff --git a/DestinyUnpackerCPP/package.h b/DestinyUnpackerCPP/package.h new file mode 100644 index 0000000..623ccbf --- /dev/null +++ b/DestinyUnpackerCPP/package.h @@ -0,0 +1,102 @@ +#pragma once +#pragma comment(lib, "bcrypt.lib") +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "helpers.h" +#include + +std::unordered_map loadH64Table(); +std::unordered_map generateH64Table(std::string packagesPath); +bool saveH64Table(std::unordered_map hash64Table); + +struct PkgHeader +{ + uint16_t pkgID; + uint16_t patchID; + uint32_t entryTableOffset; + uint32_t entryTableSize; + uint32_t blockTableOffset; + uint32_t blockTableSize; + uint32_t hash64TableOffset; + uint32_t hash64TableSize; +}; + +struct Entry +{ + std::string reference; + uint8_t numType; + uint8_t numSubType; + uint32_t startingBlock; + uint32_t startingBlockOffset; + uint32_t fileSize; +}; + +struct Block +{ + uint32_t ID; + uint32_t offset; + uint32_t size; + uint16_t patchID; + uint16_t bitFlag; + uint8_t gcmTag[16]; +}; + +typedef int64_t(*OodleLZ64_DecompressDef)(unsigned char* Buffer, int64_t BufferSize, unsigned char* OutputBuffer, int64_t OutputBufferSize, int32_t a, int32_t b, int64_t c, void* d, void* e, void* f, void* g, void* h, void* i, int32_t ThreadModule); + +/* +* Handles the separation of a .pkg file into its constituent binary files. +* It will unpack the PatchID given, so the latest should be given if updates are being processed. +*/ +class Package +{ +private: + unsigned char nonce[12] = + { + 0x84, 0xEA, 0x11, 0xC0, 0xAC, 0xAB, 0xFA, 0x20, 0x33, 0x11, 0x26, 0x99, + }; + + const std::string CUSTOM_DIR = "I:/test_out/pkg/"; + + FILE* pkgFile; + std::vector blocks; + + int64_t OodleLZ_Decompress; + HMODULE hOodleDll; + + + void getBlockTable(); + void extractFiles(); + void decryptBlock(Block block, unsigned char* blockBuffer, unsigned char* &decryptBuffer); + void decompressBlock(Block block, unsigned char* decryptBuffer, unsigned char*& decompBuffer); + +public: + std::string packagesPath = "I:/SteamLibrary/steamapps/common/Destiny 2/packages/"; + std::string packagePath; + std::string packageName; + PkgHeader header; + std::vector entries; + + // Constructor + Package(std::string packageID, std::string pkgsPath); + + bool initOodle(); + void modifyNonce(); + bool readHeader(); + bool Unpack(); + void getEntryTable(); + std::string getEntryReference(std::string hash); + uint8_t getEntryTypes(std::string hash, uint8_t& subType); + std::string getLatestPatchIDPath(std::string packageName); + unsigned char* getEntryData(std::string hash, int& fileSize); + std::vector getAllFilesGivenRef(std::string reference); + unsigned char* getBufferFromEntry(Entry entry); +}; \ No newline at end of file diff --git a/api.cpp b/api.cpp index 037735b..3e5b094 100644 --- a/api.cpp +++ b/api.cpp @@ -47,7 +47,7 @@ std::vector dataNames = std::vector getAPIModelHashes(uint32_t apiHash, std::string packagesPath, std::unordered_map hash64Table, bool& bSingle) { std::vector modelHashes; - File* modelTable = new File("A67AD080", packagesPath); + File* modelTable = new File(EntityAssignmentMapHash, packagesPath); modelTable->getData(); // Finding val uint32_t tableOffset = 0x40; @@ -81,9 +81,9 @@ std::vector getAPIModelHashes(uint32_t apiHash, std::string package uint32_t getArtArrangementHash(uint32_t apiHash, std::string packagesPath) { - File* dataTable = new File("AA3FE280", packagesPath); + File* dataTable = new File(InventoryItemMapHash, packagesPath); dataTable->getData(); - File* arrangementTable = new File("137AD080", packagesPath); + File* arrangementTable = new File(ArtArrangementMapHash, packagesPath); arrangementTable->getData(); uint32_t tableOffset = 0x30; @@ -99,8 +99,8 @@ uint32_t getArtArrangementHash(uint32_t apiHash, std::string packagesPath) memcpy((char*)&val, dataTable->data + i + 0x10, 4); File dataFile = File(uint32ToHexStr(val), packagesPath); dataFile.getData(); - memcpy((char*)&val, dataFile.data + 0x88, 4); - val += 0x88 + 8; + memcpy((char*)&val, dataFile.data + 0x80, 4); + val += 0x80 + 8; memcpy((char*)&val2, dataFile.data + val, 4); val += val2 + 0x12; memcpy((char*)&val2, dataFile.data + val, 2); @@ -119,7 +119,7 @@ uint32_t getArtArrangementHash(uint32_t apiHash, std::string packagesPath) bool getAPIShader(uint32_t apiHash, std::string outputPath, std::string packagesPath, std::unordered_map hash64Table) { - File* dataTable = new File("AA3FE280", packagesPath); + File* dataTable = new File(InventoryItemMapHash, packagesPath); dataTable->getData(); uint32_t tableOffset = 0x30; @@ -137,10 +137,10 @@ bool getAPIShader(uint32_t apiHash, std::string outputPath, std::string packages memcpy((char*)&val, dataTable->data + i + 0x10, 4); File dataFile = File(uint32ToHexStr(val), packagesPath); dataFile.getData(); - memcpy((char*)&val, dataFile.data + 0x88, 4); - val += 0x88; + memcpy((char*)&val, dataFile.data + 0x80, 4); + val += 0x80; memcpy((char*)&val2, dataFile.data + val - 4, 4); - if (val2 != 2155901815) + if (val2 != 0x80807377) { printf("Given shader is not valid!\n"); return false; @@ -173,11 +173,11 @@ bool getAPIShader(uint32_t apiHash, std::string outputPath, std::string packages } if (defaultChannelDyeMap.size() == 0) return false; - File* channelTable = new File("C92FCF80", packagesPath); + File* channelTable = new File(DyeChannelHash, packagesPath); channelTable->getData(); - File* dyeManifestTable = new File("A77AD080", packagesPath); + File* dyeManifestTable = new File(DyeManifestHash, packagesPath); dyeManifestTable->getData(); - File* dyeFileTable = new File("BDB2C180", packagesPath); + File* dyeFileTable = new File(DyeFileHash, packagesPath); dyeFileTable->getData(); uint32_t channelHash; uint32_t dyeManifestHash; @@ -272,7 +272,8 @@ bool getAPIShader(uint32_t apiHash, std::string outputPath, std::string packages normalName = channelName + "_" + std::to_string(texID) + "_" + texHash + "_" + addString; } else diffuseName = channelName + "_" + std::to_string(texID) + "_" + texHash + "_" + addString; - tex.tex2Other(outputPath + "/" + channelName + "_" + std::to_string(texID) + "_" + texHash + "_" + addString + ".dds", "png"); + tex.get(); + tex.save(outputPath + "/" + channelName + "_" + std::to_string(texID) + "_" + texHash + "_" + addString, "png"); } // Get dye data if (finalDyeFile == nullptr) continue; @@ -364,7 +365,7 @@ void writeShader(std::unordered_map getAPISingleHashes(uint32_t mHash, uint32_t fHash, std::string packagesPath, std::unordered_map hash64Table) { std::vector h64Files = { "", "" }; - File pairTable = File("BEB2C180", packagesPath); + File pairTable = File(PairTableHash, packagesPath); pairTable.getData(); uint32_t tableOffset = 0x30; uint32_t tableCount; @@ -416,7 +417,7 @@ std::vector getAPIMultiHashes(uint32_t tableOffset, File* modelTabl } } - File pairTable = File("BEB2C180", packagesPath); + File pairTable = File(PairTableHash, packagesPath); pairTable.getData(); uint32_t table2Offset = 0x30; uint32_t table2Count; diff --git a/api.h b/api.h index f8d47eb..492ea0a 100644 --- a/api.h +++ b/api.h @@ -10,3 +10,11 @@ std::vector getHashesFromH64s(std::vector h64Files, st uint32_t getArtArrangementHash(uint32_t apiHash, std::string packagesPath); bool getAPIShader(uint32_t apiHash, std::string outputPath, std::string packagesPath, std::unordered_map hash64Table); void writeShader(std::unordered_map>> dyes, std::unordered_map> textures, bool bCustom, std::string outputPath); + +const std::string InventoryItemMapHash = "14FADB80"; // 97798080 / 80807997 +const std::string ArtArrangementMapHash = "0FA0A780"; // F2708080 / 808070F2 +const std::string EntityAssignmentMapHash = "C1A1A780"; // CE558080 / 808055CE +const std::string DyeChannelHash = "0DA0A780"; // 68768080 / 80807668 +const std::string DyeManifestHash = "C2A1A780"; // C2558080 / 808055C2 +const std::string DyeFileHash = "A28EA780"; // 8C978080 / 8080978C +const std::string PairTableHash = "A38EA780"; // 434F8080 / 80804F43 \ No newline at end of file diff --git a/dynamic.cpp b/dynamic.cpp index 54914e9..e3507c8 100644 --- a/dynamic.cpp +++ b/dynamic.cpp @@ -37,11 +37,11 @@ void Dynamic::considerSkeletonOverride() break; case 1: printf("Skeleton flag 1, ripped models will use the player body rig."); - skeletonHash = "F8EEA880"; + skeletonHash = "BC38AB80"; //this is eva's body rig but could be the same break; case 2: printf("Skeleton flag 2, ripped models will use the player face rig."); - skeletonHash = "CC54A280"; + skeletonHash = "9018AB80"; //this is ikora's head rig but... might be the same? break; } } @@ -56,12 +56,15 @@ void Dynamic::getTexturePlates() { // can optimise by replacing with pointers //dyn2->getData(); - if (!dyn2->getData()) continue; + int fileSize = dyn2->getData(); + if (!fileSize) continue; memcpy((char*)&offset, dyn2->data + 0x18, 4); - offset += 712; + offset += 808; + if (offset >= fileSize) + continue; memcpy((char*)&fileVal, dyn2->data + offset, 4); + if (fileVal < 0x80a00000 || fileVal > 0x81ffffff) continue; fileHash = uint32ToHexStr(fileVal); - if (fileHash == "ffffffff") continue; TexturePlateSet* texplateSet = new TexturePlateSet(fileHash, packagesPath); texplateSets.push_back(texplateSet); } @@ -143,7 +146,7 @@ void Dynamic::getDyn3Files() continue; } memcpy((char*)&off, dyn2->data + off + 572, 4); - if (off < 2155872256) + if (off < 0x80800000) { printf("\nDynamic has no mesh data (D), skipping..."); continue; @@ -173,13 +176,13 @@ void Dynamic::getDyn3Files() while (true) { memcpy((char*)&val, dyn2->data + extOff, 4); - if (val == 2155872276) + if (val == 0x80800014) { bFound = true; extOff -= 8; break; } - else if (val == 2155913144) break; + else if (val == 0x80809FB8) break; extOff -= 4; } if (bFound) @@ -271,7 +274,7 @@ void Dynamic::parseDyn3s() memcpy((char*)&submesh->primType, dyn3->data + k + 6, 2); memcpy((char*)&submesh->indexOffset, dyn3->data + k + 0x8, 4); memcpy((char*)&submesh->indexCount, dyn3->data + k + 0xC, 4); - memcpy((char*)&submesh->lodLevel, dyn3->data + k + 0x1B, 1); + memcpy((char*)&submesh->lodLevel, dyn3->data + k + 0x1D, 1); if (submesh->lodLevel < currentLOD) lodGroup++; currentLOD = submesh->lodLevel; submesh->lodGroup = lodGroup; @@ -417,7 +420,7 @@ void Dynamic::getSubmeshes() if (mesh->vertNorm.size()) submesh->vertNorm = trimVertsData(mesh->vertNorm, dsort, false); if (mesh->vertUV.size()) submesh->vertUV = trimVertsData(mesh->vertUV, dsort, false); if (mesh->vertCol.size()) submesh->vertCol = trimVertsData(mesh->vertCol, dsort, true); - if (mesh->weights.size()) submesh->weights = trimVertsData(mesh->weights, dsort, false); + if (mesh->weights.size()) submesh->weights = trimVertsData(mesh->weights, dsort, false); //hash 5BF4DE80 is failing on trimming the weights data. if (mesh->weightIndices.size()) submesh->weightIndices = trimVertsData(mesh->weightIndices, dsort); //existingOffsets.push_back(submesh->indexOffset); existingSubmeshes[submesh->indexOffset] = submesh->lodLevel; diff --git a/fbxmodel.cpp b/fbxmodel.cpp index be50e0e..6f67fcb 100644 --- a/fbxmodel.cpp +++ b/fbxmodel.cpp @@ -144,8 +144,15 @@ FbxMesh* FbxModel::createMesh(Submesh* submesh, bool bAddSkeleton) else mesh->SetControlPointAt(FbxVector4(-v[0], v[2], v[1]), i); } - for (auto& face : submesh->faces) + for (int f = 0; f < submesh->faces.size(); f++) { + if (!submesh->faces[f].size()) + { + std::perror("why is it failing here\n"); + continue; + } + std::vector face = submesh->faces[f]; + //std::cout << std::to_string(f) << ": " << std::to_string(face[0]) << " " << std::to_string(face[1]) << " " << std::to_string(face[2]) << "\n"; mesh->BeginPolygon(); mesh->AddPolygon(face[0]); mesh->AddPolygon(face[1]); @@ -174,7 +181,15 @@ void FbxModel::save(std::string savePath, bool ascii) if (ascii) intAscii = 1; FbxExporter* exporter = FbxExporter::Create(manager, ""); - exporter->Initialize(savePath.c_str(), intAscii, manager->GetIOSettings()); + exporter->Initialize("tmp.fbx", intAscii, manager->GetIOSettings()); exporter->Export(scene); exporter->Destroy(); -} \ No newline at end of file + + // skirting around the fact that FbxExporter->Initialize() doesnt support unicode + int wchars_num = MultiByteToWideChar(CP_ACP, 0, savePath.c_str(), -1, NULL, 0); + wchar_t* widestr = new wchar_t[wchars_num]; + MultiByteToWideChar(CP_ACP, 0, savePath.c_str(), -1, widestr, wchars_num); + + CopyFile(L"tmp.fbx", widestr, false); + DeleteFile(L"tmp.fbx"); +} diff --git a/h64 b/h64 index d96451f..239b2ab 100644 Binary files a/h64 and b/h64 differ diff --git a/h64a b/h64a deleted file mode 100644 index 0079a2b..0000000 Binary files a/h64a and /dev/null differ diff --git a/helpers.cpp b/helpers.cpp index 7a0a0be..05a5c36 100644 --- a/helpers.cpp +++ b/helpers.cpp @@ -15,7 +15,12 @@ File::File(std::string x, std::string pkgsPath) int File::getData() { - if (hash.substr(hash.length() - 2) != "80" || hash.substr(hash.length() - 4) == "8080") return 0; + int hashInt = hexStrToUint32(hash); + if (hashInt < 0x80a00000 || hashInt > 0x81ffffff) + { + //std::cout << "Invalid hash: " << hash << std::endl; + return 0; + } if (pkgID == "") { @@ -30,7 +35,7 @@ int File::getData() std::string getPkgID(std::string hash) { - std::string pkgID = uint16ToHexStr(floor((hexStrToUint32(hash) - 0x80800000)/8192)); + std::string pkgID = uint16ToHexStr(floor((hexStrToUint32(hash) - 0x80800000) / 8192)); return pkgID; } diff --git a/helpers.h b/helpers.h index d80571c..651dc12 100644 --- a/helpers.h +++ b/helpers.h @@ -1,7 +1,7 @@ #pragma once #include #include -#include "../DestinyUnpackerCPP/package.h" +#include "DestinyUnpackerCPP\package.h" // forward declarations class Texture; @@ -124,8 +124,7 @@ class DynamicMesh : public Mesh VertexBufferHeader* spsbWeightsFile = nullptr; }; - -std::string getReferenceFromHash(std::string hash, std::string pkgsPath); std::string getHash64(uint64_t hash64, std::unordered_map hash64Table); +std::string getReferenceFromHash(std::string hash, std::string pkgsPath); std::string getPkgID(std::string hash); -uint16_t getPkgID(uint32_t hash); \ No newline at end of file +uint16_t getPkgID(uint32_t hash); diff --git a/libfbxsdk.dll b/libfbxsdk.dll index dc26d9e..6fdbc9c 100644 Binary files a/libfbxsdk.dll and b/libfbxsdk.dll differ diff --git a/main.cpp b/main.cpp index 26f7f46..5c52a32 100644 --- a/main.cpp +++ b/main.cpp @@ -5,19 +5,23 @@ static void show_usage() { - std::cerr << "Usage: MontevenDynamicExtractorv1.0.0 -p [packages path] -o [output path] -n [file name] -i [input hash] -t -b [package ID] -a [api hash]" + std::cerr << "Usage: MontevenDynamicExtractorv1.9.1 -p [packages path] -o [output path] -n [file name] -i [input hash] -t -b [package ID] -a [api hash] -h [shader hash] -c" << std::endl; std::cerr << "-t enables texture extraction\n"; std::cerr << "-b [package ID] extracts all the dynamic models available for that package ID. -t, -i, -n are ignored\n"; - std::cerr << "-a [api hash] extracts the models paired with that given api hash if valid. -i, -b ignored"; + std::cerr << "-a [api hash] extracts the models paired with that given api hash if valid. -i, -b are ignored\n"; + std::cerr << "-h [api shader hash] extracts the shader that is paired with the given api hash. -i, -b, -a are ignored.\n"; + std::cerr << "-c enables cbuffer extraction"; } - /* Using Sarge https://mayaposch.wordpress.com/2019/03/17/parsing-command-line-arguments-in-c/ */ + int main(int argc, char** argv) { + CoInitializeEx(nullptr, COINITBASE_MULTITHREADED); + Sarge sarge; sarge.setArgument("p", "pkgspath", "pkgs path", true); @@ -81,21 +85,25 @@ int main(int argc, char** argv) // Checking params are valid if (pkgsPath == "" || outputPath == "" || (modelHash == "" && batchPkg == "" && apiHash == 0 && shaderHash == 0)) { - std::cerr << "Invalid parameters, potentially backslashes in paths or paths not given.\n"; + std::cerr << "Invalid parameters, paths not given.\n"; show_usage(); return 1; } - else if (!std::filesystem::exists(outputPath) || !std::filesystem::exists(pkgsPath)) + else if (!std::filesystem::exists(pkgsPath)) { - std::cerr << "Output path or packages path does not exist. Check they exist and try again.\n"; + std::cerr << "Packages path does not exist. Check that it exists and try again.\n"; show_usage(); return 1; } + else if (!std::filesystem::exists(outputPath)) + { + std::filesystem::create_directories(outputPath); + } if (pkgsPath.find('\\') != std::string::npos || outputPath.find('\\') != std::string::npos) { - printf("\nBackslashes in paths detected, please change to forward slashes (/).\n"); - return 1; + std::replace(pkgsPath.begin(), pkgsPath.end(), '\\', '/'); + std::replace(outputPath.begin(), outputPath.end(), '\\', '/'); } // Check if h64 file exists, if not then generate and save @@ -221,16 +229,4 @@ void doBatch(std::string pkgsPath, std::string outputPath, std::string batchPkg, else printf("\nDynamic has no mesh data (A), skipping...\n"); } -} - -void replaceBackslashes(std::string& path) -{ - for (int i = 0; i < path.size(); i++) - { - if (path[i] == '\\') - { - path.insert(i, 1, '\\'); - i++; - } - } -} +} \ No newline at end of file diff --git a/main.h b/main.h index f97fafb..97b04ab 100644 --- a/main.h +++ b/main.h @@ -4,7 +4,7 @@ #include #include "Sarge/src/sarge.cpp" #include "dynamic.h" -#include "../DestinyUnpackerCPP/package.h" +#include "DestinyUnpackerCPP\package.h" #include #include "api.h" diff --git a/texconv.exe b/texconv.exe deleted file mode 100644 index 0543294..0000000 Binary files a/texconv.exe and /dev/null differ diff --git a/texplate.cpp b/texplate.cpp index d00065a..485ad33 100644 --- a/texplate.cpp +++ b/texplate.cpp @@ -57,13 +57,6 @@ void TexturePlate::savePlate(std::string fullSavePath) { if (!textures.size()) return; - if (type == "Dyemap") - { - for (auto& val : dimensions) - val /= 2; - } - - // See if we need to shrink the texture by half int maxValue = 0; for (auto& tex : textures) { @@ -71,33 +64,45 @@ void TexturePlate::savePlate(std::string fullSavePath) { maxValue = tex->offsetX + tex->scaleX; } - else if (tex->offsetY + tex->scaleY > maxValue) + if (tex->offsetY + tex->scaleY > maxValue) { maxValue = tex->offsetY + tex->scaleY; } } - if (maxValue <= dimensions[0] / 2 && maxValue <= dimensions[1] / 2) - { - for (auto& val : dimensions) - val /= 2; - } - // Extract every image on plate - //std::vector cvIms; - cv::Mat4b res(dimensions[0], dimensions[1], cv::Vec4b(0, 0, 0, 0)); + maxValue = (int)pow(2, ceil(log2(maxValue))); + + DXGI_FORMAT dxFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + if (type == "Diffuse") + dxFormat = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + + DirectX::ScratchImage OutputPlate; + OutputPlate.Initialize2D(dxFormat, maxValue, maxValue, 1, 0); for (auto& tex : textures) { - std::string save = fullSavePath + tex->hash + ".PNG"; - tex->tex2Other(fullSavePath + tex->hash + ".dds", "png"); - cv::Mat cvIm = cv::imread(save, cv::IMREAD_UNCHANGED); - if (cvIm.empty()) - { - printf("Tex not written!"); - exit(1); - } - cvIm.copyTo(res(cv::Rect(tex->offsetX, tex->offsetY, tex->scaleX, tex->scaleY))); - remove(save.c_str()); + tex->get(); + DirectX::ScratchImage DSResizedImage; + DirectX::Rect imageRect = DirectX::Rect(0, 0, tex->width, tex->height); + DirectX::Resize(*tex->DSImage.GetImage(0, 0, 0), tex->scaleX, tex->scaleY, DirectX::TEX_FILTER_FLAGS::TEX_FILTER_SEPARATE_ALPHA, DSResizedImage); + + DirectX::Image Resized = *DSResizedImage.GetImage(0, 0, 0); + DirectX::CopyRectangle(Resized, imageRect, *OutputPlate.GetImage(0, 0, 0), DirectX::TEX_FILTER_FLAGS::TEX_FILTER_SEPARATE_ALPHA, tex->offsetX, tex->offsetY); + + tex->DSImage.Release(); + DSResizedImage.Release(); free(tex); } - cv::imwrite(fullSavePath + hash + "_" + type + ".png", res); -} \ No newline at end of file + + std::string FileName; + wchar_t* widestr; + FileName = fullSavePath + hash + "_" + type + ".png"; + + // convert to unicode (utf-16) + int wchars_num = MultiByteToWideChar(CP_ACP, 0, FileName.c_str(), -1, NULL, 0); + widestr = new wchar_t[wchars_num]; + MultiByteToWideChar(CP_ACP, 0, FileName.c_str(), -1, widestr, wchars_num); + + DirectX::SaveToWICFile(*OutputPlate.GetImage(0, 0, 0), DirectX::WIC_FLAGS::WIC_FLAGS_NONE, GetWICCodec(DirectX::WIC_CODEC_PNG), widestr); + + OutputPlate.Release(); +} diff --git a/texplate.h b/texplate.h index edb7198..3e17504 100644 --- a/texplate.h +++ b/texplate.h @@ -1,7 +1,5 @@ #pragma once #include -#include "opencv2/opencv.hpp" -#include "opencv2/imgcodecs.hpp" #include "helpers.h" #include "texture.h" @@ -9,7 +7,7 @@ - Parse texture plate set to get each plate - Parse each plate to get their coords, scales, and tex refs - Extract each texture from a plate -- Open in opencv and combine using texplate data +- Resize and combine using DirectXTex - Save as a final image */ diff --git a/texture.cpp b/texture.cpp index 0f4d304..f28739f 100644 --- a/texture.cpp +++ b/texture.cpp @@ -4,146 +4,92 @@ void Texture::getHeader(std::string x) { - memcpy((char*)&textureFormat, data + 4, 2); - memcpy((char*)&width, data + 0x22, 2); - memcpy((char*)&height, data + 0x24, 2); - memcpy((char*)&arraySize, data + 0x28, 2); - uint32_t val; - memcpy((char*)&val, data + 0x3C, 4); - largeHash = uint32ToHexStr(val); + memcpy((char*)&textureFormat, data + 4, 2); + memcpy((char*)&width, data + 0x22, 2); + memcpy((char*)&height, data + 0x24, 2); + memcpy((char*)&arraySize, data + 0x28, 2); + uint32_t val; + memcpy((char*)&val, data + 0x3C, 4); + largeHash = uint32ToHexStr(val); + dxgiFormat = (DXGI_FORMAT)textureFormat; } -void Texture::tex2DDS(std::string fullSavePath) +void Texture::save(std::string fullSavePath, std::string saveFormat) { - if (largeHash != "ffffffff" && largeHash != "") - dataFile = new File(largeHash, packagesPath); - else - dataFile = new File(getReferenceFromHash(hash, packagesPath), packagesPath); - writeTexture(fullSavePath); + if (DSImage.GetImageCount() == 0) return; + DirectX::Image DImage = *DSImage.GetImage(0, 0, 0); + if (!DImage.width) return; + std::string FileName; + std::wstring widestr; + const wchar_t* widecstr; + if (saveFormat == "png") + { + FileName = fullSavePath + ".png"; + widestr = std::wstring(FileName.begin(), FileName.end()); + widecstr = widestr.c_str(); + DirectX::SaveToWICFile(DImage, DirectX::WIC_FLAGS::WIC_FLAGS_NONE, GetWICCodec(DirectX::WIC_CODEC_PNG), widecstr); + } + else if (saveFormat == "tga") + { + FileName = fullSavePath + ".tga"; + widestr = std::wstring(FileName.begin(), FileName.end()); + widecstr = widestr.c_str(); + DirectX::SaveToTGAFile(DImage, widecstr); + } + else + { + FileName = fullSavePath + ".dds"; + widestr = std::wstring(FileName.begin(), FileName.end()); + widecstr = widestr.c_str(); + DirectX::SaveToDDSFile(DImage, DirectX::DDS_FLAGS_NONE, widecstr); + } } -void Texture::tex2Other(std::string fullSavePath, std::string saveFormat) +void Texture::get() { - tex2DDS(fullSavePath); - std::string dxgiFormat; - dxgiFormat = DXGI_FORMAT[textureFormat]; - - /// Code to try and fix texconv not always working from command line, couldn't get it to work - //wchar_t exePath[MAX_PATH]; - //DWORD nSize = 0; - //GetModuleFileName(NULL, exePath, MAX_PATH); - //std::wstring wPath(exePath); - //wPath.erase(wPath.rfind('\\')); - - //std::wstring wFSP(fullSavePath.begin(), fullSavePath.end()); - //std::wstring wsaveFormat(saveFormat.begin(), saveFormat.end()); - //std::wstring wdxgiFormat(dxgiFormat.begin(), dxgiFormat.end()); - - //std::wstring wPathNoBackslashes = L""; + if (largeHash != "ffffffff" && largeHash != "") + dataFile = new File(largeHash, packagesPath); + else + dataFile = new File(getReferenceFromHash(hash, packagesPath), packagesPath); - //for (auto& c : wPath) - //{ - // if (c == '\\') wPathNoBackslashes += '/'; - // else wPathNoBackslashes += c; - //} + dataFile->getData(); - //std::wstring str = L'"' + wPathNoBackslashes + L"/texconv.exe" + L'"' + L" " + wFSP + L"\" -y -ft " + wsaveFormat + L" -f " + wdxgiFormat; - //wprintf(str.c_str()); - //_wsystem(str.c_str()); - - std::string str = "texconv.exe \"" + fullSavePath + "\" -y -ft " + saveFormat + " -f " + dxgiFormat; - printf(str.c_str()); - system(str.c_str()); + DirectX::Image DImage; - // Delete dds file if it exists - std::string newPath = fullSavePath.substr(0, fullSavePath.size() - 3) + saveFormat; - std::ifstream f(newPath); - if (f) std::remove(fullSavePath.c_str()); -} + DImage.width = width; + DImage.height = height; + DImage.format = dxgiFormat; -void Texture::writeTexture(std::string fullSavePath) -{ - bool bCompressed = false; - if (70 < textureFormat < 99) bCompressed = true; - - DDSHeader dds; - DXT10Header dxt; - dds.MagicNumber = 542327876; - dds.dwSize = 124; - dds.dwFlags = (0x1 + 0x2 + 0x4 + 0x1000) + 0x8; - dds.dwHeight = height; - dds.dwWidth = width; - dds.dwPitchOrLinearSize = 0; - dds.dwDepth = 0; - dds.dwMipMapCount = 0; - dds.dwReserved1 = std::array(); - dds.dwPFSize = 32; - dds.dwPFRGBBitCount = 0; - dds.dwPFRGBBitCount = 32; - dds.dwPFRBitMask = 0xFF; - dds.dwPFGBitMask = 0xFF00; - dds.dwPFBBitMask = 0xFF0000; - dds.dwPFABitMask = 0xFF000000; - dds.dwCaps = 0x1000; - dds.dwCaps2 = 0; - dds.dwCaps3 = 0; - dds.dwCaps4 = 0; - dds.dwReserved2 = 0; - if (bCompressed) + size_t rowPitch; + size_t slicePitch; + DirectX::ComputePitch(dxgiFormat, width, height, rowPitch, slicePitch); + DImage.rowPitch = rowPitch; + DImage.slicePitch = slicePitch; + DImage.pixels = dataFile->data; + if (isFormatCompressed(dxgiFormat)) { - dds.dwPFFlags = 0x1 + 0x4; // contains alpha data + contains compressed RGB data - dds.dwPFFourCC = 808540228; - dxt.dxgiFormat = textureFormat; - dxt.resourceDimension = 3; // DDS_DIMENSION_TEXTURE2D - if (arraySize % 6 == 0) - { - // Compressed cubemap - dxt.miscFlag = 4; - dxt.arraySize = arraySize / 6; - } - else - { - // Compressed BCn - dxt.miscFlag = 0; - dxt.arraySize = 1; - } + DirectX::Decompress(DImage, DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM, DSImage); } else { - // Uncompressed - dds.dwPFFlags = 0x1 + 0x40; // contains alpha data + contains uncompressed RGB data - dds.dwPFFourCC = 0; - dxt.miscFlag = 0; - dxt.arraySize = 1; - dxt.miscFlags2 = 0x1; - } - - writeFile(dds, dxt, fullSavePath); -} - -void Texture::writeFile(DDSHeader dds, DXT10Header dxt, std::string fullSavePath) -{ - FILE* outputFile; - - fopen_s(&outputFile, fullSavePath.c_str(), "wb"); - if (outputFile != NULL) { - fwrite(&dds, sizeof(struct DDSHeader), 1, outputFile); - fwrite(&dxt, sizeof(struct DXT10Header), 1, outputFile); - int fileSize = dataFile->getData(); - fwrite(dataFile->data, fileSize, 1, outputFile); - fclose(outputFile); + DSImage.InitializeFromImage(DImage); } + delete dataFile->data; } void Material::parseMaterial(std::unordered_map hash64Table) { - getData(); + uint32_t fileSize; + fileSize = getData(); uint32_t textureCount; uint32_t textureOffset; // Pixel shader textures - memcpy((char*)&textureCount, data + 0x2A0, 4); - memcpy((char*)&textureOffset, data + 0x2A8, 4); - textureOffset += 0x2A8 + 0x10; + memcpy((char*)&textureCount, data + 0x2B8, 4); + if (textureCount == 0) + return; + memcpy((char*)&textureOffset, data + 0x2C0, 4); + textureOffset += 0x2C0 + 0x10; + uint64_t h64Val; for (int i = textureOffset; i < textureOffset + textureCount * 0x18; i += 0x18) { @@ -163,6 +109,12 @@ void Material::parseMaterial(std::unordered_map hash64Table) textures[textureIndex] = texture; } } + else if ((h64Check.substr(h64Check.length() - 2) == "80" || h64Check.substr(h64Check.length() - 2) == "81") && h64Check.substr(h64Check.length() - 4) != "8080") + { + std::string textureHash = getReferenceFromHash(h64Check, packagesPath); + Texture* texture = new Texture(textureHash, packagesPath); + textures[textureIndex] = texture; + } else { printf("Support old texture format"); @@ -173,29 +125,24 @@ void Material::parseMaterial(std::unordered_map hash64Table) void Material::exportTextures(std::string fullSavePath, std::string saveFormat) { - std::string actualSavePath; std::string newPath; for (auto& element : textures) { uint8_t texID = element.first; Texture* tex = element.second; - actualSavePath = fullSavePath + "/" + tex->hash + ".dds"; - newPath = fullSavePath + "/" + tex->hash + "." + saveFormat; - std::ifstream f(newPath); - std::ifstream q(actualSavePath); - if (f || q) - { - free(tex); - continue; - } - if (saveFormat == "dds") tex->tex2DDS(actualSavePath); - else tex->tex2Other(actualSavePath, saveFormat); + newPath = fullSavePath + "/" + tex->hash; + if (!tex) continue; + tex->get(); + tex->save(newPath, saveFormat); + tex->DSImage.Release(); free(tex); } } void Material::parseCBuffers() { + //beyond light valid stuff + /* 90008080 stride 16 09008080 stride 1 @@ -212,7 +159,27 @@ void Material::parseCBuffers() pixel 0x2F0 90008080 internal offset pixel 0x30C external cbuffer hash */ - std::vector pixelOffsets = { 0x2C0, 0x2D0, 0x2F0 }; + + //wq valid stuff + + /* + 90008080 stride 16 + 09008080 stride 1 + 3F018080 stride 16 external cbuffers + --- + vertex 0x70 vertex shader texture offset + vertex 0x90 09008080 internal offset + vertex 0xA0 90008080 internal offset + vertex 0xB0 3F018080 internal offset + vertex 0xC0 90008080 internal offset + pixel 0x2D8 09008080 internal offset + pixel 0x2E8 90008080 internal offset + pixel 0x2F8 3F018080 internal offset + pixel 0x308 90008080 internal offset + pixel 0x30C external cbuffer hash + */ + + std::vector pixelOffsets = { 0x2D8, 0x2E8, 0x308 }; uint32_t val; uint32_t count; getData(); @@ -229,8 +196,8 @@ void Material::parseCBuffers() cbuffers.push_back(floats); i++; } - memcpy((char*)&val, data + 0x30C, 4); - if (val != 4294967295) + memcpy((char*)&val, data + 0x324, 4); + if (val != 0xFFFFFFFF) { File buffer = File(getReferenceFromHash(uint32ToHexStr(val), packagesPath), packagesPath); int fileSize = buffer.getData(); @@ -256,7 +223,7 @@ void Material::writeCBuffers(std::string fullSavePath) std::string getCBufferFromOffset(unsigned char* data, int offset, int count, uint32_t cbType, std::string name) { - if (cbType == 2155872265) + if (cbType == 0x80800009) { std::string allFloat = "static float cb" + name + '[' + std::to_string(count) + "] = \n{\n "; allFloat.reserve(count); @@ -264,14 +231,14 @@ std::string getCBufferFromOffset(unsigned char* data, int offset, int count, uin for (int i = 0; i < count; i++) { memcpy((char*)&val, data + offset + i, 1); - std::string floats = std::to_string((float)val/128) + ","; + std::string floats = std::to_string((float)val / 128) + ","; allFloat += floats; if (i % 8 == 0 && i != 0) allFloat += "\n "; } allFloat += "\n};\n"; return allFloat; } - else if (cbType == 2155872400 || offset == 0) + else if (cbType == 0x80800090 || offset == 0) { std::string allFloat4 = "static float4 cb" + name + '[' + std::to_string(count) + "] = \n{\n"; float_t val; @@ -293,6 +260,35 @@ std::string getCBufferFromOffset(unsigned char* data, int offset, int count, uin else { std::cerr << "\nUnknown cbuffer class found, exiting...\n"; - exit(1); + return ""; + } +} + +bool isFormatCompressed(DXGI_FORMAT fmt) { + switch (fmt) { + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + return true; + default: + return false; } } \ No newline at end of file diff --git a/texture.h b/texture.h index 103b56e..c92f2f5 100644 --- a/texture.h +++ b/texture.h @@ -1,8 +1,8 @@ #pragma once #include "helpers.h" -#include "dxgiformat.h" +//#include "dxgiformat.h" #include - +#include struct TexHeader { @@ -13,64 +13,66 @@ struct TexHeader uint32_t LargeTextureHash; }; -struct DDSHeader -{ - uint32_t MagicNumber; - uint32_t dwSize; - uint32_t dwFlags; - uint32_t dwHeight; - uint32_t dwWidth; - uint32_t dwPitchOrLinearSize; - uint32_t dwDepth; - uint32_t dwMipMapCount; - std::array dwReserved1; - uint32_t dwPFSize; - uint32_t dwPFFlags; - uint32_t dwPFFourCC; - uint32_t dwPFRGBBitCount; - uint32_t dwPFRBitMask; - uint32_t dwPFGBitMask; - uint32_t dwPFBBitMask; - uint32_t dwPFABitMask; - uint32_t dwCaps; - uint32_t dwCaps2; - uint32_t dwCaps3; - uint32_t dwCaps4; - uint32_t dwReserved2; -}; - -struct DXT10Header -{ - uint32_t dxgiFormat; - uint32_t resourceDimension; - uint32_t miscFlag; - uint32_t arraySize; - uint32_t miscFlags2; -}; +//struct DDSHeader +//{ +// uint32_t MagicNumber; +// uint32_t dwSize; +// uint32_t dwFlags; +// uint32_t dwHeight; +// uint32_t dwWidth; +// uint32_t dwPitchOrLinearSize; +// uint32_t dwDepth; +// uint32_t dwMipMapCount; +// std::array dwReserved1; +// uint32_t dwPFSize; +// uint32_t dwPFFlags; +// uint32_t dwPFFourCC; +// uint32_t dwPFRGBBitCount; +// uint32_t dwPFRBitMask; +// uint32_t dwPFGBitMask; +// uint32_t dwPFBBitMask; +// uint32_t dwPFABitMask; +// uint32_t dwCaps; +// uint32_t dwCaps2; +// uint32_t dwCaps3; +// uint32_t dwCaps4; +// uint32_t dwReserved2; +//}; +// +//struct DXT10Header +//{ +// uint32_t dxgiFormat; +// uint32_t resourceDimension; +// uint32_t miscFlag; +// uint32_t arraySize; +// uint32_t miscFlags2; +//}; class Texture : public Header { private: - File* dataFile = nullptr; - int textureFormat; - uint16_t width; - uint16_t height; uint16_t arraySize; std::string largeHash; std::string fullSavePath; void getHeader(std::string x); - void writeTexture(std::string fullSavePath); - void writeFile(DDSHeader dds, DXT10Header dxt, std::string fullSavePath); + void writeFile(std::string fullSavePath); public: + File* dataFile = nullptr; + DXGI_FORMAT dxgiFormat; + int textureFormat; + uint16_t width; + uint16_t height; + DirectX::ScratchImage DSImage; + Texture(std::string x, std::string pkgsPath) : Header(x, pkgsPath) { getData(); getHeader(x); } - - void tex2DDS(std::string fullSavePath); - void tex2Other(std::string fullSavePath, std::string saveFormat); + void get(); + //void tex2DDS(std::string fullSavePath); + void save(std::string fullSavePath, std::string saveFormat); }; class Material : public File @@ -87,4 +89,5 @@ class Material : public File void writeCBuffers(std::string fullSavePath); }; -std::string getCBufferFromOffset(unsigned char* data, int offset, int count, uint32_t cbType, std::string name); \ No newline at end of file +std::string getCBufferFromOffset(unsigned char* data, int offset, int count, uint32_t cbType, std::string name); +bool isFormatCompressed(DXGI_FORMAT fmt); diff --git a/x64/Debug/DestinyD.6c3dbec6.tlog/CL.command.1.tlog b/x64/Debug/DestinyD.6c3dbec6.tlog/CL.command.1.tlog deleted file mode 100644 index a4d3444..0000000 Binary files a/x64/Debug/DestinyD.6c3dbec6.tlog/CL.command.1.tlog and /dev/null differ diff --git a/x64/Debug/DestinyD.6c3dbec6.tlog/CL.read.1.tlog b/x64/Debug/DestinyD.6c3dbec6.tlog/CL.read.1.tlog deleted file mode 100644 index d2e73b8..0000000 Binary files a/x64/Debug/DestinyD.6c3dbec6.tlog/CL.read.1.tlog and /dev/null differ diff --git a/x64/Debug/DestinyD.6c3dbec6.tlog/CL.write.1.tlog b/x64/Debug/DestinyD.6c3dbec6.tlog/CL.write.1.tlog deleted file mode 100644 index 46a45cc..0000000 Binary files a/x64/Debug/DestinyD.6c3dbec6.tlog/CL.write.1.tlog and /dev/null differ diff --git a/x64/Debug/DestinyD.6c3dbec6.tlog/DestinyDynamicExtractor.lastbuildstate b/x64/Debug/DestinyD.6c3dbec6.tlog/DestinyDynamicExtractor.lastbuildstate deleted file mode 100644 index 595cc18..0000000 --- a/x64/Debug/DestinyD.6c3dbec6.tlog/DestinyDynamicExtractor.lastbuildstate +++ /dev/null @@ -1,2 +0,0 @@ -PlatformToolSet=v142:VCToolArchitecture=Native32Bit:VCToolsVersion=14.29.30133:VCServicingVersionATL=14.29.30136:VCServicingVersionCrtHeaders=14.29.30136:TargetPlatformVersion=10.0.20348.0:VcpkgTriplet=x64-windows: -Debug|x64|C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\| diff --git a/x64/Debug/DestinyD.6c3dbec6.tlog/DestinyDynamicExtractor.write.1u.tlog b/x64/Debug/DestinyD.6c3dbec6.tlog/DestinyDynamicExtractor.write.1u.tlog deleted file mode 100644 index 7535841..0000000 Binary files a/x64/Debug/DestinyD.6c3dbec6.tlog/DestinyDynamicExtractor.write.1u.tlog and /dev/null differ diff --git a/x64/Debug/DestinyD.6c3dbec6.tlog/link.command.1.tlog b/x64/Debug/DestinyD.6c3dbec6.tlog/link.command.1.tlog deleted file mode 100644 index 9ac9cab..0000000 Binary files a/x64/Debug/DestinyD.6c3dbec6.tlog/link.command.1.tlog and /dev/null differ diff --git a/x64/Debug/DestinyD.6c3dbec6.tlog/link.delete.1.tlog b/x64/Debug/DestinyD.6c3dbec6.tlog/link.delete.1.tlog deleted file mode 100644 index 9907085..0000000 Binary files a/x64/Debug/DestinyD.6c3dbec6.tlog/link.delete.1.tlog and /dev/null differ diff --git a/x64/Debug/DestinyD.6c3dbec6.tlog/link.read.1.tlog b/x64/Debug/DestinyD.6c3dbec6.tlog/link.read.1.tlog deleted file mode 100644 index 0deac6c..0000000 Binary files a/x64/Debug/DestinyD.6c3dbec6.tlog/link.read.1.tlog and /dev/null differ diff --git a/x64/Debug/DestinyD.6c3dbec6.tlog/link.write.1.tlog b/x64/Debug/DestinyD.6c3dbec6.tlog/link.write.1.tlog deleted file mode 100644 index 7ae0472..0000000 Binary files a/x64/Debug/DestinyD.6c3dbec6.tlog/link.write.1.tlog and /dev/null differ diff --git a/x64/Debug/DestinyDynamicExtractor.Build.CppClean.log b/x64/Debug/DestinyDynamicExtractor.Build.CppClean.log deleted file mode 100644 index e4fcbbf..0000000 --- a/x64/Debug/DestinyDynamicExtractor.Build.CppClean.log +++ /dev/null @@ -1,20 +0,0 @@ -c:\users\monta\onedrive\destiny 2 datamining\cpp\destinydataminingcpp\destinydynamicextractor\x64\debug\vc142.pdb -c:\users\monta\onedrive\destiny 2 datamining\cpp\destinydataminingcpp\destinydynamicextractor\x64\debug\vc142.idb -c:\users\monta\onedrive\destiny 2 datamining\cpp\destinydataminingcpp\destinydynamicextractor\x64\debug\main.obj -c:\users\monta\onedrive\destiny 2 datamining\cpp\destinydataminingcpp\destinydynamicextractor\x64\debug\helpers.obj -c:\users\monta\onedrive\destiny 2 datamining\cpp\destinydataminingcpp\destinydynamicextractor\x64\debug\dynamic.obj -c:\users\monta\onedrive\destiny 2 datamining\cpp\destinydataminingcpp\destinydynamicextractor\x64\debug\vertex.obj -c:\users\monta\onedrive\destiny 2 datamining\cpp\destinydataminingcpp\destinydynamicextractor\x64\debug\index.obj -c:\users\monta\onedrive\destiny 2 datamining\cpp\destinydataminingcpp\destinydynamicextractor\x64\debug\fbxmodel.obj -c:\users\monta\onedrive\destiny 2 datamining\cpp\destinydataminingcpp\x64\debug\destinydynamicextractor.exe -c:\users\monta\onedrive\destiny 2 datamining\cpp\destinydataminingcpp\x64\debug\destinydynamicextractor.ilk -c:\users\monta\onedrive\destiny 2 datamining\cpp\destinydataminingcpp\x64\debug\destinydynamicextractor.pdb -c:\users\monta\onedrive\destiny 2 datamining\cpp\destinydataminingcpp\destinydynamicextractor\x64\debug\dynamic.obj.enc -c:\users\monta\onedrive\destiny 2 datamining\cpp\destinydataminingcpp\destinydynamicextractor\x64\debug\index.obj.enc -c:\users\monta\onedrive\destiny 2 datamining\cpp\destinydataminingcpp\destinydynamicextractor\x64\debug\main.obj.enc -c:\users\monta\onedrive\destiny 2 datamining\cpp\destinydataminingcpp\destinydynamicextractor\x64\debug\destinyd.6c3dbec6.tlog\cl.command.1.tlog -c:\users\monta\onedrive\destiny 2 datamining\cpp\destinydataminingcpp\destinydynamicextractor\x64\debug\destinyd.6c3dbec6.tlog\cl.read.1.tlog -c:\users\monta\onedrive\destiny 2 datamining\cpp\destinydataminingcpp\destinydynamicextractor\x64\debug\destinyd.6c3dbec6.tlog\cl.write.1.tlog -c:\users\monta\onedrive\destiny 2 datamining\cpp\destinydataminingcpp\destinydynamicextractor\x64\debug\destinyd.6c3dbec6.tlog\link.command.1.tlog -c:\users\monta\onedrive\destiny 2 datamining\cpp\destinydataminingcpp\destinydynamicextractor\x64\debug\destinyd.6c3dbec6.tlog\link.read.1.tlog -c:\users\monta\onedrive\destiny 2 datamining\cpp\destinydataminingcpp\destinydynamicextractor\x64\debug\destinyd.6c3dbec6.tlog\link.write.1.tlog diff --git a/x64/Debug/DestinyDynamicExtractor.dll.recipe b/x64/Debug/DestinyDynamicExtractor.dll.recipe deleted file mode 100644 index 9a1a9c6..0000000 --- a/x64/Debug/DestinyDynamicExtractor.dll.recipe +++ /dev/null @@ -1,11 +0,0 @@ - - - - - C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\x64\Debug\DestinyDynamicExtractor.dll - - - - - - \ No newline at end of file diff --git a/x64/Debug/DestinyDynamicExtractor.exe.recipe b/x64/Debug/DestinyDynamicExtractor.exe.recipe deleted file mode 100644 index f9309a4..0000000 --- a/x64/Debug/DestinyDynamicExtractor.exe.recipe +++ /dev/null @@ -1,11 +0,0 @@ - - - - - C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\x64\Debug\DestinyDynamicExtractor.exe - - - - - - \ No newline at end of file diff --git a/x64/Debug/DestinyDynamicExtractor.log b/x64/Debug/DestinyDynamicExtractor.log deleted file mode 100644 index 791e3d2..0000000 --- a/x64/Debug/DestinyDynamicExtractor.log +++ /dev/null @@ -1,39 +0,0 @@ - api.cpp -C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\DestinyDynamicExtractor\api.cpp(60,30): warning C4018: '<': signed/unsigned mismatch -C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\DestinyDynamicExtractor\api.cpp(94,30): warning C4018: '<': signed/unsigned mismatch -C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\DestinyDynamicExtractor\api.cpp(132,30): warning C4018: '<': signed/unsigned mismatch -C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\DestinyDynamicExtractor\api.cpp(160,42): warning C4018: '<': signed/unsigned mismatch -C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\DestinyDynamicExtractor\api.cpp(166,41): warning C4018: '<': signed/unsigned mismatch -C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\DestinyDynamicExtractor\api.cpp(214,32): warning C4018: '<': signed/unsigned mismatch -C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\DestinyDynamicExtractor\api.cpp(257,32): warning C4018: '<': signed/unsigned mismatch -C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\DestinyDynamicExtractor\api.cpp(286,32): warning C4018: '<': signed/unsigned mismatch -C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\DestinyDynamicExtractor\api.cpp(373,30): warning C4018: '<': signed/unsigned mismatch -C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\DestinyDynamicExtractor\api.cpp(402,30): warning C4018: '<': signed/unsigned mismatch -C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\DestinyDynamicExtractor\api.cpp(412,24): warning C4018: '<': signed/unsigned mismatch -C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\DestinyDynamicExtractor\api.cpp(425,31): warning C4018: '<': signed/unsigned mismatch -C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\utility(193,16): warning C4244: 'initializing': conversion from '_Ty' to '_Ty1', possible loss of data - with - [ - _Ty=__int64 - ] - and - [ - _Ty1=const uint32_t - ] -C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\DestinyDynamicExtractor\api.cpp(20): message : see reference to function template instantiation 'std::pair::pair<__int64,const char(&)[10],0>(_Other1 &&,_Other2) noexcept(false)' being compiled - with - [ - _Other1=__int64, - _Other2=const char (&)[10] - ] -C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\DestinyDynamicExtractor\api.cpp(3): message : see reference to function template instantiation 'std::pair::pair<__int64,const char(&)[10],0>(_Other1 &&,_Other2) noexcept(false)' being compiled - with - [ - _Other1=__int64, - _Other2=const char (&)[10] - ] -LINK : warning LNK4075: ignoring '/INCREMENTAL' due to '/PROFILE' specification -package.obj : warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/OPT:REF' specification - Creating library C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\x64\Debug\DestinyDynamicExtractor.lib and object C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\x64\Debug\DestinyDynamicExtractor.exp -LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library - DestinyDynamicExtractor.vcxproj -> C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\x64\Debug\DestinyDynamicExtractor.exe diff --git a/x64/Debug/DestinyDynamicExtractor.vcxproj.FileListAbsolute.txt b/x64/Debug/DestinyDynamicExtractor.vcxproj.FileListAbsolute.txt deleted file mode 100644 index e69de29..0000000 diff --git a/x64/Debug/api.obj b/x64/Debug/api.obj deleted file mode 100644 index f94ac09..0000000 Binary files a/x64/Debug/api.obj and /dev/null differ diff --git a/x64/Debug/dynamic.obj b/x64/Debug/dynamic.obj deleted file mode 100644 index d7b4fdd..0000000 Binary files a/x64/Debug/dynamic.obj and /dev/null differ diff --git a/x64/Debug/fbxmodel.obj b/x64/Debug/fbxmodel.obj deleted file mode 100644 index cfdbc9b..0000000 Binary files a/x64/Debug/fbxmodel.obj and /dev/null differ diff --git a/x64/Debug/helpers.obj b/x64/Debug/helpers.obj deleted file mode 100644 index b55dcbe..0000000 Binary files a/x64/Debug/helpers.obj and /dev/null differ diff --git a/x64/Debug/index.obj b/x64/Debug/index.obj deleted file mode 100644 index 5c6f335..0000000 Binary files a/x64/Debug/index.obj and /dev/null differ diff --git a/x64/Debug/libfbxsdk.dll b/x64/Debug/libfbxsdk.dll deleted file mode 100644 index dc26d9e..0000000 Binary files a/x64/Debug/libfbxsdk.dll and /dev/null differ diff --git a/x64/Debug/main.obj b/x64/Debug/main.obj deleted file mode 100644 index 2137b54..0000000 Binary files a/x64/Debug/main.obj and /dev/null differ diff --git a/x64/Debug/phonon.obj b/x64/Debug/phonon.obj deleted file mode 100644 index 8e18789..0000000 Binary files a/x64/Debug/phonon.obj and /dev/null differ diff --git a/x64/Debug/skeleton.obj b/x64/Debug/skeleton.obj deleted file mode 100644 index 9d45c0c..0000000 Binary files a/x64/Debug/skeleton.obj and /dev/null differ diff --git a/x64/Debug/texplate.obj b/x64/Debug/texplate.obj deleted file mode 100644 index 7f76b34..0000000 Binary files a/x64/Debug/texplate.obj and /dev/null differ diff --git a/x64/Debug/texture.obj b/x64/Debug/texture.obj deleted file mode 100644 index fec4b5e..0000000 Binary files a/x64/Debug/texture.obj and /dev/null differ diff --git a/x64/Debug/vc142.idb b/x64/Debug/vc142.idb deleted file mode 100644 index 76958d0..0000000 Binary files a/x64/Debug/vc142.idb and /dev/null differ diff --git a/x64/Debug/vc142.pdb b/x64/Debug/vc142.pdb deleted file mode 100644 index ef4193e..0000000 Binary files a/x64/Debug/vc142.pdb and /dev/null differ diff --git a/x64/Debug/vcpkg.applocal.log b/x64/Debug/vcpkg.applocal.log deleted file mode 100644 index e02abfc..0000000 --- a/x64/Debug/vcpkg.applocal.log +++ /dev/null @@ -1 +0,0 @@ - diff --git a/x64/Debug/vertex.obj b/x64/Debug/vertex.obj deleted file mode 100644 index 705f2b1..0000000 Binary files a/x64/Debug/vertex.obj and /dev/null differ diff --git a/x64/Release/DestinyD.6c3dbec6.tlog/CL.command.1.tlog b/x64/Release/DestinyD.6c3dbec6.tlog/CL.command.1.tlog deleted file mode 100644 index d6a06ef..0000000 Binary files a/x64/Release/DestinyD.6c3dbec6.tlog/CL.command.1.tlog and /dev/null differ diff --git a/x64/Release/DestinyD.6c3dbec6.tlog/CL.read.1.tlog b/x64/Release/DestinyD.6c3dbec6.tlog/CL.read.1.tlog deleted file mode 100644 index 0b4f0ca..0000000 Binary files a/x64/Release/DestinyD.6c3dbec6.tlog/CL.read.1.tlog and /dev/null differ diff --git a/x64/Release/DestinyD.6c3dbec6.tlog/CL.write.1.tlog b/x64/Release/DestinyD.6c3dbec6.tlog/CL.write.1.tlog deleted file mode 100644 index 2f0a7fb..0000000 Binary files a/x64/Release/DestinyD.6c3dbec6.tlog/CL.write.1.tlog and /dev/null differ diff --git a/x64/Release/DestinyD.6c3dbec6.tlog/DestinyDynamicExtractor.lastbuildstate b/x64/Release/DestinyD.6c3dbec6.tlog/DestinyDynamicExtractor.lastbuildstate deleted file mode 100644 index cf010eb..0000000 --- a/x64/Release/DestinyD.6c3dbec6.tlog/DestinyDynamicExtractor.lastbuildstate +++ /dev/null @@ -1,2 +0,0 @@ -PlatformToolSet=v142:VCToolArchitecture=Native32Bit:VCToolsVersion=14.29.30133:VCServicingVersionATL=14.29.30136:VCServicingVersionCrtHeaders=14.29.30136:TargetPlatformVersion=10.0.20348.0:VcpkgTriplet=x64-windows: -Release|x64|C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\| diff --git a/x64/Release/DestinyD.6c3dbec6.tlog/DestinyDynamicExtractor.write.1u.tlog b/x64/Release/DestinyD.6c3dbec6.tlog/DestinyDynamicExtractor.write.1u.tlog deleted file mode 100644 index 6a83d34..0000000 Binary files a/x64/Release/DestinyD.6c3dbec6.tlog/DestinyDynamicExtractor.write.1u.tlog and /dev/null differ diff --git a/x64/Release/DestinyD.6c3dbec6.tlog/link.command.1.tlog b/x64/Release/DestinyD.6c3dbec6.tlog/link.command.1.tlog deleted file mode 100644 index 6d95512..0000000 Binary files a/x64/Release/DestinyD.6c3dbec6.tlog/link.command.1.tlog and /dev/null differ diff --git a/x64/Release/DestinyD.6c3dbec6.tlog/link.delete.1.tlog b/x64/Release/DestinyD.6c3dbec6.tlog/link.delete.1.tlog deleted file mode 100644 index 0f67f15..0000000 Binary files a/x64/Release/DestinyD.6c3dbec6.tlog/link.delete.1.tlog and /dev/null differ diff --git a/x64/Release/DestinyD.6c3dbec6.tlog/link.read.1.tlog b/x64/Release/DestinyD.6c3dbec6.tlog/link.read.1.tlog deleted file mode 100644 index fc4f879..0000000 Binary files a/x64/Release/DestinyD.6c3dbec6.tlog/link.read.1.tlog and /dev/null differ diff --git a/x64/Release/DestinyD.6c3dbec6.tlog/link.write.1.tlog b/x64/Release/DestinyD.6c3dbec6.tlog/link.write.1.tlog deleted file mode 100644 index da9b076..0000000 Binary files a/x64/Release/DestinyD.6c3dbec6.tlog/link.write.1.tlog and /dev/null differ diff --git a/x64/Release/DestinyDynamicExtractor.dll.recipe b/x64/Release/DestinyDynamicExtractor.dll.recipe deleted file mode 100644 index 0a6d158..0000000 --- a/x64/Release/DestinyDynamicExtractor.dll.recipe +++ /dev/null @@ -1,11 +0,0 @@ - - - - - C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\x64\Release\DestinyDynamicExtractor.dll - - - - - - \ No newline at end of file diff --git a/x64/Release/DestinyDynamicExtractor.exe.recipe b/x64/Release/DestinyDynamicExtractor.exe.recipe deleted file mode 100644 index 289c1ba..0000000 --- a/x64/Release/DestinyDynamicExtractor.exe.recipe +++ /dev/null @@ -1,11 +0,0 @@ - - - - - C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\x64\Release\DestinyDynamicExtractor.exe - - - - - - \ No newline at end of file diff --git a/x64/Release/DestinyDynamicExtractor.iobj b/x64/Release/DestinyDynamicExtractor.iobj deleted file mode 100644 index 101f7ec..0000000 Binary files a/x64/Release/DestinyDynamicExtractor.iobj and /dev/null differ diff --git a/x64/Release/DestinyDynamicExtractor.ipdb b/x64/Release/DestinyDynamicExtractor.ipdb deleted file mode 100644 index a2dea56..0000000 Binary files a/x64/Release/DestinyDynamicExtractor.ipdb and /dev/null differ diff --git a/x64/Release/DestinyDynamicExtractor.log b/x64/Release/DestinyDynamicExtractor.log deleted file mode 100644 index 6536d4c..0000000 --- a/x64/Release/DestinyDynamicExtractor.log +++ /dev/null @@ -1,6 +0,0 @@ - Creating library C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\x64\Release\DestinyDynamicExtractor.lib and object C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\x64\Release\DestinyDynamicExtractor.exp - Generating code - Previous IPDB and IOBJ mismatch, fall back to full compilation. - All 3275 functions were compiled because no usable IPDB/IOBJ from previous compilation was found. - Finished generating code - DestinyDynamicExtractor.vcxproj -> C:\Users\monta\OneDrive\Destiny 2 Datamining\CPP\DestinyDataminingCPP\x64\Release\DestinyDynamicExtractor.dll diff --git a/x64/Release/api.obj b/x64/Release/api.obj deleted file mode 100644 index 740856a..0000000 Binary files a/x64/Release/api.obj and /dev/null differ diff --git a/x64/Release/dynamic.obj b/x64/Release/dynamic.obj deleted file mode 100644 index 1c0c773..0000000 Binary files a/x64/Release/dynamic.obj and /dev/null differ diff --git a/x64/Release/fbxmodel.obj b/x64/Release/fbxmodel.obj deleted file mode 100644 index 0a9b2ae..0000000 Binary files a/x64/Release/fbxmodel.obj and /dev/null differ diff --git a/x64/Release/helpers.obj b/x64/Release/helpers.obj deleted file mode 100644 index 2f8baeb..0000000 Binary files a/x64/Release/helpers.obj and /dev/null differ diff --git a/x64/Release/index.obj b/x64/Release/index.obj deleted file mode 100644 index db07812..0000000 Binary files a/x64/Release/index.obj and /dev/null differ diff --git a/x64/Release/main.obj b/x64/Release/main.obj deleted file mode 100644 index d694238..0000000 Binary files a/x64/Release/main.obj and /dev/null differ diff --git a/x64/Release/phonon.obj b/x64/Release/phonon.obj deleted file mode 100644 index 0c0d054..0000000 Binary files a/x64/Release/phonon.obj and /dev/null differ diff --git a/x64/Release/skeleton.obj b/x64/Release/skeleton.obj deleted file mode 100644 index 1196a32..0000000 Binary files a/x64/Release/skeleton.obj and /dev/null differ diff --git a/x64/Release/texplate.obj b/x64/Release/texplate.obj deleted file mode 100644 index 23a241c..0000000 Binary files a/x64/Release/texplate.obj and /dev/null differ diff --git a/x64/Release/texture.obj b/x64/Release/texture.obj deleted file mode 100644 index 13dbec7..0000000 Binary files a/x64/Release/texture.obj and /dev/null differ diff --git a/x64/Release/vc142.pdb b/x64/Release/vc142.pdb deleted file mode 100644 index 69dd0a6..0000000 Binary files a/x64/Release/vc142.pdb and /dev/null differ diff --git a/x64/Release/vcpkg.applocal.log b/x64/Release/vcpkg.applocal.log deleted file mode 100644 index e02abfc..0000000 --- a/x64/Release/vcpkg.applocal.log +++ /dev/null @@ -1 +0,0 @@ - diff --git a/x64/Release/vertex.obj b/x64/Release/vertex.obj deleted file mode 100644 index 64ae56e..0000000 Binary files a/x64/Release/vertex.obj and /dev/null differ