Skip to content

feat(instance): 删除实例前备份截图与投影原理图 [GPT-5.6] - #3537

Open
nya-a-cat wants to merge 6 commits into
PCL-Community:devfrom
nya-a-cat:feat/protect-instance-personal-files
Open

feat(instance): 删除实例前备份截图与投影原理图 [GPT-5.6]#3537
nya-a-cat wants to merge 6 commits into
PCL-Community:devfrom
nya-a-cat:feat/protect-instance-personal-files

Conversation

@nya-a-cat

@nya-a-cat nya-a-cat commented Aug 14, 2026

Copy link
Copy Markdown

修改内容

  • 在全局启动设置增加“每次询问/始终备份/关闭”三种保护模式,默认选择“每次询问”
  • “每次询问”仅在隔离实例的 screenshots 中存在文件时弹窗,可选择备份并删除、直接删除或取消
  • 选择备份时,将 screenshotsschematics 递归复制到所选游戏目录下的 PCL/PersonalFiles/<实例名>
  • 备份失败时取消删除,避免原文件随实例删除;两个现有实例删除入口均已接入
  • “始终备份”模式的删除确认框显示“删除前会备份文件到文件夹。”

验证情况

  • dotnet build "Plain Craft Launcher 2/Plain Craft Launcher 2.csproj" -c Debug -p:Platform=x64 --no-restore:通过,0 个错误
  • 按官方工作流参数执行 x64 CI 配置 dotnet publish --no-self-contained:通过;生成的 .NET 10 可执行文件启动冒烟通过
  • 仓库外临时验证程序:截图目录不存在、空目录、嵌套截图触发,以及递归复制、已有文件覆盖、缺失来源目录与时间戳保持均通过
  • 当前 Windows 账户无创建符号链接权限;重解析点跳过逻辑已通过代码审查确认
  • git diff --check dev...feat/protect-instance-personal-files:通过

AI 使用

  • GPT-5.6:辅助实现、代码审查与本地验证
  • 仓库内未新增文档或测试文件

Summary by Sourcery

在删除隔离的 Minecraft 实例时,新增可配置的个人文件保护机制,包括可选地将截图和结构文件备份到专用归档文件夹。

New Features:

  • 引入一个全局设置,用于控制在删除隔离实例时个人文件的备份行为,支持三种模式:禁用、每次询问以及始终备份。
  • 添加备份流程,将实例的截图和结构文件复制到所选游戏目录下的按实例划分的归档目录中,并在备份成功后向用户展示反馈。

Enhancements:

  • 将个人文件备份提示和处理逻辑集成到现有的两个实例删除入口中,如果备份失败则阻止删除操作。
  • 通过使用不区分大小写的路径比较和增强的删除确认消息,改进隔离实例的检测和相关提示。
Original summary in English

Summary by Sourcery

Add configurable protection for personal files when deleting isolated Minecraft instances, including optional backup of screenshots and schematics to a dedicated archive folder.

New Features:

  • Introduce a global setting to control personal files backup behavior when deleting isolated instances, with disabled, ask every time, and always backup modes.
  • Add a backup workflow that copies instance screenshots and schematics into a per-instance archive under the selected game directory and shows user feedback on success.

Enhancements:

  • Integrate personal files backup hints and handling into both existing instance deletion entry points, preventing deletion if backup fails.
  • Improve isolated-instance detection and messaging by using case-insensitive path comparison and augmented delete confirmations.

@pcl-ce-automation pcl-ce-automation Bot added 🚧 正在处理 开发人员正在对该内容进行开发、测试或修复,进展中 size: L PR 大小评估:大型 labels Aug 14, 2026
@sourcery-ai

sourcery-ai Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

在删除隔离实例时新增可配置的个人文件备份流程,包括新的备份模式设置、UI 提示,以及用于截图和示意图的递归复制工具;当备份失败时会中止删除操作。

在删除隔离实例期间进行个人文件备份的时序图

sequenceDiagram
    actor User
    participant PageSelectRight
    participant ModPersonalFiles
    participant ModMain
    participant FileSystem

    User->>PageSelectRight: DeleteVersion(mcInstance)
    PageSelectRight->>ModPersonalFiles: GetDeleteHint()
    PageSelectRight->>ModMain: MyMsgBox(confirmFullMsg)
    ModMain-->>PageSelectRight: confirmResult = 1
    PageSelectRight->>ModPersonalFiles: TryHandleBeforeDelete(mcInstance)

    alt PersonalFilesBackupMode.Disabled
        ModPersonalFiles-->>PageSelectRight: return true
    else PersonalFilesBackupMode.AskEveryTime
        ModPersonalFiles->>ModPersonalFiles: _HasScreenshots(mcInstance.PathIndie)
        alt [no screenshots]
            ModPersonalFiles-->>PageSelectRight: return true
        else [screenshots exist]
            ModPersonalFiles->>ModMain: MyMsgBox(Ask.Message, Ask.Title)
            ModMain-->>ModPersonalFiles: promptResult
            alt promptResult == 2 (DeleteWithoutBackup)
                ModPersonalFiles-->>PageSelectRight: return true
            else promptResult != 1 (Cancel)
                ModPersonalFiles-->>PageSelectRight: return false
            else promptResult == 1 (BackupAndDelete)
                ModPersonalFiles->>ModPersonalFiles: _Backup(mcInstance)
                ModPersonalFiles->>FileSystem: Copy screenshots & schematics
                ModPersonalFiles->>HintService: Hint(Backup.Success)
                ModPersonalFiles-->>PageSelectRight: return true
            end
        end
    else PersonalFilesBackupMode.Always
        ModPersonalFiles->>ModPersonalFiles: _Backup(mcInstance)
        ModPersonalFiles->>FileSystem: Copy screenshots & schematics
        ModPersonalFiles->>HintService: Hint(Backup.Success)
        ModPersonalFiles-->>PageSelectRight: return true
    end

    PageSelectRight->>ModBase: IniClearCache(options.txt)
    PageSelectRight->>ConfigService: InvalidateCache(mcInstance.PathInstance)
    PageSelectRight->>FileSystem: Delete instance files
Loading

File-Level Changes

Change Details Files
为删除隔离实例时的个人文件新增可配置备份模式,并将其接入两个删除入口。
  • 添加 PersonalFilesBackupMode 枚举,用于表示 Disabled、AskEveryTime 和 Always 选项。
  • 通过新的 PersonalFilesBackup 配置属性持久化选定的备份模式,默认值为 AskEveryTime。
  • 在实例删除流程中挂接备份提示,并在继续删除前调用备份处理逻辑;当备份失败或用户取消时中止删除。
PCL.Core/App/ConfigEnums.cs
PCL.Core/App/Config.cs
Plain Craft Launcher 2/Pages/PageSelectRight.xaml.cs
Plain Craft Launcher 2/Pages/PageInstance/PageInstanceOverall.xaml.cs
添加 UI 控件和本地化字符串,使用户可以配置备份行为,并在删除和备份相关的信息上获得更清晰的提示。
  • 将启动设置页面中的下拉框绑定到 PersonalFilesBackup 配置值,使用户可以选择备份模式。
  • 更新删除确认消息,为隔离实例附加与备份相关的上下文敏感提示。
  • 在英文和中文资源文件中引入新的语言键,用于备份提示、交互对话和状态消息。
Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml.cs
Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml
PCL.Core/App/Localization/Languages/en-US.xaml
PCL.Core/App/Localization/Languages/zh-CN.xaml
实现 ModPersonalFiles 辅助模块,用于在安全检查和用户反馈的支持下递归备份截图和示意图。
  • 创建 ModPersonalFiles 静态类,在所选游戏目录下的 PCL/PersonalFiles/ 下建立归档根目录。
  • 实现 TryHandleBeforeDelete,以遵循备份模式,有条件地提示用户、执行备份,并显示成功或失败提示。
  • 实现递归目录复制逻辑:跳过重新解析点、保留时间戳并统计复制的文件数量,同时提供截图存在性检查以控制是否弹出提示。
Plain Craft Launcher 2/Modules/Minecraft/ModPersonalFiles.cs

Tips and commands

Interacting with Sourcery

  • 触发新的代码审查: 在拉取请求中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审查评论。
  • 从审查评论生成 GitHub Issue: 通过回复审查评论来请求 Sourcery 从该评论创建一个 Issue。你也可以在审查评论中回复 @sourcery-ai issue 来从该评论创建 Issue。
  • 生成拉取请求标题: 在拉取请求标题中任意位置写入 @sourcery-ai,即可随时生成标题。你也可以在拉取请求中评论 @sourcery-ai title 来(重新)生成标题。
  • 生成拉取请求摘要: 在拉取请求正文的任意位置写入 @sourcery-ai summary,即可在指定位置生成 PR 摘要。你也可以在拉取请求中评论 @sourcery-ai summary 来在任意时间(重新)生成摘要。
  • 生成审查者指南: 在拉取请求中评论 @sourcery-ai guide,即可在任意时间(重新)生成审查者指南。
  • 解决所有 Sourcery 评论: 在拉取请求中评论 @sourcery-ai resolve,即可解决所有 Sourcery 评论。如果你已经处理完所有评论且不再希望看到它们,这将非常有用。
  • 忽略所有 Sourcery 审查: 在拉取请求中评论 @sourcery-ai dismiss,即可忽略所有现有的 Sourcery 审查。特别适用于你希望从一次全新的审查开始——不要忘记再评论 @sourcery-ai review 以触发新的审查!

Customizing Your Experience

访问你的 dashboard 以:

  • 启用或禁用审查功能,例如 Sourcery 生成的拉取请求摘要、审查者指南等。
  • 更改审查语言。
  • 添加、移除或编辑自定义审查说明。
  • 调整其他审查设置。

Getting Help

Original review guide in English

Reviewer's Guide

Adds a configurable personal-files backup workflow when deleting isolated instances, including a new backup mode setting, UI hints, and a recursive copy utility for screenshots and schematics that aborts deletion on backup failure.

Sequence diagram for personal files backup during isolated instance deletion

sequenceDiagram
    actor User
    participant PageSelectRight
    participant ModPersonalFiles
    participant ModMain
    participant FileSystem

    User->>PageSelectRight: DeleteVersion(mcInstance)
    PageSelectRight->>ModPersonalFiles: GetDeleteHint()
    PageSelectRight->>ModMain: MyMsgBox(confirmFullMsg)
    ModMain-->>PageSelectRight: confirmResult = 1
    PageSelectRight->>ModPersonalFiles: TryHandleBeforeDelete(mcInstance)

    alt PersonalFilesBackupMode.Disabled
        ModPersonalFiles-->>PageSelectRight: return true
    else PersonalFilesBackupMode.AskEveryTime
        ModPersonalFiles->>ModPersonalFiles: _HasScreenshots(mcInstance.PathIndie)
        alt [no screenshots]
            ModPersonalFiles-->>PageSelectRight: return true
        else [screenshots exist]
            ModPersonalFiles->>ModMain: MyMsgBox(Ask.Message, Ask.Title)
            ModMain-->>ModPersonalFiles: promptResult
            alt promptResult == 2 (DeleteWithoutBackup)
                ModPersonalFiles-->>PageSelectRight: return true
            else promptResult != 1 (Cancel)
                ModPersonalFiles-->>PageSelectRight: return false
            else promptResult == 1 (BackupAndDelete)
                ModPersonalFiles->>ModPersonalFiles: _Backup(mcInstance)
                ModPersonalFiles->>FileSystem: Copy screenshots & schematics
                ModPersonalFiles->>HintService: Hint(Backup.Success)
                ModPersonalFiles-->>PageSelectRight: return true
            end
        end
    else PersonalFilesBackupMode.Always
        ModPersonalFiles->>ModPersonalFiles: _Backup(mcInstance)
        ModPersonalFiles->>FileSystem: Copy screenshots & schematics
        ModPersonalFiles->>HintService: Hint(Backup.Success)
        ModPersonalFiles-->>PageSelectRight: return true
    end

    PageSelectRight->>ModBase: IniClearCache(options.txt)
    PageSelectRight->>ConfigService: InvalidateCache(mcInstance.PathInstance)
    PageSelectRight->>FileSystem: Delete instance files
Loading

File-Level Changes

Change Details Files
Introduce configurable backup modes for personal files when deleting isolated instances and wire them into both deletion entry points.
  • Add PersonalFilesBackupMode enum to represent Disabled, AskEveryTime, and Always options.
  • Persist selected backup mode in configuration via new PersonalFilesBackup property with default AskEveryTime.
  • Hook instance deletion flows to display backup hints and call backup handler before proceeding, aborting deletion if backup fails or user cancels.
PCL.Core/App/ConfigEnums.cs
PCL.Core/App/Config.cs
Plain Craft Launcher 2/Pages/PageSelectRight.xaml.cs
Plain Craft Launcher 2/Pages/PageInstance/PageInstanceOverall.xaml.cs
Add UI controls and localization strings to let users configure backup behavior and see clearer messaging around deletion and backups.
  • Bind launch setup page combo box to PersonalFilesBackup config value so users can choose backup mode.
  • Update deletion confirmation messages to append context-sensitive backup hints for isolated instances.
  • Introduce new language keys for backup hints, prompts, and status messages in both English and Chinese resource files.
Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml.cs
Plain Craft Launcher 2/Pages/PageSetup/PageSetupLaunch.xaml
PCL.Core/App/Localization/Languages/en-US.xaml
PCL.Core/App/Localization/Languages/zh-CN.xaml
Implement ModPersonalFiles helper to perform recursive backup of screenshots and schematics with safety checks and user feedback.
  • Create ModPersonalFiles static class with archive root under selected game folder PCL/PersonalFiles/.
  • Implement TryHandleBeforeDelete to honor backup mode, conditionally prompt the user, run backup, and show success or failure hints.
  • Implement recursive directory copy logic that skips reparse points, preserves timestamps, and counts copied files, plus a screenshots existence check to gate prompts.
Plain Craft Launcher 2/Modules/Minecraft/ModPersonalFiles.cs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@nya-a-cat

Copy link
Copy Markdown
Author

关于备份截图的想法,得和 @Pigeon0v0 探讨下,删除实例损失了游玩的回忆会很可惜,但仍不确定这个功能,要以何种方式实现,目前的想法是全局设置打开后,删除游戏时会先备份截图。投影原理图是顺带的。

@Pigeon0v0

Copy link
Copy Markdown
Contributor

可以加一个每次均询问的选项,如果截图文件夹里有东西就弹个窗问一下

@nya-a-cat
nya-a-cat marked this pull request as ready for review August 14, 2026 09:54
@pcl-ce-automation pcl-ce-automation Bot added 🛠️ 等待审查 Pull Request 已完善,等待维护者或负责人进行代码审查 and removed 🚧 正在处理 开发人员正在对该内容进行开发、测试或修复,进展中 labels Aug 14, 2026

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我在这里给出了一些总体反馈:

  • 请考虑在 ModPersonalFiles._ArchiveRoot 中针对 ModFolder.mcFolderSelected 为空或未设置的情况进行保护,这样在未选择游戏根目录时触发的删除流程就不会抛出异常或生成无效的备份路径。
  • _CopyDirectory 中,确保在调用 ModBase.CopyFile 之前先创建目标子目录(例如通过 Directory.CreateDirectory(Path.GetDirectoryName(targetFile))),这样无论 CopyFile 的具体行为如何,嵌套的 screenshots/schematics 文件都能被可靠地复制。
供 AI 代理使用的提示
Please address the comments from this code review:

## Overall Comments
- Consider guarding `ModPersonalFiles._ArchiveRoot` against a null or unset `ModFolder.mcFolderSelected` so that delete flows invoked when no game root is selected don’t throw or produce an invalid backup path.
- In `_CopyDirectory`, ensure the target subdirectories are created (e.g. via `Directory.CreateDirectory(Path.GetDirectoryName(targetFile))`) before calling `ModBase.CopyFile` so nested `screenshots/schematics` files are copied reliably regardless of `CopyFile`'s behavior.

Sourcery 对开源项目是免费的——如果你觉得我们的代码审查有帮助,请考虑分享它 ✨
帮我变得更有用!请对每条评论点击 👍 或 👎,我会根据这些反馈改进为你提供的代码审查。
Original comment in English

Hey - I've left some high level feedback:

  • Consider guarding ModPersonalFiles._ArchiveRoot against a null or unset ModFolder.mcFolderSelected so that delete flows invoked when no game root is selected don’t throw or produce an invalid backup path.
  • In _CopyDirectory, ensure the target subdirectories are created (e.g. via Directory.CreateDirectory(Path.GetDirectoryName(targetFile))) before calling ModBase.CopyFile so nested screenshots/schematics files are copied reliably regardless of CopyFile's behavior.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider guarding `ModPersonalFiles._ArchiveRoot` against a null or unset `ModFolder.mcFolderSelected` so that delete flows invoked when no game root is selected don’t throw or produce an invalid backup path.
- In `_CopyDirectory`, ensure the target subdirectories are created (e.g. via `Directory.CreateDirectory(Path.GetDirectoryName(targetFile))`) before calling `ModBase.CopyFile` so nested `screenshots/schematics` files are copied reliably regardless of `CopyFile`'s behavior.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ec82020b51

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

{
case 1:
{
if (isHintIndie && !ModPersonalFiles.TryHandleBeforeDelete(mcInstance)) return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Back up isolated instances even when validation fails

When an isolated instance has a corrupt or unreadable version definition, its state is McInstanceState.Error, which forces isHintIndie to false and skips this new backup handler even if PathIndie is the instance directory. The delete operation still removes PathInstance, so screenshots and schematics are silently lost under both Ask and Always modes; determine isolation from the configured/path relationship or probe the instance directory independently of validation state.

Useful? React with 👍 / 👎.

This comment was marked as spam.

@MoYuan-CN
MoYuan-CN requested a review from a team August 23, 2026 09:51
@MoYuan-CN

Copy link
Copy Markdown
Member

Request pcl-community/ce-dev Review 就好了,不要 @ 这么多人……

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size: L PR 大小评估:大型 🛠️ 等待审查 Pull Request 已完善,等待维护者或负责人进行代码审查

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants