mirror of
https://github.com/packwiz/packwiz-installer.git
synced 2025-04-20 13:36:30 +02:00
Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
7420866dfc | ||
|
1ebb28c3cc | ||
|
c9543f74ee |
@ -21,6 +21,7 @@ import java.nio.file.StandardCopyOption
|
|||||||
|
|
||||||
internal class DownloadTask private constructor(val metadata: IndexFile.File, val index: IndexFile, private val downloadSide: Side) : IOptionDetails {
|
internal class DownloadTask private constructor(val metadata: IndexFile.File, val index: IndexFile, private val downloadSide: Side) : IOptionDetails {
|
||||||
var cachedFile: ManifestFile.File? = null
|
var cachedFile: ManifestFile.File? = null
|
||||||
|
private set
|
||||||
|
|
||||||
private var err: Exception? = null
|
private var err: Exception? = null
|
||||||
val exceptionDetails get() = err?.let { e -> ExceptionDetails(name, e) }
|
val exceptionDetails get() = err?.let { e -> ExceptionDetails(name, e) }
|
||||||
@ -28,10 +29,24 @@ internal class DownloadTask private constructor(val metadata: IndexFile.File, va
|
|||||||
fun failed() = err != null
|
fun failed() = err != null
|
||||||
|
|
||||||
var alreadyUpToDate = false
|
var alreadyUpToDate = false
|
||||||
|
private set
|
||||||
private var metadataRequired = true
|
private var metadataRequired = true
|
||||||
private var invalidated = false
|
private var invalidated = false
|
||||||
// If file is new or isOptional changed to true, the option needs to be presented again
|
// If file is new or isOptional changed to true, the option needs to be presented again
|
||||||
private var newOptional = true
|
private var newOptional = true
|
||||||
|
var completionStatus = CompletionStatus.INCOMPLETE
|
||||||
|
private set
|
||||||
|
|
||||||
|
enum class CompletionStatus {
|
||||||
|
INCOMPLETE,
|
||||||
|
DOWNLOADED,
|
||||||
|
ALREADY_EXISTS_CACHED,
|
||||||
|
ALREADY_EXISTS_VALIDATED,
|
||||||
|
SKIPPED_DISABLED,
|
||||||
|
SKIPPED_WRONG_SIDE,
|
||||||
|
DELETED_DISABLED,
|
||||||
|
DELETED_WRONG_SIDE;
|
||||||
|
}
|
||||||
|
|
||||||
val isOptional get() = metadata.linkedFile?.option?.optional ?: false
|
val isOptional get() = metadata.linkedFile?.option?.optional ?: false
|
||||||
|
|
||||||
@ -76,6 +91,7 @@ internal class DownloadTask private constructor(val metadata: IndexFile.File, va
|
|||||||
if (currHash == cachedFile.hash) { // Already up to date
|
if (currHash == cachedFile.hash) { // Already up to date
|
||||||
alreadyUpToDate = true
|
alreadyUpToDate = true
|
||||||
metadataRequired = false
|
metadataRequired = false
|
||||||
|
completionStatus = CompletionStatus.ALREADY_EXISTS_CACHED
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cachedFile.isOptional) {
|
if (cachedFile.isOptional) {
|
||||||
@ -143,6 +159,7 @@ internal class DownloadTask private constructor(val metadata: IndexFile.File, va
|
|||||||
fileSource.buffer().readAll(blackholeSink())
|
fileSource.buffer().readAll(blackholeSink())
|
||||||
if (hash == fileSource.hash) {
|
if (hash == fileSource.hash) {
|
||||||
alreadyUpToDate = true
|
alreadyUpToDate = true
|
||||||
|
completionStatus = CompletionStatus.ALREADY_EXISTS_VALIDATED
|
||||||
|
|
||||||
// Update the manifest file
|
// Update the manifest file
|
||||||
cachedFile = (cachedFile ?: ManifestFile.File()).also {
|
cachedFile = (cachedFile ?: ManifestFile.File()).also {
|
||||||
@ -181,10 +198,18 @@ internal class DownloadTask private constructor(val metadata: IndexFile.File, va
|
|||||||
if (it.cachedLocation != null) {
|
if (it.cachedLocation != null) {
|
||||||
// Ensure wrong-side or optional false files are removed
|
// Ensure wrong-side or optional false files are removed
|
||||||
try {
|
try {
|
||||||
Files.deleteIfExists(it.cachedLocation!!.nioPath)
|
completionStatus = if (Files.deleteIfExists(it.cachedLocation!!.nioPath)) {
|
||||||
|
if (correctSide()) { CompletionStatus.DELETED_DISABLED } else { CompletionStatus.DELETED_WRONG_SIDE }
|
||||||
|
} else {
|
||||||
|
if (correctSide()) { CompletionStatus.SKIPPED_DISABLED } else { CompletionStatus.SKIPPED_WRONG_SIDE }
|
||||||
|
}
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
Log.warn("Failed to delete file", e)
|
Log.warn("Failed to delete file", e)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
completionStatus =
|
||||||
|
if (correctSide()) { CompletionStatus.SKIPPED_DISABLED }
|
||||||
|
else { CompletionStatus.SKIPPED_WRONG_SIDE }
|
||||||
}
|
}
|
||||||
it.cachedLocation = null
|
it.cachedLocation = null
|
||||||
return
|
return
|
||||||
@ -284,6 +309,8 @@ internal class DownloadTask private constructor(val metadata: IndexFile.File, va
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
completionStatus = CompletionStatus.DOWNLOADED
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -48,6 +48,7 @@ class LauncherUtils internal constructor(private val opts: UpdateManager.Options
|
|||||||
val modLoaders = hashMapOf(
|
val modLoaders = hashMapOf(
|
||||||
"net.minecraft" to "minecraft",
|
"net.minecraft" to "minecraft",
|
||||||
"net.minecraftforge" to "forge",
|
"net.minecraftforge" to "forge",
|
||||||
|
"net.neoforged" to "neoforge",
|
||||||
"net.fabricmc.fabric-loader" to "fabric",
|
"net.fabricmc.fabric-loader" to "fabric",
|
||||||
"org.quiltmc.quilt-loader" to "quilt",
|
"org.quiltmc.quilt-loader" to "quilt",
|
||||||
"com.mumfrey.liteloader" to "liteloader"
|
"com.mumfrey.liteloader" to "liteloader"
|
||||||
@ -59,6 +60,7 @@ class LauncherUtils internal constructor(private val opts: UpdateManager.Options
|
|||||||
"org.lwjgl" to -1,
|
"org.lwjgl" to -1,
|
||||||
"org.lwjgl3" to -1,
|
"org.lwjgl3" to -1,
|
||||||
"net.minecraftforge" to 5,
|
"net.minecraftforge" to 5,
|
||||||
|
"net.neoforged" to 5,
|
||||||
"net.fabricmc.fabric-loader" to 10,
|
"net.fabricmc.fabric-loader" to 10,
|
||||||
"org.quiltmc.quilt-loader" to 10,
|
"org.quiltmc.quilt-loader" to 10,
|
||||||
"com.mumfrey.liteloader" to 10,
|
"com.mumfrey.liteloader" to 10,
|
||||||
|
@ -127,40 +127,44 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse
|
|||||||
|
|
||||||
ui.submitProgress(InstallProgress("Checking local files..."))
|
ui.submitProgress(InstallProgress("Checking local files..."))
|
||||||
|
|
||||||
// Invalidation checking must be done here, as it must happen before pack/index hashes are checked
|
// If the side changes, invalidate EVERYTHING (even when the index hasn't changed)
|
||||||
|
val invalidateAll = opts.side != manifest.cachedSide
|
||||||
val invalidatedUris: MutableList<PackwizFilePath> = ArrayList()
|
val invalidatedUris: MutableList<PackwizFilePath> = ArrayList()
|
||||||
for ((fileUri, file) in manifest.cachedFiles) {
|
if (!invalidateAll) {
|
||||||
// ignore onlyOtherSide files
|
// Invalidation checking must be done here, as it must happen before pack/index hashes are checked
|
||||||
if (file.onlyOtherSide) {
|
for ((fileUri, file) in manifest.cachedFiles) {
|
||||||
continue
|
// ignore onlyOtherSide files
|
||||||
}
|
if (file.onlyOtherSide) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
var invalid = false
|
var invalid = false
|
||||||
// if isn't optional, or is optional but optionValue == true
|
// if isn't optional, or is optional but optionValue == true
|
||||||
if (!file.isOptional || file.optionValue) {
|
if (!file.isOptional || file.optionValue) {
|
||||||
if (file.cachedLocation != null) {
|
if (file.cachedLocation != null) {
|
||||||
if (!file.cachedLocation!!.nioPath.toFile().exists()) {
|
if (!file.cachedLocation!!.nioPath.toFile().exists()) {
|
||||||
|
invalid = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// if cachedLocation == null, should probably be installed!!
|
||||||
invalid = true
|
invalid = true
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
// if cachedLocation == null, should probably be installed!!
|
if (invalid) {
|
||||||
invalid = true
|
Log.info("File ${fileUri.filename} invalidated, marked for redownloading")
|
||||||
|
invalidatedUris.add(fileUri)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (invalid) {
|
|
||||||
Log.info("File ${fileUri.filename} invalidated, marked for redownloading")
|
|
||||||
invalidatedUris.add(fileUri)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (manifest.packFileHash?.let { it == packFileSource.hash } == true && invalidatedUris.isEmpty()) {
|
if (manifest.packFileHash?.let { it == packFileSource.hash } == true && invalidatedUris.isEmpty()) {
|
||||||
// todo: --force?
|
// todo: --force?
|
||||||
ui.submitProgress(InstallProgress("Modpack is already up to date!", 1, 1))
|
ui.submitProgress(InstallProgress("Modpack is already up to date!", 1, 1))
|
||||||
if (manifest.cachedFiles.any { it.value.isOptional }) {
|
if (manifest.cachedFiles.any { it.value.isOptional }) {
|
||||||
ui.awaitOptionalButton(false, opts.timeout)
|
ui.awaitOptionalButton(false, opts.timeout)
|
||||||
}
|
}
|
||||||
if (!ui.optionsButtonPressed) {
|
if (!ui.optionsButtonPressed) {
|
||||||
return
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,6 +181,7 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse
|
|||||||
pf.index.hashFormat,
|
pf.index.hashFormat,
|
||||||
manifest,
|
manifest,
|
||||||
invalidatedUris,
|
invalidatedUris,
|
||||||
|
invalidateAll,
|
||||||
clientHolder
|
clientHolder
|
||||||
)
|
)
|
||||||
} catch (e1: Exception) {
|
} catch (e1: Exception) {
|
||||||
@ -202,18 +207,20 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processIndex(indexUri: PackwizPath<*>, indexHash: Hash<*>, hashFormat: HashFormat<*>, manifest: ManifestFile, invalidatedFiles: List<PackwizFilePath>, clientHolder: ClientHolder) {
|
private fun processIndex(indexUri: PackwizPath<*>, indexHash: Hash<*>, hashFormat: HashFormat<*>, manifest: ManifestFile, invalidatedFiles: List<PackwizFilePath>, invalidateAll: Boolean, clientHolder: ClientHolder) {
|
||||||
if (manifest.indexFileHash == indexHash && invalidatedFiles.isEmpty()) {
|
if (!invalidateAll) {
|
||||||
ui.submitProgress(InstallProgress("Modpack files are already up to date!", 1, 1))
|
if (manifest.indexFileHash == indexHash && invalidatedFiles.isEmpty()) {
|
||||||
if (manifest.cachedFiles.any { it.value.isOptional }) {
|
ui.submitProgress(InstallProgress("Modpack files are already up to date!", 1, 1))
|
||||||
ui.awaitOptionalButton(false, opts.timeout)
|
if (manifest.cachedFiles.any { it.value.isOptional }) {
|
||||||
}
|
ui.awaitOptionalButton(false, opts.timeout)
|
||||||
if (!ui.optionsButtonPressed) {
|
}
|
||||||
return
|
if (!ui.optionsButtonPressed) {
|
||||||
}
|
return
|
||||||
if (ui.cancelButtonPressed) {
|
}
|
||||||
showCancellationDialog()
|
if (ui.cancelButtonPressed) {
|
||||||
return
|
showCancellationDialog()
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
manifest.indexFileHash = indexHash
|
manifest.indexFileHash = indexHash
|
||||||
@ -240,31 +247,17 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse
|
|||||||
}
|
}
|
||||||
|
|
||||||
ui.submitProgress(InstallProgress("Checking local files..."))
|
ui.submitProgress(InstallProgress("Checking local files..."))
|
||||||
// TODO: use kotlin filtering/FP rather than an iterator?
|
|
||||||
val it: MutableIterator<Map.Entry<PackwizFilePath, ManifestFile.File>> = manifest.cachedFiles.entries.iterator()
|
val it: MutableIterator<Map.Entry<PackwizFilePath, ManifestFile.File>> = manifest.cachedFiles.entries.iterator()
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
val (uri, file) = it.next()
|
val (uri, file) = it.next()
|
||||||
if (file.cachedLocation != null) {
|
if (file.cachedLocation != null) {
|
||||||
var alreadyDeleted = false
|
if (indexFile.files.none { it.file.rebase(opts.packFolder) == uri }) { // File has been removed from the index
|
||||||
// Delete if option value has been set to false
|
|
||||||
if (file.isOptional && !file.optionValue) {
|
|
||||||
try {
|
try {
|
||||||
Files.deleteIfExists(file.cachedLocation!!.nioPath)
|
Files.deleteIfExists(file.cachedLocation!!.nioPath)
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
Log.warn("Failed to delete optional disabled file", e)
|
Log.warn("Failed to delete file removed from index", e)
|
||||||
}
|
|
||||||
// Set to null, as it doesn't exist anymore
|
|
||||||
file.cachedLocation = null
|
|
||||||
alreadyDeleted = true
|
|
||||||
}
|
|
||||||
if (indexFile.files.none { it.file.rebase(opts.packFolder) == uri }) { // File has been removed from the index
|
|
||||||
if (!alreadyDeleted) {
|
|
||||||
try {
|
|
||||||
Files.deleteIfExists(file.cachedLocation!!.nioPath)
|
|
||||||
} catch (e: IOException) {
|
|
||||||
Log.warn("Failed to delete file removed from index", e)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Log.info("Deleted ${file.cachedLocation!!.filename} (removed from pack)")
|
||||||
it.remove()
|
it.remove()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -281,9 +274,6 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse
|
|||||||
Log.warn("Index is empty!")
|
Log.warn("Index is empty!")
|
||||||
}
|
}
|
||||||
val tasks = createTasksFromIndex(indexFile, opts.side)
|
val tasks = createTasksFromIndex(indexFile, opts.side)
|
||||||
// If the side changes, invalidate EVERYTHING just in case
|
|
||||||
// Might not be needed, but done just to be safe
|
|
||||||
val invalidateAll = opts.side != manifest.cachedSide
|
|
||||||
if (invalidateAll) {
|
if (invalidateAll) {
|
||||||
Log.info("Side changed, invalidating all mods")
|
Log.info("Side changed, invalidating all mods")
|
||||||
}
|
}
|
||||||
@ -397,7 +387,16 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse
|
|||||||
val progress = if (exDetails != null) {
|
val progress = if (exDetails != null) {
|
||||||
"Failed to download ${exDetails.name}: ${exDetails.exception.message}"
|
"Failed to download ${exDetails.name}: ${exDetails.exception.message}"
|
||||||
} else {
|
} else {
|
||||||
"Downloaded ${task.name}"
|
when (task.completionStatus) {
|
||||||
|
DownloadTask.CompletionStatus.INCOMPLETE -> "${task.name} pending (you should never see this...)"
|
||||||
|
DownloadTask.CompletionStatus.DOWNLOADED -> "Downloaded ${task.name}"
|
||||||
|
DownloadTask.CompletionStatus.ALREADY_EXISTS_CACHED -> "${task.name} already exists (cached)"
|
||||||
|
DownloadTask.CompletionStatus.ALREADY_EXISTS_VALIDATED -> "${task.name} already exists (validated)"
|
||||||
|
DownloadTask.CompletionStatus.SKIPPED_DISABLED -> "Skipped ${task.name} (disabled)"
|
||||||
|
DownloadTask.CompletionStatus.SKIPPED_WRONG_SIDE -> "Skipped ${task.name} (wrong side)"
|
||||||
|
DownloadTask.CompletionStatus.DELETED_DISABLED -> "Deleted ${task.name} (disabled)"
|
||||||
|
DownloadTask.CompletionStatus.DELETED_WRONG_SIDE -> "Deleted ${task.name} (wrong side)"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ui.submitProgress(InstallProgress(progress, i + 1, tasks.size))
|
ui.submitProgress(InstallProgress(progress, i + 1, tasks.size))
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user