diff --git a/src/Components/Modules/AssetHandler.cpp b/src/Components/Modules/AssetHandler.cpp index 1f6fc20d..9bf98310 100644 --- a/src/Components/Modules/AssetHandler.cpp +++ b/src/Components/Modules/AssetHandler.cpp @@ -3,11 +3,29 @@ namespace Components { bool AssetHandler::BypassState = false; + std::map AssetHandler::AssetInterfaces; std::map AssetHandler::TypeCallbacks; std::vector AssetHandler::RestrictCallbacks; std::map AssetHandler::Relocations; + void AssetHandler::RegisterInterface(IAsset* iAsset) + { + if (!iAsset) return; + if (iAsset->GetType() == Game::XAssetType::ASSET_TYPE_INVALID) + { + delete iAsset; + return; + } + + if (AssetHandler::AssetInterfaces.find(iAsset->GetType()) != AssetHandler::AssetInterfaces.end()) + { + delete AssetHandler::AssetInterfaces[iAsset->GetType()]; + } + + AssetHandler::AssetInterfaces[iAsset->GetType()] = iAsset; + } + Game::XAssetHeader AssetHandler::FindAsset(Game::XAssetType type, const char* filename) { Game::XAssetHeader header = { 0 }; @@ -139,6 +157,30 @@ namespace Components } } + void AssetHandler::ZoneSave(Game::XAsset asset, ZoneBuilder::Zone* builder) + { + if (AssetHandler::AssetInterfaces.find(asset.type) != AssetHandler::AssetInterfaces.end()) + { + AssetHandler::AssetInterfaces[asset.type]->Save(asset.header, builder); + } + else + { + Logger::Error("No interface for type '%s'!", Game::DB_GetXAssetTypeName(asset.type)); + } + } + + void AssetHandler::ZoneMark(Game::XAsset asset, ZoneBuilder::Zone* builder) + { + if (AssetHandler::AssetInterfaces.find(asset.type) != AssetHandler::AssetInterfaces.end()) + { + AssetHandler::AssetInterfaces[asset.type]->Mark(asset.header, builder); + } + else + { + Logger::Error("No interface for type '%s'!", Game::DB_GetXAssetTypeName(asset.type)); + } + } + AssetHandler::AssetHandler() { // DB_FindXAssetHeader @@ -149,10 +191,20 @@ namespace Components // DB_AddXAsset Utils::Hook(0x5BB650, AssetHandler::AddAssetStub, HOOK_JUMP).Install()->Quick(); + + // Register asset interfaces + AssetHandler::RegisterInterface(new Assets::IRawFile()); + AssetHandler::RegisterInterface(new Assets::ILocalizedEntry()); } AssetHandler::~AssetHandler() { + for (auto i = AssetHandler::AssetInterfaces.begin(); i != AssetHandler::AssetInterfaces.end(); i++) + { + delete i->second; + } + + AssetHandler::AssetInterfaces.clear(); AssetHandler::TypeCallbacks.clear(); } } diff --git a/src/Components/Modules/AssetHandler.hpp b/src/Components/Modules/AssetHandler.hpp index cdb82675..0d4d0370 100644 --- a/src/Components/Modules/AssetHandler.hpp +++ b/src/Components/Modules/AssetHandler.hpp @@ -3,6 +3,16 @@ namespace Components class AssetHandler : public Component { public: + class IAsset + { + public: + virtual Game::XAssetType GetType() { return Game::XAssetType::ASSET_TYPE_INVALID; }; + virtual void Mark(Game::XAssetHeader header, ZoneBuilder::Zone* builder) { /*ErrorTypeNotSupported(this);*/ }; + virtual void Save(Game::XAssetHeader header, ZoneBuilder::Zone* builder) { /*ErrorTypeNotSupported(this);*/ }; + virtual void Dump(Game::XAssetHeader header) { /*ErrorTypeNotSupported(this);*/ }; + virtual void Load(Game::XAssetHeader* header, std::string name) { /*ErrorTypeNotSupported(this);*/ }; + }; + typedef Game::XAssetHeader(*Callback)(Game::XAssetType, const char*); typedef bool(*RestrictCallback)(Game::XAssetType type, Game::XAssetHeader asset, const char* name); @@ -15,9 +25,14 @@ namespace Components static void Relocate(void* start, void* to, DWORD size = 4); + static void ZoneSave(Game::XAsset asset, ZoneBuilder::Zone* builder); + static void ZoneMark(Game::XAsset asset, ZoneBuilder::Zone* builder); + private: static bool BypassState; + static void RegisterInterface(IAsset* iAsset); + static Game::XAssetHeader FindAsset(Game::XAssetType type, const char* filename); static bool IsAssetEligible(Game::XAssetType type, Game::XAssetHeader* asset); static void FindAssetStub(); @@ -25,9 +40,13 @@ namespace Components static void OffsetToAlias(Utils::Stream::Offset* offset); + static std::map AssetInterfaces; static std::map TypeCallbacks; static std::vector RestrictCallbacks; static std::map Relocations; }; } + +#include "AssetInterfaces\IRawFile.hpp" +#include "AssetInterfaces\ILocalizedEntry.hpp" diff --git a/src/Components/Modules/AssetInterfaces/ILocalizedEntry.cpp b/src/Components/Modules/AssetInterfaces/ILocalizedEntry.cpp new file mode 100644 index 00000000..54376ec7 --- /dev/null +++ b/src/Components/Modules/AssetInterfaces/ILocalizedEntry.cpp @@ -0,0 +1,28 @@ +#include + +namespace Assets +{ + void ILocalizedEntry::Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) + { + Utils::Stream* buffer = builder->GetBuffer(); + Game::LocalizedEntry* asset = header.localize; + Game::LocalizedEntry* dest = (Game::LocalizedEntry*)buffer->At(); + buffer->Save(asset, sizeof(Game::LocalizedEntry)); + + buffer->PushBlock(Game::XFILE_BLOCK_VIRTUAL); + + if (asset->value) + { + buffer->SaveString(asset->value); + dest->value = (char *)-1; + } + + if (asset->name) + { + buffer->SaveString(asset->name); + dest->name = (char *)-1; + } + + buffer->PopBlock(); + } +} diff --git a/src/Components/Modules/AssetInterfaces/ILocalizedEntry.hpp b/src/Components/Modules/AssetInterfaces/ILocalizedEntry.hpp new file mode 100644 index 00000000..5a6fbaf8 --- /dev/null +++ b/src/Components/Modules/AssetInterfaces/ILocalizedEntry.hpp @@ -0,0 +1,9 @@ +namespace Assets +{ + class ILocalizedEntry : public Components::AssetHandler::IAsset + { + virtual Game::XAssetType GetType() override { return Game::XAssetType::ASSET_TYPE_LOCALIZE; }; + + virtual void Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override; + }; +} diff --git a/src/Components/Modules/AssetInterfaces/IRawFile.cpp b/src/Components/Modules/AssetInterfaces/IRawFile.cpp new file mode 100644 index 00000000..8ce464fe --- /dev/null +++ b/src/Components/Modules/AssetInterfaces/IRawFile.cpp @@ -0,0 +1,36 @@ +#include + +namespace Assets +{ + void IRawFile::Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) + { + Utils::Stream* buffer = builder->GetBuffer(); + Game::RawFile* asset = header.rawfile; + Game::RawFile* dest = (Game::RawFile*)buffer->At(); + buffer->Save(asset, sizeof(Game::RawFile)); + + buffer->PushBlock(Game::XFILE_BLOCK_VIRTUAL); + + if (asset->name) + { + buffer->SaveString(asset->name); + dest->name = (char *)-1; + } + + if (asset->compressedData) + { + if (asset->sizeCompressed) + { + buffer->SaveString(asset->compressedData, asset->sizeCompressed); + } + else + { + buffer->SaveString(asset->compressedData, asset->sizeUnCompressed); + } + + dest->compressedData = (char*)-1; + } + + buffer->PopBlock(); + } +} diff --git a/src/Components/Modules/AssetInterfaces/IRawFile.hpp b/src/Components/Modules/AssetInterfaces/IRawFile.hpp new file mode 100644 index 00000000..b319322b --- /dev/null +++ b/src/Components/Modules/AssetInterfaces/IRawFile.hpp @@ -0,0 +1,9 @@ +namespace Assets +{ + class IRawFile : public Components::AssetHandler::IAsset + { + virtual Game::XAssetType GetType() override { return Game::XAssetType::ASSET_TYPE_RAWFILE; }; + + virtual void Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override; + }; +} \ No newline at end of file diff --git a/src/Components/Modules/Localization.cpp b/src/Components/Modules/Localization.cpp index e5220ea3..9ddd1f6e 100644 --- a/src/Components/Modules/Localization.cpp +++ b/src/Components/Modules/Localization.cpp @@ -3,25 +3,50 @@ namespace Components { Dvar::Var Localization::UseLocalization; - std::map Localization::LocalizeMap; + std::map Localization::LocalizeMap; + std::map Localization::TempLocalizeMap; void Localization::Set(const char* key, const char* value) { - Localization::LocalizeMap[key] = value; + Game::LocalizedEntry* entry = Utils::Memory::AllocateArray(1); + if (!entry) return; + + entry->name = Utils::Memory::DuplicateString(key); + if (!entry->name) + { + Utils::Memory::Free(entry); + return; + } + + entry->value = Utils::Memory::DuplicateString(value); + if (!entry->value) + { + Utils::Memory::Free(entry->name); + Utils::Memory::Free(entry); + return; + } + + Localization::LocalizeMap[key] = entry; } const char* Localization::Get(const char* key) { if (!Localization::UseLocalization.Get()) return key; - if (Localization::LocalizeMap.find(key) != Localization::LocalizeMap.end()) + Game::LocalizedEntry* entry = nullptr; + + if (Localization::TempLocalizeMap.find(key) != Localization::TempLocalizeMap.end()) { - return Localization::LocalizeMap[key].data(); + entry = Localization::TempLocalizeMap[key]; + } + else if (Localization::LocalizeMap.find(key) != Localization::LocalizeMap.end()) + { + entry = Localization::LocalizeMap[key]; } - Game::localizedEntry_s* entry = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_LOCALIZE, key).localize; + if (!entry || !entry->value) entry = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_LOCALIZE, key).localize; - if (entry) + if (entry && entry->value) { return entry->value; } @@ -29,6 +54,53 @@ namespace Components return key; } + void Localization::SetTemp(std::string key, std::string value) + { + if (Localization::TempLocalizeMap.find(key) != Localization::TempLocalizeMap.end()) + { + Game::LocalizedEntry* entry = Localization::TempLocalizeMap[key]; + if(entry->value) Utils::Memory::Free(entry->value); + entry->value = Utils::Memory::DuplicateString(value); + } + else + { + Game::LocalizedEntry* entry = Utils::Memory::AllocateArray(1); + if (!entry) return; + + entry->name = Utils::Memory::DuplicateString(key); + if (!entry->name) + { + Utils::Memory::Free(entry); + return; + } + + entry->value = Utils::Memory::DuplicateString(value); + if (!entry->value) + { + Utils::Memory::Free(entry->name); + Utils::Memory::Free(entry); + return; + } + + Localization::TempLocalizeMap[key] = entry; + } + } + + void Localization::ClearTemp() + { + for (auto i = Localization::TempLocalizeMap.begin(); i != Localization::TempLocalizeMap.end(); i++) + { + if (i->second) + { + if (i->second->name) Utils::Memory::Free(i->second->name); + if (i->second->value) Utils::Memory::Free(i->second->value); + Utils::Memory::Free(i->second); + } + } + + Localization::TempLocalizeMap.clear(); + } + void __stdcall Localization::SetStringStub(const char* key, const char* value, bool isEnglish) { Localization::Set(key, value); @@ -44,6 +116,22 @@ namespace Components Localization::Localization() { + AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_LOCALIZE, [] (Game::XAssetType, const char* filename) + { + Game::XAssetHeader header = { 0 }; + + if (Localization::TempLocalizeMap.find(filename) != Localization::TempLocalizeMap.end()) + { + header.localize = Localization::TempLocalizeMap[filename]; + } + else if (Localization::LocalizeMap.find(filename) != Localization::LocalizeMap.end()) + { + header.localize = Localization::LocalizeMap[filename]; + } + + return header; + }); + // Resolving hook Utils::Hook(0x629B90, Localization::Get, HOOK_JUMP).Install()->Quick(); @@ -85,6 +173,18 @@ namespace Components Localization::~Localization() { + Localization::ClearTemp(); + + for (auto i = Localization::LocalizeMap.begin(); i != Localization::LocalizeMap.end(); i++) + { + if (i->second) + { + if (i->second->name) Utils::Memory::Free(i->second->name); + if (i->second->value) Utils::Memory::Free(i->second->value); + Utils::Memory::Free(i->second); + } + } + Localization::LocalizeMap.clear(); } } diff --git a/src/Components/Modules/Localization.hpp b/src/Components/Modules/Localization.hpp index 013c62c3..5c7dc597 100644 --- a/src/Components/Modules/Localization.hpp +++ b/src/Components/Modules/Localization.hpp @@ -10,8 +10,12 @@ namespace Components static void Set(const char* key, const char* value); static const char* Get(const char* key); + static void SetTemp(std::string key, std::string value); + static void ClearTemp(); + private: - static std::map LocalizeMap; + static std::map LocalizeMap; + static std::map TempLocalizeMap; static Dvar::Var UseLocalization; static void __stdcall SetStringStub(const char* key, const char* value, bool isEnglish); diff --git a/src/Components/Modules/Menus.cpp b/src/Components/Modules/Menus.cpp index ff8679a3..00a7c4fc 100644 --- a/src/Components/Modules/Menus.cpp +++ b/src/Components/Modules/Menus.cpp @@ -68,7 +68,7 @@ namespace Components script->next = NULL; - source = (Game::source_t *)calloc(1, sizeof(Game::source_t)); + source = Utils::Memory::AllocateArray(1); if (!source) { Game::FreeMemory(script); @@ -81,7 +81,7 @@ namespace Components source->defines = NULL; source->indentstack = NULL; source->skip = 0; - source->definehash = (Game::define_t**)calloc(1, 4096); + source->definehash = (Game::define_t**)Utils::Memory::Allocate(4096); Game::sourceFiles[handle] = source; @@ -115,13 +115,13 @@ namespace Components Game::menuDef_t* Menus::ParseMenu(int handle) { - Game::menuDef_t* menu = (Game::menuDef_t*)calloc(1, sizeof(Game::menuDef_t)); + Game::menuDef_t* menu = Utils::Memory::AllocateArray(1); if (!menu) return nullptr; - menu->items = (Game::itemDef_t**)calloc(512, sizeof(Game::itemDef_t*)); + menu->items = Utils::Memory::AllocateArray(512); if (!menu->items) { - free(menu); + Utils::Memory::Free(menu); return nullptr; } @@ -230,17 +230,17 @@ namespace Components if (!menus.size()) return nullptr; // Allocate new menu list - Game::MenuList* newList = (Game::MenuList*)calloc(1, sizeof(Game::MenuList)); + Game::MenuList* newList = Utils::Memory::AllocateArray(1); if (!newList) return nullptr; - newList->menus = (Game::menuDef_t **)calloc(menus.size(), sizeof(Game::menuDef_t *)); + newList->menus = Utils::Memory::AllocateArray(menus.size()); if (!newList->menus) { - free(newList); + Utils::Memory::Free(newList); return nullptr; } - newList->name = _strdup(menu); + newList->name = Utils::Memory::DuplicateString(menu); newList->menuCount = menus.size(); // Copy new menus @@ -275,17 +275,17 @@ namespace Components } // Allocate new menu list - Game::MenuList* newList = (Game::MenuList*)calloc(1, sizeof(Game::MenuList)); + Game::MenuList* newList = Utils::Memory::AllocateArray(1); if (!newList) return menuList; - newList->menus = (Game::menuDef_t **)calloc(menus.size(), sizeof(Game::menuDef_t *)); + newList->menus = Utils::Memory::AllocateArray(menus.size()); if (!newList->menus) { - free(newList); + Utils::Memory::Free(newList); return menuList; } - newList->name = _strdup(menuList->name); + newList->name = Utils::Memory::DuplicateString(menuList->name); newList->menuCount = menus.size(); // Copy new menus @@ -331,12 +331,12 @@ namespace Components { indent = source->indentstack; source->indentstack = source->indentstack->next; - free(indent); + Utils::Memory::Free(indent); } - if (source->definehash) free(source->definehash); + if (source->definehash) Utils::Memory::Free(source->definehash); - free(source); + Utils::Memory::Free(source); Game::sourceFiles[handle] = nullptr; } @@ -357,10 +357,10 @@ namespace Components // Game::Menu_FreeItemMemory(menudef->items[i]); //} - free(menudef->items); + Utils::Memory::Free(menudef->items); } - free(menudef); + Utils::Memory::Free(menudef); } void Menus::FreeMenuList(Game::MenuList* menuList) @@ -372,15 +372,15 @@ namespace Components if (list.name) { - free(list.name); + Utils::Memory::Free(list.name); } if (list.menus) { - free(list.menus); + Utils::Memory::Free(list.menus); } - free(menuList); + Utils::Memory::Free(menuList); } void Menus::RemoveMenu(Game::menuDef_t* menudef) diff --git a/src/Components/Modules/Weapon.cpp b/src/Components/Modules/Weapon.cpp index 2876e96e..52a42ee0 100644 --- a/src/Components/Modules/Weapon.cpp +++ b/src/Components/Modules/Weapon.cpp @@ -4,7 +4,7 @@ namespace Components { Game::XAssetHeader Weapon::WeaponFileLoad(Game::XAssetType type, const char* filename) { - Game::XAssetHeader header = { nullptr }; + Game::XAssetHeader header = { 0 }; // Try loading raw weapon if (FileSystem::File(Utils::VA("weapons/mp/%s", filename)).Exists()) diff --git a/src/Components/Modules/ZoneBuilder.cpp b/src/Components/Modules/ZoneBuilder.cpp index 1563c36f..9d851f27 100644 --- a/src/Components/Modules/ZoneBuilder.cpp +++ b/src/Components/Modules/ZoneBuilder.cpp @@ -15,7 +15,7 @@ namespace Components ZoneBuilder::Zone::~Zone() { - //Assets::Patches::DeleteTemporaryLocalizeEntries(); + Localization::ClearTemp(); ZoneBuilder::Zone::Assets.clear(); ZoneBuilder::Zone::ScriptStrings.clear(); @@ -34,14 +34,6 @@ namespace Components Logger::Print("link..."); if (!ZoneBuilder::Zone::LoadAssets()) return; - Game::RawFile* rawFile = new Game::RawFile; - rawFile->name = "zob.cfg"; - rawFile->compressedData = "map mp_rust"; - rawFile->sizeUnCompressed = strlen(rawFile->compressedData) + 1; - rawFile->sizeCompressed = 0; - - Assets.push_back({ Game::XAssetType::ASSET_TYPE_RAWFILE, rawFile }); - ZoneBuilder::Zone::AddBranding(); Logger::Print("save..."); @@ -89,11 +81,11 @@ namespace Components { if (DataMap.GetColumns(i) > 2) { -// if (DataMap.GetElementAt(i, 0) == "localize") -// { -// Assets::Patches::AddTemporaryLocalizeEntry(DataMap.GetElementAt(i, 1), DataMap.GetElementAt(i, 2)); -// } -// else + if (DataMap.GetElementAt(i, 0) == "localize") + { + Localization::SetTemp(DataMap.GetElementAt(i, 1), DataMap.GetElementAt(i, 2)); + } + else { ZoneBuilder::Zone::RenameAsset(Game::DB_GetXAssetNameType(DataMap.GetElementAt(i, 0).data()), DataMap.GetElementAt(i, 1), DataMap.GetElementAt(i, 2)); } @@ -139,7 +131,7 @@ namespace Components asset.header = assetHeader; // Handle script strings and referenced assets - //Assets::Mark(&asset, this); + AssetHandler::ZoneMark(asset, this); ZoneBuilder::Zone::Assets.push_back(asset); return true; @@ -248,7 +240,7 @@ namespace Components // So scriptString loading for NULL scriptStrings from fastfile results in a NULL scriptString. // That's the reason why the count is incremented by 1, if scriptStrings are available. - // Write ScriptString pointer table + // Write ScriptString pointer table for (size_t i = 0; i < ZoneBuilder::Zone::ScriptStrings.size(); i++) { ZoneBuilder::Zone::Buffer.SaveMax(4); @@ -266,7 +258,8 @@ namespace Components // Align buffer (4 bytes) to get correct offsets for pointers ZoneBuilder::Zone::Buffer.Align(Utils::Stream::ALIGN_4); ZoneBuilder::Zone::IndexStart = ZoneBuilder::Zone::Buffer.GetBlockSize(Game::XFILE_BLOCK_VIRTUAL); // Mark AssetTable offset - // AssetTable + + // AssetTable for (auto asset : Assets) { Game::XAsset entry; @@ -280,44 +273,9 @@ namespace Components for (auto asset : Assets) { ZoneBuilder::Zone::Buffer.PushBlock(Game::XFILE_BLOCK_TEMP); - - if (asset.type == Game::XAssetType::ASSET_TYPE_RAWFILE) - { - Game::RawFile* _asset = asset.header.rawfile; - Game::RawFile* dest = (Game::RawFile*)ZoneBuilder::Zone::Buffer.At(); - ZoneBuilder::Zone::Buffer.Save(_asset, sizeof(Game::RawFile)); - ZoneBuilder::Zone::Buffer.PushBlock(Game::XFILE_BLOCK_VIRTUAL); + AssetHandler::ZoneSave(asset, this); - if (_asset->name) - { - ZoneBuilder::Zone::Buffer.SaveString(_asset->name); - dest->name = (char *)-1; - } - - if (_asset->compressedData) - { - if (_asset->sizeCompressed) - { - ZoneBuilder::Zone::Buffer.SaveString(_asset->compressedData, _asset->sizeCompressed); - } - else - { - ZoneBuilder::Zone::Buffer.SaveString(_asset->compressedData, _asset->sizeUnCompressed); - } - - dest->compressedData = (char*)-1; - } - - ZoneBuilder::Zone::Buffer.PopBlock(); - } - else - { - Logger::Error("Wat?"); - } - - //Assets::Save(asset, this); - ZoneBuilder::Zone::Buffer.PopBlock(); } @@ -327,7 +285,7 @@ namespace Components header->size = ZoneBuilder::Zone::Buffer.Length() - sizeof(Game::XFile); // Write correct data size header->externalSize = 0; // ? - // Write stream sizes + // Write stream sizes for (int i = 0; i < Game::MAX_XFILE_COUNT; i++) { header->blockSize[i] = ZoneBuilder::Zone::Buffer.GetBlockSize((Game::XFILE_BLOCK_TYPES)i); @@ -463,6 +421,16 @@ namespace Components static_assert(sizeof(Game::XFile) == 40, "Invalid XFile structure!"); static_assert(Game::MAX_XFILE_COUNT == 8, "XFile block enum is invalid!"); + AssetHandler::OnLoad([] (Game::XAssetType type, Game::XAssetHeader asset, const char* name) + { + if (FastFiles::Current() == "penis") + { + OutputDebugStringA(name); + } + + return true; + }); + if (ZoneBuilder::IsEnabled()) { Command::Add("build", [] (Command::Params params) @@ -476,6 +444,6 @@ namespace Components }); } - //Utils::Hook(0x60B4AC, TestZoneLoading, HOOK_CALL).Install()->Quick(); + Utils::Hook(0x4546DF, TestZoneLoading, HOOK_CALL).Install()->Quick(); } } diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp index 59d2aa3b..7e162af3 100644 --- a/src/Game/Functions.cpp +++ b/src/Game/Functions.cpp @@ -164,7 +164,7 @@ namespace Game void* ReallocateAssetPool(XAssetType type, unsigned int newSize) { int elSize = DB_GetXAssetSizeHandlers[type](); - void* poolEntry = new char[newSize * elSize]; + void* poolEntry = Utils::Memory::Allocate(newSize * elSize); DB_XAssetPool[type] = poolEntry; g_poolSize[type] = newSize; return poolEntry; diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index 01800433..7a169ccd 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -890,7 +890,7 @@ namespace Game UILocalVarContext localVars; }; - struct localizedEntry_s + struct LocalizedEntry { const char* value; const char* name; @@ -931,7 +931,7 @@ namespace Game menuDef_t *menu; Material *material; snd_alias_list_t *aliasList; - localizedEntry_s *localize; + LocalizedEntry *localize; StringTable *stringTable; MapEnts* mapEnts; RawFile* rawfile; diff --git a/src/STDInclude.hpp b/src/STDInclude.hpp index d19544f7..200da516 100644 --- a/src/STDInclude.hpp +++ b/src/STDInclude.hpp @@ -39,6 +39,7 @@ #include "Utils\CSV.hpp" #include "Utils\Utils.hpp" #include "Utils\WebIO.hpp" +#include "Utils\Memory.hpp" #include "Utils\Hooking.hpp" #include "Utils\Compression.hpp" diff --git a/src/Utils/Compression.cpp b/src/Utils/Compression.cpp index 4b43b53d..d7b0ddb3 100644 --- a/src/Utils/Compression.cpp +++ b/src/Utils/Compression.cpp @@ -6,38 +6,19 @@ namespace Utils { std::string ZLib::Compress(std::string data) { - z_stream stream; - ZeroMemory(&stream, sizeof(stream)); + unsigned long length = (data.size() * 2); + char* buffer = Utils::Memory::AllocateArray(length); - char* buffer = new char[data.size() * 2]; - - if (deflateInit(&stream, Z_BEST_COMPRESSION) != Z_OK) - { - delete[] buffer; - return ""; - } - - stream.next_out = reinterpret_cast(buffer); - stream.next_in = reinterpret_cast(data.data()); - stream.avail_out = data.size() * 2; - stream.avail_in = data.size(); - - if (deflate(&stream, Z_FINISH) != Z_STREAM_END) - { - delete[] buffer; - return ""; - } - - if (deflateEnd(&stream) != Z_OK) + if (compress2((Bytef*)buffer, &length, (Bytef*)data.data(), data.size(), Z_BEST_COMPRESSION) != Z_OK) { - delete[] buffer; + Utils::Memory::Free(buffer); return ""; } data.clear(); - data.append(buffer, stream.total_out); + data.append(buffer, length); - delete[] buffer; + Utils::Memory::Free(buffer); return data; } @@ -54,7 +35,7 @@ namespace Utils } int ret = 0; - uint8_t* dest = new uint8_t[CHUNK]; + uint8_t* dest = Utils::Memory::AllocateArray(CHUNK); const char* dataPtr = data.data(); do @@ -71,7 +52,7 @@ namespace Utils if (ret == Z_STREAM_ERROR) { inflateEnd(&stream); - delete[] dest; + Utils::Memory::Free(dest); return ""; } @@ -83,7 +64,7 @@ namespace Utils inflateEnd(&stream); - delete[] dest; + Utils::Memory::Free(dest); return buffer; } diff --git a/src/Utils/Memory.cpp b/src/Utils/Memory.cpp new file mode 100644 index 00000000..a08449a0 --- /dev/null +++ b/src/Utils/Memory.cpp @@ -0,0 +1,33 @@ +#include "STDInclude.hpp" + +namespace Utils +{ + void* Memory::Allocate(size_t length) + { + void* data = new char[length]; + + if (data) + { + ZeroMemory(data, length); + } + + return data; + } + + char* Memory::DuplicateString(std::string string) + { + char* newString = Memory::AllocateArray(string.size() + 1); + memcpy(newString, string.data(), string.size()); + return newString; + } + + void Memory::Free(void* data) + { + delete[] data; + } + + void Memory::Free(const void* data) + { + Memory::Free((void*)data); + } +} diff --git a/src/Utils/Memory.hpp b/src/Utils/Memory.hpp new file mode 100644 index 00000000..1e2da977 --- /dev/null +++ b/src/Utils/Memory.hpp @@ -0,0 +1,17 @@ +namespace Utils +{ + class Memory + { + public: + static void* Allocate(size_t length); + template static T* AllocateArray(size_t count) + { + return (T*)Allocate(count * sizeof(T)); + } + + static char* DuplicateString(std::string string); + + static void Free(void* data); + static void Free(const void* data); + }; +}