feat(launch): M157 实例级启动参数(五项回落 + graphicsBackend 三态)
core: 新增 game/launch_overrides(LaunchOverrides 五项 All-Option + 三级回落 + 文本补丁校验)与 launch/overrides(拼装落位:全局 java.extra_args 进 user.jvm、实例 jvmArgs 进 override_jvm、gameArgs 进 user.game、memory 进 -Xmx、backend 进 --graphicsBackend 并复用既有版本门槛告警);实例 schema 登记 launch.* 五键。 presenter: dto/LaunchArgsView+LaunchArgsPatch,主机侧读/写与门槛判定(backend_allowed),AppCommand::SetInstanceLaunchArgs。 cli: 新命令 instances launch-args(读/写/--clear),launch 装配链消费回落值。 app-iced: 实例详情页「启动参数」区(JVM/游戏参数、内存、Java、三态后端 chips + 灰化提示 + 保存/恢复),表单状态归 App、i18n 中英文案同步。
This commit is contained in:
1 parent
d68523b02a
commit
e2021645d7
56 files changed
+3776
-607
No files matched your search
@@ -41,6 +41,11 @@ pub const ISOLATION_OVERRIDES: &[&str] = &["inherit", "isolated", "shared", "cus
|
||||
pub const ISOLATION_RESOLVED: &[&str] = &["isolated", "shared", "custom"];
|
||||
/// 实例可覆盖的设置键(enum 白名单,拼错即校验失败而不是静默不生效)。
|
||||
pub const OVERRIDE_KEYS: &[&str] = &["maxMemory", "javaType", "runningDirectory"];
|
||||
/// `launch.graphicsBackend` 的允许值(`default` = 不下发 `--graphicsBackend`)。
|
||||
///
|
||||
/// 与 `crate::game::launch_overrides::GraphicsBackend::IDS` 必须是同一份集合——setting 层
|
||||
/// 不依赖 game 层(分层纪律),一致性由本文件的 `graphics_backends_match_the_game_layer` 固定。
|
||||
pub const GRAPHICS_BACKENDS: &[&str] = &["default", "opengl", "vulkan"];
|
||||
|
||||
/// profiles.json 当前 schema 版本。
|
||||
#[must_use]
|
||||
@@ -111,6 +116,42 @@ pub fn instance_schema() -> SettingSchema {
|
||||
AiPolicy::locked(),
|
||||
"该实例覆盖了全局哪些设置键(enum 白名单,拼错即校验失败)",
|
||||
))
|
||||
// M157:实例级启动参数(`launch` 段,五项全可选、逐项回落到全局)。
|
||||
// 作者是 `game::install::instance::InstanceConfig`(serde 形状与这些路径逐键对应),
|
||||
// 回落规则与生效值在 `game::launch_overrides`,拼装消费在 `launch::overrides`。
|
||||
.with(SettingSpec::text(
|
||||
"launch.jvmArgs",
|
||||
"",
|
||||
1024,
|
||||
AiPolicy::sensitive(),
|
||||
"实例级 JVM 参数(空白分隔、支持引号);留空 = 只用全局 java.extra_args(两者叠加,实例优先)",
|
||||
))
|
||||
.with(SettingSpec::text(
|
||||
"launch.gameArgs",
|
||||
"",
|
||||
1024,
|
||||
AiPolicy::audited(),
|
||||
"实例级游戏参数(追加在命令行末段,可覆盖前面一切游戏参数);留空 = 不追加",
|
||||
))
|
||||
.with(SettingSpec::int(
|
||||
"launch.memoryMb",
|
||||
0,
|
||||
(0, 65536),
|
||||
AiPolicy::sensitive(),
|
||||
"实例级最大堆(MiB);0/缺键 = 跟随全局 java.default_memory_mb(有效区间 256~65536)",
|
||||
))
|
||||
.with(SettingSpec::path(
|
||||
"launch.javaPath",
|
||||
AiPolicy::sensitive(),
|
||||
"实例级 Java 可执行文件;留空 = 跟随全局 java.selected_path 再退到自动挑(托管 > JAVA_HOME > PATH)",
|
||||
))
|
||||
.with(SettingSpec::enumeration(
|
||||
"launch.graphicsBackend",
|
||||
"default",
|
||||
GRAPHICS_BACKENDS,
|
||||
AiPolicy::audited(),
|
||||
"图形后端:default(不下发)/ opengl / vulkan。只对 MC 26.2-snapshot-2+ 下发,老版本会被门槛拦下并给出诊断告警",
|
||||
))
|
||||
.with(SettingSpec::text(
|
||||
"lastModeChange.at",
|
||||
"",
|
||||
@@ -153,3 +194,58 @@ pub fn instance_schema() -> SettingSchema {
|
||||
"该次切换的提示是否已展示过(保证切换后首次启动只提示一次)",
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
/// M157:图形后端词表**只有一份真相源**(`game::launch_overrides::GraphicsBackend`),
|
||||
/// setting 层是它的白名单视图——两边脱节就是「写得进、读不出」或「UI 三态少一档」。
|
||||
#[test]
|
||||
fn graphics_backends_match_the_game_layer() {
|
||||
use crate::game::launch_overrides::GraphicsBackend;
|
||||
let mut setting: Vec<&str> = GRAPHICS_BACKENDS.to_vec();
|
||||
let mut game: Vec<&str> = GraphicsBackend::IDS.to_vec();
|
||||
setting.sort_unstable();
|
||||
game.sort_unstable();
|
||||
assert_eq!(setting, game, "setting 白名单与 game 层词表脱节了");
|
||||
for id in GRAPHICS_BACKENDS {
|
||||
assert!(
|
||||
GraphicsBackend::parse(id).is_some(),
|
||||
"`{id}` 在 game 层解析不出来"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 五项键真的进了实例 schema 白名单(且 `default` 之外的后端值被拒)。
|
||||
#[test]
|
||||
fn launch_section_keys_are_registered() {
|
||||
let schema = instance_schema();
|
||||
assert!(schema
|
||||
.validate("launch.jvmArgs", &serde_json::json!("-XX:+UseG1GC"))
|
||||
.is_ok());
|
||||
assert!(schema
|
||||
.validate("launch.gameArgs", &serde_json::json!("--fullscreen"))
|
||||
.is_ok());
|
||||
assert!(schema
|
||||
.validate("launch.memoryMb", &serde_json::json!(4096))
|
||||
.is_ok());
|
||||
assert!(schema
|
||||
.validate(
|
||||
"launch.javaPath",
|
||||
&serde_json::json!("D:/jdk21/bin/java.exe")
|
||||
)
|
||||
.is_ok());
|
||||
assert!(schema
|
||||
.validate("launch.graphicsBackend", &serde_json::json!("vulkan"))
|
||||
.is_ok());
|
||||
// 非法后端值:白名单外必须报错(手改文件绕不过校验)。
|
||||
assert!(schema
|
||||
.validate("launch.graphicsBackend", &serde_json::json!("vulkan2"))
|
||||
.is_err());
|
||||
// 越界内存:schema 层也拦。
|
||||
assert!(schema
|
||||
.validate("launch.memoryMb", &serde_json::json!(1_000_000))
|
||||
.is_err());
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user