Skip to content

Commit 01855ea

Browse files
committed
Refactor CMake configuration and enhance logging functionality
1 parent 3a29365 commit 01855ea

File tree

5 files changed

+141
-69
lines changed

5 files changed

+141
-69
lines changed

CMakeLists.txt

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,17 @@ project(kcd2db LANGUAGES C CXX)
44
set(CMAKE_CXX_STANDARD 20)
55
set(CMAKE_CXX_STANDARD_REQUIRED ON)
66

7-
# Set default build type to Release
8-
if(NOT CMAKE_BUILD_TYPE)
9-
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build" FORCE)
10-
endif()
11-
127
if(NOT WIN32 OR NOT MSVC)
138
message(FATAL_ERROR "This project only supports Windows and MSVC")
149
endif()
10+
# 设置UTF-8编码
11+
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
12+
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
1513
# 设置为静态多线程运行时库(Release用MT,Debug用MTd)
1614
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
17-
1815
set(CMAKE_SYSTEM_NAME Windows)
1916
set(CMAKE_SYSTEM_PROCESSOR x86_64)
20-
add_compile_options("/source-charset:utf-8")
17+
2118

2219
include(FetchContent)
2320

@@ -26,7 +23,12 @@ FetchContent_Declare(libmem-config URL "https://raw.githubusercontent.com/rdbo/l
2623
FetchContent_MakeAvailable(libmem-config)
2724
set(CMAKE_PREFIX_PATH "${libmem-config_SOURCE_DIR}" "${CMAKE_PREFIX_PATH}")
2825
set(LIBMEM_DOWNLOAD_VERSION "5.0.4")
29-
set(LIBMEM_MSVC_CRT "MT")
26+
# 设置libmem的运行时,如果是Release则使用MT,如果是Debug则使用MTd
27+
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
28+
set(LIBMEM_MSVC_CRT "MTd")
29+
else()
30+
set(LIBMEM_MSVC_CRT "MT")
31+
endif()
3032

3133
# Find libmem package
3234
find_package(libmem CONFIG REQUIRED)

src/db/Database.cpp

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ int Database::GenericAccess(IFunctionHandler* pH, const AccessType action, const
114114
{
115115
case AccessType::Set:
116116
cache[key] = value;
117+
LogDebug(isGlobal ? "Set Global %s = %s" : "Set %s = %s", key, FormatAnyValue(value));
117118
if (isGlobal)
118119
{
119120
m_globalDirty = true;
@@ -127,6 +128,7 @@ int Database::GenericAccess(IFunctionHandler* pH, const AccessType action, const
127128
case AccessType::Del:
128129
{
129130
const bool erased = cache.erase(key) > 0;
131+
LogDebug(isGlobal ? "Delete Global %s: %s" : "Delete %s: %s", key, erased ? "OK" : "Not found");
130132
if (isGlobal && erased)
131133
{
132134
m_globalDirty = true;
@@ -194,10 +196,9 @@ void Database::OnPostUpdate(float /*fDeltaTime*/)
194196
if (!m_globalDirty) return;
195197
if (const auto now = steady_clock::now(); now - m_lastSaveTime < SAVE_INTERVAL) return;
196198

197-
int successCount = 0;
198-
199199
try
200200
{
201+
int successCount = 0;
201202
ExecuteTransaction([this, &successCount](const SQLite::Database& db)
202203
{
203204
SQLite::Statement clearStmt(db, "DELETE FROM Store WHERE savefile = ''");
@@ -279,32 +280,17 @@ int Database::BatchOperation(SQLite::Database& db, const Cache& cache, const std
279280

280281
std::optional<ScriptAnyValue> Database::ParseAnyValue(const int type, const std::string& value)
281282
{
282-
ScriptAnyValue any;
283283
switch (type)
284284
{
285285
case ANY_TBOOLEAN:
286-
{
287-
any.type = ANY_TBOOLEAN;
288-
any.b = std::stoi(value) != 0;
289-
}
290-
break;
286+
return ScriptAnyValue(std::stoi(value) != 0);
291287
case ANY_TNUMBER:
292-
{
293-
any.type = ANY_TNUMBER;
294-
any.number = std::stod(value);
295-
}
296-
break;
288+
return ScriptAnyValue(std::stof(value));
297289
case ANY_TSTRING:
298-
{
299-
any.type = ANY_TSTRING;
300-
// Fix for string encoding issues - ensure we properly handle UTF-8 strings
301-
any.str = _strdup(value.c_str());
302-
}
303-
break;
290+
return ScriptAnyValue(_strdup(value.c_str()));
304291
default:
305292
return std::nullopt;
306293
}
307-
return any;
308294
}
309295

310296
std::optional<std::string> Database::SerializeAnyValue(const ScriptAnyValue& any)
@@ -318,15 +304,32 @@ std::optional<std::string> Database::SerializeAnyValue(const ScriptAnyValue& any
318304
case ANY_TSTRING:
319305
{
320306
if (!any.str) return "";
321-
322-
// Return the string directly - SQLite handles UTF-8 text natively
323307
return std::string(any.str);
324308
}
325309
default:
326310
return std::nullopt;
327311
}
328312
}
329313

314+
const char* Database::FormatAnyValue(const ScriptAnyValue& value)
315+
{
316+
switch (value.type)
317+
{
318+
case ANY_TNUMBER: return std::to_string(value.number).c_str();
319+
case ANY_TSTRING: return value.str;
320+
case ANY_TBOOLEAN: return value.b ? "true" : "false";
321+
case ANY_TTABLE: return "[Table]";
322+
case ANY_TNIL: return "[Nil]";
323+
case ANY_TFUNCTION: return "[Function]";
324+
case ANY_TUSERDATA: return "[UserData]";
325+
case ANY_TVECTOR: return "[Vector]";
326+
case ANY_COUNT: return "[Count]";
327+
case ANY_THANDLE: return "[Handle]";
328+
case ANY_ANY: return "[Any]";
329+
default: return "[Unknown]";
330+
}
331+
}
332+
330333
int Database::Dump(IFunctionHandler* pH)
331334
{
332335
std::lock_guard lock(m_mutex);

src/db/Database.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class Database final : public CScriptableBase, public IGameFrameworkListener {
5959

6060
static std::optional<ScriptAnyValue> ParseAnyValue(int type, const std::string& value);
6161
static std::optional<std::string> SerializeAnyValue(const ScriptAnyValue& any);
62+
static const char* FormatAnyValue(const ScriptAnyValue& value);
6263
void ExecuteTransaction(const std::function<void(SQLite::Database&)>& task) const;
6364

6465
std::unique_ptr<SQLite::Database> m_db;

src/kcd2db.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#define KCD2_ENV_IMPORT
99
#include "db/Database.h"
1010
#include "kcd2/env.h"
11+
#include "kcd2/IGame.h"
1112
#include "log/log.h"
1213
#include "lua/db.h"
1314

@@ -18,7 +19,7 @@ std::optional<uintptr_t> find_env_addr()
1819
// 持续尝试查找模块
1920
while (!LM_FindModule(CLIENT_DLL, &module))
2021
{
21-
std::this_thread::sleep_for(std::chrono::milliseconds(100));
22+
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
2223
}
2324
// 通常会找到两个地址,不过两个地址其实通过RIP之后的偏移是一样的,都是指向 gEnv->pConsole 的 qword_1848A7C68
2425
const auto pattern = "48 8B 0D ?? ?? ?? ?? 48 8D 15 ?? ?? ?? ?? 45 33 C9 45 33 C0 4C 8B 11";
@@ -59,18 +60,22 @@ void start()
5960
LogDebug("Found environment address: 0x%llX", *env_addr);
6061

6162
auto* env_ptr = reinterpret_cast<SSystemGlobalEnvironment*>(env_addr.value());
62-
while (env_ptr->pGame == nullptr)
63+
while (env_ptr->pGame == nullptr
64+
|| env_ptr->pGame->GetIGameFramework() == nullptr
65+
|| env_ptr->pScriptSystem == nullptr
66+
|| env_ptr->pConsole == nullptr)
6367
{
6468
Sleep(1000);
6569
}
6670
LogDebug("Game Started");
6771

6872
gEnv = *env_ptr;
73+
6974
const auto db = new Database(env_ptr);
75+
LogInfo("Database initialized...%s", db->getName());
7076

7177
env_ptr->pScriptSystem->ExecuteBuffer(db_lua, strlen(db_lua), "db.lua");
72-
73-
LogInfo("Database initialized...%s", db->getName());
78+
LogInfo("DB lua API loaded");
7479
}
7580
else
7681
{

0 commit comments

Comments
 (0)