diff --git a/.github/scripts/build_lunahook.py b/.github/scripts/build_lunahook.py index c5319604..5d485a86 100644 --- a/.github/scripts/build_lunahook.py +++ b/.github/scripts/build_lunahook.py @@ -18,24 +18,23 @@ os.chdir(rootDir) os.mkdir("../build") os.mkdir("builds") - language = ["Chinese", "English", "Russian", "TradChinese"] - for lang in language: - shutil.copytree( - f"build/{lang}_64/Release_{lang}", - f"../build/Release_{lang}", - dirs_exist_ok=True, - ) - shutil.copytree( - f"build/{lang}_winxp/Release_{lang}_winxp", - f"../build/Release_{lang}", - dirs_exist_ok=True, - ) + + shutil.copytree( + f"build/64/Release", + f"../build/Release", + dirs_exist_ok=True, + ) + shutil.copytree( + f"build/winxp/Release_winxp", + f"../build/Release", + dirs_exist_ok=True, + ) - targetdir = f"../build/Release_{lang}" - target = f"builds/Release_{lang}.zip" - os.system( - rf'"C:\Program Files\7-Zip\7z.exe" a -m0=Deflate -mx9 {target} {targetdir}' - ) + targetdir = f"../build/Release" + target = f"builds/Release.zip" + os.system( + rf'"C:\Program Files\7-Zip\7z.exe" a -m0=Deflate -mx9 {target} {targetdir}' + ) exit() print(sys.version) @@ -43,9 +42,9 @@ print(rootDir) -def build_langx(lang, bit, onlycore): +def build_langx(bit, onlycore): config = ( - f"-DBUILD_PLUGIN=OFF -DWINXP=OFF -DLANGUAGE={lang} -DBUILD_GUI=ON -DBUILD_CLI=ON" + f"-DBUILD_PLUGIN=OFF -DWINXP=OFF -DBUILD_GUI=ON -DBUILD_CLI=ON" if not onlycore else "" ) @@ -53,21 +52,21 @@ def build_langx(lang, bit, onlycore): if bit == "32": ff.write( rf""" -cmake {config} ../CMakeLists.txt -G "Visual Studio 17 2022" -A win32 -T host=x86 -B ../build/x86_{lang} -cmake --build ../build/x86_{lang} --config Release --target ALL_BUILD -j 14 +cmake {config} ../CMakeLists.txt -G "Visual Studio 17 2022" -A win32 -T host=x86 -B ../build/x86 +cmake --build ../build/x86 --config Release --target ALL_BUILD -j 14 """ ) elif bit == "64": ff.write( rf""" -cmake {config} ../CMakeLists.txt -G "Visual Studio 17 2022" -A x64 -T host=x64 -B ../build/x64_{lang} -cmake --build ../build/x64_{lang} --config Release --target ALL_BUILD -j 14 +cmake {config} ../CMakeLists.txt -G "Visual Studio 17 2022" -A x64 -T host=x64 -B ../build/x64 +cmake --build ../build/x64 --config Release --target ALL_BUILD -j 14 """ ) os.system(f"cmd /c do.bat") -def build_langx_xp(lang, core): +def build_langx_xp( core): url = "https://github.com/Chuyu-Team/YY-Thunks/releases/download/v1.0.7/YY-Thunks-1.0.7-Binary.zip" os.system(rf"curl -SLo YY-Thunks-1.0.7-Binary.zip " + url) os.system(rf"7z x -y YY-Thunks-1.0.7-Binary.zip -o../../libs/YY-Thunks") @@ -77,8 +76,8 @@ def build_langx_xp(lang, core): ff.write( rf""" -cmake -DBUILD_PLUGIN=OFF -DWINXP=ON -DLANGUAGE={lang} {flags} ../CMakeLists.txt -G "Visual Studio 16 2019" -A win32 -T v141_xp -B ../build/x86_{lang}_xp -cmake --build ../build/x86_{lang}_xp --config Release --target ALL_BUILD -j 14 +cmake -DBUILD_PLUGIN=OFF -DWINXP=ON {flags} ../CMakeLists.txt -G "Visual Studio 16 2019" -A win32 -T v141_xp -B ../build/x86_xp +cmake --build ../build/x86_xp --config Release --target ALL_BUILD -j 14 """ ) os.system(f"cmd /c do.bat") @@ -104,12 +103,11 @@ def build_langx_xp(lang, core): ) os.system(f"cmd /c buildplugin.bat") elif sys.argv[1] == "build": - lang = sys.argv[2] - bit = sys.argv[3] + bit = sys.argv[2] if bit == "winxp": - build_langx_xp(lang, False) + build_langx_xp(False) elif bit == "winxp_core": - build_langx_xp(lang, True) + build_langx_xp(True) else: onlycore = int(sys.argv[4]) if len(sys.argv) >= 5 else False - build_langx(lang, bit, onlycore) + build_langx(bit, onlycore) diff --git a/.github/workflows/buildluna.yml b/.github/workflows/buildluna.yml index 4a8baac2..3e0af803 100644 --- a/.github/workflows/buildluna.yml +++ b/.github/workflows/buildluna.yml @@ -30,12 +30,12 @@ jobs: - uses: GuillaumeFalourd/setup-windows10-sdk-action@v2 with: sdk-version: 22621 - - run: python .github/scripts/build_lunahook.py build English winxp_core + - run: python .github/scripts/build_lunahook.py build winxp_core - uses: actions/upload-artifact@v4 with: name: hook_xp - path: cpp/LunaHook/builds/Release_English_winxp + path: cpp/LunaHook/builds/Release_winxp hook: runs-on: windows-latest @@ -53,12 +53,12 @@ jobs: - uses: GuillaumeFalourd/setup-windows10-sdk-action@v2 with: sdk-version: 22621 - - run: python .github/scripts/build_lunahook.py build English ${{matrix.bits}} 1 + - run: python .github/scripts/build_lunahook.py build ${{matrix.bits}} 1 - uses: actions/upload-artifact@v4 with: name: hook_${{matrix.bits}} - path: cpp/LunaHook/builds/Release_English + path: cpp/LunaHook/builds/Release pyrt: runs-on: windows-latest strategy: diff --git a/.github/workflows/buildlunahook.yml b/.github/workflows/buildlunahook.yml index 6a7f6633..f4274dbd 100644 --- a/.github/workflows/buildlunahook.yml +++ b/.github/workflows/buildlunahook.yml @@ -5,9 +5,6 @@ on: jobs: build_xp: runs-on: windows-2019 - strategy: - matrix: - language: [Chinese,English,Russian,TradChinese] permissions: id-token: write attestations: write @@ -19,12 +16,12 @@ jobs: - uses: GuillaumeFalourd/setup-windows10-sdk-action@v2 with: sdk-version: 22621 - - run: python .github/scripts/build_lunahook.py build ${{ matrix.language }} winxp + - run: python .github/scripts/build_lunahook.py build winxp - run: python .github/scripts/packlunahook.py - uses: actions/upload-artifact@v4 with: - name: ${{ matrix.language }}_winxp + name: winxp path: cpp/LunaHook/builds build_plugin: @@ -71,7 +68,6 @@ jobs: runs-on: windows-latest strategy: matrix: - language: [Chinese,English,Russian,TradChinese] bits: [64] permissions: id-token: write @@ -84,11 +80,11 @@ jobs: - uses: GuillaumeFalourd/setup-windows10-sdk-action@v2 with: sdk-version: 22621 - - run: python .github/scripts/build_lunahook.py build ${{ matrix.language }} ${{matrix.bits}} + - run: python .github/scripts/build_lunahook.py build ${{matrix.bits}} - uses: actions/upload-artifact@v4 with: - name: ${{ matrix.language }}_${{matrix.bits}} + name: ${{matrix.bits}} path: cpp/LunaHook/builds build: diff --git a/cpp/LunaHook/CMakeLists.txt b/cpp/LunaHook/CMakeLists.txt index 0662ab8d..4ccb8974 100644 --- a/cpp/LunaHook/CMakeLists.txt +++ b/cpp/LunaHook/CMakeLists.txt @@ -29,9 +29,6 @@ else() set(bitappendix "32") endif() -if(NOT DEFINED LANGUAGE) - set(LANGUAGE English) -endif() option(BUILD_CORE "BUILD_CORE" ON) option(BUILD_PLUGIN "BUILD_PLUGIN" OFF) option(BUILD_GUI "BUILD_GUI" OFF) @@ -44,10 +41,9 @@ else() set(WINXPAPP "") endif() -add_definitions(-DLANGUAGE=${LANGUAGE}) -set(CMAKE_FINAL_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/builds/${CMAKE_BUILD_TYPE}_x${bitappendix}_${LANGUAGE}${WINXPAPP}) -set(binary_out_putpath ${CMAKE_SOURCE_DIR}/builds/${CMAKE_BUILD_TYPE}_${LANGUAGE}${WINXPAPP}) +set(CMAKE_FINAL_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/builds/${CMAKE_BUILD_TYPE}_x${bitappendix}) +set(binary_out_putpath ${CMAKE_SOURCE_DIR}/builds/${CMAKE_BUILD_TYPE}) #set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY $<1:${CMAKE_FINAL_OUTPUT_DIRECTORY}>) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY $<1:${binary_out_putpath}>) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $<1:${binary_out_putpath}>) @@ -65,6 +61,7 @@ include_directories(include) include(${CMAKE_SOURCE_DIR}/../version.cmake) add_subdirectory(include) +add_subdirectory(Lang) if(BUILD_CORE) add_subdirectory(LunaHook) endif() diff --git a/cpp/LunaHook/Lang/CMakeLists.txt b/cpp/LunaHook/Lang/CMakeLists.txt new file mode 100644 index 00000000..d8fc6e3e --- /dev/null +++ b/cpp/LunaHook/Lang/CMakeLists.txt @@ -0,0 +1,4 @@ + +add_library(lang_hook Lang.cpp Lang_hook.cpp) +add_library(lang_host Lang.cpp Lang_host.cpp) +add_library(lang_ui Lang.cpp Lang_host.cpp Lang_ui.cpp) \ No newline at end of file diff --git a/cpp/LunaHook/Lang/Lang.cpp b/cpp/LunaHook/Lang/Lang.cpp new file mode 100644 index 00000000..5b89df2a --- /dev/null +++ b/cpp/LunaHook/Lang/Lang.cpp @@ -0,0 +1,4 @@ +#include "Lang_private.h" + +SUPPORT_LANG curr_lang = English; +langhelper TR; \ No newline at end of file diff --git a/cpp/LunaHook/Lang/Lang.h b/cpp/LunaHook/Lang/Lang.h index fb0ca69b..9e5fafde 100644 --- a/cpp/LunaHook/Lang/Lang.h +++ b/cpp/LunaHook/Lang/Lang.h @@ -1,22 +1,107 @@ -#pragma warning(push) -#pragma warning(disable: 4005) -#define English 0 -#define Chinese 1 -#define Russian 2 -#define TradChinese 3 -#include"en.h" +enum LANG_STRINGS_UI +{ + WndSelectProcess, + WndLunaHostGui, + TSetting, + TPlugins, + NotifyInvalidHookCode, + BtnDetach, + BtnSaveHook, + BtnAttach, + BtnRefresh, + BtnToClipboard, + BtnReadOnly, + BtnInsertUserHook, + LblFlushDelay, + LblFilterRepeat, + LblCodePage, + LblMaxBuff, + LblMaxHist, + LblLanguage, + LblAutoAttach, + LblAutoAttach_savedonly, + MenuCopyHookCode, + MenuRemoveHook, + MenuDetachProcess, + MenuRemeberSelect, + MenuForgetSelect, + MenuAddPlugin, + MenuRemovePlugin, + MenuPluginRankUp, + MenuPluginRankDown, + MenuPluginEnable, + MenuPluginVisSetting, + DefaultFont, + InvalidPlugin, + InvalidDll, + InvalidDump, + MsgError, + BtnOk, + HS_TEXT, + VersionLatest, + VersionCurrent, + LIST_HOOK, + COPYSELECTION, + FONTSELECT, +}; +enum LANG_STRINGS_HOST +{ + ALREADY_INJECTED, + NEED_32_BIT, + NEED_64_BIT, + INJECT_FAILED, + INVALID_CODEPAGE, + CONSOLE, + PROC_CONN, + PROC_DISCONN, + ProjectHomePage, + UNMATCHABLEVERSION, + T_WARNING, +}; +enum LANG_STRINGS_HOOK +{ + PIPE_CONNECTED, + INSERTING_HOOK, + REMOVING_HOOK, + TOO_MANY_HOOKS, + HOOK_SEARCH_STARTING, + HOOK_SEARCH_INITIALIZING, + NOT_ENOUGH_TEXT, + HOOK_SEARCH_INITIALIZED, + MAKE_GAME_PROCESS_TEXT, + HOOK_SEARCH_FINISHED, + OUT_OF_RECORDS_RETRY, + FUNC_MISSING, + MODULE_MISSING, + GARBAGE_MEMORY, + SEND_ERROR, + READ_ERROR, + SearchForHooks_ERROR, + ResultsNum, + HIJACK_ERROR, + COULD_NOT_FIND, + InvalidLength, + InsertHookFailed, + Match_Error, + Attach_Error, + MatchedEngine, + ConfirmStop, + Attach_Stop, + ProcessRange, + WarningDummy, + RYUJINXUNSUPPORT +}; +enum SUPPORT_LANG; +SUPPORT_LANG map_to_support_lang(const char *); +const char *map_from_support_lang(SUPPORT_LANG); +struct langhelper +{ + const char *operator[](LANG_STRINGS_HOOK); + const wchar_t *operator[](LANG_STRINGS_HOST); + const wchar_t *operator[](LANG_STRINGS_UI); +}; -#if (LANGUAGE == Chinese) -#include"zh.h" -#endif -#if (LANGUAGE == Russian) -#include"ru.h" -#endif -#if (LANGUAGE == TradChinese) -#include"cht.h" -#endif - - -#pragma warning(pop) \ No newline at end of file +extern langhelper TR; +extern SUPPORT_LANG curr_lang; \ No newline at end of file diff --git a/cpp/LunaHook/Lang/Lang_hook.cpp b/cpp/LunaHook/Lang/Lang_hook.cpp new file mode 100644 index 00000000..999142f1 --- /dev/null +++ b/cpp/LunaHook/Lang/Lang_hook.cpp @@ -0,0 +1,184 @@ +#include "Lang_private.h" + +std::unordered_map> _internal_lang_strings_hook = { + {PIPE_CONNECTED, { + {English, u8"pipe connected"}, + {Chinese, u8"管道已连接"}, + {TradChinese, u8"管道已連接"}, + {Russian, u8"Канал подключен"}, + }}, + {INSERTING_HOOK, { + {English, u8"inserting hook: %s %p"}, + {Chinese, u8"注入钩子: %s %p"}, + {TradChinese, u8"注入勾點:%s %p"}, + {Russian, u8"установка хука: %s %p"}, + }}, + {REMOVING_HOOK, { + {English, u8"removing hook: %s"}, + {Chinese, u8"移除钩子: %s"}, + {TradChinese, u8"移除勾點:%s"}, + {Russian, u8"Удаление хука: %s"}, + }}, + {TOO_MANY_HOOKS, { + {English, u8"too many hooks: can't insert"}, + {Chinese, u8"钩子数量已达上限: 无法注入"}, + {TradChinese, u8"勾點數量已達上限:無法注入"}, + {Russian, u8"Слишком много хуков: невозможно добавить"}, + }}, + {HOOK_SEARCH_STARTING, { + {English, u8"starting hook search"}, + {Chinese, u8"开始搜索钩子"}, + {TradChinese, u8"開始搜尋勾點"}, + {Russian, u8"Запущен поиск хуков"}, + }}, + {HOOK_SEARCH_INITIALIZING, { + {English, u8"initializing hook search (%f%%)"}, + {Chinese, u8"初始化钩子搜索 (%f%%)"}, + {TradChinese, u8"初始化勾點搜尋(%f%%)"}, + {Russian, u8"Инициализация поиска хуков (%f%%)"}, + }}, + {NOT_ENOUGH_TEXT, { + {English, u8"not enough text to search accurately"}, + {Chinese, u8"文本长度不足, 无法精确搜索"}, + {TradChinese, u8"文字長度不足,無法精確搜尋"}, + {Russian, u8"Недостаточно текста для точного поиска"}, + }}, + {HOOK_SEARCH_INITIALIZED, { + {English, u8"initialized hook search with %zd hooks"}, + {Chinese, u8"搜索初始化完成, 创建了 %zd 个钩子"}, + {TradChinese, u8"搜尋初始化完成,建立了 %zd 個勾點"}, + {Russian, u8"Поиск хуков инициализирован, найдено %zd хуков"}, + }}, + {MAKE_GAME_PROCESS_TEXT, { + {English, u8"please click around in the game to force it to process text during the next %d seconds"}, + {Chinese, u8"请点击游戏区域, 在接下来的 %d 秒内使游戏强制处理文本"}, + {TradChinese, u8"請點擊遊戲區域,在接下來的 %d 秒內使遊戲強制處理文字"}, + {Russian, u8"Пожалуйста, пощелкайте в игре, чтобы заставить ее обработать текст в течение следующих %d секунд"}, + }}, + {HOOK_SEARCH_FINISHED, { + {English, u8"hook search finished, %d results found"}, + {Chinese, u8"钩子搜索完毕, 找到了 %d 条结果"}, + {TradChinese, u8"勾點搜尋完畢,找到了 %d 條結果"}, + {Russian, u8"Поиск хуков завершен, найдено %d результатов"}, + }}, + {OUT_OF_RECORDS_RETRY, { + {English, u8"out of search records, please retry if results are poor (default record count increased)"}, + {Chinese, u8"搜索结果已达上限, 如果结果不理想, 请重试(默认最大记录数增加)"}, + {TradChinese, u8"搜尋結果已達上限,如果結果不理想,請重試(預設最大紀錄數增加)"}, + {Russian, u8"Закончились записи поиска, попробуйте еще раз, если результаты неудовлетворительны (количество записей по умолчанию увеличено)"}, + }}, + {FUNC_MISSING, { + {English, u8"function not present"}, + {Chinese, u8"函数不存在"}, + {TradChinese, u8"函式不存在"}, + {Russian, u8"Функция не найдена"}, + }}, + {MODULE_MISSING, { + {English, u8"module not present"}, + {Chinese, u8"模块不存在"}, + {TradChinese, u8"模組不存在"}, + {Russian, u8"Модуль не найден"}, + }}, + {GARBAGE_MEMORY, { + {English, u8"memory inline constantly changing, useless to read"}, + {Chinese, u8"内存一直在改变,无法有效读取"}, + {TradChinese, u8"記憶體一直在改變,無法有效讀取"}, + {Russian, u8"Данные в памяти постоянно меняются, чтение бесполезно"}, + }}, + {SEND_ERROR, { + {English, u8"Send ERROR (likely an unstable/incorrect H-code) in %s"}, + {Chinese, u8"Sender 错误 (可能是由于错误或不稳定的 H-code) : %s"}, + {TradChinese, u8"Sender 錯誤(可能是由於錯誤或不穩定的 H-code):%s"}, + {Russian, u8"Ошибка отправки (возможен нестабильный/неверный H-код) в %s"}, + }}, + {READ_ERROR, { + {English, u8"Reader ERROR (likely an incorrect R-code) in %s"}, + {Chinese, u8"Reader 错误 (可能是由于错误或不稳定的 R-code) : %s"}, + {TradChinese, u8"Reader 錯誤(可能是由於錯誤或不穩定的 R-code):%s"}, + {Russian, u8"Ошибка чтения (возможен неверный R-код) в %s"}, + }}, + {SearchForHooks_ERROR, { + {English, u8"SearchForHooks ERROR: out of memory, retrying to allocate %d"}, + {Chinese, u8"搜索钩子错误 : 内存溢出,尝试重新分配 %d"}, + {TradChinese, u8"搜尋勾點錯誤:記憶體溢出,嘗試重新分配 %d"}, + {Russian, u8"Ошибка SearchForHooks: недостаточно памяти, повторная попытка выделения %d"}, + }}, + {ResultsNum, { + {English, u8"%d results processed"}, + {Chinese, u8"%d 个结果被找到"}, + {TradChinese, u8"%d 個結果被找到"}, + {Russian, u8"Обработано %d результатов"}, + }}, + {HIJACK_ERROR, { + {English, u8"Hijack ERROR"}, + }}, + {COULD_NOT_FIND, { + {English, u8"could not find text"}, + {Chinese, u8"无法找到文本"}, + {TradChinese, u8"無法找到文字"}, + {Russian, u8"Не удалось найти текст"}, + }}, + {InvalidLength, { + {English, u8"something went very wrong (invalid length %d in %s)"}, + {Chinese, u8"可能存在错误 (无效的文本长度 %d 出现在 %s)"}, + {TradChinese, u8"可能存在錯誤(無效的文字長度 %d 出現 %s)"}, + {Russian, u8"Произошла критическая ошибка (неверная длина %d в %s)"}, + }}, + {InsertHookFailed, { + {English, u8"failed to insert hook %s"}, + {Chinese, u8"钩子注入失败 %s"}, + {TradChinese, u8"勾點注入失敗 %s"}, + {Russian, u8"Не удалось установить хук %s"}, + }}, + {Match_Error, { + {English, u8"ERROR happened when matching engine %s "}, + {Chinese, u8"匹配 %s 引擎时发生错误"}, + {TradChinese, u8"匹配 %s 引擎時發生錯誤"}, + {Russian, u8"Ошибка при сопоставлении с движком %s"}, + }}, + {Attach_Error, { + {English, u8"ERROR happened when attaching engine %s ERROR"}, + {Chinese, u8"连接到 %s 引擎时发生错误"}, + {TradChinese, u8"連接到 %s 引擎時發生錯誤"}, + {Russian, u8"Ошибка при подключении к движку %s"}, + }}, + {MatchedEngine, { + {English, u8"Matched engine %s"}, + {Chinese, u8"匹配到 %s 引擎"}, + {TradChinese, u8"匹配到 %s 引擎"}, + {Russian, u8"Сопоставлен движок %s"}, + }}, + {ConfirmStop, { + {English, "Confirmed engine %s, stop checking"}, + {Chinese, u8"确认是 %s 引擎, 停止匹配"}, + {TradChinese, u8"確認是 %s 引擎,停止匹配"}, + {Russian, u8"Подтвержден движок %s, поиск остановлен"}, + }}, + {Attach_Stop, { + {English, "Attach engine %s success and stop"}, + {Chinese, u8"成功连接到 %s 引擎"}, + {TradChinese, u8"成功連接到 %s 引擎"}, + {Russian, u8"Движок %s успешно подключен, поиск остановлен"}, + }}, + {ProcessRange, { + {English, "hijacking process located from 0x%p to 0x%p"}, + {Chinese, u8"获取到进程内存地址范围 0x%p 到 0x%p"}, + {TradChinese, u8"取得處理程序記憶體位址範圍 0x%p 到 0x%p"}, + {Russian, u8"Перехват процесса в диапазоне адресов с 0x%p по 0x%p"}, + }}, + {WarningDummy, { + {English, "WARNING injected process is very small, possibly a dummy!"}, + {Chinese, u8"警告,注入的进程内存很小,可能是无用进程!"}, + {TradChinese, u8"警告,注入的處理程序記憶體很小,可能是無用處理程序!"}, + {Russian, u8"ПРЕДУПРЕЖДЕНИЕ: внедренный процесс очень мал, возможно, это пустышка!"}, + }}, + {RYUJINXUNSUPPORT, { + {English, "not support ryuujinx, please use yuzu/sudachi/citron instead."}, + {Chinese, u8"不支持ryuujinz,请使用yuzu/sudachi/citron"}, + {TradChinese, u8"不支持ryuujinz,請使用yuzu/sudachi/citron"}, + {Russian, u8"Не поддерживайте ryuujinz, используйте yuzu / sudachi / citron"}, + }} + +}; + +DEFINEFUNCTION(LANG_STRINGS_HOOK, _internal_lang_strings_hook, char) \ No newline at end of file diff --git a/cpp/LunaHook/Lang/Lang_host.cpp b/cpp/LunaHook/Lang/Lang_host.cpp new file mode 100644 index 00000000..1def87b4 --- /dev/null +++ b/cpp/LunaHook/Lang/Lang_host.cpp @@ -0,0 +1,109 @@ +#include "Lang_private.h" + +std::unordered_map> + _internal_lang_strings_host = { + {T_WARNING, { + {English, L"Warning"}, + {Chinese, L"警告"}, + {TradChinese, L"警告"}, + {Russian, L"ПРЕДУПРЕЖДЕНИЕ"}, + }}, + {ALREADY_INJECTED, { + {English, L"already injected"}, + {Chinese, L"已经注入"}, + {TradChinese, L"已經注入"}, + {Russian, L"Уже внедрено"}, + }}, + {NEED_32_BIT, { + {English, L"architecture mismatch: only x86 can inject this process"}, + {Chinese, L"架构不匹配: 请尝试使用32位注入此进程"}, + {TradChinese, L"架構不匹配:請嘗試使用 32 位元注入此處理程序"}, + {Russian, L"Неверная архетектура: тут нужно x86"}, + }}, + {NEED_64_BIT, { + {English, L"architecture mismatch: only x64 can inject this process"}, + {Chinese, L"架构不匹配: 请尝试使用64位注入此进程"}, + {TradChinese, L"架構不匹配:請嘗試使用 64 位元注入此處理程序"}, + {Russian, L"Неверная архетектура: тут нужно x64"}, + }}, + {INJECT_FAILED, { + {English, L"couldn't inject"}, + {Chinese, L"注入失败"}, + {TradChinese, L"注入失敗"}, + {Russian, L"Не удалось внедрить"}, + }}, + {INVALID_CODEPAGE, { + {English, L"couldn't convert text (invalid codepage?)"}, + {Chinese, L"无法转换文本 (无效的代码页?)"}, + {TradChinese, L"無法轉換文字(無效的字碼頁?)"}, + {Russian, L"Не удалось преобразовать текст (неверная кодовая страница?)"}, + }}, + {CONSOLE, { + {English, L"Console"}, + {Chinese, L"控制台"}, + {TradChinese, L"控制台"}, + {Russian, L"Консоль"}, + }}, + {PROC_CONN, { + {English, L"process connected %d"}, + {Chinese, L"进程 %d 已连接"}, + {TradChinese, L"處理程序已連接 %d"}, + {Russian, L"Процесс подключен %d"}, + }}, + {PROC_DISCONN, { + {English, L"process disconnected %d"}, + {Chinese, L"进程 %d 已断开连接"}, + {TradChinese, L"處理程序已中斷連接 %d"}, + {Russian, L"Процесс отключен %d"}, + }}, + {ProjectHomePage, { + {English, L"Github: https://github.com/HIllya51/LunaTranslator\nHomepage: https://lunatranslator.org\npatreon: https://patreon.com/HIllya51\nDiscord: https://discord.com/invite/ErtDwVeAbB"}, + {Chinese, L"Github: https://github.com/HIllya51/LunaTranslator\n项目主页: https://lunatranslator.org\npatreon:https://patreon.com/HIllya51\nDiscord:https://discord.com/invite/ErtDwVeAbB"}, + {TradChinese, L"GitHub:https://github.com/HIllya51/LunaTranslator\n專案首頁:https://lunatranslator.org\nPatreon:https://patreon.com/HIllya51\nDiscord:https://discord.com/invite/ErtDwVeAbB"}, + {Russian, L"Github: https://github.com/HIllya51/LunaTranslator\nСтраница проекта: https://lunatranslator.org\npatreon: https://patreon.com/HIllya51\nDiscord: https://discord.com/invite/ErtDwVeAbB"}, + }}, + {UNMATCHABLEVERSION, { + {English, L"The file version cannot be matched, may not work properly, please re-download again!"}, + {Chinese, L"文件版本无法匹配,可能无法正常工作,请重新下载!"}, + {TradChinese, L"文件版本不匹配,可能無法正常運作,請重新下載!"}, + {Russian, L"Версии файлов не совпадают и могут не работать должным образом, пожалуйста, загрузите их снова!"}, + }}, +}; + +DEFINEFUNCTION(LANG_STRINGS_HOST, _internal_lang_strings_host, wchar_t) + +std::vector>> lang_map = { + {Chinese, L"简体中文", {"zh"}}, + {TradChinese, L"繁體中文", {"cht", "zh-TW"}}, + {English, L"English", {"en"}}, + {Russian, L"Русский язык", {"ru"}}, +}; + +const char *map_from_support_lang(SUPPORT_LANG _c) +{ + for (auto &&[c, _, ls] : lang_map) + { + if (c == _c) + return ls[0].c_str(); + } + return "en"; +} +SUPPORT_LANG map_to_support_lang(const char *s) +{ + for (auto &&[c, _, ls] : lang_map) + for (auto &&l : ls) + if (l == s) + return c; + + std::string sub = s; + auto _fnd = sub.find('-'); + if (_fnd != sub.npos) + { + sub = sub.substr(0, _fnd); + for (auto &&[c, _, ls] : lang_map) + for (auto &&l : ls) + if (l == sub) + return c; + } + return English; +} diff --git a/cpp/LunaHook/Lang/Lang_private.h b/cpp/LunaHook/Lang/Lang_private.h new file mode 100644 index 00000000..94b7e201 --- /dev/null +++ b/cpp/LunaHook/Lang/Lang_private.h @@ -0,0 +1,19 @@ +#include "Lang.h" +#include +#include +enum SUPPORT_LANG +{ + Chinese, + TradChinese, + English, + Russian, +}; +#define DEFINEFUNCTION(type, mp, ret) \ + const ret *langhelper::operator[](type langstring) \ + { \ + auto &&_ = mp[langstring]; \ + auto &&__ = _.find(curr_lang); \ + if (__ == _.end()) \ + __ = _.find(English); \ + return __->second; \ + } diff --git a/cpp/LunaHook/Lang/Lang_ui.cpp b/cpp/LunaHook/Lang/Lang_ui.cpp new file mode 100644 index 00000000..7694521e --- /dev/null +++ b/cpp/LunaHook/Lang/Lang_ui.cpp @@ -0,0 +1,259 @@ +#include "Lang_private.h" + +std::unordered_map> + _internal_lang_strings_ui = { + {WndSelectProcess, { + {English, L"SelectProcess"}, + {Chinese, L"选择进程"}, + {TradChinese, L"選擇處理程序"}, + {Russian, L"Выбор процесса"}, + }}, + {WndLunaHostGui, { + {English, L"LunaTranslator Hook Simple GUI"}, + }}, + {TSetting, { + {English, L"Settings"}, + {Chinese, L"设置"}, + {TradChinese, L"設定"}, + {Russian, L"Настройки"}, + }}, + {TPlugins, { + {English, L"Plugins"}, + {Chinese, L"插件"}, + {TradChinese, L"外掛程式"}, + {Russian, L"Плагины"}, + }}, + {NotifyInvalidHookCode, { + {English, L"Invalid HookCode"}, + {Chinese, L"特殊码无效"}, + {TradChinese, L"特殊碼無效"}, + {Russian, L"Неверный код хука"}, + }}, + {BtnDetach, { + {English, L"Detach"}, + {Chinese, L"从游戏分离"}, + {TradChinese, L"從遊戲分離"}, + {Russian, L"Отключить"}, + }}, + {BtnSaveHook, { + {English, L"Save hook"}, + {Chinese, L"保存钩子"}, + {TradChinese, L"儲存勾點"}, + {Russian, L"Сохранить хук"}, + }}, + {BtnAttach, { + {English, L"Attach"}, + {Chinese, L"注入进程"}, + {TradChinese, L"注入處理程序"}, + {Russian, L"Подключить"}, + }}, + {BtnRefresh, { + {English, L"Refresh"}, + {Chinese, L"刷新"}, + {TradChinese, L"重新整理"}, + {Russian, L"Обновить"}, + }}, + {BtnToClipboard, { + {English, L"Copy To Clipboard"}, + {Chinese, L"复制到剪贴板"}, + {TradChinese, L"複製到剪貼簿"}, + {Russian, L"Скопировать в буфер обмена"}, + }}, + {BtnReadOnly, { + {English, L"Text box Read only"}, + {Chinese, L"文本框只读"}, + {TradChinese, L"文字框唯讀"}, + {Russian, L"Текстовое поле доступно только для чтения"}, + }}, + {BtnInsertUserHook, { + {English, L"Insert UserHook"}, + {Chinese, L"插入特殊码"}, + {TradChinese, L"插入特殊碼"}, + {Russian, L"Добавить польз. хук"}, + }}, + {LblFlushDelay, { + {English, L"Flush delay"}, + {Chinese, L"刷新延迟"}, + {TradChinese, L"排清延遲"}, + {Russian, L"Задержка сброса"}, + }}, + {LblFilterRepeat, { + {English, L"Filter repetition"}, + {Chinese, L"过滤重复文本"}, + {TradChinese, L"過濾重複文字"}, + {Russian, L"Фильтр повторов"}, + }}, + {LblLanguage, { + {English, L"Language"}, + {Chinese, L"语言"}, + {TradChinese, L"語言"}, + {Russian, L"Язык"}, + }}, + {LblCodePage, { + {English, L"Default codepage"}, + {Chinese, L"默认代码页"}, + {TradChinese, L"預設字碼頁"}, + {Russian, L"Кодовая страница по умолчанию"}, + }}, + {LblMaxBuff, { + {English, L"Max buffer size"}, + {Chinese, L"最大缓冲区长度"}, + {TradChinese, L"最大緩衝區長度"}, + {Russian, L"Максимальный размер буфера"}, + }}, + {LblMaxHist, { + {English, L"Max history size"}, + {Chinese, L"最大缓存文本长度"}, + {TradChinese, L"最大快取文字長度"}, + {Russian, L"Максимальный размер истории"}, + }}, + {LblAutoAttach, { + {English, L"Auto attach"}, + {Chinese, L"自动附加"}, + {TradChinese, L"自動附加"}, + {Russian, L"Автоподключение"}, + }}, + {LblAutoAttach_savedonly, { + {English, L"Auto attach (saved only)"}, + {Chinese, L"自动附加 (仅限保存过配置的游戏)"}, + {TradChinese, L"自動附加(僅限儲存過配置的遊戲)"}, + {Russian, L"Автоподключение (только сохраненные)"}, + }}, + {MenuCopyHookCode, { + {English, L"CopyHookCode"}, + {Chinese, L"复制特殊码"}, + {TradChinese, L"複製特殊碼"}, + {Russian, L"Скопировать код хука"}, + }}, + {MenuRemoveHook, { + {English, L"RemoveHook"}, + {Chinese, L"移除钩子"}, + {TradChinese, L"移除勾點"}, + {Russian, L"Удалить хук"}, + }}, + {MenuDetachProcess, { + {English, L"DetachProcess"}, + {Chinese, L"离开进程"}, + {TradChinese, L"離開處理程序"}, + {Russian, L"Отключиться от процесса"}, + }}, + {MenuRemeberSelect, { + {English, L"Remeber Hook Selection"}, + {Chinese, L"记住选择的钩子"}, + {TradChinese, L"記住選擇的勾點"}, + {Russian, L"Запомнить выбранный хук"}, + }}, + {MenuForgetSelect, { + {English, L"Forget Hook Selection"}, + {Chinese, L"忘掉选择的钩子"}, + {TradChinese, L"忘掉選擇的勾點"}, + {Russian, L"Забыть выбранный хук"}, + }}, + {MenuAddPlugin, { + {English, L"Add Plugin"}, + {Chinese, L"添加插件"}, + {TradChinese, L"新增外掛程式"}, + {Russian, L"Добавить плагин"}, + }}, + {MenuRemovePlugin, { + {English, L"Remove Plugin"}, + {Chinese, L"移除插件"}, + {TradChinese, L"移除外掛程式"}, + {Russian, L"Удалить плагин"}, + }}, + {MenuPluginRankUp, { + {English, L"Up"}, + {Chinese, L"上移"}, + {TradChinese, L"上移"}, + {Russian, L"Вверх"}, + }}, + {MenuPluginRankDown, { + {English, L"Down"}, + {Chinese, L"下移"}, + {TradChinese, L"下移"}, + {Russian, L"Вниз"}, + }}, + {MenuPluginEnable, { + {English, L"Enable"}, + {Chinese, L"使用"}, + {TradChinese, L"使用"}, + {Russian, L"Включить"}, + }}, + {MenuPluginVisSetting, { + {English, L"Show Setting"}, + {Chinese, L"显示设置"}, + {TradChinese, L"顯示設定"}, + {Russian, L"Показать настройки"}, + }}, + {DefaultFont, { + {English, L"Arial"}, + {Chinese, L"微软雅黑"}, + {TradChinese, L"Microsoft JhengHei"}, + {Russian, L"Arial"}, + }}, + {InvalidPlugin, { + {English, L"Invalid Plugin!"}, + {Chinese, L"插件无效!"}, + {TradChinese, L"外掛程式無效!"}, + {Russian, L"Неверный плагин!"}, + }}, + {InvalidDll, { + {English, L"Invalid Dll!"}, + {Chinese, L"Dll无效!"}, + {TradChinese, L"DLL 無效!"}, + {Russian, L"Неверная DLL!"}, + }}, + {InvalidDump, { + {English, L"Dumplicated!"}, + {Chinese, L"重复!"}, + {TradChinese, L"重複!"}, + {Russian, L"Дубликат!"}, + }}, + {MsgError, { + {English, L"Error"}, + {Chinese, L"错误"}, + {TradChinese, L"錯誤"}, + {Russian, L"Ошибка"}, + }}, + {BtnOk, { + {English, L"OK"}, + {Chinese, L"确定"}, + {TradChinese, L"確定"}, + {Russian, L"OK"}, + }}, + {HS_TEXT, { + {English, L"Text"}, + {Chinese, L"文本"}, + {TradChinese, L"文字"}, + {Russian, L"Текст"}, + }}, + {VersionLatest, { + {English, L"Latest version"}, + {Chinese, L"最新版本"}, + {TradChinese, L"最新版本"}, + {Russian, L"Последняя версия"}, + }}, + {VersionCurrent, { + {English, L"Current version"}, + {Chinese, L"当前版本"}, + {TradChinese, L"目前版本"}, + {Russian, L"Текущая версия"}, + }}, + {LIST_HOOK, { + {English, L"Hook"}, + }}, + {COPYSELECTION, { + {English, L"auto send selected text in textbox to clipboard"}, + {Chinese, L"自动将文本框中选取的文本复制到剪贴板"}, + {TradChinese, L"自動將文字框中選取的文字複製到剪貼簿"}, + {Russian, L"Автоматически копировать выделенный текст в буфер обмена"}, + }}, + {FONTSELECT, { + {English, L"Select Font"}, + {Chinese, L"选择字体"}, + {TradChinese, L"選擇字體"}, + {Russian, L"Выбрать шрифт"}, + }}, +}; + +DEFINEFUNCTION(LANG_STRINGS_UI, _internal_lang_strings_ui, wchar_t) diff --git a/cpp/LunaHook/Lang/cht.h b/cpp/LunaHook/Lang/cht.h deleted file mode 100644 index 3cc5197d..00000000 --- a/cpp/LunaHook/Lang/cht.h +++ /dev/null @@ -1,102 +0,0 @@ - -#define ALREADY_INJECTED L"已經注入" -#define NEED_32_BIT L"架構不匹配:請嘗試使用 32 位元注入此處理程序" -#define NEED_64_BIT L"架構不匹配:請嘗試使用 64 位元注入此處理程序" -#define INJECT_FAILED L"注入失敗" -#define INVALID_CODEPAGE L"無法轉換文字(無效的字碼頁?)" -#define PIPE_CONNECTED u8"管道已連接" -#define INSERTING_HOOK u8"注入勾點:%s %p" -#define REMOVING_HOOK u8"移除勾點:%s" -#define TOO_MANY_HOOKS u8"勾點數量已達上限:無法注入" -#define HOOK_SEARCH_STARTING u8"開始搜尋勾點" -#define HOOK_SEARCH_INITIALIZING u8"初始化勾點搜尋(%f%%)" -#define NOT_ENOUGH_TEXT u8"文字長度不足,無法精確搜尋" -#define HOOK_SEARCH_INITIALIZED u8"搜尋初始化完成,建立了 %zd 個勾點" -#define MAKE_GAME_PROCESS_TEXT u8"請點擊遊戲區域,在接下來的 %d 秒內使遊戲強制處理文字" -#define HOOK_SEARCH_FINISHED u8"勾點搜尋完畢,找到了 %d 條結果" -#define OUT_OF_RECORDS_RETRY u8"搜尋結果已達上限,如果結果不理想,請重試(預設最大紀錄數增加)" -#define FUNC_MISSING u8"函式不存在" -#define MODULE_MISSING u8"模組不存在" -#define GARBAGE_MEMORY u8"記憶體一直在改變,無法有效讀取" -#define SEND_ERROR u8"Sender 錯誤(可能是由於錯誤或不穩定的 H-code):%s" -#define READ_ERROR u8"Reader 錯誤(可能是由於錯誤或不穩定的 R-code):%s" -#define SearchForHooks_ERROR u8"搜尋勾點錯誤:記憶體移除,嘗試重新分配 %d" -#define ResultsNum u8"%d 個結果被找到" -#define HIJACK_ERROR u8"Hijack 錯誤" -#define COULD_NOT_FIND u8"無法找到文字" -#define CONSOLE L"控制台" -#define InvalidLength u8"可能存在錯誤(無效的文字長度 %d 出現 %s)" -#define InsertHookFailed u8"勾點注入失敗 %s" -#define Match_Error u8"匹配 %s 引擎時發生錯誤" -#define Attach_Error u8"連接到 %s 引擎時發生錯誤" -#define MatchedEngine u8"匹配到 %s 引擎" -#define ConfirmStop u8"確認是 %s 引擎,停止匹配" -#define Attach_Stop u8"成功連接到 %s 引擎" -#define ProcessRange u8"取得處理程序記憶體位址範圍 0x%p 到 0x%p" -#define WarningDummy u8"警告,注入的處理程序記憶體很小,可能是無用處理程序!" -#define WndSelectProcess L"選擇處理程序" -#define WndLunaHostGui L"LunaHost GUI" -#define WndSetting L"設定" -#define WndPlugins L"外掛程式" -#define NotifyInvalidHookCode L"特殊碼無效" -#define BtnSelectProcess L"選擇處理程序" -#define BtnDetach L"從遊戲分離" -#define BtnSaveHook L"儲存勾點" -#define BtnShowSettingWindow L"設定" -#define BtnAttach L"注入處理程序" -#define BtnRefresh L"重新整理" -#define BtnToClipboard L"複製到剪貼簿" -#define BtnReadOnly L"文字框唯讀" -#define BtnInsertUserHook L"插入特殊碼" -#define BtnSearchHook L"搜尋勾點" -#define BtnPlugin L"外掛程式" -#define LblFlushDelay L"排清延遲" -#define LblFilterRepeat L"過濾重複文字" -#define LblCodePage L"預設字碼頁" -#define LblMaxBuff L"最大緩衝區長度" -#define LblMaxHist L"最大快取文字長度" -#define LblAutoAttach L"自動附加" -#define LblAutoAttach_savedonly L"自動附加(僅限儲存過配置的遊戲)" -#define MenuCopyHookCode L"複製特殊碼" -#define MenuRemoveHook L"移除勾點" -#define MenuDetachProcess L"離開處理程序" -#define MenuRemeberSelect L"記住選擇的勾點" -#define MenuForgetSelect L"忘掉選擇的勾點" -#define MenuAddPlugin L"新增外掛程式" -#define MenuRemovePlugin L"移除外掛程式" -#define MenuPluginRankUp L"上移" -#define MenuPluginRankDown L"下移" -#define MenuPluginEnable L"使用" -#define MenuPluginVisSetting L"顯示設定" -#define DefaultFont L"Microsoft JhengHei" -#define CantLoadQtLoader L"無法載入 QtLoader.dll" -#define InvalidPlugin L"外掛程式無效!" -#define InvalidDll L"DLL 無效!" -#define InvalidDump L"重複!" -#define MsgError L"錯誤" -#define SEARCH_CJK L"搜尋中文 / 日文 / 韓文" -#define HS_SETTINGS L"設定" -#define BtnOk L"確定" -#define HS_START_HOOK_SEARCH L"開始搜尋勾點" -#define HS_SEARCH_PATTERN L"搜尋匹配特徵(Hex Byte Array)" -#define HS_SEARCH_DURATION L"搜尋持續時間(ms)" -#define HS_SEARCH_MODULE L"搜尋指定模組" -#define HS_PATTERN_OFFSET L"相對於特徵位址的偏移值" -#define HS_MAX_HOOK_SEARCH_RECORDS L"搜尋結果達到上限" -#define HS_MIN_ADDRESS L"起始位址(hex)" -#define HS_MAX_ADDRESS L"結束位址(hex)" -#define HS_STRING_OFFSET L"字串偏移值(hex)" -#define HS_HOOK_SEARCH_FILTER L"結果必須匹配的正則表達式" -#define HS_TEXT L"文字" -#define HS_CODEPAGE L"字碼頁" -#define HS_SEARCH_FOR_TEXT L"搜尋指定文字" -#define VersionLatest L"最新版本" -#define VersionCurrent L"目前版本" -#define ProjectHomePage L"GitHub:https://github.com/HIllya51/LunaTranslator\n專案首頁:https://lunatranslator.org\nPatreon:https://patreon.com/HIllya51\nDiscord:https://discord.com/invite/ErtDwVeAbB" -#define LIST_HOOK L"Hook" -#define LIST_TEXT L"文字" -#define PROC_CONN L"處理程序已連接 %d" -#define PROC_DISCONN L"處理程序已中斷連接 %d" -#define COPYSELECTION L"自動將文字框中選取的文字複製到剪貼簿" -#define FONTSELECT L"選擇字體" -#define UNMATCHABLEVERSION L"文件版本不匹配,可能無法正常運作,請重新下載!" \ No newline at end of file diff --git a/cpp/LunaHook/Lang/en.h b/cpp/LunaHook/Lang/en.h deleted file mode 100644 index 9ae6bbb1..00000000 --- a/cpp/LunaHook/Lang/en.h +++ /dev/null @@ -1,102 +0,0 @@ - -#define ALREADY_INJECTED L"already injected" -#define NEED_32_BIT L"architecture mismatch: only x86 can inject this process" -#define NEED_64_BIT L"architecture mismatch: only x64 can inject this process" -#define INJECT_FAILED L"couldn't inject" -#define INVALID_CODEPAGE L"couldn't convert text (invalid codepage?)" -#define PIPE_CONNECTED u8"pipe connected" -#define INSERTING_HOOK u8"inserting hook: %s %p" -#define REMOVING_HOOK u8"removing hook: %s" -#define TOO_MANY_HOOKS u8"too many hooks: can't insert" -#define HOOK_SEARCH_STARTING u8"starting hook search" -#define HOOK_SEARCH_INITIALIZING u8"initializing hook search (%f%%)" -#define NOT_ENOUGH_TEXT u8"not enough text to search accurately" -#define HOOK_SEARCH_INITIALIZED u8"initialized hook search with %zd hooks" -#define MAKE_GAME_PROCESS_TEXT u8"please click around in the game to force it to process text during the next %d seconds" -#define HOOK_SEARCH_FINISHED u8"hook search finished, %d results found" -#define OUT_OF_RECORDS_RETRY u8"out of search records, please retry if results are poor (default record count increased)" -#define FUNC_MISSING u8"function not present" -#define MODULE_MISSING u8"module not present" -#define GARBAGE_MEMORY u8"memory inline constantly changing, useless to read" -#define SEND_ERROR u8"Send ERROR (likely an unstable/incorrect H-code) in %s" -#define READ_ERROR u8"Reader ERROR (likely an incorrect R-code) in %s" -#define SearchForHooks_ERROR u8"SearchForHooks ERROR: out of memory, retrying to allocate %d" -#define ResultsNum u8"%d results processed" -#define HIJACK_ERROR u8"Hijack ERROR" -#define COULD_NOT_FIND u8"could not find text" -#define CONSOLE L"Console" -#define InvalidLength u8"something went very wrong (invalid length %d in %s)" -#define InsertHookFailed u8"failed to insert hook %s" -#define Match_Error u8"ERROR happened when matching engine %s " -#define Attach_Error u8"ERROR happened when attaching engine %s ERROR" -#define MatchedEngine u8"Matched engine %s" -#define ConfirmStop "Confirmed engine %s, stop checking" -#define Attach_Stop "Attach engine %s success and stop" -#define ProcessRange "hijacking process located from 0x%p to 0x%p" -#define WarningDummy "WARNING injected process is very small, possibly a dummy!" -#define WndSelectProcess L"SelectProcess" -#define WndLunaHostGui L"LunaHost GUI" -#define WndSetting L"Setting" -#define WndPlugins L"Plugins" -#define NotifyInvalidHookCode L"Invalid HookCode" -#define BtnSelectProcess L"Select Process" -#define BtnDetach L"Detach" -#define BtnSaveHook L"Save hook" -#define BtnShowSettingWindow L"Settings" -#define BtnAttach L"Attach" -#define BtnRefresh L"Refresh" -#define BtnToClipboard L"Copy To Clipboard" -#define BtnReadOnly L"Text box Read only" -#define BtnInsertUserHook L"Insert UserHook" -#define BtnSearchHook L"Search for hooks" -#define BtnPlugin L"Plugins" -#define LblFlushDelay L"Flush delay" -#define LblFilterRepeat L"Filter repetition" -#define LblCodePage L"Default codepage" -#define LblMaxBuff L"Max buffer size" -#define LblMaxHist L"Max history size" -#define LblAutoAttach L"Auto attach" -#define LblAutoAttach_savedonly L"Auto attach (saved only)" -#define MenuCopyHookCode L"CopyHookCode" -#define MenuRemoveHook L"RemoveHook" -#define MenuDetachProcess L"DetachProcess" -#define MenuRemeberSelect L"Remeber Hook Selection" -#define MenuForgetSelect L"Forget Hook Selection" -#define MenuAddPlugin L"Add Plugin" -#define MenuRemovePlugin L"Remove Plugin" -#define MenuPluginRankUp L"Up" -#define MenuPluginRankDown L"Down" -#define MenuPluginEnable L"Enable" -#define MenuPluginVisSetting L"Show Setting" -#define DefaultFont L"Arial" -#define CantLoadQtLoader L"Can't Load QtLoader.dll" -#define InvalidPlugin L"Invalid Plugin!" -#define InvalidDll L"Invalid Dll!" -#define InvalidDump L"Dumplicated!" -#define MsgError L"Error" -#define SEARCH_CJK L"Search for Chinese/Japanese/Korean" -#define HS_SETTINGS L"Settings" -#define BtnOk L"OK" -#define HS_START_HOOK_SEARCH L"Start hook search" -#define HS_SEARCH_PATTERN L"Search pattern (hex byte array)" -#define HS_SEARCH_DURATION L"Search duration (ms)" -#define HS_SEARCH_MODULE L"Search within module" -#define HS_PATTERN_OFFSET L"Offset from pattern start" -#define HS_MAX_HOOK_SEARCH_RECORDS L"Search result cap" -#define HS_MIN_ADDRESS L"Minimum address (hex)" -#define HS_MAX_ADDRESS L"Maximum address (hex)" -#define HS_STRING_OFFSET L"String offset (hex)" -#define HS_HOOK_SEARCH_FILTER L"Results must match this regex" -#define HS_TEXT L"Text" -#define HS_CODEPAGE L"Codepage" -#define HS_SEARCH_FOR_TEXT L"Search for specific text" -#define VersionLatest L"Latest version" -#define VersionCurrent L"Current version" -#define ProjectHomePage L"Github: https://github.com/HIllya51/LunaTranslator\nHomepage: https://lunatranslator.org\npatreon: https://patreon.com/HIllya51\nDiscord: https://discord.com/invite/ErtDwVeAbB" -#define LIST_HOOK L"Hook" -#define LIST_TEXT L"Text" -#define PROC_CONN L"process connected %d" -#define PROC_DISCONN L"process disconnected %d" -#define COPYSELECTION L"auto send selected text in textbox to clipboard" -#define FONTSELECT L"Select Font" -#define UNMATCHABLEVERSION L"The file version cannot be matched, may not work properly, please re-download again!" \ No newline at end of file diff --git a/cpp/LunaHook/Lang/ru.h b/cpp/LunaHook/Lang/ru.h deleted file mode 100644 index 231706b9..00000000 --- a/cpp/LunaHook/Lang/ru.h +++ /dev/null @@ -1,102 +0,0 @@ - -#define ALREADY_INJECTED L"Уже внедрено" -#define NEED_32_BIT L"Неверная архетектура: тут нужно x86" -#define NEED_64_BIT L"Неверная архетектура: тут нужно x64" -#define INJECT_FAILED L"Не удалось внедрить" -#define INVALID_CODEPAGE L"Не удалось преобразовать текст (неверная кодовая страница?)" -#define PIPE_CONNECTED u8"Канал подключен" -#define INSERTING_HOOK u8"установка хука: %s %p" -#define REMOVING_HOOK u8"Удаление хука: %s" -#define TOO_MANY_HOOKS u8"Слишком много хуков: невозможно добавить" -#define HOOK_SEARCH_STARTING u8"Запущен поиск хуков" -#define HOOK_SEARCH_INITIALIZING u8"Инициализация поиска хуков (%f%%)" -#define NOT_ENOUGH_TEXT u8"Недостаточно текста для точного поиска" -#define HOOK_SEARCH_INITIALIZED u8"Поиск хуков инициализирован, найдено %zd хуков" -#define MAKE_GAME_PROCESS_TEXT u8"Пожалуйста, пощелкайте в игре, чтобы заставить ее обработать текст в течение следующих %d секунд" -#define HOOK_SEARCH_FINISHED u8"Поиск хуков завершен, найдено %d результатов" -#define OUT_OF_RECORDS_RETRY u8"Закончились записи поиска, попробуйте еще раз, если результаты неудовлетворительны (количество записей по умолчанию увеличено)" -#define FUNC_MISSING u8"Функция не найдена" -#define MODULE_MISSING u8"Модуль не найден" -#define GARBAGE_MEMORY u8"Данные в памяти постоянно меняются, чтение бесполезно" -#define SEND_ERROR u8"Ошибка отправки (возможен нестабильный/неверный H-код) в %s" -#define READ_ERROR u8"Ошибка чтения (возможен неверный R-код) в %s" -#define SearchForHooks_ERROR u8"Ошибка SearchForHooks: недостаточно памяти, повторная попытка выделения %d" -#define ResultsNum u8"Обработано %d результатов" -#define HIJACK_ERROR u8"Ошибка перехвата" -#define COULD_NOT_FIND u8"Не удалось найти текст" -#define CONSOLE L"Консоль" -#define InvalidLength u8"Произошла критическая ошибка (неверная длина %d в %s)" -#define InsertHookFailed u8"Не удалось установить хук %s" -#define Match_Error u8"Ошибка при сопоставлении с движком %s" -#define Attach_Error u8"Ошибка при подключении к движку %s" -#define MatchedEngine u8"Сопоставлен движок %s" -#define ConfirmStop u8"Подтвержден движок %s, поиск остановлен" -#define Attach_Stop u8"Движок %s успешно подключен, поиск остановлен" -#define ProcessRange u8"Перехват процесса в диапазоне адресов с 0x%p по 0x%p" -#define WarningDummy u8"ПРЕДУПРЕЖДЕНИЕ: внедренный процесс очень мал, возможно, это пустышка!" -#define WndSelectProcess L"Выбор процесса" -#define WndLunaHostGui L"LunaHost - GUI" -#define WndSetting L"Настройки" -#define WndPlugins L"Плагины" -#define NotifyInvalidHookCode L"Неверный код хука" -#define BtnSelectProcess L"Выбрать процесс" -#define BtnDetach L"Отключить" -#define BtnSaveHook L"Сохранить хук" -#define BtnShowSettingWindow L"Настройки" -#define BtnAttach L"Подключить" -#define BtnRefresh L"Обновить" -#define BtnToClipboard L"Скопировать в буфер обмена" -#define BtnReadOnly L"Текстовое поле доступно только для чтения" -#define BtnInsertUserHook L"Добавить польз. хук" -#define BtnSearchHook L"Найти хуки" -#define BtnPlugin L"Плагины" -#define LblFlushDelay L"Задержка сброса" -#define LblFilterRepeat L"Фильтр повторов" -#define LblCodePage L"Кодовая страница по умолчанию" -#define LblMaxBuff L"Максимальный размер буфера" -#define LblMaxHist L"Максимальный размер истории" -#define LblAutoAttach L"Автоподключение" -#define LblAutoAttach_savedonly L"Автоподключение (только сохраненные)" -#define MenuCopyHookCode L"Скопировать код хука" -#define MenuRemoveHook L"Удалить хук" -#define MenuDetachProcess L"Отключиться от процесса" -#define MenuRemeberSelect L"Запомнить выбранный хук" -#define MenuForgetSelect L"Забыть выбранный хук" -#define MenuAddPlugin L"Добавить плагин" -#define MenuRemovePlugin L"Удалить плагин" -#define MenuPluginRankUp L"Вверх" -#define MenuPluginRankDown L"Вниз" -#define MenuPluginEnable L"Включить" -#define MenuPluginVisSetting L"Показать настройки" -#define DefaultFont L"Arial" -#define CantLoadQtLoader L"Не удалось загрузить QtLoader.dll" -#define InvalidPlugin L"Неверный плагин!" -#define InvalidDll L"Неверная DLL!" -#define InvalidDump L"Дубликат!" -#define MsgError L"Ошибка" -#define SEARCH_CJK L"Искать китайские/японские/корейские символы" -#define HS_SETTINGS L"Настройки" -#define BtnOk L"OK" -#define HS_START_HOOK_SEARCH L"Начать поиск хуков" -#define HS_SEARCH_PATTERN L"Шаблон поиска (массив шестнадцатеричных байтов)" -#define HS_SEARCH_DURATION L"Длительность поиска (мс)" -#define HS_SEARCH_MODULE L"Искать внутри модуля" -#define HS_PATTERN_OFFSET L"Смещение от начала шаблона" -#define HS_MAX_HOOK_SEARCH_RECORDS L"Максимальное количество результатов поиска" -#define HS_MIN_ADDRESS L"Минимальный адрес (шестнадцатеричный)" -#define HS_MAX_ADDRESS L"Максимальный адрес (шестнадцатеричный)" -#define HS_STRING_OFFSET L"Смещение строки (шестнадцатеричное)" -#define HS_HOOK_SEARCH_FILTER L"Результаты должны соответствовать этому регулярному выражению" -#define HS_TEXT L"Текст" -#define HS_CODEPAGE L"Кодовая страница" -#define HS_SEARCH_FOR_TEXT L"Искать определенный текст" -#define VersionLatest L"Последняя версия" -#define VersionCurrent L"Текущая версия" -#define ProjectHomePage L"Github: https://github.com/HIllya51/LunaTranslator\nСтраница проекта: https://lunatranslator.org\npatreon: https://patreon.com/HIllya51\nDiscord: https://discord.com/invite/ErtDwVeAbB" -#define LIST_HOOK L"Хук" -#define LIST_TEXT L"Текст" -#define PROC_CONN L"Процесс подключен %d" -#define PROC_DISCONN L"Процесс отключен %d" -#define COPYSELECTION L"Автоматически копировать выделенный текст в буфер обмена" -#define FONTSELECT L"Выбрать шрифт" -#define UNMATCHABLEVERSION L"Версии файлов не совпадают и могут не работать должным образом, пожалуйста, загрузите их снова!" \ No newline at end of file diff --git a/cpp/LunaHook/Lang/zh.h b/cpp/LunaHook/Lang/zh.h deleted file mode 100644 index cd843294..00000000 --- a/cpp/LunaHook/Lang/zh.h +++ /dev/null @@ -1,102 +0,0 @@ - -#define ALREADY_INJECTED L"已经注入" -#define NEED_32_BIT L"架构不匹配: 请尝试使用32位注入此进程" -#define NEED_64_BIT L"架构不匹配: 请尝试使用64位注入此进程" -#define INJECT_FAILED L"注入失败" -#define INVALID_CODEPAGE L"无法转换文本 (无效的代码页?)" -#define PIPE_CONNECTED u8"管道已连接" -#define INSERTING_HOOK u8"注入钩子: %s %p" -#define REMOVING_HOOK u8"移除钩子: %s" -#define TOO_MANY_HOOKS u8"钩子数量已达上限: 无法注入" -#define HOOK_SEARCH_STARTING u8"开始搜索钩子" -#define HOOK_SEARCH_INITIALIZING u8"初始化钩子搜索 (%f%%)" -#define NOT_ENOUGH_TEXT u8"文本长度不足, 无法精确搜索" -#define HOOK_SEARCH_INITIALIZED u8"搜索初始化完成, 创建了 %zd 个钩子" -#define MAKE_GAME_PROCESS_TEXT u8"请点击游戏区域, 在接下来的 %d 秒内使游戏强制处理文本" -#define HOOK_SEARCH_FINISHED u8"钩子搜索完毕, 找到了 %d 条结果" -#define OUT_OF_RECORDS_RETRY u8"搜索结果已达上限, 如果结果不理想, 请重试(默认最大记录数增加)" -#define FUNC_MISSING u8"函数不存在" -#define MODULE_MISSING u8"模块不存在" -#define GARBAGE_MEMORY u8"内存一直在改变,无法有效读取" -#define SEND_ERROR u8"Sender 错误 (可能是由于错误或不稳定的 H-code) : %s" -#define READ_ERROR u8"Reader 错误 (可能是由于错误或不稳定的 R-code) : %s" -#define SearchForHooks_ERROR u8"搜索钩子错误 : 内存移除,尝试重新分配 %d" -#define ResultsNum u8"%d 个结果被找到" -#define HIJACK_ERROR u8"Hijack 错误" -#define COULD_NOT_FIND u8"无法找到文本" -#define CONSOLE L"控制台" -#define InvalidLength u8"可能存在错误 (无效的文本长度 %d 出现 %s)" -#define InsertHookFailed u8"钩子注入失败 %s" -#define Match_Error u8"匹配 %s 引擎时发生错误" -#define Attach_Error u8"连接到 %s 引擎时发送错误" -#define MatchedEngine u8"匹配到 %s 引擎" -#define ConfirmStop u8"确认是 %s 引擎, 停止匹配" -#define Attach_Stop u8"成功连接到 %s 引擎" -#define ProcessRange u8"获取到进程内存地址范围 0x%p 到 0x%p" -#define WarningDummy u8"警告,注入的进程内存很小,可能是无用进程!" -#define WndSelectProcess L"选择进程" -#define WndLunaHostGui L"LunaHost GUI" -#define WndSetting L"设置" -#define WndPlugins L"插件" -#define NotifyInvalidHookCode L"特殊码无效" -#define BtnSelectProcess L"选择进程" -#define BtnDetach L"从游戏分离" -#define BtnSaveHook L"保存钩子" -#define BtnShowSettingWindow L"设置" -#define BtnAttach L"注入进程" -#define BtnRefresh L"刷新" -#define BtnToClipboard L"复制到剪贴板" -#define BtnReadOnly L"文本框只读" -#define BtnInsertUserHook L"插入特殊码" -#define BtnSearchHook L"搜索钩子" -#define BtnPlugin L"插件" -#define LblFlushDelay L"刷新延迟" -#define LblFilterRepeat L"过滤重复文本" -#define LblCodePage L"默认代码页" -#define LblMaxBuff L"最大缓冲区长度" -#define LblMaxHist L"最大缓存文本长度" -#define LblAutoAttach L"自动附加" -#define LblAutoAttach_savedonly L"自动附加 (仅限保存过配置的游戏)" -#define MenuCopyHookCode L"复制特殊码" -#define MenuRemoveHook L"移除钩子" -#define MenuDetachProcess L"离开进程" -#define MenuRemeberSelect L"记住选择的钩子" -#define MenuForgetSelect L"忘掉选择的钩子" -#define MenuAddPlugin L"添加插件" -#define MenuRemovePlugin L"移除插件" -#define MenuPluginRankUp L"上移" -#define MenuPluginRankDown L"下移" -#define MenuPluginEnable L"使用" -#define MenuPluginVisSetting L"显示设置" -#define DefaultFont L"微软雅黑" -#define CantLoadQtLoader L"无法加载QtLoader.dll" -#define InvalidPlugin L"插件无效!" -#define InvalidDll L"Dll无效!" -#define InvalidDump L"重复!" -#define MsgError L"错误" -#define SEARCH_CJK L"搜索中文/日文/韩文" -#define HS_SETTINGS L"设置" -#define BtnOk L"确定" -#define HS_START_HOOK_SEARCH L"开始搜索钩子" -#define HS_SEARCH_PATTERN L"搜索匹配特征 (hex byte array)" -#define HS_SEARCH_DURATION L"搜索持续时间 (ms)" -#define HS_SEARCH_MODULE L"搜索指定模块" -#define HS_PATTERN_OFFSET L"相对于特征地址的偏移值" -#define HS_MAX_HOOK_SEARCH_RECORDS L"搜索结果达到上限" -#define HS_MIN_ADDRESS L"起始地址 (hex)" -#define HS_MAX_ADDRESS L"结束地址 (hex)" -#define HS_STRING_OFFSET L"字符串偏移值 (hex)" -#define HS_HOOK_SEARCH_FILTER L"结果必须匹配的正则表达式" -#define HS_TEXT L"文本" -#define HS_CODEPAGE L"代码页" -#define HS_SEARCH_FOR_TEXT L"搜索指定文本" -#define VersionLatest L"最新版本" -#define VersionCurrent L"当前版本" -#define ProjectHomePage L"Github: https://github.com/HIllya51/LunaTranslator\n项目主页: https://lunatranslator.org\npatreon:https://patreon.com/HIllya51\nDiscord:https://discord.com/invite/ErtDwVeAbB" -#define LIST_HOOK L"Hook" -#define LIST_TEXT L"文本" -#define PROC_CONN L"进程已连接 %d" -#define PROC_DISCONN L"进程已断开连接 %d" -#define COPYSELECTION L"自动将文本框中选取的文本复制到剪贴板" -#define FONTSELECT L"选择字体" -#define UNMATCHABLEVERSION L"文件版本无法匹配,可能无法正常工作,请重新下载!" \ No newline at end of file diff --git a/cpp/LunaHook/LunaHook/CMakeLists.txt b/cpp/LunaHook/LunaHook/CMakeLists.txt index b70c1135..222d5ad8 100644 --- a/cpp/LunaHook/LunaHook/CMakeLists.txt +++ b/cpp/LunaHook/LunaHook/CMakeLists.txt @@ -51,4 +51,4 @@ target_precompile_headers(LunaHook REUSE_FROM pchhook) set_target_properties(LunaHook PROPERTIES OUTPUT_NAME "LunaHook${bitappendix}") -target_link_libraries(LunaHook VERSION_DEF Version httpapi ws2_32 Shlwapi pch minhook commonengine utils ${YY_Thunks_for_WinXP}) \ No newline at end of file +target_link_libraries(LunaHook lang_hook VERSION_DEF Version httpapi ws2_32 Shlwapi pch minhook commonengine utils ${YY_Thunks_for_WinXP}) \ No newline at end of file diff --git a/cpp/LunaHook/LunaHook/engine32/DAC.cpp b/cpp/LunaHook/LunaHook/engine32/DAC.cpp index 8ab53425..9992a07c 100644 --- a/cpp/LunaHook/LunaHook/engine32/DAC.cpp +++ b/cpp/LunaHook/LunaHook/engine32/DAC.cpp @@ -18,7 +18,7 @@ bool DAC::attach_function() if (!addr) return false; HookParam hp; - hp.address = 0x431040; + hp.address = addr; hp.offset = stackoffset(2); hp.type = USING_STRING; hp.user_value = (DWORD) new std::map; diff --git a/cpp/LunaHook/LunaHook/engine64/Ryujinx.cpp b/cpp/LunaHook/LunaHook/engine64/Ryujinx.cpp index 996e0f43..dc26882c 100644 --- a/cpp/LunaHook/LunaHook/engine64/Ryujinx.cpp +++ b/cpp/LunaHook/LunaHook/engine64/Ryujinx.cpp @@ -67,7 +67,7 @@ struct passinfo }; bool Ryujinx::attach_function() { - HostInfo(HOSTINFO::Warning, "not support ryuujinx, please use yuzu/sudachi instead."); + HostInfo(HOSTINFO::Warning, TR[RYUJINXUNSUPPORT]); return true; /* UnsafeJitFunction diff --git a/cpp/LunaHook/LunaHook/engine64/vita3k.cpp b/cpp/LunaHook/LunaHook/engine64/vita3k.cpp index 9e310b53..33a37668 100644 --- a/cpp/LunaHook/LunaHook/engine64/vita3k.cpp +++ b/cpp/LunaHook/LunaHook/engine64/vita3k.cpp @@ -146,23 +146,27 @@ namespace s = std::regex_replace(s, std::regex("\n"), ""); buffer->from(s); } - template - void FPCSG01282(TextBuffer *buffer, HookParam *hp) + void FPCSG01282_1(TextBuffer *buffer, HookParam *hp) { auto s = buffer->strA(); s = std::regex_replace(s, std::regex("(\\n)+"), " "); s = std::regex_replace(s, std::regex("\\d$|^@[a-z]+|#.*?#|\\$"), ""); + buffer->from(s); + } + template + void FPCSG01282(TextBuffer *buffer, HookParam *hp) + { + FPCSG01282_1(buffer, hp); static std::string last; + auto s = buffer->viewA(); if (last == s) return buffer->clear(); last = s; - buffer->from(s); } - template void ReadU16TextAndLenDW(hook_context *context, HookParam *hp, TextBuffer *buffer, uintptr_t *split) { - auto address = VITA3K::emu_arg(context)[index]; + auto address = VITA3K::emu_arg(context)[hp->offset]; buffer->from(address + 0xC, (*(DWORD *)(address + 0x8)) * 2); } @@ -494,14 +498,9 @@ namespace s = std::regex_replace(s, std::regex(R"(#\w.+?])"), ""); buffer->from(s); } - template - void FPCSG00855_2(TextBuffer *buffer, HookParam *hp) + void FPCSG00855_2_1(TextBuffer *buffer, HookParam *hp) { auto s = buffer->strA(); - static std::string last; - if (last == s) - return buffer->clear(); - last = s; strReplace(s, u8"Χ", u8"、"); strReplace(s, u8"Δ", u8"。"); strReplace(s, u8"Λ", u8"っ"); @@ -516,6 +515,15 @@ namespace buffer->from(s); FPCSG00855(buffer, hp); } + template + void FPCSG00855_2(TextBuffer *buffer, HookParam *hp) + { + auto s = buffer->viewA(); + static std::string last; + if (last == s) + return buffer->clear(); + FPCSG00855_2_1(buffer, hp); + } void FPCSG00477(TextBuffer *buffer, HookParam *hp) { auto ws = StringToWideString(buffer->viewA(), 932).value(); @@ -564,9 +572,9 @@ namespace {0x80011f1a, {0, 0, 0, 0, FPCSG01282<2>, "PCSG01282"}}, // Name {0x8001ebac, {0, 1, 0, 0, FPCSG01282<3>, "PCSG01282"}}, // choices // 神凪ノ杜 五月雨綴り - {0x828bb50c, {CODEC_UTF16, 0, 0, ReadU16TextAndLenDW<0>, 0, "PCSG01268"}}, // dialogue - {0x828ba9b6, {CODEC_UTF16, 0, 0, ReadU16TextAndLenDW<0>, 0, "PCSG01268"}}, // name - {0x8060D376, {CODEC_UTF8, 0, 0, 0, 0, "PCSG01268"}}, // vita3k v0.2.0 can't find 0x828bb50c && 0x828ba9b6, unknown reason. + {0x828bb50c, {CODEC_UTF16, 0, 0, ReadU16TextAndLenDW, 0, "PCSG01268"}}, // dialogue + {0x828ba9b6, {CODEC_UTF16, 0, 0, ReadU16TextAndLenDW, 0, "PCSG01268"}}, // name + {0x8060D376, {CODEC_UTF8, 0, 0, 0, 0, "PCSG01268"}}, // vita3k v0.2.0 can't find 0x828bb50c && 0x828ba9b6, unknown reason. // 参千世界遊戯 ~MultiUniverse Myself~ {0x8005ae24, {0, 0, 0, 0, 0, "PCSG01194"}}, // dialouge+name,sjis,need remap jis char,to complex // Marginal #4 Road to Galaxy @@ -583,9 +591,9 @@ namespace {0x80070e30, {0, 2, 0, 0, FPCSG00751, "PCSG00751"}}, // all,sjis {0x80070cdc, {0, 1, 0, 0, FPCSG00751, "PCSG00751"}}, // text // もし、この世界に神様がいるとするならば。 - {0x80c1f270, {CODEC_UTF16, 0, 0, ReadU16TextAndLenDW<0>, FPCSG00706, "PCSG00706"}}, // dialogue - {0x80d48bfc, {CODEC_UTF16, 0, 0, ReadU16TextAndLenDW<1>, FPCSG00706, "PCSG00706"}}, // Dictionary1 - {0x80d48c20, {CODEC_UTF16, 0, 0, ReadU16TextAndLenDW<0>, FPCSG00706, "PCSG00706"}}, // Dictionary2 + {0x80c1f270, {CODEC_UTF16, 0, 0, ReadU16TextAndLenDW, FPCSG00706, "PCSG00706"}}, // dialogue + {0x80d48bfc, {CODEC_UTF16, 1, 0, ReadU16TextAndLenDW, FPCSG00706, "PCSG00706"}}, // Dictionary1 + {0x80d48c20, {CODEC_UTF16, 0, 0, ReadU16TextAndLenDW, FPCSG00706, "PCSG00706"}}, // Dictionary2 // アンジェーリーク ルトゥール {0x8008bd1a, {0, 1, 0, 0, FPCSG00696, "PCSG00696"}}, // text1,sjis {0x8008cd48, {0, 0, 0, 0, FPCSG00696, "PCSG00696"}}, // text2 diff --git a/cpp/LunaHook/LunaHook/engine64/yuzu.cpp b/cpp/LunaHook/LunaHook/engine64/yuzu.cpp index 12000a65..80b98628 100644 --- a/cpp/LunaHook/LunaHook/engine64/yuzu.cpp +++ b/cpp/LunaHook/LunaHook/engine64/yuzu.cpp @@ -308,23 +308,20 @@ namespace buffer->from(s); } - template void ReadTextAndLenDW(hook_context *context, HookParam *hp, TextBuffer *buffer, uintptr_t *split) { - auto address = YUZU::emu_arg(context)[index]; + auto address = YUZU::emu_arg(context)[hp->offset]; buffer->from(address + 0x14, (*(DWORD *)(address + 0x10)) * 2); } - template void ReadTextAndLenW(hook_context *context, HookParam *hp, TextBuffer *buffer, uintptr_t *split) { - auto address = YUZU::emu_arg(context)[index]; + auto address = YUZU::emu_arg(context)[hp->offset]; buffer->from(address + 0x14, (*(WORD *)(address + 0x10)) * 2); } - template void mages_readstring(hook_context *context, HookParam *hp, TextBuffer *buffer, uintptr_t *split) { - auto s = mages::readString(YUZU::emu_arg(context)[0], idx); + auto s = mages::readString(YUZU::emu_arg(context)[0], hp->offset); buffer->from(s); } @@ -793,10 +790,9 @@ namespace s = std::regex_replace(s, std::wregex(L"\n+"), L" "); buffer->from(utf16_to_utf32(s)); } - template void T01000BB01CB8A000(hook_context *context, HookParam *hp, TextBuffer *buffer, uintptr_t *split) { - auto address = YUZU::emu_arg(context)[index]; + auto address = YUZU::emu_arg(context)[hp->offset]; std::wstring s; while (auto c = *(uint16_t *)address) { @@ -838,11 +834,10 @@ namespace buffer->from(s); } - template void T0100B0100E26C000(hook_context *context, HookParam *hp, TextBuffer *buffer, uintptr_t *split) { - auto address = YUZU::emu_arg(context)[index]; - if (type == 2) + auto address = YUZU::emu_arg(context)[hp->offset]; + if (hp->padding == 2) address += 0xA; auto length = (*(DWORD *)(address + 0x10)) * 2; buffer->from(address + 0x14, length); @@ -1535,10 +1530,9 @@ namespace strReplace(collect, "\x81\x40", ""); buffer->from(collect); } - template void T0100CF400F7CE000(hook_context *context, HookParam *hp, TextBuffer *buffer, uintptr_t *split) { - auto address = YUZU::emu_arg(context)[idx]; + auto address = YUZU::emu_arg(context)[hp->offset]; std::string s; int i = 0; while (1) @@ -1698,10 +1692,8 @@ namespace dump.insert(s); buffer->from(s); } - template - void F0100CC80140F8000(TextBuffer *buffer, HookParam *hp) + void F0100CC80140F8000_1(TextBuffer *buffer, HookParam *hp) { - auto s = buffer->strW(); s = std::regex_replace(s, std::wregex(L"^(?:スキップ|メニュー|バックログ|ズームイン|ズームアウト|ガイド OFF|早送り|オート|人物情報|ユニット表示切替|カメラリセット|ガイド表示切替|ページ切替|閉じる|コマンド選択|詳細|シミュレーション|移動)$([\\r?\\n|\\r])?"), L""); @@ -1711,11 +1703,18 @@ namespace { s = std::regex_replace(s, std::wregex(L"^\\s*$"), L""); } + buffer->from(s); + } + + template + void F0100CC80140F8000(TextBuffer *buffer, HookParam *hp) + { + F0100CC80140F8000_1(buffer, hp); + auto s = buffer->viewW(); static std::wstring last; if (last == s) return buffer->clear(); last = s; - buffer->from(s); } void F0100D9A01BD86000_0(TextBuffer *buffer, HookParam *hp) @@ -2430,42 +2429,42 @@ namespace { emfunctionhooks = { // Memories Off - {0x8003eeac, {CODEC_UTF16, 0, 0, mages_readstring<0>, 0, 0x0100978013276000ull, "1.0.0"}}, - {0x8003eebc, {CODEC_UTF16, 0, 0, mages_readstring<0>, 0, 0x0100978013276000ull, "1.0.1"}}, + {0x8003eeac, {CODEC_UTF16, 0, 0, mages_readstring, 0, 0x0100978013276000ull, "1.0.0"}}, + {0x8003eebc, {CODEC_UTF16, 0, 0, mages_readstring, 0, 0x0100978013276000ull, "1.0.1"}}, // Memories Off ~それから~ - {0x8003fb7c, {CODEC_UTF16, 0, 0, mages_readstring<0>, 0, 0x0100B4A01326E000ull, "1.0.0"}}, - {0x8003fb8c, {CODEC_UTF16, 0, 0, mages_readstring<0>, 0, 0x0100B4A01326E000ull, "1.0.1"}}, + {0x8003fb7c, {CODEC_UTF16, 0, 0, mages_readstring, 0, 0x0100B4A01326E000ull, "1.0.0"}}, + {0x8003fb8c, {CODEC_UTF16, 0, 0, mages_readstring, 0, 0x0100B4A01326E000ull, "1.0.1"}}, // ファミコン探偵倶楽部 消えた後継者 - {0x80052a10, {CODEC_UTF16, 0, 0, mages_readstring<3>, 0, 0x0100B4500F7AE000ull, "1.0.0"}}, + {0x80052a10, {CODEC_UTF16, 3, 0, mages_readstring, 0, 0x0100B4500F7AE000ull, "1.0.0"}}, // ファミコン探偵倶楽部PartII うしろに立つ少女 - {0x8004cb30, {CODEC_UTF16, 0, 0, mages_readstring<3>, 0, 0x010078400F7B0000ull, "1.0.0"}}, + {0x8004cb30, {CODEC_UTF16, 3, 0, mages_readstring, 0, 0x010078400F7B0000ull, "1.0.0"}}, // Memories Off 2nd - {0x8003ee0c, {CODEC_UTF16, 0, 0, mages_readstring<0>, 0, 0x0100D31013274000ull, "1.0.0"}}, - {0x8003ee1c, {CODEC_UTF16, 0, 0, mages_readstring<0>, 0, 0x0100D31013274000ull, "1.0.1"}}, + {0x8003ee0c, {CODEC_UTF16, 0, 0, mages_readstring, 0, 0x0100D31013274000ull, "1.0.0"}}, + {0x8003ee1c, {CODEC_UTF16, 0, 0, mages_readstring, 0, 0x0100D31013274000ull, "1.0.1"}}, // 想い出にかわる君 ~メモリーズオフ~ - {0x8003ef6c, {CODEC_UTF16, 0, 0, mages_readstring<0>, 0, 0x0100FFA013272000ull, "1.0.0"}}, - {0x8003ef7c, {CODEC_UTF16, 0, 0, mages_readstring<0>, 0, 0x0100FFA013272000ull, "1.0.1"}}, + {0x8003ef6c, {CODEC_UTF16, 0, 0, mages_readstring, 0, 0x0100FFA013272000ull, "1.0.0"}}, + {0x8003ef7c, {CODEC_UTF16, 0, 0, mages_readstring, 0, 0x0100FFA013272000ull, "1.0.1"}}, // メモリーズオフ6 ~T-wave~ - {0x80043d7c, {CODEC_UTF16, 0, 0, mages_readstring<0>, 0, 0x010047A013268000ull, "1.0.0"}}, - {0x80043d5c, {CODEC_UTF16, 0, 0, mages_readstring<0>, 0, 0x010047A013268000ull, "1.0.1"}}, + {0x80043d7c, {CODEC_UTF16, 0, 0, mages_readstring, 0, 0x010047A013268000ull, "1.0.0"}}, + {0x80043d5c, {CODEC_UTF16, 0, 0, mages_readstring, 0, 0x010047A013268000ull, "1.0.1"}}, // メモリーズオフ ゆびきりの記憶 - {0x800440ec, {CODEC_UTF16, 0, 0, mages_readstring<0>, 0, 0x010079C012896000ull, "1.0.0"}}, + {0x800440ec, {CODEC_UTF16, 0, 0, mages_readstring, 0, 0x010079C012896000ull, "1.0.0"}}, // Memories Off #5 とぎれたフィルム - {0x8003f6ac, {CODEC_UTF16, 0, 0, mages_readstring<0>, 0, 0x010073901326C000ull, "1.0.0"}}, - {0x8003f5fc, {CODEC_UTF16, 0, 0, mages_readstring<0>, 0, 0x010073901326C000ull, "1.0.1"}}, + {0x8003f6ac, {CODEC_UTF16, 0, 0, mages_readstring, 0, 0x010073901326C000ull, "1.0.0"}}, + {0x8003f5fc, {CODEC_UTF16, 0, 0, mages_readstring, 0, 0x010073901326C000ull, "1.0.1"}}, // シンスメモリーズ 星天の下で - {0x80048cc8, {CODEC_UTF16, 0, 0, mages_readstring<4>, 0, 0x0100E94014792000ull, 0}}, // line + name => join - {0x8004f44c, {CODEC_UTF16, 0, 0, mages_readstring<4>, 0, 0x0100E94014792000ull, 0}}, // fast trophy - {0x8004f474, {CODEC_UTF16, 0, 0, mages_readstring<4>, 0, 0x0100E94014792000ull, 0}}, // prompt - {0x80039dc0, {CODEC_UTF16, 0, 0, mages_readstring<4>, 0, 0x0100E94014792000ull, 0}}, // choice + {0x80048cc8, {CODEC_UTF16, 4, 0, mages_readstring, 0, 0x0100E94014792000ull, 0}}, // line + name => join + {0x8004f44c, {CODEC_UTF16, 4, 0, mages_readstring, 0, 0x0100E94014792000ull, 0}}, // fast trophy + {0x8004f474, {CODEC_UTF16, 4, 0, mages_readstring, 0, 0x0100E94014792000ull, 0}}, // prompt + {0x80039dc0, {CODEC_UTF16, 4, 0, mages_readstring, 0, 0x0100E94014792000ull, 0}}, // choice // やはりゲームでも俺の青春ラブコメはまちがっている。 - {0x8005DFB8, {CODEC_UTF16, 0, 0, mages_readstring<0>, 0, 0x0100E0D0154BC000ull, "1.0.0"}}, + {0x8005DFB8, {CODEC_UTF16, 0, 0, mages_readstring, 0, 0x0100E0D0154BC000ull, "1.0.0"}}, // CHAOS;HEAD NOAH - {0x80046700, {CODEC_UTF16, 0, 0, mages_readstring<0>, 0, 0x0100957016B90000ull, "1.0.0"}}, - {0x8003A2c0, {CODEC_UTF16, 0, 0, mages_readstring<0>, 0, 0x0100957016B90000ull, "1.0.0"}}, // choice - {0x8003EAB0, {CODEC_UTF16, 0, 0, mages_readstring<0>, 0, 0x0100957016B90000ull, "1.0.0"}}, // TIPS list (menu) - {0x8004C648, {CODEC_UTF16, 0, 0, mages_readstring<0>, 0, 0x0100957016B90000ull, "1.0.0"}}, // system message - {0x80050374, {CODEC_UTF16, 0, 0, mages_readstring<0>, 0, 0x0100957016B90000ull, "1.0.0"}}, // TIPS (red) + {0x80046700, {CODEC_UTF16, 0, 0, mages_readstring, 0, 0x0100957016B90000ull, "1.0.0"}}, + {0x8003A2c0, {CODEC_UTF16, 0, 0, mages_readstring, 0, 0x0100957016B90000ull, "1.0.0"}}, // choice + {0x8003EAB0, {CODEC_UTF16, 0, 0, mages_readstring, 0, 0x0100957016B90000ull, "1.0.0"}}, // TIPS list (menu) + {0x8004C648, {CODEC_UTF16, 0, 0, mages_readstring, 0, 0x0100957016B90000ull, "1.0.0"}}, // system message + {0x80050374, {CODEC_UTF16, 0, 0, mages_readstring, 0, 0x0100957016B90000ull, "1.0.0"}}, // TIPS (red) // 白と黒のアリス {0x80013f20, {CODEC_UTF8, 0, 0, 0, NewLineCharFilterW, 0x0100A460141B8000ull, "1.0.0"}}, {0x80013f94, {CODEC_UTF8, 0, 0, 0, NewLineCharFilterW, 0x0100A460141B8000ull, "1.0.0"}}, @@ -2481,9 +2480,9 @@ namespace {0x800e3424, {CODEC_UTF8, 0, 0, 0, F010045C0109F2000, 0x010045C0109F2000ull, "1.0.1"}}, //"System Messages + Choices"), //Also includes the names of characters, {0x800fb080, {CODEC_UTF8, 3, 0, 0, F010045C0109F2000, 0x010045C0109F2000ull, "1.0.1"}}, // Main Text // AMNESIA for Nintendo Switch - {0x805bba5c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<2>, F0100A1E00BFEA000, 0x0100A1E00BFEA000ull, "1.0.1"}}, // dialogue - {0x805e9930, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F0100A1E00BFEA000, 0x0100A1E00BFEA000ull, "1.0.1"}}, // choice - {0x805e7fd8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F0100A1E00BFEA000, 0x0100A1E00BFEA000ull, "1.0.1"}}, // name + {0x805bba5c, {CODEC_UTF16, 2, 0, ReadTextAndLenDW, F0100A1E00BFEA000, 0x0100A1E00BFEA000ull, "1.0.1"}}, // dialogue + {0x805e9930, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F0100A1E00BFEA000, 0x0100A1E00BFEA000ull, "1.0.1"}}, // choice + {0x805e7fd8, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F0100A1E00BFEA000, 0x0100A1E00BFEA000ull, "1.0.1"}}, // name // 蝶の毒 華の鎖 {0x80095010, {CODEC_UTF16, 1, 0, 0, F0100A1200CA3C000, 0x0100A1200CA3C000ull, "2.0.1"}}, // Main Text + Names // Live a Live @@ -2516,9 +2515,9 @@ namespace {0x808f7e84, {CODEC_UTF32, 0, 0, 0, F0100936018EB4000, 0x0100936018EB4000ull, "1.0.3"}}, // Item name {0x80bdf804, {CODEC_UTF32, 0, 0, 0, F0100936018EB4000, 0x0100936018EB4000ull, "1.0.3"}}, // Item description // 乙女ゲームの破滅フラグしかない悪役令嬢に転生してしまった… 〜波乱を呼ぶ海賊〜 - {0x81e75940, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F0100982015606000, 0x0100982015606000ull, "1.0.0"}}, // Hamekai.TalkPresenter$$AddMessageBacklog - {0x81c9ae60, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F0100982015606000, 0x0100982015606000ull, "1.0.0"}}, // Hamekai.ChoicesText$$SetText - {0x81eb7dc0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F0100982015606000, 0x0100982015606000ull, "1.0.0"}}, // Hamekai.ShortStoryTextView$$AddText + {0x81e75940, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F0100982015606000, 0x0100982015606000ull, "1.0.0"}}, // Hamekai.TalkPresenter$$AddMessageBacklog + {0x81c9ae60, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F0100982015606000, 0x0100982015606000ull, "1.0.0"}}, // Hamekai.ChoicesText$$SetText + {0x81eb7dc0, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F0100982015606000, 0x0100982015606000ull, "1.0.0"}}, // Hamekai.ShortStoryTextView$$AddText // Death end re;Quest {0x80241088, {CODEC_UTF8, 8, 0, 0, F0100AEC013DDA000, 0x0100AEC013DDA000ull, "1.0.0"}}, // english ver // Death end re;Quest 2 @@ -2540,45 +2539,45 @@ namespace {0x8025e210, {CODEC_UTF8, 2, 0, 0, F010045C014650000, 0x010045C014650000ull, "1.0.0"}}, // scene context example: 数日前 咲良高校 1年B組 教室 1985年5月" {0x8005c518, {CODEC_UTF8, 0, 0, 0, F010045C014650000, 0x010045C014650000ull, "1.0.0"}}, // game help // Sea of Stars - {0x83e93ca0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F01008C0016544000, 0x01008C0016544000ull, "1.0.45861"}}, // Main text - {0x820c3fa0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F01008C0016544000, 0x01008C0016544000ull, "1.0.47140"}}, // Main text + {0x83e93ca0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F01008C0016544000, 0x01008C0016544000ull, "1.0.45861"}}, // Main text + {0x820c3fa0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F01008C0016544000, 0x01008C0016544000ull, "1.0.47140"}}, // Main text // Final Fantasy I - {0x81e88040, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x01000EA014150000ull, "1.0.1"}}, // Main text - {0x81cae54c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x01000EA014150000ull, "1.0.1"}}, // Intro text - {0x81a3e494, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x01000EA014150000ull, "1.0.1"}}, // battle text - {0x81952c28, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x01000EA014150000ull, "1.0.1"}}, // Location + {0x81e88040, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x01000EA014150000ull, "1.0.1"}}, // Main text + {0x81cae54c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x01000EA014150000ull, "1.0.1"}}, // Intro text + {0x81a3e494, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x01000EA014150000ull, "1.0.1"}}, // battle text + {0x81952c28, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x01000EA014150000ull, "1.0.1"}}, // Location // Final Fantasy II - {0x8208f4cc, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x01006B7014156000ull, "1.0.1"}}, // Main text - {0x817e464c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x01006B7014156000ull, "1.0.1"}}, // Intro text - {0x81fb6414, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x01006B7014156000ull, "1.0.1"}}, // battle text + {0x8208f4cc, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x01006B7014156000ull, "1.0.1"}}, // Main text + {0x817e464c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x01006B7014156000ull, "1.0.1"}}, // Intro text + {0x81fb6414, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x01006B7014156000ull, "1.0.1"}}, // battle text // Final Fantasy III - {0x82019e84, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x01002E2014158000ull, "1.0.1"}}, // Main text1 - {0x817ffcfc, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x01002E2014158000ull, "1.0.1"}}, // Main text2 - {0x81b8b7e4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x01002E2014158000ull, "1.0.1"}}, // battle text - {0x8192c4a8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x01002E2014158000ull, "1.0.1"}}, // Location + {0x82019e84, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x01002E2014158000ull, "1.0.1"}}, // Main text1 + {0x817ffcfc, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x01002E2014158000ull, "1.0.1"}}, // Main text2 + {0x81b8b7e4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x01002E2014158000ull, "1.0.1"}}, // battle text + {0x8192c4a8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x01002E2014158000ull, "1.0.1"}}, // Location // Final Fantasy IV - {0x81e44bf4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x01004B301415A000ull, "1.0.2"}}, // Main text - {0x819f92c4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x01004B301415A000ull, "1.0.2"}}, // Rolling text - {0x81e2e798, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x01004B301415A000ull, "1.0.2"}}, // Battle text - {0x81b1e6a8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x01004B301415A000ull, "1.0.2"}}, // Location + {0x81e44bf4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x01004B301415A000ull, "1.0.2"}}, // Main text + {0x819f92c4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x01004B301415A000ull, "1.0.2"}}, // Rolling text + {0x81e2e798, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x01004B301415A000ull, "1.0.2"}}, // Battle text + {0x81b1e6a8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x01004B301415A000ull, "1.0.2"}}, // Location // Final Fantasy V - {0x81d63e24, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x0100AA201415C000ull, "1.0.2"}}, // Main text - {0x81adfb3c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x0100AA201415C000ull, "1.0.2"}}, // Location - {0x81a8fda8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x0100AA201415C000ull, "1.0.2"}}, // Battle text + {0x81d63e24, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x0100AA201415C000ull, "1.0.2"}}, // Main text + {0x81adfb3c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x0100AA201415C000ull, "1.0.2"}}, // Location + {0x81a8fda8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x0100AA201415C000ull, "1.0.2"}}, // Battle text // Final Fantasy VI - {0x81e6b350, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x0100AA001415E000ull, "1.0.2"}}, // Main text - {0x81ab40ec, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x0100AA001415E000ull, "1.0.2"}}, // Location - {0x819b8c88, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x0100AA001415E000ull, "1.0.2"}}, // Battle text + {0x81e6b350, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x0100AA001415E000ull, "1.0.2"}}, // Main text + {0x81ab40ec, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x0100AA001415E000ull, "1.0.2"}}, // Location + {0x819b8c88, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x0100AA001415E000ull, "1.0.2"}}, // Battle text // Final Fantasy IX - {0x80034b90, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F01006F000B056000, 0x01006F000B056000ull, "1.0.1"}}, // Main Text - {0x802ade64, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F01006F000B056000, 0x01006F000B056000ull, "1.0.1"}}, // Battle Text - {0x801b1b84, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F01006F000B056000, 0x01006F000B056000ull, "1.0.1"}}, // Descriptions - {0x805aa0b0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F01006F000B056000, 0x01006F000B056000ull, "1.0.1"}}, // Key Item Name - {0x805a75d8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F01006F000B056000, 0x01006F000B056000ull, "1.0.1"}}, // Key Item Content - {0x8002f79c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F01006F000B056000, 0x01006F000B056000ull, "1.0.1"}}, // Menu - {0x80ca88b0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F01006F000B056000, 0x01006F000B056000ull, "1.0.1"}}, // Tutorial1 - {0x80ca892c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F01006F000B056000, 0x01006F000B056000ull, "1.0.1"}}, // Tutorial2 - {0x80008d88, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F01006F000B056000, 0x01006F000B056000ull, "1.0.1"}}, // Location + {0x80034b90, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F01006F000B056000, 0x01006F000B056000ull, "1.0.1"}}, // Main Text + {0x802ade64, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F01006F000B056000, 0x01006F000B056000ull, "1.0.1"}}, // Battle Text + {0x801b1b84, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F01006F000B056000, 0x01006F000B056000ull, "1.0.1"}}, // Descriptions + {0x805aa0b0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F01006F000B056000, 0x01006F000B056000ull, "1.0.1"}}, // Key Item Name + {0x805a75d8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F01006F000B056000, 0x01006F000B056000ull, "1.0.1"}}, // Key Item Content + {0x8002f79c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F01006F000B056000, 0x01006F000B056000ull, "1.0.1"}}, // Menu + {0x80ca88b0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F01006F000B056000, 0x01006F000B056000ull, "1.0.1"}}, // Tutorial1 + {0x80ca892c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F01006F000B056000, 0x01006F000B056000ull, "1.0.1"}}, // Tutorial2 + {0x80008d88, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F01006F000B056000, 0x01006F000B056000ull, "1.0.1"}}, // Location // Norn9 Var Commons {0x8003E874, {CODEC_UTF8, 0, 0, 0, F0100068019996000, 0x0100068019996000ull, "1.0.0"}}, // English // 薄桜鬼 真改 遊戯録 隊士達の大宴会 for Nintendo Switch 三合一 @@ -2640,7 +2639,7 @@ namespace {0x800878fc, {CODEC_UTF8, 0, 0, 0, F0100D9500A0F6000, 0x0100D9500A0F6000ull, "1.0.0"}}, // prompt {0x80087aa0, {CODEC_UTF8, 0, 0, 0, F0100D9500A0F6000, 0x0100D9500A0F6000ull, "1.0.0"}}, // choice // ゆるキャン△ Have a nice day! - {0x816d03f8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100982015606000, 0x0100D12014FC2000ull, "1.0.0"}}, // dialog / backlog + {0x816d03f8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100982015606000, 0x0100D12014FC2000ull, "1.0.0"}}, // dialog / backlog // 悪役令嬢は隣国の王太子に溺愛される {0x817b35c4, {CODEC_UTF8, 1, 0, 0, F0100DA201E0DA000, 0x0100DA201E0DA000ull, "1.0.0"}}, // Dialogue // ゆのはなSpRING!~Mellow Times~ @@ -2656,71 +2655,71 @@ namespace {0x8051a9a8, {CODEC_UTF8, 0, 0, 0, F01006590155AC000, 0x0100D11018A7E000ull, "1.0.0"}}, // dialogue {0x80500178, {CODEC_UTF8, 0, 0, 0, F01006590155AC000, 0x0100D11018A7E000ull, "1.0.0"}}, // choice // AKA - {0x8166eb80, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100B0601852A000, 0x0100B0601852A000ull, "1.0.0"}}, // Main text - {0x817d44a4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100B0601852A000, 0x0100B0601852A000ull, "1.0.0"}}, // Letter - {0x815cb0f4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100B0601852A000, 0x0100B0601852A000ull, "1.0.0"}}, // Mission title - {0x815cde30, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100B0601852A000, 0x0100B0601852A000ull, "1.0.0"}}, // Mission description - {0x8162a910, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100B0601852A000, 0x0100B0601852A000ull, "1.0.0"}}, // Craft description - {0x817fdca8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100B0601852A000, 0x0100B0601852A000ull, "1.0.0"}}, // Inventory item name + {0x8166eb80, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100B0601852A000, 0x0100B0601852A000ull, "1.0.0"}}, // Main text + {0x817d44a4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100B0601852A000, 0x0100B0601852A000ull, "1.0.0"}}, // Letter + {0x815cb0f4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100B0601852A000, 0x0100B0601852A000ull, "1.0.0"}}, // Mission title + {0x815cde30, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100B0601852A000, 0x0100B0601852A000ull, "1.0.0"}}, // Mission description + {0x8162a910, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100B0601852A000, 0x0100B0601852A000ull, "1.0.0"}}, // Craft description + {0x817fdca8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100B0601852A000, 0x0100B0601852A000ull, "1.0.0"}}, // Inventory item name // Etrian Odyssey I HD - {0x82d57550, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100B0C016164000, 0x01008A3016162000ull, "1.0.2"}}, // Text - {0x824ff408, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100B0C016164000, 0x01008A3016162000ull, "1.0.2"}}, // Config Description - {0x8296b4e4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100B0C016164000, 0x01008A3016162000ull, "1.0.2"}}, // Class Description - {0x81b2204c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100B0C016164000, 0x01008A3016162000ull, "1.0.2"}}, // Item Description + {0x82d57550, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100B0C016164000, 0x01008A3016162000ull, "1.0.2"}}, // Text + {0x824ff408, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100B0C016164000, 0x01008A3016162000ull, "1.0.2"}}, // Config Description + {0x8296b4e4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100B0C016164000, 0x01008A3016162000ull, "1.0.2"}}, // Class Description + {0x81b2204c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100B0C016164000, 0x01008A3016162000ull, "1.0.2"}}, // Item Description // Etrian Odyssey II HD - {0x82f24c70, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100B0C016164000, 0x0100B0C016164000ull, "1.0.2"}}, // Text - {0x82cc0988, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100B0C016164000, 0x0100B0C016164000ull, "1.0.2"}}, // Config Description - {0x8249acd4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100B0C016164000, 0x0100B0C016164000ull, "1.0.2"}}, // Class Description - {0x81b27644, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100B0C016164000, 0x0100B0C016164000ull, "1.0.2"}}, // Item Description + {0x82f24c70, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100B0C016164000, 0x0100B0C016164000ull, "1.0.2"}}, // Text + {0x82cc0988, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100B0C016164000, 0x0100B0C016164000ull, "1.0.2"}}, // Config Description + {0x8249acd4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100B0C016164000, 0x0100B0C016164000ull, "1.0.2"}}, // Class Description + {0x81b27644, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100B0C016164000, 0x0100B0C016164000ull, "1.0.2"}}, // Item Description // Etrian Odyssey III HD - {0x83787f04, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100B0C016164000, 0x0100D32015A52000ull, "1.0.2"}}, // Text - {0x8206915c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100B0C016164000, 0x0100D32015A52000ull, "1.0.2"}}, // Config Description - {0x82e6d1d4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100B0C016164000, 0x0100D32015A52000ull, "1.0.2"}}, // Class Description - {0x82bf5d48, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100B0C016164000, 0x0100D32015A52000ull, "1.0.2"}}, // Item Description + {0x83787f04, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100B0C016164000, 0x0100D32015A52000ull, "1.0.2"}}, // Text + {0x8206915c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100B0C016164000, 0x0100D32015A52000ull, "1.0.2"}}, // Config Description + {0x82e6d1d4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100B0C016164000, 0x0100D32015A52000ull, "1.0.2"}}, // Class Description + {0x82bf5d48, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100B0C016164000, 0x0100D32015A52000ull, "1.0.2"}}, // Item Description // Fire Emblem Engage - {0x8248c550, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<2>, 0, 0x0100A6301214E000ull, "1.3.0"}}, // App.Talk3D.TalkLog$$AddLog - {0x820C6530, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<2>, 0, 0x0100A6301214E000ull, "2.0.0"}}, // App.Talk3D.TalkLog$$AddLog + {0x8248c550, {CODEC_UTF16, 2, 0, ReadTextAndLenDW, 0, 0x0100A6301214E000ull, "1.3.0"}}, // App.Talk3D.TalkLog$$AddLog + {0x820C6530, {CODEC_UTF16, 2, 0, ReadTextAndLenDW, 0, 0x0100A6301214E000ull, "2.0.0"}}, // App.Talk3D.TalkLog$$AddLog // AMNESIA LATER×CROWD for Nintendo Switch - {0x800ebc34, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F0100982015606000, 0x0100B5700CDFC000ull, "1.0.0"}}, // waterfall - {0x8014dc64, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F0100982015606000, 0x0100B5700CDFC000ull, "1.0.0"}}, // name - {0x80149b10, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F0100982015606000, 0x0100B5700CDFC000ull, "1.0.0"}}, // dialogue - {0x803add50, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F0100982015606000, 0x0100B5700CDFC000ull, "1.0.0"}}, // choice + {0x800ebc34, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F0100982015606000, 0x0100B5700CDFC000ull, "1.0.0"}}, // waterfall + {0x8014dc64, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F0100982015606000, 0x0100B5700CDFC000ull, "1.0.0"}}, // name + {0x80149b10, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F0100982015606000, 0x0100B5700CDFC000ull, "1.0.0"}}, // dialogue + {0x803add50, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F0100982015606000, 0x0100B5700CDFC000ull, "1.0.0"}}, // choice // Natsumon! 20th Century Summer Vacation {0x80db5d34, {CODEC_UTF16, 0, 0, 0, F0100A8401A0A8000, 0x0100A8401A0A8000ull, "1.1.0"}}, // tutorial {0x846fa578, {CODEC_UTF16, 0, 0, 0, F0100A8401A0A8000, 0x0100A8401A0A8000ull, "1.1.0"}}, // choice {0x8441e800, {CODEC_UTF16, 0, 0, 0, F0100A8401A0A8000, 0x0100A8401A0A8000ull, "1.1.0"}}, // examine + dialog // Super Mario RPG - {0x81d78c58, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Main Text - {0x81dc9cf8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Name - {0x81c16b80, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Cutscene - {0x821281f0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Special/Item/Menu/Objective Description - {0x81cd8148, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Special Name - {0x81fc2820, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Item Name Battle - {0x81d08d28, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Item Name Off-battle - {0x82151aac, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Shop Item Name - {0x81fcc870, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Objective Title - {0x821bd328, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Monster List - Name - {0x820919b8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Monster List - Description - {0x81f56518, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Info - {0x82134ce0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Help Category - {0x82134f30, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Help Name - {0x821372e4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Help Description 1 - {0x82137344, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Help Description 2 - {0x81d0ee80, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<2>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Location - {0x82128f64, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Album Title - {0x81f572a0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<3>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Load/Save Text - {0x81d040a8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Levelup First Part - {0x81d043fc, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Levelup Second Part - {0x81d04550, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Levelup New Ability Description - {0x81fbfa18, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Yoshi Mini-Game Header - {0x81fbfa74, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Yoshi Mini-Game Text - {0x81cf41b4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Enemy Special Attacks + {0x81d78c58, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Main Text + {0x81dc9cf8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Name + {0x81c16b80, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Cutscene + {0x821281f0, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Special/Item/Menu/Objective Description + {0x81cd8148, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Special Name + {0x81fc2820, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Item Name Battle + {0x81d08d28, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Item Name Off-battle + {0x82151aac, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Shop Item Name + {0x81fcc870, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Objective Title + {0x821bd328, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Monster List - Name + {0x820919b8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Monster List - Description + {0x81f56518, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Info + {0x82134ce0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Help Category + {0x82134f30, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Help Name + {0x821372e4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Help Description 1 + {0x82137344, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Help Description 2 + {0x81d0ee80, {CODEC_UTF16, 2, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Location + {0x82128f64, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Album Title + {0x81f572a0, {CODEC_UTF16, 3, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Load/Save Text + {0x81d040a8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Levelup First Part + {0x81d043fc, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Levelup Second Part + {0x81d04550, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Levelup New Ability Description + {0x81fbfa18, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Yoshi Mini-Game Header + {0x81fbfa74, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Yoshi Mini-Game Text + {0x81cf41b4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BC0018138000, 0x0100BC0018138000ull, "1.0.0"}}, // Enemy Special Attacks // Trials of Mana {0x800e8abc, {CODEC_UTF16, 1, 0, 0, F0100D7800E9E0000, 0x0100D7800E9E0000ull, "1.1.1"}}, // Text // 空蝉の廻 - {0x821b452c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x0100DA101D9AA000ull, "1.0.0"}}, // text1 - {0x821b456c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x0100DA101D9AA000ull, "1.0.0"}}, // text2 - {0x821b45ac, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x0100DA101D9AA000ull, "1.0.0"}}, // text3 + {0x821b452c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x0100DA101D9AA000ull, "1.0.0"}}, // text1 + {0x821b456c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x0100DA101D9AA000ull, "1.0.0"}}, // text2 + {0x821b45ac, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x0100DA101D9AA000ull, "1.0.0"}}, // text3 // バディミッション BOND {0x80046dd0, {0, 0, 0, T0100DB300B996000, 0, 0x0100DB300B996000ull, 0}}, // 1.0.0, 1.0.1,sjis {0x80046de0, {0, 0, 0, T0100DB300B996000, 0, 0x0100DB300B996000ull, 0}}, @@ -2763,10 +2762,10 @@ namespace // Pokémon Let’s Go, Pikachu! {0x8067d9fc, {CODEC_UTF16, 0, 0, 0, F010003F003A34000, 0x010003F003A34000ull, "1.0.2"}}, // Text // イケメン戦国◆時をかける恋 新たなる出逢い - {0x813e4fb4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x01008BE016CE2000ull, "1.0.0"}}, // Main Text - {0x813e4c60, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x01008BE016CE2000ull, "1.0.0"}}, // Name - {0x813b5360, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x01008BE016CE2000ull, "1.0.0"}}, // Choices - {0x81bab9ac, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, 0, 0x01008BE016CE2000ull, "1.0.0"}}, // Info + {0x813e4fb4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x01008BE016CE2000ull, "1.0.0"}}, // Main Text + {0x813e4c60, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x01008BE016CE2000ull, "1.0.0"}}, // Name + {0x813b5360, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x01008BE016CE2000ull, "1.0.0"}}, // Choices + {0x81bab9ac, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, 0, 0x01008BE016CE2000ull, "1.0.0"}}, // Info // Shin Megami Tensei V {0x80ce01a4, {CODEC_UTF16, 0, 0, 0, 0, 0x01006BD0095F4000ull, "1.0.2"}}, // Text // The Legend of Zelda: Link's Awakening @@ -2775,7 +2774,7 @@ namespace {0x8001ab8c, {CODEC_UTF8, 2, 0, 0, F0100DE200C0DA000, 0x01006B000A666000ull, "1.0.0"}}, // name {0x80027b30, {CODEC_UTF8, 0, 0, 0, F0100DE200C0DA000, 0x01006B000A666000ull, "1.0.0"}}, // dialogue // Crayon Shin-chan Shiro of Coal Town - {0x83fab4bc, {CODEC_UTF16, 0, 0, ReadTextAndLenW<0>, F01007B601C608000, 0x01007B601C608000ull, "1.0.1"}}, + {0x83fab4bc, {CODEC_UTF16, 0, 0, ReadTextAndLenW, F01007B601C608000, 0x01007B601C608000ull, "1.0.1"}}, // 風雨来記4 {0x80008c80, {CODEC_UTF32, 1, 0, 0, F010046601125A000, 0x010046601125A000ull, "1.0.0"}}, // Main {0x80012b1c, {CODEC_UTF32, 1, 0, 0, F010046601125A000, 0x010046601125A000ull, "1.0.0"}}, // Wordpad @@ -2783,24 +2782,24 @@ namespace {0x80009f74, {CODEC_UTF32, 1, 0, 0, F010046601125A000, 0x010046601125A000ull, "1.0.0"}}, // Choices {0x80023d64, {CODEC_UTF32, 0, 0, 0, F010046601125A000, 0x010046601125A000ull, "1.0.0"}}, // Location // 剣が君 for S - {0x81477128, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100771013FA8000, 0x0100771013FA8000ull, "1.1"}}, // Main Text - {0x81470e38, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100771013FA8000, 0x0100771013FA8000ull, "1.1"}}, // Secondary Text + {0x81477128, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100771013FA8000, 0x0100771013FA8000ull, "1.1"}}, // Main Text + {0x81470e38, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100771013FA8000, 0x0100771013FA8000ull, "1.1"}}, // Secondary Text // ANONYMOUS;CODE {0x80011608, {CODEC_UTF8, 1, 0, 0, F0100556015CCC000, 0x0100556015CCC000ull, "1.0.0"}}, // dialouge, menu // Sugar * Style {0x800ccbc8, {0, 0, 0, 0, 0, 0x0100325012B70000ull, "1.0.0"}}, // ret x0 name + text (readShiftJisString), filter is to complex, quit. // Nightshade/百花百狼 - {0x802999c8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F010042300C4F6000, 0x010042300C4F6000ull, "1.0.1"}}, // dialogue - {0x8015b544, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F010042300C4F6000, 0x010042300C4F6000ull, "1.0.1"}}, // name - {0x802a2fd4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F010042300C4F6000, 0x010042300C4F6000ull, "1.0.1"}}, // choice1 - {0x802b7900, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F010042300C4F6000, 0x010042300C4F6000ull, "1.0.1"}}, // choice2 + {0x802999c8, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F010042300C4F6000, 0x010042300C4F6000ull, "1.0.1"}}, // dialogue + {0x8015b544, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F010042300C4F6000, 0x010042300C4F6000ull, "1.0.1"}}, // name + {0x802a2fd4, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F010042300C4F6000, 0x010042300C4F6000ull, "1.0.1"}}, // choice1 + {0x802b7900, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F010042300C4F6000, 0x010042300C4F6000ull, "1.0.1"}}, // choice2 // 囚われのパルマ - {0x8015b7a8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F010044800D2EC000, 0x010044800D2EC000ull, "1.0.0"}}, // text x0 - {0x8015b46c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F010044800D2EC000, 0x010044800D2EC000ull, "1.0.0"}}, // name x1 + {0x8015b7a8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F010044800D2EC000, 0x010044800D2EC000ull, "1.0.0"}}, // text x0 + {0x8015b46c, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F010044800D2EC000, 0x010044800D2EC000ull, "1.0.0"}}, // name x1 // Brothers Conflict: Precious Baby - {0x8016aecc, {CODEC_UTF16, 0, 0, ReadTextAndLenW<0>, F0100982015606000, 0x010037400DAAE000ull, "1.0.0"}}, // name - {0x80126b9c, {CODEC_UTF16, 0, 0, ReadTextAndLenW<0>, F0100982015606000, 0x010037400DAAE000ull, "1.0.0"}}, // dialogue - {0x80129160, {CODEC_UTF16, 0, 0, ReadTextAndLenW<2>, F0100982015606000, 0x010037400DAAE000ull, "1.0.0"}}, // choice + {0x8016aecc, {CODEC_UTF16, 0, 0, ReadTextAndLenW, F0100982015606000, 0x010037400DAAE000ull, "1.0.0"}}, // name + {0x80126b9c, {CODEC_UTF16, 0, 0, ReadTextAndLenW, F0100982015606000, 0x010037400DAAE000ull, "1.0.0"}}, // dialogue + {0x80129160, {CODEC_UTF16, 2, 0, ReadTextAndLenW, F0100982015606000, 0x010037400DAAE000ull, "1.0.0"}}, // choice // 絶対階級学園 ~Eden with roses and phantasm~ {0x80067b5c, {CODEC_UTF16, 1, 0, 0, F010021300F69E000<0>, 0x010021300F69E000ull, "1.0.0"}}, // name+ dialogue main(ADV)+choices {0x80067cd4, {CODEC_UTF16, 1, 0, 0, F010021300F69E000<1>, 0x010021300F69E000ull, "1.0.0"}}, // dialogueNVL @@ -2819,11 +2818,11 @@ namespace {0x8076ab04, {CODEC_UTF8, 1, 0, 0, F010050000705E000, 0x010050000705E000ull, "1.7.3"}}, // Tutorial header {0x8076ab2c, {CODEC_UTF8, 1, 0, 0, F010050000705E000, 0x010050000705E000ull, "1.7.3"}}, // Tutorial explanation // BUSTAFELLOWS シーズン2 - {0x819ed3e4, {CODEC_UTF16, 0, 0, ReadTextAndLenW<0>, F0100874017BE2000, 0x010037400DAAE000ull, "1.0.0"}}, // dialogue - {0x82159cd0, {CODEC_UTF16, 0, 0, ReadTextAndLenW<1>, F0100874017BE2000, 0x010037400DAAE000ull, "1.0.0"}}, // textmessage - {0x81e17530, {CODEC_UTF16, 0, 0, ReadTextAndLenW<0>, F0100874017BE2000, 0x010037400DAAE000ull, "1.0.0"}}, // option - {0x81e99d64, {CODEC_UTF16, 0, 0, ReadTextAndLenW<0>, F0100874017BE2000, 0x010037400DAAE000ull, "1.0.0"}}, // choice - {0x8186f81c, {CODEC_UTF16, 0, 0, ReadTextAndLenW<0>, F0100874017BE2000, 0x010037400DAAE000ull, "1.0.0"}}, // archives + {0x819ed3e4, {CODEC_UTF16, 0, 0, ReadTextAndLenW, F0100874017BE2000, 0x010037400DAAE000ull, "1.0.0"}}, // dialogue + {0x82159cd0, {CODEC_UTF16, 1, 0, ReadTextAndLenW, F0100874017BE2000, 0x010037400DAAE000ull, "1.0.0"}}, // textmessage + {0x81e17530, {CODEC_UTF16, 0, 0, ReadTextAndLenW, F0100874017BE2000, 0x010037400DAAE000ull, "1.0.0"}}, // option + {0x81e99d64, {CODEC_UTF16, 0, 0, ReadTextAndLenW, F0100874017BE2000, 0x010037400DAAE000ull, "1.0.0"}}, // choice + {0x8186f81c, {CODEC_UTF16, 0, 0, ReadTextAndLenW, F0100874017BE2000, 0x010037400DAAE000ull, "1.0.0"}}, // archives // 5分後に意外な結末 モノクロームの図書館 {0x81fa4890, {CODEC_UTF16, 1, 0X14, 0, F010094601D910000, 0x010094601D910000ull, "1.0.1"}}, // book text {0x81fa5250, {CODEC_UTF16, 1, 0X14, 0, F010094601D910000, 0x010094601D910000ull, "1.0.1"}}, // book text @@ -2834,22 +2833,22 @@ namespace {0x800374a0, {0, 0, 0, 0, F0100068019996000, 0x010024200E00A000ull, "1.0.0"}}, // Main Text + Name,sjis {0x8002ea08, {0, 0, 0, 0, F0100068019996000, 0x010024200E00A000ull, "1.0.0"}}, // Choices,sjis // ワンド オブ フォーチュン R~ for Nintendo Switch - {0x81ed0580, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100DA201E0DA000, 0x01000C7019E1C000ull, "1.0.0"}}, // dialogue - {0x81f96bac, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100DA201E0DA000, 0x01000C7019E1C000ull, "1.0.0"}}, // name - {0x8250ac28, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100DA201E0DA000, 0x01000C7019E1C000ull, "1.0.0"}}, // choice + {0x81ed0580, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100DA201E0DA000, 0x01000C7019E1C000ull, "1.0.0"}}, // dialogue + {0x81f96bac, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100DA201E0DA000, 0x01000C7019E1C000ull, "1.0.0"}}, // name + {0x8250ac28, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100DA201E0DA000, 0x01000C7019E1C000ull, "1.0.0"}}, // choice // ワンド オブ フォーチュン R2 ~時空に沈む黙示録~ for Nintendo Switch - {0x821540c4, {CODEC_UTF16, 0, 0, ReadTextAndLenW<0>, F0100DA201E0DA000, 0x010088A01A774000ull, "1.0.0"}}, // dialogue - {0x8353e674, {CODEC_UTF16, 0, 0, ReadTextAndLenW<0>, F0100DA201E0DA000, 0x010088A01A774000ull, "1.0.0"}}, // choice - {0x835015e8, {CODEC_UTF16, 0, 0, ReadTextAndLenW<0>, F0100DA201E0DA000, 0x010088A01A774000ull, "1.0.0"}}, // name + {0x821540c4, {CODEC_UTF16, 0, 0, ReadTextAndLenW, F0100DA201E0DA000, 0x010088A01A774000ull, "1.0.0"}}, // dialogue + {0x8353e674, {CODEC_UTF16, 0, 0, ReadTextAndLenW, F0100DA201E0DA000, 0x010088A01A774000ull, "1.0.0"}}, // choice + {0x835015e8, {CODEC_UTF16, 0, 0, ReadTextAndLenW, F0100DA201E0DA000, 0x010088A01A774000ull, "1.0.0"}}, // name // Yo-kai Watch 4++ {0x80a88080, {CODEC_UTF8, 1, 0, 0, F010086C00AF7C000, 0x010086C00AF7C000ull, "2.2.0"}}, // All Text // キューピット・パラサイト -Sweet & Spicy Darling.- {0x80138150, {CODEC_UTF32, 2, 0, 0, F010079C017B98000, 0x010079C017B98000ull, "1.0.0"}}, // name + text {0x801a1bf0, {CODEC_UTF32, 0, 0, 0, F010079C017B98000, 0x010079C017B98000ull, "1.0.0"}}, // choice // DesperaDrops - {0x8199c95c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F010061A01C1CE000, 0x010061A01C1CE000ull, "1.0.0"}}, // text1 - {0x81d5c900, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F010061A01C1CE000, 0x010061A01C1CE000ull, "1.0.0"}}, // text2 - {0x820d6324, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F010061A01C1CE000, 0x010061A01C1CE000ull, "1.0.0"}}, // choice + {0x8199c95c, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F010061A01C1CE000, 0x010061A01C1CE000ull, "1.0.0"}}, // text1 + {0x81d5c900, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F010061A01C1CE000, 0x010061A01C1CE000ull, "1.0.0"}}, // text2 + {0x820d6324, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F010061A01C1CE000, 0x010061A01C1CE000ull, "1.0.0"}}, // choice // Dragon Ball Z: Kakarot {0x812a8e28, {CODEC_UTF16, 0, 0, 0, F01008C0016544000, 0x0100EF00134F4000ull, "1.50"}}, // Main Text {0x812a8c90, {CODEC_UTF16, 0, 0, 0, F01008C0016544000, 0x0100EF00134F4000ull, "1.50"}}, // Name @@ -2911,26 +2910,26 @@ namespace // The World Ends with You: Final Remix {0x80706ab8, {CODEC_UTF16, 2, 0, 0, F01006F000B056000, 0x01001C1009892000ull, "1.0.0"}}, // Text // JackJanne - {0x81f02cd8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100982015606000, 0x01001DD010A2E800ull, "1.0.5"}}, // Text - {0x821db028, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100982015606000, 0x01001DD010A2E800ull, "1.0.5"}}, // choice + {0x81f02cd8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100982015606000, 0x01001DD010A2E800ull, "1.0.5"}}, // Text + {0x821db028, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100982015606000, 0x01001DD010A2E800ull, "1.0.5"}}, // choice // Collar x Malice {0x800444c4, {CODEC_UTF8, 0, 0, 0, 0, 0x01002B400E9DA000ull, "1.0.0"}}, // Text // 神田アリスも推理スル。 {0x80041db0, {0, 0, 0, 0, F01003BD013E30000, 0x01003BD013E30000ull, "1.0.0"}}, // sjis // Rune Factory 3 Special - {0x81fb3364, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F01001EF017BE6000, 0x01001EF017BE6000ull, "1.0.4"}}, // Main Text - {0x826c0f20, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F01001EF017BE6000, 0x01001EF017BE6000ull, "1.0.4"}}, // Aproach - {0x81fb3320, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F01001EF017BE6000, 0x01001EF017BE6000ull, "1.0.4"}}, // Choices - {0x821497e8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F01001EF017BE6000, 0x01001EF017BE6000ull, "1.0.4"}}, // Calendar - {0x826ba1a0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F01001EF017BE6000, 0x01001EF017BE6000ull, "1.0.4"}}, // Info - {0x823f6200, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F01001EF017BE6000, 0x01001EF017BE6000ull, "1.0.4"}}, // More Info - {0x826c381c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F01001EF017BE6000, 0x01001EF017BE6000ull, "1.0.4"}}, // Item Select Name + {0x81fb3364, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F01001EF017BE6000, 0x01001EF017BE6000ull, "1.0.4"}}, // Main Text + {0x826c0f20, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F01001EF017BE6000, 0x01001EF017BE6000ull, "1.0.4"}}, // Aproach + {0x81fb3320, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F01001EF017BE6000, 0x01001EF017BE6000ull, "1.0.4"}}, // Choices + {0x821497e8, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F01001EF017BE6000, 0x01001EF017BE6000ull, "1.0.4"}}, // Calendar + {0x826ba1a0, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F01001EF017BE6000, 0x01001EF017BE6000ull, "1.0.4"}}, // Info + {0x823f6200, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F01001EF017BE6000, 0x01001EF017BE6000ull, "1.0.4"}}, // More Info + {0x826c381c, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F01001EF017BE6000, 0x01001EF017BE6000ull, "1.0.4"}}, // Item Select Name // 囚われのパルマ Refrain - {0x80697300, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F01000EA00D2EE000, 0x01000EA00D2EE000ull, "1.0.0"}}, // text x1 - {0x806f43c0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F01000EA00D2EE000, 0x01000EA00D2EE000ull, "1.0.0"}}, // name x0 - {0x80d2aca4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F01000EA00D2EE000, 0x01000EA00D2EE000ull, "1.0.0"}}, // choice x0 - {0x804b04c8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F01000EA00D2EE000, 0x01000EA00D2EE000ull, "1.0.0"}}, // alert x0 - {0x804b725c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F01000EA00D2EE000, 0x01000EA00D2EE000ull, "1.0.0"}}, // prompt x0 + {0x80697300, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F01000EA00D2EE000, 0x01000EA00D2EE000ull, "1.0.0"}}, // text x1 + {0x806f43c0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F01000EA00D2EE000, 0x01000EA00D2EE000ull, "1.0.0"}}, // name x0 + {0x80d2aca4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F01000EA00D2EE000, 0x01000EA00D2EE000ull, "1.0.0"}}, // choice x0 + {0x804b04c8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F01000EA00D2EE000, 0x01000EA00D2EE000ull, "1.0.0"}}, // alert x0 + {0x804b725c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F01000EA00D2EE000, 0x01000EA00D2EE000ull, "1.0.0"}}, // prompt x0 // 穢翼のユースティア {0x804BEFD0, {CODEC_UTF8, 0, 0, 0, F01006590155AC000, 0x01001CC017BB2000ull, "1.0.0"}}, // x0 - name {0x804BEFE8, {CODEC_UTF8, 0, 0, 0, F01006590155AC000, 0x01001CC017BB2000ull, "1.0.0"}}, // x0 - dialogue @@ -2963,30 +2962,30 @@ namespace {0x80e20290, {CODEC_UTF8, 3, 0, 0, F010051D010FC2000, 0x010051D010FC2000ull, "4.0.0"}}, // Opening Song Text etc {0x80c43680, {CODEC_UTF8, 3, 0, 0, F010051D010FC2000, 0x010051D010FC2000ull, "4.0.0"}}, // Cutscene Text // NEO: The World Ends With You - {0x81581d6c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F010043B013C5C000, 0x010043B013C5C000ull, "1.03"}}, // Text - {0x818eb248, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F010043B013C5C000, 0x010043B013C5C000ull, "1.03"}}, // Objective - {0x81db84a4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F010043B013C5C000, 0x010043B013C5C000ull, "1.03"}}, // Menu: Collection Item Name - {0x81db8660, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F010043B013C5C000, 0x010043B013C5C000ull, "1.03"}}, // Menu: Collection Item Description - {0x81c71a48, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F010043B013C5C000, 0x010043B013C5C000ull, "1.03"}}, // Tutorial Title - {0x81c71b28, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F010043B013C5C000, 0x010043B013C5C000ull, "1.03"}}, // Tutorial Description + {0x81581d6c, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F010043B013C5C000, 0x010043B013C5C000ull, "1.03"}}, // Text + {0x818eb248, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F010043B013C5C000, 0x010043B013C5C000ull, "1.03"}}, // Objective + {0x81db84a4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F010043B013C5C000, 0x010043B013C5C000ull, "1.03"}}, // Menu: Collection Item Name + {0x81db8660, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F010043B013C5C000, 0x010043B013C5C000ull, "1.03"}}, // Menu: Collection Item Description + {0x81c71a48, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F010043B013C5C000, 0x010043B013C5C000ull, "1.03"}}, // Tutorial Title + {0x81c71b28, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F010043B013C5C000, 0x010043B013C5C000ull, "1.03"}}, // Tutorial Description // Eiyuden Chronicle: Rising - {0x82480190, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, 0, 0x010039B015CB6000ull, "1.02"}}, // Main Text - {0x824805d0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, 0, 0x010039B015CB6000ull, "1.02"}}, // Name - {0x81f05c44, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x010039B015CB6000ull, "1.02"}}, // Intro Text - {0x82522ac4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x010039B015CB6000ull, "1.02"}}, // Character Info - {0x81b715f4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x010039B015CB6000ull, "1.02"}}, // Info - {0x825274d0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, 0, 0x010039B015CB6000ull, "1.02"}}, // Info2 - {0x825269b0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x010039B015CB6000ull, "1.02"}}, // Tutorial Title - {0x82526a0c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x010039B015CB6000ull, "1.02"}}, // Tutorial Description - {0x82523e04, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x010039B015CB6000ull, "1.02"}}, // Objective Title - {0x82524160, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x010039B015CB6000ull, "1.02"}}, // Objective Description - {0x81f0351c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x010039B015CB6000ull, "1.02"}}, // Location Selection Title - {0x81f0358c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x010039B015CB6000ull, "1.02"}}, // Location Selection Description - {0x81f0d520, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x010039B015CB6000ull, "1.02"}}, // Quest Title - {0x81f0d58c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x010039B015CB6000ull, "1.02"}}, // Quest Description - {0x81f00318, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x010039B015CB6000ull, "1.02"}}, // Help Title - {0x81f00368, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x010039B015CB6000ull, "1.02"}}, // Help Description - {0x81f0866c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, 0, 0x010039B015CB6000ull, "1.02"}}, // Config Description + {0x82480190, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, 0, 0x010039B015CB6000ull, "1.02"}}, // Main Text + {0x824805d0, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, 0, 0x010039B015CB6000ull, "1.02"}}, // Name + {0x81f05c44, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x010039B015CB6000ull, "1.02"}}, // Intro Text + {0x82522ac4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x010039B015CB6000ull, "1.02"}}, // Character Info + {0x81b715f4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x010039B015CB6000ull, "1.02"}}, // Info + {0x825274d0, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, 0, 0x010039B015CB6000ull, "1.02"}}, // Info2 + {0x825269b0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x010039B015CB6000ull, "1.02"}}, // Tutorial Title + {0x82526a0c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x010039B015CB6000ull, "1.02"}}, // Tutorial Description + {0x82523e04, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x010039B015CB6000ull, "1.02"}}, // Objective Title + {0x82524160, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x010039B015CB6000ull, "1.02"}}, // Objective Description + {0x81f0351c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x010039B015CB6000ull, "1.02"}}, // Location Selection Title + {0x81f0358c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x010039B015CB6000ull, "1.02"}}, // Location Selection Description + {0x81f0d520, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x010039B015CB6000ull, "1.02"}}, // Quest Title + {0x81f0d58c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x010039B015CB6000ull, "1.02"}}, // Quest Description + {0x81f00318, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x010039B015CB6000ull, "1.02"}}, // Help Title + {0x81f00368, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x010039B015CB6000ull, "1.02"}}, // Help Description + {0x81f0866c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, 0, 0x010039B015CB6000ull, "1.02"}}, // Config Description // Ghost Trick: Phantom Detective {0x81448898, {CODEC_UTF16, 0, 0, 0, F010043B013C5C000, 0x010029B018432000ull, "1.0.0"}}, // Main Text {0x80c540d4, {CODEC_UTF16, 0, 0, 0, F010043B013C5C000, 0x010029B018432000ull, "1.0.0"}}, // Secondary Text @@ -3002,42 +3001,42 @@ namespace {0x80026378, {CODEC_UTF8, 0, 0, 0, 0, 0x01006A300BA2C000ull, "1.0.0"}}, // x0 Yes|No {0x801049a8, {CODEC_UTF8, 0, 0, 0, 0, 0x01006A300BA2C000ull, "1.0.0"}}, // x0 topLeft (double: ♪ + text) // 殺し屋とストロベリー - {0x81322cec, {CODEC_UTF16, 0, 0, ReadTextAndLenW<0>, F010042300C4F6000, 0x0100E390145C8000ull, "1.0.0"}}, // dialogue - {0x819b1a78, {CODEC_UTF16, 0, 0, ReadTextAndLenW<2>, F010042300C4F6000, 0x0100E390145C8000ull, "1.0.0"}}, // dialogue - {0x81314e8c, {CODEC_UTF16, 0, 0, ReadTextAndLenW<0>, F010042300C4F6000, 0x0100E390145C8000ull, "1.0.0"}}, // dialogue + {0x81322cec, {CODEC_UTF16, 0, 0, ReadTextAndLenW, F010042300C4F6000, 0x0100E390145C8000ull, "1.0.0"}}, // dialogue + {0x819b1a78, {CODEC_UTF16, 2, 0, ReadTextAndLenW, F010042300C4F6000, 0x0100E390145C8000ull, "1.0.0"}}, // dialogue + {0x81314e8c, {CODEC_UTF16, 0, 0, ReadTextAndLenW, F010042300C4F6000, 0x0100E390145C8000ull, "1.0.0"}}, // dialogue // ときめきメモリアル Girl's Side - {0x822454a4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // dialogue1 - {0x82247138, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // dialogue2 - {0x822472e0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // dialogue3 - {0x82156988, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // choice - {0x82642200, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<2>, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // option1 - {0x81ecd758, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // option2 - {0x823185e4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // mail - {0x823f2edc, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // roomDescript - {0x821e3cf0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // dateDescript - {0x81e20050, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // characterDesc1 - {0x81e1fe50, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // characterDesc2 - {0x81e1feb0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // characterDesc3 - {0x81e1ff04, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // characterDesc4 - {0x821d03b0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<3>, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // news - {0x82312008, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // luckyitem - {0x8093F4F4, {CODEC_UTF8, 1, 0, 0, F0100D9A01BD86000_0, 0x0100D9A01BD86000ull, "1.0.0"}}, // text + {0x822454a4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // dialogue1 + {0x82247138, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // dialogue2 + {0x822472e0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // dialogue3 + {0x82156988, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // choice + {0x82642200, {CODEC_UTF16, 2, 0, ReadTextAndLenDW, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // option1 + {0x81ecd758, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // option2 + {0x823185e4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // mail + {0x823f2edc, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // roomDescript + {0x821e3cf0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // dateDescript + {0x81e20050, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // characterDesc1 + {0x81e1fe50, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // characterDesc2 + {0x81e1feb0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // characterDesc3 + {0x81e1ff04, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // characterDesc4 + {0x821d03b0, {CODEC_UTF16, 3, 0, ReadTextAndLenDW, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // news + {0x82312008, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100D9A01BD86000, 0x0100D9A01BD86000ull, "1.0.1"}}, // luckyitem + {0x8093F4F4, {CODEC_UTF8, 1, 0, 0, F0100D9A01BD86000_0, 0x0100D9A01BD86000ull, "1.0.0"}}, // text // ときめきメモリアル Girl’s Side 2nd Kiss - {0x82058848, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F010079201BD88000, 0x010079201BD88000ull, "1.0.1"}}, // dialogue1 - {0x82058aa0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F010079201BD88000, 0x010079201BD88000ull, "1.0.1"}}, // dialogue2 - {0x8205a244, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F010079201BD88000, 0x010079201BD88000ull, "1.0.1"}}, // dialogue3 - {0x826ee1d8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F010079201BD88000, 0x010079201BD88000ull, "1.0.1"}}, // choice - {0x8218e258, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F010079201BD88000, 0x010079201BD88000ull, "1.0.1"}}, // news - {0x823b61d4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F010079201BD88000, 0x010079201BD88000ull, "1.0.1"}}, // mail - {0x82253454, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F010079201BD88000, 0x010079201BD88000ull, "1.0.1"}}, // luckyitem - {0x82269240, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F010079201BD88000, 0x010079201BD88000ull, "1.0.1"}}, // profile1 - {0x82269138, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F010079201BD88000, 0x010079201BD88000ull, "1.0.1"}}, // profile2 - {0x822691ec, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F010079201BD88000, 0x010079201BD88000ull, "1.0.1"}}, // profile3 - {0x82269198, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F010079201BD88000, 0x010079201BD88000ull, "1.0.1"}}, // profile4 + {0x82058848, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F010079201BD88000, 0x010079201BD88000ull, "1.0.1"}}, // dialogue1 + {0x82058aa0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F010079201BD88000, 0x010079201BD88000ull, "1.0.1"}}, // dialogue2 + {0x8205a244, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F010079201BD88000, 0x010079201BD88000ull, "1.0.1"}}, // dialogue3 + {0x826ee1d8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F010079201BD88000, 0x010079201BD88000ull, "1.0.1"}}, // choice + {0x8218e258, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F010079201BD88000, 0x010079201BD88000ull, "1.0.1"}}, // news + {0x823b61d4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F010079201BD88000, 0x010079201BD88000ull, "1.0.1"}}, // mail + {0x82253454, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F010079201BD88000, 0x010079201BD88000ull, "1.0.1"}}, // luckyitem + {0x82269240, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F010079201BD88000, 0x010079201BD88000ull, "1.0.1"}}, // profile1 + {0x82269138, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F010079201BD88000, 0x010079201BD88000ull, "1.0.1"}}, // profile2 + {0x822691ec, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F010079201BD88000, 0x010079201BD88000ull, "1.0.1"}}, // profile3 + {0x82269198, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F010079201BD88000, 0x010079201BD88000ull, "1.0.1"}}, // profile4 // ときめきメモリアル Girl's Side 4th Heart - {0x817e7da8, {CODEC_UTF16, 0, 0, T0100B0100E26C000<2, 0>, 0, 0x0100B0100E26C000ull, "1.0.0"}}, // name (x1) + dialogue (x2) - {0x81429f54, {CODEC_UTF16, 0, 0, T0100B0100E26C000<0, 1>, 0, 0x0100B0100E26C000ull, "1.0.0"}}, // choice (x0) - {0x8180633c, {CODEC_UTF16, 0, 0, T0100B0100E26C000<1, 2>, 0, 0x0100B0100E26C000ull, "1.0.0"}}, // help (x1) + {0x817e7da8, {CODEC_UTF16, 2, 0, T0100B0100E26C000, F0100982015606000, 0x0100B0100E26C000ull, "1.0.0"}}, // name (x1) + dialogue (x2) + {0x81429f54, {CODEC_UTF16, 0, 1, T0100B0100E26C000, F0100982015606000, 0x0100B0100E26C000ull, "1.0.0"}}, // choice (x0) + {0x8180633c, {CODEC_UTF16, 1, 2, T0100B0100E26C000, F0100982015606000, 0x0100B0100E26C000ull, "1.0.0"}}, // help (x1) // Triangle Strategy {0x80aadebc, {CODEC_UTF16, 0, 0, 0, F0100CC80140F8000<0>, 0x0100CC80140F8000ull, "1.1.0"}}, // Main Text {0x81358ce4, {CODEC_UTF16, 3, 0, 0, F0100CC80140F8000<1>, 0x0100CC80140F8000ull, "1.1.0"}}, // Secondary Text @@ -3063,14 +3062,14 @@ namespace {0x8002bf6c, {CODEC_UTF8, 0, 0x1c, 0, FF010061300DF48000_2, 0x01004D601B0AA000ull, "1.0.1"}}, {0x8004e720, {CODEC_UTF8, 1, 0, 0, FF010061300DF48000_2, 0x01004D601B0AA000ull, "1.0.1"}}, // スペードの国のアリス ~Wonderful White World~ - {0x8135d018, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F01008C0016544000, 0x01003FE00E2F8000ull, "1.0.0"}}, // Text + Name + {0x8135d018, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F01008C0016544000, 0x01003FE00E2F8000ull, "1.0.0"}}, // Text + Name // スペードの国のアリス ~Wonderful Black World~ {0x819dbdc8, {CODEC_UTF16, 0, 0x14, 0, F0100AB100E2FA000, 0x0100AB100E2FA000ull, "1.0.0"}}, {0x81f8e564, {CODEC_UTF16, 1, 0x14, 0, F0100AB100E2FA000, 0x0100AB100E2FA000ull, "1.0.0"}}, // 十三支演義 偃月三国伝1・2 for Nintendo Switch (Juuzaengi ~Engetsu Sangokuden~) - {0x82031f20, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<2>, F0100DA201E0DA000, 0x01003D2017FEA000ull, "1.0.0"}}, // name - {0x82ef9550, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F0100DA201E0DA000, 0x01003D2017FEA000ull, "1.0.0"}}, // dialogue - {0x83252e0c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100DA201E0DA000, 0x01003D2017FEA000ull, "1.0.0"}}, // choice + {0x82031f20, {CODEC_UTF16, 2, 0, ReadTextAndLenDW, F0100DA201E0DA000, 0x01003D2017FEA000ull, "1.0.0"}}, // name + {0x82ef9550, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F0100DA201E0DA000, 0x01003D2017FEA000ull, "1.0.0"}}, // dialogue + {0x83252e0c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100DA201E0DA000, 0x01003D2017FEA000ull, "1.0.0"}}, // choice // Tales of Vesperia: Definitive Edition {0x802de170, {CODEC_UTF8, 2, 0, 0, F01002C0008E52000, 0x01002C0008E52000ull, "1.0.2"}}, // Ptc Text {0x802cf170, {CODEC_UTF8, 3, 0, 0, F01002C0008E52000, 0x01002C0008E52000ull, "1.0.2"}}, // Cutscene @@ -3116,107 +3115,107 @@ namespace {0x218B40, {FULL_STRING, 1, 0, 0, F010028D0148E6000_2, 0x010028D0148E6000ull, "1.0.1"}}, // TEXT {0x20D420, {0, 0, 0, 0, 0, 0x010028D0148E6000ull, "1.0.1"}}, // NAME+TEXT // アナザーコード リコレクション:2つの記憶 / 記憶の扉 - {0x82dcad30, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Main Text - {0x82f2cfb0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Item Description - {0x82dcc5fc, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Tutorial PopUp Header - {0x82dcc61c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Tutorial PopUp Description - {0x82f89e78, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Aproach Text - {0x82973300, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Chapter - {0x82dd2604, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Location - {0x82bcb77c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Save Message - {0x828ccfec, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Acquired Item - {0x83237b14, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Question Options - {0x82dcee10, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Tutorial Header - {0x82dcee38, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Tutorial Description - {0x82e5cadc, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Character Info Name - {0x82e5cc38, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Character Info Description - {0x82871ac8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Letter Message - {0x82e4dad4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // アナザーキー - {0x82bd65d0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Message Title - {0x82bd65f0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Message Content - {0x82c1ccf0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Decision Header - {0x82c1d218, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Decision1 - {0x82c1e43c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Decision2 + {0x82dcad30, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Main Text + {0x82f2cfb0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Item Description + {0x82dcc5fc, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Tutorial PopUp Header + {0x82dcc61c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Tutorial PopUp Description + {0x82f89e78, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Aproach Text + {0x82973300, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Chapter + {0x82dd2604, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Location + {0x82bcb77c, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Save Message + {0x828ccfec, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Acquired Item + {0x83237b14, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Question Options + {0x82dcee10, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Tutorial Header + {0x82dcee38, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Tutorial Description + {0x82e5cadc, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Character Info Name + {0x82e5cc38, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Character Info Description + {0x82871ac8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Letter Message + {0x82e4dad4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // アナザーキー + {0x82bd65d0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Message Title + {0x82bd65f0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Message Content + {0x82c1ccf0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Decision Header + {0x82c1d218, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Decision1 + {0x82c1e43c, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100CB9018F5A000, 0x0100CB9018F5A000ull, "1.0.0"}}, // Decision2 // AI:ソムニウム ファイル - {0x8165a9a4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100C7400CFB4000, 0x0100C7400CFB4000ull, "1.0.2"}}, // Main Text + Tutorial - {0x80320dd4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F0100C7400CFB4000, 0x0100C7400CFB4000ull, "1.0.2"}}, // Menu Interface Text1 - {0x80320e20, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F0100C7400CFB4000, 0x0100C7400CFB4000ull, "1.0.2"}}, // Menu Interface Text2 + {0x8165a9a4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100C7400CFB4000, 0x0100C7400CFB4000ull, "1.0.2"}}, // Main Text + Tutorial + {0x80320dd4, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F0100C7400CFB4000, 0x0100C7400CFB4000ull, "1.0.2"}}, // Menu Interface Text1 + {0x80320e20, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F0100C7400CFB4000, 0x0100C7400CFB4000ull, "1.0.2"}}, // Menu Interface Text2 // AI: ソムニウムファイル ニルヴァーナイニシアチブ - {0x8189ae64, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BD4014D8C000, 0x0100BD4014D8C000ull, "1.0.1"}}, // Main Text + Tutorial - {0x81813428, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BD4014D8C000, 0x0100BD4014D8C000ull, "1.0.1"}}, // Hover Investigation Text - {0x82e122b8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BD4014D8C000, 0x0100BD4014D8C000ull, "1.0.1"}}, // Info - {0x82cffff8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BD4014D8C000, 0x0100BD4014D8C000ull, "1.0.1"}}, // Config Description - {0x818c3cd8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BD4014D8C000, 0x0100BD4014D8C000ull, "1.0.1"}}, // File: Names - {0x82ea1a38, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BD4014D8C000, 0x0100BD4014D8C000ull, "1.0.1"}}, // File: Contents - {0x82cbb1fc, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F0100BD4014D8C000, 0x0100BD4014D8C000ull, "1.0.1"}}, // Investigation Choices + {0x8189ae64, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BD4014D8C000, 0x0100BD4014D8C000ull, "1.0.1"}}, // Main Text + Tutorial + {0x81813428, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BD4014D8C000, 0x0100BD4014D8C000ull, "1.0.1"}}, // Hover Investigation Text + {0x82e122b8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BD4014D8C000, 0x0100BD4014D8C000ull, "1.0.1"}}, // Info + {0x82cffff8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BD4014D8C000, 0x0100BD4014D8C000ull, "1.0.1"}}, // Config Description + {0x818c3cd8, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BD4014D8C000, 0x0100BD4014D8C000ull, "1.0.1"}}, // File: Names + {0x82ea1a38, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BD4014D8C000, 0x0100BD4014D8C000ull, "1.0.1"}}, // File: Contents + {0x82cbb1fc, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F0100BD4014D8C000, 0x0100BD4014D8C000ull, "1.0.1"}}, // Investigation Choices // ファタモルガーナの館 -DREAMS OF THE REVENANTS EDITION- - {0x8025a998, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F01008C0016544000, 0x0100BE40138B8000ull, "1.0.1"}}, // Main Text - {0x801d6050, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F01008C0016544000, 0x0100BE40138B8000ull, "1.0.1"}}, // Choices + {0x8025a998, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F01008C0016544000, 0x0100BE40138B8000ull, "1.0.1"}}, // Main Text + {0x801d6050, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F01008C0016544000, 0x0100BE40138B8000ull, "1.0.1"}}, // Choices // Ni no Kuni II: Revenant Kingdom {0x80ac651c, {CODEC_UTF8, 0, 0, 0, F0100C4E013E5E000, 0x0100C4E013E5E000ull, "1.0.0"}}, // Main Text {0x80335ea0, {CODEC_UTF8, 0, 0, 0, F0100C4E013E5E000, 0x0100C4E013E5E000ull, "1.0.0"}}, // Name // 遙かなる時空の中で7 - {0x800102bc, {0, 0, 0, T0100CF400F7CE000<0>, F0100CF400F7CE000, 0x0100CF400F7CE000ull, "1.0.0"}}, // name, sjis - {0x80051f90, {0, 0, 0, T0100CF400F7CE000<1>, F0100CF400F7CE000, 0x0100CF400F7CE000ull, "1.0.0"}}, // text - {0x80010b48, {0, 0, 0, T0100CF400F7CE000<0>, F0100CF400F7CE000, 0x0100CF400F7CE000ull, "1.0.0"}}, // prompt - {0x80010c80, {0, 0, 0, T0100CF400F7CE000<0>, F0100CF400F7CE000, 0x0100CF400F7CE000ull, "1.0.0"}}, // choice + {0x800102bc, {0, 0, 0, T0100CF400F7CE000, F0100CF400F7CE000, 0x0100CF400F7CE000ull, "1.0.0"}}, // name, sjis + {0x80051f90, {0, 1, 0, T0100CF400F7CE000, F0100CF400F7CE000, 0x0100CF400F7CE000ull, "1.0.0"}}, // text + {0x80010b48, {0, 0, 0, T0100CF400F7CE000, F0100CF400F7CE000, 0x0100CF400F7CE000ull, "1.0.0"}}, // prompt + {0x80010c80, {0, 0, 0, T0100CF400F7CE000, F0100CF400F7CE000, 0x0100CF400F7CE000ull, "1.0.0"}}, // choice // アンジェリーク ルミナライズ - {0x80046c04, {0, 0, 0, T0100CF400F7CE000<0>, F0100CF400F7CE000, 0x0100D11018A7E000ull, "1.0.0"}}, // ingameDialogue, sjis - {0x80011284, {0, 0, 0, T0100CF400F7CE000<0>, F0100CF400F7CE000, 0x0100D11018A7E000ull, "1.0.0"}}, // choice - {0x80011140, {0, 0, 0, T0100CF400F7CE000<0>, F0100CF400F7CE000, 0x0100D11018A7E000ull, "1.0.0"}}, // prompt first + {0x80046c04, {0, 0, 0, T0100CF400F7CE000, F0100CF400F7CE000, 0x0100D11018A7E000ull, "1.0.0"}}, // ingameDialogue, sjis + {0x80011284, {0, 0, 0, T0100CF400F7CE000, F0100CF400F7CE000, 0x0100D11018A7E000ull, "1.0.0"}}, // choice + {0x80011140, {0, 0, 0, T0100CF400F7CE000, F0100CF400F7CE000, 0x0100D11018A7E000ull, "1.0.0"}}, // prompt first // Star Ocean The Second Story R - {0x81d5e4d0, {0, 0, 0, ReadTextAndLenDW<1>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Main Text + Tutorial - {0x81d641b4, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Intro Cutscene - {0x824b1f00, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Character Selection Name - {0x81d4c670, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Character Selection Lore - {0x8203a048, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // General Description - {0x82108cd0, {0, 0, 0, ReadTextAndLenDW<1>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Unique Spot Title - {0x827a9848, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Chest Item - {0x82756890, {0, 0, 0, ReadTextAndLenDW<1>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Info - {0x82241410, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Menu Talk - {0x81d76404, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Secondary Talk - {0x821112e0, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Location - {0x82111320, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Location Interior - {0x81d6ea24, {0, 0, 0, ReadTextAndLenDW<1>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Special Arts/Spells Name - {0x81d6ea68, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Special Arts/Spells Description - {0x81d6ed48, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Special Arts/Spells Range - {0x81d6eb3c, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Special Arts/Spells Effect - {0x81d6f880, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Special Arts/Spells Bonus - {0x8246d81c, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Tactics Name - {0x8246d83c, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Tactics Description - {0x8212101c, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Achievements Name - {0x82121088, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Achievements Description - {0x81d6c480, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Acquired Item1 - {0x821143f0, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Acquired Item2 - {0x81d6fb18, {0, 0, 0, ReadTextAndLenDW<1>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Battle Skill Name - {0x81d6fb4c, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Battle Skill Description - {0x81d6fb7c, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Battle Skill Bonus Description - {0x8212775c, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Battle Item Name - {0x82127788, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Battle Item Description - {0x821361ac, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Battle Ability Name - {0x821361f4, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Battle Ability Range - {0x82136218, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Battle Ability Effect - {0x8238451c, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Battle Strategy Name - {0x82134610, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Battle Acquired Item - {0x824b5eac, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Item Name - {0x824b5f04, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Item Description - {0x824b5f54, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Item Effect - {0x81d71790, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Item Factor Title - {0x824b62c0, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Item Factor Description - {0x824c2e2c, {0, 0, 0, ReadTextAndLenDW<1>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // IC/Specialty Skills Name - {0x824c2e54, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // IC/Specialty Skills Description - {0x824c2fbc, {0, 0, 0, ReadTextAndLenDW<1>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // IC/Specialty Skills Level - {0x823e7230, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // IC/Specialty Name - {0x823e94bc, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // IC/Specialty Description - {0x823e9980, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // IC/Specialty Talent - {0x823ea9c4, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // IC/Specialty Support Item - {0x82243b18, {0, 0, 0, ReadTextAndLenDW<1>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Enemy Info Skills - {0x81d64540, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Guild Mission Description - {0x823b4f6c, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Guild Mission Reward - {0x826facd8, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Challenge Mission Description - {0x826f98f8, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Challenge Mission Reward - {0x8244af2c, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Formation Name - {0x8244ae90, {0, 0, 0, ReadTextAndLenDW<0>, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Formation Description + {0x81d5e4d0, {0, 1, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Main Text + Tutorial + {0x81d641b4, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Intro Cutscene + {0x824b1f00, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Character Selection Name + {0x81d4c670, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Character Selection Lore + {0x8203a048, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // General Description + {0x82108cd0, {0, 1, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Unique Spot Title + {0x827a9848, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Chest Item + {0x82756890, {0, 1, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Info + {0x82241410, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Menu Talk + {0x81d76404, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Secondary Talk + {0x821112e0, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Location + {0x82111320, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Location Interior + {0x81d6ea24, {0, 1, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Special Arts/Spells Name + {0x81d6ea68, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Special Arts/Spells Description + {0x81d6ed48, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Special Arts/Spells Range + {0x81d6eb3c, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Special Arts/Spells Effect + {0x81d6f880, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Special Arts/Spells Bonus + {0x8246d81c, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Tactics Name + {0x8246d83c, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Tactics Description + {0x8212101c, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Achievements Name + {0x82121088, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Achievements Description + {0x81d6c480, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Acquired Item1 + {0x821143f0, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Acquired Item2 + {0x81d6fb18, {0, 1, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Battle Skill Name + {0x81d6fb4c, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Battle Skill Description + {0x81d6fb7c, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Battle Skill Bonus Description + {0x8212775c, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Battle Item Name + {0x82127788, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Battle Item Description + {0x821361ac, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Battle Ability Name + {0x821361f4, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Battle Ability Range + {0x82136218, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Battle Ability Effect + {0x8238451c, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Battle Strategy Name + {0x82134610, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Battle Acquired Item + {0x824b5eac, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Item Name + {0x824b5f04, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Item Description + {0x824b5f54, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Item Effect + {0x81d71790, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Item Factor Title + {0x824b62c0, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Item Factor Description + {0x824c2e2c, {0, 1, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // IC/Specialty Skills Name + {0x824c2e54, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // IC/Specialty Skills Description + {0x824c2fbc, {0, 1, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // IC/Specialty Skills Level + {0x823e7230, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // IC/Specialty Name + {0x823e94bc, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // IC/Specialty Description + {0x823e9980, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // IC/Specialty Talent + {0x823ea9c4, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // IC/Specialty Support Item + {0x82243b18, {0, 1, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Enemy Info Skills + {0x81d64540, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Guild Mission Description + {0x823b4f6c, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Guild Mission Reward + {0x826facd8, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Challenge Mission Description + {0x826f98f8, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Challenge Mission Reward + {0x8244af2c, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Formation Name + {0x8244ae90, {0, 0, 0, ReadTextAndLenDW, F010065301A2E0000, 0x010065301A2E0000ull, "1.0.2"}}, // Formation Description // 魔法使いの夜 通常版 {0x80086ba0, {CODEC_UTF8, 0, 0, T010012A017F18000, 0, 0x010012A017F18000ull, "1.0.0"}}, {0x80086e70, {CODEC_UTF8, 0, 0, T010012A017F18000, 0, 0x010012A017F18000ull, "1.0.2"}}, @@ -3231,15 +3230,15 @@ namespace // 神様のような君へ {0x80487CD0, {CODEC_UTF8, 0, 0, 0, F01006B5014E2E000, 0x01006B5014E2E000ull, "1.0.0"}}, // text // BUSTAFELLOWS - {0x80191b18, {CODEC_UTF16, 0, 0, ReadTextAndLenW<0>, F0100874017BE2000, 0x010060800B7A8000ull, "1.1.3"}}, // Dialogue - {0x80191f88, {CODEC_UTF16, 0, 0, ReadTextAndLenW<0>, F0100874017BE2000, 0x010060800B7A8000ull, "1.1.3"}}, // Choice - {0x801921a4, {CODEC_UTF16, 0, 0, ReadTextAndLenW<0>, F0100874017BE2000, 0x010060800B7A8000ull, "1.1.3"}}, // Choice 2 - {0x801935f0, {CODEC_UTF16, 0, 0, ReadTextAndLenW<0>, F0100874017BE2000, 0x010060800B7A8000ull, "1.1.3"}}, // option + {0x80191b18, {CODEC_UTF16, 0, 0, ReadTextAndLenW, F0100874017BE2000, 0x010060800B7A8000ull, "1.1.3"}}, // Dialogue + {0x80191f88, {CODEC_UTF16, 0, 0, ReadTextAndLenW, F0100874017BE2000, 0x010060800B7A8000ull, "1.1.3"}}, // Choice + {0x801921a4, {CODEC_UTF16, 0, 0, ReadTextAndLenW, F0100874017BE2000, 0x010060800B7A8000ull, "1.1.3"}}, // Choice 2 + {0x801935f0, {CODEC_UTF16, 0, 0, ReadTextAndLenW, F0100874017BE2000, 0x010060800B7A8000ull, "1.1.3"}}, // option // 猛獣使いと王子様 ~Flower & Snow~ for Nintendo Switch {0x800a1a10, {CODEC_UTF8, 1, 0, 0, F01001B900C0E2000, 0x01001B900C0E2000ull, "1.0.0"}}, // Dialogue 1 {0x80058f80, {CODEC_UTF8, 1, 0, 0, F01001B900C0E2000, 0x01001B900C0E2000ull, "1.0.0"}}, // Dialogue 2 // Detective Pikachu Returns - {0x81585750, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<2>, F010007500F27C000, 0x010007500F27C000ull, "1.0.0"}}, // All Text + {0x81585750, {CODEC_UTF16, 2, 0, ReadTextAndLenDW, F010007500F27C000, 0x010007500F27C000ull, "1.0.0"}}, // All Text // Dragon Quest Treasures {0x80bd62c4, {CODEC_UTF16, 0, 0, 0, F0100217014266000, 0x0100217014266000ull, "1.0.1"}}, // Cutscene {0x80a74b64, {CODEC_UTF16, 0, 0, 0, F0100217014266000, 0x0100217014266000ull, "1.0.1"}}, // Ptc Text @@ -3267,8 +3266,8 @@ namespace {0x802b1f3c, {CODEC_UTF8, 0, 0, 0, F010080C01AA22000, 0x010080C01AA22000ull, "1.0.0"}}, // Info {0x802ab46c, {CODEC_UTF8, 0, 0, 0, F010080C01AA22000, 0x010080C01AA22000ull, "1.0.0"}}, // Documents // DORAEMON STORY OF SEASONS: Friends of the Great Kingdom - {0x839558e4, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F01009B50139A8000, 0x01009B50139A8000ull, "1.1.1"}}, // Text - {0x8202a9b0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F01009B50139A8000, 0x01009B50139A8000ull, "1.1.1"}}, // Tutorial + {0x839558e4, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F01009B50139A8000, 0x01009B50139A8000ull, "1.1.1"}}, // Text + {0x8202a9b0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F01009B50139A8000, 0x01009B50139A8000ull, "1.1.1"}}, // Tutorial // Monster Hunter Stories 2: Wings of Ruin {0x8042fe60, {CODEC_UTF8, 1, 0, 0, F0100CB700D438000, 0x0100CB700D438000ull, "1.5.2"}}, // Cutscene {0x804326c0, {CODEC_UTF8, 1, 0, 0, F0100CB700D438000, 0x0100CB700D438000ull, "1.5.2"}}, // Ptc Text @@ -3291,9 +3290,9 @@ namespace // プリズンプリンセス {0x800eba00, {CODEC_UTF16, 2, 0x14, 0, 0, 0x0100F4800F872000ull, "1.0.0"}}, // 泡沫のユークロニア - {0x8180de40, {CODEC_UTF16, 0, 0, ReadTextAndLenW<0>, F010027401A2A2000, 0x010027401A2A2000ull, "1.0.0"}}, // text box - {0x816b61c0, {CODEC_UTF16, 0, 0, ReadTextAndLenW<0>, F010027401A2A2000, 0x010027401A2A2000ull, "1.0.0"}}, // dictionary - {0x815fe594, {CODEC_UTF16, 0, 0, ReadTextAndLenW<0>, F010027401A2A2000, 0x010027401A2A2000ull, "1.0.0"}}, // choices + {0x8180de40, {CODEC_UTF16, 0, 0, ReadTextAndLenW, F010027401A2A2000, 0x010027401A2A2000ull, "1.0.0"}}, // text box + {0x816b61c0, {CODEC_UTF16, 0, 0, ReadTextAndLenW, F010027401A2A2000, 0x010027401A2A2000ull, "1.0.0"}}, // dictionary + {0x815fe594, {CODEC_UTF16, 0, 0, ReadTextAndLenW, F010027401A2A2000, 0x010027401A2A2000ull, "1.0.0"}}, // choices {0x81836E0C, {CODEC_UTF16, 1, 0, 0, F010027401A2A2000_2, 0x010027401A2A2000ull, "1.0.1"}}, // リトルバスターズ!Converted Edition {0x800A97C8, {CODEC_UTF8, 9, 0, 0, F0100943010310000, 0x0100943010310000ull, "1.0.0"}}, @@ -3414,10 +3413,10 @@ namespace {0x83d225c0, {CODEC_UTF16, 0, 0x14, 0, F010044701E9BC000, 0x010044701E9BC000ull, "1.2.0"}}, {0x83d26fd8, {CODEC_UTF16, 0, 0x14, 0, F010044701E9BC000, 0x010044701E9BC000ull, "1.2.0"}}, // トラブル・マギア ~訳アリ少女は未来を勝ち取るために異国の魔法学校へ留学します~ - {0x8017e6b0, {CODEC_UTF16, 0, 0, T01000BB01CB8A000<1>, F01000BB01CB8A000, 0x01000BB01CB8A000ull, "1.0.0"}}, - {0x80177ae0, {CODEC_UTF16, 0, 0, T01000BB01CB8A000<0>, F01000BB01CB8A000, 0x01000BB01CB8A000ull, "1.0.0"}}, - {0x80122a4c, {CODEC_UTF16, 0, 0, T01000BB01CB8A000<0>, F01000BB01CB8A000, 0x01000BB01CB8A000ull, "1.0.0"}}, - {0x800ba088, {CODEC_UTF16, 0, 0, T01000BB01CB8A000<0>, F01000BB01CB8A000, 0x01000BB01CB8A000ull, "1.0.0"}}, + {0x8017e6b0, {CODEC_UTF16, 1, 0, T01000BB01CB8A000, F01000BB01CB8A000, 0x01000BB01CB8A000ull, "1.0.0"}}, + {0x80177ae0, {CODEC_UTF16, 0, 0, T01000BB01CB8A000, F01000BB01CB8A000, 0x01000BB01CB8A000ull, "1.0.0"}}, + {0x80122a4c, {CODEC_UTF16, 0, 0, T01000BB01CB8A000, F01000BB01CB8A000, 0x01000BB01CB8A000ull, "1.0.0"}}, + {0x800ba088, {CODEC_UTF16, 0, 0, T01000BB01CB8A000, F01000BB01CB8A000, 0x01000BB01CB8A000ull, "1.0.0"}}, // 燃えよ! 乙女道士 ~華遊恋語~ {0x8005c698, {CODEC_UTF16, 1, 0x20, 0, F01001BA01EBFC000, 0x01001BA01EBFC000ull, "1.0.0"}}, {0x80051cd0, {CODEC_UTF16, 1, 0, 0, F01001BA01EBFC000, 0x01001BA01EBFC000ull, "1.0.0"}}, @@ -3531,7 +3530,7 @@ namespace {0x8006BCC0, {0, 8, 0, 0, F01002BB00A662000, 0x01002BB00A662000ull, "1.0.0"}}, // text {0x8007C1D4, {0, 0, 0, 0, F01002BB00A662000, 0x01002BB00A662000ull, "1.0.0"}}, // name+text 这个两作都能提到。实际上只留这一个也行,但它显示完才有,速度慢。 // 八剱伝 - {0x819ade74, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<1>, F01007A901E728000, 0x01007A901E728000ull, "1.0.1"}}, + {0x819ade74, {CODEC_UTF16, 1, 0, ReadTextAndLenDW, F01007A901E728000, 0x01007A901E728000ull, "1.0.1"}}, // 大正メビウスライン大全 三合一 {0x800C43D4, {0, 0, 0, 0, F0100509013040000, 0x0100509013040000ull, "1.0.0"}}, // text {0x800C4468, {0, 0, 0, 0, F0100509013040000, 0x0100509013040000ull, "1.0.1"}}, // text @@ -3576,7 +3575,7 @@ namespace {0x80020974, {0, 0, 0, 0, F0100D8B019FC0000, 0x0100D8B019FC0000ull, "1.0.0"}}, {0x80020958, {0, 0, 0, 0, F0100D8B019FC0000, 0x0100D8B019FC0000ull, "1.0.0"}}, // FANTASIAN Neo Dimension - {0x81719ea0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW<0>, F01001BB01E8E2000, 0x01001BB01E8E2000ull, "1.0.0"}}, + {0x81719ea0, {CODEC_UTF16, 0, 0, ReadTextAndLenDW, F01001BB01E8E2000, 0x01001BB01E8E2000ull, "1.0.0"}}, // アイキス3cute {0x804C18C4, {CODEC_UTF8, 1, 0, 0, F0100FD4016528000, 0x0100FD4016528000ull, nullptr}}, // 1.0.0 && 1.0.2 diff --git a/cpp/LunaHook/LunaHook/enginecontrol.cpp b/cpp/LunaHook/LunaHook/enginecontrol.cpp index a278f5c5..cd319978 100644 --- a/cpp/LunaHook/LunaHook/enginecontrol.cpp +++ b/cpp/LunaHook/LunaHook/enginecontrol.cpp @@ -51,7 +51,7 @@ bool safematch(ENGINE *m) } __except (EXCEPTION_EXECUTE_HANDLER) { - ConsoleOutput(Match_Error, m->getenginename()); + ConsoleOutput(TR[Match_Error], m->getenginename()); // ConsoleOutput("match ERROR"); } return matched; @@ -65,7 +65,7 @@ bool safeattach(ENGINE *m) } __except (EXCEPTION_EXECUTE_HANDLER) { - ConsoleOutput(Attach_Error, m->getenginename()); + ConsoleOutput(TR[Attach_Error], m->getenginename()); // ConsoleOutput("attach ERROR"); } return attached; @@ -90,16 +90,16 @@ bool checkengine() //ConsoleOutput("Progress %d/%d, %s",current,engines.size(),infomations[matched+attached]); if (matched == false) continue; - ConsoleOutput(MatchedEngine, m->getenginename()); + ConsoleOutput(TR[MatchedEngine], m->getenginename()); if (m->is_engine_certain) { - ConsoleOutput(ConfirmStop, m->getenginename()); + ConsoleOutput(TR[ConfirmStop], m->getenginename()); return attached; } if (attached) { - ConsoleOutput(Attach_Stop, m->getenginename()); + ConsoleOutput(TR[Attach_Stop], m->getenginename()); return true; } } @@ -121,10 +121,10 @@ void HIJACK() std::tie(processStartAddress, processStopAddress) = Util::QueryModuleLimits(GetModuleHandleW(nullptr), 0, 1 + PAGE_NOACCESS); spDefault.minAddress = processStartAddress; spDefault.maxAddress = processStopAddress; - ConsoleOutput(ProcessRange, processStartAddress, processStopAddress); + ConsoleOutput(TR[ProcessRange], processStartAddress, processStopAddress); if (processStartAddress + 0x40000 > processStopAddress) - ConsoleOutput(WarningDummy); + ConsoleOutput(TR[WarningDummy]); bool result = false; __try @@ -133,7 +133,7 @@ void HIJACK() } __except (EXCEPTION_EXECUTE_HANDLER) { - ConsoleOutput(HIJACK_ERROR); + ConsoleOutput(TR[HIJACK_ERROR]); } if (!result) diff --git a/cpp/LunaHook/LunaHook/engines/ppsspp/specialgames.hpp b/cpp/LunaHook/LunaHook/engines/ppsspp/specialgames.hpp index f28d598a..1a799caf 100644 --- a/cpp/LunaHook/LunaHook/engines/ppsspp/specialgames.hpp +++ b/cpp/LunaHook/LunaHook/engines/ppsspp/specialgames.hpp @@ -219,9 +219,20 @@ namespace ppsspp std::string s; int i = 0; uint8_t c; - while ((c = *(uint8_t *)(address + i)) != 0) + if (*(BYTE *)(address + i) == 0xaa) + i += 1; + + while (true) { - if (c == 0x1b) + c = *(uint8_t *)(address + i); + if (!c) + { + if (*(uint8_t *)(address + i + 1) == 0xaa) + i += 2; + else + break; + } + else if (c == 0x1b) { if (*haveName) return s; // (1) skip junk after name @@ -254,7 +265,7 @@ namespace ppsspp } void ULJM05428(hook_context *context, HookParam *hp, TextBuffer *buffer, uintptr_t *split) { - auto address = PPSSPP::emu_arg(context)[1]; + auto address = PPSSPP::emu_arg(context)[hp->offset]; bool haveNamve; auto s = Corda::readBinaryString(address, &haveNamve); *split = haveNamve; @@ -963,14 +974,22 @@ namespace ppsspp {0x0891D72C, {CODEC_UTF8, 0, 0, 0, ULJM06119_filter, "ULJM06119"}}, // Princess Evangile {0x88506d0, {CODEC_UTF16, 2, 0, 0, ULJM06036_filter, "ULJM06036"}}, // [0x88506d0(2)...0x088507C0(?)] // name text text (line doubled) + // 金色のコルダ3 AnotherSky feat.神南 + {0x883C940, {0, 0, 0, ULJM05428, 0, "NPJH50845"}}, + // 金色のコルダ3 フルボイス Special + {0x8A731B0, {0, 1, 0, ULJM05428, 0, "NPJH50821"}}, + // 金色のコルダ3 AnotherSky feat.至誠館 + {0x8A99BD8, {0, 1, 0, ULJM05428, 0, "NPJH50846"}}, + // 金色のコルダ3 AnotherSky feat.天音学園 + {0x8AAB770, {0, 1, 0, ULJM05428, 0, "NPJH50847"}}, // 金色のコルダ3 - {0x896C3B8, {0, 0, 0, ULJM05428, 0, "ULJM05624"}}, + {0x896C3B8, {0, 1, 0, ULJM05428, 0, "ULJM05624"}}, // 金色のコルダ2 f - {0x89b59dc, {0, 0, 0, ULJM05428, 0, "ULJM05428"}}, + {0x89b59dc, {0, 1, 0, ULJM05428, 0, "ULJM05428"}}, // 金色のコルダ2 f アンコール - {0x89D9FB0, {0, 0, 0, ULJM05428, 0, "ULJM05508"}}, + {0x89D9FB0, {0, 1, 0, ULJM05428, 0, "ULJM05508"}}, // 金色のコルダ - {0x886162c, {0, 0, 0, ULJM05428, 0, "ULJM05054"}}, // dialogue: 0x886162c (x1), 0x889d5fc-0x889d520(a2) fullLine + {0x886162c, {0, 1, 0, ULJM05428, 0, "ULJM05054"}}, // dialogue: 0x886162c (x1), 0x889d5fc-0x889d520(a2) fullLine {0x8899e90, {0, 0, 0x3c, 0, 0, "ULJM05054"}}, // name 0x88da57c, 0x8899ca4 (x0, oneTime), 0x8899e90 // Sol Trigger {0x8952cfc, {CODEC_UTF8, 0, 0, 0, NPJH50619F, "NPJH50619"}}, // dialog diff --git a/cpp/LunaHook/LunaHook/hookfinder.cc b/cpp/LunaHook/LunaHook/hookfinder.cc index 2bc42375..f2b4ab49 100644 --- a/cpp/LunaHook/LunaHook/hookfinder.cc +++ b/cpp/LunaHook/LunaHook/hookfinder.cc @@ -174,7 +174,7 @@ void DoSend(int i, uintptr_t address, char *str, intptr_t padding, JITTYPE jitty if (n == sp.maxRecords) { spDefault.maxRecords = sp.maxRecords * 2; - ConsoleOutput(OUT_OF_RECORDS_RETRY); + ConsoleOutput(TR[OUT_OF_RECORDS_RETRY]); } } } @@ -281,7 +281,7 @@ void mergevector(std::vector &v1, std::vector &v2) } void SearchForHooks_Return() { - ConsoleOutput(HOOK_SEARCH_FINISHED, sp.maxRecords - recordsAvailable); + ConsoleOutput(TR[HOOK_SEARCH_FINISHED], sp.maxRecords - recordsAvailable); for (int i = 0, results = 0; i < sp.maxRecords; ++i) { HookParam hp; @@ -306,7 +306,7 @@ void SearchForHooks_Return() } NotifyHookFound(hp, (wchar_t *)records[i].text); if (++results % 100'000 == 0) - ConsoleOutput(ResultsNum, results); + ConsoleOutput(TR[ResultsNum], results); } records.reset(); for (int i = 0; i < CACHE_SIZE; ++i) @@ -321,7 +321,7 @@ void initrecords() } catch (std::bad_alloc) { - ConsoleOutput(SearchForHooks_ERROR, sp.maxRecords /= 2); + ConsoleOutput(TR[SearchForHooks_ERROR], sp.maxRecords /= 2); } while (!records && sp.maxRecords); } @@ -332,7 +332,7 @@ void SearchForHooks(SearchParam spUser) static std::mutex m; std::scoped_lock lock(m); *(void**)(trampoline + send_offset) = Send; - ConsoleOutput(HOOK_SEARCH_INITIALIZING, 0.); + ConsoleOutput(TR[HOOK_SEARCH_INITIALIZING], 0.); sp = spUser.length == 0 ? spDefault : spUser; sp.codepage=spUser.codepage; @@ -441,7 +441,7 @@ void SearchForHooks(SearchParam spUser) memcpy(trampolines[i], trampoline, sizeof(trampoline)); *(uintptr_t*)(trampolines[i] + addr_offset) = addresses[i]; *(void**)(trampolines[i] + original_offset) = original; - if (i % 2500 == 0) ConsoleOutput(HOOK_SEARCH_INITIALIZING, 1 + 98. * i / addresses.size()); + if (i % 2500 == 0) ConsoleOutput(TR[HOOK_SEARCH_INITIALIZING], 1 + 98. * i / addresses.size()); } //避免MH_RemoveHook时移除原本已有hook for(int i=0;isuccessaddr; uintptr_t minemaddr=-1,maxemaddr=0; - ConsoleOutput(HOOK_SEARCH_INITIALIZED, jitaddr2emuaddr.size()); + ConsoleOutput(TR[HOOK_SEARCH_INITIALIZED], jitaddr2emuaddr.size()); for(auto addr:jitaddr2emuaddr){ minemaddr=min(minemaddr,addr.second.second); @@ -490,10 +490,10 @@ void SearchForHooks(SearchParam spUser) //addresses.push_back(addr.first); if(add_veh_hook((void*)addr.first,std::bind(SendJitVeh,std::placeholders::_1,addr.first,addr.second.second,addr.second.first,sp.padding))) successaddr.push_back(addr.first); - if (i % 2500 == 0) ConsoleOutput(HOOK_SEARCH_INITIALIZING, 1 + 98. * i / jitaddr2emuaddr.size()); + if (i % 2500 == 0) ConsoleOutput(TR[HOOK_SEARCH_INITIALIZING], 1 + 98. * i / jitaddr2emuaddr.size()); } - ConsoleOutput(HOOK_SEARCH_INITIALIZED, i); - ConsoleOutput(MAKE_GAME_PROCESS_TEXT, sp.searchTime / 1000); + ConsoleOutput(TR[HOOK_SEARCH_INITIALIZED], i); + ConsoleOutput(TR[MAKE_GAME_PROCESS_TEXT], sp.searchTime / 1000); Sleep(sp.searchTime); // for(auto addr:successaddr){ // remove_veh_hook((void*)addr); @@ -514,8 +514,8 @@ void SearchForText(wchar_t *text, UINT codepage) WideCharToMultiByte(codepage, 0, text, PATTERN_SIZE, codepageText, PATTERN_SIZE * 4, nullptr, nullptr); if (strlen(utf8Text) < 4 || ((codepage != CP_UTF8) && (strlen(codepageText) < 4)) || wcslen(text) < 4) - return ConsoleOutput(NOT_ENOUGH_TEXT); - ConsoleOutput(HOOK_SEARCH_STARTING); + return ConsoleOutput(TR[NOT_ENOUGH_TEXT]); + ConsoleOutput(TR[HOOK_SEARCH_STARTING]); auto GenerateHooks = [&](std::vector addresses, HookParamType type) { for (auto addr : addresses) @@ -535,5 +535,5 @@ void SearchForText(wchar_t *text, UINT codepage) GenerateHooks(Util::SearchMemory(codepageText, strlen(codepageText), PAGE_READWRITE), USING_STRING); GenerateHooks(Util::SearchMemory(text, wcslen(text) * sizeof(wchar_t), PAGE_READWRITE), CODEC_UTF16); if (!found) - ConsoleOutput(COULD_NOT_FIND); + ConsoleOutput(TR[COULD_NOT_FIND]); } diff --git a/cpp/LunaHook/LunaHook/main.cc b/cpp/LunaHook/LunaHook/main.cc index 6f85967e..5a65191a 100644 --- a/cpp/LunaHook/LunaHook/main.cc +++ b/cpp/LunaHook/LunaHook/main.cc @@ -39,7 +39,8 @@ DWORD WINAPI Pipe(LPVOID) WriteFile(hookPipe, buffer, sizeof(DWORD), &count, nullptr); WriteFile(hookPipe, LUNA_VERSION, sizeof(LUNA_VERSION), &count, nullptr); - ConsoleOutput(PIPE_CONNECTED); + ReadFile(hostPipe, &curr_lang, sizeof(SUPPORT_LANG), &count, nullptr); + ConsoleOutput(TR[PIPE_CONNECTED]); HIJACK(); host_connected = true; while (running && ReadFile(hostPipe, buffer, PIPE_BUFFER_SIZE, &count, nullptr)) @@ -61,6 +62,12 @@ DWORD WINAPI Pipe(LPVOID) PcHooks::hookOtherPcFunctions(); } break; + case HOST_COMMAND_SET_LANGUAGE: + { + auto info = *(SetLanguageCmd *)buffer; + curr_lang = info.lang; + } + break; case HOST_COMMAND_REMOVE_HOOK: { auto info = *(RemoveHookCmd *)buffer; @@ -152,7 +159,7 @@ void NotifyHookFound(HookParam hp, wchar_t *text) void NotifyHookRemove(uint64_t addr, LPCSTR name) { if (name) - ConsoleOutput(REMOVING_HOOK, name); + ConsoleOutput(TR[REMOVING_HOOK], name); HookRemovedNotif buffer(addr); WriteFile(hookPipe, &buffer, sizeof(buffer), DUMMY, nullptr); } @@ -232,7 +239,7 @@ bool NewHook_1(HookParam &hp, LPCSTR lpname) if (++currentHook >= MAX_HOOK) { - ConsoleOutput(TOO_MANY_HOOKS); + ConsoleOutput(TR[TOO_MANY_HOOKS]); return false; } if (lpname && *lpname) @@ -241,7 +248,7 @@ bool NewHook_1(HookParam &hp, LPCSTR lpname) wcscpy_s(hp.hookcode, HOOKCODE_LEN, HookCode::Generate(hp, GetCurrentProcessId()).c_str()); if (!(*hooks)[currentHook].Insert(hp)) { - ConsoleOutput(InsertHookFailed, WideStringToString(hp.hookcode).c_str()); + ConsoleOutput(TR[InsertHookFailed], WideStringToString(hp.hookcode).c_str()); (*hooks)[currentHook].Clear(); return false; } @@ -254,7 +261,7 @@ bool NewHook_1(HookParam &hp, LPCSTR lpname) void delayinsertadd(HookParam hp, std::string name) { delayinserthook->insert(std::make_pair(hp.emu_addr, std::make_pair(name, hp))); - ConsoleOutput(INSERTING_HOOK, name.c_str(), hp.emu_addr); + ConsoleOutput(TR[INSERTING_HOOK], name.c_str(), hp.emu_addr); } void delayinsertNewHook(uint64_t em_address) { diff --git a/cpp/LunaHook/LunaHook/pchhook.h b/cpp/LunaHook/LunaHook/pchhook.h index e4a48924..74e79409 100644 --- a/cpp/LunaHook/LunaHook/pchhook.h +++ b/cpp/LunaHook/LunaHook/pchhook.h @@ -18,7 +18,6 @@ #include "embed_util.h" #include "hijackfuns.h" -#include "Lang/Lang.h" #include "veh_hook.h" #include "engines/emujitarg.hpp" #include "engines/mono/monoil2cpp.h" diff --git a/cpp/LunaHook/LunaHook/texthook.cc b/cpp/LunaHook/LunaHook/texthook.cc index e7078851..a6cf4c80 100644 --- a/cpp/LunaHook/LunaHook/texthook.cc +++ b/cpp/LunaHook/LunaHook/texthook.cc @@ -106,14 +106,14 @@ uintptr_t getasbaddr(const HookParam &hp) if (function) address += (uint64_t)function; else - return ConsoleOutput(FUNC_MISSING), 0; + return ConsoleOutput(TR[FUNC_MISSING]), 0; } else { if (HMODULE moduleBase = GetModuleHandleW(hp.module)) address += (uint64_t)moduleBase; else - return ConsoleOutput(MODULE_MISSING), 0; + return ConsoleOutput(TR[MODULE_MISSING]), 0; } } return address; @@ -126,7 +126,7 @@ bool TextHook::Insert(HookParam hp) return false; RemoveHook(addr, 0); - ConsoleOutput(INSERTING_HOOK, hp.name, addr); + ConsoleOutput(TR[INSERTING_HOOK], hp.name, addr); local_buffer = new BYTE[PIPE_BUFFER_SIZE]; { std::scoped_lock lock(viewMutex); @@ -330,7 +330,7 @@ void TextHook::Send(hook_context *context) __leave; if (buff.size > TEXT_BUFFER_SIZE) { - ConsoleOutput(InvalidLength, buff.size, hp.name); + ConsoleOutput(TR[InvalidLength], buff.size, hp.name); buff.size = TEXT_BUFFER_SIZE; } if (hp.type & USING_CHAR || (!hp.text_fun && !(hp.type & USING_STRING))) @@ -436,7 +436,7 @@ void TextHook::Send(hook_context *context) if (!err && !(hp.type & KNOWN_UNSTABLE)) { err = true; - ConsoleOutput(SEND_ERROR, hp.name); + ConsoleOutput(TR[SEND_ERROR], hp.name); } } @@ -519,7 +519,7 @@ void TextHook::Read() } __except (EXCEPTION_EXECUTE_HANDLER) { - ConsoleOutput(READ_ERROR, hp.name); + ConsoleOutput(TR[READ_ERROR], hp.name); Clear(); } } diff --git a/cpp/LunaHook/LunaHost/CMakeLists.txt b/cpp/LunaHook/LunaHost/CMakeLists.txt index 7d5626c1..aa4351dc 100644 --- a/cpp/LunaHook/LunaHost/CMakeLists.txt +++ b/cpp/LunaHook/LunaHost/CMakeLists.txt @@ -21,13 +21,13 @@ target_link_libraries(host VERSION_DEF) add_library(LunaHostDll MODULE LunaHostDll.cpp ${versioninfohost}) target_precompile_headers(LunaHostDll REUSE_FROM pch) set_target_properties(LunaHostDll PROPERTIES OUTPUT_NAME "LunaHost${bitappendix}") -target_link_libraries(LunaHostDll pch host ${YY_Thunks_for_WinXP}) +target_link_libraries(LunaHostDll pch host ${YY_Thunks_for_WinXP} lang_host) if(BUILD_CLI) add_executable(LunaHostCLI LunaHostCLI.cpp ${versioninfohost}) target_precompile_headers(LunaHostCLI REUSE_FROM pch) set_target_properties(LunaHostCLI PROPERTIES OUTPUT_NAME "LunaHostCLI${bitappendix}") -target_link_libraries(LunaHostCLI pch host ${YY_Thunks_for_WinXP}) +target_link_libraries(LunaHostCLI pch host ${YY_Thunks_for_WinXP} lang_host) endif() add_subdirectory(GUI) \ No newline at end of file diff --git a/cpp/LunaHook/LunaHost/GUI/CMakeLists.txt b/cpp/LunaHook/LunaHost/GUI/CMakeLists.txt index 2c6c5be8..0345c915 100644 --- a/cpp/LunaHook/LunaHost/GUI/CMakeLists.txt +++ b/cpp/LunaHook/LunaHost/GUI/CMakeLists.txt @@ -3,7 +3,7 @@ if(BUILD_GUI) add_executable(LunaHost WIN32 confighelper.cpp controls.cpp main.cpp processlistwindow.cpp LunaHost.cpp window.cpp ../../../exec/luna.rc pluginmanager.cpp Plugin/extensionimpl.cpp Plugin/copyclipboard.cpp QtLoader_inline.cpp app.manifest ${versioninfohost}) target_precompile_headers(LunaHost REUSE_FROM pch) set_target_properties(LunaHost PROPERTIES OUTPUT_NAME "LunaHost${bitappendix}") -target_link_libraries(LunaHost comctl32 winhttp pch host nlohmann ${YY_Thunks_for_WinXP}) +target_link_libraries(LunaHost comctl32 winhttp pch host nlohmann ${YY_Thunks_for_WinXP} lang_ui) endif() if(BUILD_PLUGIN) diff --git a/cpp/LunaHook/LunaHost/GUI/LunaHost.cpp b/cpp/LunaHook/LunaHost/GUI/LunaHost.cpp index f1464ad2..8f322d9d 100644 --- a/cpp/LunaHook/LunaHost/GUI/LunaHost.cpp +++ b/cpp/LunaHook/LunaHost/GUI/LunaHost.cpp @@ -7,9 +7,8 @@ #include "host.h" #include "textthread.h" #include "LunaHost.h" -#include "Lang/Lang.h" #include "http.hpp" - +extern std::vector>> lang_map; bool sendclipboarddata_i(const std::wstring &text, HWND hwnd) { if (!OpenClipboard((HWND)hwnd)) @@ -64,13 +63,28 @@ void LunaHost::savesettings() configs->set("fontsize", uifont.fontsize); configs->set("font_italic", uifont.italic); configs->set("font_bold", uifont.bold); + configs->set("Language", map_from_support_lang(curr_lang)); +} + +std::string getdefaultlang() +{ + LANGID langid = GetUserDefaultUILanguage(); + CHAR szLang[100]; + std::string lang; + GetLocaleInfoA(MAKELCID(langid, SORT_DEFAULT), LOCALE_SISO639LANGNAME, szLang, 100); + lang += szLang; + GetLocaleInfoA(MAKELCID(langid, SORT_DEFAULT), LOCALE_SISO3166CTRYNAME, szLang, 100); + lang += "-"; + lang += szLang; + return lang; } void LunaHost::loadsettings() { + curr_lang = map_to_support_lang(configs->get("Language", getdefaultlang()).c_str()); uifont.italic = configs->get("font_italic", false); uifont.bold = configs->get("font_bold", false); uifont.fontsize = configs->get("fontsize", 14); - uifont.fontfamily = StringToWideString(configs->get("DefaultFont2", WideStringToString(std::wstring(DefaultFont)))); + uifont.fontfamily = StringToWideString(configs->get("DefaultFont2", WideStringToString(TR[DefaultFont]))); check_toclipboard_selection = configs->get("ToClipboardSelection", false); check_toclipboard = configs->get("ToClipboard", false); autoattach = configs->get("AutoAttach", false); @@ -146,12 +160,12 @@ LunaHost::LunaHost() loadsettings(); setfont(uifont); - btnshowsettionwindow = new button(this, BtnShowSettingWindow); - g_selectprocessbutton = new button(this, BtnSelectProcess); + btnshowsettionwindow = new button(this, TR[TSetting]); + g_selectprocessbutton = new button(this, TR[WndSelectProcess]); // btnsavehook=new button(this,BtnSaveHook,10,10,10,10); // btnsavehook->onclick=std::bind(&LunaHost::btnsavehookscallback,this); - btndetachall = new button(this, BtnDetach); + btndetachall = new button(this, TR[BtnDetach]); btndetachall->onclick = [&]() { for (auto pid : attachedprocess) @@ -162,7 +176,7 @@ LunaHost::LunaHost() }; g_hEdit_userhook = new lineedit(this); - btnplugin = new button(this, BtnPlugin); + btnplugin = new button(this, TR[TPlugins]); plugins = new Pluginmanager(this); btnplugin->onclick = [&]() @@ -171,7 +185,7 @@ LunaHost::LunaHost() pluginwindow = new Pluginwindow(this, plugins); pluginwindow->show(); }; - g_hButton_insert = new button(this, BtnInsertUserHook); + g_hButton_insert = new button(this, TR[BtnInsertUserHook]); btnshowsettionwindow->onclick = [&]() { if (settingwindow == 0) @@ -196,12 +210,12 @@ LunaHost::LunaHost() } else { - showtext(NotifyInvalidHookCode, false); + showtext(TR[NotifyInvalidHookCode], false); } }; g_hListBox_listtext = new listview(this, false, false); - g_hListBox_listtext->setheader({LIST_HOOK, LIST_TEXT}); + g_hListBox_listtext->setheader({TR[LIST_HOOK], TR[HS_TEXT]}); g_hListBox_listtext->oncurrentchange = [&](int idx) { auto thread_p = g_hListBox_listtext->getdata(idx); @@ -216,18 +230,18 @@ LunaHost::LunaHost() auto tt = (TextThread *)g_hListBox_listtext->getdata(g_hListBox_listtext->currentidx()); Menu menu; - menu.add(MenuCopyHookCode, [&, tt]() + menu.add(TR[MenuCopyHookCode], [&, tt]() { sendclipboarddata(tt->hp.hookcode, winId); }); menu.add_sep(); - menu.add(MenuRemoveHook, [&, tt]() + menu.add(TR[MenuRemoveHook], [&, tt]() { Host::RemoveHook(tt->tp.processId, tt->tp.addr); }); - menu.add(MenuDetachProcess, [&, tt]() + menu.add(TR[MenuDetachProcess], [&, tt]() { Host::DetachProcess(tt->tp.processId); userdetachedpids.insert(tt->tp.processId); }); menu.add_sep(); - menu.add(MenuRemeberSelect, [&, tt]() + menu.add(TR[MenuRemeberSelect], [&, tt]() { if(auto pexe=getModuleFilename(tt->tp.processId)) savedhookcontext[WideStringToString(pexe.value())]={ @@ -236,7 +250,7 @@ LunaHost::LunaHost() {"ctx2",tt->tp.ctx2}, {"name",WideStringToString(tt->name)} }; }); - menu.add(MenuForgetSelect, [&, tt]() + menu.add(TR[MenuForgetSelect], [&, tt]() { if(auto pexe=getModuleFilename(tt->tp.processId)) savedhookcontext.erase(WideStringToString(pexe.value())); }); @@ -246,14 +260,6 @@ LunaHost::LunaHost() g_showtexts = new multilineedit(this); g_showtexts->setreadonly(true); - btnsearchhooks = new button(this, BtnSearchHook); - btnsearchhooks->onclick = [&]() - { - if (hooksearchwindow == 0) - hooksearchwindow = new Hooksearchwindow(this); - hooksearchwindow->show(); - }; - Host::StartEx( std::bind(&LunaHost::on_proc_connect, this, std::placeholders::_1), std::bind(&LunaHost::on_proc_disconnect, this, std::placeholders::_1), @@ -271,9 +277,8 @@ LunaHost::LunaHost() mainlayout->addcontrol(btndetachall, 0, 1); mainlayout->addcontrol(btnshowsettionwindow, 0, 2); mainlayout->addcontrol(btnplugin, 0, 3); - mainlayout->addcontrol(g_hEdit_userhook, 1, 0, 1, 2); - mainlayout->addcontrol(g_hButton_insert, 1, 2); - mainlayout->addcontrol(btnsearchhooks, 1, 3); + mainlayout->addcontrol(g_hEdit_userhook, 1, 0, 1, 3); + mainlayout->addcontrol(g_hButton_insert, 1, 3); mainlayout->addcontrol(g_hListBox_listtext, 2, 0, 1, 4); mainlayout->addcontrol(g_showtexts, 3, 0, 1, 4); @@ -282,7 +287,7 @@ LunaHost::LunaHost() mainlayout->setfixedheigth(1, 30); setlayout(mainlayout); setcentral(1200, 800); - std::wstring title = WndLunaHostGui; + std::wstring title = TR[WndLunaHostGui]; settext(title); std::thread([&]() @@ -313,7 +318,7 @@ LunaHost::LunaHost() WCHAR vs[32]; - wsprintf(vs, L" | %s v%d.%d.%d", VersionCurrent, LUNA_VERSION[0], LUNA_VERSION[1], LUNA_VERSION[2]); + wsprintf(vs, L" | %s v%d.%d.%d", TR[VersionCurrent], LUNA_VERSION[0], LUNA_VERSION[1], LUNA_VERSION[2]); title += vs; settext(title); std::thread([&]() @@ -328,7 +333,7 @@ LunaHost::LunaHost() try{ auto resp=nlohmann::json::parse(WideStringToString(httpRequest.response)); std::string ver=resp["version"]; - settext(text()+L" | "+VersionLatest+L" "+ StringToWideString(ver)); + settext(text()+L" | "+TR[VersionLatest]+L" "+ StringToWideString(ver)); } catch(std::exception&e){} } }) @@ -417,7 +422,7 @@ void LunaHost::on_info(HOSTINFO type, const std::wstring &warning) switch (type) { case HOSTINFO::Warning: - MessageBoxW(winId, warning.c_str(), L"warning", 0); + MessageBoxW(winId, warning.c_str(), TR[T_WARNING], 0); break; } } @@ -481,14 +486,14 @@ Settingwindow::Settingwindow(LunaHost *host) : mainwindow(host) TextThread::maxHistorySize = v; }; - ckbfilterrepeat = new checkbox(this, LblFilterRepeat); + ckbfilterrepeat = new checkbox(this, TR[LblFilterRepeat]); ckbfilterrepeat->onclick = [=]() { TextThread::filterRepetition = ckbfilterrepeat->ischecked(); }; ckbfilterrepeat->setcheck(TextThread::filterRepetition); - g_check_clipboard = new checkbox(this, BtnToClipboard); + g_check_clipboard = new checkbox(this, TR[BtnToClipboard]); g_check_clipboard->onclick = [=]() { host->check_toclipboard = g_check_clipboard->ischecked(); @@ -501,21 +506,21 @@ Settingwindow::Settingwindow(LunaHost *host) : mainwindow(host) // }; // copyselect->setcheck(host->check_toclipboard_selection); - autoattach = new checkbox(this, LblAutoAttach); + autoattach = new checkbox(this, TR[LblAutoAttach]); autoattach->onclick = [=]() { host->autoattach = autoattach->ischecked(); }; autoattach->setcheck(host->autoattach); - autoattach_so = new checkbox(this, LblAutoAttach_savedonly); + autoattach_so = new checkbox(this, TR[LblAutoAttach_savedonly]); autoattach_so->onclick = [=]() { host->autoattach_savedonly = autoattach_so->ischecked(); }; autoattach_so->setcheck(host->autoattach_savedonly); - readonlycheck = new checkbox(this, BtnReadOnly); + readonlycheck = new checkbox(this, TR[BtnReadOnly]); readonlycheck->onclick = [=]() { host->g_showtexts->setreadonly(readonlycheck->ischecked()); @@ -539,7 +544,7 @@ Settingwindow::Settingwindow(LunaHost *host) : mainwindow(host) showfont = new lineedit(this); showfont->settext(host->uifont.fontfamily); showfont->setreadonly(true); - selectfont = new button(this, FONTSELECT); + selectfont = new button(this, TR[FONTSELECT]); selectfont->onclick = [=]() { FontSelector(winId, host->uifont, [=](const Font &f) @@ -548,31 +553,42 @@ Settingwindow::Settingwindow(LunaHost *host) : mainwindow(host) showfont->settext(f.fontfamily); host->setfont(f); }); }; - + language = new combobox(this); + for (auto &&[_, l, __] : lang_map) + { + language->additem(l); + } + language->setcurrent(curr_lang); + language->oncurrentchange = [](int idx) + { + curr_lang = (decltype(curr_lang))idx; + }; mainlayout = new gridlayout(); - mainlayout->addcontrol(new label(this, LblFlushDelay), 0, 0); - mainlayout->addcontrol(g_timeout, 0, 1); + mainlayout->addcontrol(new label(this, TR[LblLanguage]), 0, 0); + mainlayout->addcontrol(language, 0, 1); + mainlayout->addcontrol(new label(this, TR[LblFlushDelay]), 1, 0); + mainlayout->addcontrol(g_timeout, 1, 1); - mainlayout->addcontrol(new label(this, LblCodePage), 1, 0); - mainlayout->addcontrol(g_codepage, 1, 1); + mainlayout->addcontrol(new label(this, TR[LblCodePage]), 2, 0); + mainlayout->addcontrol(g_codepage, 2, 1); - mainlayout->addcontrol(new label(this, LblMaxBuff), 2, 0); - mainlayout->addcontrol(spinmaxbuffsize, 2, 1); + mainlayout->addcontrol(new label(this, TR[LblMaxBuff]), 3, 0); + mainlayout->addcontrol(spinmaxbuffsize, 3, 1); - mainlayout->addcontrol(new label(this, LblMaxHist), 3, 0); - mainlayout->addcontrol(spinmaxhistsize, 3, 1); + mainlayout->addcontrol(new label(this, TR[LblMaxHist]), 4, 0); + mainlayout->addcontrol(spinmaxhistsize, 4, 1); - mainlayout->addcontrol(ckbfilterrepeat, 4, 0, 1, 2); - mainlayout->addcontrol(g_check_clipboard, 5, 0, 1, 2); - mainlayout->addcontrol(autoattach, 6, 0, 1, 2); - mainlayout->addcontrol(autoattach_so, 7, 0, 1, 2); - mainlayout->addcontrol(readonlycheck, 8, 0, 1, 2); - mainlayout->addcontrol(showfont, 9, 1); - mainlayout->addcontrol(selectfont, 9, 0); + mainlayout->addcontrol(ckbfilterrepeat, 5, 0, 1, 2); + mainlayout->addcontrol(g_check_clipboard, 6, 0, 1, 2); + mainlayout->addcontrol(autoattach, 7, 0, 1, 2); + mainlayout->addcontrol(autoattach_so, 8, 0, 1, 2); + mainlayout->addcontrol(readonlycheck, 9, 0, 1, 2); + mainlayout->addcontrol(showfont, 10, 1); + mainlayout->addcontrol(selectfont, 10, 0); setlayout(mainlayout); setcentral(600, 500); - settext(WndSetting); + settext(TR[TSetting]); } void Pluginwindow::on_size(int w, int h) { @@ -611,7 +627,7 @@ Pluginwindow::Pluginwindow(mainwindow *p, Pluginmanager *pl) : mainwindow(p), pl listplugins->on_menu = [&]() { Menu menu; - menu.add(MenuAddPlugin, [&]() + menu.add(TR[MenuAddPlugin], [&]() { if(auto f=pluginmanager->selectpluginfile()) switch (auto res=pluginmanager->addplugin(f.value())) @@ -621,24 +637,24 @@ Pluginwindow::Pluginwindow(mainwindow *p, Pluginmanager *pl) : mainwindow(p), pl break; default: std::map errorlog={ - {addpluginresult::isnotaplugins,InvalidPlugin}, - {addpluginresult::invaliddll,InvalidDll}, - {addpluginresult::dumplicate,InvalidDump}, + {addpluginresult::isnotaplugins,TR[InvalidPlugin]}, + {addpluginresult::invaliddll,TR[InvalidDll]}, + {addpluginresult::dumplicate,TR[InvalidDump]}, }; - MessageBoxW(winId,errorlog[res],MsgError,0); + MessageBoxW(winId,errorlog[res],TR[MsgError],0); } }); auto idx = listplugins->currentidx(); if (idx != -1) { - menu.add(MenuRemovePlugin, [&, idx]() + menu.add(TR[MenuRemovePlugin], [&, idx]() { pluginmanager->remove((LPCWSTR)listplugins->getdata(idx)); listplugins->deleteitem(idx); }); menu.add_sep(); - menu.add(MenuPluginRankUp, std::bind(&Pluginwindow::pluginrankmove, this, -1)); - menu.add(MenuPluginRankDown, std::bind(&Pluginwindow::pluginrankmove, this, 1)); + menu.add(TR[MenuPluginRankUp], std::bind(&Pluginwindow::pluginrankmove, this, -1)); + menu.add(TR[MenuPluginRankDown], std::bind(&Pluginwindow::pluginrankmove, this, 1)); menu.add_sep(); - menu.add_checkable(MenuPluginEnable, pluginmanager->getenable(idx), [&, idx](bool check) + menu.add_checkable(TR[MenuPluginEnable], pluginmanager->getenable(idx), [&, idx](bool check) { pluginmanager->setenable(idx,check); if(check) @@ -646,7 +662,7 @@ Pluginwindow::Pluginwindow(mainwindow *p, Pluginmanager *pl) : mainwindow(p), pl else pluginmanager->unload((LPCWSTR)listplugins->getdata(idx)); }); if (pluginmanager->getvisible_setable(idx)) - menu.add_checkable(MenuPluginVisSetting, pluginmanager->getvisible(idx), [&, idx](bool check) + menu.add_checkable(TR[MenuPluginVisSetting], pluginmanager->getvisible(idx), [&, idx](bool check) { pluginmanager->setvisible(idx, check); }); } return menu; @@ -656,242 +672,6 @@ Pluginwindow::Pluginwindow(mainwindow *p, Pluginmanager *pl) : mainwindow(p), pl { listadd(pluginmanager->getname(i)); } - settext(WndPlugins); + settext(TR[TPlugins]); setcentral(500, 400); } - -void HooksearchText::call(std::set pids) -{ - edittext->settext(L""); - checkok->onclick = [&, pids]() - { - close(); - auto cp = codepage->getcurr(); - if (!IsValidCodePage(cp)) - return; - SearchParam sp = {}; - sp.codepage = cp; - wcsncpy_s(sp.text, edittext->text().c_str(), PATTERN_SIZE - 1); - for (auto pid : pids) - Host::FindHooks(pid, sp); - }; - show(); -} -HooksearchText::HooksearchText(mainwindow *p) : mainwindow(p) -{ - codepage = new spinbox(this, Host::defaultCodepage); - codepage->setminmax(0, CP_UTF8); - - edittext = new lineedit(this); - checkok = new button(this, BtnOk); - layout = new gridlayout(); - layout->addcontrol(new label(this, HS_TEXT), 0, 0); - layout->addcontrol(new label(this, HS_CODEPAGE), 1, 0); - layout->addcontrol(edittext, 0, 1); - layout->addcontrol(codepage, 1, 1); - layout->addcontrol(checkok, 2, 1); - - setlayout(layout); - setcentral(500, 200); -} -std::wstring tohex(BYTE *bs, int len) -{ - std::wstring buffer; - for (int i = 0; i < len; i += 1) - { - buffer.append(FormatString(L"%02hX ", bs[i])); - } - return buffer; -} -std::wstring addr2hex(uintptr_t addr) -{ - return FormatString(L"%p", addr); -} -void realcallsearchhooks(std::set pids, std::wstring filter, SearchParam sp) -{ - - auto hooks = std::make_shared>(); - - try - { - for (auto processId : pids) - Host::FindHooks(processId, sp, - [hooks, filter](HookParam hp, std::wstring text) - { - std::wsmatch matches; - if (std::regex_search(text, matches, std::wregex(filter))) - { - hooks->emplace_back(std::wstring(hp.hookcode) + L"=>" + text); - } - }); - } - catch (std::exception &e) - { - // std::wcout<size() == 0 || hooks->size() != lastSize; Sleep(2000)) lastSize = hooks->size(); - - std::ofstream of; - of.open("savehooks.txt"); - for (auto line:*hooks) of<clear(); }) - .detach(); -} -Hooksearchsetting::Hooksearchsetting(mainwindow *p) : mainwindow(p) -{ - layout = new gridlayout(); - SearchParam sp{}; - spinduration = new spinbox(this, sp.searchTime); - spinoffset = new spinbox(this, sp.offset); - spincap = new spinbox(this, sp.maxRecords); - spincodepage = new spinbox(this, Host::defaultCodepage); - editpattern = new lineedit(this); - editpattern->settext(tohex(sp.pattern, sp.length)); - editmodule = new lineedit(this); - editmaxaddr = new lineedit(this); - editmaxaddr->settext(addr2hex(sp.maxAddress)); - editminaddr = new lineedit(this); - editminaddr->settext(addr2hex(sp.minAddress)); - spinpadding = new spinbox(this, 0); - editregex = new lineedit(this); - start = new button(this, HS_START_HOOK_SEARCH); - layout->addcontrol(new label(this, HS_SEARCH_PATTERN), 0, 0); - layout->addcontrol(new label(this, HS_SEARCH_DURATION), 1, 0); - layout->addcontrol(new label(this, HS_PATTERN_OFFSET), 2, 0); - layout->addcontrol(new label(this, HS_MAX_HOOK_SEARCH_RECORDS), 3, 0); - layout->addcontrol(new label(this, HS_CODEPAGE), 4, 0); - layout->addcontrol(new label(this, HS_SEARCH_MODULE), 5, 0); - layout->addcontrol(new label(this, HS_MIN_ADDRESS), 6, 0); - layout->addcontrol(new label(this, HS_MAX_ADDRESS), 7, 0); - layout->addcontrol(new label(this, HS_STRING_OFFSET), 8, 0); - layout->addcontrol(new label(this, HS_HOOK_SEARCH_FILTER), 9, 0); - layout->addcontrol(start, 10, 1); - - layout->addcontrol(editpattern, 0, 1); - layout->addcontrol(spinduration, 1, 1); - layout->addcontrol(spinoffset, 2, 1); - layout->addcontrol(spincap, 3, 1); - layout->addcontrol(spincodepage, 4, 1); - layout->addcontrol(editmodule, 5, 1); - layout->addcontrol(editminaddr, 6, 1); - layout->addcontrol(editmaxaddr, 7, 1); - layout->addcontrol(spinpadding, 8, 1); - layout->addcontrol(editregex, 9, 1); - - setlayout(layout); - setcentral(1000, 600); -} -std::vector hexStringToBytes(const std::wstring &hexString_) -{ - auto hexString = hexString_; - strReplace(hexString, L" ", L""); - strReplace(hexString, L"??", FormatString(L"%02hX", XX)); - std::vector bytes; - if (hexString.length() % 2 != 0) - { - return {}; - } - for (int i = 0; i < hexString.size() / 2; i++) - { - auto byteValue = std::stoi(hexString.substr(i * 2, 2), nullptr, 16); - bytes.push_back(byteValue); - } - - return bytes; -} -void Hooksearchsetting::call(std::set pids, std::wstring reg) -{ - if (pids.empty()) - return; - - if (auto filename = getModuleFilename(*pids.begin())) - editmodule->settext(std::filesystem::path(filename.value()).filename().wstring()); - editregex->settext(reg); - spincodepage->setcurr(Host::defaultCodepage); - - start->onclick = [&, pids]() - { - close(); - SearchParam sp{}; - sp.searchTime = spinduration->getcurr(); - sp.offset = spinoffset->getcurr(); - sp.maxRecords = spincap->getcurr(); - sp.codepage = spincodepage->getcurr(); - - if (editpattern->text().find(L".") == std::wstring::npos) - { - auto hex = hexStringToBytes(editpattern->text()); - memcpy(sp.pattern, hex.data(), hex.size()); - sp.length = hex.size(); - } - else - { - wcsncpy_s(sp.exportModule, editpattern->text().c_str(), MAX_MODULE_SIZE - 1); - sp.length = 1; - } - - wcscpy(sp.boundaryModule, editmodule->text().c_str()); - sp.minAddress = std::stoull(editminaddr->text(), nullptr, 16); - sp.maxAddress = std::stoull(editmaxaddr->text(), nullptr, 16); - sp.padding = spinpadding->getcurr(); - realcallsearchhooks(pids, editregex->text(), sp); - }; - show(); -} -Hooksearchwindow::Hooksearchwindow(LunaHost *host) : mainwindow(host) -{ - - cjkcheck = new checkbox(this, SEARCH_CJK); - hs_default = new button(this, HS_START_HOOK_SEARCH); - hs_text = new button(this, HS_SEARCH_FOR_TEXT); - hs_user = new button(this, HS_SETTINGS); - - layout = new gridlayout(); - layout->addcontrol(cjkcheck, 0, 0, 1, 3); - layout->addcontrol(hs_default, 1, 0); - layout->addcontrol(hs_text, 1, 1); - layout->addcontrol(hs_user, 1, 2); - - setlayout(layout); - - settext(BtnSearchHook); - setcentral(800, 200); - - auto dohooksearchdispatch = [&, host](int type) - { - close(); - if (type == 1) - { - if (hooksearchText == 0) - hooksearchText = new HooksearchText(this); - hooksearchText->call(host->attachedprocess); - return; - } - - auto filter = (cjkcheck->ischecked() ? L"[\\u3000-\\ua000]{4,}" : L"[\\u0020-\\u1000]{4,}"); - - if (type == 0) - { - SearchParam sp = {}; - sp.codepage = Host::defaultCodepage; - sp.length = 0; - realcallsearchhooks(host->attachedprocess, filter, sp); - } - else if (type == 2) - { - if (hooksearchsetting == 0) - hooksearchsetting = new Hooksearchsetting(this); - hooksearchsetting->call(host->attachedprocess, filter); - return; - } - }; - - hs_default->onclick = std::bind(dohooksearchdispatch, 0); - hs_text->onclick = std::bind(dohooksearchdispatch, 1); - hs_user->onclick = std::bind(dohooksearchdispatch, 2); -} \ No newline at end of file diff --git a/cpp/LunaHook/LunaHost/GUI/LunaHost.h b/cpp/LunaHook/LunaHost/GUI/LunaHost.h index f4682aa8..b923639f 100644 --- a/cpp/LunaHook/LunaHost/GUI/LunaHost.h +++ b/cpp/LunaHook/LunaHost/GUI/LunaHost.h @@ -29,6 +29,7 @@ class Settingwindow : public mainwindow gridlayout *mainlayout; lineedit *showfont; button *selectfont; + combobox *language; public: Settingwindow(LunaHost *); @@ -78,17 +79,6 @@ class Hooksearchsetting : public mainwindow Hooksearchsetting(mainwindow *); void call(std::set pids, std::wstring); }; -class Hooksearchwindow : public mainwindow -{ - checkbox *cjkcheck; - button *hs_default, *hs_text, *hs_user; - gridlayout *layout; - Hooksearchsetting *hooksearchsetting = 0; - HooksearchText *hooksearchText = 0; - -public: - Hooksearchwindow(LunaHost *parent); -}; class LunaHost : public mainwindow { Pluginwindow *pluginwindow = 0; @@ -102,13 +92,11 @@ class LunaHost : public mainwindow multilineedit *g_showtexts; button *g_selectprocessbutton; button *btndetachall; - button *btnsearchhooks; button *btnshowsettionwindow; // button* btnsavehook; processlistwindow *_processlistwindow = 0; Settingwindow *settingwindow = 0; Pluginmanager *plugins; - Hooksearchwindow *hooksearchwindow = 0; std::atomic hasstoped = false; bool on_text_recv(TextThread &thread, std::wstring &sentence); void on_text_recv_checkissaved(TextThread &thread); @@ -135,7 +123,6 @@ class LunaHost : public mainwindow void on_close(); LunaHost(); friend class Settingwindow; - friend class Hooksearchwindow; private: void loadsettings(); diff --git a/cpp/LunaHook/LunaHost/GUI/controls.cpp b/cpp/LunaHook/LunaHost/GUI/controls.cpp index 8d654584..25cebe4e 100644 --- a/cpp/LunaHook/LunaHost/GUI/controls.cpp +++ b/cpp/LunaHook/LunaHost/GUI/controls.cpp @@ -37,6 +37,36 @@ void checkbox::setcheck(bool b) { SendMessage(winId, BM_SETCHECK, (WPARAM)BST_CHECKED * b, 0); } +combobox::combobox(mainwindow *parent) : control(parent) +{ + winId = CreateWindowEx(0, L"COMBOBOX", NULL, WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST, + 0, 0, 0, 0, parent->winId, NULL, NULL, NULL); +} +int combobox::additem(const std::wstring &text) +{ + return SendMessage(winId, CB_ADDSTRING, 0, (LPARAM)text.c_str()); +} +int combobox::currentidx() +{ + return SendMessage(winId, CB_GETCURSEL, 0, 0); +} +void combobox::setcurrent(int idx) +{ + SendMessage(winId, CB_SETCURSEL, idx, 0); + if (idx != -1) + oncurrentchange(idx); +} + +void combobox::dispatch(WPARAM wparam) +{ + if (HIWORD(wparam) == CBN_SELCHANGE) + { + auto idx = currentidx(); + if (idx != -1) + oncurrentchange(idx); + } +} + int spinbox::getcurr() { return SendMessage(hUpDown, UDM_GETPOS32, 0, 0); diff --git a/cpp/LunaHook/LunaHost/GUI/controls.h b/cpp/LunaHook/LunaHost/GUI/controls.h index 4784467a..4d0f12f5 100644 --- a/cpp/LunaHook/LunaHost/GUI/controls.h +++ b/cpp/LunaHook/LunaHost/GUI/controls.h @@ -90,6 +90,16 @@ class label : public control label(mainwindow *, const std::wstring &); }; +class combobox : public control +{ +public: + combobox(mainwindow *); + int additem(const std::wstring &); + int currentidx(); + void dispatch(WPARAM); + void setcurrent(int idx); + std::function oncurrentchange = [](int) {}; +}; class listbox : public control { public: diff --git a/cpp/LunaHook/LunaHost/GUI/pluginmanager.cpp b/cpp/LunaHook/LunaHost/GUI/pluginmanager.cpp index 2c181baf..ef6100f8 100644 --- a/cpp/LunaHook/LunaHost/GUI/pluginmanager.cpp +++ b/cpp/LunaHook/LunaHost/GUI/pluginmanager.cpp @@ -4,7 +4,6 @@ #include #include #include "LunaHost.h" -#include "Lang/Lang.h" #include "host.h" std::optional SelectFile(HWND hwnd, LPCWSTR lpstrFilter) diff --git a/cpp/LunaHook/LunaHost/GUI/processlistwindow.cpp b/cpp/LunaHook/LunaHost/GUI/processlistwindow.cpp index 865c372a..b5eed948 100644 --- a/cpp/LunaHook/LunaHost/GUI/processlistwindow.cpp +++ b/cpp/LunaHook/LunaHost/GUI/processlistwindow.cpp @@ -3,7 +3,6 @@ #include #include "host.h" #include "LunaHost.h" -#include "Lang/Lang.h" #include std::unordered_map> getprocesslist() { @@ -62,8 +61,8 @@ void processlistwindow::PopulateProcessList(listview *_listbox, std::unordered_m processlistwindow::processlistwindow(mainwindow *p) : mainwindow(p) { g_hEdit = new lineedit(this); - g_hButton = new button(this, BtnAttach); - g_refreshbutton = new button(this, BtnRefresh); + g_hButton = new button(this, TR[BtnAttach]); + g_refreshbutton = new button(this, TR[BtnRefresh]); g_hButton->onclick = [&]() { auto str = g_hEdit->text(); @@ -108,7 +107,7 @@ processlistwindow::processlistwindow(mainwindow *p) : mainwindow(p) } g_hEdit->settext(_); }; - settext(WndSelectProcess); + settext(TR[WndSelectProcess]); mainlayout = new gridlayout(); mainlayout->addcontrol(g_hEdit, 0, 0, 1, 2); mainlayout->addcontrol(g_hButton, 0, 2); diff --git a/cpp/LunaHook/LunaHost/GUI/window.cpp b/cpp/LunaHook/LunaHost/GUI/window.cpp index 842c5ec7..aa6695bd 100644 --- a/cpp/LunaHook/LunaHost/GUI/window.cpp +++ b/cpp/LunaHook/LunaHost/GUI/window.cpp @@ -1,6 +1,5 @@ #include "window.h" #include "controls.h" -#include "Lang/Lang.h" #include HICON GetExeIcon(const std::wstring &filePath) { diff --git a/cpp/LunaHook/LunaHost/LunaHostDll.cpp b/cpp/LunaHook/LunaHost/LunaHostDll.cpp index 3865625b..e70642cc 100644 --- a/cpp/LunaHook/LunaHost/LunaHostDll.cpp +++ b/cpp/LunaHook/LunaHost/LunaHostDll.cpp @@ -30,6 +30,7 @@ std::optional checkoption(bool check, T &&t) return std::move(t); return {}; } + C_LUNA_API void Luna_Start(ProcessEvent Connect, ProcessEvent Disconnect, ThreadEvent_maybe_embed Create, ThreadEvent Destroy, OutputCallback Output, HostInfoHandler hostinfo, HookInsertHandler hookinsert, EmbedCallback embed) { Host::StartEx( @@ -70,7 +71,10 @@ C_LUNA_API void Luna_Settings(int flushDelay, bool filterRepetition, int default TextThread::maxBufferSize = maxBufferSize; TextThread::maxHistorySize = maxHistorySize; } - +C_LUNA_API void Luna_SetLanguage(const char* lang) +{ + Host::SetLanguage(lang); +} C_LUNA_API void Luna_InsertPCHooks(DWORD pid, int which) { Host::InsertPCHooks(pid, which); diff --git a/cpp/LunaHook/LunaHost/host.cpp b/cpp/LunaHook/LunaHost/host.cpp index 0adbf559..966f975b 100644 --- a/cpp/LunaHook/LunaHost/host.cpp +++ b/cpp/LunaHook/LunaHost/host.cpp @@ -1,7 +1,6 @@ #include "host.h" typedef LONG NTSTATUS; #include "yapi.hpp" -#include "Lang/Lang.h" #define SEARCH_SJIS_UNSAFE 0 namespace { @@ -89,25 +88,24 @@ namespace hostPipe = CreateNamedPipeW((std::wstring(HOST_PIPE) + std::to_wstring(pid)).c_str(), PIPE_ACCESS_OUTBOUND, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, PIPE_UNLIMITED_INSTANCES, PIPE_BUFFER_SIZE, 0, MAXDWORD, &allAccess); HANDLE pipeAvailableEvent = CreateEventW(&allAccess, FALSE, FALSE, (std::wstring(PIPE_AVAILABLE_EVENT) + std::to_wstring(pid)).c_str()); - Host::AddConsoleOutput((std::wstring(PIPE_AVAILABLE_EVENT) + std::to_wstring(pid))); SetEvent(pipeAvailableEvent); std::thread([hookPipe, hostPipe, pipeAvailableEvent] { ConnectNamedPipe(hookPipe, nullptr); CloseHandle(pipeAvailableEvent); + WORD hookversion[4]; BYTE buffer[PIPE_BUFFER_SIZE] = {}; DWORD bytesRead, processId; ReadFile(hookPipe, &processId, sizeof(processId), &bytesRead, nullptr); + ReadFile(hookPipe, hookversion, sizeof(hookversion), &bytesRead, nullptr); + if(memcmp(hookversion,LUNA_VERSION,sizeof(hookversion))!=0) + Host::InfoOutput(HOSTINFO::Warning, TR[UNMATCHABLEVERSION]); + processRecordsByIds->try_emplace(processId, processId, hostPipe); OnConnect(processId); - Host::AddConsoleOutput(FormatString(PROC_CONN,processId)); - //CreatePipe(); - WORD hookversion[4]; - if( ReadFile(hookPipe, hookversion, sizeof(hookversion), &bytesRead, nullptr)){ - if(memcmp(hookversion,LUNA_VERSION,sizeof(hookversion))!=0) - Host::InfoOutput(HOSTINFO::Warning, UNMATCHABLEVERSION); - } - + processRecordsByIds->at(processId).Send(curr_lang); + Host::AddConsoleOutput(FormatString(TR[PROC_CONN],processId)); + while (ReadFile(hookPipe, buffer, PIPE_BUFFER_SIZE, &bytesRead, nullptr)) switch (*(HostNotificationType*)buffer) { @@ -201,7 +199,7 @@ namespace RemoveThreads([&](ThreadParam tp) { return tp.processId == processId; }); OnDisconnect(processId); - Host::AddConsoleOutput(FormatString(PROC_DISCONN,processId)); + Host::AddConsoleOutput(FormatString(TR[PROC_DISCONN],processId)); processRecordsByIds->erase(processId); }) .detach(); } @@ -212,6 +210,16 @@ namespace Host std::mutex threadmutex; std::mutex outputmutex; std::mutex procmutex; + + void SetLanguage(const char *lang) + { + curr_lang = map_to_support_lang(lang); + auto &prs = processRecordsByIds.Acquire().contents; + for (auto &&[_, record] : prs) + { + record.Send(SetLanguageCmd(curr_lang)); + } + } void Start(ProcessEventHandler Connect, ProcessEventHandler Disconnect, ThreadEventHandler Create, ThreadEventHandler Destroy, TextThread::OutputCallback Output, bool createconsole) { OnConnect = [=](auto &&...args) @@ -227,11 +235,10 @@ namespace Host if (createconsole) { - OnCreate(textThreadsByParams->try_emplace(console, console, HookParam{}, CONSOLE).first->second); + OnCreate(textThreadsByParams->try_emplace(console, console, HookParam{}, TR[CONSOLE]).first->second); consolethread = &textThreadsByParams->at(console); - Host::AddConsoleOutput(ProjectHomePage); + Host::AddConsoleOutput(TR[ProjectHomePage]); } - // CreatePipe(); } void StartEx(std::optional Connect, @@ -281,7 +288,7 @@ namespace Host } else if (GetLastError() == ERROR_ACCESS_DENIED) { - AddConsoleOutput(NEED_64_BIT); // https://stackoverflow.com/questions/16091141/createremotethread-access-denied + AddConsoleOutput(TR[NEED_64_BIT]); // https://stackoverflow.com/questions/16091141/createremotethread-access-denied succ = false; } VirtualFreeEx(process, remoteData, 0, MEM_RELEASE); @@ -309,7 +316,7 @@ namespace Host WinMutex(ITH_HOOKMAN_MUTEX_ + std::to_wstring(processId)); if (GetLastError() == ERROR_ALREADY_EXISTS) { - AddConsoleOutput(ALREADY_INJECTED); + AddConsoleOutput(TR[ALREADY_INJECTED]); return false; } return true; @@ -322,7 +329,6 @@ namespace Host bool proc64 = Is64BitProcess(process); auto dllname = proc64 ? LUNA_HOOK_DLL_64 : LUNA_HOOK_DLL_32; std::wstring location = locationX.size() ? (locationX + L"\\" + dllname) : std::filesystem::path(getModuleFilename().value()).replace_filename(dllname); - AddConsoleOutput(location); if (proc64 == x64) { return (SafeInject(process, location)); @@ -348,7 +354,7 @@ namespace Host std::thread([=] { if(InjectDll(processId,locationX))return ; - AddConsoleOutput(INJECT_FAILED); }) + AddConsoleOutput(TR[INJECT_FAILED]); }) .detach(); } @@ -359,7 +365,6 @@ namespace Host return; prs.at(processId).Send(HOST_COMMAND_DETACH); } - void InsertPCHooks(DWORD processId, int which) { auto &prs = processRecordsByIds.Acquire().contents; @@ -426,7 +431,7 @@ namespace Host switch (type) { case HOSTINFO::Warning: - text = L"[Warning] " + text; + text = FormatString(L"[%s]", TR[T_WARNING]) + text; break; case HOSTINFO::EmuGameName: text = L"[Game] " + text; diff --git a/cpp/LunaHook/LunaHost/host.h b/cpp/LunaHook/LunaHost/host.h index 4a83f77d..60a274ec 100644 --- a/cpp/LunaHook/LunaHost/host.h +++ b/cpp/LunaHook/LunaHost/host.h @@ -17,6 +17,7 @@ namespace Host void DetachProcess(DWORD processId); void InsertHook(DWORD processId, HookParam hp); + void SetLanguage(const char*); void InsertPCHooks(DWORD processId, int which); void RemoveHook(DWORD processId, uint64_t address); void FindHooks(DWORD processId, SearchParam sp, HookEventHandler HookFound = {}); diff --git a/cpp/LunaHook/LunaHost/textthread.cpp b/cpp/LunaHook/LunaHost/textthread.cpp index bb203979..d77c3b46 100644 --- a/cpp/LunaHook/LunaHost/textthread.cpp +++ b/cpp/LunaHook/LunaHost/textthread.cpp @@ -1,6 +1,5 @@ #include "textthread.h" #include "host.h" -#include "Lang/Lang.h" // return true if repetition found (see https://github.com/Artikash/Textractor/issues/40) static bool RemoveRepetition(std::wstring &text) @@ -66,7 +65,7 @@ void TextThread::Push(BYTE *data, int length) buffer.push_back(L'\n'); } else - Host::AddConsoleOutput(INVALID_CODEPAGE); + Host::AddConsoleOutput(TR[INVALID_CODEPAGE]); UpdateFlushTime(); diff --git a/cpp/LunaHook/include/const.h b/cpp/LunaHook/include/const.h index 9dc8ebd6..b71b0aa2 100644 --- a/cpp/LunaHook/include/const.h +++ b/cpp/LunaHook/include/const.h @@ -26,6 +26,7 @@ enum HostCommandType HOST_COMMAND_HIJACK_PROCESS, HOST_COMMAND_DETACH, HOST_COMMAND_INSERT_PC_HOOKS, + HOST_COMMAND_SET_LANGUAGE, }; enum HostNotificationType @@ -35,7 +36,6 @@ enum HostNotificationType HOST_NOTIFICATION_FOUND_HOOK, HOST_NOTIFICATION_RMVHOOK, HOST_NOTIFICATION_INSERTING_HOOK, - HOST_SETTEXTTHREADTYPE, }; enum class HOSTINFO { diff --git a/cpp/LunaHook/include/pch.h b/cpp/LunaHook/include/pch.h index 9fe72d8d..5f81b9ba 100644 --- a/cpp/LunaHook/include/pch.h +++ b/cpp/LunaHook/include/pch.h @@ -42,4 +42,5 @@ #include "types.h" #include "hookcode.h" #include "winevent.hpp" -#include "lrucache.hpp" \ No newline at end of file +#include "lrucache.hpp" +#include "Lang/Lang.h" \ No newline at end of file diff --git a/cpp/LunaHook/include/types.h b/cpp/LunaHook/include/types.h index b8ed0bd3..e00ea248 100644 --- a/cpp/LunaHook/include/types.h +++ b/cpp/LunaHook/include/types.h @@ -258,33 +258,27 @@ struct SearchParam wchar_t text[PATTERN_SIZE] = {}; // text to search for bool isjithook; }; -struct InsertPCHooksCmd -{ - InsertPCHooksCmd(int _which) : which(_which) {} - HostCommandType command = HOST_COMMAND_INSERT_PC_HOOKS; - int which; -}; -struct InsertHookCmd // From host -{ - InsertHookCmd(HookParam hp) : hp(hp) {} - HostCommandType command = HOST_COMMAND_NEW_HOOK; - HookParam hp; -}; -struct RemoveHookCmd // From host -{ - RemoveHookCmd(uint64_t address) : address(address) {} - HostCommandType command = HOST_COMMAND_REMOVE_HOOK; - uint64_t address; -}; +enum SUPPORT_LANG; -struct FindHookCmd // From host -{ - FindHookCmd(SearchParam sp) : sp(sp) {} - HostCommandType command = HOST_COMMAND_FIND_HOOK; - SearchParam sp; -}; +#define DECLARE_SIMPLE_CMD(structname, type, var, CMD) \ + struct structname \ + { \ + structname(type _) : var(_) {} \ + decltype(CMD) command = CMD; \ + type var; \ + }; + +// host->hook +DECLARE_SIMPLE_CMD(SetLanguageCmd, SUPPORT_LANG, lang, HOST_COMMAND_SET_LANGUAGE) +DECLARE_SIMPLE_CMD(InsertPCHooksCmd, int, which, HOST_COMMAND_INSERT_PC_HOOKS) +DECLARE_SIMPLE_CMD(InsertHookCmd, HookParam, hp, HOST_COMMAND_NEW_HOOK) +DECLARE_SIMPLE_CMD(RemoveHookCmd, uint64_t, address, HOST_COMMAND_REMOVE_HOOK) +DECLARE_SIMPLE_CMD(FindHookCmd, SearchParam, sp, HOST_COMMAND_FIND_HOOK) + +// hook->host +DECLARE_SIMPLE_CMD(HookRemovedNotif, uint64_t, address, HOST_NOTIFICATION_RMVHOOK) -struct HostInfoNotif // From dll +struct HostInfoNotif { HostInfoNotif(std::string message = "") { strncpy_s(this->message, message.c_str(), MESSAGE_SIZE - 1); } HostNotificationType command = HOST_NOTIFICATION_TEXT; @@ -292,7 +286,7 @@ struct HostInfoNotif // From dll char message[MESSAGE_SIZE] = {}; }; -struct HookFoundNotif // From dll +struct HookFoundNotif { HookFoundNotif(HookParam hp, wchar_t *text) : hp(hp) { wcsncpy_s(this->text, text, MESSAGE_SIZE - 1); } HostNotificationType command = HOST_NOTIFICATION_FOUND_HOOK; @@ -300,14 +294,7 @@ struct HookFoundNotif // From dll wchar_t text[MESSAGE_SIZE] = {}; // though type is wchar_t, may not be encoded in UTF-16 (it's just convenient to use wcs* functions) }; -struct HookRemovedNotif // From dll -{ - HookRemovedNotif(uint64_t address) : address(address) {}; - HostNotificationType command = HOST_NOTIFICATION_RMVHOOK; - uint64_t address; -}; - -struct HookInsertingNotif // From dll +struct HookInsertingNotif { HookInsertingNotif(uint64_t addr1) : addr(addr1) {} HostNotificationType command = HOST_NOTIFICATION_INSERTING_HOOK; diff --git a/cpp/LunaHook/scripts/builden.bat b/cpp/LunaHook/scripts/build.bat similarity index 100% rename from cpp/LunaHook/scripts/builden.bat rename to cpp/LunaHook/scripts/build.bat diff --git a/cpp/LunaHook/scripts/build32xp_local.bat b/cpp/LunaHook/scripts/build32xp_local.bat index d41757d9..bc89b907 100644 --- a/cpp/LunaHook/scripts/build32xp_local.bat +++ b/cpp/LunaHook/scripts/build32xp_local.bat @@ -1,3 +1,2 @@ cmake -DBUILD_PLUGIN=OFF -DBUILD_GUI=ON -DBUILD_CLI=ON -DWINXP=1 ../CMakeLists.txt -G "Visual Studio 17 2022" -A win32 -T host=x86 -B ../build/x86_xp -@REM cmake -DBUILD_PLUGIN=OFF -DWINXP=1 -DLANGUAGE=Chinese ../CMakeLists.txt -G "Visual Studio 17 2022" -A win32 -T host=x86 -B ../build/x86_zh_xp call dobuildxp.bat \ No newline at end of file diff --git a/cpp/LunaHook/scripts/buildcore.bat b/cpp/LunaHook/scripts/buildcore.bat index 51cb15b2..4b1f2198 100644 --- a/cpp/LunaHook/scripts/buildcore.bat +++ b/cpp/LunaHook/scripts/buildcore.bat @@ -3,4 +3,4 @@ cmake --build ..\build\x86 --config Release --target ALL_BUILD -j 14 cmake ..\CMakeLists.txt -G "Visual Studio 17 2022" -A x64 -T host=x64 -B ..\build\x64 cmake --build ..\build\x64 --config Release --target ALL_BUILD -j 14 -robocopy ..\builds\Release_English ..\..\..\py\files\plugins\LunaHook \ No newline at end of file +robocopy ..\builds\Release ..\..\..\py\files\plugins\LunaHook \ No newline at end of file diff --git a/cpp/LunaHook/scripts/dobuildxp.bat b/cpp/LunaHook/scripts/dobuildxp.bat index 2e8d46d9..220b5975 100644 --- a/cpp/LunaHook/scripts/dobuildxp.bat +++ b/cpp/LunaHook/scripts/dobuildxp.bat @@ -60,5 +60,4 @@ goto :main ) call :activate_msvc "%target_arch%" || goto :eof msbuild ..\build\x86_xp\LunaHook.sln -p:Configuration=Release - msbuild ..\build\x86_zh_xp\LunaHook.sln -p:Configuration=Release goto :eof diff --git a/cpp/LunaHook/scripts/edit_target.py b/cpp/LunaHook/scripts/edit_target.py index 51ddc733..bda73705 100644 --- a/cpp/LunaHook/scripts/edit_target.py +++ b/cpp/LunaHook/scripts/edit_target.py @@ -1,6 +1,6 @@ import os #妈的,不知道为什么我重装系统后,装了vs2017 cmake也识别不到,只能手动改了。 -for f in ['../build/x86_zh_xp','../build/x86_xp']: +for f in ['../build/x86_xp']: for dirname,_,fs in os.walk(f): for ff in fs: if ff.endswith('.vcxproj')==False:continue diff --git a/cpp/version.cmake b/cpp/version.cmake index e2f47f09..53fa3674 100644 --- a/cpp/version.cmake +++ b/cpp/version.cmake @@ -1,7 +1,7 @@ set(VERSION_MAJOR 6) -set(VERSION_MINOR 11) -set(VERSION_PATCH 10) +set(VERSION_MINOR 12) +set(VERSION_PATCH 0) set(VERSION_REVISION 0) set(LUNA_VERSION "{${VERSION_MAJOR},${VERSION_MINOR},${VERSION_PATCH},${VERSION_REVISION}}") add_library(VERSION_DEF ${CMAKE_CURRENT_LIST_DIR}/version_def.cpp) diff --git a/py/LunaTranslator/gui/setting_about.py b/py/LunaTranslator/gui/setting_about.py index f4f84c97..319a158c 100644 --- a/py/LunaTranslator/gui/setting_about.py +++ b/py/LunaTranslator/gui/setting_about.py @@ -379,7 +379,10 @@ def setTab_about(self, basel): def changeUIlanguage(_): languageChangeEvent = QEvent(QEvent.Type.LanguageChange) QApplication.sendEvent(QApplication.instance(), languageChangeEvent) - + try: + gobject.baseobject.textsource.setlang() + except: + pass def setTab_update(self, basel): version = winsharedutils.queryversion(getcurrexe()) diff --git a/py/LunaTranslator/myutils/config.py b/py/LunaTranslator/myutils/config.py index 731034ab..aabf9119 100644 --- a/py/LunaTranslator/myutils/config.py +++ b/py/LunaTranslator/myutils/config.py @@ -561,11 +561,11 @@ def syncconfig(config1, default, drop=False, deep=0, skipdict=False): ] -def getlanguse(): +def getlanguse() -> str: return globalconfig["languageuse2"] -def langfile(lang): +def langfile(lang) -> str: return "./files/lang/{}.json".format(lang) @@ -582,7 +582,7 @@ def loadlanguage(): languageshow = {} -def _TR(k: str): +def _TR(k: str) -> str: if not k: return "" if "_" in k: diff --git a/py/LunaTranslator/textsource/texthook.py b/py/LunaTranslator/textsource/texthook.py index 4945fb93..03758f3a 100644 --- a/py/LunaTranslator/textsource/texthook.py +++ b/py/LunaTranslator/textsource/texthook.py @@ -8,6 +8,7 @@ savehook_new_data, static_data, findgameuidofpath, + getlanguse, ) from textsource.textsourcebase import basetext from myutils.utils import ( @@ -219,6 +220,8 @@ def initdll(self): self.Luna_RemoveHook.argtypes = DWORD, c_uint64 self.Luna_Detach = LunaHost.Luna_Detach self.Luna_Detach.argtypes = (DWORD,) + self.Luna_SetLanguage = LunaHost.Luna_SetLanguage + self.Luna_SetLanguage.argtypes = (c_char_p,) self.Luna_FindHooks = LunaHost.Luna_FindHooks self.Luna_FindHooks.argtypes = ( DWORD, @@ -258,6 +261,8 @@ def initdll(self): self.keepref += procs ptrs = [cast(_, c_void_p).value for _ in procs] self.Luna_Start(*ptrs) + self.setsettings() + self.setlang() def listprocessm(self): cachefname = gobject.gettempdir("{}.txt".format(time.time())) @@ -351,7 +356,6 @@ def start(self, hwnd, pids, gamepath, gameuid, autostart=False): except: pass self.startsql(sqlitef) - self.setsettings() if autostart: autostarthookcode = savehook_new_data[gameuid]["hook"] needinserthookcode = savehook_new_data[gameuid]["needinserthookcode"] @@ -570,6 +574,9 @@ def onnewhook(self, hc, hn, tp, isembedable): ) return True + def setlang(self): + self.Luna_SetLanguage(getlanguse().encode()) + def setsettings(self): self.Luna_Settings( self.config["textthreaddelay"], @@ -639,11 +646,7 @@ def inserthook(self, hookcode): for pid in self.pids.copy(): succ = self.Luna_InsertHookCode(pid, hookcode) and succ if succ == False: - getQMessageBox( - gobject.baseobject.hookselectdialog, - "Error", - "Invalie Hook Code Format!", - ) + getQMessageBox(gobject.baseobject.hookselectdialog, "错误", "特殊码无效") @threader def delaycollectallselectedoutput(self): diff --git a/py/files/lang/ar.json b/py/files/lang/ar.json index ae10b5c8..aa450fc7 100644 --- a/py/files/lang/ar.json +++ b/py/files/lang/ar.json @@ -754,5 +754,6 @@ "更新记录": "تحديث السجلات", "打开选择文本窗口": "فتح نافذة اختيار النص", "成功": "النجاح .", - "Win32通用钩子": "win32 هوك العالمي" + "Win32通用钩子": "win32 هوك العالمي", + "特殊码无效": "رمز خاص غير صالح" } \ No newline at end of file diff --git a/py/files/lang/cht.json b/py/files/lang/cht.json index 7576791a..79b943ea 100644 --- a/py/files/lang/cht.json +++ b/py/files/lang/cht.json @@ -754,5 +754,6 @@ "更新记录": "更新記錄", "打开选择文本窗口": "打開選擇文字視窗", "成功": "成功", - "Win32通用钩子": "Win32通用鉤子" + "Win32通用钩子": "Win32通用鉤子", + "特殊码无效": "特殊碼無效" } \ No newline at end of file diff --git a/py/files/lang/cs.json b/py/files/lang/cs.json index 93d0d8e7..bdfc0e6a 100644 --- a/py/files/lang/cs.json +++ b/py/files/lang/cs.json @@ -754,5 +754,6 @@ "更新记录": "Aktualizovat záznam", "打开选择文本窗口": "Otevřít textové okno výběru", "成功": "úspěch", - "Win32通用钩子": "Univerzální hák Win32" + "Win32通用钩子": "Univerzální hák Win32", + "特殊码无效": "Speciální kód je neplatný" } \ No newline at end of file diff --git a/py/files/lang/de.json b/py/files/lang/de.json index a80c2957..7dc30c41 100644 --- a/py/files/lang/de.json +++ b/py/files/lang/de.json @@ -754,5 +754,6 @@ "更新记录": "Datensatz aktualisieren", "打开选择文本窗口": "Öffnen des Auswahltextfensters", "成功": "Erfolg", - "Win32通用钩子": "Win32 Universal Hook" + "Win32通用钩子": "Win32 Universal Hook", + "特殊码无效": "Der spezielle Code ist ungültig" } \ No newline at end of file diff --git a/py/files/lang/en.json b/py/files/lang/en.json index 02b7ce66..7a5160c3 100644 --- a/py/files/lang/en.json +++ b/py/files/lang/en.json @@ -754,5 +754,6 @@ "更新记录": "Update Record", "打开选择文本窗口": "Open the selection text window", "成功": "success", - "Win32通用钩子": "Win32 Universal Hook" + "Win32通用钩子": "Win32 Universal Hook", + "特殊码无效": "The special code is invalid" } \ No newline at end of file diff --git a/py/files/lang/es.json b/py/files/lang/es.json index 20d3cc10..11fee3d5 100644 --- a/py/files/lang/es.json +++ b/py/files/lang/es.json @@ -754,5 +754,6 @@ "更新记录": "Actualización de registros", "打开选择文本窗口": "Abrir la ventana de texto de selección", "成功": "éxito", - "Win32通用钩子": "Gancho universal Win32" + "Win32通用钩子": "Gancho universal Win32", + "特殊码无效": "El código especial no es válido" } \ No newline at end of file diff --git a/py/files/lang/fr.json b/py/files/lang/fr.json index 4b344cba..07e54073 100644 --- a/py/files/lang/fr.json +++ b/py/files/lang/fr.json @@ -754,5 +754,6 @@ "更新记录": "Mettre à jour les enregistrements", "打开选择文本窗口": "Ouvrir la fenêtre sélectionner le texte", "成功": "Succès", - "Win32通用钩子": "Win32 crochet universel" + "Win32通用钩子": "Win32 crochet universel", + "特殊码无效": "Code spécial invalide" } \ No newline at end of file diff --git a/py/files/lang/it.json b/py/files/lang/it.json index a0709c54..201e88ab 100644 --- a/py/files/lang/it.json +++ b/py/files/lang/it.json @@ -754,5 +754,6 @@ "更新记录": "Aggiorna record", "打开选择文本窗口": "Apri la finestra del testo di selezione", "成功": "successo", - "Win32通用钩子": "Win32 Universal Hook" + "Win32通用钩子": "Win32 Universal Hook", + "特殊码无效": "Il codice speciale non è valido" } \ No newline at end of file diff --git a/py/files/lang/ja.json b/py/files/lang/ja.json index 975d5e45..ac24b913 100644 --- a/py/files/lang/ja.json +++ b/py/files/lang/ja.json @@ -754,5 +754,6 @@ "更新记录": "レコードの更新", "打开选择文本窗口": "テキストの選択ウィンドウを開く", "成功": "成功", - "Win32通用钩子": "Win 32汎用フック" + "Win32通用钩子": "Win 32汎用フック", + "特殊码无效": "特殊コードが無効です" } \ No newline at end of file diff --git a/py/files/lang/ko.json b/py/files/lang/ko.json index 5459fea9..32f33fa3 100644 --- a/py/files/lang/ko.json +++ b/py/files/lang/ko.json @@ -754,5 +754,6 @@ "更新记录": "레코드 업데이트", "打开选择文本窗口": "텍스트 선택 창 열기", "成功": "성공", - "Win32通用钩子": "Win32 범용 갈고리" + "Win32通用钩子": "Win32 범용 갈고리", + "特殊码无效": "잘못된 특수 코드" } \ No newline at end of file diff --git a/py/files/lang/nl.json b/py/files/lang/nl.json index 55da03d9..23196361 100644 --- a/py/files/lang/nl.json +++ b/py/files/lang/nl.json @@ -754,5 +754,6 @@ "更新记录": "Record bijwerken", "打开选择文本窗口": "Het selectietekstvenster openen", "成功": "succes", - "Win32通用钩子": "Win32 universele haak" + "Win32通用钩子": "Win32 universele haak", + "特殊码无效": "De speciale code is ongeldig" } \ No newline at end of file diff --git a/py/files/lang/pl.json b/py/files/lang/pl.json index 572db4df..14ae4e4e 100644 --- a/py/files/lang/pl.json +++ b/py/files/lang/pl.json @@ -754,5 +754,6 @@ "更新记录": "Aktualizuj rekord", "打开选择文本窗口": "Otwórz okno tekstowe zaznaczenia", "成功": "sukces", - "Win32通用钩子": "Uniwersalny hak Win32" + "Win32通用钩子": "Uniwersalny hak Win32", + "特殊码无效": "Kod specjalny jest nieprawidłowy" } \ No newline at end of file diff --git a/py/files/lang/pt.json b/py/files/lang/pt.json index 73bd2daf..d85e71e3 100644 --- a/py/files/lang/pt.json +++ b/py/files/lang/pt.json @@ -754,5 +754,6 @@ "更新记录": "Actualizar o Registo", "打开选择文本窗口": "Abrir a janela de texto da selecção", "成功": "sucesso", - "Win32通用钩子": "Gancho Universal Win32" + "Win32通用钩子": "Gancho Universal Win32", + "特殊码无效": "O código especial é inválido" } \ No newline at end of file diff --git a/py/files/lang/ru.json b/py/files/lang/ru.json index f033c147..7c2366b5 100644 --- a/py/files/lang/ru.json +++ b/py/files/lang/ru.json @@ -754,5 +754,6 @@ "更新记录": "Обновить запись", "打开选择文本窗口": "Открыть окно выбора текста", "成功": "Успех", - "Win32通用钩子": "Win32 Универсальный крюк" + "Win32通用钩子": "Win32 Универсальный крюк", + "特殊码无效": "Специальный код не работает." } \ No newline at end of file diff --git a/py/files/lang/sv.json b/py/files/lang/sv.json index de99b6d5..f785ab29 100644 --- a/py/files/lang/sv.json +++ b/py/files/lang/sv.json @@ -754,5 +754,6 @@ "更新记录": "Uppdatera post", "打开选择文本窗口": "Öppna markeringstextfönstret", "成功": "framgång", - "Win32通用钩子": "Win32 universalkrok" + "Win32通用钩子": "Win32 universalkrok", + "特殊码无效": "Specialkoden är ogiltig" } \ No newline at end of file diff --git a/py/files/lang/th.json b/py/files/lang/th.json index b5f334d9..59e1f70e 100644 --- a/py/files/lang/th.json +++ b/py/files/lang/th.json @@ -754,5 +754,6 @@ "更新记录": "บันทึกการปรับปรุง", "打开选择文本窗口": "เปิดหน้าต่างเลือกข้อความ", "成功": "ความสำเร็จ", - "Win32通用钩子": "ตะขอสากล Win32" + "Win32通用钩子": "ตะขอสากล Win32", + "特殊码无效": "รหัสพิเศษไม่ถูกต้อง" } \ No newline at end of file diff --git a/py/files/lang/tr.json b/py/files/lang/tr.json index da2eb659..14873ef4 100644 --- a/py/files/lang/tr.json +++ b/py/files/lang/tr.json @@ -754,5 +754,6 @@ "更新记录": "Kayıt Güncelle", "打开选择文本窗口": "Seçim metin penceresini aç", "成功": "başarılı", - "Win32通用钩子": "Win32 Universal Hook" + "Win32通用钩子": "Win32 Universal Hook", + "特殊码无效": "Özel kodu geçersiz." } \ No newline at end of file diff --git a/py/files/lang/uk.json b/py/files/lang/uk.json index c6442887..1ddc57f7 100644 --- a/py/files/lang/uk.json +++ b/py/files/lang/uk.json @@ -754,5 +754,6 @@ "更新记录": "Оновити запис", "打开选择文本窗口": "Відкрити текстове вікно вибору", "成功": "успіх", - "Win32通用钩子": "Win32 Universal Hook" + "Win32通用钩子": "Win32 Universal Hook", + "特殊码无效": "Некоректний особливий код" } \ No newline at end of file diff --git a/py/files/lang/vi.json b/py/files/lang/vi.json index a5302455..8214841c 100644 --- a/py/files/lang/vi.json +++ b/py/files/lang/vi.json @@ -754,5 +754,6 @@ "更新记录": "Cập nhật hồ sơ", "打开选择文本窗口": "Mở cửa sổ Select Text", "成功": "Thành công", - "Win32通用钩子": "Win32 phổ Hook" + "Win32通用钩子": "Win32 phổ Hook", + "特殊码无效": "Mã đặc biệt không hợp lệ" } \ No newline at end of file diff --git a/py/files/lang/zh.json b/py/files/lang/zh.json index 73db625b..69710a44 100644 --- a/py/files/lang/zh.json +++ b/py/files/lang/zh.json @@ -754,5 +754,6 @@ "更新记录": "", "打开选择文本窗口": "", "成功": "", - "Win32通用钩子": "" + "Win32通用钩子": "", + "特殊码无效": "" } \ No newline at end of file