From d131fd4016efddb27b038c62d67534450cfaa360 Mon Sep 17 00:00:00 2001 From: Suyashtnt Date: Tue, 4 Jun 2024 17:48:20 +0200 Subject: [PATCH] feat: add a way to update jvm args during the launch process --- flake.lock | 12 ++++----- flake.nix | 4 +++ libs/copper/examples/full_launch.rs | 10 +++++++ libs/copper/src/assets/asset_index.rs | 39 ++++++++++++++++++++++++++- libs/copper/src/assets/client.rs | 11 ++++++++ libs/copper/src/launcher.rs | 9 ++++++- 6 files changed, 77 insertions(+), 8 deletions(-) diff --git a/flake.lock b/flake.lock index 0c3d7b6..71f349e 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1716137900, - "narHash": "sha256-sowPU+tLQv8GlqtVtsXioTKeaQvlMz/pefcdwg8MvfM=", + "lastModified": 1717196966, + "narHash": "sha256-yZKhxVIKd2lsbOqYd5iDoUIwsRZFqE87smE2Vzf6Ck0=", "owner": "nixos", "repo": "nixpkgs", - "rev": "6c0b7a92c30122196a761b440ac0d46d3d9954f1", + "rev": "57610d2f8f0937f39dbd72251e9614b1561942d8", "type": "github" }, "original": { @@ -51,11 +51,11 @@ ] }, "locked": { - "lastModified": 1716257780, - "narHash": "sha256-R+NjvJzKEkTVCmdrKRfPE4liX/KMGVqGUwwS5H8ET8A=", + "lastModified": 1717467480, + "narHash": "sha256-9Fbar+ycxdfZ6HbwOCgD+jWG3du/12TFisKRQm4Zhfc=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "4e5e3d2c5c9b2721bd266f9e43c14e96811b89d2", + "rev": "260ff391290a2b23958d04db0d3e7015c8417401", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index aa1aea3..e825251 100644 --- a/flake.nix +++ b/flake.nix @@ -29,6 +29,10 @@ libraries = with pkgs; [ openssl_3 pkg-config + libGL + mesa_drivers + glfw-wayland + libglvnd ]; packages = with pkgs; [ diff --git a/libs/copper/examples/full_launch.rs b/libs/copper/examples/full_launch.rs index 98e419a..fb3f9fe 100644 --- a/libs/copper/examples/full_launch.rs +++ b/libs/copper/examples/full_launch.rs @@ -185,10 +185,20 @@ async fn main() { .build() .unwrap(); + // launcher.add_jvm_argument(Jvm::String( + // "-Dorg.lwjgl.glfw.libname=glfw_wayland".to_string(), + // )); + info!("Launcher created. Downloading files"); let index = manifest.asset_index().download().await.unwrap(); + let index_dir = minecraft_dir.join("assets").join("indexes"); + index + .save_to_disk(&index_dir.join("Vanilla.json")) + .await + .unwrap(); + let mut downloader = launcher::Downloader::new(&launcher, index, manifest.libraries().to_vec(), 16); let mut reciever = downloader.create_channel(); diff --git a/libs/copper/src/assets/asset_index.rs b/libs/copper/src/assets/asset_index.rs index bee610c..6203642 100644 --- a/libs/copper/src/assets/asset_index.rs +++ b/libs/copper/src/assets/asset_index.rs @@ -1,19 +1,56 @@ use error_stack::{report, Result, ResultExt}; use futures::{stream, StreamExt, TryStreamExt}; use serde::{Deserialize, Serialize}; -use std::{cmp::min, collections::HashMap, path::PathBuf, sync::Arc}; +use serde_json::to_string; +use std::{ + cmp::min, + collections::HashMap, + path::{Path, PathBuf}, + sync::Arc, +}; use tokio::{ + fs, io::AsyncWriteExt, sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender}, }; +use tracing::debug; use crate::downloader::{DownloadError, DownloadMessage, Downloader}; +use super::client::SaveError; + #[derive(Debug, Serialize, Deserialize, Clone)] pub struct Assets { objects: HashMap, } +impl Assets { + /// Saves the manifest to disk. + /// + /// # Errors + /// Returns a [`SaveError`] if the manifest could not be serialized or if an IO error occurred. + #[tracing::instrument] + pub async fn save_to_disk(&self, path: &Path) -> error_stack::Result<(), SaveError> { + debug!("Saving Asset index to disk"); + debug!("Serializing index to JSON"); + let value = to_string(self).change_context(SaveError::SerializeError)?; + + let directory = path.parent().ok_or_else(|| report!(SaveError::IOError))?; + + if !directory.exists() { + debug!("Creating directory {}", directory.display()); + fs::create_dir_all(directory) + .await + .change_context(SaveError::IOError)?; + } + + debug!("Writing asset index to {}", path.display()); + fs::write(path, value) + .await + .change_context(SaveError::IOError) + } +} + #[derive(Debug, Clone)] pub struct AssetDownloader { assets: Assets, diff --git a/libs/copper/src/assets/client.rs b/libs/copper/src/assets/client.rs index 5e81730..0218c99 100644 --- a/libs/copper/src/assets/client.rs +++ b/libs/copper/src/assets/client.rs @@ -133,6 +133,17 @@ impl Manifest { ) } + /// Gets the mutable arguments for a manifest + /// + /// # Panics + /// Panics if there are no jvm arguments. This is a TODO + #[must_use] + pub(crate) fn arguments_mut(&mut self) -> &mut Arguments { + self.arguments.as_mut().unwrap_or_else(|| { + todo!("Handle older versions of minecraft that don't have new argument syntax") + }) + } + /// Gets the asset index for a manifest #[must_use] pub const fn asset_index(&self) -> &AssetIndex { diff --git a/libs/copper/src/launcher.rs b/libs/copper/src/launcher.rs index 56af2f0..84c4100 100644 --- a/libs/copper/src/launcher.rs +++ b/libs/copper/src/launcher.rs @@ -21,7 +21,7 @@ use winsafe::IsWindows10OrGreater; use crate::{ assets::{ asset_index::{AssetDownloader, Assets, Object}, - client::{self, Artifact, ClassDownloader, DownloadClass, Library, LibraryDownloader}, + client::{self, Artifact, ClassDownloader, DownloadClass, Jvm, Library, LibraryDownloader}, }, auth::{ structs::{MinecraftProfile, MinecraftToken}, @@ -498,3 +498,10 @@ impl Launcher { self.quickplay.as_ref() } } + +/// Manipulation methods for the launcher +impl Launcher { + pub fn add_jvm_argument(&mut self, arg: Jvm) { + self.manifest.arguments_mut().jvm.push(arg); + } +}