add kpatch.ini

This commit is contained in:
Kuriko Moe
2025-03-13 17:53:30 +08:00
parent f9a3ea007e
commit b9e5ed10ca
11 changed files with 414 additions and 259 deletions
+26 -1
View File
@@ -10,4 +10,29 @@
由于动态修改代码,请以 -insecure 启动,或者自觉不要进有 vac 的服务器(被 vac 后果自负)
4gb_patch.exe 用于让 left4dead2.exe 最多只能用 2G 内存提高到 4G (32 位系统下内存总计 4G,默认情况下应用只被允许用 2G,剩下的分配给系统)
4gb_patch.exe 用于让 left4dead2.exe 最多只能用 2G 内存提高到 4G (32 位系统下内存总计 4G,默认情况下应用只被允许用 2G,剩下的分配给系统)
配置文件说明:
[System]
debug = false ; 开启调试输出
; Too Many Indices 的上限数值(buffer 大小+ 判断)
[Indices]
enable = true ; 修改too many indices 上限和对应的判断检测。
value = 131072
; dynamic vertex buffer 大小限制(这个修改 buffer 大小)
[DynamicVB]
enable = false ; 修改 dynamic vertex buffer 的大小。
value = 65536
; dynamic vertex buffer 判断限制(这个只修改上限判断)
[GetMaxToRender]
enable = false ; 修改 dynamic vertex buffer 的上限(一般用于判断)。
debug = true
old_value = 32768 ; 映射机制,这里是原值。
new_value = 65536 ; 这里是修改值
+5 -12
View File
@@ -13,12 +13,12 @@ clean:
rm -rf build
build:
xmake f -m testing
xmake f -m release
xmake
copy: build
cp build/windows/x86/testing/kpatch.dll "{{TARGET}}"
cp build/windows/x86/testing/left4dead2_fix.exe "{{TARGET}}"
cp build/windows/x86/release/kpatch.dll "{{TARGET}}"
cp build/windows/x86/release/left4dead2_fix.exe "{{TARGET}}"
copyrel:
xmake f -m release
@@ -28,7 +28,7 @@ copyrel:
release:
rm release -rf
mkdir -p release/testing
mkdir -p release
# release
xmake f -m release
@@ -37,14 +37,7 @@ release:
cp build/windows/x86/release/left4dead2_fix.exe release/
cp assets/请读我.txt release/
cp third/4gb_patch.exe release/
# testing
xmake f -m release.testing
xmake
cp build/windows/x86/release.testing/kpatch.dll release/testing
cp build/windows/x86/release.testing/left4dead2_fix.exe release/testing
cp assets/请读我-自测补丁.txt release/testing
cp third/4gb_patch.exe release/testing
cp kpatch.ini release/
@run:
./build/{{preset}}/bin/{{target}}
+21
View File
@@ -0,0 +1,21 @@
[System]
debug = false
; Too Many Indices 的上限数值(buffer 大小+ 判断)
[Indices]
enable = true
value = 131072
; dynamic vertex buffer 大小限制(这个修改 buffer 大小)
[DynamicVB]
enable = false
value = 65536
; dynamic vertex buffer 判断限制(这个只修改上限判断)
[GetMaxToRender]
enable = false
debug = true
old_value = 32768
new_value = 65536
-6
View File
@@ -27,12 +27,6 @@ int WINAPI wWinMain(
LPCWSTR target_exe_path = game_name;
// if (std::filesystem::exists(L"left4dead2.exe.orig")) {
// target_exe_path = L"left4dead2.exe.orig";
// } else {
// target_exe_path = game_name;
// }
STARTUPINFOW si;
PROCESS_INFORMATION pi;
+17 -221
View File
@@ -3,48 +3,26 @@
#include <spdlog/sinks/basic_file_sink.h>
#include <windows.h>
#include <libloaderapi.h>
#include <cstdint>
#include <cstddef>
#include <iostream>
#include <filesystem>
#include <fstream>
#include <algorithm>
#include <detours/detours.h>
#include <MinHook.h>
#include <inipp.h>
#include "helper.hpp"
#ifdef NDEBUG
constexpr bool isDebug = false;
#else
constexpr bool isDebug = true;
#endif
#include "vars.h"
#ifdef NTESTING
constexpr bool isTesting = false;
constexpr int VERTEX_BUFFER_SIZE = 0x020000;
#else
constexpr bool isTesting = true;
constexpr int VERTEX_BUFFER_SIZE = 32;
#endif
#include "hooks_indices.h"
#include "hooks_dvb.h"
HMODULE baseModule = GetModuleHandle(NULL);
HMODULE thisModule; // Fix DLL
// Version
std::string sFixName = "L4D2Fix";
std::string sFixVer = "1.3.0";
std::string sLogFile = sFixName + ".log";
// Logger
std::shared_ptr<spdlog::logger> logger;
std::filesystem::path sExePath;
std::string sExeName;
std::filesystem::path sThisModulePath;
void InitConsole() {
AllocConsole();
FILE *dummy;
@@ -52,7 +30,7 @@ void InitConsole() {
}
void Logging() {
if constexpr (isDebug) {
if (cfg::System::debug) {
InitConsole();
}
// Get this module path
@@ -75,7 +53,7 @@ void Logging() {
auto start_time = std::chrono::system_clock::now();
if (isDebug) {
if (cfg::System::debug) {
spdlog::set_level(spdlog::level::debug);
}
@@ -99,132 +77,12 @@ void Logging() {
}
using CVertexBufferCtorFn = void* (__thiscall*)(void*, int, int, int, int, int, int, char*, char, char);
CVertexBufferCtorFn oCVertexBufferCtorFn = nullptr;
CVertexBufferCtorFn tCVertexBufferCtorFn = nullptr;
intptr_t nCVertexBufferCtorFn = NULL;
void*__fastcall hCVertexBufferCtorFn(
void* This,
DWORD EDX,
int a2,
int a3,
int a4,
int a5,
int count,
int bufSize,
char * source,
char a6,
char a7)
{
// std::string msg = std::format(
// "This: {:x}, EDX: {:x}, a2: {:x}, a3: {}, a4: {}, a5: {}, count: {}, bufSize: {}, source: {}, a6: {}, a7: {}",
// (intptr_t)This,
// EDX,
// a2, a3, a4, a5,
// count, bufSize,
// source, (int)a6, (int)a7
// );
// spdlog::info(msg);
// MessageBoxW(NULL, L"inside CVertexBufferCtorFn", L"", MB_OK);
if (isDebug) {
return tCVertexBufferCtorFn(This, a2, a3, a4, a5,
count,
32,
source, a6, a7);
}
return tCVertexBufferCtorFn(This, a2, a3, a4, a5,
std::max(1, count * bufSize / VERTEX_BUFFER_SIZE),
VERTEX_BUFFER_SIZE,
source, a6, a7);
}
void __declspec(naked) nakedCVertexBufferCtorFn() {
__asm {
call hCVertexBufferCtorFn
jmp nCVertexBufferCtorFn
};
}
using GetMaxToRenderFn = int (__thiscall*)(void*, DWORD*, char, int*, int*);
GetMaxToRenderFn oGetMaxToRender = nullptr;
int __fastcall hGetMaxToRender(
void* This,
DWORD EDX,
DWORD* a2,
char a3,
int* p_bufsize,
int* p_nCount
) {
auto ret = oGetMaxToRender(This, a2, a3, p_bufsize, p_nCount);
// spdlog::debug("p_bufSize: {} {:x}, p_nCount: {} {:x}", *p_bufsize, *p_bufsize, *p_nCount, *p_nCount);
if (*p_bufsize == 32768) *p_bufsize = VERTEX_BUFFER_SIZE;
return ret;
}
bool fixDynamicVB(HMODULE hDll) {
const char* pat = "0F B6 C8 8B 45 10 51 8B 4D FC 99 68 ?? ?? ?? ?? 68 00 80 00 00";
size_t offset_imm = 0xe13b - 0xe12a;
size_t offset_call = 0xe152 - 0xe12a;
std::uint8_t* ptr = Memory::PatternScan(hDll, pat, 0);
if (ptr == nullptr) {
spdlog::info(L"Can not find the DynamicVB call");
return false;
}
spdlog::info(L"Hook DynamicVB Call success");
ptr += offset_call;
spdlog::info(L"Modified the DynamicVB call @ 0x{:0x}", (intptr_t)ptr - (intptr_t)hDll);
oCVertexBufferCtorFn = reinterpret_cast<CVertexBufferCtorFn>(ptr);
nCVertexBufferCtorFn = reinterpret_cast<intptr_t>(ptr) + 0x5;
// copy the target address, call is followed by an relative address
const char* pat_GameCVertexBufferCtor = "55 8B EC 81 EC 08 01 00 00 A1 ?? ?? ?? ?? 33 C5 89 45 FC 53 56 57 8B 45 08 8B 55 10";
std::uint8_t* ptr_GameCVertexBufferCtor = Memory::PatternScan(hDll, pat_GameCVertexBufferCtor, 0);
if (ptr_GameCVertexBufferCtor == nullptr) {
spdlog::info(L"Can not find the GameCVertexBufferCtor");
return false;
}
tCVertexBufferCtorFn = reinterpret_cast<CVertexBufferCtorFn>(ptr_GameCVertexBufferCtor);
spdlog::info(L"Hook GameCVertexBufferCtor success");
const char* pat_GetMaxToRender = "55 8B EC 57 8B 7D 08 85 FF 75 ?? 8B 45 10 89 38";
std::uint8_t* ptr_GetMaxToRender = Memory::PatternScan(hDll, pat_GetMaxToRender, 0);
oGetMaxToRender = reinterpret_cast<GetMaxToRenderFn>(ptr_GetMaxToRender);
if (oGetMaxToRender == nullptr) {
spdlog::info(L"Can not find the GetMaxToRender");
return false;
}
spdlog::info(L"Hook GetMaxToRender success");
// Only for debugging
// Memory::Write((uintptr_t)hDll + 0xbb67, (uint16_t)0x9090);
DetourRestoreAfterWith();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)oCVertexBufferCtorFn, nakedCVertexBufferCtorFn);
DetourAttach(&(PVOID&)oGetMaxToRender, hGetMaxToRender);
DetourTransactionCommit();
spdlog::info(L"New DynamicVB call to 0x{:0x}", (intptr_t)oCVertexBufferCtorFn);
return true;
}
DWORD __stdcall Main(void*) {
LoadIni();
Logging();
if constexpr (isTesting) {
MessageBoxW(NULL, L"警告:这是测试版补丁,设定为必定会炸,用于检测补丁是否正确应用。", L"L4D2 Fix", MB_OK|MB_SYSTEMMODAL|MB_ICONWARNING);
if (cfg::System::debug) {
MessageBoxW(NULL, L"警告:你已开启 debug 输出。", L"L4D2 Fix", MB_OK|MB_SYSTEMMODAL|MB_ICONWARNING);
}
std::filesystem::path startup_check = L"success.txt";
@@ -248,6 +106,8 @@ DWORD __stdcall Main(void*) {
spdlog::info(L"Detected Vulkan: using {}", dllName);
isVulkan = true;
} else {
// Preload d3d9.dll
LoadLibraryW(L"d3d9.dll");
spdlog::info(L"Detected DirectX9: using {}", dllName);
}
@@ -272,84 +132,20 @@ DWORD __stdcall Main(void*) {
exit(-1);
}
// Tag, pattern, start_search_path, write_offset
auto f = [&](const wchar_t* tag, const char* pattern, size_t offset, size_t w_offset) {
std::uint8_t* ptr = Memory::PatternScan(hDll, pattern, offset);
uint32_t new_buffer_size = VERTEX_BUFFER_SIZE;
// uint32_t new_buffer_size = 0x020000;
if (ptr != nullptr) {
Memory::Write((uintptr_t)(ptr + w_offset), new_buffer_size);
spdlog::info(L"Modified the vertex max buffer {}: {} @ 0x{:0x}", dllName, tag, (intptr_t)(ptr) - (intptr_t)hDll);
return ptr;
}
spdlog::error(L"Pattern scan failed for {}: {}", dllName, tag);
return (uint8_t*)nullptr;
};
std::vector<void*> ptr_cache;
std::string pattern;
// CreateEmptyColorMesh
pattern = "68 ?? ?? ?? ?? 68 00 80 00 00 6A 04";
auto* ptr1 = f(
L"CreateEmptyColorMesh",
pattern.c_str(),
0,
6
);
ptr_cache.push_back(ptr1);
pattern = "68 00 80 00 00 50 8B";
auto* ptr1_1 = f(
L"CreateEmptyColorMesh Later",
pattern.c_str(),
(size_t)ptr1,
1
);
ptr_cache.push_back(ptr1_1);
// CreateVertexIDBuffer
pattern = "68 ?? ?? ?? ?? 68 00 80 00 00 6A 04";
auto* ptr2 = f(
L"CreateVertexIDBuffer",
pattern.c_str(),
(size_t)ptr1_1,
6
);
ptr_cache.push_back(ptr2);
pattern = "68 00 80 00 00 50 8B";
auto* ptr2_1 = f(
L"CreateVertexIDBuffer Later",
pattern.c_str(),
(size_t)ptr2,
1
);
ptr_cache.push_back(ptr2_1);
auto* ptr3 = f(
L"Unknown",
"0F B6 C0 50 68 00 80 00 00 53 8B CF E8 ?? ?? ?? ??",
(size_t)ptr2,
5
);
ptr_cache.push_back(ptr3);
// Not known
auto ret = fixDynamicVB(hDll);
auto ret = 0;
ret += PatchIndices(hDll, dllName);
ret += hooks_dvb(hDll, dllName);
if (!ret || std::ranges::any_of(ptr_cache, [](void* ptr) { return ptr == nullptr; })) {
if (ret != 0) {
MessageBoxW(NULL, L"未能正常应用补丁,patch 未生效,请联系开发者\n这只是一个警告,可能不影响游戏运行", L"L4D2 Fix", MB_OK);
} else {
std::fstream file(startup_check, std::ios::out);
file << "补丁已生效,关闭启动提示,删除本文件可以重新启用" << std::endl;
}
return true;
return TRUE;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
+2
View File
@@ -1,3 +1,5 @@
#pragma once
#include <cassert>
#include <windows.h>
#include <cstdint>
+167
View File
@@ -0,0 +1,167 @@
#pragma once
#define SPDLOG_WCHAR_TO_UTF8_SUPPORT
#include <spdlog/spdlog.h>
#include <spdlog/sinks/basic_file_sink.h>
#include <windows.h>
#include <iostream>
#include <format>
#include <string>
#include <detours/detours.h>
#include "inipp.h"
#include "helper.hpp"
#include "vars.h"
// ---------------------------------------------------------------------------------
using CVertexBufferCtorFn = void* (__thiscall*)(void*, int, int, int, int, int, int, char*, char, char);
CVertexBufferCtorFn oCVertexBufferCtorFn = nullptr;
CVertexBufferCtorFn tCVertexBufferCtorFn = nullptr;
intptr_t nCVertexBufferCtorFn = NULL;
void*__fastcall hCVertexBufferCtorFn(
void* This, DWORD EDX,
int a2, int a3, int a4, int a5,
int count, int bufSize,
char * source, char a6, char a7)
{
// std::string msg = std::format(
// "This: {:x}, EDX: {:x}, a2: {:x}, a3: {}, a4: {}, a5: {}, count: {}, bufSize: {}, source: {}, a6: {}, a7: {}",
// (intptr_t)This,
// EDX,
// a2, a3, a4, a5,
// count, bufSize,
// source, (int)a6, (int)a7
// );
// spdlog::info(msg);
// MessageBoxW(NULL, L"inside CVertexBufferCtorFn", L"", MB_OK);
// auto new_count = std::max(1, count * bufSize / VBS);
auto new_count = count;
auto new_bufsize = cfg::DynamicVB::value;
if (cfg::DynamicVB::debug) {
spdlog::debug("alloc: {}, {}", new_count, new_bufsize);
}
return tCVertexBufferCtorFn(This, a2, a3, a4, a5,
new_count,
new_bufsize,
source, a6, a7);
// return tCVertexBufferCtorFn(This, a2, a3, a4, a5,
// count,
// bufSize,
// source, a6, a7);
}
void __declspec(naked) nakedCVertexBufferCtorFn() {
__asm {
call hCVertexBufferCtorFn
jmp nCVertexBufferCtorFn
};
}
int patchDynamicVB(HMODULE hDll) {
const char* pat = "0F B6 C8 8B 45 10 51 8B 4D FC 99 68 ?? ?? ?? ?? 68 00 80 00 00";
size_t offset_imm = 0xe13b - 0xe12a;
size_t offset_call = 0xe152 - 0xe12a;
std::uint8_t* ptr = Memory::PatternScan(hDll, pat, 0);
if (ptr == nullptr) {
spdlog::info(L"Can not find the DynamicVB call");
return -1;
}
spdlog::info(L"Hook DynamicVB Call success");
ptr += offset_call;
spdlog::info(L"Modified the DynamicVB call @ 0x{:0x}", (intptr_t)ptr - (intptr_t)hDll);
oCVertexBufferCtorFn = reinterpret_cast<CVertexBufferCtorFn>(ptr);
nCVertexBufferCtorFn = reinterpret_cast<intptr_t>(ptr) + 0x5;
// copy the target address, call is followed by an relative address
const char* pat_GameCVertexBufferCtor = "55 8B EC 81 EC 08 01 00 00 A1 ?? ?? ?? ?? 33 C5 89 45 FC 53 56 57 8B 45 08 8B 55 10";
std::uint8_t* ptr_GameCVertexBufferCtor = Memory::PatternScan(hDll, pat_GameCVertexBufferCtor, 0);
if (ptr_GameCVertexBufferCtor == nullptr) {
spdlog::info(L"Can not find the GameCVertexBufferCtor");
return -1;
}
tCVertexBufferCtorFn = reinterpret_cast<CVertexBufferCtorFn>(ptr_GameCVertexBufferCtor);
spdlog::info(L"Hook GameCVertexBufferCtor success");
// Only for debugging
// Memory::Write((uintptr_t)hDll + 0xbb67, (uint16_t)0x9090);
spdlog::info(L"New DynamicVB call to 0x{:0x}", (intptr_t)oCVertexBufferCtorFn);
DetourRestoreAfterWith();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)oCVertexBufferCtorFn, nakedCVertexBufferCtorFn);
DetourTransactionCommit();
return 0;
}
// ---------------------------------------------------------------------------------
using GetMaxToRenderFn = int (__thiscall*)(void*, DWORD*, char, int*, int*);
GetMaxToRenderFn oGetMaxToRender = nullptr;
int __fastcall hGetMaxToRender(
void* This,
DWORD EDX,
DWORD* a2,
char a3,
int* p_bufsize,
int* p_nCount
) {
auto ret = oGetMaxToRender(This, a2, a3, p_bufsize, p_nCount);
// if (cfg::GetMaxToRender::debug) {
// if (p_bufsize != nullptr && p_nCount != nullptr) {
// spdlog::debug("p_bufSize: {} {:x}, p_nCount: {} {:x}", *p_bufsize, *p_bufsize, *p_nCount, *p_nCount);
// } else {
// spdlog::debug("invalid pointer, omitting, {}, {}", (intptr_t)p_bufsize, (intptr_t)p_nCount);
// }
// }
if (p_bufsize != nullptr && *p_bufsize == cfg::GetMaxToRender::old_value) *p_bufsize = cfg::GetMaxToRender::new_value;
return ret;
}
int patchGetMaxToRender(HMODULE hDll) {
const char* pat_GetMaxToRender = "55 8B EC 57 8B 7D 08 85 FF 75 ?? 8B 45 10 89 38";
std::uint8_t* ptr_GetMaxToRender = Memory::PatternScan(hDll, pat_GetMaxToRender, 0);
oGetMaxToRender = reinterpret_cast<GetMaxToRenderFn>(ptr_GetMaxToRender);
if (oGetMaxToRender == nullptr) {
spdlog::info(L"Can not find the GetMaxToRender");
return -1;
}
spdlog::info(L"Hook GetMaxToRender success");
DetourRestoreAfterWith();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)oGetMaxToRender, hGetMaxToRender);
DetourTransactionCommit();
return 0;
}
// ---------------------------------------------------------------------------------
int hooks_dvb(HMODULE hDll, std::wstring dllName) {
auto ret = 0;
if (cfg::DynamicVB::enable) {
ret += patchDynamicVB(hDll);
}
if (cfg::GetMaxToRender::enable) {
ret += patchGetMaxToRender(hDll);
}
return ret;
}
+86
View File
@@ -0,0 +1,86 @@
#pragma once
#define SPDLOG_WCHAR_TO_UTF8_SUPPORT
#include <spdlog/spdlog.h>
#include <spdlog/sinks/basic_file_sink.h>
#include <string>
#include <ranges>
#include "helper.hpp"
#include "vars.h"
int PatchIndices(HMODULE hDll, std::wstring dllName) {
if (!cfg::Indices::enable) return 0;
// Tag, pattern, start_search_path, write_offset
auto f = [&](const wchar_t* tag, const char* pattern, size_t offset, size_t w_offset) {
std::uint8_t* ptr = Memory::PatternScan(hDll, pattern, offset);
auto new_buffer_size = cfg::Indices::value;
if (ptr != nullptr) {
Memory::Write((uintptr_t)(ptr + w_offset), new_buffer_size);
spdlog::info(L"Modified the vertex max buffer {}: {} @ 0x{:0x}", dllName, tag, (intptr_t)(ptr) - (intptr_t)hDll);
return ptr;
}
spdlog::error(L"Pattern scan failed for {}: {}", dllName, tag);
return (uint8_t*)nullptr;
};
std::vector<void*> ptr_cache;
std::string pattern;
// CreateEmptyColorMesh
pattern = "68 ?? ?? ?? ?? 68 00 80 00 00 6A 04";
auto* ptr1 = f(
L"CreateEmptyColorMesh",
pattern.c_str(),
0,
6
);
ptr_cache.push_back(ptr1);
pattern = "68 00 80 00 00 50 8B";
auto* ptr1_1 = f(
L"CreateEmptyColorMesh Later",
pattern.c_str(),
(size_t)ptr1,
1
);
ptr_cache.push_back(ptr1_1);
// CreateVertexIDBuffer
pattern = "68 ?? ?? ?? ?? 68 00 80 00 00 6A 04";
auto* ptr2 = f(
L"CreateVertexIDBuffer",
pattern.c_str(),
(size_t)ptr1_1,
6
);
ptr_cache.push_back(ptr2);
pattern = "68 00 80 00 00 50 8B";
auto* ptr2_1 = f(
L"CreateVertexIDBuffer Later",
pattern.c_str(),
(size_t)ptr2,
1
);
ptr_cache.push_back(ptr2_1);
auto* ptr3 = f(
L"Unknown",
"0F B6 C0 50 68 00 80 00 00 53 8B CF E8 ?? ?? ?? ??",
(size_t)ptr2,
5
);
ptr_cache.push_back(ptr3);
if (std::ranges::any_of(ptr_cache, [](void* ptr) { return ptr == nullptr; })) {
return -1;
}
return 0;
}
BIN
View File
Binary file not shown.
+88
View File
@@ -0,0 +1,88 @@
#pragma once
#define SPDLOG_WCHAR_TO_UTF8_SUPPORT
#include <spdlog/spdlog.h>
#include <spdlog/sinks/basic_file_sink.h>
#include <windows.h>
#include <string>
#include <cstdlib>
#include <filesystem>
#include "inipp.h"
HMODULE baseModule = GetModuleHandle(NULL);
HMODULE thisModule; // Fix DLL
// Version
std::string sFixName = "L4D2Fix";
std::string sFixVer = "1.3.0";
std::string sLogFile = sFixName + ".log";
// Logger
std::shared_ptr<spdlog::logger> logger;
std::filesystem::path sExePath;
std::string sExeName;
std::filesystem::path sThisModulePath;
// Ini Config
inipp::Ini<char> ini;
// Global config vars
namespace cfg {
namespace System {
bool debug;
}
namespace Indices {
bool enable;
bool debug;
int value;
}
namespace DynamicVB {
bool enable;
bool debug;
int value;
}
namespace GetMaxToRender {
bool enable;
bool debug;
int old_value;
int new_value;
}
}
void LoadIni() {
using namespace cfg;
std::ifstream is("kpatch.ini");
ini.parse(is);
{
using namespace System;
inipp::extract(ini.sections["System"]["debug"], debug);
}
{
using namespace Indices;
inipp::extract(ini.sections["Indices"]["enable"], enable);
inipp::extract(ini.sections["Indices"]["debug"], debug);
inipp::extract(ini.sections["Indices"]["value"], value);
}
{
using namespace DynamicVB;
inipp::extract(ini.sections["DynamicVB"]["enable"], enable);
inipp::extract(ini.sections["DynamicVB"]["debug"], debug);
inipp::extract(ini.sections["DynamicVB"]["value"], value);
}
{
using namespace GetMaxToRender;
inipp::extract(ini.sections["GetMaxToRender"]["enable"], enable);
inipp::extract(ini.sections["GetMaxToRender"]["debug"], debug);
inipp::extract(ini.sections["GetMaxToRender"]["old_value"], old_value);
inipp::extract(ini.sections["GetMaxToRender"]["new_value"], new_value);
}
}
+2 -19
View File
@@ -10,16 +10,13 @@ set_arch("x86") -- Use "x64" for 64-bit builds
add_requires("spdlog")
add_requires("minhook")
add_requires("vcpkg::detours")
if is_mode("release") then
add_defines("NDEBUG", "NTESTING")
end
add_requires("vcpkg::inipp")
local name = "kpatch"
target(name)
set_kind("shared")
add_files("src/dllmain.cpp")
add_packages("spdlog", "vcpkg::detours", "minhook")
add_packages("spdlog", "vcpkg::detours", "minhook", "vcpkg::inipp")
add_links("user32", "gdi32")
local name = "left4dead2_fix"
@@ -29,17 +26,3 @@ target(name)
add_files("assets/app.rc")
add_links("user32", "gdi32")
add_packages("vcpkg::detours")
rule("mode.release.testing")
on_config(function (target)
if is_mode("release.testing") then
target:add_defines("NDEBUG")
end
end)
rule("mode.testing")
on_config(function (target)
if is_mode("testing") then
end
end)