Skip to content

Make it#11

Open
WinterWolfVN wants to merge 121 commits intoFireworkSky:mainfrom
WinterWolfVN:main
Open

Make it#11
WinterWolfVN wants to merge 121 commits intoFireworkSky:mainfrom
WinterWolfVN:main

Conversation

@WinterWolfVN
Copy link

No description provided.

shjjgg and others added 30 commits February 27, 2026 13:01
Updated comments and fixed parameter errors in the APK build workflow.
Updated the build workflow for APKs, including fixes to comments, environment setup, and build steps. Enhanced error handling and output reporting.
Updated comments and steps in the build APK workflow for clarity and accuracy.
Updated comments and fixed NDK version to match project requirements. Improved build steps and added detailed logging for APK builds.
Updated the build workflow to match the latest build.gradle configurations, including SDK versions and build tools.
Updated the build workflow to include diagnostic information and enhanced error logging for failed builds.
Updated the workflow to include detailed steps for building the RAL APK, including environment setup, SDK component installation, and artifact upload.
Updated build process for APKs to include stack traces and improved error handling for APK file detection. Adjusted paths for uploaded artifacts and modified logging messages for clarity.
[Bug] v2.0.1 Release 缺少 runtime_libs.tar.xz 文件
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR primarily targets adding Android 7.1 (API 25) compatibility across the project by lowering minSdk, enabling desugaring, and removing usages of java.nio.file.Path/kotlin.io.path in favor of java.io.File, plus a few runtime/workflow adjustments to avoid crashes on older devices.

Changes:

  • Lower Android minSdk to 25 and align toolchains/JVM targets to Java 17; enable core library desugaring.
  • Replace Path/kotlin.io.path usage with File throughout patching, extraction, and shared storage code paths.
  • Add Android 7/old-API safety fallbacks (Haze blur opt-out, edge-to-edge guarding, linker namespace bypass gating), and adjust CI workflows.

Reviewed changes

Copilot reviewed 36 out of 37 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
shared/src/commonMain/kotlin/com/app/ralaunch/shared/core/util/HazeUtils.kt Introduces expect modifier helper for conditional Haze usage.
shared/src/androidMain/kotlin/com/app/ralaunch/shared/core/util/HazeUtils.android.kt Android actual implementation: only apply haze on API 31+.
shared/src/commonMain/kotlin/com/app/ralaunch/shared/core/model/domain/GameItem.kt Switches path joining to java.io.File.
shared/src/commonMain/kotlin/com/app/ralaunch/shared/core/data/repository/SettingsRepositoryImpl.kt Migrates settings file IO from kotlin.io.path to File + rename-based persistence.
shared/src/commonMain/kotlin/com/app/ralaunch/shared/core/data/local/CommonGameListStorage.kt Migrates game list storage IO from kotlin.io.path to File.
shared/src/commonMain/kotlin/com/app/ralaunch/shared/core/data/local/CommonControlLayoutStorage.kt Migrates control layout storage IO from kotlin.io.path to File.
shared/src/androidMain/kotlin/com/app/ralaunch/core/platform/runtime/renderer/RendererRegistry.kt Replaces Path.resolve with File for MG dir env var; minor loop cleanup.
shared/build.gradle.kts Lowers toolchain to 17, minSdk to 25, enables desugaring for shared module, adds desugar dependency.
gradle/libs.versions.toml Adds version-catalog entry for desugar JDK libs.
app/src/main/java/com/app/ralaunch/feature/patch/data/PatchManifest.kt Removes Path overloads and Files.* checks; uses File.
app/src/main/java/com/app/ralaunch/feature/patch/data/PatchManagerConfig.kt Migrates patch config keys and IO from Path/Files to File.
app/src/main/java/com/app/ralaunch/feature/patch/data/PatchManager.kt Migrates patch manager storage/discovery/installation from Path/Files to File.
app/src/main/java/com/app/ralaunch/feature/patch/data/Patch.kt Migrates patch model from Path to File.
app/src/main/java/com/app/ralaunch/feature/init/InitializationActivity.kt Guards edge-to-edge / insets behavior for older Android versions; formatting cleanups.
app/src/main/java/com/app/ralaunch/feature/game/legacy/GamePresenter.kt Updates patch manager calls to pass File instead of Path.
app/src/main/java/com/app/ralaunch/core/ui/dialog/PatchManagementDialogCompose.kt Migrates patch import/install flow from Path/Files to File streams.
app/src/main/java/com/app/ralaunch/core/platform/runtime/GameLauncher.kt Replaces kotlin.io.path usage with File for existence checks and directory creation.
app/src/main/java/com/app/ralaunch/core/platform/runtime/AssemblyPatcher.kt Migrates MonoMod install path and asset copy from Path/Files to File.
app/src/main/java/com/app/ralaunch/core/platform/install/extractors/GogShFileExtractor.kt Migrates extractor paths from Path/Files to File.
app/src/main/java/com/app/ralaunch/core/platform/install/extractors/ExtractorCollection.kt Updates extractor interface signatures from Path to File.
app/src/main/java/com/app/ralaunch/core/platform/install/extractors/BasicSevenZipExtractor.kt Migrates extractor implementation to File and adds path traversal checks/prefix filtering.
app/src/main/java/com/app/ralaunch/core/platform/install/GameExtractorUtils.kt Updates extraction utilities to use File-based extractor APIs.
app/src/main/java/com/app/ralaunch/core/platform/android/provider/RaLaunchDocumentsProvider.kt Migrates delete recursion helper usage from Paths.get(...) to File.
app/src/main/java/com/app/ralaunch/core/platform/android/ProcessLauncherService.kt Updates patch lookup call sites to use File(assemblyPath).
app/src/main/java/com/app/ralaunch/core/common/util/TemporaryFileAcquirer.kt Migrates temp file management from Path to File.
app/src/main/java/com/app/ralaunch/core/common/util/FileUtils.kt Replaces NIO-based recursive delete with File-based implementation; adds helpers.
app/src/main/java/com/app/ralaunch/core/common/GameDeletionManager.kt Migrates delete calls to use File rather than Paths.
app/src/main/java/com/app/ralaunch/RaLaunchApp.kt Adds global uncaught exception logger + startup-step logging; minor refactors.
app/src/main/cpp/liblinkernsbypass/android_linker_ns.cpp Disables namespace-bypass logic on API < 28 and falls back to regular dlopen.
app/src/main/cpp/CMakeLists.txt Makes SDL target selection dynamic and adjusts install target list.
app/src/main/AndroidManifest.xml Adds tools:targetApi annotations and uses-sdk overrideLibrary; reorders some attributes.
app/build.gradle Lowers minSdk, enables desugaring, aligns Java/Kotlin targets to 17, adjusts native platform argument.
README_ZH.md Updates requirements badge/text to Android 7.1+.
README.md Updates requirements badge/text to Android 7.1+.
.github/workflows/sync-fork.yml Adds fork sync workflow that prefers local changes on conflict.
.github/workflows/build-apk.yml Simplifies build workflow, pins JDK 17, builds release on push, signs/archives output.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +68 to +71
dependencies {
coreLibraryDesugaring(libs.desugar.jdk.libs)
implementation 'androidx.multidex:multidex:2.0.1'
}
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dependencies { ... } is nested inside the android { ... } block, which is not valid in the Android Gradle plugin DSL and will fail configuration ("Could not find method dependencies()..."). Move these dependencies to the top-level dependencies { ... } block (and keep coreLibraryDesugaringEnabled in compileOptions).

Copilot uses AI. Check for mistakes.
Comment on lines +76 to +85
// Dùng File thay vì Path
val tempFile = File(settingsFile.parent, "${settingsFile.name}.tmp")
tempFile.writeText(serialized)

// Atomic move
if (!tempFile.renameTo(settingsFile)) {
// Nếu renameTo thất bại (khác partition), dùng copy + delete
settingsFile.writeText(serialized)
tempFile.delete()
}
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renameTo() is not a reliable atomic replacement across Android filesystems/SAF providers, and the fallback path writes directly to the final settings file (risking partial/corrupted writes if the process is killed mid-write). Use an actual atomic file pattern (e.g., AndroidX/Android AtomicFile, or a temp + fsync + replace strategy) and handle failures explicitly.

Copilot uses AI. Check for mistakes.
Comment on lines +163 to +166
// Tinh toan target file va chong path traversal
val targetFile = File(destinationFile, relativeFilePath).canonicalFile
if (!targetFile.path.startsWith(destinationFile.canonicalPath)) {
throw SevenZipException("Path traversal detected: $targetFile")
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The path traversal guard is too weak: targetFile.path.startsWith(destinationFile.canonicalPath) can be bypassed by paths like ${dest}../... (handled by canonicalization) but also by sibling prefixes (e.g., /dest_evil/... startsWith /dest). Compare against destCanonical + File.separator (or use Path-based startsWith) to ensure the extracted file is truly inside the destination directory.

Copilot uses AI. Check for mistakes.
val prefix = sourceExtractionPrefix.path
val relativeFilePath = if (prefix.isEmpty() || prefix == ".") {
filePath
} else if (filePath.startsWith(prefix)) {
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prefix filtering uses a plain startsWith(prefix) check. This can incorrectly match entries like data/noarch/gameX/... when the prefix is data/noarch/game, causing unintended files to be extracted. Ensure the match is on a path segment boundary (e.g., require filePath == prefix or filePath.startsWith(prefix + "/")) before stripping the prefix.

Suggested change
} else if (filePath.startsWith(prefix)) {
} else if (filePath == prefix || filePath.startsWith("$prefix/") || filePath.startsWith("$prefix\\")) {

Copilot uses AI. Check for mistakes.
Comment on lines 35 to 40
fun getEnabledPatchIds(gameAsmFile: File): ArrayList<String> { // CHANGED: Path to File
return enabledPatches.getOrDefault(
gameAsmPath.toAbsolutePath().normalize().toString(),
// CHANGED: toAbsolutePath().normalize().toString() to canonicalFile.absolutePath
gameAsmFile.canonicalFile.absolutePath,
arrayListOf()
)
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

canonicalFile can throw an IOException. Using it directly here means patch enable/disable checks can crash the app if the path cannot be canonicalized (e.g., permission issues, broken symlinks). Wrap canonicalization in runCatching { ... } with a safe fallback (like absoluteFile) and make sure the same normalization strategy is used consistently across reads/writes.

Copilot uses AI. Check for mistakes.
Comment on lines +10 to 12
fun getEntryAssemblyAbsolutePath(): File {
return File(patchDir, manifest.entryAssemblyFile).canonicalFile
}
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getEntryAssemblyAbsolutePath() uses canonicalFile, which can throw IOException at call sites (e.g., when constructing DOTNET_STARTUP_HOOKS). A failure here would crash the launch flow; consider catching canonicalization errors and falling back to absoluteFile (or returning a Result).

Copilot uses AI. Check for mistakes.
// 本地 JAR/AAR 依赖
// --- THAY ĐỔI 4: Thêm thư viện Desugaring ---
// Điều này bắt buộc để chạy các API Java hiện đại trên Android 7
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.2'
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

coreLibraryDesugaring is declared twice and with different versions (version-catalog at libs.desugar.jdk.libs vs hardcoded 2.1.2). This can lead to confusing resolution and makes version bumps error-prone. Prefer a single declaration using the version catalog (e.g., coreLibraryDesugaring(libs.desugar.jdk.libs)) in the top-level dependencies block.

Suggested change
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.2'
coreLibraryDesugaring(libs.desugar.jdk.libs)

Copilot uses AI. Check for mistakes.
Comment on lines +91 to +94
// Bạn có thể thay bằng alias libs.desugar.jdk.libs nếu đã khai báo trong toml
// Hoặc dùng trực tiếp chuỗi này:
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.2")
}
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The shared module enables core library desugaring, but the dependency is pinned to a hardcoded version (2.1.2) even though the version catalog defines desugarJdkLibs. Using the catalog here avoids version drift (the app module already references the catalog) and reduces the chance of runtime/compile classpath mismatches.

Suggested change
// Bạn có thể thay bằng alias libs.desugar.jdk.libs nếu đã khai báo trong toml
// Hoặc dùng trực tiếp chuỗi này:
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.2")
}
// Sử dụng alias từ version catalog để tránh lệch phiên bản giữa các module
coreLibraryDesugaring(libs.desugarJdkLibs)
}

Copilot uses AI. Check for mistakes.
Comment on lines +96 to 103
if (!settingsFile.exists()) return
val backupFile = File(
settingsFile.parent,
"${settingsFile.name}.corrupt.${System.currentTimeMillis()}"
)
settingsFilePathFull.moveTo(backupPathFull, overwrite = true)
// Dùng renameTo thay vì moveTo
settingsFile.renameTo(backupFile)
}
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

backupCorruptedFile() calls settingsFile.renameTo(backupFile) but ignores the boolean result. If the rename fails, the corrupted file remains in place and the app will keep failing to parse it on the next startup. Check the return value and consider falling back to copy+delete (or at least delete the corrupted file if it cannot be backed up).

Copilot uses AI. Check for mistakes.
Comment on lines 181 to 192
@Throws(IOException::class)
private fun getDefaultPatchStorageDirectories(customStoragePath: String?): Path {
private fun getDefaultPatchStorageDirectories(customStoragePath: String?): File {
val context: Context = KoinJavaComponent.get(Context::class.java)
val baseDir = customStoragePath ?: if (IS_DEFAULT_PATCH_STORAGE_DIR_EXTERNAL) {
Objects.requireNonNull(context.getExternalFilesDir(null))?.absolutePath
context.getExternalFilesDir(null)?.absolutePath
?: context.filesDir.absolutePath
} else {
context.filesDir.absolutePath
}
return Paths.get(baseDir, PATCH_STORAGE_DIR).normalize()
// Thay Paths.get().normalize() bang File()
return File(baseDir, PATCH_STORAGE_DIR).canonicalFile
}
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getDefaultPatchStorageDirectories() returns File(...).canonicalFile, which can throw IOException and crash during PatchManager initialization. Prefer a non-throwing normalization (absoluteFile) or catch IOException and fall back to the non-canonical path (while still normalizing separators) to avoid startup crashes.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants