diff --git a/PCL.Core/App/Localization/Languages/en-US.xaml b/PCL.Core/App/Localization/Languages/en-US.xaml index 9b8708be9..3052c3d46 100644 --- a/PCL.Core/App/Localization/Languages/en-US.xaml +++ b/PCL.Core/App/Localization/Languages/en-US.xaml @@ -3551,4 +3551,249 @@ Minecraft window loaded: {0} ({1}) Minecraft window maximized: {0} - \ No newline at end of file + + + + en-US + English (US) + Launch + Download + Settings + Tools + Download + Version details + Install to current instance + Choose download location + Please select a Minecraft instance first + None + UVMC Exclusive + Language + Language + Display language + Follow system ({0}) + Regional format + Follow system regional format + Follow UI language + Multi-language support is currently limited to certain new interfaces. Others will be updated in upcoming migrations. To ensure work efficiency and convenience, only "English (US)" and "简体中文(中国大陆)" are guaranteed to be partially available during the migration process. Other languages will be opened up to the community for translation contributions on the translation platform once the future migration work is fully completed. + Language settings updated + Sky Blue + LTCat Blue + Crash Blue + HMCL + Window title + {name} | Player: {user} | Logged in as {login} + Customize the game window title. Leave it blank to keep the default. The following alternate tags are supported: · {user}: Username · {login}: Login method · {name}: Instance name · {date}, {time}: System time · {version}: Vanilla game version Note: If your instance has the Modern UI mod installed, this setting will not take effect. + Launcher visibility + Close immediately after game starts + Hide after game starts, close automatically after game exits + Hide after game starts, reopen after game exits + Minimize after game starts + Keep unchanged after game starts + If the launcher is closed immediately after the game starts, features such as crash detection and changing the game title will be unavailable. To keep these features, you can choose to hide the launcher after the game starts and close it automatically after the game exits. + Reminder + Continue + Process priority + Realtime (runs the game at the highest priority; use with caution, may severely impact system performance) + Very high (use with caution, may severely impact other programs) + High (prioritizes game performance, but may cause other programs to lag) + Normal (balanced) + Low (prioritizes other programs, but may cause the game to lag; suitable for running in the background) + Window size + Note: If your instance has the Modern UI mod installed, this setting will not take effect + Fullscreen + Same as launcher size + Custom size + Some versions such as Forge 1.12.2 have a bug that causes the height setting to not take effect + Maximized + Add + Loading Java list... + Auto select + Java auto mode: automatically selects the appropriate Java based on game requirements. + This Java is unavailable. Please refresh the list. + Please enable this Java before selecting it as default. + Please deselect this Java as default before disabling it. + Details + Java information + Type: {0} Version: {1} Architecture: {2} ({3}) Vendor: {4} Location: {5} + Disable this Java + Enable this Java + Select Java program + Java program (java.exe)|java.exe + This Java already exists, so it does not need to be added again... + Java added! + Failed to add Java to the list. + Failed to change Java enabled state + Default instance isolation + All instances use the same profile. Saves, mods, resource packs, and other files are shared. If multiple instances with mods installed are present, this may cause mod conflicts. + When installing a new instance, the isolation option for the new instance will be automatically set accordingly. To adjust the isolation policy for an existing instance, please go to instance settings. + Isolate instances with mod support + Isolate instances with mod support like Forge and Fabric to avoid mod conflicts, while other instances like Vanilla are not isolated. + Isolate non-releases + Isolate snapshots, pre-releases, old versions, and April Fools' versions from other instances. + Isolate instances with mod support and non-releases + Isolate all instances + Saves, mods, resource packs, and other files are not shared between instances. Saves will not be shared between Vanilla instances either, so this is generally not recommended. + The default policy only applies to newly installed instances. Existing instances' isolation policy needs to be adjusted in their settings. + Custom text + This text will be displayed in the title screen and the F3 debug screen. + Microsoft login method + The Web Account Manager has a simpler Microsoft login flow, while the Device Code Flow allows you to authenticate on any device with a web browser. If you encounter issues with the Web Account Manager, try using the Device Code Flow. If you are temporarily logging in on a public computer, Device Code Flow is recommended. Due to issues with some dependencies, this option is temporarily forced to Device Code Flow. + Web Account Manager (temporarily forced to Device Code Flow) + Device Code Flow + IP protocol preference + Set the Minecraft IP protocol preference through JVM arguments. In general, IPv4 preferred is recommended to ensure that the PCL CE lobby works properly. If you need manual IPv6 networking, you can choose another option. IPv4 preferred: -Djava.net.preferIPv4Stack=true Default: no extra arguments IPv6 preferred: -Djava.net.preferIPv6Stack=true + IPv4 preferred + Java default + IPv6 preferred + Unlimited + Log operations + Export log + Export all logs + Open log folder + Clear historical logs + All logs + {0} (current) + Temporarily stored logs ({0}) + Temporarily stored logs that have not been output + Export log file + PCL CE log archive|*.zip + Log saved successfully! + Failed to save log + Do you want to delete all historical logs? + Clear historical logs + Log files cleaned successfully! + Select save location + PCL config file (*.json)|*.json + Settings exported successfully! + Select config file + Settings imported successfully! Please restart PCL to apply them... + Restart + Follow global settings + Follow global settings + Instance isolation + Enabled + Saves, mods, and other files are kept separate from other instances, without interfering with each other. This prevents cross-instance save sharing, but can help avoid mod conflicts. + Share saves, mods, and other files with instances that have isolation disabled. If multiple instances with mods are present, mod conflicts may cause crashes. + Customize the game window title. Leave empty to follow the global setting. The following replacement tokens are supported: · {user}: Player name · {login}: Player login method · {name}: Game instance name · {date}, {time}: Current system time · {version}: Game vanilla version Note: If your instance uses the Modern UI mod, this setting will be ineffective. + Default window title + Whether the game window title should keep the default. + This info is displayed at the bottom-left of the game's main screen and the top-left of the F3 debug screen. Leave empty to follow the global setting. + Game Java + If Java is placed in the game or PCL folder, PCL will prefer selecting it during auto-detection. + Loading… + Auth server address automatically formatted! + Confirm setting override + Your third-party login settings will be overridden with LittleSkin login. Do not proceed unless you are the server owner, or the server owner has instructed you to do so. Are you sure you want to override the current settings? + Continue + LittleSkin login + Confirm login method lock + You are about to lock the login method for this instance. Once locked, the login method requirement cannot be changed, and the game must be launched using the specified login method. This feature may help some server owners. Continue? + Follow global settings + Auto-select + Select Java in launcher directory + Select Java in launcher directory (current path is invalid) + Java in launcher directory | {0} + Relative path: {0} Resolved path: {1} + Invalid path: {0} Click this item to re-select a valid Java + Select a Java path relative to the instance directory + Path: {0} Version: {1} Source: {2} + Path is out of allowed range. Please select a file within or under the launcher directory. + Failed to load list, please retry + No available Java runtime detected + Please manually specify a Java path in settings, or click "Scan" to re-detect + After changing instance isolation, you may need to manually migrate save files, mods, and other files to the new game folder. If you find your saves are missing after the change, reverting this setting will restore them. If you don't know how to migrate saves, it is not recommended to change this setting! + This option changes the game log level to the minimum, which may consume substantial disk space and potentially affect game performance. It may also pose some security risks. Do not change this option if you don't know what you're doing! Are you sure you want to continue? + This instance cannot install mods + You need to install a mod loader such as Forge, Fabric, etc. to use mods. Please go to the download page to install one. If you have already installed a mod loader, you may have selected the wrong instance. Please switch to the correct instance. + Go to the download page + Select an instance + Config file is invalid or empty! + Modpack export config (*.txt)|*.txt + Whether to bundle the stable version of PCL so players without a launcher can install the modpack. + Whether to bundle PCL custom content, such as feature toggle settings, homepage, background music and images, etc. + Whether to place Mods, resource packs, and shader packs directly into the modpack so they don't need to be downloaded during import. + Only consider this when you cannot reliably connect to CurseForge or Modrinth. + Redistribution may violate usage terms. Please avoid publicly distributing modpacks with bundled resource files! + If you plan to upload to Modrinth, enabling this will generate fully Modrinth-compliant modpack files. + Due to Modrinth requirements, resources only available from CurseForge cannot be downloaded online and will be bundled directly. + This option conflicts with IncludeLauncher, IncludeLauncherCustom, and DontCheckHostedAssets. + Storage location for the exported file. + If set, the file will be placed directly at this path during export without prompting for a location. + If IncludeLauncher is True, it should end with .zip; if False, it should end with .mrpack. + Modify the rules below to control the content to be exported. + Prefix with ! to invert. You can use *, ?, [] wildcards. Later lines override earlier ones. + Excluded files + If you want to automatically place additional files in the root of the archive, write their paths below. + Must be absolute paths. In each line, ending with \\ indicates a folder; not ending with \\ indicates a file. + (Shader config) + Folder specified in config not found: {0} + File specified in config not found: {0} + Sorry, PCL could not determine the cause of the crash. + Sorry, your game ran into some issues... If you need help, please send the crash report file instead of a photo or screenshot of this window. + Additionally, + You can view the crash report to learn more about how the crash happened. + If you need help, please send the crash report file instead of a photo or screenshot of this window. + Additionally, you are using an old version of PCL. Updating PCL might also resolve this issue. You can click Settings → Launcher → Check for updates to update PCL. + - {0} + The mod loader version is incompatible with the mod + A mod file has been extracted, so the game cannot continue running. Put the entire mod file directly into the mods folder. Extracting it will cause the game to crash. Please delete the extracted mod from the mods folder, and then launch the game again. + Minecraft ran out of memory and cannot continue running. This is likely caused by insufficient system memory, too little memory allocated to the game, or overly demanding settings. Please increase the memory allocated to the game in launch settings, and remove resource packs, mods, or shaders with high system requirements. If this still does not help, close other programs before launching the game, or... get a better computer? + The game crashed because OpenJ9 is being used. Please switch to a non-OpenJ9 Java in the Java selection under launch settings, and then launch the game again. + The game seems to have crashed because you are using a JDK, or because your Java version is too new. Please switch to JRE 8 (Java 8) in the Java selection under launch settings, and then launch the game again. If JRE 8 is not installed, you can download and install it from the internet. + The game seems to have crashed because the Java version you are using is too new. Please switch to an older Java version in the Java selection under launch settings, and then launch the game again. If none is installed, you can download and install one from the internet. + The game is incompatible with the Java version you are currently using. If a suitable Java version is not installed, you can download and install one from the internet. + The game crashed because a mod file name contains special characters. Please try renaming the mod file so that it only contains letters, numbers, hyphens (-), underscores (_), and periods, and then launch the game again. + The game crashed because MixinBootstrap is missing. Please try installing MixinBootstrap. If the game still crashes after installation, try adding an exclamation mark to the beginning of its file name. + It looks like you are using 32-bit Java. This prevents Minecraft from using the memory it needs and may cause crashes. Please switch to 64-bit Java in the Java selection under launch settings, and then launch the game again. If 64-bit Java is not installed, you can download and install it from the internet. + You are using a 32-bit operating system. This prevents Minecraft from using the memory it needs and may cause crashes. You may need to reinstall a 64-bit operating system to resolve this issue. If your computer has 2 GB of memory or less, you may need a better computer... + The mod loader version is incompatible with the mod. Please go to Instance settings → Modify to change the loader version. Details: {0} + The game exited because a required dependency mod is not installed correctly. Missing dependency: - {0} Please handle it according to the information above. + The game exited because a required dependency mod is not installed correctly. Please handle it according to the log information in the crash report. + Your game ran into some issues, and PCL found a suspicious keyword: {0}. If you know which mod this keyword belongs to, that mod may be causing the crash. You can also view the crash report for details. + Your game ran into some issues, and PCL found the following suspicious keywords: - {0} If you know which mod these keywords belong to, that mod may be causing the crash. You can also view the crash report for details. + PCL suspects that the mod named {0} caused the game to crash, but it cannot be completely certain. You can try disabling this mod, and then check whether the game still crashes. + PCL suspects that the following mods caused the game to crash, but it cannot be completely certain: {0} You can try disabling these mods one by one, and then check whether the game still crashes. + The mod named {0} caused the game to crash. You can try disabling this mod, and then check whether the game still crashes. + The following mods caused the game to crash: {0} You can try disabling these mods one by one, and then check whether the game still crashes. + Some mods failed to inject, causing the game to crash. This usually means that some mods are incompatible with other mods or the current environment, or that they contain bugs. You can try disabling mods step by step, and then check whether the game still crashes to locate the mod that caused the crash. + The mod named {0} failed to inject, causing the game to crash. This usually means that it is incompatible with other mods or the current environment, or that it contains a bug. You can try disabling this mod, and then check whether the game still crashes. + The following mods caused the game to crash: {0} This usually means that they are incompatible with other mods or the current environment, or that they contain bugs. You can try disabling these mods one by one, and then check whether the game still crashes. + The mod named {0} caused the game to crash. + The mod named {0} caused the game to crash: Its configuration file {1} has an error and cannot be read. + The mod named {0} failed to initialize, preventing the game from continuing to load. You can try disabling this mod, and then check whether the game still crashes. + The following mods failed to initialize, causing the game to crash: {0} You can try disabling these mods one by one, and then check whether the game still crashes. + The game seems to have run into a problem because of block {0}. You can create a new world and observe how the game runs: - If it runs normally, this block caused the crash, and you may need to remove it somehow. - If it still crashes, the problem may come from something else... + The game seems to have run into a problem because of some blocks in the world. You can create a new world and observe how the game runs: - If it runs normally, some blocks caused the crash, and you may need to delete this world. - If it still crashes, the problem may come from something else... + You have installed multiple copies of the same mod: {0} Each mod should only appear once. Please delete the duplicate mods, and then launch the game again. + You may have installed multiple copies of the same mod, causing the game to crash. Each mod should only appear once. Please delete the duplicate mods, and then launch the game again. + The game seems to have run into a problem because of entity {0}. You can create a new world, spawn this entity, and observe how the game runs: - If it runs normally, this entity caused the crash, and you may need to remove it somehow. - If it still crashes, the problem may come from something else... + The game seems to have run into a problem because of some entities in the world. You can create a new world, spawn various entities, and observe how the game runs: - If it runs normally, some entities caused the crash, and you may need to delete this world. - If it still crashes, the problem may come from something else... + The game crashed because OptiFine is incompatible with the current Forge version. Please visit the official OptiFine website (https://optifine.net/downloads) to check which Forge versions are compatible with OptiFine, and reinstall the game strictly according to the matching version. + You do not need to install both OptiFine and Shaders Mod, because OptiFine already includes Shaders Mod features. After deleting Shaders Mod, the game should be able to run normally. + The game crashed because an old Forge version is incompatible with the current Java version. Please try the following solutions: - Update Forge to 36.2.26 or later - Switch to a Java version earlier than 1.8.0.320 + Possibly because another launcher modified the Forge version, the current instance files are abnormal, causing the game to crash. Please try reinstalling Forge from scratch instead of using another launcher to modify the Forge version. + * Actually, there is nothing wrong with your game. You triggered this crash yourself. * Don't you have anything more important to do? + Some installed mods seem to require Java 11 to launch. Please switch to Java 11 in the Java selection under launch settings, and then launch the game again. If Java 11 is not installed, you can download and install it from the internet. + The program returned the following message: {0} + The OptiFine version you are using may have caused problems in your game. This issue only appears in certain OptiFine versions. You can try switching to another OptiFine version. + There is a problem with your graphics driver, or the dedicated GPU is not being used, causing the game to fail to run normally. If your computer has a dedicated GPU, please launch PCL and Minecraft with the dedicated GPU instead of the Intel integrated graphics. If the problem persists, try updating your graphics driver to the latest version, or rolling it back to the factory version. If it still does not work, you can also try using Java 8.0.51 or earlier. + There is a problem with your graphics driver, causing the game to fail to run normally. Please try updating your graphics driver to the latest version, or rolling it back to the factory version, and then launch the game again. If it still does not work, you can try using Java 8.0.51 or earlier. If the problem persists, you may need a better graphics card... + The resource pack resolution you are using is too high, or your graphics card is not powerful enough, causing the game to stop running. If you are using a high-resolution resource pack, please remove it. If you are not using any resource pack, you may need to update your graphics driver, or get a better graphics card... + The game crashed because Night Config has a problem. You can try installing the Night Config Fixes mod, which may resolve this issue. + The shader or resource pack you are using caused some problems in the game... Please try deleting the extra resources you added. + The game crashed because you have installed too many mods and exceeded the game's ID limit. Please try installing a fix mod such as JEID, or delete some large mods. + Some files or content failed validation, causing problems in the game. Please try deleting the game files (including mods) and downloading them again. + The game cannot run normally because some installed Forge files are missing. Please reset this instance in instance settings, and then launch the game again. Deleting the libraries folder while packaging the game may cause this error. + Fabric provided the following error message: {0} Please handle it according to the information above. + Fabric may have provided an error message. Please handle it according to the log information in the crash report. + The mods you installed are incompatible: {0} Please handle it according to the information above. + The mods you installed are incompatible, and the mod loader may have provided an error message. Please handle it according to the log information in the crash report. + The mod loader provided the following error message: {0} Please handle it according to the information above. + The mod loader may have provided an error message. Please handle it according to the log information in the crash report. + Fabric provided the following solution: {0} Please handle it according to the information above. + Fabric may have provided a solution. Please handle it according to the log information in the crash report. + Forge provided the following error message: {0} Please handle it according to the information above. + Forge may have provided an error message. Please handle it according to the log information in the crash report. + Your game ran into some issues, but PCL could not find any relevant log files, so it cannot analyze the crash. + PCL found an error reason without detailed information ({0}). Please submit feedback to the PCL developers for details. + diff --git a/PCL.Core/App/Localization/Languages/zh-CN.xaml b/PCL.Core/App/Localization/Languages/zh-CN.xaml index 156ba98dd..76f050e03 100644 --- a/PCL.Core/App/Localization/Languages/zh-CN.xaml +++ b/PCL.Core/App/Localization/Languages/zh-CN.xaml @@ -3551,4 +3551,249 @@ Minecraft 窗口已加载:{0}({1}) 已最大化 Minecraft 窗口:{0} - \ No newline at end of file + + + + zh-CN + 简体中文(中国大陆) + 启动 + 下载 + 设置 + 工具 + 下载 + 版本详情 + 安装到当前实例 + 选择下载位置 + 请先选择一个 Minecraft 实例 + + UVMC 特供下载 + 语言 + 语言 + 界面语言 + 跟随系统({0}) + 区域格式 + 跟随系统区域格式 + 同步界面语言 + 目前仅部分新增界面支持多语言功能,其余界面将在后续迁移中逐步完成生效。 为确保工作效率与便捷性,迁移过程中仅确保“English (US)”与“简体中文(中国大陆)”部分可用。其余语言将在未来迁移工作完成后,交由社区于翻译平台进行翻译贡献。 + 语言设置已更新 + 天空蓝 + 龙猫蓝 + 死机蓝 + HMCL + 游戏窗口标题 + {name} | 玩家 : {user} | 使用 {login} 登录 + 自定义游戏窗口的标题,若留空则不进行更改。 支持以下替换标记: · {user}:玩家名字 · {login}:玩家的登录方式 · {name}:游戏实例名 · {date}、{time}:当前的系统时间 · {version}:游戏对应的原版版本号 注意:如果你的实例安装了 Modern UI 模组,那么这里的设置将会失效 + 启动器可见性 + 游戏启动后立即关闭 + 游戏启动后隐藏,游戏退出后自动关闭 + 游戏启动后隐藏,游戏退出后重新打开 + 游戏启动后最小化 + 游戏启动后仍保持不变 + 若在游戏启动后立即关闭启动器,崩溃检测、更改游戏标题等功能将失效。 如果想保留这些功能,可以选择让启动器在游戏启动后隐藏,游戏退出后自动关闭。 + 提醒 + 继续 + 进程优先级 + 实时(使游戏以最高优先级运行,谨慎使用,可能严重影响系统运行) + 极高(谨慎使用,可能严重影响其他程序运行) + 高(优先保证游戏运行,游戏性能更佳,但可能造成其他程序卡顿) + 中(平衡) + 低(优先保证其他程序运行,但可能让游戏卡顿,适合挂机时使用) + 窗口大小 + 注意:如果你的实例安装了 Modern UI 模组,那么这里的设置将会失效 + 全屏 + 与启动器尺寸一致 + 自定义尺寸 + Forge 1.12.2 等个别版本存在 Bug,会导致高度设定无效 + 最大化 + 添加 + 正在加载 Java 列表 + 自动选择 + Java 选择自动挡,依据游戏需要自动选择合适的 Java + 此 Java 不可用,请刷新列表 + 请先启用此 Java 后再选择其作为默认 Java + 请先取消选择此 Java 作为默认 Java 后再禁用 + 详细信息 + Java 信息 + 类型: {0} 版本: {1} 架构: {2} ({3}) 发行商: {4} 位置: {5} + 禁用此 Java + 启用此 Java + 选择 Java 程序 + Java 程序(java.exe)|java.exe + Java 已经存在,不用再次添加…… + 已添加 Java! + 未能成功将 Java 加入列表中 + 调整 Java 启用状态失败 + 默认实例隔离 + 所有实例均使用同一档案,存档、模组、资源包等均为公用。 若存在多个安装了模组的实例,可能会导致模组冲突。 + 当安装新实例时,据此自动设置新实例的隔离选项。 若想调整已有实例的隔离策略,请前往它的实例设置。 + 隔离可安装模组的实例 + 可安装模组的实例(例如 Forge、Fabric)均互相独立以避免模组冲突,其他实例(例如原版)则不会被隔离。 + 隔离非正式版 + 将 Minecraft 快照、预发布版、远古版本、愚人节版本与其他实例进行隔离 + 隔离可安装模组的实例与非正式版 + 隔离所有实例 + 不同实例之间的存档、模组、资源包等均不互通。 这会导致不同原版实例间的存档不能共用,所以一般不推荐。 + 默认策略只会对今后新安装的实例生效。 已有实例的隔离策略需要在它的设置中调整。 + 自定义信息 + 该信息会显示在游戏主界面的左下角,与 F3 调试页面的左上角 + 正版验证方式 + Web 账户管理器的正版验证流程更为简单,而设备代码流允许你在任意设备上打开网页进行验证。 如果使用 Web 账户管理器登录遇到问题,可以尝试使用设备代码流。 如果正在公共计算机上临时登录账号,推荐使用设备代码流。 由于部分依赖组件存在较多问题,该选项暂时强制指定为设备代码流。 + Web 账户管理器(暂时强制设备代码流) + 设备代码流 + IP 协议偏好 + 通过设置 Java 虚拟机参数来设置 MC 的 IP 协议版本偏好。 一般建议设置为 "IPv4 优先",这能确保 PCL CE 大厅正常工作。 如果有手动 IPv6 联机等需要,可以选择其他选项。 IPv4 优先:-Djava.net.preferIPv4Stack=true 默认:不添加额外参数 IPv6 优先:-Djava.net.preferIPv6Stack=true + IPv4 优先 + Java 默认 + IPv6 优先 + 无限制 + 日志操作 + 导出日志 + 导出全部日志 + 打开日志目录 + 清理历史日志 + 所有日志 + {0} (当前) + 临时存储的日志 ({0}) + 临时存储的未输出日志 + 导出日志文件 + PCL CE 日志压缩包|*.zip + 日志保存成功! + 日志保存失败 + 是否删除所有历史日志? + 清理历史日志 + 清理日志文件成功! + 选择保存位置 + PCL 配置文件(*.json)|*.json + 配置导出成功! + 选择配置文件 + 配置导入成功!请重启 PCL 以应用配置…… + 重启 + 跟随全局设置 + 跟随全局设置 + 实例隔离 + 开启 + 与其他实例的存档、模组等文件相互独立,互不干涉。 这会使你无法跨实例共享存档,但可以规避模组冲突问题。 + 与其余关闭隔离的实例共享存档、模组等文件。 若存在多个安装了模组的实例,可能会由于模组冲突而导致崩溃。 + 自定义游戏窗口的标题,若留空则跟随全局设置的值。 支持以下替换标记: · {user}:玩家名字 · {login}:玩家的登录方式 · {name}:游戏实例名 · {date}、{time}:当前的系统时间 · {version}:游戏对应的原版版本号 注意:如果你的实例安装了 Modern UI 模组,那么这里的设置将会失效 + 默认窗口标题 + 游戏窗口标题是否保留默认。 + 该信息会显示在游戏主界面的左下角,与 F3 调试页面的左上角。 若留空,则跟随全局设置的值。 + 游戏 Java + 若将 Java 放在游戏文件夹或 PCL 文件夹,在进行自动选择时 PCL 会尽量优先选择它 + 加载中…… + 已自动格式化验证服务器地址! + 设置覆盖确认 + 即将把第三方登录设置覆盖为 LittleSkin 登录。 除非你是服主,或者服主要求你这样做,否则请不要继续。 是否确实需要覆盖当前设置? + 继续 + LittleSkin 登录 + 锁定验证方式确认 + 你正在选择锁定此实例的验证方式。锁定之后,将无法再更改此实例的验证方式要求,启动此实例将必须使用指定的验证方式。 此功能可能会帮助一些服主吧。 是否继续? + 跟随全局设置 + 自动选择合适的 Java + 选择启动器目录下的 Java + 选择启动器目录下的 Java(当前路径无效) + 启动器目录下的 Java | {0} + 相对路径: {0} 解析路径: {1} + 无效路径: {0} 点击此项重新选择有效 Java + 将选择相对于实例目录的 Java 路径 + 路径: {0} 版本: {1} 来源: {2} + 超出路径允许范围,请选择启动器文件夹或其子文件夹下的文件 + 列表加载失败,请重试 + 未检测到可用的 Java 运行时 + 请在设置中手动指定 Java 路径,或点击“扫描”按钮重新检测 + 调整实例隔离后,你可能得把游戏存档、模组等文件手动迁移到新的游戏文件夹中。 如果修改后发现存档消失,把这项设置改回来就能恢复。 如果你不会迁移存档,不建议修改这项设置! + 本选项会修改游戏日志级别修改为最低,大量日志输出会消耗大量磁盘空间并可能影响游戏性能。这也可能带来一定安全风险。如果你不知道你在做什么,不要修改此选项! 你确定要继续修改吗? + 该实例不可使用模组 + 你需要先安装 Forge、Fabric 等模组加载器才能使用模组,请在下载页面安装这些实例。 如果你已经安装过了模组加载器,那么你很可能选择了错误的实例,请点击实例选择按钮切换实例。 + 转到下载页面 + 实例选择 + 配置文件内容无效或为空! + 整合包导出配置(*.txt)|*.txt + 是否打包正式版 PCL,以便没有启动器的玩家安装整合包。 + 是否打包 PCL 个性化内容,例如功能隐藏设置、主页、背景音乐和图片等。 + 是否将模组、资源包、光影包的文件直接放入整合包中,这样在导入时就无需联网下载它们。 + 建议仅在无法稳定连接 CurseForge 或 Modrinth 时才考虑启用。 + 二次分发可能违反使用协议,请尽量不要公开发布包含资源文件的整合包! + 如果你想要打包上传到 Modrinth,启用此项会生成完全符合 Modrinth 要求的整合包文件。 + 由于 Modrinth 要求,只能从 CurseForge 下载的资源将无法联网下载,会被直接放入整合包中。 + 此选项与 IncludeLauncher、IncludeLauncherCustom、DontCheckHostedAssets 冲突。 + 导出的文件的存放位置。 + 若设置了此项,在导出时会直接将文件放到此路径,不会弹窗要求选择。 + 若 IncludeLauncher 为 True,应以 .zip 结尾;若为 False,应以 .mrpack 结尾。 + 修改下方的规则以控制需要导出的内容。 + 以 ! 开头以反选。可以使用 *、?、[] 通配符。靠后的行覆盖靠前的。 + 排除的文件 + 如果想将额外的文件自动放到压缩包根目录中,可以将它们的路径写在下方。 + 必须是完整路径。每行中,若以 \ 结尾则代表是文件夹,不以 \ 结尾则代表是文件。 + (光影配置文件) + 未找到配置文件中指定的文件夹:{0} + 未找到配置文件中指定的单个文件:{0} + 很抱歉,PCL CE 无法确定错误原因。 + 很抱歉,你的游戏出现了一些问题…… 如果要寻求帮助,请把错误报告文件发给对方,而不是发送这个窗口的照片或者截图。 + 此外, + 你可以查看错误报告了解错误具体是如何发生的。 + 如果要寻求帮助,请把错误报告文件发给对方,而不是发送这个窗口的照片或者截图。 + 此外,你正在使用老版本 PCL CE,更新 PCL CE 或许也能解决这个问题。 你可以点击 设置 → 启动器 → 检查更新 来更新 PCL CE。 + - {0} + 模组加载器版本与模组不兼容 + 由于模组文件被解压了,导致游戏无法继续运行。 直接把整个模组文件放进模组文件夹中即可,若解压就会导致游戏出错。 请删除模组文件夹中已被解压的模组,然后再启动游戏。 + Minecraft 内存不足,导致其无法继续运行。 这很可能是因为电脑内存不足、游戏分配的内存不足,或是配置要求过高。 请在启动设置中增加为游戏分配的内存,并删除配置要求较高的材质、模组、光影。 如果依然不奏效,请在开始游戏前尽量关闭其他软件,或者……换台电脑? + 游戏因为使用 OpenJ9 而崩溃了。 请在启动设置的 Java 选择一项中改用非 OpenJ9 的 Java,然后再启动游戏。 + 游戏似乎因为使用 JDK,或 Java 版本过高而崩溃了。 请在启动设置的 Java 选择一项中改用 JRE 8(Java 8),然后再启动游戏。 如果你没有安装 JRE 8,你可以从网络中下载、安装一个。 + 游戏似乎因为你所使用的 Java 版本过高而崩溃了。 请在启动设置的 Java 选择一项中改用较低版本的 Java,然后再启动游戏。 如果没有,可以从网络中下载、安装一个。 + 游戏不兼容你当前使用的 Java。 如果没有合适的 Java,可以从网络中下载、安装一个。 + 由于有模组的名称包含特殊字符,导致游戏崩溃。 请尝试修改模组文件名,让它只包含英文字母、数字、减号(-)、下划线(_)和小数点,然后再启动游戏。 + 由于缺失 MixinBootstrap,导致游戏崩溃。 请尝试安装 MixinBootstrap。若安装后依然崩溃,可以尝试在文件名前添加英文感叹号。 + 你似乎正在使用 32 位 Java,这会导致 Minecraft 无法使用所需的内存,进而造成崩溃。 请在启动设置的 Java 选择一项中改用 64 位的 Java 再启动游戏,然后再启动游戏。 如果你没有安装 64 位的 Java,你可以从网络中下载、安装一个。 + 你正在使用 32 位的操作系统,这会导致 Minecraft 无法使用所需的内存,进而造成崩溃。 你或许只能重装 64 位的操作系统来解决此问题。 如果你的电脑内存在 2GB 以内,那或许只能换台电脑了…… + 模组加载器版本与模组不兼容,请前往 实例设置 - 修改 更换加载器版本。 详细信息: {0} + 由于未安装正确的前置模组,导致游戏退出。 缺失的依赖项: - {0} 请根据上述信息进行对应处理,如果看不懂英文可以使用翻译软件。 + 由于未安装正确的前置模组,导致游戏退出。 请根据错误报告中的日志信息进行对应处理,如果看不懂英文可以使用翻译软件。 + 你的游戏遇到了一些问题,PCL CE 为此找到了一个可疑的关键词:{0}。 如果你知道某个关键词对应的模组,那么有可能就是它引起的错误,你也可以查看错误报告获取详情。 + 你的游戏遇到了一些问题,PCL CE 为此找到了以下可疑的关键词: - {0} 如果你知道某个关键词对应的模组,那么有可能就是它引起的错误,你也可以查看错误报告获取详情。 + PCL CE 怀疑名为 {0} 的模组导致了游戏出错,但不能完全确定。 你可以尝试禁用此模组,然后观察游戏是否还会崩溃。 + PCL CE 怀疑以下模组导致了游戏出错,但不能完全确定: {0} 你可以尝试依次禁用上述模组,然后观察游戏是否还会崩溃。 + 名为 {0} 的模组导致了游戏出错。 你可以尝试禁用此模组,然后观察游戏是否还会崩溃。 + 以下模组导致了游戏出错: {0} 你可以尝试依次禁用上述模组,然后观察游戏是否还会崩溃。 + 部分模组注入失败,导致游戏出错。 这一般代表着部分模组与其他模组或当前环境不兼容,或是它存在 Bug。 你可以尝试逐步禁用模组,然后观察游戏是否还会崩溃,以此定位导致崩溃的模组。 + 名为 {0} 的模组注入失败,导致游戏出错。 这一般代表着它与其他模组或当前环境不兼容,或是它存在 Bug。 你可以尝试禁用此模组,然后观察游戏是否还会崩溃。 + 以下模组导致了游戏出错: {0} 这一般代表着它们与其他模组或当前环境不兼容,或是它存在 Bug。 你可以尝试依次禁用上述模组,然后观察游戏是否还会崩溃。 + 名为 {0} 的模组导致了游戏出错。 + 名为 {0} 的模组导致了游戏出错: 其配置文件 {1} 存在异常,无法读取。 + 名为 {0} 的模组初始化失败,导致游戏无法继续加载。 你可以尝试禁用此模组,然后观察游戏是否还会崩溃。 + 以下模组初始化失败,导致游戏出错: {0} 你可以尝试依次禁用上述模组,然后观察游戏是否还会崩溃。 + 游戏似乎因为方块 {0} 出现了问题。 你可以创建一个新世界,并观察游戏的运行情况: - 若正常运行,则是该方块导致出错,你或许需要使用一些方式删除此方块。 - 若仍然出错,问题就可能来自其他原因…… + 游戏似乎因为世界中的某些方块出现了问题。 你可以创建一个新世界,并观察游戏的运行情况: - 若正常运行,则是某些方块导致出错,你或许需要删除该世界。 - 若仍然出错,问题就可能来自其他原因…… + 你重复安装了多个相同的模组: {0} 每个模组只能出现一次,请删除重复的模组,然后再启动游戏。 + 你可能重复安装了多个相同的模组,导致游戏出错。 每个模组只能出现一次,请删除重复的模组,然后再启动游戏。 + 游戏似乎因为实体 {0} 出现了问题。 你可以创建一个新世界,并生成一个该实体,然后观察游戏的运行情况: - 若正常运行,则是该实体导致出错,你或许需要使用一些方式删除此实体。 - 若仍然出错,问题就可能来自其他原因…… + 游戏似乎因为世界中的某些实体出现了问题。 你可以创建一个新世界,并生成各种实体,观察游戏的运行情况: - 若正常运行,则是某些实体导致出错,你或许需要删除该世界。 - 若仍然出错,问题就可能来自其他原因…… + 由于 OptiFine 与当前版本的 Forge 不兼容,导致了游戏崩溃。 请前往 OptiFine 官网(https://optifine.net/downloads)查看 OptiFine 所兼容的 Forge 版本,并严格按照对应版本重新安装游戏。 + 无需同时安装 OptiFine 和其他光影模组(如 Iris),OptiFine 已经集成了光影模组的功能。 在删除光影模组后,游戏即可正常运行。 + 由于低版本 Forge 与当前 Java 不兼容,导致了游戏崩溃。 请尝试以下解决方案: - 更新 Forge 到 36.2.26 或更高版本 - 换用版本低于 1.8.0.320 的 Java + 可能由于其他启动器修改了 Forge 版本,当前实例的文件存在异常,导致了游戏崩溃。 请尝试重新全新安装 Forge,而非使用其他启动器修改 Forge 版本。 + * 事实上,你的游戏没有任何问题,这是你自己触发的崩溃。 * 你难道没有更重要的事要做吗? + 你所安装的部分模组似乎需要使用 Java 11 启动。 请在启动设置的 Java 选择一项中改用 Java 11,然后再启动游戏。 如果你没有安装 Java 11,你可以从网络中下载、安装一个。 + 程序返回了以下信息: {0} + 你所使用的 OptiFine 可能导致了你的游戏出现问题。 该问题只在特定 OptiFine 版本中出现,你可以尝试更换 OptiFine 的版本。 + 你的显卡驱动存在问题,或未使用独立显卡,导致游戏无法正常运行。 如果你的电脑存在独立显卡,请使用独立显卡而非 Intel 核显启动 PCL CE 与 Minecraft。 如果问题依然存在,请尝试升级你的显卡驱动到最新版本,或回退到出厂版本。 如果还是不行,还可以尝试使用 8.0.51 或更低版本的 Java。 + 你的显卡驱动存在问题,导致游戏无法正常运行。 请尝试升级你的显卡驱动到最新版本,或回退到出厂版本,然后再启动游戏。 如果还是不行,可以尝试使用 8.0.51 或更低版本的 Java。 如果问题依然存在,那么你可能需要换个更好的显卡…… + 你所使用的材质分辨率过高,或显卡配置不足,导致游戏无法继续运行。 如果你正在使用高清材质,请将它移除。 如果你没有使用材质,那么你可能需要更新显卡驱动,或者换个更好的显卡…… + 由于 Night Config 存在问题,导致了游戏崩溃。 你可以尝试安装 Night Config Fixes 模组,这或许能解决此问题。 + 你所使用的光影或材质导致游戏出现了一些问题…… 请尝试删除你所添加的这些额外资源。 + 你所安装的模组过多,超出了游戏的 ID 限制,导致了游戏崩溃。 请尝试安装 JEID 等修复模组,或删除部分大型模组。 + 部分文件或内容校验失败,导致游戏出现了问题。 请尝试删除游戏(包括模组)并重新下载,或尝试在重新下载时使用 VPN。 + 由于安装的 Forge 文件丢失,导致游戏无法正常运行。 请前往实例设置重置该实例,然后再启动游戏。 在打包游戏时删除 libraries 文件夹可能导致此错误。 + Fabric 提供了以下错误信息: {0} 请根据上述信息进行对应处理,如果看不懂英文可以使用翻译软件。 + Fabric 可能已经提供了错误信息,请根据错误报告中的日志信息进行对应处理,如果看不懂英文可以使用翻译软件。 + 你所安装的模组不兼容: {0} 请根据上述信息进行对应处理,如果看不懂英文可以使用翻译软件。 + 你所安装的模组不兼容,模组加载器可能已经提供了错误信息,请根据错误报告中的日志信息进行对应处理,如果看不懂英文可以使用翻译软件。 + 模组加载器提供了以下错误信息: {0} 请根据上述信息进行对应处理,如果看不懂英文可以使用翻译软件。 + 模组加载器可能已经提供了错误信息,请根据错误报告中的日志信息进行对应处理,如果看不懂英文可以使用翻译软件。 + Fabric 提供了以下解决方案: {0} 请根据上述信息进行对应处理,如果看不懂英文可以使用翻译软件。 + Fabric 可能已经提供了解决方案,请根据错误报告中的日志信息进行对应处理,如果看不懂英文可以使用翻译软件。 + Forge 提供了以下错误信息: {0} 请根据上述信息进行对应处理,如果看不懂英文可以使用翻译软件。 + Forge 可能已经提供了错误信息,请根据错误报告中的日志信息进行对应处理,如果看不懂英文可以使用翻译软件。 + 你的游戏出现了一些问题,但 PCL CE 未能找到相关记录文件,因此无法进行分析。 + PCL CE 获取到了没有详细信息的错误原因({0}),请向 PCL CE 开发团队提交反馈以获取详情。 + diff --git a/Plain Craft Launcher 2/Controls/MyListItem.xaml.cs b/Plain Craft Launcher 2/Controls/MyListItem.xaml.cs index dce07b624..caa7f39d7 100644 --- a/Plain Craft Launcher 2/Controls/MyListItem.xaml.cs +++ b/Plain Craft Launcher 2/Controls/MyListItem.xaml.cs @@ -27,6 +27,7 @@ public partial class MyListItem : IMyRadio public event IMyRadio.ChangedEventHandler? Changed; public event ClickEventHandler? Click; + public event ClickEventHandler? RightClick; public event LogoClickEventHandler? LogoClick; public void RefreshColor(object sender, EventArgs e) @@ -474,6 +475,8 @@ public MyListItem() PreviewMouseLeftButtonDown += Button_MouseDown; MouseLeave += Button_MouseLeave; PreviewMouseLeftButtonUp += Button_MouseLeave; + // 右键事件(用于触发 RightClick,例如模组版本项右键直接另存为) + PreviewMouseRightButtonUp += (_, e) => RightClick?.Invoke(this, e); MouseEnter += RefreshColor; MouseLeave += RefreshColor; MouseLeftButtonDown += RefreshColor; diff --git a/Plain Craft Launcher 2/Controls/MyMsg/ModDependencyMsgBox.xaml b/Plain Craft Launcher 2/Controls/MyMsg/ModDependencyMsgBox.xaml new file mode 100644 index 000000000..0f3e5f189 --- /dev/null +++ b/Plain Craft Launcher 2/Controls/MyMsg/ModDependencyMsgBox.xaml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Plain Craft Launcher 2/Controls/MyMsg/ModDependencyMsgBox.xaml.cs b/Plain Craft Launcher 2/Controls/MyMsg/ModDependencyMsgBox.xaml.cs new file mode 100644 index 000000000..98e43b4a7 --- /dev/null +++ b/Plain Craft Launcher 2/Controls/MyMsg/ModDependencyMsgBox.xaml.cs @@ -0,0 +1,225 @@ +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Interop; +using System.Windows.Media; +using PCL.Core.App.Localization; +using PCL.Core.UI.Controls; + +namespace PCL; + +/// +/// 模组版本的「前置详情」弹窗:展示该版本的版本信息、必要前置 / 可选前置, +/// 并提供「安装到当前实例」/「选择下载位置」两个动作。点击某个前置项会关闭弹窗并返回该前置工程。 +/// 布局由 XAML 定义,调用方只需传入 CompFile 数据(由 触发)。 +/// +public partial class ModDependencyMsgBox +{ + private readonly ModMain.MyMsgBoxConverter myConverter; + private readonly int uuid = ModBase.GetUuid(); + + public ModDependencyMsgBox(ModMain.MyMsgBoxConverter converter) + { + try + { + InitializeComponent(); + AppendUniqueNameSuffix(Btn1); + AppendUniqueNameSuffix(Btn2); + AppendUniqueNameSuffix(Btn3); + myConverter = converter; + LabTitle.Text = Lang.Text("Download.Comp.Detail.VersionPopup.Title"); + Btn1.Text = Lang.Text("Download.Comp.Detail.VersionPopup.ButtonInstall"); + Btn2.Text = Lang.Text("Download.Comp.Detail.VersionPopup.ButtonSaveAs"); + Btn3.Text = Lang.Text("Common.Action.Cancel"); + ShapeLine.StrokeThickness = ModBase.GetWPFSize(1d); + if (converter.Content is ModComp.CompFile file) + Populate(file); + } + catch (Exception ex) + { + ModBase.Log(ex, "前置弹窗初始化失败", ModBase.LogLevel.Hint); + } + + Loaded += Load; + PreviewKeyDown += ModDependencyMsgBox_PreviewKeyDown; + Btn1.Click += Btn1_Click; + Btn2.Click += Btn2_Click; + Btn3.Click += Btn3_Click; + LabTitle.MouseLeftButtonDown += Drag; + PanBorder.MouseLeftButtonDown += Drag; + } + + private void AppendUniqueNameSuffix(FrameworkElement element) + { + element.Name += ModBase.GetUuid(); + } + + /// + /// 填充版本信息与必要 / 可选前置项。 + /// + private void Populate(ModComp.CompFile file) + { + // 1. 版本信息 + LabVersionInfo.Text = file.DisplayName; + _AddTag(file.StatusDescription); + foreach (var loader in file.ModLoaders) + _AddTag(loader.ToString()); + LabDateInfo.Text = Lang.Text("Download.Comp.Detail.FileList.Updated", file.ReleaseDate.ToString("G")); + + // 2. 必要前置 / 可选前置 + FillDependencySection(LabReqTitle, PanReqDeps, file.Dependencies, + Lang.Text("Download.Comp.Detail.FileList.RequiredDependencies")); + FillDependencySection(LabOptTitle, PanOptDeps, file.OptionalDependencies, + Lang.Text("Download.Comp.Detail.FileList.OptionalDependencies")); + } + + private void _AddTag(string text) + { + var tag = new Border + { + Background = new SolidColorBrush(Color.FromArgb(17, 0, 0, 0)), + Padding = new Thickness(3d, 1d, 3d, 1d), + CornerRadius = new CornerRadius(3d), + Margin = new Thickness(0d, 0d, 3d, 0d), + SnapsToDevicePixels = true, + UseLayoutRounding = false + }; + tag.Child = new TextBlock + { + Text = text, + Foreground = new SolidColorBrush(Color.FromRgb(134, 134, 134)), + FontSize = 11d + }; + PanVersionTags.Children.Add(tag); + } + + /// + /// 填充一个前置分区:标题 + 可点击的前置项(点击以该前置工程关闭弹窗)。 + /// + private void FillDependencySection(TextBlock header, StackPanel panel, List depIds, string title) + { + var projects = new List(); + foreach (var id in depIds) + if (ModComp.compProjectCache.TryGetValue(id, out var project)) + projects.Add(project); + + header.Text = $"{title}({projects.Count})"; + + if (!projects.Any()) + { + header.Visibility = Visibility.Collapsed; + panel.Visibility = Visibility.Collapsed; + return; + } + + foreach (var project in projects) + { + var captured = project; + // 复用「游戏资源 → 模组」搜索结果同款 MyCompItem 卡片样式; + // 关闭其内置跳转(AutoNavigate=false),改由弹窗统一「先关闭再跳转」 + var item = project.ToCompItem(true, true).Init(); + item.AutoNavigate = false; + item.Click += (_, _) => ReturnResult(captured); + panel.Children.Add(item); + } + } + + /// + /// 以指定返回值关闭弹窗:按钮返回 1 / 2,前置项返回对应 CompProject。 + /// + private void ReturnResult(object result) + { + if (myConverter.IsExited) + return; + myConverter.IsExited = true; + myConverter.Result = result; + Close(); + } + + private void Load(object sender, EventArgs e) + { + try + { + // UI 初始化 + if (Btn2.IsVisible && !(Btn1.ColorType == MyButton.ColorState.Red)) + Btn1.ColorType = MyButton.ColorState.Highlight; + Btn1.Focus(); + // 动画 + Opacity = 0d; + ModAnimation.AniStart( + ModAnimation.AaColor(ModMain.frmMain.PanMsgBackground, BlurBorder.BackgroundProperty, + new ModBase.MyColor(90d, 0d, 0d, 0d) - ModMain.frmMain.PanMsgBackground.Background, 200), + "PanMsgBackground Background"); + ModAnimation.AniStart( + new[] + { + ModAnimation.AaOpacity(this, 1d, 120, 60), + ModAnimation.AaDouble(i => TransformPos.Y += (double)i, + -TransformPos.Y, 300, 60, new ModAnimation.AniEaseOutBack(ModAnimation.AniEasePower.Weak)), + ModAnimation.AaDouble(i => TransformRotate.Angle += (double)i, + -TransformRotate.Angle, 300, 60, + new ModAnimation.AniEaseOutFluent(ModAnimation.AniEasePower.Weak)) + }, "MyMsgBox " + uuid); + ModBase.Log("[Control] 前置详情弹窗:" + LabTitle.Text); + } + catch (Exception ex) + { + ModBase.Log(ex, "前置详情弹窗加载失败", ModBase.LogLevel.Hint); + } + } + + private void Close() + { + // 结束线程阻塞 + myConverter.WaitFrame.Continue = false; + ComponentDispatcher.PopModal(); + // 动画 + ModAnimation.AniStart(new[] + { + ModAnimation.AaCode(() => + { + if (!ModMain.WaitingMyMsgBox.Any()) + ModAnimation.AniStart(ModAnimation.AaColor(ModMain.frmMain.PanMsgBackground, + BlurBorder.BackgroundProperty, + new ModBase.MyColor(0d, 0d, 0d, 0d) - ModMain.frmMain.PanMsgBackground.Background, 200, + ease: new ModAnimation.AniEaseOutFluent(ModAnimation.AniEasePower.Weak))); + }, 30), + ModAnimation.AaOpacity(this, -Opacity, 80, 20), + ModAnimation.AaDouble(i => TransformPos.Y += (double)i, 20d - TransformPos.Y, + 150, 0, new ModAnimation.AniEaseOutFluent()), + ModAnimation.AaDouble(i => TransformRotate.Angle += (double)i, + 6d - TransformRotate.Angle, 150, 0, new ModAnimation.AniEaseInFluent(ModAnimation.AniEasePower.Weak)), + ModAnimation.AaCode(() => ((Grid)Parent).Children.Remove(this), after: true) + }, "MyMsgBox " + uuid); + } + + public void Btn1_Click(object sender, MouseButtonEventArgs e) => ReturnResult(1); + + public void Btn2_Click(object sender, MouseButtonEventArgs e) => ReturnResult(2); + + public void Btn3_Click(object sender, MouseButtonEventArgs e) => ReturnResult(null); + + /// 按 Esc 关闭弹窗(等同点击「取消」,返回 null)。 + private void ModDependencyMsgBox_PreviewKeyDown(object sender, KeyEventArgs e) + { + if (e.Key == Key.Escape) + { + e.Handled = true; + ReturnResult(null); + } + } + + private void Drag(object sender, MouseButtonEventArgs e) + { + try + { + if (e.LeftButton == MouseButtonState.Pressed) + if (e.GetPosition(ShapeLine).Y <= 2d) + ModMain.frmMain.DragMove(); + } + catch (Exception ex) + { + ModBase.Log(ex, "拖拽移动失败", ModBase.LogLevel.Hint); + } + } +} diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModComp.cs b/Plain Craft Launcher 2/Modules/Minecraft/ModComp.cs index 5f70fe7f6..ca12b871a 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModComp.cs +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModComp.cs @@ -3140,7 +3140,9 @@ public JsonObject ToJson() /// public MyVirtualizingElement ToListItem(MyListItem.ClickEventHandler onClick, MyIconButton.ClickEventHandler? onSaveClick = null, - bool badDisplayName = false) + bool badDisplayName = false, + MyListItem.ClickEventHandler? onRightClick = null, + MyIconButton.ClickEventHandler? onDownloadClick = null) { return new MyVirtualizingElement(() => { @@ -3187,8 +3189,11 @@ public MyVirtualizingElement ToListItem(MyListItem.ClickEventHandler } }; newItem.Click += onClick; + if (onRightClick is not null) + newItem.RightClick += onRightClick; - // 4. 建立另存为按钮 + // 4. 建立右侧按钮(另存为 / 下载) + var buttons = new List(); if (onSaveClick is not null) { var btnSave = new MyIconButton { SvgIcon = "lucide/save", ToolTip = Lang.Text("Download.Version.SaveAs") }; @@ -3196,8 +3201,19 @@ public MyVirtualizingElement ToListItem(MyListItem.ClickEventHandler ToolTipService.SetVerticalOffset(btnSave, 30); ToolTipService.SetHorizontalOffset(btnSave, 2); btnSave.Click += onSaveClick; - newItem.Buttons = new[] { btnSave }; + buttons.Add(btnSave); } + if (onDownloadClick is not null) + { + var btnDownload = new MyIconButton { SvgIcon = "lucide/download", ToolTip = Lang.Text("Download.Version.Download") }; + ToolTipService.SetPlacement(btnDownload, PlacementMode.Center); + ToolTipService.SetVerticalOffset(btnDownload, 30); + ToolTipService.SetHorizontalOffset(btnDownload, 2); + btnDownload.Click += onDownloadClick; + buttons.Add(btnDownload); + } + if (buttons.Any()) + newItem.Buttons = buttons.ToArray(); return newItem; }) @@ -3402,26 +3418,8 @@ public static void QuickDownload(CompProject project) return; } - var behavior = Config.Download.Comp.QuickDownloadBehavior; - if (behavior == 0) - { - // 总是询问:弹「方式选择」 - int? choice = ModBase.RunInUiWait(() => - { - var options = new List - { - new MyRadioBox { Text = Lang.Text("Download.Comp.QuickDownload.ChooseMethod.CurrentInstance") }, - new MyRadioBox { Text = Lang.Text("Download.Comp.QuickDownload.ChooseMethod.AskInstance") }, - new MyRadioBox { Text = Lang.Text("Download.Comp.QuickDownload.ChooseMethod.AskPath") } - }; - return ModMain.MyMsgBoxSelect(options, - Lang.Text("Download.Comp.QuickDownload.ChooseMethod.Title"), - button1: Lang.Text("Common.Action.Continue"), - button2: Lang.Text("Common.Action.Cancel")); - }); - if (choice is null) return; // 用户取消 - behavior = choice.Value + 1; // 0→1 当前实例, 1→2 选实例, 2→3 选路径 - } + var behavior = _ResolveQuickDownloadBehavior(); + if (behavior is null) return; // 用户取消 switch (behavior) { @@ -3451,6 +3449,67 @@ public static void QuickDownload(CompProject project) }, "Comp QuickDownload"); } + /// + /// 快速下载指定版本(版本项右侧下载按钮入口):行为与 一致, + /// 但下载用户指定的具体版本,而非自动挑选的最新兼容版本。 + /// + public static void QuickDownload(CompProject project, CompFile file) + { + ModBase.RunInNewThread(() => + { + try + { + var files = new List { file }; + var behavior = _ResolveQuickDownloadBehavior(); + if (behavior is null) return; // 用户取消 + switch (behavior) + { + case 1: // 下载到当前选中实例 + _QuickDownloadToInstance(project, files, ModInstanceList.McMcInstanceSelected); + break; + case 2: // 询问并下载到选择的实例 + { + var instance = _QuickDownloadPickInstance(project, files); + if (instance is null) return; + _QuickDownloadToInstance(project, files, instance); + break; + } + case 3: // 询问并下载到一个路径 + _QuickDownloadToFolder(project, files); + break; + } + } + catch (Exception ex) + { + ModBase.Log(ex, "[Comp] 快速下载(指定版本)失败", ModBase.LogLevel.Feedback); + } + }, "Comp QuickDownload (version)"); + } + + /// + /// 解析快速下载行为:配置为「总是询问」时弹「方式选择」让用户选;用户取消返回 null,否则返回 1/2/3。 + /// + private static int? _ResolveQuickDownloadBehavior() + { + var behavior = Config.Download.Comp.QuickDownloadBehavior; + if (behavior != 0) return behavior; + int? choice = ModBase.RunInUiWait(() => + { + var options = new List + { + new MyRadioBox { Text = Lang.Text("Download.Comp.QuickDownload.ChooseMethod.CurrentInstance") }, + new MyRadioBox { Text = Lang.Text("Download.Comp.QuickDownload.ChooseMethod.AskInstance") }, + new MyRadioBox { Text = Lang.Text("Download.Comp.QuickDownload.ChooseMethod.AskPath") } + }; + return ModMain.MyMsgBoxSelect(options, + Lang.Text("Download.Comp.QuickDownload.ChooseMethod.Title"), + button1: Lang.Text("Common.Action.Continue"), + button2: Lang.Text("Common.Action.Cancel")); + }); + if (choice is null) return null; + return choice.Value + 1; // 0→1 当前实例, 1→2 选实例, 2→3 选路径 + } + /// 下载到指定实例的最新兼容版本。 private static void _QuickDownloadToInstance(CompProject project, List files, McInstance? instance) { @@ -3641,66 +3700,5 @@ public static bool IsInstanceSuitableForFile(McInstance? version, CompFile file, #endregion - /// - /// 预载包含大量 CompFile 的卡片,添加必要的元素和前置列表。 - /// 前置列表(必要 / 可选)会被放入可折叠栏:必要前置默认展开,可选前置默认收起。 - /// - public static void CompFilesCardPreload(StackPanel stack, List files) - { - // 获取卡片对应的前置 ID - // 如果为整合包就不会有 Dependencies 信息,所以不用管 - var deps = files.SelectMany(f => f.Dependencies).Distinct().ToList(); - var optionalDeps = files.SelectMany(f => f.OptionalDependencies).Distinct().ToList(); - if (!deps.Any() && !optionalDeps.Any()) - return; - - // 必要前置:默认展开 - _AddDependencyBar(stack, deps, - Lang.Text("Download.Comp.Detail.FileList.RequiredDependencies"), collapsed: false); - // 可选前置:默认收起(库 Mod 可能有大量可选前置,参见 Issue #2873) - _AddDependencyBar(stack, optionalDeps, - Lang.Text("Download.Comp.Detail.FileList.OptionalDependencies"), collapsed: true); - - // 添加结尾间隔(版本列表标题) - stack.Children.Add(new TextBlock - { - Text = Lang.Text("Download.Comp.Detail.FileList.VersionList"), FontSize = 14d, - HorizontalAlignment = HorizontalAlignment.Left, Margin = new Thickness(6d, 12d, 0d, 5d) - }); - } - - /// - /// 将一组前置依赖(按工程 ID)渲染为一个可折叠栏并加入 。 - /// 仅保留在 compProjectCache 中有信息的前置;若过滤后为空则不添加任何折叠栏。 - /// - /// 是否默认收起。前置 item 全部加入即可,靠 MyVirtualizingElement 在可见时才实例化。 - private static void _AddDependencyBar(StackPanel stack, List depIds, string title, bool collapsed) - { - if (depIds is null || !depIds.Any()) - return; - - depIds.Sort(); - var projects = new List(); - foreach (var dep in depIds) - { - if (compProjectCache.TryGetValue(dep, out var project)) - projects.Add(project); - else - ModBase.Log($"[Comp] 未找到 ID {dep} 的前置信息", ModBase.LogLevel.Debug); - } - if (!projects.Any()) - return; - - var bar = new MyCollapseBar - { - Title = $"{title} ({projects.Count})", - IsCollapsed = collapsed - }; - foreach (var project in projects) - bar.ContentPanel.Children.Add(project.ToCompItem(false, false)); - - stack.Children.Add(bar); - } - #endregion } diff --git a/Plain Craft Launcher 2/Modules/ModMain.cs b/Plain Craft Launcher 2/Modules/ModMain.cs index 5a6f43a6f..e569c8b08 100644 --- a/Plain Craft Launcher 2/Modules/ModMain.cs +++ b/Plain Craft Launcher 2/Modules/ModMain.cs @@ -305,7 +305,8 @@ public enum MyMsgBoxType Select, Input, Login, - Markdown + Markdown, + ModDependency } private static string GetDefaultDialogTitle() => Lang.Text("Common.Dialog.Title"); @@ -582,6 +583,34 @@ public static string MyMsgBoxInput(string title, string text = "", string defaul return (int?)converter.Result; } + /// + /// 显示模组版本的「前置详情」弹窗。返回值:1 = 安装到当前实例;2 = 选择下载位置; + /// 若点击某个前置项,则返回该前置的 ;关闭返回 null。 + /// + /// 要展示前置信息的模组版本文件。 + public static object? ModDependencyMsgBox(ModComp.CompFile file) + { + var converter = new MyMsgBoxConverter + { + Type = MyMsgBoxType.ModDependency, Content = file + }; + WaitingMyMsgBox.Add(converter); + try + { + if (frmMain is not null) + frmMain.DragStop(); + ComponentDispatcher.PushModal(); + Dispatcher.PushFrame(converter.WaitFrame); + } + finally + { + ComponentDispatcher.PopModal(); + } + + ModBase.Log($"[Control] 前置详情弹框返回:{converter.Result ?? "null"}"); + return converter.Result; + } + public static void MyMsgBoxTick() { @@ -625,6 +654,11 @@ public static void MyMsgBoxTick() frmMain.PanMsg.Children.Add(new MyMsgMarkdown(WaitingMyMsgBox[0])); break; } + case MyMsgBoxType.ModDependency: + { + frmMain.PanMsg.Children.Add(new ModDependencyMsgBox(WaitingMyMsgBox[0])); + break; + } } WaitingMyMsgBox.RemoveAt(0); diff --git a/Plain Craft Launcher 2/Pages/PageDownload/Comp/MyCompItem.xaml.cs b/Plain Craft Launcher 2/Pages/PageDownload/Comp/MyCompItem.xaml.cs index 2cebfa044..d3057b889 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/Comp/MyCompItem.xaml.cs +++ b/Plain Craft Launcher 2/Pages/PageDownload/Comp/MyCompItem.xaml.cs @@ -266,6 +266,11 @@ public void RefreshFavoriteStatus() // 触发点击事件 public event ClickEventHandler? Click; + /// + /// 点击时是否自动跳转到该工程的详情页。默认 true;在弹窗等需要自行处理点击的场景设为 false。 + /// + public bool AutoNavigate = true; + public delegate void ClickEventHandler(object sender, MouseButtonEventArgs e); private void BtnDelete_Click(object sender, EventArgs e) @@ -285,6 +290,7 @@ private void _BtnDownload_Click(object sender, EventArgs e) private void MyCompItem_Click(MyCompItem sender, EventArgs e) { + if (!AutoNavigate) return; // 记录当前展开的卡片标题(#2712) var titles = new List(); if (ModMain.frmMain.pageCurrent.page == FormMain.PageType.CompDetail) diff --git a/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadCompDetail.xaml.cs b/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadCompDetail.xaml.cs index df2ee66d9..2f8a0db0a 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadCompDetail.xaml.cs +++ b/Plain Craft Launcher 2/Pages/PageDownload/Comp/PageDownloadCompDetail.xaml.cs @@ -5,6 +5,7 @@ using System.Text; using System.Windows; using System.Windows.Controls; +using System.Windows.Input; using FluentValidation; using PCL.Core.App; using PCL.Core.App.Localization; @@ -253,15 +254,29 @@ public void InstallWorld_Click(MyListItem sender, EventArgs e) public void Save_Click(object sender, EventArgs e) { - // 获取点击项关联的文件对象 - var file = sender switch + SaveCompFile(ResolveFileFromSender(sender)); + } + + /// + /// 从点击事件 sender(MyListItem 或其内部按钮)解析出关联的 CompFile。 + /// + private static ModComp.CompFile? ResolveFileFromSender(object sender) + { + return sender switch { FrameworkElement Element when Element.Tag is ModComp.CompFile CompFile => CompFile, FrameworkElement Element when Element.Parent is FrameworkElement Parent && Parent.Tag is ModComp.CompFile CompFile => CompFile, FrameworkElement Element when Element.Parent is FrameworkElement Parent && Parent.Parent is FrameworkElement GrandParent && GrandParent.Tag is ModComp.CompFile CompFile => CompFile, _ => null }; + } + /// + /// 另存为:弹窗选择保存位置(模组可选自动安装必需前置),与历史行为完全一致。 + /// + private void SaveCompFile(ModComp.CompFile file) + { + if (file is null) return; ModBase.RunInNewThread(() => { try @@ -564,6 +579,90 @@ void DownloadDependencies() }, "Download CompDetail Save"); } + /// + /// 左键单击版本项:弹窗展示该版本的前置 / 可选前置,并提供“安装到当前实例” / “选择下载位置”。 + /// 把前置信息按版本拆分展示,避免合并所有版本导致的误导(参见 Issue #3265)。 + /// + public void ShowVersionPopup_Click(object sender, MouseButtonEventArgs e) + { + var file = ResolveFileFromSender(sender); + if (file is null) return; + var result = ModMain.ModDependencyMsgBox(file); + switch (result) + { + case ModComp.CompProject project: + // 点击了某个前置项,跳转到该前置的详情页 + ModMain.frmMain.PageChange(new FormMain.PageStackData + { + page = FormMain.PageType.CompDetail, + additional = (project, new List(), "", ModComp.CompLoaderType.Any, + ModComp.CompType.Any, null) + }); + break; + case 1: + InstallToInstance(file); + break; + case 2: + SaveCompFile(file); + break; + } + } + + /// + /// 安装到当前实例:仅把模组本体下载到当前实例的 mods 文件夹,不安装前置。 + /// + private void InstallToInstance(ModComp.CompFile file) + { + var instance = ModInstanceList.McMcInstanceSelected; + if (instance is null) + { + ModMain.MyMsgBox(Lang.Text("Download.Comp.Detail.VersionPopup.NoInstance"), + Lang.Text("Download.Comp.Detail.VersionPopup.Title"), button1: null, isWarn: true, forceWait: true); + return; + } + if (!instance.IsLoaded) instance.Load(); + var modsFolder = instance.PathIndie + "mods\\"; + ModBase.RunInNewThread(() => + { + try + { + Directory.CreateDirectory(modsFolder); + var target = modsFolder + ModComp.CompFileNameGet(_project, file); + var loaderName = Lang.Text("Download.Comp.Detail.DownloadResource", + Lang.Text("Download.Comp.Type.Mod"), ModBase.GetFileNameWithoutExtentionFromPath(target)); + var loaders = new List + { + new LoaderDownload(Lang.Text("Download.Comp.Detail.DownloadFile"), + new List { file.ToNetFile(target) }) + { + ProgressWeight = 6, + block = true + } + }; + var loader = new ModLoader.LoaderCombo(loaderName, loaders); + loader.OnStateChanged = ModDownloadLib.LoaderStateChangedHintOnly; + loader.Start(1); + ModLoader.LoaderTaskbarAdd(loader); + ModMain.frmMain.BtnExtraDownload.ShowRefresh(); + ModMain.frmMain.BtnExtraDownload.Ribble(); + } + catch (Exception ex) + { + ModBase.Log(ex, "安装到当前实例失败", ModBase.LogLevel.Feedback); + } + }, "Download CompDetail Install"); + } + + /// + /// 版本项右侧下载按钮:快速下载该指定版本(行为与搜索结果快速下载一致,受 QuickDownloadBehavior 设置控制)。 + /// + public void Download_Click(object sender, EventArgs e) + { + var file = ResolveFileFromSender(sender); + if (file is null) return; + ModComp.QuickDownload(_project, file); + } + private void BtnIntroWeb_Click(object sender, EventArgs e) { ModBase.OpenWebsite(_project.Website); @@ -1091,9 +1190,11 @@ private void UpdateFilterResult() default: { - ModComp.CompFilesCardPreload(stack, list); foreach (var item in list) - stack.Children.Add(item.ToListItem(ModMain.frmDownloadCompDetail.Save_Click, + stack.Children.Add(item.ToListItem( + ModMain.frmDownloadCompDetail.ShowVersionPopup_Click, + onRightClick: ModMain.frmDownloadCompDetail.Save_Click, + onDownloadClick: ModMain.frmDownloadCompDetail.Download_Click, badDisplayName: badDisplayName)); break; }