diff options
| author | 2025-02-10 22:22:45 -0600 | |
|---|---|---|
| committer | 2025-02-10 22:22:45 -0600 | |
| commit | a4853f8fdabad445f49968d063f736f0f461314e (patch) | |
| tree | 941a49ef58996d4d4e83c65c179f11d81a27a99c /ozone-cli/src/cli.rs | |
| parent | last commit before rewriting settings system?? (diff) | |
basic cli functionality
Diffstat (limited to 'ozone-cli/src/cli.rs')
| -rw-r--r-- | ozone-cli/src/cli.rs | 139 |
1 files changed, 115 insertions, 24 deletions
diff --git a/ozone-cli/src/cli.rs b/ozone-cli/src/cli.rs index 281a996..f60c4d2 100644 --- a/ozone-cli/src/cli.rs +++ b/ozone-cli/src/cli.rs @@ -1,56 +1,147 @@ use std::path::PathBuf;
use clap::{Args, Parser, Subcommand};
+use clap::error::ErrorKind;
+use ozone::launcher::{Instance, InstanceVersion, JavaRuntimeSetting, Resolution};
#[derive(Args, Debug)]
-pub struct ProfileSelectArgs {
- /// The name of the profile to select.
+pub struct InstanceSelectArgs {
+ /// The name of the instance to select.
#[arg(index = 1)]
- pub profile: String
+ pub instance: String
+}
+
+fn parse_resolution_argument(val: &str) -> Result<Option<Resolution>, clap::Error> {
+ match val.to_ascii_lowercase().as_str() {
+ "default" => Ok(None),
+ s => {
+ let Some(idx) = s.find('x') else {
+ return Err(clap::Error::raw(ErrorKind::InvalidValue, "malformed resolution argument (expected 'x')"));
+ };
+
+ let width: u32 = s[..idx].parse().map_err(|e| clap::Error::raw(ErrorKind::InvalidValue, e))?;
+ let height: u32 = s[idx+1..].parse().map_err(|e| clap::Error::raw(ErrorKind::InvalidValue, e))?;
+
+ if width == 0 || height == 0 {
+ return Err(clap::Error::raw(ErrorKind::InvalidValue, "malformed resolution argument (width and height must be positive)"));
+ }
+
+ Ok(Some(Resolution { width, height }))
+ }
+ }
+}
+
+#[derive(Args, Debug)]
+pub struct InstanceSettingsArgs {
+ /// Specify a version of the game which this profile should launch.
+ #[arg(long, short = 'v', conflicts_with_all = ["latest_release", "latest_snapshot"])]
+ pub version: Option<String>,
+
+ /// If set, this profile should always use the latest release (default).
+ ///
+ /// **Note**: Whenever a new version of Minecraft is released, this profile will
+ /// automatically switch to that version. This could cause unintended upgrades of settings and
+ /// worlds.
+ #[arg(long, conflicts_with_all = ["version", "latest_snapshot"])]
+ pub latest_release: bool,
+
+ /// If set, this profile should always use the latest snapshot.
+ ///
+ /// **Note**: Whenever a new version of Minecraft is released, this profile will
+ /// automatically switch to that version. This could cause unintended upgrades of settings and
+ /// worlds.
+ #[arg(long, short = 's', conflicts_with_all = ["version", "latest_release"])]
+ pub latest_snapshot: bool,
+
+ /// Specify the path to the java runtime that this profile should use to run the game.
+ ///
+ /// By default, the launcher will attempt to download a compatible java runtime before running the game.
+ #[arg(long, short = 'j', conflicts_with_all = ["jre_component", "jre_default"])]
+ pub jre_path: Option<PathBuf>,
+
+ /// Specify the java runtime component which this profile should download and use when launching
+ /// the game. If you don't understand what this means, you probably don't need this argument.
+ #[arg(long, conflicts_with_all = ["jre_path", "jre_default"])]
+ pub jre_component: Option<String>,
+
+ /// If set, configures this profile to automatically determine the java runtime to download and
+ /// use when launching the game. This is the default behavior.
+ #[arg(long, conflicts_with_all = ["jre_path", "jre_component"])]
+ pub jre_default: bool,
+
+ /// Specify the resolution of the Minecraft game window. Note that this argument is a suggestion
+ /// to the game process, and could be ignored or unsupported on some versions.
+ ///
+ /// Pass the resolution as _width_x_height_ (like `800x600').
+ ///
+ /// Use the special value _default_ to reset to the default value.
+ #[arg(long, short = 'r', value_parser = parse_resolution_argument)]
+ pub resolution: Option<Option<Resolution>>,
+}
+
+impl InstanceSettingsArgs {
+ pub fn apply_to(&self, inst: &mut Instance) {
+ if let Some(ref ver) = self.version {
+ inst.game_version = InstanceVersion::Specific(ver.clone());
+ } else if self.latest_release {
+ inst.game_version = InstanceVersion::LatestRelease;
+ } else if self.latest_snapshot {
+ inst.game_version = InstanceVersion::LatestSnapshot;
+ }
+
+ if let Some(ref path) = self.jre_path {
+ inst.java_runtime = Some(JavaRuntimeSetting::Path(path.clone()));
+ } else if let Some(ref comp) = self.jre_component {
+ inst.java_runtime = Some(JavaRuntimeSetting::Component(comp.clone()));
+ } else if self.jre_default {
+ inst.java_runtime = None;
+ }
+
+ if let Some(res) = self.resolution {
+ inst.resolution = res;
+ }
+ }
}
#[derive(Args, Debug)]
-pub struct ProfileCreateArgs {
- /// The name of the new profile.
+pub struct InstanceCreateArgs {
+ /// The name of the new instance. Must not be an empty string.
#[arg(index = 1)]
pub name: String,
- /// Clone profile information from an existing profile.
+ /// If set, clones settings from the selected instance.
#[arg(long, short = 'c')]
- pub clone: Option<String>,
+ pub clone: bool,
- /// The Minecraft version to be launched by this profile. Will use the latest release by default.
- #[arg(long, short = 'v')]
- pub version: Option<String>,
+ /// If set, don't select the newly created instance.
+ #[arg(long)]
+ pub no_select: bool,
- /// The instance in which this profile will launch the game. By default, will create a new instance
- /// with the same name as this profile.
- #[arg(long, short = 'i')]
- pub instance: Option<String>
+ #[command(flatten)]
+ pub settings: InstanceSettingsArgs
}
#[derive(Subcommand, Debug)]
-pub enum ProfileCommand {
- Select(ProfileSelectArgs),
- Create(ProfileCreateArgs),
+pub enum InstanceCommand {
+ Select(InstanceSelectArgs),
+ Create(InstanceCreateArgs),
List
}
#[derive(Args, Debug)]
-pub struct ProfileArgs {
+pub struct InstanceArgs {
#[command(subcommand)]
- subcmd: Option<ProfileCommand>
+ subcmd: Option<InstanceCommand>
}
-impl ProfileArgs {
- pub fn command(&self) -> &ProfileCommand {
- self.subcmd.as_ref().unwrap_or(&ProfileCommand::List)
+impl InstanceArgs {
+ pub fn command(&self) -> &InstanceCommand {
+ self.subcmd.as_ref().unwrap_or(&InstanceCommand::List)
}
}
#[derive(Subcommand, Debug)]
pub enum RootCommand {
- Profile(ProfileArgs),
- Instance,
+ Instance(InstanceArgs),
Launch
}
|
