Some optimization
This commit is contained in:
parent
2a64c578c7
commit
276e35e2d2
2
deps/mongoose
vendored
2
deps/mongoose
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 06b6bf6185067506a851a2efadf94599ad1cb880
|
Subproject commit 845e608280419460c6b4f52854db7600e2728535
|
2
deps/protobuf
vendored
2
deps/protobuf
vendored
@ -1 +1 @@
|
|||||||
Subproject commit dfe0c9ad3836dc3756a908fa0e4aee1c2b3f2ce1
|
Subproject commit 401e07d3726e91659228dff8ed9f7cb02026c47e
|
@ -132,7 +132,7 @@ workspace "iw4x"
|
|||||||
-- Pre-compiled header
|
-- Pre-compiled header
|
||||||
pchheader "STDInclude.hpp" -- must be exactly same as used in #include directives
|
pchheader "STDInclude.hpp" -- must be exactly same as used in #include directives
|
||||||
pchsource "src/STDInclude.cpp" -- real path
|
pchsource "src/STDInclude.cpp" -- real path
|
||||||
buildoptions { "/Zm91 -Zm91" }
|
buildoptions { "/Zm200" }
|
||||||
filter "files:**.pb.*"
|
filter "files:**.pb.*"
|
||||||
flags {
|
flags {
|
||||||
"NoPCH",
|
"NoPCH",
|
||||||
|
@ -26,6 +26,7 @@ namespace Components
|
|||||||
Loader::Register(new Command());
|
Loader::Register(new Command());
|
||||||
Loader::Register(new Console());
|
Loader::Register(new Console());
|
||||||
Loader::Register(new IPCPipe());
|
Loader::Register(new IPCPipe());
|
||||||
|
Loader::Register(new ModList());
|
||||||
Loader::Register(new Network());
|
Loader::Register(new Network());
|
||||||
Loader::Register(new Theatre());
|
Loader::Register(new Theatre());
|
||||||
Loader::Register(new Download());
|
Loader::Register(new Download());
|
||||||
@ -51,7 +52,6 @@ namespace Components
|
|||||||
Loader::Register(new MusicalTalent());
|
Loader::Register(new MusicalTalent());
|
||||||
Loader::Register(new StructuredData());
|
Loader::Register(new StructuredData());
|
||||||
Loader::Register(new ConnectProtocol());
|
Loader::Register(new ConnectProtocol());
|
||||||
Loader::Register(new ModList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Loader::Uninitialize()
|
void Loader::Uninitialize()
|
||||||
|
@ -38,6 +38,7 @@ namespace Components
|
|||||||
#include "Modules\Command.hpp"
|
#include "Modules\Command.hpp"
|
||||||
#include "Modules\Console.hpp"
|
#include "Modules\Console.hpp"
|
||||||
#include "Modules\IPCPipe.hpp"
|
#include "Modules\IPCPipe.hpp"
|
||||||
|
#include "Modules\ModList.hpp"
|
||||||
#include "Modules\Network.hpp"
|
#include "Modules\Network.hpp"
|
||||||
#include "Modules\Theatre.hpp"
|
#include "Modules\Theatre.hpp"
|
||||||
#include "Modules\Node.hpp"
|
#include "Modules\Node.hpp"
|
||||||
@ -67,4 +68,3 @@ namespace Components
|
|||||||
#include "Modules\MusicalTalent.hpp"
|
#include "Modules\MusicalTalent.hpp"
|
||||||
#include "Modules\StructuredData.hpp"
|
#include "Modules\StructuredData.hpp"
|
||||||
#include "Modules\ConnectProtocol.hpp"
|
#include "Modules\ConnectProtocol.hpp"
|
||||||
#include "Modules\ModList.hpp"
|
|
||||||
|
@ -140,8 +140,7 @@ namespace Components
|
|||||||
unsigned int Auth::GetKeyHash()
|
unsigned int Auth::GetKeyHash()
|
||||||
{
|
{
|
||||||
Auth::LoadKey();
|
Auth::LoadKey();
|
||||||
std::string key = Auth::GuidKey.GetPublicKey();
|
return (Utils::Cryptography::JenkinsOneAtATime::Compute(Auth::GuidKey.GetPublicKey()));
|
||||||
return (Utils::Cryptography::JenkinsOneAtATime::Compute(key.data(), key.size()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Auth::StoreKey()
|
void Auth::StoreKey()
|
||||||
@ -337,7 +336,7 @@ namespace Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if guid matches the certificate
|
// Check if guid matches the certificate
|
||||||
else if (id != (Utils::Cryptography::JenkinsOneAtATime::Compute(response.publickey().data(), response.publickey().size()) & ~0x80000000))
|
else if (id != (Utils::Cryptography::JenkinsOneAtATime::Compute(response.publickey()) & ~0x80000000))
|
||||||
{
|
{
|
||||||
info->state = Auth::STATE_INVALID;
|
info->state = Auth::STATE_INVALID;
|
||||||
Game::SV_KickClientError(client, "XUID doesn't match the certificate!");
|
Game::SV_KickClientError(client, "XUID doesn't match the certificate!");
|
||||||
|
@ -48,7 +48,7 @@ namespace Components
|
|||||||
std::string compressedList = Utils::Compression::ZLib::Compress(Playlist::CurrentPlaylistBuffer);
|
std::string compressedList = Utils::Compression::ZLib::Compress(Playlist::CurrentPlaylistBuffer);
|
||||||
|
|
||||||
Proto::Party::Playlist list;
|
Proto::Party::Playlist list;
|
||||||
list.set_hash(Utils::Cryptography::JenkinsOneAtATime::Compute(compressedList.data(), compressedList.size()));
|
list.set_hash(Utils::Cryptography::JenkinsOneAtATime::Compute(compressedList));
|
||||||
list.set_buffer(compressedList);
|
list.set_buffer(compressedList);
|
||||||
|
|
||||||
Network::SendCommand(address, "playlistResponse", list.SerializeAsString());
|
Network::SendCommand(address, "playlistResponse", list.SerializeAsString());
|
||||||
@ -72,7 +72,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
// Generate buffer and hash
|
// Generate buffer and hash
|
||||||
std::string compressedData(list.buffer());
|
std::string compressedData(list.buffer());
|
||||||
unsigned int hash = Utils::Cryptography::JenkinsOneAtATime::Compute(compressedData.data(), compressedData.size());
|
unsigned int hash = Utils::Cryptography::JenkinsOneAtATime::Compute(compressedData);
|
||||||
|
|
||||||
//Validate hashes
|
//Validate hashes
|
||||||
if (hash != list.hash())
|
if (hash != list.hash())
|
||||||
|
@ -323,6 +323,16 @@ namespace Components
|
|||||||
|
|
||||||
// developer_Script 1
|
// developer_Script 1
|
||||||
Utils::Hook::Set<bool>(0x60AE2B, true);
|
Utils::Hook::Set<bool>(0x60AE2B, true);
|
||||||
|
|
||||||
|
// Constantly draw the mini console
|
||||||
|
Utils::Hook::Set<BYTE>(0x412A45, 0xEB);
|
||||||
|
Renderer::OnFrame([] ()
|
||||||
|
{
|
||||||
|
if (*reinterpret_cast<Game::Font**>(0x62E4BAC))
|
||||||
|
{
|
||||||
|
Game::Con_DrawMiniConsole(0, 2, 4, (Game::CL_IsCgameInitialized() ? 1.0f : 0.4f));
|
||||||
|
}
|
||||||
|
});
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,9 +117,7 @@ namespace Components
|
|||||||
info.Set("shortversion", VERSION_STR);
|
info.Set("shortversion", VERSION_STR);
|
||||||
info.Set("mapname", Dvar::Var("mapname").Get<const char*>());
|
info.Set("mapname", Dvar::Var("mapname").Get<const char*>());
|
||||||
info.Set("isPrivate", (Dvar::Var("g_password").Get<std::string>().empty() ? "0" : "1"));
|
info.Set("isPrivate", (Dvar::Var("g_password").Get<std::string>().empty() ? "0" : "1"));
|
||||||
|
info.Set("checksum", Utils::VA("%X", Utils::Cryptography::JenkinsOneAtATime::Compute(Utils::VA("%u", Game::Com_Milliseconds()))));
|
||||||
std::string time = Utils::VA("%u", Game::Com_Milliseconds());
|
|
||||||
info.Set("checksum", Utils::VA("%X", Utils::Cryptography::JenkinsOneAtATime::Compute(time.data(), time.size())));
|
|
||||||
|
|
||||||
// Ensure mapname is set
|
// Ensure mapname is set
|
||||||
if (info.Get("mapname").empty())
|
if (info.Get("mapname").empty())
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Components
|
namespace Components
|
||||||
{
|
{
|
||||||
|
Utils::Memory::Allocator StringTable::MemAllocator;
|
||||||
std::map<std::string, Game::StringTable*> StringTable::StringTableMap;
|
std::map<std::string, Game::StringTable*> StringTable::StringTableMap;
|
||||||
|
|
||||||
int StringTable::Hash(const char* data)
|
int StringTable::Hash(const char* data)
|
||||||
@ -27,19 +28,18 @@ namespace Components
|
|||||||
{
|
{
|
||||||
Utils::CSV parsedTable(rawTable.GetBuffer(), false, false);
|
Utils::CSV parsedTable(rawTable.GetBuffer(), false, false);
|
||||||
|
|
||||||
table = Utils::Memory::AllocateArray<Game::StringTable>(1);
|
table = StringTable::MemAllocator.AllocateArray<Game::StringTable>(1);
|
||||||
|
|
||||||
if (table)
|
if (table)
|
||||||
{
|
{
|
||||||
table->name = Utils::Memory::DuplicateString(filename);
|
table->name = StringTable::MemAllocator.DuplicateString(filename);
|
||||||
table->columnCount = parsedTable.GetColumns();
|
table->columnCount = parsedTable.GetColumns();
|
||||||
table->rowCount = parsedTable.GetRows();
|
table->rowCount = parsedTable.GetRows();
|
||||||
|
|
||||||
table->values = Utils::Memory::AllocateArray<Game::StringTableCell>(table->columnCount * table->rowCount);
|
table->values = StringTable::MemAllocator.AllocateArray<Game::StringTableCell>(table->columnCount * table->rowCount);
|
||||||
|
|
||||||
if (!table->values)
|
if (!table->values)
|
||||||
{
|
{
|
||||||
Utils::Memory::Free(table);
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ namespace Components
|
|||||||
{
|
{
|
||||||
Game::StringTableCell* cell = &table->values[i * table->columnCount + j];
|
Game::StringTableCell* cell = &table->values[i * table->columnCount + j];
|
||||||
cell->hash = StringTable::Hash(parsedTable.GetElementAt(i, j).data());
|
cell->hash = StringTable::Hash(parsedTable.GetElementAt(i, j).data());
|
||||||
cell->string = Utils::Memory::DuplicateString(parsedTable.GetElementAt(i, j));
|
cell->string = StringTable::MemAllocator.DuplicateString(parsedTable.GetElementAt(i, j));
|
||||||
//if (!cell->string) cell->string = ""; // We have to assume it allocated successfully
|
//if (!cell->string) cell->string = ""; // We have to assume it allocated successfully
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,28 +86,7 @@ namespace Components
|
|||||||
|
|
||||||
StringTable::~StringTable()
|
StringTable::~StringTable()
|
||||||
{
|
{
|
||||||
for (auto i = StringTable::StringTableMap.begin(); i != StringTable::StringTableMap.end(); ++i)
|
|
||||||
{
|
|
||||||
Game::StringTable* table = i->second;
|
|
||||||
if (table)
|
|
||||||
{
|
|
||||||
if (table->values)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < table->rowCount * table->columnCount; ++j)
|
|
||||||
{
|
|
||||||
if (table->values[j].string)
|
|
||||||
{
|
|
||||||
Utils::Memory::Free(table->values[j].string);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Utils::Memory::Free(table->values);
|
|
||||||
}
|
|
||||||
|
|
||||||
Utils::Memory::Free(table);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StringTable::StringTableMap.clear();
|
StringTable::StringTableMap.clear();
|
||||||
|
StringTable::MemAllocator.Free();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ namespace Components
|
|||||||
const char* GetName() { return "StringTable"; };
|
const char* GetName() { return "StringTable"; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static Utils::Memory::Allocator MemAllocator;
|
||||||
static std::map<std::string, Game::StringTable*> StringTableMap;
|
static std::map<std::string, Game::StringTable*> StringTableMap;
|
||||||
|
|
||||||
static int Hash(const char* data);
|
static int Hash(const char* data);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Components
|
namespace Components
|
||||||
{
|
{
|
||||||
StructuredData* StructuredData::Singleton = nullptr;
|
Utils::Memory::Allocator StructuredData::MemAllocator;
|
||||||
|
|
||||||
const char* StructuredData::EnumTranslation[ENUM_MAX] =
|
const char* StructuredData::EnumTranslation[ENUM_MAX] =
|
||||||
{
|
{
|
||||||
@ -43,7 +43,7 @@ namespace Components
|
|||||||
unsigned int indexCount = dataEnum->numIndices + entries.size();
|
unsigned int indexCount = dataEnum->numIndices + entries.size();
|
||||||
|
|
||||||
// Allocate new entries
|
// Allocate new entries
|
||||||
Game::StructuredDataEnumEntry* indices = StructuredData::GetSingleton()->MemAllocator.AllocateArray<Game::StructuredDataEnumEntry>(indexCount);
|
Game::StructuredDataEnumEntry* indices = StructuredData::MemAllocator.AllocateArray<Game::StructuredDataEnumEntry>(indexCount);
|
||||||
memcpy(indices, dataEnum->indices, sizeof(Game::StructuredDataEnumEntry) * dataEnum->numIndices);
|
memcpy(indices, dataEnum->indices, sizeof(Game::StructuredDataEnumEntry) * dataEnum->numIndices);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < entries.size(); ++i)
|
for (unsigned int i = 0; i < entries.size(); ++i)
|
||||||
@ -71,7 +71,7 @@ namespace Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
indices[pos].index = i + lastIndex;
|
indices[pos].index = i + lastIndex;
|
||||||
indices[pos].key = StructuredData::GetSingleton()->MemAllocator.DuplicateString(entries[i]);
|
indices[pos].key = StructuredData::MemAllocator.DuplicateString(entries[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply our patches
|
// Apply our patches
|
||||||
@ -79,23 +79,11 @@ namespace Components
|
|||||||
dataEnum->indices = indices;
|
dataEnum->indices = indices;
|
||||||
}
|
}
|
||||||
|
|
||||||
StructuredData* StructuredData::GetSingleton()
|
|
||||||
{
|
|
||||||
if (!StructuredData::Singleton)
|
|
||||||
{
|
|
||||||
Logger::Error("StructuredData singleton is null!");
|
|
||||||
}
|
|
||||||
|
|
||||||
return StructuredData::Singleton;
|
|
||||||
}
|
|
||||||
|
|
||||||
StructuredData::StructuredData()
|
StructuredData::StructuredData()
|
||||||
{
|
{
|
||||||
// Only execute this when building zones
|
// Only execute this when building zones
|
||||||
if (!ZoneBuilder::IsEnabled()) return;
|
if (!ZoneBuilder::IsEnabled()) return;
|
||||||
|
|
||||||
StructuredData::Singleton = this;
|
|
||||||
|
|
||||||
AssetHandler::OnLoad([] (Game::XAssetType type, Game::XAssetHeader asset, std::string filename, bool* restrict)
|
AssetHandler::OnLoad([] (Game::XAssetType type, Game::XAssetHeader asset, std::string filename, bool* restrict)
|
||||||
{
|
{
|
||||||
// Only intercept playerdatadef loading
|
// Only intercept playerdatadef loading
|
||||||
@ -169,7 +157,7 @@ namespace Components
|
|||||||
if (patchDefinitions.empty()) return;
|
if (patchDefinitions.empty()) return;
|
||||||
|
|
||||||
// Reallocate the definition
|
// Reallocate the definition
|
||||||
Game::StructuredDataDef* newData = StructuredData::GetSingleton()->MemAllocator.AllocateArray<Game::StructuredDataDef>(data->count + patchDefinitions.size());
|
Game::StructuredDataDef* newData = StructuredData::MemAllocator.AllocateArray<Game::StructuredDataDef>(data->count + patchDefinitions.size());
|
||||||
memcpy(&newData[patchDefinitions.size()], data->data, sizeof Game::StructuredDataDef * data->count);
|
memcpy(&newData[patchDefinitions.size()], data->data, sizeof Game::StructuredDataDef * data->count);
|
||||||
|
|
||||||
// Prepare the buffers
|
// Prepare the buffers
|
||||||
@ -179,7 +167,7 @@ namespace Components
|
|||||||
newData[i].version = (patchDefinitions.size() - i) + 155;
|
newData[i].version = (patchDefinitions.size() - i) + 155;
|
||||||
|
|
||||||
// Reallocate the enum array
|
// Reallocate the enum array
|
||||||
Game::StructuredDataEnum* newEnums = StructuredData::GetSingleton()->MemAllocator.AllocateArray<Game::StructuredDataEnum>(data->data->numEnums);
|
Game::StructuredDataEnum* newEnums = StructuredData::MemAllocator.AllocateArray<Game::StructuredDataEnum>(data->data->numEnums);
|
||||||
memcpy(newEnums, data->data->enums, sizeof Game::StructuredDataEnum * data->data->numEnums);
|
memcpy(newEnums, data->data->enums, sizeof Game::StructuredDataEnum * data->data->numEnums);
|
||||||
newData[i].enums = newEnums;
|
newData[i].enums = newEnums;
|
||||||
}
|
}
|
||||||
@ -220,6 +208,6 @@ namespace Components
|
|||||||
|
|
||||||
StructuredData::~StructuredData()
|
StructuredData::~StructuredData()
|
||||||
{
|
{
|
||||||
StructuredData::Singleton = nullptr;
|
StructuredData::MemAllocator.Free();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,11 +27,7 @@ namespace Components
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static void PatchPlayerDataEnum(Game::StructuredDataDef* data, PlayerDataType type, std::vector<std::string>& entries);
|
static void PatchPlayerDataEnum(Game::StructuredDataDef* data, PlayerDataType type, std::vector<std::string>& entries);
|
||||||
static StructuredData* GetSingleton();
|
static Utils::Memory::Allocator MemAllocator;
|
||||||
|
|
||||||
Utils::Memory::Allocator MemAllocator;
|
|
||||||
|
|
||||||
static StructuredData* Singleton;
|
|
||||||
|
|
||||||
static const char* EnumTranslation[ENUM_MAX];
|
static const char* EnumTranslation[ENUM_MAX];
|
||||||
};
|
};
|
||||||
|
@ -24,5 +24,8 @@ namespace Components
|
|||||||
Utils::Hook::Nop(0x408228, 5); // find asset header
|
Utils::Hook::Nop(0x408228, 5); // find asset header
|
||||||
Utils::Hook::Nop(0x408230, 5); // is asset default
|
Utils::Hook::Nop(0x408230, 5); // is asset default
|
||||||
Utils::Hook::Nop(0x40823A, 2); // jump
|
Utils::Hook::Nop(0x40823A, 2); // jump
|
||||||
|
|
||||||
|
// Skip double loading for fs_game
|
||||||
|
Utils::Hook::Set<BYTE>(0x4081FD, 0xEB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,8 @@ namespace Game
|
|||||||
Com_Milliseconds_t Com_Milliseconds = (Com_Milliseconds_t)0x42A660;
|
Com_Milliseconds_t Com_Milliseconds = (Com_Milliseconds_t)0x42A660;
|
||||||
Com_ParseExt_t Com_ParseExt = (Com_ParseExt_t)0x474D60;
|
Com_ParseExt_t Com_ParseExt = (Com_ParseExt_t)0x474D60;
|
||||||
|
|
||||||
|
Con_DrawMiniConsole_t Con_DrawMiniConsole = (Con_DrawMiniConsole_t)0x464F30;
|
||||||
|
|
||||||
DB_EnumXAssets_t DB_EnumXAssets = (DB_EnumXAssets_t)0x4B76D0;
|
DB_EnumXAssets_t DB_EnumXAssets = (DB_EnumXAssets_t)0x4B76D0;
|
||||||
DB_FindXAssetHeader_t DB_FindXAssetHeader = (DB_FindXAssetHeader_t)0x407930;
|
DB_FindXAssetHeader_t DB_FindXAssetHeader = (DB_FindXAssetHeader_t)0x407930;
|
||||||
DB_GetXAssetNameHandler_t* DB_GetXAssetNameHandlers = (DB_GetXAssetNameHandler_t*)0x799328;
|
DB_GetXAssetNameHandler_t* DB_GetXAssetNameHandlers = (DB_GetXAssetNameHandler_t*)0x799328;
|
||||||
|
@ -45,6 +45,9 @@ namespace Game
|
|||||||
typedef char* (__cdecl * Com_ParseExt_t)(const char **data_p);
|
typedef char* (__cdecl * Com_ParseExt_t)(const char **data_p);
|
||||||
extern Com_ParseExt_t Com_ParseExt;
|
extern Com_ParseExt_t Com_ParseExt;
|
||||||
|
|
||||||
|
typedef char* (__cdecl * Con_DrawMiniConsole_t)(int localClientNum, int xPos, int yPos, float alpha);
|
||||||
|
extern Con_DrawMiniConsole_t Con_DrawMiniConsole;
|
||||||
|
|
||||||
typedef void(__cdecl * DB_EnumXAssets_t)(XAssetType type, void(*)(XAssetHeader, void *), void* userdata, bool overrides);
|
typedef void(__cdecl * DB_EnumXAssets_t)(XAssetType type, void(*)(XAssetHeader, void *), void* userdata, bool overrides);
|
||||||
extern DB_EnumXAssets_t DB_EnumXAssets;
|
extern DB_EnumXAssets_t DB_EnumXAssets;
|
||||||
|
|
||||||
|
@ -167,6 +167,11 @@ namespace Utils
|
|||||||
|
|
||||||
#pragma region JenkinsOneAtATime
|
#pragma region JenkinsOneAtATime
|
||||||
|
|
||||||
|
unsigned int JenkinsOneAtATime::Compute(std::string data)
|
||||||
|
{
|
||||||
|
return JenkinsOneAtATime::Compute(data.data(), data.size());
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int JenkinsOneAtATime::Compute(const char *key, size_t len)
|
unsigned int JenkinsOneAtATime::Compute(const char *key, size_t len)
|
||||||
{
|
{
|
||||||
unsigned int hash, i;
|
unsigned int hash, i;
|
||||||
|
@ -300,6 +300,7 @@ namespace Utils
|
|||||||
class JenkinsOneAtATime
|
class JenkinsOneAtATime
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static unsigned int Compute(std::string data);
|
||||||
static unsigned int Compute(const char *key, size_t len);
|
static unsigned int Compute(const char *key, size_t len);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ namespace Utils
|
|||||||
{
|
{
|
||||||
void* data = new char[length];
|
void* data = new char[length];
|
||||||
|
|
||||||
|
assert(data != nullptr);
|
||||||
|
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
ZeroMemory(data, length);
|
ZeroMemory(data, length);
|
||||||
@ -23,7 +25,10 @@ namespace Utils
|
|||||||
|
|
||||||
void Memory::Free(void* data)
|
void Memory::Free(void* data)
|
||||||
{
|
{
|
||||||
delete[] data;
|
if (data)
|
||||||
|
{
|
||||||
|
delete[] data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Memory::Free(const void* data)
|
void Memory::Free(const void* data)
|
||||||
|
@ -14,6 +14,11 @@ namespace Utils
|
|||||||
this->RefMemory.clear();
|
this->RefMemory.clear();
|
||||||
}
|
}
|
||||||
~Allocator()
|
~Allocator()
|
||||||
|
{
|
||||||
|
this->Free();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Free()
|
||||||
{
|
{
|
||||||
for (auto i = this->RefMemory.begin(); i != this->RefMemory.end(); ++i)
|
for (auto i = this->RefMemory.begin(); i != this->RefMemory.end(); ++i)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user