mirror of
				https://github.com/packwiz/packwiz-installer.git
				synced 2025-10-31 19:04:32 +01:00 
			
		
		
		
	Add option to automatically close after a user-supplied amount of time (#42)
* Add option to automatically close after a user-specific amount of time Add the -t/--timeout command line option to specific a number of seconds to wait before automatically closing if there is no update or user-interactivity required. * Also use timeout setting when prompting about optional mods after/during an update Additionally, clears the TODO comment. * Change default timeout to 10 seconds
This commit is contained in:
		| @@ -103,10 +103,13 @@ class Main(args: Array<String>) { | |||||||
| 		val manifestFile = ui.wrap("Invalid manifest file path") { | 		val manifestFile = ui.wrap("Invalid manifest file path") { | ||||||
| 			packFolder / (cmd.getOptionValue("meta-file") ?: "packwiz.json") | 			packFolder / (cmd.getOptionValue("meta-file") ?: "packwiz.json") | ||||||
| 		} | 		} | ||||||
|  | 		val timeout = ui.wrap("Invalid timeout value") { | ||||||
|  | 			cmd.getOptionValue("timeout")?.toLong() ?: 10 | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		// Start update process! | 		// Start update process! | ||||||
| 		try { | 		try { | ||||||
| 			UpdateManager(UpdateManager.Options(packFile, manifestFile, packFolder, multimcFolder, side), ui) | 			UpdateManager(UpdateManager.Options(packFile, manifestFile, packFolder, multimcFolder, side, timeout), ui) | ||||||
| 		} catch (e: Exception) { | 		} catch (e: Exception) { | ||||||
| 			ui.showErrorAndExit("Update process failed", e) | 			ui.showErrorAndExit("Update process failed", e) | ||||||
| 		} | 		} | ||||||
| @@ -123,6 +126,7 @@ class Main(args: Array<String>) { | |||||||
| 			options.addOption(null, "pack-folder", true, "Folder to install the pack to (defaults to the JAR directory)") | 			options.addOption(null, "pack-folder", true, "Folder to install the pack to (defaults to the JAR directory)") | ||||||
| 			options.addOption(null, "multimc-folder", true, "The MultiMC pack folder (defaults to the parent of the pack directory)") | 			options.addOption(null, "multimc-folder", true, "The MultiMC pack folder (defaults to the parent of the pack directory)") | ||||||
| 			options.addOption(null, "meta-file", true, "JSON file to store pack metadata, relative to the pack folder (defaults to packwiz.json)") | 			options.addOption(null, "meta-file", true, "JSON file to store pack metadata, relative to the pack folder (defaults to packwiz.json)") | ||||||
|  | 			options.addOption("t", "timeout", true, "Seconds to wait before automatically launching when asking about optional mods (defaults to 10)") | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// TODO: link these somehow so they're only defined once? | 		// TODO: link these somehow so they're only defined once? | ||||||
|   | |||||||
| @@ -48,7 +48,8 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse | |||||||
| 		val manifestFile: PackwizFilePath, | 		val manifestFile: PackwizFilePath, | ||||||
| 		val packFolder: PackwizFilePath, | 		val packFolder: PackwizFilePath, | ||||||
| 		val multimcFolder: PackwizFilePath, | 		val multimcFolder: PackwizFilePath, | ||||||
| 		val side: Side | 		val side: Side, | ||||||
|  | 		val timeout: Long, | ||||||
| 	) | 	) | ||||||
|  |  | ||||||
| 	// TODO: make this return a value based on results? | 	// TODO: make this return a value based on results? | ||||||
| @@ -157,7 +158,7 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse | |||||||
| 			// 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) | 				ui.awaitOptionalButton(false, opts.timeout) | ||||||
| 			} | 			} | ||||||
| 			if (!ui.optionsButtonPressed) { | 			if (!ui.optionsButtonPressed) { | ||||||
| 				return | 				return | ||||||
| @@ -206,7 +207,7 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse | |||||||
| 		if (manifest.indexFileHash == indexHash && invalidatedFiles.isEmpty()) { | 		if (manifest.indexFileHash == indexHash && invalidatedFiles.isEmpty()) { | ||||||
| 			ui.submitProgress(InstallProgress("Modpack files are already up to date!", 1, 1)) | 			ui.submitProgress(InstallProgress("Modpack files are already up to date!", 1, 1)) | ||||||
| 			if (manifest.cachedFiles.any { it.value.isOptional }) { | 			if (manifest.cachedFiles.any { it.value.isOptional }) { | ||||||
| 				ui.awaitOptionalButton(false) | 				ui.awaitOptionalButton(false, opts.timeout) | ||||||
| 			} | 			} | ||||||
| 			if (!ui.optionsButtonPressed) { | 			if (!ui.optionsButtonPressed) { | ||||||
| 				return | 				return | ||||||
| @@ -338,7 +339,7 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse | |||||||
| 			if (!ui.optionsButtonPressed) { | 			if (!ui.optionsButtonPressed) { | ||||||
| 				// TODO: this is so ugly | 				// TODO: this is so ugly | ||||||
| 				ui.submitProgress(InstallProgress("Reconfigure optional mods?", 0,1)) | 				ui.submitProgress(InstallProgress("Reconfigure optional mods?", 0,1)) | ||||||
| 				ui.awaitOptionalButton(true) | 				ui.awaitOptionalButton(true, opts.timeout) | ||||||
| 				if (ui.cancelButtonPressed) { | 				if (ui.cancelButtonPressed) { | ||||||
| 					showCancellationDialog() | 					showCancellationDialog() | ||||||
| 					return | 					return | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ interface IUserInterface { | |||||||
|  |  | ||||||
| 	fun showUpdateConfirmationDialog(oldVersions: List<Pair<String, String?>>, newVersions: List<Pair<String, String?>>): UpdateConfirmationResult = UpdateConfirmationResult.CANCELLED | 	fun showUpdateConfirmationDialog(oldVersions: List<Pair<String, String?>>, newVersions: List<Pair<String, String?>>): UpdateConfirmationResult = UpdateConfirmationResult.CANCELLED | ||||||
|  |  | ||||||
| 	fun awaitOptionalButton(showCancel: Boolean) | 	fun awaitOptionalButton(showCancel: Boolean, timeout: Long) | ||||||
|  |  | ||||||
| 	enum class ExceptionListResult { | 	enum class ExceptionListResult { | ||||||
| 		CONTINUE, CANCEL, IGNORE | 		CONTINUE, CANCEL, IGNORE | ||||||
|   | |||||||
| @@ -63,7 +63,7 @@ class CLIHandler : IUserInterface { | |||||||
| 		return ExceptionListResult.CANCEL | 		return ExceptionListResult.CANCEL | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	override fun awaitOptionalButton(showCancel: Boolean) { | 	override fun awaitOptionalButton(showCancel: Boolean, timeout: Long) { | ||||||
| 		// Do nothing | 		// Do nothing | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -7,11 +7,13 @@ import link.infra.packwiz.installer.ui.data.IOptionDetails | |||||||
| import link.infra.packwiz.installer.ui.data.InstallProgress | import link.infra.packwiz.installer.ui.data.InstallProgress | ||||||
| import link.infra.packwiz.installer.util.Log | import link.infra.packwiz.installer.util.Log | ||||||
| import java.awt.EventQueue | import java.awt.EventQueue | ||||||
|  | import java.util.Timer | ||||||
| import java.util.concurrent.CompletableFuture | import java.util.concurrent.CompletableFuture | ||||||
| import java.util.concurrent.CountDownLatch | import java.util.concurrent.CountDownLatch | ||||||
| import javax.swing.JDialog | import javax.swing.JDialog | ||||||
| import javax.swing.JOptionPane | import javax.swing.JOptionPane | ||||||
| import javax.swing.UIManager | import javax.swing.UIManager | ||||||
|  | import kotlin.concurrent.timer | ||||||
| import kotlin.system.exitProcess | import kotlin.system.exitProcess | ||||||
|  |  | ||||||
| class GUIHandler : IUserInterface { | class GUIHandler : IUserInterface { | ||||||
| @@ -220,12 +222,28 @@ class GUIHandler : IUserInterface { | |||||||
| 		return future.get() | 		return future.get() | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	override fun awaitOptionalButton(showCancel: Boolean) { | 	override fun awaitOptionalButton(showCancel: Boolean, timeout: Long) { | ||||||
| 		EventQueue.invokeAndWait { | 		EventQueue.invokeAndWait { | ||||||
| 			frmPackwizlauncher.showOk(!showCancel) | 			frmPackwizlauncher.showOk(!showCancel) | ||||||
| 		} | 		} | ||||||
| 		visibleCountdownLatch.await() | 		visibleCountdownLatch.await() | ||||||
|  |  | ||||||
|  | 		var closeTimer: Timer? = null | ||||||
|  | 		if (timeout >= 0) { | ||||||
|  | 			var count = 0 | ||||||
|  | 			closeTimer = timer("timeout", true, 0, 1000) { | ||||||
|  | 				if (count >= timeout) { | ||||||
|  | 					optionalSelectedLatch.countDown() | ||||||
|  | 					cancel() | ||||||
|  | 				} else { | ||||||
|  | 					frmPackwizlauncher.timeoutOk(timeout - count) | ||||||
|  | 					count += 1 | ||||||
|  | 				} | ||||||
|  | 			}; | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		optionalSelectedLatch.await() | 		optionalSelectedLatch.await() | ||||||
|  | 		closeTimer?.cancel() | ||||||
| 		EventQueue.invokeLater { | 		EventQueue.invokeLater { | ||||||
| 			frmPackwizlauncher.hideOk() | 			frmPackwizlauncher.hideOk() | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -121,4 +121,8 @@ class InstallWindow(private val handler: GUIHandler) : JFrame() { | |||||||
| 		} | 		} | ||||||
| 		buttonsPanel.revalidate() | 		buttonsPanel.revalidate() | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	fun timeoutOk(remaining: Long) { | ||||||
|  | 		btnOk.text = "Continue ($remaining)" | ||||||
|  | 	} | ||||||
| } | } | ||||||
		Reference in New Issue
	
	Block a user