Skip to content

Commit

Permalink
Fix crash when MC updates (#14)
Browse files Browse the repository at this point in the history
* Fix crash when MC updates

* Fix fabric ordering + add neoforge support

* run clippy

* run clippy
  • Loading branch information
Geometrically committed Nov 9, 2023
1 parent b1ca2cc commit 6fe1fa3
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 43 deletions.
19 changes: 18 additions & 1 deletion daedalus/src/modded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::minecraft::{
Argument, ArgumentType, Library, VersionInfo, VersionType,
};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use serde::{Deserialize, Deserializer, Serialize};
use std::collections::HashMap;

#[cfg(feature = "bincode")]
Expand Down Expand Up @@ -32,6 +32,21 @@ pub struct SidedDataEntry {
pub server: String,
}

fn deserialize_date<'de, D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;

DateTime::parse_from_rfc3339(&s)
.map(|dt| dt.with_timezone(&Utc))
.or_else(|_| {
DateTime::parse_from_str(&s, "%Y-%m-%dT%H:%M:%S%.f")
.map(|dt| dt.with_timezone(&Utc))
})
.map_err(serde::de::Error::custom)
}

#[cfg_attr(feature = "bincode", derive(Encode, Decode))]
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
Expand All @@ -43,9 +58,11 @@ pub struct PartialVersionInfo {
pub inherits_from: String,
/// The time that the version was released
#[cfg_attr(feature = "bincode", bincode(with_serde))]
#[serde(deserialize_with = "deserialize_date")]
pub release_time: DateTime<Utc>,
/// The latest time a file in this version was updated
#[cfg_attr(feature = "bincode", bincode(with_serde))]
#[serde(deserialize_with = "deserialize_date")]
pub time: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
/// The classpath to the main class to launch the game
Expand Down
5 changes: 1 addition & 4 deletions daedalus_client/src/fabric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub async fn retrieve_data(
uploaded_files: &mut Vec<String>,
semaphore: Arc<Semaphore>,
) -> Result<(), Error> {
let mut list = fetch_fabric_versions(None, semaphore.clone()).await?;
let list = fetch_fabric_versions(None, semaphore.clone()).await?;
let old_manifest = daedalus::modded::fetch_manifest(&format_url(&format!(
"fabric/v{}/manifest.json",
daedalus::modded::CURRENT_FABRIC_FORMAT_VERSION,
Expand Down Expand Up @@ -51,9 +51,6 @@ pub async fn retrieve_data(
))
}
}

list.loader
.retain(|x| loaders.iter().any(|val| val.1 == x.version))
}

const DUMMY_GAME_VERSION: &str = "1.19.4-rc2";
Expand Down
39 changes: 30 additions & 9 deletions daedalus_client/src/minecraft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,18 +141,39 @@ pub async fn retrieve_data(
let mut cloned_manifest =
cloned_manifest_mutex.lock().await;

let position = cloned_manifest
if let Some(position) = cloned_manifest
.versions
.iter()
.position(|x| version.id == x.id)
.unwrap();
cloned_manifest.versions[position].url =
format_url(&version_path);
cloned_manifest.versions[position].assets_index_sha1 =
Some(version_info.asset_index.sha1.clone());
cloned_manifest.versions[position].assets_index_url =
Some(format_url(&assets_path));
cloned_manifest.versions[position].sha1 = version_info_hash;
{
cloned_manifest.versions[position].url =
format_url(&version_path);
cloned_manifest.versions[position].assets_index_sha1 =
Some(version_info.asset_index.sha1.clone());
cloned_manifest.versions[position].assets_index_url =
Some(format_url(&assets_path));
cloned_manifest.versions[position].sha1 =
version_info_hash;
} else {
cloned_manifest.versions.insert(
0,
daedalus::minecraft::Version {
id: version_info.id.clone(),
type_: version_info.type_.clone(),
url: format_url(&version_path),
time: version_info.time,
release_time: version_info.release_time,
sha1: version_info_hash,
compliance_level: 1,
assets_index_url: Some(
version_info.asset_index.sha1.clone(),
),
assets_index_sha1: Some(
version_info.asset_index.sha1.clone(),
),
},
)
}
}

let mut download_assets = false;
Expand Down
75 changes: 50 additions & 25 deletions daedalus_client/src/neo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub async fn retrieve_data(
uploaded_files: &mut Vec<String>,
semaphore: Arc<Semaphore>,
) -> Result<(), Error> {
let maven_metadata = fetch_maven_metadata(None, semaphore.clone()).await?;
let maven_metadata = fetch_maven_metadata(semaphore.clone()).await?;
let old_manifest = daedalus::modded::fetch_manifest(&format_url(&format!(
"neo/v{}/manifest.json",
daedalus::modded::CURRENT_NEOFORGE_FORMAT_VERSION,
Expand All @@ -42,18 +42,18 @@ pub async fn retrieve_data(
for (minecraft_version, loader_versions) in maven_metadata.clone() {
let mut loaders = Vec::new();

for (full, loader_version) in loader_versions {
for (full, loader_version, new_forge) in loader_versions {
let version = Version::parse(&loader_version)?;

loaders.push((full, version))
loaders.push((full, version, new_forge.to_string()))
}

if !loaders.is_empty() {
version_futures.push(async {
let mut loaders_versions = Vec::new();

{
let loaders_futures = loaders.into_iter().map(|(loader_version_full, _)| async {
let loaders_futures = loaders.into_iter().map(|(loader_version_full, _, new_forge)| async {
let versions_mutex = Arc::clone(&old_versions);
let visited_assets = Arc::clone(&visited_assets_mutex);
let uploaded_files_mutex = Arc::clone(&uploaded_files_mutex);
Expand All @@ -72,13 +72,13 @@ pub async fn retrieve_data(
}

info!("Forge - Installer Start {}", loader_version_full.clone());
let bytes = download_file(&format!("https://maven.neoforged.net/net/neoforged/forge/{0}/forge-{0}-installer.jar", loader_version_full), None, semaphore.clone()).await?;
let bytes = download_file(&format!("https://maven.neoforged.net/net/neoforged/{1}/{0}/{1}-{0}-installer.jar", loader_version_full, if &*new_forge == "true" { "neoforge" } else { "forge" }), None, semaphore.clone()).await?;

let reader = std::io::Cursor::new(bytes);

if let Ok(archive) = zip::ZipArchive::new(reader) {
let mut archive_clone = archive.clone();
let mut profile = tokio::task::spawn_blocking(move || {
let mut profile = tokio::task::spawn_blocking(move || {
let mut install_profile = archive_clone.by_name("install_profile.json")?;

let mut contents = String::new();
Expand Down Expand Up @@ -404,8 +404,10 @@ pub async fn retrieve_data(
Ok(())
}

const DEFAULT_MAVEN_METADATA_URL: &str =
const DEFAULT_MAVEN_METADATA_URL_1: &str =
"https://maven.neoforged.net/net/neoforged/forge/maven-metadata.xml";
const DEFAULT_MAVEN_METADATA_URL_2: &str =
"https://maven.neoforged.net/net/neoforged/neoforge/maven-metadata.xml";

#[derive(Debug, Deserialize)]
struct Metadata {
Expand All @@ -423,32 +425,55 @@ struct Versions {
}

pub async fn fetch_maven_metadata(
url: Option<&str>,
semaphore: Arc<Semaphore>,
) -> Result<HashMap<String, Vec<(String, String)>>, Error> {
let values = serde_xml_rs::from_str::<Metadata>(
&String::from_utf8(
download_file(
url.unwrap_or(DEFAULT_MAVEN_METADATA_URL),
None,
semaphore,
) -> Result<HashMap<String, Vec<(String, String, bool)>>, Error> {
async fn fetch_values(
url: &str,
semaphore: Arc<Semaphore>,
) -> Result<Metadata, Error> {
Ok(serde_xml_rs::from_str(
&String::from_utf8(
download_file(url, None, semaphore).await?.to_vec(),
)
.await?
.to_vec(),
)
.unwrap_or_default(),
)?;
.unwrap_or_default(),
)?)
}

let forge_values =
fetch_values(DEFAULT_MAVEN_METADATA_URL_1, semaphore.clone()).await?;
let neo_values =
fetch_values(DEFAULT_MAVEN_METADATA_URL_2, semaphore).await?;

let mut map: HashMap<String, Vec<(String, String)>> = HashMap::new();
let mut map: HashMap<String, Vec<(String, String, bool)>> = HashMap::new();

for value in values.versioning.versions.version {
for value in forge_values.versioning.versions.version {
let original = value.clone();

let parts: Vec<&str> = value.split('-').collect();
if parts.len() == 2 {
map.entry(parts[0].to_string())
.or_default()
.push((original, parts[1].to_string()));
map.entry(parts[0].to_string()).or_default().push((
original,
parts[1].to_string(),
false,
));
}
}

for value in neo_values.versioning.versions.version {
let original = value.clone();

let mut parts = value.split('.');

if let Some(major) = parts.next() {
if let Some(minor) = parts.next() {
let game_version = format!("1.{}.{}", major, minor);

map.entry(game_version.clone()).or_default().push((
original.clone(),
format!("{}-{}", game_version, original),
true,
));
}
}
}

Expand Down
5 changes: 1 addition & 4 deletions daedalus_client/src/quilt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub async fn retrieve_data(
uploaded_files: &mut Vec<String>,
semaphore: Arc<Semaphore>,
) -> Result<(), Error> {
let mut list = fetch_quilt_versions(None, semaphore.clone()).await?;
let list = fetch_quilt_versions(None, semaphore.clone()).await?;
let old_manifest = daedalus::modded::fetch_manifest(&format_url(&format!(
"quilt/v{}/manifest.json",
daedalus::modded::CURRENT_QUILT_FORMAT_VERSION,
Expand Down Expand Up @@ -51,9 +51,6 @@ pub async fn retrieve_data(
))
}
}

list.loader
.retain(|x| loaders.iter().any(|val| val.1 == x.version))
}

const DUMMY_GAME_VERSION: &str = "1.19.4-rc2";
Expand Down

0 comments on commit 6fe1fa3

Please sign in to comment.