clean up api related functions, and change version to 1.3
This commit is contained in:
parent
8834f75f63
commit
4d1f8fe244
@ -121,7 +121,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
@ -165,19 +165,15 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\bo2plugin_test - Copy\framework.h" />
|
||||
<ClInclude Include="functions.h" />
|
||||
<ClInclude Include="framework.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="SimpleIni.h" />
|
||||
<ClInclude Include="utils\hook.hpp" />
|
||||
<ClInclude Include="utils\memory.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="functions.cpp" />
|
||||
<ClCompile Include="utils\hook.cpp" />
|
||||
<ClCompile Include="utils\memory.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
@ -18,12 +18,6 @@
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="framework.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pch.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\bo2plugin_test - Copy\framework.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@ -33,15 +27,24 @@
|
||||
<ClInclude Include="SimpleIni.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="utils\hook.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="utils\memory.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<ClCompile Include="functions.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="functions.cpp">
|
||||
<ClCompile Include="utils\hook.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="utils\memory.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
|
11
dllmain.cpp
11
dllmain.cpp
@ -1,4 +1,4 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
@ -7,16 +7,17 @@
|
||||
#include <cstdlib>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
HMODULE LogHandle;
|
||||
|
||||
|
||||
|
||||
void init()
|
||||
{
|
||||
|
||||
std::cout << "ClanTagRank (1.2) by INSANEMODE\n";
|
||||
std::cout << "loaded iw4m-admin url from .\\Plugins\\GetClanTag.ini: " << Game::configfile() << '\n';
|
||||
std::thread rank(Game::clanTagThread);
|
||||
rank.detach();
|
||||
std::cout << "ClanTagRank (1.3) by INSANEMODE\n";
|
||||
|
||||
std::thread addcommands(Game::addCommands);
|
||||
addcommands.detach();
|
||||
}
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule,
|
||||
|
169
functions.cpp
169
functions.cpp
@ -1,4 +1,4 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
@ -10,145 +10,84 @@
|
||||
#include "curl\curl.h"
|
||||
#include "simpleini.h"
|
||||
#include <filesystem>
|
||||
#define GetCurrentDir _getcwd
|
||||
#include "utils/hook.hpp"
|
||||
#include "utils/memory.hpp"
|
||||
#include <functional>
|
||||
#include "functions.h"
|
||||
|
||||
utils::memory::allocator allocator;
|
||||
|
||||
std::function<void(const std::string& code)> callback;
|
||||
|
||||
int clientAddr{ 0x02347D10 - 0x57F8 };// check for client GUID instead of name
|
||||
int clientNameAddr{ 0x02347cd4 - 0x57F8 };
|
||||
int clanTagAddr{ 0x30 };
|
||||
int clientOffset{ 0x57F8 };
|
||||
|
||||
namespace Game
|
||||
|
||||
{
|
||||
static Cmd_AddCommand_t Cmd_AddCommand = Cmd_AddCommand_t(0x004DC2A0);
|
||||
static Cmd_Argv_t Cmd_Argv = (Cmd_Argv_t)0x006B3D40;
|
||||
|
||||
std::string configfile()
|
||||
void clanTagChanger_guid(unsigned int guid, std::string rank)
|
||||
{
|
||||
|
||||
|
||||
CSimpleIniA ini;
|
||||
|
||||
std::string currentpath = std::filesystem::current_path().generic_string();
|
||||
std::string configfile = currentpath + (R"(/t6r/data/plugins/GetClanTag.ini)");
|
||||
SI_Error rc = ini.LoadFile(configfile.c_str());
|
||||
//SI_Error rc = ini.LoadFile("\\t6r\\data\\plugins\\GetClanTag.ini");
|
||||
if (rc < 0)
|
||||
{
|
||||
ini.SetValue("Config", "URL", "127.0.0.1:1624");
|
||||
ini.SaveFile(configfile.c_str());
|
||||
};
|
||||
const char* pVal = ini.GetValue("Config", "URL", "http://127.0.0.1:1624");
|
||||
return pVal;
|
||||
}
|
||||
|
||||
|
||||
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp)
|
||||
{
|
||||
((std::string*)userp)->append((char*)contents, size * nmemb);
|
||||
return size * nmemb;
|
||||
}
|
||||
std::string testcurl(unsigned int clientguid)
|
||||
{
|
||||
std::string guidstring = std::to_string(clientguid);
|
||||
//std::cout << "guid string: " + guidstring + '\n';
|
||||
CURL* curl;
|
||||
CURLcode res;
|
||||
std::string readBuffer;
|
||||
curl = curl_easy_init();
|
||||
if (curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, configfile() + "/api/gsc/clientguid/" + guidstring);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
|
||||
/* example.com is redirected, so we tell libcurl to follow redirection */
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if (res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
}
|
||||
return readBuffer;
|
||||
}
|
||||
std::string ClanTagRequest(unsigned int clientguid)
|
||||
{
|
||||
std::string readBuffer;
|
||||
//const char* constClanTag;
|
||||
if (clientguid != 0)
|
||||
{
|
||||
readBuffer = testcurl(clientguid);
|
||||
}
|
||||
readBuffer.erase(std::remove(readBuffer.begin(), readBuffer.end(), '\n'), readBuffer.end());
|
||||
readBuffer.erase(std::remove(readBuffer.begin(), readBuffer.end(), '\r'), readBuffer.end());
|
||||
|
||||
//readBuffer contains the rank that will be put into the clan tag of the client with the requested username
|
||||
return readBuffer;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
void clanTagChanger()
|
||||
{
|
||||
|
||||
|
||||
unsigned int clientguid{};
|
||||
char emptyname[16]{};
|
||||
char currentname[16]{};
|
||||
std::string currentname_str;
|
||||
char currentClanTag[8]{};
|
||||
const char* changeClanTag{};
|
||||
std::string changeClanTag_str;
|
||||
|
||||
|
||||
|
||||
int clientAddr{ 0x02347D10 - 0x57F8 };// check for client GUID instead of name
|
||||
int clientNameAddr{ 0x02347cd4 - 0x57F8 };
|
||||
int clanTagAddr{ 0x30 };
|
||||
int clientOffset{ 0x57F8 };
|
||||
|
||||
//loop through clients to get their name and current clan tag.
|
||||
//loop through clients to get their guid
|
||||
for (int i = 1; i < 9; i++)
|
||||
{
|
||||
memcpy(&clientguid, (void*)((clientAddr + (clientOffset * i))), 4);
|
||||
memcpy(¤tname, (void*)((clientNameAddr + (clientOffset * i))), 16);
|
||||
//currentname_str = std::string(currentname, 16);
|
||||
memcpy((void*)currentClanTag, (void*)(((clientAddr +(clientOffset * i)) + clanTagAddr)), 8);
|
||||
//std::cout << "guid uint: " + clientguid << '\n';
|
||||
|
||||
//if ((strstr(currentClanTag, "Creator") == NULL) && (strstr(currentClanTag, "Admin") == NULL) && (strstr(currentClanTag, "SrAdmin") == NULL) && (strstr(currentClanTag, "Trusted") == NULL) && (strstr(currentClanTag, "Mod") == NULL) && (strstr(currentClanTag, "Owner") == NULL) && (strstr(currentClanTag, "3arc") == NULL) && (clientguid > 0) && (clientguid != NULL))
|
||||
if (!*currentClanTag && (clientguid > 0) && (clientguid != NULL))
|
||||
if (clientguid == guid)
|
||||
{
|
||||
changeClanTag_str = ClanTagRequest(clientguid);
|
||||
|
||||
changeClanTag = changeClanTag_str.c_str();
|
||||
if ((strstr(currentClanTag, changeClanTag) == NULL) || (strstr(changeClanTag, "Error: Client info is null") == NULL))
|
||||
{
|
||||
|
||||
if(!(changeClanTag_str.find("Error:") != std::string::npos)) //&& !(changeClanTag_str.find("User") != std::string::npos))
|
||||
{
|
||||
std::cout << "ClanTag Rank: [" + changeClanTag_str + "]" + currentname + '\n';
|
||||
memcpy((void*)(clientAddr + (clientOffset * i) + clanTagAddr), changeClanTag, 8);
|
||||
|
||||
}
|
||||
changeClanTag = rank.c_str();
|
||||
memcpy((void*)(clientAddr + (clientOffset * i) + clanTagAddr), changeClanTag, 8);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void clanTagThread()
|
||||
//
|
||||
void clanTagChanger_slot(int slot, std::string rank)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
configfile();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10000));
|
||||
clanTagChanger();
|
||||
}
|
||||
|
||||
const char* changeClanTag{rank.c_str()};
|
||||
slot += 1;
|
||||
//loop through clients to get their guid
|
||||
memcpy((void*)(clientAddr + (clientOffset * slot) + clanTagAddr), changeClanTag, 8);
|
||||
}
|
||||
|
||||
void setrank_guid()
|
||||
{
|
||||
std::string::size_type sz; // alias of size_t
|
||||
unsigned int guid = std::stoi(Cmd_Argv(1), &sz);
|
||||
clanTagChanger_guid(guid, Cmd_Argv(2));
|
||||
|
||||
}
|
||||
void setrank()
|
||||
{
|
||||
std::string::size_type sz; // alias of size_t
|
||||
int client_slot = std::stoi(Cmd_Argv(1), &sz);
|
||||
clanTagChanger_slot(client_slot, Cmd_Argv(2));
|
||||
|
||||
}
|
||||
void addCommands()
|
||||
{
|
||||
//std::this_thread::sleep_for(std::chrono::milliseconds(15000));
|
||||
const auto cmd_function = allocator.allocate<cmd_function_t>();
|
||||
const auto cmd_function_2 = allocator.allocate<cmd_function_t>();
|
||||
|
||||
Cmd_AddCommand("setrank", setrank, cmd_function);
|
||||
Cmd_AddCommand("setrank_guid", setrank_guid, cmd_function_2);
|
||||
//Cmd_AddCommand("commandtest", commandtest);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
24
functions.h
24
functions.h
@ -1,10 +1,26 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
|
||||
|
||||
HMODULE LogHandle;
|
||||
|
||||
namespace Game
|
||||
{
|
||||
//void Testprint();
|
||||
void clanTagThread();
|
||||
std::string configfile();
|
||||
|
||||
void addCommands();
|
||||
|
||||
struct cmd_function_t
|
||||
{
|
||||
cmd_function_t* next;
|
||||
const char* name;
|
||||
const char* autoCompleteDir;
|
||||
const char* autoCompleteExt;
|
||||
void(__cdecl* function)();
|
||||
int flags;
|
||||
};
|
||||
|
||||
|
||||
typedef void (*Cmd_AddCommand_t)(const char* cmdName, void (*function)(), cmd_function_t* allocedCmd);
|
||||
extern Cmd_AddCommand_t Cmd_AddCommand;
|
||||
|
||||
typedef char* (*Cmd_Argv_t)(int arg);
|
||||
}
|
||||
|
15
utils/hook.cpp
Normal file
15
utils/hook.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
|
||||
//#include "../pch.h"
|
||||
#include <windows.h>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
#include <mutex>
|
||||
|
||||
|
||||
namespace utils::hook
|
||||
{
|
||||
void* allocate_stub_memory(size_t size)
|
||||
{
|
||||
return VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||
}
|
||||
}
|
150
utils/hook.hpp
Normal file
150
utils/hook.hpp
Normal file
@ -0,0 +1,150 @@
|
||||
#pragma once
|
||||
|
||||
// stolen from plutoscript
|
||||
|
||||
namespace utils::hook
|
||||
{
|
||||
void* allocate_stub_memory(size_t size);
|
||||
|
||||
template<typename ValueType, typename AddressType>
|
||||
inline ValueType get(AddressType address)
|
||||
{
|
||||
return *static_cast<ValueType*>(address);
|
||||
}
|
||||
|
||||
template<typename ValueType, typename AddressType>
|
||||
inline void set(AddressType address, ValueType value)
|
||||
{
|
||||
std::memcpy((void*)address, &value, sizeof(value));
|
||||
}
|
||||
|
||||
template<typename ValueType, typename AddressType>
|
||||
inline void set(AddressType address, const ValueType* data, size_t length)
|
||||
{
|
||||
std::memcpy((void*)address, data, sizeof(ValueType) * length);
|
||||
}
|
||||
|
||||
template<typename AddressType>
|
||||
inline void nop(AddressType address, size_t length)
|
||||
{
|
||||
std::memset((void*)address, 0x90, length);
|
||||
}
|
||||
|
||||
template<typename FuncType, typename AddressType>
|
||||
inline void jump(AddressType address, FuncType func)
|
||||
{
|
||||
set<uint8_t>(address, 0xE9);
|
||||
set<uintptr_t>((uintptr_t)address + 1, (uintptr_t)func - (uintptr_t)address - 5);
|
||||
}
|
||||
|
||||
template<typename FuncType, typename AddressType>
|
||||
inline void call(AddressType address, FuncType func)
|
||||
{
|
||||
set<uint8_t>(address, 0xE8);
|
||||
set<int>((uintptr_t)address + 1, (intptr_t)func - (intptr_t)address - 5);
|
||||
}
|
||||
|
||||
template<typename FuncType, typename AddressType>
|
||||
FuncType detour(AddressType target, FuncType hook, const int len)
|
||||
{
|
||||
uintptr_t tampoline = (uintptr_t)allocate_stub_memory(len + 5);
|
||||
|
||||
std::memcpy((void*)tampoline, (void*)target, len);
|
||||
|
||||
set<uint8_t>(tampoline + len, 0xE9);
|
||||
set<int>((uintptr_t)tampoline + len + 1, (intptr_t)target - (intptr_t)tampoline - 5);
|
||||
|
||||
set<uint8_t>(target, 0xE9);
|
||||
set<int>((uintptr_t)target + 1, (intptr_t)hook - (intptr_t)target - 5);
|
||||
|
||||
int pos = len - 5;
|
||||
if (pos > 0) nop((uintptr_t)target + 5, pos);
|
||||
|
||||
return reinterpret_cast<FuncType>(tampoline);
|
||||
}
|
||||
|
||||
namespace vp
|
||||
{
|
||||
template<typename ValueType, typename AddressType>
|
||||
inline void set(AddressType address, ValueType value)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((void*)address, sizeof(value), PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
std::memcpy((void*)address, &value, sizeof(value));
|
||||
|
||||
VirtualProtect((void*)address, sizeof(value), oldProtect, &oldProtect);
|
||||
}
|
||||
|
||||
template<typename ValueType, typename AddressType>
|
||||
inline void set(AddressType address, const ValueType* data, size_t length)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((void*)address, sizeof(ValueType) * length, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
std::memcpy((void*)address, data, sizeof(ValueType) * length);
|
||||
|
||||
VirtualProtect((void*)address, sizeof(ValueType) * length, oldProtect, &oldProtect);
|
||||
}
|
||||
|
||||
template<typename AddressType>
|
||||
inline void nop(AddressType address, size_t length)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((void*)address, length, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
std::memset((void*)address, 0x90, length);
|
||||
|
||||
VirtualProtect((void*)address, length, oldProtect, &oldProtect);
|
||||
}
|
||||
|
||||
template<typename FuncType, typename AddressType>
|
||||
inline void jump(AddressType address, FuncType func)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
hook::set<uint8_t>(address, 0xE9);
|
||||
hook::set<int>((uintptr_t)address + 1, (intptr_t)func - (intptr_t)address - 5);
|
||||
|
||||
VirtualProtect((void*)address, 5, oldProtect, &oldProtect);
|
||||
}
|
||||
|
||||
template<typename FuncType, typename AddressType>
|
||||
inline void call(AddressType address, FuncType func)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
hook::set<uint8_t>(address, 0xE8);
|
||||
hook::set<int>((uintptr_t)address + 1, (intptr_t)func - (intptr_t)address - 5);
|
||||
|
||||
VirtualProtect((void*)address, 5, oldProtect, &oldProtect);
|
||||
}
|
||||
|
||||
template<typename FuncType, typename AddressType>
|
||||
FuncType detour(AddressType target, FuncType hook, const int len)
|
||||
{
|
||||
uintptr_t tampoline = (uintptr_t)allocate_stub_memory(len + 5);
|
||||
|
||||
std::memcpy((void*)tampoline, (void*)target, len);
|
||||
|
||||
hook::set<uint8_t>(tampoline + len, 0xE9);
|
||||
hook::set<int>((uintptr_t)tampoline + len + 1, (intptr_t)target - (intptr_t)tampoline - 5);
|
||||
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((void*)target, len, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
hook::set<uint8_t>(target, 0xE9);
|
||||
hook::set<int>((uintptr_t)target + 1, (intptr_t)hook - (intptr_t)target - 5);
|
||||
|
||||
int pos = len - 5;
|
||||
if (pos > 0) hook::nop((uintptr_t)target + 5, pos);
|
||||
|
||||
VirtualProtect((void*)target, len, oldProtect, &oldProtect);
|
||||
|
||||
return reinterpret_cast<FuncType>(tampoline);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
122
utils/memory.cpp
Normal file
122
utils/memory.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
|
||||
https://github.com/momo5502/open-iw5
|
||||
|
||||
*/
|
||||
//#include "../pch.h"
|
||||
#include <windows.h>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
#include <mutex>
|
||||
#include "memory.hpp"
|
||||
|
||||
|
||||
|
||||
namespace utils
|
||||
{
|
||||
memory::allocator memory::mem_allocator_;
|
||||
|
||||
memory::allocator::~allocator()
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void memory::allocator::clear()
|
||||
{
|
||||
std::lock_guard _(this->mutex_);
|
||||
|
||||
for (auto& data : this->pool_)
|
||||
{
|
||||
memory::free(data);
|
||||
}
|
||||
|
||||
this->pool_.clear();
|
||||
}
|
||||
|
||||
void memory::allocator::free(void* data)
|
||||
{
|
||||
std::lock_guard _(this->mutex_);
|
||||
|
||||
const auto j = std::find(this->pool_.begin(), this->pool_.end(), data);
|
||||
if (j != this->pool_.end())
|
||||
{
|
||||
memory::free(data);
|
||||
this->pool_.erase(j);
|
||||
}
|
||||
}
|
||||
|
||||
void memory::allocator::free(const void* data)
|
||||
{
|
||||
this->free(const_cast<void*>(data));
|
||||
}
|
||||
|
||||
void* memory::allocator::allocate(const size_t length)
|
||||
{
|
||||
std::lock_guard _(this->mutex_);
|
||||
|
||||
const auto data = memory::allocate(length);
|
||||
this->pool_.push_back(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
bool memory::allocator::empty() const
|
||||
{
|
||||
return this->pool_.empty();
|
||||
}
|
||||
|
||||
/*char* memory::allocator::duplicate_string(const std::string& string)
|
||||
{
|
||||
std::lock_guard _(this->mutex_);
|
||||
|
||||
const auto data = memory::duplicate_string(string);
|
||||
this->pool_.push_back(data);
|
||||
return data;
|
||||
}*/
|
||||
|
||||
void* memory::allocate(const size_t length)
|
||||
{
|
||||
const auto data = calloc(length, 1);
|
||||
assert(data != nullptr);
|
||||
return data;
|
||||
}
|
||||
|
||||
/*char* memory::duplicate_string(const std::string& string)
|
||||
{
|
||||
const auto new_string = allocate_array<char>(string.size() + 1);
|
||||
std::memcpy(new_string, string.data(), string.size());
|
||||
return new_string;
|
||||
}*/
|
||||
|
||||
void memory::free(void* data)
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
::free(data);
|
||||
}
|
||||
}
|
||||
|
||||
void memory::free(const void* data)
|
||||
{
|
||||
free(const_cast<void*>(data));
|
||||
}
|
||||
|
||||
bool memory::is_set(const void* mem, const char chr, const size_t length)
|
||||
{
|
||||
const auto mem_arr = static_cast<const char*>(mem);
|
||||
|
||||
for (size_t i = 0; i < length; ++i)
|
||||
{
|
||||
if (mem_arr[i] != chr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
memory::allocator* memory::get_allocator()
|
||||
{
|
||||
return &memory::mem_allocator_;
|
||||
}
|
||||
}
|
76
utils/memory.hpp
Normal file
76
utils/memory.hpp
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
|
||||
https://github.com/momo5502/open-iw5
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
class memory final
|
||||
{
|
||||
public:
|
||||
class allocator final
|
||||
{
|
||||
public:
|
||||
~allocator();
|
||||
|
||||
void clear();
|
||||
|
||||
void free(void* data);
|
||||
|
||||
void free(const void* data);
|
||||
|
||||
void* allocate(size_t length);
|
||||
|
||||
template <typename T>
|
||||
T* allocate()
|
||||
{
|
||||
return this->allocate_array<T>(1);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* allocate_array(const size_t count = 1)
|
||||
{
|
||||
return static_cast<T*>(this->allocate(count * sizeof(T)));
|
||||
}
|
||||
|
||||
bool empty() const;
|
||||
|
||||
//char* duplicate_string(const std::string& string);
|
||||
|
||||
private:
|
||||
std::mutex mutex_;
|
||||
std::vector<void*> pool_;
|
||||
};
|
||||
|
||||
static void* allocate(size_t length);
|
||||
|
||||
template <typename T>
|
||||
static inline T* allocate()
|
||||
{
|
||||
return allocate_array<T>(1);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline T* allocate_array(const size_t count = 1)
|
||||
{
|
||||
return static_cast<T*>(allocate(count * sizeof(T)));
|
||||
}
|
||||
|
||||
//static char* duplicate_string(const std::string& string);
|
||||
|
||||
static void free(void* data);
|
||||
static void free(const void* data);
|
||||
|
||||
static bool is_set(const void* mem, char chr, size_t length);
|
||||
|
||||
static allocator* get_allocator();
|
||||
|
||||
private:
|
||||
static allocator mem_allocator_;
|
||||
};
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user