add vulkan support

This commit is contained in:
Kuriko Moe
2025-01-22 11:22:46 +08:00
parent 53ca93676a
commit 6cbd0f1a3d
4 changed files with 72 additions and 61 deletions
+3 -9
View File
@@ -3,8 +3,6 @@ cmake_minimum_required(VERSION 3.25.0)
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake CACHE STRING "")
set(CMAKE_EXPORT_COMPILE_COMMANDS true)
# set(CMAKE_GENERATOR_TOOLSET "v140" CACHE STRING "Platform Toolset" FORCE)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
@@ -12,16 +10,12 @@ include(AutoCCache)
project(KProject)
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
set(CMAKE_CXX_STANDARD 20)
# set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
# set(CMAKE_CXX_FLAGS_RELEASE "/MT")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
# find_package(Catch2 CONFIG REQUIRED)
# target_link_libraries(main PRIVATE Catch2::Catch2 Catch2::Catch2WithMain)
find_package(minhook CONFIG REQUIRED)
find_package(spdlog CONFIG REQUIRED)
set(TARGET "kpatch")
@@ -30,7 +24,7 @@ set(TARGET_OUTPUT_NAME "kpatch")
add_library(${TARGET} SHARED ${TARGET_SRC})
set_target_properties(${TARGET} PROPERTIES OUTPUT_NAME ${TARGET_OUTPUT_NAME})
target_include_directories(${TARGET} PRIVATE ${CMAKE_SOURCE_DIR}/include)
target_link_libraries(${TARGET} PUBLIC spdlog::spdlog)
target_link_libraries(${TARGET} PRIVATE spdlog::spdlog_header_only)
# target_link_libraries(${TARGET} PUBLIC minhook::minhook)
+6 -1
View File
@@ -17,7 +17,12 @@ config:
build:
cmake --build --preset {{preset}} --config Release
cp -f ./build/x86-release-msvc/bin/Release/kpatch.dll "{{TARGET}}/kpatch.asi"
copy: build
cd ./build/x86-release-msvc/bin/Release && \
cp -f kpatch.dll "{{TARGET}}/kpatch.asi" && \
cp -f fmt.dll "{{TARGET}}/"
cp -f third/version.dll "{{TARGET}}/"
@run:
./build/{{preset}}/bin/{{target}}
+61 -50
View File
@@ -1,15 +1,18 @@
#include "stdafx.h"
#include "helper.hpp"
#define SPDLOG_WCHAR_TO_UTF8_SUPPORT
#include <spdlog/spdlog.h>
#include <spdlog/sinks/rotating_file_sink.h>
#include <mutex>
#include <spdlog/sinks/basic_file_sink.h>
#include <cctype>
#include <algorithm>
#include "helper.hpp"
HMODULE baseModule = GetModuleHandle(NULL);
HMODULE thisModule; // Fix DLL
// Version
std::string sFixName = "L4D2Fix";
std::string sFixVer = "0.0.1";
std::string sFixVer = "1.1.0";
std::string sLogFile = sFixName + ".log";
// Logger
@@ -18,8 +21,7 @@ std::filesystem::path sExePath;
std::string sExeName;
std::filesystem::path sThisModulePath;
void Logging()
{
void Logging() {
// Get this module path
WCHAR thisModulePath[_MAX_PATH] = { 0 };
GetModuleFileNameW(thisModule, thisModulePath, MAX_PATH);
@@ -34,52 +36,67 @@ void Logging()
sExePath = sExePath.remove_filename();
// spdlog initialisation
{
try {
// Create 10MB truncated logger
auto logger = spdlog::rotating_logger_mt(sFixName, sLogFile, 1048576 * 5, 3);
spdlog::set_default_logger(logger);
try {
auto logger = spdlog::basic_logger_mt(sFixName, sLogFile, true);
spdlog::set_default_logger(logger);
spdlog::flush_on(spdlog::level::debug);
spdlog::info("----------");
spdlog::info("{} v{} loaded.", sFixName.c_str(), sFixVer.c_str());
spdlog::info("----------");
spdlog::info("Log file: {}", sThisModulePath.string() + sLogFile);
spdlog::info("----------");
auto start_time = std::chrono::system_clock::now();
// Log module details
spdlog::info("Module Name: {0:s}", sExeName.c_str());
spdlog::info("Module Path: {0:s}", sExePath.string());
spdlog::info("Module Address: 0x{0:x}", (uintptr_t)baseModule);
spdlog::info("Module Timestamp: {0:d}", Memory::ModuleTimestamp(baseModule));
spdlog::info("----------");
}
catch (const spdlog::spdlog_ex& ex) {
AllocConsole();
FILE* dummy;
freopen_s(&dummy, "CONOUT$", "w", stdout);
std::cout << "Log initialisation failed: " << ex.what() << std::endl;
FreeLibraryAndExitThread(baseModule, 1);
}
spdlog::flush_on(spdlog::level::debug);
spdlog::info("----------");
spdlog::info("Date: {}", std::chrono::system_clock::to_time_t(start_time));
spdlog::info("{} v{} loaded.", sFixName.c_str(), sFixVer.c_str());
spdlog::info("----------");
spdlog::info("Log file: {}", sThisModulePath.string() + sLogFile);
spdlog::info("----------");
// Log module details
spdlog::info("Module Name: {0:s}", sExeName.c_str());
spdlog::info("Module Path: {0:s}", sExePath.string());
spdlog::info("Module Address: 0x{0:x}", (uintptr_t)baseModule);
spdlog::info("Module Timestamp: {0:d}", Memory::ModuleTimestamp(baseModule));
spdlog::info("----------");
} catch (const spdlog::spdlog_ex &ex) {
AllocConsole();
FILE *dummy;
freopen_s(&dummy, "CONOUT$", "w", stdout);
std::cout << "Log initialisation failed: " << ex.what() << std::endl;
FreeLibraryAndExitThread(baseModule, 1);
}
}
DWORD __stdcall Main(void*) {
Logging();
std::filesystem::path startup_check = L"success.txt";
// MessageBoxW(NULL, L"警告:这是测试版补丁,设定为必定会炸,用于检测补丁是否正确应用。", L"L4D2 Fix", MB_OK);
// MessageBoxW(NULL, L"警告:这是测试版补丁,设定为必定会炸,用于检测补丁是否正确应用。", L"L4D2 Fix", MB_OK|MB_SYSTEMMODAL|MB_ICONWARNING);
if (!std::filesystem::exists(startup_check)) {
MessageBoxW(NULL, L"这是一个启动测试,用于检验补丁是否正常运行。\n请注意由于修改内存,请不要进 VAC 服,后果未知。\n本弹窗仅首次启动出现,后续运行情况参见 L4D2Fix.log 日志文件。\n\n关注B站 5050 直播间,谢谢喵 by KurikoMoe!", L"L4D2 Fix", MB_OK);
MessageBoxW(
NULL,
L"这是一个启动测试,用于检验补丁是否正常运行。\n请注意由于修改内存,请不要进 VAC 服,后果自负。\n本弹窗仅首次启动出现,后续运行情况参见 L4D2Fix.log 日志文件。\n\n关注B站 5050 直播间,谢谢喵 by KurikoMoe!",
L"L4D2 Fix", MB_OK);
}
auto hDll = LoadLibraryW(L"shaderapidx9.dll");
std::wstring cmdline = GetCommandLineW();
spdlog::info(L"Startup commandline: {}", cmdline.c_str());
std::wstring dllName;
std::transform(cmdline.cbegin(), cmdline.cend(), cmdline.begin(), ::tolower);
if (cmdline.find(L"-vulkan") != std::wstring::npos) {
dllName = L"shaderapivk.dll";
spdlog::info(L"Detected Vulkan: using {}", dllName);
} else {
dllName = L"shaderapidx9.dll";
}
auto hDll = LoadLibraryW(dllName.c_str());
if (hDll == nullptr) {
MessageBoxW(NULL, L"Failed to load shaderapidx9.dll!", L"L4D2 Fix", MB_OK);
MessageBoxW(NULL, std::format(L"Failed to load {}!", dllName).c_str(), L"L4D2 Fix", MB_OK|MB_SYSTEMMODAL|MB_ICONSTOP);
exit(-1);
}
auto f = [&](const char* tag, const char* pattern, size_t offset, size_t w_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);
constexpr uint32_t new_buffer_size = 0x020000;
@@ -87,25 +104,25 @@ DWORD __stdcall Main(void*) {
if (ptr != nullptr) {
Memory::Write((uintptr_t)(ptr + w_offset), new_buffer_size);
spdlog::info("Modified the vertex max buffer shaderapidx9.dll: {}", tag);
spdlog::info(L"Modified the vertex max buffer {}: {}", dllName, tag);
return ptr;
}
spdlog::error("Pattern scan failed for shaderapidx9.dll: {}", tag);
spdlog::error(L"Pattern scan failed for {}: {}", dllName, tag);
return (uint8_t*)nullptr;
};
// CreateEmptyColorMesh
auto ptr1 = f("CreateEmptyColorMesh", "68 ?? ?? ?? ?? 68 00 80 00 00 6A 04", 0, 6);
auto ptr1 = f(L"CreateEmptyColorMesh", "68 ?? ?? ?? ?? 68 00 80 00 00 6A 04", 0, 6);
auto ptr1_1 = f("CreateEmptyColorMesh Later", "68 00 80 00 00 50 8B", (size_t)ptr1, 1);
auto ptr1_1 = f(L"CreateEmptyColorMesh Later", "68 00 80 00 00 50 8B", (size_t)ptr1, 1);
// CreateVertexIDBuffer
auto ptr2 = f("CreateVertexIDBuffer", "68 ?? ?? ?? ?? 68 00 80 00 00 6A 04", (size_t)ptr1_1, 6);
auto ptr2_1 = f("CreateVertexIDBuffer Later", "68 00 80 00 00 50 8B", (size_t)ptr2, 1);
auto ptr2 = f(L"CreateVertexIDBuffer", "68 ?? ?? ?? ?? 68 00 80 00 00 6A 04", (size_t)ptr1_1, 6);
auto ptr2_1 = f(L"CreateVertexIDBuffer Later", "68 00 80 00 00 50 8B", (size_t)ptr2, 1);
// Not known
auto ptr3 = f("Unknown", "0F B6 C0 50 68 00 80 00 00 53 8B CF E8 ?? ?? ?? ??", (size_t)ptr1, 5);
auto ptr3 = f(L"Unknown", "0F B6 C0 50 68 00 80 00 00 53 8B CF E8 ?? ?? ?? ??", (size_t)ptr1, 5);
if (ptr1 == nullptr
|| ptr1_1 == nullptr
@@ -128,12 +145,6 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
Main(nullptr);
// HANDLE mainHandle = CreateThread(NULL, 0, Main, 0, CREATE_SUSPENDED, 0);
// if (mainHandle) {
// SetThreadPriority(mainHandle, THREAD_PRIORITY_TIME_CRITICAL);
// ResumeThread(mainHandle);
// CloseHandle(mainHandle);
// }
break;
}
return TRUE;
+2 -1
View File
@@ -7,6 +7,7 @@
#include <windows.h>
#include <fstream>
#include <iostream>
#include <inttypes.h>
#include <filesystem>
#include <string>
#include <cstdint>
#include <cstddef>