Add modpack creation and compilation

This commit is contained in:
Daniel Hutzley 2021-12-05 12:20:59 -08:00
parent 5ffddd6c8a
commit fc076c2e54
5 changed files with 219 additions and 10 deletions

142
Cargo.lock generated
View File

@ -75,12 +75,39 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "block-buffer"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
dependencies = [
"block-padding",
"byte-tools",
"byteorder",
"generic-array",
]
[[package]]
name = "block-padding"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
dependencies = [
"byte-tools",
]
[[package]]
name = "bumpalo"
version = "3.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
[[package]]
name = "byte-tools"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
[[package]]
name = "byteorder"
version = "1.4.3"
@ -181,6 +208,15 @@ dependencies = [
"tokio",
]
[[package]]
name = "digest"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
dependencies = [
"generic-array",
]
[[package]]
name = "encoding_rs"
version = "0.8.29"
@ -190,6 +226,12 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "fake-simd"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
[[package]]
name = "flate2"
version = "1.0.22"
@ -328,6 +370,15 @@ dependencies = [
"slab",
]
[[package]]
name = "generic-array"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
dependencies = [
"typenum",
]
[[package]]
name = "getrandom"
version = "0.2.3"
@ -504,6 +555,17 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "json5"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1"
dependencies = [
"pest",
"pest_derive",
"serde",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
@ -534,6 +596,12 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "maplit"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
[[package]]
name = "matches"
version = "0.1.9"
@ -646,6 +714,12 @@ version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
[[package]]
name = "opaque-debug"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
[[package]]
name = "openssl"
version = "0.10.38"
@ -716,6 +790,49 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
name = "pest"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
dependencies = [
"ucd-trie",
]
[[package]]
name = "pest_derive"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0"
dependencies = [
"pest",
"pest_generator",
]
[[package]]
name = "pest_generator"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"
dependencies = [
"pest",
"pest_meta",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "pest_meta"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
dependencies = [
"maplit",
"pest",
"sha-1",
]
[[package]]
name = "pin-project-lite"
version = "0.2.7"
@ -956,6 +1073,18 @@ dependencies = [
"serde",
]
[[package]]
name = "sha-1"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
dependencies = [
"block-buffer",
"digest",
"fake-simd",
"opaque-debug",
]
[[package]]
name = "sha1"
version = "0.6.0"
@ -1039,6 +1168,7 @@ dependencies = [
"daedalus",
"fs_extra",
"futures",
"json5",
"lazy_static",
"path-clean",
"regex",
@ -1194,6 +1324,18 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
[[package]]
name = "typenum"
version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec"
[[package]]
name = "ucd-trie"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
[[package]]
name = "unicode-bidi"
version = "0.3.7"

View File

@ -15,6 +15,7 @@ daedalus = "0.1.6"
reqwest = { version = "0.11", features = ["json"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
json5 = "0.4.1"
chrono = { version = "0.4", features = ["serde"] }
uuid = { version = "0.8", features = ["serde", "v4"] }
bytes = "1"

View File

@ -1,4 +1,5 @@
use daedalus::minecraft::{ArgumentType, VersionInfo};
use serde::{Deserialize, Serialize};
use std::path::Path;
use std::process::{Command, Stdio};
use thiserror::Error;
@ -65,7 +66,8 @@ pub async fn fetch_metadata() -> Result<
Ok((game?, forge?, fabric?))
}
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
#[derive(Debug, Eq, PartialEq, Clone, Copy, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum ModLoader {
Vanilla,
Forge,

View File

@ -4,18 +4,23 @@ use daedalus::download_file;
use fs_extra::dir::CopyOptions;
use serde::Deserialize;
use std::{convert::TryFrom, env, io, path::Path};
use tokio::fs;
use tokio::{fs, try_join};
use uuid::Uuid;
use zip::ZipArchive;
use self::{manifest::Manifest, pack::Modpack};
use self::{
manifest::Manifest,
pack::{Modpack, ModpackGame},
};
pub mod pack;
pub mod manifest;
pub mod modrinth_api;
pub mod pack;
pub const COMPILED_PATH: &'static str = "compiled/";
pub const MANIFEST_PATH: &'static str = "index.json";
pub const OVERRIDES_PATH: &'static str = "overrides/";
pub const PACK_JSON5_PATH: &'static str = "modpack.json5";
#[derive(thiserror::Error, Debug)]
pub enum ModpackError {
@ -43,6 +48,9 @@ pub enum ModpackError {
#[error("Error parsing json: {0}")]
JsonError(#[from] serde_json::Error),
#[error("Error parsing json5: {0}")]
Json5Error(#[from] json5::Error),
#[error("Error joining futures: {0}")]
JoinError(#[from] tokio::task::JoinError),
@ -50,7 +58,7 @@ pub enum ModpackError {
VersionError(String),
#[error("Error downloading file: {0}")]
FetchError(#[from] reqwest::Error)
FetchError(#[from] reqwest::Error),
}
type ModpackResult<T> = Result<T, ModpackError>;
@ -121,3 +129,57 @@ pub async fn realise_modpack(
modpack.download_files(dest, side).await?;
Ok(())
}
pub fn to_pack_json5(pack: &Modpack) -> ModpackResult<String> {
let json5 = json5::to_string(pack)?;
Ok(format!("// This modpack is managed using Theseus. It can be edited using either a Theseus-compatible launcher or manually.\n{}", json5))
}
lazy_static::lazy_static! {
static ref PACK_GITIGNORE: String = format!(r#"
{0}
"#, COMPILED_PATH);
}
pub async fn create_modpack(
name: &str,
game: ModpackGame,
summary: Option<&str>,
) -> ModpackResult<()> {
let output_dir = Path::new("./").join(name);
let pack = Modpack::new(game, "0.1.0", name, summary);
try_join!(
fs::create_dir(&output_dir),
fs::create_dir(output_dir.join(OVERRIDES_PATH)),
fs::write(output_dir.join(".gitignore"), PACK_GITIGNORE.as_str()),
fs::write(output_dir.join(PACK_JSON5_PATH), to_pack_json5(&pack)?),
)?;
Ok(())
}
pub async fn compile_modpack(dir: &Path) -> ModpackResult<()> {
let result_dir = dir.join(COMPILED_PATH);
let pack: Modpack = json5::from_str(&fs::read_to_string(dir.join(PACK_JSON5_PATH)).await?)?;
if dir.join(OVERRIDES_PATH).exists() {
fs_extra::dir::copy(
dir.join(OVERRIDES_PATH),
result_dir.join(OVERRIDES_PATH),
&CopyOptions::new(),
)?;
}
let manifest = Manifest::try_from(&pack)?;
try_join!(
fs::create_dir(&result_dir),
fs::write(
result_dir.join(MANIFEST_PATH),
serde_json::to_string(&manifest)?
),
)?;
Ok(())
}

View File

@ -1,5 +1,6 @@
use daedalus::download_file_mirrors;
use futures::future;
use serde::{Deserialize, Serialize};
use std::{
collections::HashSet,
hash::Hash,
@ -13,7 +14,7 @@ use super::{
};
use crate::launcher::ModLoader;
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
pub struct Modpack {
pub game: ModpackGame,
pub version: String,
@ -96,14 +97,14 @@ impl Modpack {
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
pub enum ModpackGame {
// TODO: Currently, the launcher does not support specifying mod loader versions, so I just
// store the loader here.
Minecraft(String, ModLoader),
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
pub struct ModpackFile {
pub path: PathBuf,
pub hashes: ModpackFileHashes,
@ -145,7 +146,8 @@ impl ModpackFile {
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum ModpackEnv {
ClientOnly,
ServerOnly,
@ -168,7 +170,7 @@ impl ModpackEnv {
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
pub struct ModpackFileHashes {
pub sha1: String,
}