cobble-core 1.2.0

Library for managing, installing and launching Minecraft instances and more.
Documentation
use crate::error::{CobbleError, CobbleResult};
use crate::instance::Instance;
use crate::minecraft::{build_launch_command, GameProcess, GameProcessHandle, LaunchOptions};
use std::process::{Command, Stdio};
use tokio::process::Child;

impl Instance {
    /// Builds the launch command for this instance.
    /// The instance needs to be properly installed.
    pub async fn launch_command(&self, options: &LaunchOptions) -> CobbleResult<Command> {
        trace!("Check if instance is installed");
        if !self.installed {
            return Err(CobbleError::NotInstalled);
        }

        trace!("Read version data from disk");
        let version_data = self.read_version_data().await?;

        Ok(build_launch_command(
            &version_data,
            options,
            self.dot_minecraft_path(),
            self.libraries_path(),
            self.assets_path(),
            self.natives_path(),
            self.log_configs_path(),
        ))
    }

    /// Launches the instance as a child process.
    /// Game process exits if parent exits.
    pub async fn launch<I, O, E>(
        &self,
        options: &LaunchOptions,
        stdin: I,
        stdout: O,
        stderr: E,
    ) -> CobbleResult<Child>
    where
        I: Into<Stdio> + Send,
        O: Into<Stdio> + Send,
        E: Into<Stdio> + Send,
    {
        let mut command = self.launch_command(options).await?;

        command.stdin(stdin).stdout(stdout).stderr(stderr);

        let mut command = tokio::process::Command::from(command);

        Ok(command.spawn()?)
    }

    /// Launches the instance as a detached process.
    /// Game process does not exit if parent exits.
    ///
    /// On unix platforms it is done by forking the process.
    ///
    /// On windows it is done using the
    /// [DETACHED_PROCESS and CREATE_NEW_PROCESS_GROUP flags](https://docs.microsoft.com/en-us/windows/win32/procthread/process-creation-flags).
    pub async fn detached_launch<I, O, E>(
        &self,
        options: &LaunchOptions,
        stdin: I,
        stdout: O,
        stderr: E,
    ) -> CobbleResult<GameProcessHandle>
    where
        I: Into<Stdio> + Send,
        O: Into<Stdio> + Send,
        E: Into<Stdio> + Send,
    {
        let mut command = self.launch_command(options).await?;

        command.stdin(stdin).stdout(stdout).stderr(stderr);

        Ok(GameProcessHandle::launch(command)?)
    }
}