parent
23d5e8cc29
commit
220a2b4553
@ -0,0 +1,39 @@
|
||||
pub mod manifest;
|
||||
|
||||
pub struct MinecraftVersion {
|
||||
pub version_json: manifest::VersionJson,
|
||||
}
|
||||
|
||||
pub fn get_latest_version() -> Result<MinecraftVersion, ureq::Error> {
|
||||
let response = ureq::get("https://launchermeta.mojang.com/mc/game/version_manifest.json").call();
|
||||
let version_manifest = response.unwrap().into_string().unwrap();
|
||||
let version_manifest: manifest::VersionManifest = serde_json::from_str(&version_manifest).unwrap();
|
||||
let latest_release = &version_manifest.latest.release;
|
||||
fetch_version(latest_release)
|
||||
}
|
||||
|
||||
pub fn fetch_version(version_name: &str) -> Result<MinecraftVersion, ureq::Error> {
|
||||
let response = ureq::get("https://launchermeta.mojang.com/mc/game/version_manifest.json").call();
|
||||
let version_manifest = response.unwrap().into_string().unwrap();
|
||||
let version_manifest: manifest::VersionManifest = serde_json::from_str(&version_manifest).unwrap();
|
||||
let selected_version = version_manifest.versions.iter().find(
|
||||
|version| version.id.as_str() == version_name)
|
||||
.unwrap();
|
||||
|
||||
let response = ureq::get(&selected_version.url).call();
|
||||
let version_json = response.unwrap().into_string().unwrap();
|
||||
let version_json: manifest::VersionJson = serde_json::from_str(&version_json).unwrap();
|
||||
Ok(MinecraftVersion { version_json: version_json })
|
||||
}
|
||||
|
||||
impl MinecraftVersion {
|
||||
pub fn get_asset_index(&self) -> Result<manifest::AssetIndex, ureq::Error> {
|
||||
let response = ureq::get(&self.version_json.asset_index.url).call();
|
||||
let asset_index = response.unwrap().into_string().unwrap();
|
||||
let asset_index: manifest::AssetIndex = serde_json::from_str(&asset_index).unwrap();
|
||||
Ok(asset_index)
|
||||
}
|
||||
pub fn get_libraries_for_os(&self, os: &str) -> Vec<manifest::Library> {
|
||||
todo!("Stub; Needs filtering by os name, taking into account both the blacklist and whitelist");
|
||||
}
|
||||
}
|
@ -0,0 +1,232 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::skip_serializing_none;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct VersionManifest {
|
||||
pub latest: Latest,
|
||||
pub versions: Vec<Version>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Latest {
|
||||
pub release: String,
|
||||
pub snapshot: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Version {
|
||||
pub id: String,
|
||||
#[serde(rename = "type")]
|
||||
pub type_: String,
|
||||
pub url: String,
|
||||
pub time: String,
|
||||
#[serde(rename = "releaseTime")]
|
||||
pub release_time: String,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct AssetIndexUrl {
|
||||
pub id: String,
|
||||
pub sha1: String,
|
||||
pub size: u64,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct VersionJson {
|
||||
pub arguments: Option<Arguments>,
|
||||
#[serde(rename = "assetIndex")]
|
||||
pub asset_index: AssetIndexUrl,
|
||||
pub assets: String,
|
||||
#[serde(rename = "complianceLevel")]
|
||||
pub compliance_level: Option<u32>,
|
||||
pub downloads: Downloads,
|
||||
pub id: String,
|
||||
#[serde(rename = "javaVersion")]
|
||||
pub java_version: Option<JavaVersion>,
|
||||
pub libraries: Vec<Library>,
|
||||
pub logging: Option<Logging>,
|
||||
#[serde(rename = "mainClass")]
|
||||
pub main_class: String,
|
||||
#[serde(rename = "minimumLauncherVersion")]
|
||||
pub minimum_launcher_version: u32,
|
||||
#[serde(rename = "releaseTime")]
|
||||
pub release_time: String,
|
||||
pub time: String,
|
||||
#[serde(rename = "type")]
|
||||
pub type_: String,
|
||||
#[serde(rename = "minecraftArguments")]
|
||||
pub minecraft_arguments: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Arguments {
|
||||
pub game: Option<Vec<GameArgument>>,
|
||||
pub jvm: Option<Vec<JVMArgument>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(untagged)]
|
||||
pub enum GameArgument {
|
||||
String(String),
|
||||
Complex(GameArgumentComplex),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct GameArgumentComplex {
|
||||
pub rules: Option<Vec<Rule>>,
|
||||
pub value: ValueType,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(untagged)]
|
||||
pub enum JVMArgument {
|
||||
String(String),
|
||||
Complex(JVMArgumentComplex),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct JVMArgumentComplex {
|
||||
pub rules: Option<Vec<Rule>>,
|
||||
pub value: ValueType,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(untagged)]
|
||||
pub enum ValueType {
|
||||
String(String),
|
||||
VecString(Vec<String>),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Rule {
|
||||
pub action: String,
|
||||
pub os: Option<OS>,
|
||||
pub features: Option<HashMap<String, bool>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct OS {
|
||||
pub arch: Option<String>,
|
||||
pub name: Option<String>,
|
||||
pub version: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct AssetIndex {
|
||||
pub objects: HashMap<String, AssetObject>,
|
||||
#[serde(rename = "virtual")]
|
||||
pub virtual_: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct AssetObject {
|
||||
pub hash: String,
|
||||
pub size: u64,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Downloads {
|
||||
pub client: DownloadFile,
|
||||
#[serde(rename = "client_mappings")]
|
||||
pub client_mappings: Option<DownloadFile>,
|
||||
pub server: DownloadFile,
|
||||
#[serde(rename = "server_mappings")]
|
||||
pub server_mappings: Option<DownloadFile>,
|
||||
#[serde(rename = "windows_server")]
|
||||
pub windows_server: Option<DownloadFile>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct DownloadFile {
|
||||
pub sha1: String,
|
||||
pub size: u64,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct JavaVersion {
|
||||
pub component: String,
|
||||
#[serde(rename = "majorVersion")]
|
||||
pub major_version: u32,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Library {
|
||||
pub downloads: LibraryDownloads,
|
||||
pub name: String,
|
||||
pub rules: Option<Vec<Rule>>,
|
||||
pub extract: Option<Extract>,
|
||||
pub natives: Option<Natives>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(untagged)]
|
||||
pub enum LibraryDownloads {
|
||||
Artifact(LibraryArtifact),
|
||||
Classifiers(LibraryClassifiers),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct LibraryArtifact {
|
||||
pub artifact: LibraryFile,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct LibraryClassifiers {
|
||||
pub classifiers: Classifiers,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Classifiers {
|
||||
#[serde(rename = "natives-linux")]
|
||||
pub natives_linux: Option<LibraryFile>,
|
||||
#[serde(rename = "natives-osx")]
|
||||
pub natives_osx: Option<LibraryFile>,
|
||||
#[serde(rename = "natives-windows")]
|
||||
pub natives_windows: Option<LibraryFile>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct LibraryFile {
|
||||
pub path: String,
|
||||
pub sha1: String,
|
||||
pub size: u64,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Extract {
|
||||
pub exclude: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Natives {
|
||||
pub linux: String,
|
||||
pub osx: String,
|
||||
pub windows: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Logging {
|
||||
pub client: LoggingClient,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct LoggingClient {
|
||||
pub argument: String,
|
||||
pub file: LoggingFile,
|
||||
#[serde(rename = "type")]
|
||||
pub type_: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct LoggingFile {
|
||||
pub id: String,
|
||||
pub sha1: String,
|
||||
pub size: u64,
|
||||
pub url: String,
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
use mclaunch::manifest::*;
|
||||
|
||||
#[test]
|
||||
fn test_arguments() {
|
||||
let src = r#"
|
||||
{
|
||||
"game": [
|
||||
{
|
||||
"rules": [
|
||||
],
|
||||
"value": [
|
||||
"--quickPlayRealms",
|
||||
"${quickPlayRealms}"
|
||||
]
|
||||
}
|
||||
],
|
||||
"jvm": [
|
||||
]
|
||||
}
|
||||
"#;
|
||||
let arguments: Arguments = serde_json::from_str(src).unwrap();
|
||||
println!("{:#?}", arguments);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_basic_decode() {
|
||||
// Grab minecraft version manifest
|
||||
let response = ureq::get("https://launchermeta.mojang.com/mc/game/version_manifest.json").call();
|
||||
let version_manifest = response.unwrap().into_string().unwrap();
|
||||
// Deserialize the version manifest
|
||||
let version_manifest: VersionManifest = serde_json::from_str(&version_manifest).unwrap();
|
||||
// Print the version manifest
|
||||
println!("{:#?}", version_manifest);
|
||||
// fetch the latest release version
|
||||
let latest_release = &version_manifest.latest.release;
|
||||
// Print the latest release version
|
||||
println!("Latest release version: {}", latest_release);
|
||||
// Fetch the Version struct for the latest release version
|
||||
let latest_release_version = version_manifest.versions.iter().find(
|
||||
|version| version.id.as_str() == latest_release.as_str())
|
||||
.unwrap();
|
||||
// Print the latest release version struct
|
||||
println!("{:#?}", latest_release_version);
|
||||
|
||||
// Fetch the version manifest for the latest release version
|
||||
let response = ureq::get(&latest_release_version.url).call();
|
||||
let version_json = response.unwrap().into_string().unwrap();
|
||||
// Print the version manifest for the latest release version
|
||||
println!("{}", version_json);
|
||||
// Deserialize the version manifest for the latest release version
|
||||
let version_json: VersionJson = serde_json::from_str(&version_json).unwrap();
|
||||
// Print the version manifest for the latest release version
|
||||
println!("{:#?}", version_json);
|
||||
// Grab the asset index url
|
||||
let asset_index_url = &version_json.asset_index.url;
|
||||
// Print the asset index url
|
||||
println!("Asset index url: {}", asset_index_url);
|
||||
// Fetch the asset index
|
||||
let response = ureq::get(asset_index_url).call();
|
||||
let asset_index = response.unwrap().into_string().unwrap();
|
||||
// Print the asset index
|
||||
println!("{}", asset_index);
|
||||
// Deserialize the asset index
|
||||
let asset_index: AssetIndex = serde_json::from_str(&asset_index).unwrap();
|
||||
// Print the asset index
|
||||
println!("{:#?}", asset_index);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_164_decode() {
|
||||
// Grab minecraft version manifest
|
||||
let response = ureq::get("https://launchermeta.mojang.com/mc/game/version_manifest.json").call();
|
||||
let version_manifest = response.unwrap().into_string().unwrap();
|
||||
// Deserialize the version manifest
|
||||
let version_manifest: VersionManifest = serde_json::from_str(&version_manifest).unwrap();
|
||||
// Print the version manifest
|
||||
println!("{:#?}", version_manifest);
|
||||
// fetch the 1.6.4 version
|
||||
let version_164 = version_manifest.versions.iter().find(
|
||||
|version| version.id.as_str() == "1.6.4")
|
||||
.unwrap();
|
||||
// Print the 1.6.4 version
|
||||
println!("{:#?}", version_164);
|
||||
|
||||
// Fetch the version manifest for the 1.6.4 version
|
||||
let response = ureq::get(&version_164.url).call();
|
||||
let version_json = response.unwrap().into_string().unwrap();
|
||||
// Print the version manifest for the 1.6.4 version
|
||||
println!("{}", version_json);
|
||||
// Deserialize the version manifest for the 1.6.4 version
|
||||
let version_json: VersionJson = serde_json::from_str(&version_json).unwrap();
|
||||
// Print the version manifest for the 1.6.4 version
|
||||
println!("{:#?}", version_json);
|
||||
// Grab the asset index url
|
||||
let asset_index_url = &version_json.asset_index.url;
|
||||
// Print the asset index url
|
||||
println!("Asset index url: {}", asset_index_url);
|
||||
// Fetch the asset index
|
||||
let response = ureq::get(asset_index_url).call();
|
||||
let asset_index = response.unwrap().into_string().unwrap();
|
||||
// Print the asset index
|
||||
println!("{}", asset_index);
|
||||
// Deserialize the asset index
|
||||
let asset_index: AssetIndex = serde_json::from_str(&asset_index).unwrap();
|
||||
// Print the asset index
|
||||
println!("{:#?}", asset_index);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_latest_decode() {
|
||||
let latest = mclaunch::get_latest_version().unwrap();
|
||||
let _asset_index = latest.get_asset_index().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_164_decode_latest() {
|
||||
let version_164 = mclaunch::fetch_version("1.6.4").unwrap();
|
||||
let _asset_index = version_164.get_asset_index().unwrap();
|
||||
}
|
Loading…
Reference in new issue