You've already forked AstralRinth
forked from didirus/AstralRinth
Legacy Forge Support
This commit is contained in:
@@ -3,6 +3,13 @@ name = "daedalus"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Jai A <jaiagr+gpg@pm.me>"]
|
authors = ["Jai A <jaiagr+gpg@pm.me>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
license = "MIT"
|
||||||
|
description = "Utilities for querying and parsing Minecraft metadata"
|
||||||
|
repository = "https://github.com/modrinth/daedalus/"
|
||||||
|
include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE"]
|
||||||
|
keywords = ["minecraft", "launcher"]
|
||||||
|
categories = ["game-development", "api-bindings"]
|
||||||
|
readme = "README.md"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
@@ -14,4 +21,4 @@ chrono = { version = "0.4", features = ["serde"] }
|
|||||||
bytes = "1"
|
bytes = "1"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
sha1 = { version = "0.6.0", features = ["std"]}
|
sha1 = { version = "0.6.0", features = ["std"]}
|
||||||
|
|||||||
6
daedalus/README.md
Normal file
6
daedalus/README.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Daedalus
|
||||||
|
|
||||||
|
Daedalus (the rust library) is a library providing model structs and methods for requesting and parsing things
|
||||||
|
from Minecraft and other mod loaders meta APIs.
|
||||||
|
|
||||||
|
This is a work in progress!
|
||||||
@@ -20,7 +20,7 @@ pub struct PartialVersionInfo {
|
|||||||
/// The latest time a file in this version was updated
|
/// The latest time a file in this version was updated
|
||||||
pub time: DateTime<Utc>,
|
pub time: DateTime<Utc>,
|
||||||
/// The classpath to the main class to launch the game
|
/// The classpath to the main class to launch the game
|
||||||
pub main_class: String,
|
pub main_class: Option<String>,
|
||||||
/// Arguments passed to the game or JVM
|
/// Arguments passed to the game or JVM
|
||||||
pub arguments: Option<HashMap<ArgumentType, Vec<Argument>>>,
|
pub arguments: Option<HashMap<ArgumentType, Vec<Argument>>>,
|
||||||
/// Libraries that the version depends on
|
/// Libraries that the version depends on
|
||||||
@@ -51,7 +51,11 @@ pub fn merge_partial_version(partial: PartialVersionInfo, merge: VersionInfo) ->
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(merge.libraries)
|
.chain(merge.libraries)
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
main_class: partial.main_class,
|
main_class: if let Some(main_class) = partial.main_class {
|
||||||
|
main_class
|
||||||
|
} else {
|
||||||
|
merge.main_class
|
||||||
|
},
|
||||||
minecraft_arguments: merge.minecraft_arguments,
|
minecraft_arguments: merge.minecraft_arguments,
|
||||||
minimum_launcher_version: merge.minimum_launcher_version,
|
minimum_launcher_version: merge.minimum_launcher_version,
|
||||||
release_time: partial.release_time,
|
release_time: partial.release_time,
|
||||||
|
|||||||
21
daedalus/src/forge.rs
Normal file
21
daedalus/src/forge.rs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
use crate::{download_file, Error};
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
/// The latest version of the format the model structs deserialize to
|
||||||
|
pub const CURRENT_FORMAT_VERSION: usize = 0;
|
||||||
|
|
||||||
|
const DEFAULT_MAVEN_METADATA_URL: &str =
|
||||||
|
"https://files.minecraftforge.net/net/minecraftforge/forge/maven-metadata.json";
|
||||||
|
|
||||||
|
/// Fetches the forge maven metadata from the specified URL. If no URL is specified, the default is used.
|
||||||
|
/// Returns a hashmap specifying the versions of the forge mod loader
|
||||||
|
/// The hashmap key is a Minecraft version, and the value is the loader versions that work on
|
||||||
|
/// the specified Minecraft version
|
||||||
|
pub async fn fetch_maven_metadata(
|
||||||
|
url: Option<&str>,
|
||||||
|
) -> Result<HashMap<String, Vec<String>>, Error> {
|
||||||
|
Ok(serde_json::from_slice(
|
||||||
|
&download_file(url.unwrap_or(DEFAULT_MAVEN_METADATA_URL), None).await?,
|
||||||
|
)?)
|
||||||
|
}
|
||||||
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
/// Models and methods for fetching metadata for the Fabric mod loader
|
/// Models and methods for fetching metadata for the Fabric mod loader
|
||||||
pub mod fabric;
|
pub mod fabric;
|
||||||
|
/// Models and methods for fetching metadata for the Forge mod loader
|
||||||
|
pub mod forge;
|
||||||
/// Models and methods for fetching metadata for Minecraft
|
/// Models and methods for fetching metadata for Minecraft
|
||||||
pub mod minecraft;
|
pub mod minecraft;
|
||||||
|
|
||||||
@@ -56,18 +58,41 @@ pub fn get_path_from_artifact(artifact: &str) -> Result<String, Error> {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(format!(
|
Ok(format!(
|
||||||
"{}/{}/{}-{}.jar",
|
"{}/{}/{}/{}-{}.jar",
|
||||||
package.replace(".", "/"),
|
package.replace(".", "/"),
|
||||||
|
name,
|
||||||
version,
|
version,
|
||||||
name,
|
name,
|
||||||
version
|
version
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Downloads a file from specified mirrors
|
||||||
|
pub async fn download_file_mirrors(
|
||||||
|
base: &str,
|
||||||
|
mirrors: &[&str],
|
||||||
|
sha1: Option<&str>,
|
||||||
|
) -> Result<bytes::Bytes, Error> {
|
||||||
|
if mirrors.is_empty() {
|
||||||
|
return Err(Error::ParseError("No mirrors provided!".to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (index, mirror) in mirrors.iter().enumerate() {
|
||||||
|
let result = download_file(&*format!("{}{}", mirror, base), sha1).await;
|
||||||
|
|
||||||
|
if result.is_ok() || (result.is_err() && index == (mirrors.len() - 1)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
|
||||||
/// Downloads a file with retry and checksum functionality
|
/// Downloads a file with retry and checksum functionality
|
||||||
pub async fn download_file(url: &str, sha1: Option<&str>) -> Result<bytes::Bytes, Error> {
|
pub async fn download_file(url: &str, sha1: Option<&str>) -> Result<bytes::Bytes, Error> {
|
||||||
let client = reqwest::Client::builder()
|
let client = reqwest::Client::builder()
|
||||||
.tcp_keepalive(Some(std::time::Duration::from_secs(10)))
|
.tcp_keepalive(Some(std::time::Duration::from_secs(10)))
|
||||||
|
.timeout(std::time::Duration::from_secs(30))
|
||||||
.build()
|
.build()
|
||||||
.map_err(|err| Error::FetchError {
|
.map_err(|err| Error::FetchError {
|
||||||
inner: err,
|
inner: err,
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ pub struct LatestVersion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
/// Data of all game versions of Minecrafat
|
/// Data of all game versions of Minecraft
|
||||||
pub struct VersionManifest {
|
pub struct VersionManifest {
|
||||||
/// A struct containing the latest snapshot and release of the game
|
/// A struct containing the latest snapshot and release of the game
|
||||||
pub latest: LatestVersion,
|
pub latest: LatestVersion,
|
||||||
@@ -154,7 +154,7 @@ pub struct LibraryDownloads {
|
|||||||
pub classifiers: Option<HashMap<String, LibraryDownload>>,
|
pub classifiers: Option<HashMap<String, LibraryDownload>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
/// The action a rule can follow
|
/// The action a rule can follow
|
||||||
pub enum RuleAction {
|
pub enum RuleAction {
|
||||||
@@ -164,7 +164,7 @@ pub enum RuleAction {
|
|||||||
Disallow,
|
Disallow,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Hash)]
|
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Hash, Clone)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
/// An enum representing the different types of operating systems
|
/// An enum representing the different types of operating systems
|
||||||
pub enum Os {
|
pub enum Os {
|
||||||
@@ -178,7 +178,7 @@ pub enum Os {
|
|||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
/// A rule which depends on what OS the user is on
|
/// A rule which depends on what OS the user is on
|
||||||
pub struct OsRule {
|
pub struct OsRule {
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
@@ -192,7 +192,7 @@ pub struct OsRule {
|
|||||||
pub arch: Option<String>,
|
pub arch: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
/// A rule which depends on the toggled features of the launcher
|
/// A rule which depends on the toggled features of the launcher
|
||||||
pub struct FeatureRule {
|
pub struct FeatureRule {
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
@@ -203,7 +203,7 @@ pub struct FeatureRule {
|
|||||||
pub has_demo_resolution: Option<bool>,
|
pub has_demo_resolution: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
/// A rule deciding whether a file is downloaded, an argument is used, etc.
|
/// A rule deciding whether a file is downloaded, an argument is used, etc.
|
||||||
pub struct Rule {
|
pub struct Rule {
|
||||||
/// The action the rule takes
|
/// The action the rule takes
|
||||||
@@ -244,9 +244,12 @@ pub struct Library {
|
|||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
/// Rules deciding whether the library should be downloaded or not
|
/// Rules deciding whether the library should be downloaded or not
|
||||||
pub rules: Option<Vec<Rule>>,
|
pub rules: Option<Vec<Rule>>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
/// SHA1 Checksums for validating the library's integrity. Only present for forge libraries
|
||||||
|
pub checksums: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
/// A container for an argument or multiple arguments
|
/// A container for an argument or multiple arguments
|
||||||
pub enum ArgumentValue {
|
pub enum ArgumentValue {
|
||||||
@@ -256,7 +259,7 @@ pub enum ArgumentValue {
|
|||||||
Many(Vec<String>),
|
Many(Vec<String>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
/// A command line argument passed to a program
|
/// A command line argument passed to a program
|
||||||
pub enum Argument {
|
pub enum Argument {
|
||||||
@@ -271,7 +274,7 @@ pub enum Argument {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Hash)]
|
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Hash, Clone, Copy)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
/// The type of argument
|
/// The type of argument
|
||||||
pub enum ArgumentType {
|
pub enum ArgumentType {
|
||||||
|
|||||||
0
daedalus_client/src/forge.rs
Normal file
0
daedalus_client/src/forge.rs
Normal file
Reference in New Issue
Block a user