Conversation
Reviewer's Guide在模组下载过程中实现所需前置模组依赖的自动安装,包括可复用的依赖解析引擎、与下载流程的集成、配置和 UI 开关,以及单元测试。 带自动依赖安装的模组下载顺序图sequenceDiagram
actor User
participant PageDownloadCompDetail
participant ModCompDependency
participant ModDependencyResolver
participant ModMain
participant ModLoader
User->>PageDownloadCompDetail: Click_Save_for_mod_download
PageDownloadCompDetail->>PageDownloadCompDetail: Determine_targetDir_and_AllowedLoaders
alt AutoInstallDependencies_enabled_and_mod_has_Dependencies
PageDownloadCompDetail->>PageDownloadCompDetail: Detect_targetInstance_and_MC_version
PageDownloadCompDetail->>ModCompDependency: BuildRequest(file, project, mcVersion, targetLoaders, targetDir)
ModCompDependency-->>PageDownloadCompDetail: ModDependencyRequest
PageDownloadCompDetail->>ModDependencyResolver: Resolve(request)
ModDependencyResolver-->>PageDownloadCompDetail: ModDependencyResolutionResult
PageDownloadCompDetail->>ModCompDependency: ConfirmDependencyInstall(result)
ModCompDependency->>ModMain: MyMsgBox(confirm_message)
ModMain-->>ModCompDependency: user_choice
ModCompDependency-->>PageDownloadCompDetail: bool_confirmed
alt User_confirms
PageDownloadCompDetail->>ModCompDependency: BuildDependencyDownloads(result, targetDir)
ModCompDependency-->>PageDownloadCompDetail: List_DownloadFile_depDownloads
PageDownloadCompDetail->>PageDownloadCompDetail: Prepend_depDownloads_to_downloadFiles
else User_cancels
PageDownloadCompDetail-->>User: Abort_download
PageDownloadCompDetail->>PageDownloadCompDetail: return
end
else AutoInstallDependencies_disabled_or_no_Dependencies
PageDownloadCompDetail->>PageDownloadCompDetail: Prepare_single_mod_downloadFile
end
PageDownloadCompDetail->>ModLoader: Start_LoaderDownload("下载文件", downloadFiles)
ModLoader-->>User: Download_mod_and_dependencies
ModDependencyResolver 及相关类型类图classDiagram
class ModDependencyReference {
+string ProjectId
+string Source
+bool IsRequired
}
class ModDependencyRequest {
+string TargetMinecraftVersion
+List~string~ TargetLoaders
+List~ModDependencyReference~ RequiredDependencies
+List~InstalledModIdentity~ InstalledMods
+Func~string,string,ModDependencyProject?~ ProjectResolver
}
class ModDependencyProject {
+string ProjectId
+string Source
+string ProjectName
+List~ModDependencyReference~ RequiredDependencies
+List~ModDependencyFile~ Files
}
class ModDependencyFile {
+string Id
+string DisplayName
+string Version
+List~string~ GameVersions
+List~string~ Loaders
+int ReleaseType
+DateTime ReleaseDate
+List~ModDependencyReference~ RequiredDependencies
}
class InstalledModIdentity {
+string SourceProjectId
+string Source
+string ModId
+List~string~ GameVersions
+List~string~ Loaders
}
class ModDependencyResolutionResult {
+List~ResolvedDependencyInstall~ ToInstall
+List~UnresolvedDependency~ Unresolved
+List~IgnoredDependency~ Satisfied
}
class ResolvedDependencyInstall {
+string ProjectId
+string Source
+string ProjectName
+ModDependencyFile File
}
class UnresolvedDependency {
+string ProjectId
+string Source
+string Reason
}
class IgnoredDependency {
+string ProjectId
+string Source
+string Reason
}
class ModDependencyResolver {
+Resolve(request ModDependencyRequest) ModDependencyResolutionResult
-ResolveDependency(context ResolutionContext, dependency ModDependencyReference, depth int) void
-SelectBestFile(files IEnumerable~ModDependencyFile~, targetMinecraftVersion string, targetLoaders HashSet~string~) ModDependencyFile
-IsCompatibleFile(file ModDependencyFile, targetMinecraftVersion string, targetLoaders HashSet~string~) bool
-HasExactGameVersionMatch(file ModDependencyFile, targetMinecraftVersion string) bool
-HasLoaderMatch(file ModDependencyFile, targetLoaders HashSet~string~) bool
-NormalizeReleaseType(releaseType int) int
}
class ResolutionContext {
+ModDependencyRequest Request
+ModDependencyResolutionResult Result
+HashSet~string~ Visited
+string TargetMinecraftVersion
+HashSet~string~ TargetLoaders
+GetVisitedKey(projectId string, source string) string
+IsInstalledCompatible(projectId string, source string) bool
+AddInstall(project ModDependencyProject, file ModDependencyFile) void
+AddUnresolved(projectId string, source string, reason string) void
+AddSatisfied(projectId string, source string, reason string) void
-bool LoadersCompatible(installedLoaders List~string~)
-string GetProjectKey(projectId string, source string)
}
ModDependencyResolver --> ResolutionContext : uses
ModDependencyRequest --> ModDependencyReference : contains
ModDependencyRequest --> InstalledModIdentity : contains
ModDependencyRequest --> ModDependencyProject : uses via ProjectResolver
ModDependencyProject --> ModDependencyReference : contains
ModDependencyProject --> ModDependencyFile : contains
ModDependencyFile --> ModDependencyReference : contains
ModDependencyResolutionResult --> ResolvedDependencyInstall : contains
ModDependencyResolutionResult --> UnresolvedDependency : contains
ModDependencyResolutionResult --> IgnoredDependency : contains
ResolvedDependencyInstall --> ModDependencyFile : contains
ResolutionContext --> ModDependencyRequest : has
ResolutionContext --> ModDependencyResolutionResult : builds
ResolutionContext --> InstalledModIdentity : checks compatibility
ModCompDependency 集成层类图classDiagram
class CompFile {
+string Id
+string DisplayName
+string Version
+List~string~ GameVersions
+List~CompLoaderType~ ModLoaders
+List~string~ Dependencies
+List~string~ OptionalDependencies
+CompType Type
+List~string~ ToNetFile(target string)
}
class CompProject {
+string Id
+bool FromCurseForge
+string TranslatedName
+string RawName
}
class LocalCompFile {
+string ModId
+CompProject Comp
+CompFile CompFile
+Load() void
+static IsModFile(path string) bool
}
class ModCompDependency {
<<static>>
+BuildRequest(file CompFile, project CompProject, targetMinecraftVersion string, targetLoaders List~CompLoaderType~, targetModsFolder string) ModDependencyRequest
+ScanInstalledMods(targetModsFolder string) List~InstalledModIdentity~
+ResolveProjectFiles(source string, projectId string) ModDependencyProject
+SelectCompatibleDependencyFile(result ModDependencyResolutionResult, projectId string, source string) ModDependencyFile
+BuildDependencyDownloads(result ModDependencyResolutionResult, targetModsFolder string) List~DownloadFile~
+ConfirmDependencyInstall(result ModDependencyResolutionResult) bool
+ShowDependencyAbortMessage(reason string) void
-string GetSource(fromCurseForge bool)
-List~string~ ToLoaderNames(loaders IEnumerable~CompLoaderType~)
-int MapReleaseType(status CompFileStatus)
}
class DownloadFile {
}
class ModComp {
+static Dictionary~string,CompProject~ CompProjectCache
+static List~CompFile~ CompFilesGet(projectId string, fromCurseForge bool)
+static string CompFileNameGet(project CompProject, file CompFile)
}
class InstalledModIdentity {
+string SourceProjectId
+string Source
+string ModId
+List~string~ GameVersions
+List~string~ Loaders
}
class ModDependencyRequest {
}
class ModDependencyProject {
}
class ModDependencyFile {
}
class ModDependencyResolutionResult {
+List~ResolvedDependencyInstall~ ToInstall
+List~UnresolvedDependency~ Unresolved
+List~IgnoredDependency~ Satisfied
}
class ModMain {
+static int MyMsgBox(message string, title string, Button1 string, Button2 string, bool IsWarn, bool ForceWait)
}
ModCompDependency --> ModDependencyRequest : builds
ModCompDependency --> InstalledModIdentity : returns
ModCompDependency --> ModDependencyProject : returns
ModCompDependency --> ModDependencyFile : returns
ModCompDependency --> ModDependencyResolutionResult : consumes
ModCompDependency --> DownloadFile : builds
ModCompDependency --> ModMain : shows dialogs
ModCompDependency --> CompFile : from
ModCompDependency --> CompProject : from
ModCompDependency --> LocalCompFile : scans
ModComp --> CompProject : caches
ModComp --> CompFile : provides
ModCompDependency --> ModComp : queries caches
文件级变更
与关联 Issue 的对照评估
可能相关的 Issue
技巧与命令与 Sourcery 交互
自定义你的使用体验访问你的 控制面板 来:
获取帮助Original review guide in EnglishReviewer's GuideImplements automatic installation of required mod dependencies during mod downloads, including a reusable dependency resolution engine, wiring it into the download flow, configuration and UI toggles, and unit tests. Sequence diagram for mod download with automatic dependency installationsequenceDiagram
actor User
participant PageDownloadCompDetail
participant ModCompDependency
participant ModDependencyResolver
participant ModMain
participant ModLoader
User->>PageDownloadCompDetail: Click_Save_for_mod_download
PageDownloadCompDetail->>PageDownloadCompDetail: Determine_targetDir_and_AllowedLoaders
alt AutoInstallDependencies_enabled_and_mod_has_Dependencies
PageDownloadCompDetail->>PageDownloadCompDetail: Detect_targetInstance_and_MC_version
PageDownloadCompDetail->>ModCompDependency: BuildRequest(file, project, mcVersion, targetLoaders, targetDir)
ModCompDependency-->>PageDownloadCompDetail: ModDependencyRequest
PageDownloadCompDetail->>ModDependencyResolver: Resolve(request)
ModDependencyResolver-->>PageDownloadCompDetail: ModDependencyResolutionResult
PageDownloadCompDetail->>ModCompDependency: ConfirmDependencyInstall(result)
ModCompDependency->>ModMain: MyMsgBox(confirm_message)
ModMain-->>ModCompDependency: user_choice
ModCompDependency-->>PageDownloadCompDetail: bool_confirmed
alt User_confirms
PageDownloadCompDetail->>ModCompDependency: BuildDependencyDownloads(result, targetDir)
ModCompDependency-->>PageDownloadCompDetail: List_DownloadFile_depDownloads
PageDownloadCompDetail->>PageDownloadCompDetail: Prepend_depDownloads_to_downloadFiles
else User_cancels
PageDownloadCompDetail-->>User: Abort_download
PageDownloadCompDetail->>PageDownloadCompDetail: return
end
else AutoInstallDependencies_disabled_or_no_Dependencies
PageDownloadCompDetail->>PageDownloadCompDetail: Prepare_single_mod_downloadFile
end
PageDownloadCompDetail->>ModLoader: Start_LoaderDownload("下载文件", downloadFiles)
ModLoader-->>User: Download_mod_and_dependencies
Class diagram for ModDependencyResolver and related typesclassDiagram
class ModDependencyReference {
+string ProjectId
+string Source
+bool IsRequired
}
class ModDependencyRequest {
+string TargetMinecraftVersion
+List~string~ TargetLoaders
+List~ModDependencyReference~ RequiredDependencies
+List~InstalledModIdentity~ InstalledMods
+Func~string,string,ModDependencyProject?~ ProjectResolver
}
class ModDependencyProject {
+string ProjectId
+string Source
+string ProjectName
+List~ModDependencyReference~ RequiredDependencies
+List~ModDependencyFile~ Files
}
class ModDependencyFile {
+string Id
+string DisplayName
+string Version
+List~string~ GameVersions
+List~string~ Loaders
+int ReleaseType
+DateTime ReleaseDate
+List~ModDependencyReference~ RequiredDependencies
}
class InstalledModIdentity {
+string SourceProjectId
+string Source
+string ModId
+List~string~ GameVersions
+List~string~ Loaders
}
class ModDependencyResolutionResult {
+List~ResolvedDependencyInstall~ ToInstall
+List~UnresolvedDependency~ Unresolved
+List~IgnoredDependency~ Satisfied
}
class ResolvedDependencyInstall {
+string ProjectId
+string Source
+string ProjectName
+ModDependencyFile File
}
class UnresolvedDependency {
+string ProjectId
+string Source
+string Reason
}
class IgnoredDependency {
+string ProjectId
+string Source
+string Reason
}
class ModDependencyResolver {
+Resolve(request ModDependencyRequest) ModDependencyResolutionResult
-ResolveDependency(context ResolutionContext, dependency ModDependencyReference, depth int) void
-SelectBestFile(files IEnumerable~ModDependencyFile~, targetMinecraftVersion string, targetLoaders HashSet~string~) ModDependencyFile
-IsCompatibleFile(file ModDependencyFile, targetMinecraftVersion string, targetLoaders HashSet~string~) bool
-HasExactGameVersionMatch(file ModDependencyFile, targetMinecraftVersion string) bool
-HasLoaderMatch(file ModDependencyFile, targetLoaders HashSet~string~) bool
-NormalizeReleaseType(releaseType int) int
}
class ResolutionContext {
+ModDependencyRequest Request
+ModDependencyResolutionResult Result
+HashSet~string~ Visited
+string TargetMinecraftVersion
+HashSet~string~ TargetLoaders
+GetVisitedKey(projectId string, source string) string
+IsInstalledCompatible(projectId string, source string) bool
+AddInstall(project ModDependencyProject, file ModDependencyFile) void
+AddUnresolved(projectId string, source string, reason string) void
+AddSatisfied(projectId string, source string, reason string) void
-bool LoadersCompatible(installedLoaders List~string~)
-string GetProjectKey(projectId string, source string)
}
ModDependencyResolver --> ResolutionContext : uses
ModDependencyRequest --> ModDependencyReference : contains
ModDependencyRequest --> InstalledModIdentity : contains
ModDependencyRequest --> ModDependencyProject : uses via ProjectResolver
ModDependencyProject --> ModDependencyReference : contains
ModDependencyProject --> ModDependencyFile : contains
ModDependencyFile --> ModDependencyReference : contains
ModDependencyResolutionResult --> ResolvedDependencyInstall : contains
ModDependencyResolutionResult --> UnresolvedDependency : contains
ModDependencyResolutionResult --> IgnoredDependency : contains
ResolvedDependencyInstall --> ModDependencyFile : contains
ResolutionContext --> ModDependencyRequest : has
ResolutionContext --> ModDependencyResolutionResult : builds
ResolutionContext --> InstalledModIdentity : checks compatibility
Class diagram for ModCompDependency integration layerclassDiagram
class CompFile {
+string Id
+string DisplayName
+string Version
+List~string~ GameVersions
+List~CompLoaderType~ ModLoaders
+List~string~ Dependencies
+List~string~ OptionalDependencies
+CompType Type
+List~string~ ToNetFile(target string)
}
class CompProject {
+string Id
+bool FromCurseForge
+string TranslatedName
+string RawName
}
class LocalCompFile {
+string ModId
+CompProject Comp
+CompFile CompFile
+Load() void
+static IsModFile(path string) bool
}
class ModCompDependency {
<<static>>
+BuildRequest(file CompFile, project CompProject, targetMinecraftVersion string, targetLoaders List~CompLoaderType~, targetModsFolder string) ModDependencyRequest
+ScanInstalledMods(targetModsFolder string) List~InstalledModIdentity~
+ResolveProjectFiles(source string, projectId string) ModDependencyProject
+SelectCompatibleDependencyFile(result ModDependencyResolutionResult, projectId string, source string) ModDependencyFile
+BuildDependencyDownloads(result ModDependencyResolutionResult, targetModsFolder string) List~DownloadFile~
+ConfirmDependencyInstall(result ModDependencyResolutionResult) bool
+ShowDependencyAbortMessage(reason string) void
-string GetSource(fromCurseForge bool)
-List~string~ ToLoaderNames(loaders IEnumerable~CompLoaderType~)
-int MapReleaseType(status CompFileStatus)
}
class DownloadFile {
}
class ModComp {
+static Dictionary~string,CompProject~ CompProjectCache
+static List~CompFile~ CompFilesGet(projectId string, fromCurseForge bool)
+static string CompFileNameGet(project CompProject, file CompFile)
}
class InstalledModIdentity {
+string SourceProjectId
+string Source
+string ModId
+List~string~ GameVersions
+List~string~ Loaders
}
class ModDependencyRequest {
}
class ModDependencyProject {
}
class ModDependencyFile {
}
class ModDependencyResolutionResult {
+List~ResolvedDependencyInstall~ ToInstall
+List~UnresolvedDependency~ Unresolved
+List~IgnoredDependency~ Satisfied
}
class ModMain {
+static int MyMsgBox(message string, title string, Button1 string, Button2 string, bool IsWarn, bool ForceWait)
}
ModCompDependency --> ModDependencyRequest : builds
ModCompDependency --> InstalledModIdentity : returns
ModCompDependency --> ModDependencyProject : returns
ModCompDependency --> ModDependencyFile : returns
ModCompDependency --> ModDependencyResolutionResult : consumes
ModCompDependency --> DownloadFile : builds
ModCompDependency --> ModMain : shows dialogs
ModCompDependency --> CompFile : from
ModCompDependency --> CompProject : from
ModCompDependency --> LocalCompFile : scans
ModComp --> CompProject : caches
ModComp --> CompFile : provides
ModCompDependency --> ModComp : queries caches
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - 我在这里给出了一些高层面的反馈:
- 在 Save_Click 的依赖处理代码块中,如果在解析依赖时发生任何异常,当前行为是记录日志然后直接返回,而不会通知用户或继续原始模组的下载;建议调用 ShowDependencyAbortMessage(或以其他方式向用户展示提示信息)以及/或者回退为仅下载所选模组,这样依赖解析失败时就不会在无提示的情况下静默失败。
- ModDependencyProject.RequiredDependencies 在 ResolveProjectFiles 中被填充,但 ModDependencyResolver 从未读取该字段,而是只使用按文件(per-file)的 RequiredDependencies;如果项目级的依赖并不是必需的,建议移除该字段及其赋值逻辑,以减少关于依赖遍历行为的困惑。
给 AI 代理的提示
请根据这次代码评审中的评论进行修改:
## 总体评论
- 在 Save_Click 的依赖处理代码块中,如果在解析依赖时发生任何异常,当前行为是记录日志然后直接返回,而不会通知用户或继续原始模组的下载;建议调用 ShowDependencyAbortMessage(或以其他方式向用户展示提示信息)以及/或者回退为仅下载所选模组,这样依赖解析失败时就不会在无提示的情况下静默失败。
- ModDependencyProject.RequiredDependencies 在 ResolveProjectFiles 中被填充,但 ModDependencyResolver 从未读取该字段,而是只使用按文件(per-file)的 RequiredDependencies;如果项目级的依赖并不是必需的,建议移除该字段及其赋值逻辑,以减少关于依赖遍历行为的困惑。帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续的评审。
Original comment in English
Hey - I've left some high level feedback:
- In the Save_Click dependency handling block, any exception during dependency resolution logs and then returns without notifying the user or proceeding with the original mod download; consider invoking ShowDependencyAbortMessage (or otherwise surfacing a message) and/or falling back to downloading just the selected mod so failures are not silent.
- ModDependencyProject.RequiredDependencies is populated in ResolveProjectFiles but never read by ModDependencyResolver, which only uses per-file RequiredDependencies; if project-level dependencies are not needed, consider removing this field/population to reduce confusion about how dependency traversal works.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In the Save_Click dependency handling block, any exception during dependency resolution logs and then returns without notifying the user or proceeding with the original mod download; consider invoking ShowDependencyAbortMessage (or otherwise surfacing a message) and/or falling back to downloading just the selected mod so failures are not silent.
- ModDependencyProject.RequiredDependencies is populated in ResolveProjectFiles but never read by ModDependencyResolver, which only uses per-file RequiredDependencies; if project-level dependencies are not needed, consider removing this field/population to reduce confusion about how dependency traversal works.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Remove the fallback to project-level dependencies when resolving nested dependencies, ensuring that only the dependencies explicitly required by the selected file are processed.
e01f2e1 to
8c6fe77
Compare
Contributor
|
考虑在实例 Mod 列表内检测一下么 如果已经有了就当我没说( |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Close #557
Summary by Sourcery
在模组下载过程中,新增对所需模组依赖的自动解析和安装功能,包括配置项、UI 开关、解析核心逻辑以及相关辅助工具。
新功能:
错误修复:
改进内容:
测试:
Original summary in English
Summary by Sourcery
Add automatic resolution and installation of required mod dependencies during mod downloads, including configuration, UI toggle, resolver core, and supporting utilities.
New Features:
Bug Fixes:
Enhancements:
Tests: