Unlucky Launcher v0.0.1-alpha
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
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 开发中。
This commit is contained in:
commit
bc41dfcf7d
517 files changed
+92844
No files matched your search
@@ -0,0 +1,358 @@
|
||||
//! 启动请求:命令行组装的输入模型(纯数据,无 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>,
|
||||
}
|
||||
Reference in new issue
Block a user