diff --git a/.github/workflows/buildit.yaml b/.github/workflows/buildit.yaml index e477e99b..63f22fbd 100644 --- a/.github/workflows/buildit.yaml +++ b/.github/workflows/buildit.yaml @@ -16,6 +16,11 @@ jobs: run: | curl --output C:/qt5.7z -L "https://github.com/LoL-Fantome/lolcustomskin-tools/releases/download/release23/qt5.15.5-x86_64-msvc-static.7z" 7z x -oC:/ C:/qt5.7z + - name: "Download patcher" + shell: bash + run: | + curl --output cslol-patcher.zip -L "https://github.com/LeagueToolkit/cslol-patcher/releases/latest/download/cslol-patcher.zip" + 7z x -o./cslol-tools/ cslol-patcher.zip - name: "Build" run: | mkdir build diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index f036ee06..3f867181 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -18,6 +18,11 @@ jobs: run: | curl --output C:/qt5.7z -L "https://github.com/LoL-Fantome/lolcustomskin-tools/releases/download/release23/qt5.15.5-x86_64-msvc-static.7z" 7z x -oC:/ C:/qt5.7z + - name: "Download patcher" + shell: bash + run: | + curl --output cslol-patcher.zip -L "https://github.com/LeagueToolkit/cslol-patcher/releases/latest/download/cslol-patcher.zip" + 7z x -o./cslol-tools/ cslol-patcher.zip - name: "Build" run: | mkdir build diff --git a/cslol-tools/CMakeLists.txt b/cslol-tools/CMakeLists.txt index b3ba16df..eeb72cb4 100644 --- a/cslol-tools/CMakeLists.txt +++ b/cslol-tools/CMakeLists.txt @@ -95,3 +95,20 @@ add_executable(wad-make src/main_wad_make.cpp ) target_link_libraries(wad-make PRIVATE cslol-lib) + +if (WIN32) + if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/cslol-patcher") + add_library(cslol-patcher SHARED IMPORTED) + set_target_properties(cslol-patcher PROPERTIES + IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/cslol-patcher/cslol-dll.lib + IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/cslol-patcher/cslol-dll.dll + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/cslol-patcher/ + ) + target_link_libraries(cslol-lib PUBLIC cslol-patcher) + add_custom_command(TARGET mod-tools POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy -t $ $ + COMMAND_EXPAND_LISTS + ) + endif() +endif() + diff --git a/cslol-tools/lib/lol/patcher/patcher_win32.cpp b/cslol-tools/lib/lol/patcher/patcher_win32.cpp index 5a25fe1e..68c4de93 100644 --- a/cslol-tools/lib/lol/patcher/patcher_win32.cpp +++ b/cslol-tools/lib/lol/patcher/patcher_win32.cpp @@ -312,13 +312,23 @@ static auto skinhack_detected() -> char const* { lol_throw_msg("NEW PATCH DETECTED, THIS IS NOT AN ERROR!\n"); } +static auto new_patcher(std::function update, + fs::path const& profile_path, + fs::path const& config_path, + fs::path const& game_path, + fs::names const& opts) -> bool; + auto patcher::run(std::function update, fs::path const& profile_path, fs::path const& config_path, fs::path const& game_path, fs::names const& opts) -> void { - lol_throw_if(skinhack_detected()); + for (auto const& o : opts) { + if (o == "dllpatcher") { + if (new_patcher(std::move(update), profile_path, config_path, game_path, opts)) return; + } + } auto ctx = Context{}; ctx.set_prefix(profile_path); ctx.kernel32 = Kernel32::load(); @@ -392,4 +402,62 @@ auto patcher::run(std::function update, } } +# if !__has_include("cslol-api.h") +static auto new_patcher(std::function update, + fs::path const& profile_path, + fs::path const& config_path, + fs::path const& game_path, + fs::names const& opts) -> bool { + return false; +} +# else +# include "cslol-api.h" +static auto new_patcher(std::function update, + fs::path const& profile_path, + fs::path const& config_path, + fs::path const& game_path, + fs::names const& opts) -> bool { + // Initialize first proces. + lol_throw_if(cslol_init()); + lol_throw_if(cslol_set_flags(CSLOL_HOOK_DISALBE_NONE)); + lol_throw_if(cslol_set_log_level(CSLOL_LOG_INFO)); + lol_throw_if(cslol_set_config(profile_path.generic_u16string().c_str())); + + for (;;) { + auto tid = run_until_or( + 30s, + Intervals{10ms}, + [&] { + update(M_WAIT_START, ""); + return cslol_find(); + }, + []() -> std::uint32_t { return 0; }); + if (!tid) { + continue; + } + + // Signal that process has been found. + update(M_FOUND, ""); + + // Hook in 30 seconds or error. + lol_throw_if(cslol_hook(tid, 30000, 100)); + + // Wait for exit. + update(M_WAIT_EXIT, ""); + run_until_or( + 3h, + Intervals{5s, 10s, 15s}, + [&, tid] { + char const* msg = NULL; + while ((msg = cslol_log_pull())) { + // post log message + update(M_WAIT_EXIT, msg); + } + if (!msg) update(M_WAIT_EXIT, ""); + return tid != cslol_find(); + }, + []() -> bool { throw PatcherTimeout(std::string("Timed out exit")); }); + } +} +# endif #endif diff --git a/cslol-tools/src/main_mod_tools.cpp b/cslol-tools/src/main_mod_tools.cpp index 690ff686..d012cdd4 100644 --- a/cslol-tools/src/main_mod_tools.cpp +++ b/cslol-tools/src/main_mod_tools.cpp @@ -275,6 +275,13 @@ static auto mod_runoverlay(fs::path overlay, fs::path config_file, fs::path game *lock = false; } } + if (msg == patcher::M_WAIT_EXIT) { + if (arg && *arg) { + fprintf(stdout, "patcher: %s\n", arg); + fflush(stdout); + old_msg = patcher::M_COUNT_OF; + } + } }, overlay, config_file, diff --git a/make-release.sh b/make-release.sh index 2e4c6301..2638beed 100755 --- a/make-release.sh +++ b/make-release.sh @@ -10,6 +10,7 @@ copy2folder() { cp "./LICENSE" "$2" cp "$1/cslol-tools/"*.exe "$2/cslol-tools" + cp "$1/cslol-tools/"*.dll "$2/cslol-tools" cp "$1/cslol-manager.exe" "$2" echo "windeployqt is only necessary for non-static builds" windeployqt --qmldir "src/qml" "$2/cslol-manager.exe" diff --git a/src/CSLOLTools.h b/src/CSLOLTools.h index 303a70ed..fa6adf17 100644 --- a/src/CSLOLTools.h +++ b/src/CSLOLTools.h @@ -54,7 +54,7 @@ class CSLOLTools : public QObject { void deleteMod(QString name); void exportMod(QString name, QString dest); void installFantomeZip(QString path); - void saveProfile(QString name, QJsonObject mods, bool run, bool skipConflict); + void saveProfile(QString name, QJsonObject mods, bool run, bool skipConflict, bool experimentalDll); void loadProfile(QString name); void deleteProfile(QString name); void stopProfile(); diff --git a/src/CSLOLToolsImpl.cpp b/src/CSLOLToolsImpl.cpp index 8cc59c32..a40d50c0 100644 --- a/src/CSLOLToolsImpl.cpp +++ b/src/CSLOLToolsImpl.cpp @@ -510,7 +510,7 @@ void CSLOLToolsImpl::doUpdate(QString urls) { } } -void CSLOLToolsImpl::saveProfile(QString name, QJsonObject mods, bool run, bool skipConflict) { +void CSLOLToolsImpl::saveProfile(QString name, QJsonObject mods, bool run, bool skipConflict, bool experimentalDll) { if (state_ == CSLOLState::StateIdle) { setState(CSLOLState::StateBusy); @@ -541,7 +541,7 @@ void CSLOLToolsImpl::saveProfile(QString name, QJsonObject mods, bool run, bool prog_ + "/profiles/" + name, prog_ + "/profiles/" + name + ".config", "--game:" + game_, - "--opts:" + QString("none"), + "--opts:" + QString(experimentalDll ? "dllpatcher" : "none"), }); } else { setState(CSLOLState::StateIdle); diff --git a/src/CSLOLToolsImpl.h b/src/CSLOLToolsImpl.h index 1c7f52b0..43dd9fab 100644 --- a/src/CSLOLToolsImpl.h +++ b/src/CSLOLToolsImpl.h @@ -60,7 +60,7 @@ public slots: void deleteMod(QString name); void exportMod(QString name, QString dest); void installFantomeZip(QString path); - void saveProfile(QString name, QJsonObject mods, bool run, bool skipConflict); + void saveProfile(QString name, QJsonObject mods, bool run, bool skipConflict, bool experimentalDll); void loadProfile(QString name); void deleteProfile(QString name); void stopProfile(); diff --git a/src/qml/CSLOLDialogSettings.qml b/src/qml/CSLOLDialogSettings.qml index 4bbbb690..02f65248 100644 --- a/src/qml/CSLOLDialogSettings.qml +++ b/src/qml/CSLOLDialogSettings.qml @@ -30,6 +30,7 @@ Dialog { property alias enableSystray: enableSystrayCheck.checked property alias enableAutoRun: enableAutoRunCheck.checked property alias updateUrls: updateUrlsTextArea.text + property alias experimentalDll: experimentalDllCheck.checked property var colors_LIST: [ "Red", @@ -115,6 +116,12 @@ Dialog { checked: false Layout.fillWidth: true } + Switch { + id: experimentalDllCheck + text: qsTr("Experimental dll patcher(might result in bans)") + checked: false + Layout.fillWidth: true + } } ColumnLayout { diff --git a/src/qml/main.qml b/src/qml/main.qml index bedfc100..b7ccdea4 100644 --- a/src/qml/main.qml +++ b/src/qml/main.qml @@ -31,6 +31,7 @@ ApplicationWindow { property alias themeDarkMode: cslolDialogSettings.themeDarkMode property alias themePrimaryColor: cslolDialogSettings.themePrimaryColor property alias themeAccentColor: cslolDialogSettings.themeAccentColor + property alias experimentalDll: cslolDialogSettings.experimentalDll property alias removeUnknownNames: cslolDialogEditMod.removeUnknownNames property alias lastZipDirectory: cslolDialogOpenZipFantome.folder @@ -97,7 +98,7 @@ ApplicationWindow { let name = cslolToolBar.profilesCurrentName let mods = cslolModsView.saveProfile() if (checkGamePath()) { - cslolTools.saveProfile(name, mods, run, settings.suppressInstallConflicts) + cslolTools.saveProfile(name, mods, run, settings.suppressInstallConflicts, settings.experimentalDll) } }