Files
Unlucky-Launcher/crates/core/src/launch/request.rs
T
AskaEth bc41dfcf7d
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
Unlucky Launcher v0.0.1-alpha
Rust 原生单文件 Minecraft 启动器:CLI 完整可用(install/launch/accounts/java/diagnose/agent),
MCP server 接入外部 Agent 工具,GUI 开发中。
2026-10-31 21:54:10 +08:00

359 lines
11 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! 启动请求:命令行组装的输入模型(纯数据,无 IO,便于快照测试)。
//!
//! 与 `crate::game` / `crate::download` 的映射关系见
//! `DevDocs/SubAgentsTalk/launch-接口约定.md` §6:launch 阶段只消费本结构,
//! 由薄适配层把 game 的快照搬进来,避免 launch 对 manifest 类型产生编译期依赖。
use std::path::PathBuf;
use crate::launch::argument::ArgumentEntry;
use crate::launch::error::MissingComponent;
use crate::launch::game_version::GameVersion;
use crate::launch::natives::NativesPlan;
/// 实例信息。
#[derive(Debug, Clone, Default)]
pub struct InstanceInfo {
/// 实例/版本 id(稳定 UUID 或版本目录名)。
pub id: String,
/// 展示名(`${version_name}`)。
pub name: String,
/// 游戏版本号(分支门限用)。
pub version: GameVersion,
/// 版本类型(`release` / `snapshot`;`${version_type}`)。
pub version_type: String,
}
/// 启动器自身信息(`${launcher_name}` / `${launcher_version}`)。
#[derive(Debug, Clone, Default)]
pub struct LauncherInfo {
/// 名称。
pub name: String,
/// 版本。
pub version: String,
}
/// 选定的 Java 运行时。
#[derive(Debug, Clone, Default)]
pub struct JavaSelection {
/// `java` 可执行文件路径。
pub binary: PathBuf,
/// 主版本号(8 / 17 / 21 / 25 …)。
pub major: u32,
/// 位数(32 / 64)。
pub bits: u32,
}
impl JavaSelection {
/// 构造。
pub fn new(binary: impl Into<PathBuf>, major: u32, bits: u32) -> Self {
Self {
binary: binary.into(),
major,
bits,
}
}
/// 是否 64 位 JVM。
pub fn is_64bit(&self) -> bool {
self.bits == 64
}
}
/// 内存设置(MiB)。
#[derive(Debug, Clone, Copy, Default)]
pub struct MemoryOptions {
/// 初始堆 `-Xms`。
pub min_mb: Option<u32>,
/// 最大堆 `-Xmx`。
pub max_mb: Option<u32>,
}
/// 版本清单里的参数(`arguments.jvm` / `arguments.game` / 旧版 `minecraftArguments`)。
#[derive(Debug, Clone, Default)]
pub struct ManifestArgs {
/// 主类。
pub main_class: Option<String>,
/// 现代清单的 JVM 参数(带 rules)。
pub jvm: Vec<ArgumentEntry>,
/// 现代清单的游戏参数(带 rules)。
pub game: Vec<ArgumentEntry>,
/// 旧版清单的整串游戏参数(1.12 及更早)。
pub legacy_arguments: Option<String>,
/// 版本库表里带 LWJGL 的 Vulkan 绑定(`org.lwjgl:lwjgl-vulkan`)。
///
/// 只作「无法排序的版本」(周快照)的 `--graphicsBackend` 兜底判据与 UI 提示;
/// 可解析版本的下发门限仍是 `26.2-snapshot-2`(见
/// [`graphics_backend_allowed`](crate::launch::game_args::graphics_backend_allowed))。
pub has_vulkan_backend: bool,
}
impl ManifestArgs {
/// 是否走旧版参数模板(只有 `minecraftArguments`,没有 `arguments`)。
pub fn is_legacy(&self) -> bool {
self.jvm.is_empty() && self.legacy_arguments.is_some()
}
}
/// 目录布局。
#[derive(Debug, Clone, Default)]
pub struct LaunchDirs {
/// 运行目录(`${game_directory}`,同时是子进程的 CWD)。
///
/// D20:这个值是**隔离覆盖链的派生结果**(`game::isolation::derive_game_dir`:
/// 临时参数 > 实例 `isolation` > 全局 `instances.mode`)。launch 侧只消费、不派生,
/// 也不读配置——路径语义的真相在 `core::game`。
pub game_dir: PathBuf,
/// 资产根。
pub assets_root: PathBuf,
/// 重建后的虚拟资产目录(`${game_assets}`)。
pub game_assets: PathBuf,
/// 资产索引 id(`${assets_index_name}`)。
pub assets_index: String,
/// 原生库目录(按 Java 平台选择,`analyse/02` §4.6)。
pub natives_dir: PathBuf,
/// 库根目录。
pub library_dir: PathBuf,
/// 主 jar。
pub primary_jar: PathBuf,
}
/// 账户占位符值。
#[derive(Debug, Clone, Default)]
pub struct AuthPlaceholders {
/// 玩家名。
pub player_name: String,
/// 无连字符 UUID。
pub uuid: String,
/// 访问令牌(落盘前必须脱敏)。
pub access_token: String,
/// `msa` / `legacy`。
pub user_type: String,
/// `user_properties` JSON 串。
pub user_properties: String,
}
/// 用户自定义参数。
#[derive(Debug, Clone, Default)]
pub struct UserArgs {
/// 最高优先级 JVM 参数(不解析转义,会读 `@argfile`)。
pub override_jvm: Vec<String>,
/// 普通 JVM 参数(整体按“默认值”处理)。
pub jvm: Vec<String>,
/// 追加在最后、可覆盖前面一切的 game 参数。
pub game: Vec<String>,
/// 额外环境变量(用户自定义,最后覆盖)。
pub environment: Vec<(String, String)>,
}
/// 清单参数 rules 求值所需的特性开关。
#[derive(Debug, Clone, Copy, Default)]
pub struct FeatureSet {
/// 用户指定了分辨率(`--width/--height` 的开关)。
pub has_custom_resolution: bool,
/// 演示模式。
pub is_demo_user: bool,
/// 支持 QuickPlay(1.20+)。
pub has_quick_plays_support: bool,
}
impl FeatureSet {
/// 按特性名查询(未知特性为 `None`)。
pub fn get(&self, name: &str) -> Option<bool> {
match name {
"has_custom_resolution" => Some(self.has_custom_resolution),
"is_demo_user" => Some(self.is_demo_user),
"has_quick_plays_support" => Some(self.has_quick_plays_support),
_ => None,
}
}
}
/// 窗口分辨率。
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Resolution {
/// 宽。
pub width: u32,
/// 高。
pub height: u32,
}
/// 一键进入目标。
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum QuickPlay {
/// 直入存档。
Singleplayer {
/// 存档目录名。
world: String,
},
/// 直入服务器。
Multiplayer {
/// `host:port` 形式地址。
address: String,
},
/// 直入 Realms。
Realms {
/// Realm id。
realm_id: String,
},
}
/// SOCKS 代理。
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SocksProxy {
/// 主机。
pub host: String,
/// 端口。
pub port: u16,
/// 用户名。
pub username: Option<String>,
/// 密码。
pub password: Option<String>,
}
/// 模组加载器种类(决定 Forge 专属参数与环境变量)。
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum ModLoaderKind {
/// 原版。
#[default]
Vanilla,
/// Forge。
Forge,
/// NeoForge。
NeoForge,
/// Fabric。
Fabric,
/// Quilt。
Quilt,
/// LiteLoader。
LiteLoader,
/// OptiFine(独立安装器)。
OptiFine,
}
impl ModLoaderKind {
/// 是否使用 FML/LaunchWrapper(决定 `-Dfml.ignore*` 参数)。
pub fn is_fml_like(self) -> bool {
matches!(self, Self::Forge | Self::NeoForge | Self::LiteLoader)
}
}
/// Log4j 注入选项。
#[derive(Debug, Clone)]
pub struct Log4jOptions {
/// 是否注入日志配置(HMCL:版本 ≥1.7 即注入,探测失败按 1.7 兜底)。
pub enabled: bool,
/// 配置文件路径(`-Dlog4j.configurationFile=`)。
pub config_file: Option<PathBuf>,
/// 调试日志变体。
pub debug: bool,
}
impl Default for Log4jOptions {
fn default() -> Self {
Self {
enabled: true,
config_file: None,
debug: false,
}
}
}
/// 渲染器相关开关(`analyse/02` §4.1 #17、§4.10)。
#[derive(Debug, Clone, Default)]
pub struct RendererOptions {
/// 软件渲染(Mesa/llvmpipe)。
pub software: bool,
/// Windows 上 mesa 的 native 目录。
pub mesa_native_dir: Option<PathBuf>,
/// macOS 上的 Vulkan ICD JSON。
pub vulkan_icd: Option<PathBuf>,
}
/// JVM 自动优化选项。
#[derive(Debug, Clone)]
pub struct OptimizationOptions {
/// 是否注入自动优化参数(用户可关)。
pub enabled: bool,
/// 物理内存 MiB(决定 CodeCache 一组参数的开关)。
pub physical_memory_mb: Option<u64>,
}
impl Default for OptimizationOptions {
fn default() -> Self {
Self {
enabled: true,
physical_memory_mb: None,
}
}
}
/// 一次启动的完整输入。
#[derive(Debug, Clone, Default)]
pub struct LaunchRequest {
/// 实例信息。
pub instance: InstanceInfo,
/// 启动器信息。
pub launcher: LauncherInfo,
/// Java 运行时。
pub java: JavaSelection,
/// 内存。
pub memory: MemoryOptions,
/// 清单参数。
pub manifest: ManifestArgs,
/// 目录布局。
pub dirs: LaunchDirs,
/// natives 解压计划(`dirs.natives_dir` 为目标目录,`jars` 为分类器构件清单)。
///
/// 解压发生在**组装期**(`Launcher::dry_run`/`spawn` 的「环境准备」段),
/// 见 [`crate::launch::natives`] 与 `SubAgentsTalk/launch-natives-解压与时代分界.md`。
pub natives: NativesPlan,
/// 账户。
pub auth: AuthPlaceholders,
/// 用户参数。
pub user: UserArgs,
/// 特性开关。
pub features: FeatureSet,
/// 分辨率(`None` 表示不指定)。
pub resolution: Option<Resolution>,
/// 一键进入。
pub quick_play: Option<QuickPlay>,
/// SOCKS 代理。
pub proxy: Option<SocksProxy>,
/// 图形后端(`default` / `opengl` / `vulkan`)。
///
/// 下发门限见 [`graphics_backend_allowed`](crate::launch::game_args::graphics_backend_allowed):
/// 可解析版本 ≥ `26.2-snapshot-2`,周快照另按版本库表的能力位判。
pub graphics_backend: Option<String>,
/// 全屏。
pub fullscreen: bool,
/// 进程优先级(POSIX `nice -n`,Windows 忽略)。
pub nice: Option<i32>,
/// 命令包装器(`optirun`、`prime-run` 等)。
pub wrapper: Vec<String>,
/// `-javaagent:` 列表。
pub java_agents: Vec<String>,
/// 登录源提供的 JVM 参数(authlib-injector)。
pub auth_jvm_args: Vec<String>,
/// 登录源提供的游戏参数。
pub auth_game_args: Vec<String>,
/// 模组加载器。
pub mod_loader: ModLoaderKind,
/// Log4j 注入。
pub log4j: Log4jOptions,
/// 渲染器开关。
pub renderer: RendererOptions,
/// JVM 自动优化。
pub optimization: OptimizationOptions,
/// `-Dfile.encoding` 指定值(`COMPAT` 表示跟随系统)。
pub encoding: Option<String>,
/// 界面语言(`${language}`)。
pub language: String,
/// 已过滤为“确实存在”的 classpath(主 jar 由组装器追加到末位)。
pub classpath: Vec<PathBuf>,
/// 组件就绪检查发现的缺失项(非空则组装直接失败)。
pub missing_components: Vec<MissingComponent>,
/// 额外注入的 JVM 参数(品牌/特性钩子,`appendJvmArgs` 的替代者)。
pub extra_jvm: Vec<String>,
}