diff --git a/CMakeLists.txt b/CMakeLists.txt index 21bff98..0548c9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,14 +13,13 @@ add_compile_options( /D_UNICODE ) -include_directories(include) if(${CMAKE_SIZEOF_VOID_P} EQUAL 8) set(CMAKE_FINAL_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/builds/${CMAKE_BUILD_TYPE}_x64) - file(GLOB LIBS x64libs/*) + set(LIBDIR x64libs) else() set(CMAKE_FINAL_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/builds/${CMAKE_BUILD_TYPE}_x86) - file(GLOB LIBS x86libs/*) + set(LIBDIR x86libs) endif() set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_FINAL_OUTPUT_DIRECTORY}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_FINAL_OUTPUT_DIRECTORY}) @@ -28,8 +27,12 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_FINAL_OUTPUT_DIRECTORY}) set(CMAKE_CONFIGURATION_TYPES Debug Release) +file(GLOB LIBS ${LIBDIR}/*) file(COPY ${LIBS} DESTINATION ${CMAKE_FINAL_OUTPUT_DIRECTORY}) +include_directories(include) +link_directories(${LIBDIR}) + add_library(text text.cpp) link_libraries(text) diff --git a/deploy.ps1 b/deploy.ps1 index 2a2603f..9f7577b 100644 --- a/deploy.ps1 +++ b/deploy.ps1 @@ -11,11 +11,13 @@ $targets = @( "Qt5Widgets.dll", "LoaderDll.dll", "LocaleEmulator.dll", + "lua53.dll", "Bing Translate.dll", "Copy to Clipboard.dll", "Extra Newlines.dll", "Extra Window.dll", "Google Translate.dll", + "Lua.dll", "Regex Filter.dll", "Remove Repetition.dll", "Replacer.dll", diff --git a/extensions/CMakeLists.txt b/extensions/CMakeLists.txt index 78cbe4e..ff166d8 100644 --- a/extensions/CMakeLists.txt +++ b/extensions/CMakeLists.txt @@ -9,6 +9,7 @@ add_library(Copy\ to\ Clipboard SHARED copyclipboard.cpp extensionimpl.cpp) add_library(Extra\ Newlines SHARED extranewlines.cpp extensionimpl.cpp) add_library(Extra\ Window SHARED extrawindow.cpp extensionimpl.cpp) add_library(Google\ Translate SHARED googletranslate.cpp extensionimpl.cpp) +add_library(Lua SHARED lua.cpp extensionimpl.cpp) add_library(Regex\ Filter SHARED regexfilter.cpp extensionimpl.cpp) add_library(Remove\ Repetition SHARED removerepeat.cpp extensionimpl.cpp) add_library(Replacer SHARED replacer.cpp extensionimpl.cpp) @@ -19,5 +20,6 @@ add_executable(Extension_Tests extensiontester.cpp) target_link_libraries(Bing\ Translate winhttp Qt5::Widgets) target_link_libraries(Extra\ Window Qt5::Widgets) target_link_libraries(Google\ Translate winhttp Qt5::Widgets) +target_link_libraries(Lua lua53 Qt5::Widgets) target_link_libraries(Regex\ Filter Qt5::Widgets) target_link_libraries(Thread\ Linker Qt5::Widgets) diff --git a/extensions/lua.cpp b/extensions/lua.cpp new file mode 100644 index 0000000..14e6049 --- /dev/null +++ b/extensions/lua.cpp @@ -0,0 +1,168 @@ +#include "extension.h" +#include "util.h" +#include "text.h" +#include "defs.h" +#include +#include +#include +#include +#include + +extern "C" +{ + enum LuaType + { + LUA_TNONE = -1, + LUA_TNIL = 0, + LUA_TBOOLEAN = 1, + LUA_TLIGHTUSERDATA = 2, + LUA_TNUMBER = 3, + LUA_TSTRING = 4, + LUA_TTABLE = 5, + LUA_TFUNCTION = 6, + LUA_TUSERDATA = 7, + LUA_TTHREAD = 8 + }; + + enum LuaStatus + { + LUA_OK = 0, + LUA_YIELD = 1, + LUA_ERRRUN = 2, + LUA_ERRSYNTAX = 3, + LUA_ERRMEM = 4, + LUA_ERRGCMM = 5, + LUA_ERRERR = 6 + }; + + struct lua_State; + __declspec(dllimport) lua_State* luaL_newstate(); + __declspec(dllimport) void luaL_openlibs(lua_State*); + __declspec(dllimport) void lua_close(lua_State*); + + __declspec(dllimport) LuaStatus luaL_loadstring(lua_State*, const char* str); + + __declspec(dllimport) LuaStatus lua_pcallk(lua_State*, int nargs, int nresults, int msgh, void*, void*); + + __declspec(dllimport) const char* lua_tolstring(lua_State*, int index, size_t* size); + __declspec(dllimport) const char* lua_pushstring(lua_State*, const char* str); + + __declspec(dllimport) void lua_pushinteger(lua_State*, int64_t n); + + __declspec(dllimport) void lua_createtable(lua_State*, int narr, int nrec); + __declspec(dllimport) void lua_settable(lua_State*, int index); + + __declspec(dllimport) void lua_settop(lua_State*, int index); + __declspec(dllimport) LuaType lua_getglobal(lua_State*, const char* name); +} + +bool luaL_dostring(lua_State* L, const char* str) +{ + return luaL_loadstring(L, str) || lua_pcallk(L, 0, -1, 0, NULL, NULL); +} + +bool logErrors = true; + +std::mutex m; +std::string script; +int revCount = 0; + +struct : QMainWindow +{ + void launch() + { + auto centralWidget = new QWidget(this); + auto layout = new QVBoxLayout(centralWidget); + auto scriptEditor = new QPlainTextEdit(centralWidget); + auto loadButton = new QPushButton("Load Script", centralWidget); + layout->addWidget(scriptEditor); + layout->addWidget(loadButton); + connect(loadButton, &QPushButton::clicked, [=](bool) + { + std::lock_guard l(m); + ++revCount; + script = scriptEditor->toPlainText().toUtf8(); + }); + resize(800, 600); + setCentralWidget(centralWidget); + setWindowTitle("Lua"); + show(); + } +}*window = nullptr; + +BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + { + QTimer::singleShot(0, [] + { + std::lock_guard l(m); + (window = new std::remove_pointer_t)->launch(); + }); + } + break; + case DLL_PROCESS_DETACH: + { + if (lpReserved == NULL) // https://blogs.msdn.microsoft.com/oldnewthing/20120105-00/?p=8683 + { + std::lock_guard l(m); + delete window; + window = nullptr; + } + } + break; + } + return TRUE; +} + +bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo) +{ + thread_local static std::unique_ptr> L_(luaL_newstate()); + thread_local static lua_State* L = L_.get(); + thread_local static auto _ = (luaL_openlibs(L), luaL_dostring(L, "function ProcessSentence() end")); + thread_local static int revCount = 0; + + if (::revCount > revCount) + { + std::lock_guard l(m); + revCount = ::revCount; + luaL_dostring(L, "ProcessSentence = nil"); + if (luaL_dostring(L, script.c_str()) != LUA_OK) + { + sentence += NEWLINE + LUA_ERROR + StringToWideString(lua_tolstring(L, -1, nullptr)); + lua_settop(L, 0); + return logErrors; + } + } + + if (lua_getglobal(L, "ProcessSentence") != LUA_TFUNCTION) + { + sentence += NEWLINE + LUA_ERROR + L"ProcessSentence is not a function"; + lua_settop(L, 0); + return logErrors; + } + lua_pushstring(L, WideStringToString(sentence).c_str()); + lua_createtable(L, 0, 0); + for (auto info = sentenceInfo.infoArray; info->name != nullptr; ++info) + { + lua_pushstring(L, info->name); + lua_pushinteger(L, info->value); + lua_settable(L, 3); + } + if (lua_pcallk(L, 2, 1, 0, NULL, NULL) != LUA_OK) + { + sentence += NEWLINE + LUA_ERROR + StringToWideString(lua_tolstring(L, -1, nullptr)); + lua_settop(L, 0); + return logErrors; + } + if (const char* newSentence = lua_tolstring(L, -1, nullptr)) + { + sentence = StringToWideString(newSentence); + lua_settop(L, 0); + return true; + } + lua_settop(L, 0); + return false; +} diff --git a/include/defs.h b/include/defs.h index fc220f8..ddf719c 100644 --- a/include/defs.h +++ b/include/defs.h @@ -29,7 +29,7 @@ constexpr auto REPLACE_SAVE_FILE = u8"SavedReplacements.txt"; // Misc -constexpr auto DEFAULT_EXTENSIONS = u8"Remove Repetition>Copy to Clipboard>Google Translate>Extra Window>Extra Newlines"; +constexpr auto DEFAULT_EXTENSIONS = u8"Remove Repetition>Lua>Copy to Clipboard>Bing Translate>Extra Window>Extra Newlines"; // Functions diff --git a/include/text.h b/include/text.h index 9a338e5..564c0d3 100644 --- a/include/text.h +++ b/include/text.h @@ -55,7 +55,7 @@ extern const char* BG_COLOR; extern const char* TEXT_COLOR; extern const char* FONT_SIZE; extern const char* TOPMOST; -extern const char* ALWAYS_ON_TOP; +extern const wchar_t* LUA_ERROR; extern const char* REGEX_FILTER; extern const char* INVALID_REGEX; extern const char* CURRENT_FILTER; diff --git a/text.cpp b/text.cpp index d779c66..7decde8 100644 --- a/text.cpp +++ b/text.cpp @@ -84,7 +84,7 @@ const char* BG_COLOR = u8"Background Color"; const char* TEXT_COLOR = u8"Text Color"; const char* FONT_SIZE = u8"Font Size"; const char* TOPMOST = u8"Always on Top"; -const char* ALWAYS_ON_TOP = u8"Keep this window on top"; +const wchar_t* LUA_ERROR = L"Lua error: "; const char* REGEX_FILTER = u8"Regex Filter"; const char* INVALID_REGEX = u8"Invalid regex"; const char* CURRENT_FILTER = u8"Currently filtering: "; @@ -215,7 +215,6 @@ Clic y arrastra los bordes de la ventana para moverla, o en la esquina inferior TEXT_COLOR = u8"Color de texto"; FONT_SIZE = u8"Tamaño de letra"; TOPMOST = u8"Siempre visible"; - ALWAYS_ON_TOP = u8"Matener esta ventana encima"; REGEX_FILTER = u8"Filtro Regex"; INVALID_REGEX = u8"Regex inválido"; CURRENT_FILTER = u8"Actualmente filtrando: "; @@ -300,7 +299,6 @@ S/Q/V: 代码页/UTF-16/UTF-8 字符串 TEXT_COLOR = u8"文本颜色"; FONT_SIZE = u8"字体大小"; TOPMOST = u8"总是位于最上层"; - ALWAYS_ON_TOP = u8"将本窗口在保持最上层"; REGEX_FILTER = u8"正则表达式过滤器"; INVALID_REGEX = u8"无效的正则表达式"; CURRENT_FILTER = u8"当前过滤中: "; diff --git a/x64libs/lua53.dll b/x64libs/lua53.dll new file mode 100644 index 0000000..a0d8de2 Binary files /dev/null and b/x64libs/lua53.dll differ diff --git a/x64libs/lua53.lib b/x64libs/lua53.lib new file mode 100644 index 0000000..9f2a77e Binary files /dev/null and b/x64libs/lua53.lib differ diff --git a/x86libs/lua53.dll b/x86libs/lua53.dll new file mode 100644 index 0000000..7d65811 Binary files /dev/null and b/x86libs/lua53.dll differ diff --git a/x86libs/lua53.lib b/x86libs/lua53.lib new file mode 100644 index 0000000..508951f Binary files /dev/null and b/x86libs/lua53.lib differ