From 6ec3f9e5f3476387caa485f0fe2b05bf7a68a6c3 Mon Sep 17 00:00:00 2001 From: guttir14 Date: Sat, 7 Aug 2021 09:13:24 +0300 Subject: [PATCH] Update readme, remove map of types, add exception handler for Decrypt_ANSI --- Dumper/Dumper.vcxproj | 3 +- Dumper/defs.h | 13 +- Dumper/engine.cpp | 209 ++++++-------------------- Dumper/generic.cpp | 4 +- Dumper/wrappers.cpp | 339 +++++++++++++++++------------------------- README.md | 6 +- include/hash/hash.h | 23 +++ include/types.h | 9 ++ 8 files changed, 228 insertions(+), 378 deletions(-) create mode 100644 include/hash/hash.h create mode 100644 include/types.h diff --git a/Dumper/Dumper.vcxproj b/Dumper/Dumper.vcxproj index 2342c8b..11acf15 100644 --- a/Dumper/Dumper.vcxproj +++ b/Dumper/Dumper.vcxproj @@ -67,6 +67,7 @@ stdcpplatest FastCall true + Async Console @@ -87,7 +88,7 @@ FastCall ProgramDatabase false - Sync + Async AnySuitable true Default diff --git a/Dumper/defs.h b/Dumper/defs.h index 93b1538..bf8eaa3 100644 --- a/Dumper/defs.h +++ b/Dumper/defs.h @@ -1,4 +1,5 @@ #pragma once +#include #ifdef GetObject #undef GetObject @@ -18,14 +19,4 @@ enum class STATUS { INVALID_IMAGE, FILE_NOT_OPEN, ZERO_PACKAGES -}; - -typedef signed char int8; -typedef short int16; -typedef int int32; -typedef long long int64; - -typedef unsigned char uint8; -typedef unsigned short uint16; -typedef unsigned int uint32; -typedef unsigned long long uint64; +}; \ No newline at end of file diff --git a/Dumper/engine.cpp b/Dumper/engine.cpp index 6f6c96b..5d00cd5 100644 --- a/Dumper/engine.cpp +++ b/Dumper/engine.cpp @@ -10,64 +10,6 @@ Offsets offsets; ansi_fn Decrypt_ANSI = nullptr; // wide_fn Decrypt_WIDE = nullptr; -struct { - uint16 Stride = 4; - struct { - uint16 Size = 24; - } FUObjectItem; - struct { - uint16 Number = 8; - } FName; - struct { - uint16 Info = 4; - uint16 WideBit = 0; - uint16 LenBit = 1; - uint16 HeaderSize = 6; - } FNameEntry; - struct { - uint16 Index = 0xC; - uint16 Class = 0x10; - uint16 Name = 0x18; - uint16 Outer = 0x28; - } UObject; - struct { - uint16 Next = 0x30; - } UField; - struct { - uint16 SuperStruct = 0x48; - uint16 Children = 0x50; - uint16 ChildProperties = 0x58; - uint16 PropertiesSize = 0x60; - } UStruct; - struct { - uint16 Names = 0x48; - } UEnum; - struct { - uint16 FunctionFlags = 0xB8; - uint16 Func = 0xB8 + 0x28; // ue3-ue4, always +0x28 from flags location. - } UFunction; - struct { - uint16 Class = 0x8; - uint16 Next = 0x20; - uint16 Name = 0x28; - } FField; - struct { - uint16 ArrayDim = 0x38; - uint16 ElementSize = 0x3C; - uint16 PropertyFlags = 0x40; - uint16 Offset = 0x4C; - uint16 Size = 0x80; - } FProperty; - struct { - uint16 ArrayDim = 0; - uint16 ElementSize = 0; - uint16 PropertyFlags = 0; - uint16 Offset = 0; - uint16 Size = 0; // sizeof(UProperty) - } UProperty; -} DeadByDaylight; -static_assert(sizeof(DeadByDaylight) == sizeof(Offsets)); - struct { uint16 Stride = 2; struct { @@ -123,44 +65,44 @@ struct { uint16 Offset = 0; uint16 Size = 0; // sizeof(UProperty) } UProperty; -} RogueCompany; -static_assert(sizeof(RogueCompany) == sizeof(Offsets)); +} Default; +static_assert(sizeof(Default) == sizeof(Offsets)); struct { - uint16 Stride = 2; + uint16 Stride = 4; struct { uint16 Size = 24; } FUObjectItem; struct { - uint16 Number = 4; + uint16 Number = 8; } FName; struct { - uint16 Info = 0; + uint16 Info = 4; uint16 WideBit = 0; - uint16 LenBit = 6; - uint16 HeaderSize = 2; + uint16 LenBit = 1; + uint16 HeaderSize = 6; } FNameEntry; struct { uint16 Index = 0xC; uint16 Class = 0x10; uint16 Name = 0x18; - uint16 Outer = 0x20; + uint16 Outer = 0x28; } UObject; struct { - uint16 Next = 0x28; + uint16 Next = 0x30; } UField; struct { - uint16 SuperStruct = 0x40; - uint16 Children = 0x48; - uint16 ChildProperties = 0x50; - uint16 PropertiesSize = 0x58; + uint16 SuperStruct = 0x48; + uint16 Children = 0x50; + uint16 ChildProperties = 0x58; + uint16 PropertiesSize = 0x60; } UStruct; struct { - uint16 Names = 0x40; + uint16 Names = 0x48; } UEnum; struct { - uint16 FunctionFlags = 0xB0; - uint16 Func = 0xB0 + 0x30; + uint16 FunctionFlags = 0xB8; + uint16 Func = 0xB8 + 0x28; // ue3-ue4, always +0x28 from flags location. } UFunction; struct { uint16 Class = 0x8; @@ -172,7 +114,7 @@ struct { uint16 ElementSize = 0x3C; uint16 PropertyFlags = 0x40; uint16 Offset = 0x4C; - uint16 Size = 0x78; + uint16 Size = 0x80; } FProperty; struct { uint16 ArrayDim = 0; @@ -181,13 +123,13 @@ struct { uint16 Offset = 0; uint16 Size = 0; // sizeof(UProperty) } UProperty; -} Scavengers; -static_assert(sizeof(Scavengers) == sizeof(Offsets)); +} DeadByDaylight; +static_assert(sizeof(DeadByDaylight) == sizeof(Offsets)); struct { uint16 Stride = 2; struct { - uint16 Size = 32; + uint16 Size = 24; } FUObjectItem; struct { uint16 Number = 4; @@ -218,7 +160,7 @@ struct { } UEnum; struct { uint16 FunctionFlags = 0xB0; - uint16 Func = 0xB0 + 0x28; + uint16 Func = 0xB0 + 0x30; } UFunction; struct { uint16 Class = 0x8; @@ -239,13 +181,13 @@ struct { uint16 Offset = 0; uint16 Size = 0; // sizeof(UProperty) } UProperty; -} Brickadia; -static_assert(sizeof(Brickadia) == sizeof(Offsets)); +} Scavengers; +static_assert(sizeof(Scavengers) == sizeof(Offsets)); struct { uint16 Stride = 2; struct { - uint16 Size = 24; + uint16 Size = 32; } FUObjectItem; struct { uint16 Number = 4; @@ -297,67 +239,8 @@ struct { uint16 Offset = 0; uint16 Size = 0; // sizeof(UProperty) } UProperty; -} Fortnite; -static_assert(sizeof(Fortnite) == sizeof(Offsets)); - - -struct { - uint16 Stride = 2; - struct { - uint16 Size = 24; - } FUObjectItem; - struct { - uint16 Number = 4; - } FName; - struct { - uint16 Info = 0; - uint16 WideBit = 0; - uint16 LenBit = 6; - uint16 HeaderSize = 2; - } FNameEntry; - struct { - uint16 Index = 0xC; - uint16 Class = 0x10; - uint16 Name = 0x18; - uint16 Outer = 0x20; - } UObject; - struct { - uint16 Next = 0x28; - } UField; - struct { - uint16 SuperStruct = 0x40; - uint16 Children = 0x48; - uint16 ChildProperties = 0x50; - uint16 PropertiesSize = 0x58; - } UStruct; - struct { - uint16 Names = 0x40; - } UEnum; - struct { - uint16 FunctionFlags = 0xB0; - uint16 Func = 0xB0 + 0x28; - } UFunction; - struct { - uint16 Class = 0x8; - uint16 Next = 0x20; - uint16 Name = 0x28; - } FField; - struct { - uint16 ArrayDim = 0x38; - uint16 ElementSize = 0x3C; - uint16 PropertyFlags = 0x40; - uint16 Offset = 0x4C; - uint16 Size = 0x78; - } FProperty; - struct { - uint16 ArrayDim = 0; - uint16 ElementSize = 0; - uint16 PropertyFlags = 0; - uint16 Offset = 0; - uint16 Size = 0; // sizeof(UProperty) - } UProperty; -} TheIsle; -static_assert(sizeof(TheIsle) == sizeof(Offsets)); +} Brickadia; +static_assert(sizeof(Brickadia) == sizeof(Offsets)); struct { void* offsets; // address to filled offsets structure @@ -366,7 +249,7 @@ struct { std::function*)> callback; } engines[] = { { // RogueCompany | PropWitchHuntModule-Win64-Shipping | Scum - &RogueCompany, + &Default, {"\x48\x8D\x0D\x00\x00\x00\x00\xE8\x00\x00\x00\x00\xC6\x05\x00\x00\x00\x00\x01\x0F\x10\x03\x4C\x8D\x44\x24\x20\x48\x8B\xC8", 30}, {"\x48\x8B\x05\x00\x00\x00\x00\x48\x8B\x0C\xC8\x48\x8D\x04\xD1\xEB", 16}, nullptr @@ -390,13 +273,13 @@ struct { nullptr }, { // POLYGON-Win64-Shipping - &RogueCompany, + &Default, {"\x48\x8D\x35\x00\x00\x00\x00\xEB\x16", 9}, {"\x48\x8d\x1d\x00\x00\x00\x00\x39\x44\x24\x68", 11}, nullptr }, { // FortniteClient-Win64-Shipping - &Fortnite, + &Default, {"\x4C\x8D\x35\x00\x00\x00\x00\x0F\x10\x07\x83\xFB\x01", 13}, {"\x48\x8B\x05\x00\x00\x00\x00\x48\x8B\x0C\xC8\x48\x8D\x04\xD1\xEB", 16}, [](std::pair* s) { @@ -424,9 +307,8 @@ struct { return false; } }, - { - // TheIsleClient-Win64-Shipping - &TheIsle, + { // TheIsleClient-Win64-Shipping + &Default, {"\x48\x8D\x05\x00\x00\x00\x00\xEB\x13", 9}, {"\x48\x8B\x05\x00\x00\x00\x00\x48\x8B\x0C\xC8\x48\x8D\x04\xD1\xEB\x03", 17}, nullptr @@ -434,16 +316,16 @@ struct { }; std::unordered_map games = { - {"RogueCompany", &engines[0]}, - {"SCUM", &engines[0]}, - {"PropWitchHuntModule-Win64-Shipping", &engines[0]}, - {"HLL-Win64-Shipping", &engines[0]}, - {"Scavenger-Win64-Shipping", &engines[1]}, - {"DeadByDaylight-Win64-Shipping", &engines[2]}, - {"Brickadia-Win64-Shipping", &engines[3]}, - {"POLYGON-Win64-Shipping", &engines[4]}, - {"FortniteClient-Win64-Shipping", &engines[5]}, - {"TheIsleClient-Win64-Shipping", &engines[6]} + {"RogueCompany", &engines[0]}, + {"SCUM", &engines[0]}, + {"PropWitchHuntModule-Win64-Shipping", &engines[0]}, + {"HLL-Win64-Shipping", &engines[0]}, + {"Scavenger-Win64-Shipping", &engines[1]}, + {"DeadByDaylight-Win64-Shipping", &engines[2]}, + {"Brickadia-Win64-Shipping", &engines[3]}, + {"POLYGON-Win64-Shipping", &engines[4]}, + {"FortniteClient-Win64-Shipping", &engines[5]}, + {"TheIsleClient-Win64-Shipping", &engines[6]} }; STATUS EngineInit(std::string game, void* image) { @@ -478,7 +360,14 @@ STATUS EngineInit(std::string game, void* image) { ObjObjects = *(decltype(ObjObjects)*)objects; auto entry = UE_FNameEntry(NamePoolData.GetEntry(0)); - if (*(uint32*)entry.String().data() != 'enoN') return STATUS::ENGINE_FAILED; + + // exception handler exclusively for Decrypt_ANSI + try { + if (*(uint32*)entry.String().data() != 'enoN') return STATUS::ENGINE_FAILED; + } + catch (...) { + return STATUS::ENGINE_FAILED; + } return STATUS::SUCCESS; } diff --git a/Dumper/generic.cpp b/Dumper/generic.cpp index bb19d57..ee2ef5f 100644 --- a/Dumper/generic.cpp +++ b/Dumper/generic.cpp @@ -28,7 +28,7 @@ void FNamePool::DumpBlock(uint32 blockId, uint32 blockSize, std::function callback) const { - for (uint32 i = 0u; i < CurrentBlock; i++) { + for (uint32 i = 0; i < CurrentBlock; i++) { DumpBlock(i, offsets.Stride * 65536, callback); } DumpBlock(CurrentBlock, CurrentByteCursor, callback); @@ -73,7 +73,7 @@ void TUObjectArray::ForEachObjectOfClass(const UE_UClass cmp, std::function #include #include +#include #include "engine.h" #include "memory.h" #include "wrappers.h" @@ -118,8 +119,7 @@ std::string UE_UObject::GetCppName() const { } bool UE_UObject::IsA(UE_UClass cmp) const { - for (auto super = GetClass(); super; - super = super.GetSuper().Cast()) { + for (auto super = GetClass(); super; super = super.GetSuper().Cast()) { if (super == cmp) { return true; } @@ -676,210 +676,147 @@ uint64 UE_FProperty::GetPropertyFlags() const { return Read(object + offsets.FProperty.PropertyFlags); } -std::unordered_map> types = { - { - "StructProperty", - [](const UE_FProperty *prop, type &type) { - auto obj = prop->Cast(); - type = {PropertyType::StructProperty, obj.GetTypeStr()}; - } - }, - { - "ObjectProperty", - [](const UE_FProperty *prop, type &type) { - auto obj = prop->Cast(); - type = {PropertyType::ObjectProperty, obj.GetTypeStr()}; - } - }, - { - "SoftObjectProperty", - [](const UE_FProperty *prop, type &type) { - auto obj = prop->Cast(); - type = {PropertyType::SoftObjectProperty, "struct TSoftObjectPtr<" + obj.GetPropertyClass().GetCppName() + ">"}; - } - }, - { - "FloatProperty", - [](const UE_FProperty *prop, type &type) { - type = {PropertyType::FloatProperty, "float"}; - } - }, - { - "ByteProperty", - [](const UE_FProperty *prop, type &type) { - auto obj = prop->Cast(); - type = {PropertyType::ByteProperty, obj.GetTypeStr()}; - } - }, - { - "BoolProperty", - [](const UE_FProperty *prop, type &type) { - auto obj = prop->Cast(); - type = {PropertyType::BoolProperty, obj.GetTypeStr()}; - } - }, - { - "IntProperty", - [](const UE_FProperty *prop, type &type) { - type = {PropertyType::IntProperty, "int32_t"}; - } - }, - { - "Int8Property", - [](const UE_FProperty *prop, type &type) { - type = {PropertyType::Int8Property, "int8_t"}; - } - }, - { - "Int16Property", - [](const UE_FProperty *prop, type &type) { - type = {PropertyType::Int16Property, "int16_t"}; - } - }, - { - "Int64Property", - [](const UE_FProperty *prop, type &type) { - type = {PropertyType::Int64Property, "int64_t"}; - } - }, - { - "UInt16Property", - [](const UE_FProperty *prop, type& type) { - type = {PropertyType::UInt16Property, "uint16_t"}; - } - }, - { - "UInt32Property", - [](const UE_FProperty *prop, type &type) { - type = {PropertyType::UInt32Property, "uint32_t"}; - } - }, - { - "UInt64Property", - [](const UE_FProperty *prop, type &type) { - type = {PropertyType::UInt64Property, "uint64_t"}; - } - }, - { - "NameProperty", - [](const UE_FProperty *prop, type &type) { - type = {PropertyType::NameProperty, "struct FName"}; - } - }, - { - "DelegateProperty", - [](const UE_FProperty *prop, type &type) { - type = {PropertyType::DelegateProperty, "struct FDelegate"}; - } - }, - { - "SetProperty", - [](const UE_FProperty *prop, type &type) { - auto obj = prop->Cast(); - type = {PropertyType::SetProperty, obj.GetTypeStr()}; - } - }, - { - "ArrayProperty", - [](const UE_FProperty *prop, type &type) { - auto obj = prop->Cast(); - type = {PropertyType::ArrayProperty, obj.GetTypeStr()}; - } - }, - { - "WeakObjectProperty", - [](const UE_FProperty *prop, type &type) { - auto obj = prop->Cast(); - type = {PropertyType::WeakObjectProperty, "struct TWeakObjectPtr<" + obj.GetTypeStr() + ">"}; - } - }, - { - "StrProperty", - [](const UE_FProperty *prop, type &type) { - type = {PropertyType::StrProperty, "struct FString"}; - } - }, - { - "TextProperty", - [](const UE_FProperty* prop, type& type) { - type = {PropertyType::TextProperty, "struct FText"}; - } - }, - { - "MulticastSparseDelegateProperty", - [](const UE_FProperty* prop, type& type) { - type = {PropertyType::MulticastSparseDelegateProperty, "struct FMulticastSparseDelegate"}; - } - }, - { - "EnumProperty", - [](const UE_FProperty* prop, type& type) { - auto obj = prop->Cast(); - type = {PropertyType::EnumProperty, obj.GetTypeStr()}; - } - }, - { - "DoubleProperty", - [](const UE_FProperty* prop, type& type) { - type = {PropertyType::DoubleProperty, "double"}; - } - }, - { - "MulticastDelegateProperty", - [](const UE_FProperty* prop, type& type) { - type = {PropertyType::MulticastDelegateProperty, "FMulticastDelegate"}; - } - }, - { - "ClassProperty", - [](const UE_FProperty* prop, type& type) { - auto obj = prop->Cast(); - type = {PropertyType::ClassProperty, obj.GetTypeStr()}; - } - }, - { - "MulticastInlineDelegateProperty", - [](const UE_FProperty* prop, type& type) { - type = {PropertyType::MulticastDelegateProperty, "struct FMulticastInlineDelegate"}; - } - }, - { - "MapProperty", - [](const UE_FProperty* prop, type& type) { - auto obj = prop->Cast(); - type = {PropertyType::MapProperty, obj.GetTypeStr()}; - } - }, - { - "InterfaceProperty", - [](const UE_FProperty* prop, type& type) { - auto obj = prop->Cast(); - type = {PropertyType::InterfaceProperty, obj.GetTypeStr()}; - } - }, - { - "FieldPathProperty", - [](const UE_FProperty* prop, type& type) { - auto obj = prop->Cast(); - type = { PropertyType::FieldPathProperty, obj.GetTypeStr() }; - } - }, - { - "SoftClassProperty", - [](const UE_FProperty* prop, type& type) { - type = {PropertyType::SoftClassProperty, "struct TSoftClassPtr"}; - } - } -}; - type UE_FProperty::GetType() const { auto objectClass = Read(object + offsets.FField.Class); type type = {PropertyType::Unknown, objectClass.GetName()}; - auto fn = types.find(type.second); + auto& str = type.second; + auto hash = Hash(str.c_str(), str.size()); + switch (hash) { + case HASH("StructProperty"): { + auto obj = this->Cast(); + type = { PropertyType::StructProperty, obj.GetTypeStr() }; + break; + } + case HASH("ObjectProperty"): { + auto obj = this->Cast(); + type = { PropertyType::ObjectProperty, obj.GetTypeStr() }; + break; + } + case HASH("SoftObjectProperty"): { + auto obj = this->Cast(); + type = { PropertyType::SoftObjectProperty, "struct TSoftObjectPtr<" + obj.GetPropertyClass().GetCppName() + ">" }; + break; + } + case HASH("FloatProperty"): { + type = { PropertyType::FloatProperty, "float" }; + break; + } + case HASH("ByteProperty"): { + auto obj = this->Cast(); + type = { PropertyType::ByteProperty, obj.GetTypeStr() }; + break; + } + case HASH("BoolProperty"): { + auto obj = this->Cast(); + type = { PropertyType::BoolProperty, obj.GetTypeStr() }; + break; + } + case HASH("IntProperty"): { + type = { PropertyType::IntProperty, "int32_t" }; + break; + } + case HASH("Int8Property"): { + type = { PropertyType::Int8Property, "int8_t" }; + break; + } + case HASH("Int16Property"): { + type = { PropertyType::Int16Property, "int16_t" }; + break; + } + case HASH("Int64Property"): { + type = { PropertyType::Int64Property, "int64_t" }; + break; + } + case HASH("UInt16Property"): { + type = { PropertyType::UInt16Property, "uint16_t" }; + break; + } + case HASH("UInt32Property"): { + type = { PropertyType::UInt32Property, "uint32_t" }; + break; + } + case HASH("UInt64Property"): { + type = { PropertyType::UInt64Property, "uint64_t" }; + break; + } + case HASH("NameProperty"): { + type = { PropertyType::NameProperty, "struct FName" }; + break; + } + case HASH("DelegateProperty"): { + type = { PropertyType::DelegateProperty, "struct FDelegate" }; + break; + } + case HASH("SetProperty"): { + auto obj = this->Cast(); + type = { PropertyType::SetProperty, obj.GetTypeStr() }; + break; + } + case HASH("ArrayProperty"): { + auto obj = this->Cast(); + type = { PropertyType::ArrayProperty, obj.GetTypeStr() }; + break; + } + case HASH("WeakObjectProperty"): { + auto obj = this->Cast(); + type = { PropertyType::WeakObjectProperty, "struct TWeakObjectPtr<" + obj.GetTypeStr() + ">" }; - if (fn != types.end()) { - fn->second(this, type); + break; + } + case HASH("StrProperty"): { + type = { PropertyType::StrProperty, "struct FString" }; + break; + } + case HASH("TextProperty"): { + type = { PropertyType::TextProperty, "struct FText" }; + break; + } + case HASH("MulticastSparseDelegateProperty"): { + type = { PropertyType::MulticastSparseDelegateProperty, "struct FMulticastSparseDelegate" }; + break; + } + case HASH("EnumProperty"): { + auto obj = this->Cast(); + type = { PropertyType::EnumProperty, obj.GetTypeStr() }; + break; + } + case HASH("DoubleProperty"): { + type = { PropertyType::DoubleProperty, "double" }; + break; + } + case HASH("MulticastDelegateProperty"): { + type = { PropertyType::MulticastDelegateProperty, "FMulticastDelegate" }; + break; + } + case HASH("ClassProperty"): { + auto obj = this->Cast(); + type = { PropertyType::ClassProperty, obj.GetTypeStr() }; + break; + } + case HASH("MulticastInlineDelegateProperty"): { + type = { PropertyType::MulticastDelegateProperty, "struct FMulticastInlineDelegate" }; + break; + } + case HASH("MapProperty"): { + auto obj = this->Cast(); + type = { PropertyType::MapProperty, obj.GetTypeStr() }; + break; + } + case HASH("InterfaceProperty"): { + auto obj = this->Cast(); + type = { PropertyType::InterfaceProperty, obj.GetTypeStr() }; + break; + } + case HASH("FieldPathProperty"): { + auto obj = this->Cast(); + type = { PropertyType::FieldPathProperty, obj.GetTypeStr() }; + break; + } + case HASH("SoftClassProperty"): { + type = { PropertyType::SoftClassProperty, "struct TSoftClassPtr" }; + break; + } } return type; diff --git a/README.md b/README.md index c7b28aa..fa45e2c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ ### Edit engine.cpp in order to add support for your game - ### Currently supported games: - Fortnite - Rogue Company @@ -10,7 +9,8 @@ - SCUM - Scavengers - The Isle - +### Supported engine versions: +- UE 4.23-4.27 ### Usage: ``` .\Dumper.exe -[options] @@ -23,4 +23,4 @@ Options: '-f packageNameHere' - specifies package where we should look for pointers in paddings (can take a lot of time) ``` ### Todo: -- Analyze functions to get offsets to referenced fields +- Analyze functions to get offsets to referenced fields \ No newline at end of file diff --git a/include/hash/hash.h b/include/hash/hash.h new file mode 100644 index 0000000..7eaff48 --- /dev/null +++ b/include/hash/hash.h @@ -0,0 +1,23 @@ +#pragma once +#include + +constexpr uint64 Prime = 1099511628211; +constexpr uint64 Basis = 14695981039346656037; + +template< typename Type > +constexpr uint64 HashCompute(uint64 hash, const Type* const data, uint64 size) { + const auto element = (uint64)(data[0]); + return (size == 0) ? hash : HashCompute((hash * Prime) ^ element, data + 1, size - 1); +} + +template< typename Type > +constexpr uint64 Hash(const Type* const data, uint64 size){ + return HashCompute(Basis, data, size); +} + +#define HASH( Data ) \ + [ & ]() \ + { \ + constexpr auto hash = Hash( Data, sizeof(Data) - 1 ); \ + return hash; \ + }() \ No newline at end of file diff --git a/include/types.h b/include/types.h new file mode 100644 index 0000000..b7fea6e --- /dev/null +++ b/include/types.h @@ -0,0 +1,9 @@ +typedef signed char int8; +typedef short int16; +typedef int int32; +typedef long long int64; + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; +typedef unsigned long long uint64; \ No newline at end of file