CI / fmt (rustfmt --check) (push) Canceled after 0s
CI / clippy (ubuntu-latest) (push) Canceled after 0s
CI / clippy (windows-latest) (push) Canceled after 0s
CI / test (ubuntu-latest) (push) Canceled after 0s
CI / test (windows-latest) (push) Canceled after 0s
CI / build release (ubuntu-latest) (push) Canceled after 0s
CI / build release (windows-latest) (push) Canceled after 0s
Guards / core 零 UI 守门 (push) Canceled after 0s
Guards / 文件行数 ≤400 守门 (push) Canceled after 0s
Guards / 依赖许可与来源(cargo-deny) (push) Canceled after 0s
Rust 原生单文件 Minecraft 启动器:CLI 完整可用(install/launch/accounts/java/diagnose/agent), MCP server 接入外部 Agent 工具,GUI 开发中。
107 lines
3.9 KiB
Rust
107 lines
3.9 KiB
Rust
//! MC↔Java 映射:版本 JSON 的 `javaVersion` 优先(含继承链),上限取自静态表。
|
|
|
|
use std::path::PathBuf;
|
|
|
|
use unlucky_core::game::java::mapping;
|
|
|
|
fn temp_dir(tag: &str) -> PathBuf {
|
|
use std::sync::atomic::{AtomicU64, Ordering};
|
|
static COUNTER: AtomicU64 = AtomicU64::new(0);
|
|
let nanos = std::time::SystemTime::now()
|
|
.duration_since(std::time::UNIX_EPOCH)
|
|
.map_or(0, |elapsed| elapsed.as_nanos());
|
|
let seq = COUNTER.fetch_add(1, Ordering::Relaxed);
|
|
let dir = std::env::temp_dir().join(format!(
|
|
"ull-java-{tag}-{}-{nanos}-{seq}",
|
|
std::process::id()
|
|
));
|
|
let _ = std::fs::remove_dir_all(&dir);
|
|
std::fs::create_dir_all(&dir).expect("建临时目录");
|
|
dir
|
|
}
|
|
|
|
#[test]
|
|
fn version_json_java_version_beats_the_static_table() {
|
|
let root = temp_dir("mapping");
|
|
let layout = unlucky_core::game::GameLayout::new(&root);
|
|
let write = |id: &str, json: serde_json::Value| {
|
|
let dir = root.join("versions").join(id);
|
|
std::fs::create_dir_all(&dir).expect("建版本目录");
|
|
std::fs::write(
|
|
dir.join(format!("{id}.json")),
|
|
serde_json::to_vec(&json).expect("序列化"),
|
|
)
|
|
.expect("写版本 JSON");
|
|
};
|
|
|
|
// 1.17 的清单自己说是 16(静态表也是 16,但来源必须标 manifest)。
|
|
write(
|
|
"1.17.1",
|
|
serde_json::json!({"id": "1.17.1", "javaVersion": {"component": "java-runtime-alpha", "majorVersion": 16}}),
|
|
);
|
|
let manifest = mapping::requirement_for_version(&layout, "1.17.1");
|
|
assert_eq!(manifest.minimum, 16);
|
|
assert_eq!(manifest.source.as_str(), "manifest");
|
|
|
|
// 魔改实例覆盖父版本:21 应当生效。
|
|
write("1.20.1", serde_json::json!({"id": "1.20.1"}));
|
|
write(
|
|
"1.20.1-forge",
|
|
serde_json::json!({"id": "1.20.1-forge", "inheritsFrom": "1.20.1", "javaVersion": {"majorVersion": 21}}),
|
|
);
|
|
assert_eq!(
|
|
mapping::requirement_for_version(&layout, "1.20.1-forge").minimum,
|
|
21
|
|
);
|
|
|
|
// 清单没写 javaVersion:父版本也没有 → 静态表兜底。
|
|
let table = mapping::requirement_for_version(&layout, "1.20.1");
|
|
assert_eq!(table.minimum, 17);
|
|
assert_eq!(table.source.as_str(), "table");
|
|
|
|
// 1.12.2:清单只说「最低 8」,但上限(LaunchWrapper 只能 Java 8)由静态表补上。
|
|
write(
|
|
"1.12.2",
|
|
serde_json::json!({"id": "1.12.2", "javaVersion": {"component": "jre-legacy", "majorVersion": 8}}),
|
|
);
|
|
let legacy = mapping::requirement_for_version(&layout, "1.12.2");
|
|
assert_eq!((legacy.minimum, legacy.maximum), (8, Some(8)));
|
|
assert_eq!(legacy.source.as_str(), "manifest");
|
|
assert!(
|
|
mapping::check(21, &legacy).is_some(),
|
|
"1.12.2 + Java 21 必须报不符"
|
|
);
|
|
|
|
// 版本根本没装:按 id 走静态表,不报错。
|
|
let missing = mapping::requirement_for_version(&layout, "26.3");
|
|
assert_eq!(missing.minimum, 25);
|
|
let _ = std::fs::remove_dir_all(&root);
|
|
}
|
|
|
|
#[test]
|
|
fn parent_java_version_is_inherited() {
|
|
let root = temp_dir("inherit");
|
|
let layout = unlucky_core::game::GameLayout::new(&root);
|
|
let write = |id: &str, json: serde_json::Value| {
|
|
let dir = root.join("versions").join(id);
|
|
std::fs::create_dir_all(&dir).expect("建版本目录");
|
|
std::fs::write(
|
|
dir.join(format!("{id}.json")),
|
|
serde_json::to_vec(&json).expect("序列化"),
|
|
)
|
|
.expect("写版本 JSON");
|
|
};
|
|
write(
|
|
"1.20.5",
|
|
serde_json::json!({"id": "1.20.5", "javaVersion": {"component": "java-runtime-delta", "majorVersion": 21}}),
|
|
);
|
|
write(
|
|
"1.20.5-fabric",
|
|
serde_json::json!({"id": "1.20.5-fabric", "inheritsFrom": "1.20.5"}),
|
|
);
|
|
let requirement = mapping::requirement_for_version(&layout, "1.20.5-fabric");
|
|
assert_eq!(requirement.minimum, 21);
|
|
assert_eq!(requirement.source.as_str(), "manifest");
|
|
let _ = std::fs::remove_dir_all(&root);
|
|
}
|