mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-07 11:06:11 -10:00
Keep title panorama optional during full resource preparation
This commit is contained in:
1 parent
eebf5621bf
commit
aab88753b6
3 files changed
+58
-11
No files matched your search
@@ -685,7 +685,8 @@ fn steps(
|
||||
|
||||
// The JAR holds only gray 1x1 panorama placeholders. Import the indexed
|
||||
// textures afterwards, including on reruns that just extracted the JAR again.
|
||||
panorama(repo, minecraft, run.log)?;
|
||||
// Cosmetic assets are optional when preparing from already-imported JARs.
|
||||
sounds::optional_panorama(repo, minecraft, run.log);
|
||||
|
||||
// One file each, exported again when the exporter or the jar it reads changed.
|
||||
let single = |what: &str,
|
||||
|
||||
@@ -85,6 +85,15 @@ pub fn panorama(root: &Path, minecraft: Option<&Path>, log: Log) -> Result<PathB
|
||||
copy_assets(root, minecraft, log, is_panorama, "Panorama", &PANORAMA)
|
||||
}
|
||||
|
||||
/// Full preparation can run from cached JARs without an official launcher install.
|
||||
pub(crate) fn optional_panorama(root: &Path, minecraft: Option<&Path>, log: Log) {
|
||||
if let Err(error) = panorama(root, minecraft, log) {
|
||||
log(&format!(
|
||||
"Title panorama not imported: {error}; run horizon-prepare panorama later"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
const PANORAMA: [&str; 7] = [
|
||||
"minecraft/textures/gui/title/background/panorama_0.png",
|
||||
"minecraft/textures/gui/title/background/panorama_1.png",
|
||||
@@ -138,6 +147,7 @@ fn copy_assets(
|
||||
}
|
||||
}
|
||||
let mut total: u64 = 0;
|
||||
let mut copies = Vec::with_capacity(wanted.len());
|
||||
for (name, info) in &wanted {
|
||||
let hash = info
|
||||
.get("hash")
|
||||
@@ -151,15 +161,14 @@ fn copy_assets(
|
||||
let relative = artifacts::safe_relative(name)
|
||||
.ok_or_else(|| format!("Unsafe asset name {name:?} in the asset index"))?;
|
||||
let source = launcher_object(&store, hash)?;
|
||||
artifacts::import_copy(
|
||||
&source,
|
||||
&target.join("assets").join(relative),
|
||||
hash,
|
||||
"sha1",
|
||||
"",
|
||||
)?;
|
||||
copies.push((source, target.join("assets").join(relative), hash));
|
||||
total += size;
|
||||
}
|
||||
// Check the entire set before replacing any placeholders: a missing late face
|
||||
// must not leave a mixture of real textures and gray faces in either entry point.
|
||||
for (source, destination, hash) in copies {
|
||||
artifacts::import_copy(&source, &destination, hash, "sha1", "")?;
|
||||
}
|
||||
log(&format!(
|
||||
"{label} assets ready: {} files, {:.1} MB",
|
||||
wanted.len(),
|
||||
@@ -366,6 +375,42 @@ mod tests {
|
||||
assert!(!f.root.join(".local/horizon-client/9.9/assets").exists());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn full_preparation_keeps_placeholders_when_panorama_is_unavailable() {
|
||||
for missing in ["store", "install", "last-object"] {
|
||||
let f = Fixture::new(&format!("optional-panorama-{missing}"));
|
||||
// The JARs and manifest were imported earlier; the launcher need not remain.
|
||||
artifacts::import_manifest(&Lock::read(&f.root).unwrap(), &f.minecraft).unwrap();
|
||||
let target = f.root.join(".local/horizon-client/9.9/assets");
|
||||
for name in PANORAMA {
|
||||
let path = target.join(name);
|
||||
fs::create_dir_all(path.parent().unwrap()).unwrap();
|
||||
fs::write(path, b"jar placeholder").unwrap();
|
||||
}
|
||||
match missing {
|
||||
"store" => fs::remove_dir_all(f.minecraft.join("assets")).unwrap(),
|
||||
"install" => fs::remove_dir_all(&f.minecraft).unwrap(),
|
||||
_ => fs::remove_file(f.object(f.objects.len() - 1)).unwrap(),
|
||||
}
|
||||
// The repair subcommand remains strict, even for a missing final object.
|
||||
let error = panorama(&f.root, Some(&f.minecraft), &|_| {}).unwrap_err();
|
||||
let lines = std::cell::RefCell::new(Vec::new());
|
||||
// This is the optional import step used by full preparation after extraction.
|
||||
optional_panorama(&f.root, Some(&f.minecraft), &|line| {
|
||||
lines.borrow_mut().push(line.to_string())
|
||||
});
|
||||
assert_eq!(
|
||||
*lines.borrow(),
|
||||
[format!(
|
||||
"Title panorama not imported: {error}; run horizon-prepare panorama later"
|
||||
)]
|
||||
);
|
||||
for name in PANORAMA {
|
||||
assert_eq!(fs::read(target.join(name)).unwrap(), b"jar placeholder");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_index_must_be_the_pinned_one() {
|
||||
let f = Fixture::new("index");
|
||||
|
||||
@@ -23,9 +23,10 @@ verifies it against the pinned checksums, runs vanilla's data generator and smal
|
||||
exporters against those jars, and extracts the jar's assets and data into ignored
|
||||
`.local/horizon-client/26.3/`. Sounds (about 380 MB) are copied from your
|
||||
launcher's asset store by `horizon-prepare sounds`, each file checked against the asset
|
||||
index's SHA-1. Preparation also replaces the JAR's gray 1×1 title panorama placeholders
|
||||
with the full textures from that asset store. To repair an existing classic menu background
|
||||
without rerunning the Java exporters, run `horizon-prepare panorama` (or
|
||||
index's SHA-1. Preparation also tries to replace the JAR's gray 1×1 title panorama
|
||||
placeholders with the full textures from that asset store. If the store is missing or
|
||||
incomplete, preparation logs a warning and keeps the placeholders. To import the panorama
|
||||
later without rerunning the Java exporters, run `horizon-prepare panorama` (or
|
||||
`cargo run --release -p horizon-prepare -- panorama` in a checkout). Pass
|
||||
`--minecraft-dir PATH` when using a different Minecraft installation.
|
||||
Prepared resources are private; never commit them.
|
||||
|
||||
Reference in new issue
Block a user