diff --git a/pkNX.Containers/Misc/FnvHashDecoder.cs b/pkNX.Containers/Misc/FnvHashDecoder.cs new file mode 100644 index 00000000..5f1e52a5 --- /dev/null +++ b/pkNX.Containers/Misc/FnvHashDecoder.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace pkNX.Containers; + +public class FnvHashDecoder +{ + public const string AllowedChars = "etaoinshrdlcumw_0123456789fgypbvkjxqz/."; // Sorted by most common first + + public HashSet HashesToTest = new() { 9252365659083253459, 17205188591700921149, 1234775724179408742 }; + + // 64 bit implementation + private const ulong kFnvPrime_64 = 0x00000100000001b3; + private const ulong kOffsetBasis_64 = 0xCBF29CE484222645; + + public Dictionary FoundKeys = new(); + + public Dictionary Run(int minLength, int maxLength) + { + Debug.Assert(FnvHash.HashFnv1a_64("stickyball") == 0x15cb1f582d2b05ab); + + int length = maxLength; + + var tasks = new List(); + + for (int i = 0; i < AllowedChars.Length; ++i) + { + int startChar = i; + tasks.Add(Task.Run(() => + { + var dict = pkNXHashDecoder.FnvHashDecoderLib.StartDecoding(length, startChar); + + if (dict.Count != 0) + { + foreach (var x in dict) + { + FoundKeys.Add(x.Key, x.Value); + } + } + //StartLoop(length, startChar); + })); + } + + Task t = Task.WhenAll(tasks); + try + { + t.Wait(); + } + catch { } + + return FoundKeys; + } + + private void StartLoop(int length, int startChar) + { + Span chars = stackalloc char[length]; + Span allowedCharIndex = stackalloc byte[length]; // Current AllowedChar + + // Reset all chars to starting point + chars[0] = AllowedChars[startChar]; + allowedCharIndex[0] = (byte)startChar; + + for (int i = 1; i < length; i++) + chars[i] = AllowedChars[0]; + + while (allowedCharIndex[0] == startChar) + { + // Build the hash of all chars except the last one + ulong hashBase = kOffsetBasis_64; + for (int i = 0; i < length - 1; ++i) + { + hashBase ^= chars[i]; + hashBase *= kFnvPrime_64; + + // Automatically test for shorter length strings + if (hashBase == 9252365659083253459) + { + FoundKeys.Add(hashBase, new string(chars[0..i])); + } + } + + // Loop through all AllowedChars + for (int j = 0; j < AllowedChars.Length; ++j) + { + ulong hash = hashBase; + hash ^= AllowedChars[j]; + hash *= kFnvPrime_64; + + if (hash == 9252365659083253459) + { + chars[length - 1] = AllowedChars[j]; + FoundKeys.Add(hash, new string(chars)); + } + } + + int carry = 0; + int c = length - 2; + for (; c >= 0; c--) + { + ++allowedCharIndex[c]; + carry = allowedCharIndex[c] / AllowedChars.Length; + allowedCharIndex[c] %= (byte)AllowedChars.Length; + + chars[c] = AllowedChars[allowedCharIndex[c]]; + + if (carry == 0) + break; + } + + // Reached the end + if (carry != 0 && c == 0) + break; + + // Already found all keys + if (FoundKeys.Count != 0) + return; + } + } +} diff --git a/pkNX.Containers/pkNX.Containers.csproj b/pkNX.Containers/pkNX.Containers.csproj index 025142bd..7aceaca5 100644 --- a/pkNX.Containers/pkNX.Containers.csproj +++ b/pkNX.Containers/pkNX.Containers.csproj @@ -11,4 +11,8 @@ + + + + diff --git a/pkNX.HashDecoder/AssemblyInfo.cpp b/pkNX.HashDecoder/AssemblyInfo.cpp new file mode 100644 index 00000000..14e8704f --- /dev/null +++ b/pkNX.HashDecoder/AssemblyInfo.cpp @@ -0,0 +1,20 @@ +#include "pch.h" + +using namespace System; +using namespace System::Reflection; +using namespace System::Runtime::CompilerServices; +using namespace System::Runtime::InteropServices; +using namespace System::Security::Permissions; + +[assembly:AssemblyTitleAttribute(L"pkNXHashDecoder")]; +[assembly:AssemblyDescriptionAttribute(L"")]; +[assembly:AssemblyConfigurationAttribute(L"")]; +[assembly:AssemblyCompanyAttribute(L"")]; +[assembly:AssemblyProductAttribute(L"pkNXHashDecoder")]; +[assembly:AssemblyCopyrightAttribute(L"Copyright (c) 2022")]; +[assembly:AssemblyTrademarkAttribute(L"")]; +[assembly:AssemblyCultureAttribute(L"")]; + +[assembly:AssemblyVersionAttribute(L"1.0.*")]; + +[assembly:ComVisible(false)]; diff --git a/pkNX.HashDecoder/HashDecoderLib.cpp b/pkNX.HashDecoder/HashDecoderLib.cpp new file mode 100644 index 00000000..bb674b71 --- /dev/null +++ b/pkNX.HashDecoder/HashDecoderLib.cpp @@ -0,0 +1,2 @@ +#include "pch.h" +#include "HashDecoderLib.h" diff --git a/pkNX.HashDecoder/HashDecoderLib.h b/pkNX.HashDecoder/HashDecoderLib.h new file mode 100644 index 00000000..4c10074b --- /dev/null +++ b/pkNX.HashDecoder/HashDecoderLib.h @@ -0,0 +1,35 @@ +#pragma once +#include "../pkNX.HashDecoderConsole/HashDecoder.h" + +using namespace System; + +namespace pkNXHashDecoder { + private ref class FnvHashDecoderWrapper + { + public: + std::unordered_map StartDecoding(int length, int startChar) + { + return nativeHandle_->StartDecoding(length, startChar); + } + + private: + FnvHashDecoder* nativeHandle_ = new FnvHashDecoder(); + }; + + public ref class FnvHashDecoderLib + { + public: + static System::Collections::Generic::Dictionary^ StartDecoding(int length, int startChar) + { + FnvHashDecoderWrapper decoder{}; + auto map = decoder.StartDecoding(length, startChar); + + auto dict = gcnew System::Collections::Generic::Dictionary(); + + for (const auto& entry : map) + dict->Add(entry.first, gcnew System::String(entry.second.c_str())); + + return dict; + } + }; +} diff --git a/pkNX.HashDecoder/Resource.h b/pkNX.HashDecoder/Resource.h new file mode 100644 index 00000000..d5ac7c42 --- /dev/null +++ b/pkNX.HashDecoder/Resource.h @@ -0,0 +1,3 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by app.rc diff --git a/pkNX.HashDecoder/app.ico b/pkNX.HashDecoder/app.ico new file mode 100644 index 00000000..789d7ccb Binary files /dev/null and b/pkNX.HashDecoder/app.ico differ diff --git a/pkNX.HashDecoder/app.rc b/pkNX.HashDecoder/app.rc new file mode 100644 index 00000000..eab43064 Binary files /dev/null and b/pkNX.HashDecoder/app.rc differ diff --git a/pkNX.HashDecoder/pch.cpp b/pkNX.HashDecoder/pch.cpp new file mode 100644 index 00000000..64b7eef6 --- /dev/null +++ b/pkNX.HashDecoder/pch.cpp @@ -0,0 +1,5 @@ +// pch.cpp: source file corresponding to the pre-compiled header + +#include "pch.h" + +// When you are using pre-compiled headers, this source file is necessary for compilation to succeed. diff --git a/pkNX.HashDecoder/pch.h b/pkNX.HashDecoder/pch.h new file mode 100644 index 00000000..f6d1c1d6 --- /dev/null +++ b/pkNX.HashDecoder/pch.h @@ -0,0 +1,14 @@ +// pch.h: This is a precompiled header file. +// Files listed below are compiled only once, improving build performance for future builds. +// This also affects IntelliSense performance, including code completion and many code browsing features. +// However, files listed here are ALL re-compiled if any one of them is updated between builds. +// Do not add files here that you will be updating frequently as this negates the performance advantage. + +#ifndef PCH_H +#define PCH_H + +#include +#include +#include + +#endif //PCH_H diff --git a/pkNX.HashDecoder/pkNX.HashDecoder.vcxproj b/pkNX.HashDecoder/pkNX.HashDecoder.vcxproj new file mode 100644 index 00000000..2d42d4b9 --- /dev/null +++ b/pkNX.HashDecoder/pkNX.HashDecoder.vcxproj @@ -0,0 +1,152 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + true + {5483B213-C7A4-4AF6-91E8-5935AAE595E3} + NetCoreCProj + pkNXHashDecoder + 10.0 + net6.0 + + + + DynamicLibrary + true + v143 + NetCore + Unicode + + + DynamicLibrary + false + v143 + NetCore + Unicode + + + DynamicLibrary + true + v143 + NetCore + Unicode + + + DynamicLibrary + false + v143 + NetCore + Unicode + + + + + + + + + + + + + + + + + + + + + + + Use + pch.h + Level3 + _DEBUG;%(PreprocessorDefinitions) + stdcpp17 + + + + + + + + Use + pch.h + Level3 + WIN32;_DEBUG;%(PreprocessorDefinitions) + stdcpp17 + + + + + + + + Use + pch.h + Level3 + WIN32;NDEBUG;%(PreprocessorDefinitions) + stdcpp17 + + + + + + + + Use + pch.h + Level3 + NDEBUG;%(PreprocessorDefinitions) + stdcpp17 + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + \ No newline at end of file diff --git a/pkNX.HashDecoder/pkNX.HashDecoder.vcxproj.filters b/pkNX.HashDecoder/pkNX.HashDecoder.vcxproj.filters new file mode 100644 index 00000000..3070d578 --- /dev/null +++ b/pkNX.HashDecoder/pkNX.HashDecoder.vcxproj.filters @@ -0,0 +1,55 @@ + + + + + {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 + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/pkNX.HashDecoderConsole/HashDecoder.cpp b/pkNX.HashDecoderConsole/HashDecoder.cpp new file mode 100644 index 00000000..40f8d61a --- /dev/null +++ b/pkNX.HashDecoderConsole/HashDecoder.cpp @@ -0,0 +1,100 @@ +#include "pch.h" + +#include "HashDecoder.h" +#include "Timer.h" + +using namespace pkNXHashDecoder; + +std::string FnvHashDecoder::BuildString(const size_t length) const +{ + // Create string from chars + std::vector chars(length); + for (int j = 0; j < length; ++j) + chars[j] = AllowedChars[charIndex[j]]; + + return { chars.begin(), chars.end() }; +} + +std::unordered_map FnvHashDecoder::StartDecoding(const int length, const int startChar) +{ + std::unordered_map foundKeys; + + // Reset all chars to starting point + charIndex[0] = (uint32_t)startChar; + + // Build the hash of all chars except the last one + hashBases[0] = kOffsetBasis_64; + for (int i = 0; i < length - 1; ++i) + { + hashBases[i] ^= AllowedChars[0]; + hashBases[i] *= kFnvPrime_64; + + // Move the hash to the next index as basis + hashBases[i + 1] = hashBases[i]; + } + + //LoopTimer timer{}; + while (charIndex[0] == startChar) + { + // Loop through all AllowedChars + const uint64_t hashBase = hashBases[length - 1]; + for (int i = 0; i < AllowedCharsCount; ++i) + { + uint64_t hash = hashBase; + hash ^= AllowedChars[i]; + hash *= kFnvPrime_64; + + if (hash == 9252365659083253459ul) + { + charIndex[length - 1] = i; + foundKeys.emplace(hash, BuildString(length)); + } + } + + // Already found all keys + if (!foundKeys.empty()) + return foundKeys; + + bool carry = false; + int c = length - 2; + for (; c >= 0; c--) + { + ++charIndex[c]; + carry = charIndex[c] >= AllowedCharsCount; + + if (!carry) + break; + + charIndex[c] = 0; + } + + // Reached the end + if (carry && c == 0) + break; + + // Rebuild the hash basis + hashBases[c] = hashBases[c - 1]; + for (int i = c; i < length - 1; ++i) + { + hashBases[i] ^= AllowedChars[charIndex[i]]; + hashBases[i] *= kFnvPrime_64; + + // Move the hash to the next index as basis + hashBases[i + 1] = hashBases[i]; + + // Automatically test for shorter length strings + if (hashBases[i] == 9252365659083253459ul) + { + foundKeys.emplace(hashBases[i], BuildString(i)); + } + } + + /*if (c < length - 4) + timer.Loop(); + + if (c < length - 6) + timer.Print();*/ + } + + return foundKeys; +} diff --git a/pkNX.HashDecoderConsole/HashDecoder.h b/pkNX.HashDecoderConsole/HashDecoder.h new file mode 100644 index 00000000..29f17f74 --- /dev/null +++ b/pkNX.HashDecoderConsole/HashDecoder.h @@ -0,0 +1,23 @@ +#pragma once +#include "pch.h" + +namespace pkNXHashDecoder { + class __declspec(align(64)) FnvHashDecoder + { + public: + std::unordered_map StartDecoding(int length, int startChar); + + private: + constexpr static int MAX_LENGTH = 128; + constexpr static std::string_view AllowedChars = "etaoinshrdlcumw_0123456789fgypbvkjxqz/."; // Sorted by most common first + constexpr static size_t AllowedCharsCount = AllowedChars.size(); + + constexpr static uint64_t kFnvPrime_64 = 0x00000100000001b3; + constexpr static uint64_t kOffsetBasis_64 = 0xCBF29CE484222645; + + std::array charIndex{}; // Current AllowedChar index + std::array hashBases{}; // Current AllowedChar index + + std::string BuildString(size_t length) const; + }; +} diff --git a/pkNX.HashDecoderConsole/Timer.cpp b/pkNX.HashDecoderConsole/Timer.cpp new file mode 100644 index 00000000..e71f542e --- /dev/null +++ b/pkNX.HashDecoderConsole/Timer.cpp @@ -0,0 +1,2 @@ +#include "pch.h" +#include "Timer.h" diff --git a/pkNX.HashDecoderConsole/Timer.h b/pkNX.HashDecoderConsole/Timer.h new file mode 100644 index 00000000..e34b8dfe --- /dev/null +++ b/pkNX.HashDecoderConsole/Timer.h @@ -0,0 +1,83 @@ +#pragma once +#include "pch.h" +#include +#include + +namespace pkNXHashDecoder { + + class Timer { + public: + /// Construct a new timer + Timer() { + Reset(); + } + + /// Resets the timer to now + void Reset() { + start_ = Clock::now(); + } + + auto Elapsed() const { + return FMicro(Clock::now() - start_).count(); + } + + auto ElapsedMillis() const { + return FMili(Clock::now() - start_).count(); + } + + private: + using Clock = std::chrono::high_resolution_clock; + using FMicro = std::chrono::duration; + using FMili = std::chrono::duration; + + Clock::time_point start_; + }; + + class LoopTimer : Timer { + public: + LoopTimer() = default; + + /// Resets the timer to now + void Reset() { + loops = 0; + } + + auto ElapsedAverage() const { + return Elapsed() / static_cast(loops); + } + + auto ElapsedAverageMillis() const { + return totalTime / static_cast(loops); + } + + void Loop() { + totalTime += ElapsedMillis(); + ++loops; + Timer::Reset(); + } + + void Print() + { + std::cout << "[Timer]: " << loops << " loops, " << ElapsedAverageMillis() << "ms avg.\n"; + } + + private: + int loops = 0; + float totalTime = 0.0f; + }; + + class ScopedTimer { + public: + ScopedTimer(const std::string_view& name) + : _name(name) { + } + + ~ScopedTimer() { + std::cout << "[Timer]: " << _name << " - " << _timer.ElapsedMillis() << "ms"; + } + + private: + std::string _name; + Timer _timer; + }; +} // namespace pix::foundation diff --git a/pkNX.HashDecoderConsole/pch.cpp b/pkNX.HashDecoderConsole/pch.cpp new file mode 100644 index 00000000..64b7eef6 --- /dev/null +++ b/pkNX.HashDecoderConsole/pch.cpp @@ -0,0 +1,5 @@ +// pch.cpp: source file corresponding to the pre-compiled header + +#include "pch.h" + +// When you are using pre-compiled headers, this source file is necessary for compilation to succeed. diff --git a/pkNX.HashDecoderConsole/pch.h b/pkNX.HashDecoderConsole/pch.h new file mode 100644 index 00000000..f6d1c1d6 --- /dev/null +++ b/pkNX.HashDecoderConsole/pch.h @@ -0,0 +1,14 @@ +// pch.h: This is a precompiled header file. +// Files listed below are compiled only once, improving build performance for future builds. +// This also affects IntelliSense performance, including code completion and many code browsing features. +// However, files listed here are ALL re-compiled if any one of them is updated between builds. +// Do not add files here that you will be updating frequently as this negates the performance advantage. + +#ifndef PCH_H +#define PCH_H + +#include +#include +#include + +#endif //PCH_H diff --git a/pkNX.HashDecoderConsole/pkNX.HashDecoderConsole.cpp b/pkNX.HashDecoderConsole/pkNX.HashDecoderConsole.cpp new file mode 100644 index 00000000..cf4b3e7c --- /dev/null +++ b/pkNX.HashDecoderConsole/pkNX.HashDecoderConsole.cpp @@ -0,0 +1,24 @@ +// pkNX.HashDecoderConsole.cpp : This file contains the 'main' function. Program execution begins and ends there. +// +#include "pch.h" +#include +#include "HashDecoder.h" + +int main() +{ + pkNXHashDecoder::FnvHashDecoder decoder{}; + auto map = decoder.StartDecoding(10, 0); + + std::cout << "Hello World!\n"; +} + +// Run program: Ctrl + F5 or Debug > Start Without Debugging menu +// Debug program: F5 or Debug > Start Debugging menu + +// Tips for Getting Started: +// 1. Use the Solution Explorer window to add/manage files +// 2. Use the Team Explorer window to connect to source control +// 3. Use the Output window to see build output and other messages +// 4. Use the Error List window to view errors +// 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project +// 6. In the future, to open this project again, go to File > Open > Project and select the .sln file diff --git a/pkNX.HashDecoderConsole/pkNX.HashDecoderConsole.vcxproj b/pkNX.HashDecoderConsole/pkNX.HashDecoderConsole.vcxproj new file mode 100644 index 00000000..5ef3a9e0 --- /dev/null +++ b/pkNX.HashDecoderConsole/pkNX.HashDecoderConsole.vcxproj @@ -0,0 +1,168 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {8bba9d0d-6fa3-48bc-a6e7-2e26eb14c3f0} + pkNXHashDecoderConsole + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp17 + %(AdditionalIncludeDirectories) + Use + pch.h + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp17 + %(AdditionalIncludeDirectories) + Use + pch.h + Speed + AdvancedVectorExtensions2 + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp17 + %(AdditionalIncludeDirectories) + Use + pch.h + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp17 + %(AdditionalIncludeDirectories) + Use + pch.h + Speed + AdvancedVectorExtensions2 + + + Console + true + true + true + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + \ No newline at end of file diff --git a/pkNX.HashDecoderConsole/pkNX.HashDecoderConsole.vcxproj.filters b/pkNX.HashDecoderConsole/pkNX.HashDecoderConsole.vcxproj.filters new file mode 100644 index 00000000..ae01fd07 --- /dev/null +++ b/pkNX.HashDecoderConsole/pkNX.HashDecoderConsole.vcxproj.filters @@ -0,0 +1,42 @@ + + + + + {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 + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/pkNX.WinForms/MainEditor/EditorPLA.cs b/pkNX.WinForms/MainEditor/EditorPLA.cs index 7f604759..c3beda34 100644 --- a/pkNX.WinForms/MainEditor/EditorPLA.cs +++ b/pkNX.WinForms/MainEditor/EditorPLA.cs @@ -684,6 +684,13 @@ public void EditPokedexFormStorage() [EditorCallable(EditorCategory.Misc)] public void EditEventRestrictionBattle() => PopFlatConfig(GameFile.EventRestrictionBattle, "Event Restriction Battle Editor"); [EditorCallable(EditorCategory.Misc)] public void EditEventWork() => PopFlatConfig(GameFile.EventWork, "Event Work Editor"); + [EditorCallable(EditorCategory.Misc)] + public void RunHashDecoder() + { + FnvHashDecoder decoder = new(); + WinFormsUtil.Alert(decoder.Run(0, 10).Select(x => $"0x{x.Key:X} {x.Value}").ToArray()); + } + public void EditMasterDump() { using var md = new DumperPLA(ROM); diff --git a/pkNX.WinForms/pkNX.WinForms.csproj b/pkNX.WinForms/pkNX.WinForms.csproj index 9058a4c6..cc971dad 100644 --- a/pkNX.WinForms/pkNX.WinForms.csproj +++ b/pkNX.WinForms/pkNX.WinForms.csproj @@ -14,6 +14,7 @@ pkNX 10 enable + AnyCPU;x64 diff --git a/pkNX.sln b/pkNX.sln index 3115f5da..392f650a 100644 --- a/pkNX.sln +++ b/pkNX.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31605.320 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32901.215 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "pkNX.Randomization", "pkNX.Randomization\pkNX.Randomization.csproj", "{77E3FEBB-9C86-4F8D-B4E0-66B7504080D5}" ProjectSection(ProjectDependencies) = postProject @@ -26,46 +26,142 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "pkNX.Game", "pkNX.Game\pkNX EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "pkNX.Sprites", "pkNX.Sprites\pkNX.Sprites.csproj", "{55D82546-3DDA-42E1-9A24-F6A08EE231B0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "pkNX.Structures.FlatBuffers", "pkNX.Structures.FlatBuffers\pkNX.Structures.FlatBuffers.csproj", "{83E23C09-6DB8-459C-B68B-08FE4EAAC86C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "pkNX.Structures.FlatBuffers", "pkNX.Structures.FlatBuffers\pkNX.Structures.FlatBuffers.csproj", "{83E23C09-6DB8-459C-B68B-08FE4EAAC86C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pkNX.HashDecoder", "pkNX.HashDecoder\pkNX.HashDecoder.vcxproj", "{5483B213-C7A4-4AF6-91E8-5935AAE595E3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pkNX.HashDecoderConsole", "pkNX.HashDecoderConsole\pkNX.HashDecoderConsole.vcxproj", "{8BBA9D0D-6FA3-48BC-A6E7-2E26EB14C3F0}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {77E3FEBB-9C86-4F8D-B4E0-66B7504080D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {77E3FEBB-9C86-4F8D-B4E0-66B7504080D5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {77E3FEBB-9C86-4F8D-B4E0-66B7504080D5}.Debug|x64.ActiveCfg = Debug|Any CPU + {77E3FEBB-9C86-4F8D-B4E0-66B7504080D5}.Debug|x64.Build.0 = Debug|Any CPU + {77E3FEBB-9C86-4F8D-B4E0-66B7504080D5}.Debug|x86.ActiveCfg = Debug|Any CPU + {77E3FEBB-9C86-4F8D-B4E0-66B7504080D5}.Debug|x86.Build.0 = Debug|Any CPU {77E3FEBB-9C86-4F8D-B4E0-66B7504080D5}.Release|Any CPU.ActiveCfg = Release|Any CPU {77E3FEBB-9C86-4F8D-B4E0-66B7504080D5}.Release|Any CPU.Build.0 = Release|Any CPU + {77E3FEBB-9C86-4F8D-B4E0-66B7504080D5}.Release|x64.ActiveCfg = Release|Any CPU + {77E3FEBB-9C86-4F8D-B4E0-66B7504080D5}.Release|x64.Build.0 = Release|Any CPU + {77E3FEBB-9C86-4F8D-B4E0-66B7504080D5}.Release|x86.ActiveCfg = Release|Any CPU + {77E3FEBB-9C86-4F8D-B4E0-66B7504080D5}.Release|x86.Build.0 = Release|Any CPU {01447516-8382-4E9B-8B6C-92FF0A2D0CBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {01447516-8382-4E9B-8B6C-92FF0A2D0CBF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {01447516-8382-4E9B-8B6C-92FF0A2D0CBF}.Debug|x64.ActiveCfg = Debug|Any CPU + {01447516-8382-4E9B-8B6C-92FF0A2D0CBF}.Debug|x64.Build.0 = Debug|Any CPU + {01447516-8382-4E9B-8B6C-92FF0A2D0CBF}.Debug|x86.ActiveCfg = Debug|Any CPU + {01447516-8382-4E9B-8B6C-92FF0A2D0CBF}.Debug|x86.Build.0 = Debug|Any CPU {01447516-8382-4E9B-8B6C-92FF0A2D0CBF}.Release|Any CPU.ActiveCfg = Release|Any CPU {01447516-8382-4E9B-8B6C-92FF0A2D0CBF}.Release|Any CPU.Build.0 = Release|Any CPU + {01447516-8382-4E9B-8B6C-92FF0A2D0CBF}.Release|x64.ActiveCfg = Release|Any CPU + {01447516-8382-4E9B-8B6C-92FF0A2D0CBF}.Release|x64.Build.0 = Release|Any CPU + {01447516-8382-4E9B-8B6C-92FF0A2D0CBF}.Release|x86.ActiveCfg = Release|Any CPU + {01447516-8382-4E9B-8B6C-92FF0A2D0CBF}.Release|x86.Build.0 = Release|Any CPU {2A909229-C9C0-42CE-88E0-72D9AF84AFE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2A909229-C9C0-42CE-88E0-72D9AF84AFE3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2A909229-C9C0-42CE-88E0-72D9AF84AFE3}.Debug|x64.ActiveCfg = Debug|Any CPU + {2A909229-C9C0-42CE-88E0-72D9AF84AFE3}.Debug|x64.Build.0 = Debug|Any CPU + {2A909229-C9C0-42CE-88E0-72D9AF84AFE3}.Debug|x86.ActiveCfg = Debug|Any CPU + {2A909229-C9C0-42CE-88E0-72D9AF84AFE3}.Debug|x86.Build.0 = Debug|Any CPU {2A909229-C9C0-42CE-88E0-72D9AF84AFE3}.Release|Any CPU.ActiveCfg = Release|Any CPU {2A909229-C9C0-42CE-88E0-72D9AF84AFE3}.Release|Any CPU.Build.0 = Release|Any CPU + {2A909229-C9C0-42CE-88E0-72D9AF84AFE3}.Release|x64.ActiveCfg = Release|Any CPU + {2A909229-C9C0-42CE-88E0-72D9AF84AFE3}.Release|x64.Build.0 = Release|Any CPU + {2A909229-C9C0-42CE-88E0-72D9AF84AFE3}.Release|x86.ActiveCfg = Release|Any CPU + {2A909229-C9C0-42CE-88E0-72D9AF84AFE3}.Release|x86.Build.0 = Release|Any CPU {3CF3FA3E-B38E-4774-BA77-924A391DDC9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3CF3FA3E-B38E-4774-BA77-924A391DDC9D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3CF3FA3E-B38E-4774-BA77-924A391DDC9D}.Debug|x64.ActiveCfg = Debug|x64 + {3CF3FA3E-B38E-4774-BA77-924A391DDC9D}.Debug|x64.Build.0 = Debug|x64 + {3CF3FA3E-B38E-4774-BA77-924A391DDC9D}.Debug|x86.ActiveCfg = Debug|Any CPU + {3CF3FA3E-B38E-4774-BA77-924A391DDC9D}.Debug|x86.Build.0 = Debug|Any CPU {3CF3FA3E-B38E-4774-BA77-924A391DDC9D}.Release|Any CPU.ActiveCfg = Release|Any CPU {3CF3FA3E-B38E-4774-BA77-924A391DDC9D}.Release|Any CPU.Build.0 = Release|Any CPU + {3CF3FA3E-B38E-4774-BA77-924A391DDC9D}.Release|x64.ActiveCfg = Release|x64 + {3CF3FA3E-B38E-4774-BA77-924A391DDC9D}.Release|x64.Build.0 = Release|x64 + {3CF3FA3E-B38E-4774-BA77-924A391DDC9D}.Release|x86.ActiveCfg = Release|Any CPU + {3CF3FA3E-B38E-4774-BA77-924A391DDC9D}.Release|x86.Build.0 = Release|Any CPU {6CF919B7-BA0F-4A04-899B-6C8CAB343B86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6CF919B7-BA0F-4A04-899B-6C8CAB343B86}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6CF919B7-BA0F-4A04-899B-6C8CAB343B86}.Debug|x64.ActiveCfg = Debug|Any CPU + {6CF919B7-BA0F-4A04-899B-6C8CAB343B86}.Debug|x64.Build.0 = Debug|Any CPU + {6CF919B7-BA0F-4A04-899B-6C8CAB343B86}.Debug|x86.ActiveCfg = Debug|Any CPU + {6CF919B7-BA0F-4A04-899B-6C8CAB343B86}.Debug|x86.Build.0 = Debug|Any CPU {6CF919B7-BA0F-4A04-899B-6C8CAB343B86}.Release|Any CPU.ActiveCfg = Release|Any CPU {6CF919B7-BA0F-4A04-899B-6C8CAB343B86}.Release|Any CPU.Build.0 = Release|Any CPU + {6CF919B7-BA0F-4A04-899B-6C8CAB343B86}.Release|x64.ActiveCfg = Release|Any CPU + {6CF919B7-BA0F-4A04-899B-6C8CAB343B86}.Release|x64.Build.0 = Release|Any CPU + {6CF919B7-BA0F-4A04-899B-6C8CAB343B86}.Release|x86.ActiveCfg = Release|Any CPU + {6CF919B7-BA0F-4A04-899B-6C8CAB343B86}.Release|x86.Build.0 = Release|Any CPU {3C4AF1ED-7C81-4AF8-A6DB-1D397650DA0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3C4AF1ED-7C81-4AF8-A6DB-1D397650DA0A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3C4AF1ED-7C81-4AF8-A6DB-1D397650DA0A}.Debug|x64.ActiveCfg = Debug|Any CPU + {3C4AF1ED-7C81-4AF8-A6DB-1D397650DA0A}.Debug|x64.Build.0 = Debug|Any CPU + {3C4AF1ED-7C81-4AF8-A6DB-1D397650DA0A}.Debug|x86.ActiveCfg = Debug|Any CPU + {3C4AF1ED-7C81-4AF8-A6DB-1D397650DA0A}.Debug|x86.Build.0 = Debug|Any CPU {3C4AF1ED-7C81-4AF8-A6DB-1D397650DA0A}.Release|Any CPU.ActiveCfg = Release|Any CPU {3C4AF1ED-7C81-4AF8-A6DB-1D397650DA0A}.Release|Any CPU.Build.0 = Release|Any CPU + {3C4AF1ED-7C81-4AF8-A6DB-1D397650DA0A}.Release|x64.ActiveCfg = Release|Any CPU + {3C4AF1ED-7C81-4AF8-A6DB-1D397650DA0A}.Release|x64.Build.0 = Release|Any CPU + {3C4AF1ED-7C81-4AF8-A6DB-1D397650DA0A}.Release|x86.ActiveCfg = Release|Any CPU + {3C4AF1ED-7C81-4AF8-A6DB-1D397650DA0A}.Release|x86.Build.0 = Release|Any CPU {55D82546-3DDA-42E1-9A24-F6A08EE231B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {55D82546-3DDA-42E1-9A24-F6A08EE231B0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {55D82546-3DDA-42E1-9A24-F6A08EE231B0}.Debug|x64.ActiveCfg = Debug|Any CPU + {55D82546-3DDA-42E1-9A24-F6A08EE231B0}.Debug|x64.Build.0 = Debug|Any CPU + {55D82546-3DDA-42E1-9A24-F6A08EE231B0}.Debug|x86.ActiveCfg = Debug|Any CPU + {55D82546-3DDA-42E1-9A24-F6A08EE231B0}.Debug|x86.Build.0 = Debug|Any CPU {55D82546-3DDA-42E1-9A24-F6A08EE231B0}.Release|Any CPU.ActiveCfg = Release|Any CPU {55D82546-3DDA-42E1-9A24-F6A08EE231B0}.Release|Any CPU.Build.0 = Release|Any CPU + {55D82546-3DDA-42E1-9A24-F6A08EE231B0}.Release|x64.ActiveCfg = Release|Any CPU + {55D82546-3DDA-42E1-9A24-F6A08EE231B0}.Release|x64.Build.0 = Release|Any CPU + {55D82546-3DDA-42E1-9A24-F6A08EE231B0}.Release|x86.ActiveCfg = Release|Any CPU + {55D82546-3DDA-42E1-9A24-F6A08EE231B0}.Release|x86.Build.0 = Release|Any CPU {83E23C09-6DB8-459C-B68B-08FE4EAAC86C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {83E23C09-6DB8-459C-B68B-08FE4EAAC86C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {83E23C09-6DB8-459C-B68B-08FE4EAAC86C}.Debug|x64.ActiveCfg = Debug|Any CPU + {83E23C09-6DB8-459C-B68B-08FE4EAAC86C}.Debug|x64.Build.0 = Debug|Any CPU + {83E23C09-6DB8-459C-B68B-08FE4EAAC86C}.Debug|x86.ActiveCfg = Debug|Any CPU + {83E23C09-6DB8-459C-B68B-08FE4EAAC86C}.Debug|x86.Build.0 = Debug|Any CPU {83E23C09-6DB8-459C-B68B-08FE4EAAC86C}.Release|Any CPU.ActiveCfg = Release|Any CPU {83E23C09-6DB8-459C-B68B-08FE4EAAC86C}.Release|Any CPU.Build.0 = Release|Any CPU + {83E23C09-6DB8-459C-B68B-08FE4EAAC86C}.Release|x64.ActiveCfg = Release|Any CPU + {83E23C09-6DB8-459C-B68B-08FE4EAAC86C}.Release|x64.Build.0 = Release|Any CPU + {83E23C09-6DB8-459C-B68B-08FE4EAAC86C}.Release|x86.ActiveCfg = Release|Any CPU + {83E23C09-6DB8-459C-B68B-08FE4EAAC86C}.Release|x86.Build.0 = Release|Any CPU + {5483B213-C7A4-4AF6-91E8-5935AAE595E3}.Debug|Any CPU.ActiveCfg = Debug|x64 + {5483B213-C7A4-4AF6-91E8-5935AAE595E3}.Debug|Any CPU.Build.0 = Debug|x64 + {5483B213-C7A4-4AF6-91E8-5935AAE595E3}.Debug|x64.ActiveCfg = Debug|x64 + {5483B213-C7A4-4AF6-91E8-5935AAE595E3}.Debug|x64.Build.0 = Debug|x64 + {5483B213-C7A4-4AF6-91E8-5935AAE595E3}.Debug|x86.ActiveCfg = Debug|Win32 + {5483B213-C7A4-4AF6-91E8-5935AAE595E3}.Debug|x86.Build.0 = Debug|Win32 + {5483B213-C7A4-4AF6-91E8-5935AAE595E3}.Release|Any CPU.ActiveCfg = Release|x64 + {5483B213-C7A4-4AF6-91E8-5935AAE595E3}.Release|Any CPU.Build.0 = Release|x64 + {5483B213-C7A4-4AF6-91E8-5935AAE595E3}.Release|x64.ActiveCfg = Release|x64 + {5483B213-C7A4-4AF6-91E8-5935AAE595E3}.Release|x64.Build.0 = Release|x64 + {5483B213-C7A4-4AF6-91E8-5935AAE595E3}.Release|x86.ActiveCfg = Release|Win32 + {5483B213-C7A4-4AF6-91E8-5935AAE595E3}.Release|x86.Build.0 = Release|Win32 + {8BBA9D0D-6FA3-48BC-A6E7-2E26EB14C3F0}.Debug|Any CPU.ActiveCfg = Debug|x64 + {8BBA9D0D-6FA3-48BC-A6E7-2E26EB14C3F0}.Debug|Any CPU.Build.0 = Debug|x64 + {8BBA9D0D-6FA3-48BC-A6E7-2E26EB14C3F0}.Debug|x64.ActiveCfg = Debug|x64 + {8BBA9D0D-6FA3-48BC-A6E7-2E26EB14C3F0}.Debug|x64.Build.0 = Debug|x64 + {8BBA9D0D-6FA3-48BC-A6E7-2E26EB14C3F0}.Debug|x86.ActiveCfg = Debug|Win32 + {8BBA9D0D-6FA3-48BC-A6E7-2E26EB14C3F0}.Debug|x86.Build.0 = Debug|Win32 + {8BBA9D0D-6FA3-48BC-A6E7-2E26EB14C3F0}.Release|Any CPU.ActiveCfg = Release|x64 + {8BBA9D0D-6FA3-48BC-A6E7-2E26EB14C3F0}.Release|Any CPU.Build.0 = Release|x64 + {8BBA9D0D-6FA3-48BC-A6E7-2E26EB14C3F0}.Release|x64.ActiveCfg = Release|x64 + {8BBA9D0D-6FA3-48BC-A6E7-2E26EB14C3F0}.Release|x64.Build.0 = Release|x64 + {8BBA9D0D-6FA3-48BC-A6E7-2E26EB14C3F0}.Release|x86.ActiveCfg = Release|Win32 + {8BBA9D0D-6FA3-48BC-A6E7-2E26EB14C3F0}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE