fix(loader): packageDist NO-SOURCE on clean + relax Minecraft filter
build.gradle
- Rewrite packageDist: drop the Copy task type and use a plain
task with `copy { from src; into ... }` inside doLast. The
Copy task snapshots its source set at configuration time, so
a first `./gradlew clean dll` saw the source path before
buildNative produced OpenZenLoader.exe and ended the task as
NO-SOURCE. Doing the copy in doLast defers source resolution
to after buildNative, which is when the EXE actually exists.
- Bail with a clear GradleException if the EXE is still missing
after buildNative instead of silently leaving build/dist
empty, and log the packaged size on success.
native/loader/src/MainWindow.cpp
- Loosen the in-game window filter to: title startsWith
"Minecraft" OR window class equals "GLFW30" (case-insensitive).
GLFW30 is the LWJGL3 window class Minecraft uses before the
title is set, so this catches the early-startup window too.
Drop the "Launcher" blacklist - launchers are no longer
matched by either branch.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+18
-3
@@ -387,13 +387,28 @@ tasks.register('buildNative', Exec) {
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register('packageDist', Copy) {
|
||||
tasks.register('packageDist') {
|
||||
group = 'openzen'
|
||||
description = 'Collect the Loader EXE into build/dist for distribution. ' +
|
||||
'OpenZen.dll is embedded inside the EXE, so we only ship one file.'
|
||||
dependsOn 'buildNative'
|
||||
from "$nativeBuildDir/loader/Release/OpenZenLoader.exe"
|
||||
into "$buildDir/dist"
|
||||
// Use an inline copy { } block inside doLast rather than the Copy task
|
||||
// type. Copy snapshots its source set at configuration time and reports
|
||||
// NO-SOURCE on a first clean build because the EXE that buildNative is
|
||||
// about to produce does not exist yet. doLast runs after buildNative,
|
||||
// by which point the file is definitely on disk.
|
||||
doLast {
|
||||
def src = file("$nativeBuildDir/loader/Release/OpenZenLoader.exe")
|
||||
if (!src.isFile()) {
|
||||
throw new GradleException(
|
||||
"Expected OpenZenLoader.exe at ${src} after buildNative; missing")
|
||||
}
|
||||
copy {
|
||||
from src
|
||||
into "$buildDir/dist"
|
||||
}
|
||||
logger.lifecycle("Packaged ${src.length()} bytes -> ${buildDir}/dist/${src.name}")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register('dll') {
|
||||
|
||||
@@ -21,12 +21,19 @@ QString fromW(const std::wstring& w) {
|
||||
return QString::fromWCharArray(w.c_str(), static_cast<int>(w.size()));
|
||||
}
|
||||
|
||||
bool isMinecraft(const std::wstring& title) {
|
||||
bool startsWithMinecraft(const std::wstring& title) {
|
||||
static const std::wstring prefix = L"Minecraft";
|
||||
static const std::wstring banned = L"Launcher";
|
||||
if (title.size() < prefix.size()) return false;
|
||||
if (title.compare(0, prefix.size(), prefix) != 0) return false;
|
||||
return title.find(banned) == std::wstring::npos;
|
||||
return title.compare(0, prefix.size(), prefix) == 0;
|
||||
}
|
||||
|
||||
bool isMinecraft(const std::wstring& title, const std::wstring& cls) {
|
||||
// Either the window title starts with "Minecraft" (in-game window
|
||||
// labelled e.g. "Minecraft 1.20.1"), or the window class is "GLFW30"
|
||||
// (the class Minecraft's LWJGL GLFW windows always use, even before the
|
||||
// title has been set).
|
||||
if (startsWithMinecraft(title)) return true;
|
||||
return _wcsicmp(cls.c_str(), L"GLFW30") == 0;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
@@ -167,7 +174,7 @@ void MainWindow::refreshNow() {
|
||||
QVector<Row> filtered;
|
||||
filtered.reserve(procs.size());
|
||||
for (const auto& jp : procs) {
|
||||
if (!isMinecraft(jp.window_title)) continue;
|
||||
if (!isMinecraft(jp.window_title, jp.window_class)) continue;
|
||||
Row r{ jp.pid, fromW(jp.window_title), fromW(jp.window_class) };
|
||||
filtered.push_back(std::move(r));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user