|
|
@@ -982,7 +982,8 @@ Retry:
|
|
|
"modtranslations", 'Mod 翻译
|
|
|
"schematics", 'schematics 模组
|
|
|
".*\.BakaCoreInfo", 'BakaXL 配置
|
|
|
- "hmclversion\.cfg", "log4j2\.xml" 'HMCL 配置
|
|
|
+ "hmclversion\.cfg", "log4j2\.xml", 'HMCL 配置
|
|
|
+ "assets", "libraries", "\$natives", "launcher_profiles\.json", "versions" '开启版本隔离时排除的文件
|
|
|
}
|
|
|
Public Function IsVerRedundant(FilePath As String) As Boolean
|
|
|
FilePath = FilePath.Replace("/", "\")
|
|
|
@@ -999,9 +1000,9 @@ Retry:
|
|
|
Private MustExport As String() = {
|
|
|
"mods", "PCL", ".*\.json"
|
|
|
}
|
|
|
- Public Function IsMustExport(FileName As String) As Boolean
|
|
|
+ Public Function IsMustExport(FilePath As String) As Boolean
|
|
|
For Each regex In MustExport
|
|
|
- If RegexCheck(FileName, regex, RegularExpressions.RegexOptions.IgnoreCase) Then Return True
|
|
|
+ If RegexCheck(GetFileNameFromPath(FilePath), regex, RegularExpressions.RegexOptions.IgnoreCase) Then Return True
|
|
|
Next
|
|
|
Return False
|
|
|
End Function
|
|
|
@@ -1015,112 +1016,112 @@ Retry:
|
|
|
Log($"[Export] 缓存文件夹:{tempDir}")
|
|
|
Directory.CreateDirectory(tempDir)
|
|
|
|
|
|
- '步骤 1:从 Modrinth 获取 Mod 工程信息,得到 URL
|
|
|
- Dim Mods As New List(Of McMod)
|
|
|
- If Directory.Exists(Version.Path & "mods\") Then
|
|
|
- For Each m In Directory.EnumerateFiles(Version.Path & "mods\")
|
|
|
- If m.EndsWithF(".jar") Then Mods.Add(New McMod(m))
|
|
|
- Next
|
|
|
- End If
|
|
|
+ ' '步骤 1:从 Modrinth 获取 Mod 工程信息,得到 URL
|
|
|
+ ' Dim Mods As New List(Of McMod)
|
|
|
+ ' If Directory.Exists(Version.Path & "mods\") Then
|
|
|
+ ' For Each m In Directory.EnumerateFiles(Version.Path & "mods\")
|
|
|
+ ' If m.EndsWithF(".jar") Then Mods.Add(New McMod(m))
|
|
|
+ ' Next
|
|
|
+ ' End If
|
|
|
|
|
|
- '从 Modrinth 获取信息
|
|
|
- Dim ModrinthHashes = Mods.Select(Function(m) m.ModrinthHash).ToList()
|
|
|
- Dim ModrinthVersion = CType(GetJson(NetRequestRetry("https://api.modrinth.com/v2/version_files", "POST",
|
|
|
- $"{{""hashes"": [""{ModrinthHashes.Join(""",""")}""], ""algorithm"": ""sha1""}}", "application/json")), JObject)
|
|
|
- Log($"[Export] 从 Modrinth 获取到 {ModrinthVersion.Count} 个本地 Mod 的对应信息")
|
|
|
+ ' '从 Modrinth 获取信息
|
|
|
+ ' Dim ModrinthHashes = Mods.Select(Function(m) m.ModrinthHash).ToList()
|
|
|
+ ' Dim ModrinthVersion = CType(GetJson(NetRequestRetry("https://api.modrinth.com/v2/version_files", "POST",
|
|
|
+ '$"{{""hashes"": [""{ModrinthHashes.Join(""",""")}""], ""algorithm"": ""sha1""}}", "application/json")), JObject)
|
|
|
+ ' Log($"[Export] 从 Modrinth 获取到 {ModrinthVersion.Count} 个本地 Mod 的对应信息")
|
|
|
|
|
|
- Dim ModrinthMapping As New Dictionary(Of String, JObject) 'Modrinth 获取到的 Mod
|
|
|
- Dim ModrinthFailed As New List(Of McMod) 'Modrinth 获取失败的 Mod
|
|
|
- For Each Entry In Mods
|
|
|
- If (Not ModrinthVersion.ContainsKey(Entry.ModrinthHash)) OrElse
|
|
|
- (ModrinthVersion(Entry.ModrinthHash)("files")(0)("hashes")("sha1") <> Entry.ModrinthHash) Then
|
|
|
- ModrinthFailed.Add(Entry)
|
|
|
- Continue For
|
|
|
- End If
|
|
|
- ModrinthMapping.Add(Entry.FileName, ModrinthVersion(Entry.ModrinthHash)("files")(0))
|
|
|
- Next
|
|
|
+ ' Dim ModrinthMapping As New Dictionary(Of String, JObject) 'Modrinth 获取到的 Mod
|
|
|
+ ' Dim ModrinthFailed As New List(Of McMod) 'Modrinth 获取失败的 Mod
|
|
|
+ ' For Each Entry In Mods
|
|
|
+ ' If (Not ModrinthVersion.ContainsKey(Entry.ModrinthHash)) OrElse
|
|
|
+ ' (ModrinthVersion(Entry.ModrinthHash)("files")(0)("hashes")("sha1") <> Entry.ModrinthHash) Then
|
|
|
+ ' ModrinthFailed.Add(Entry)
|
|
|
+ ' Continue For
|
|
|
+ ' End If
|
|
|
+ ' ModrinthMapping.Add(Entry.FileName, ModrinthVersion(Entry.ModrinthHash)("files")(0))
|
|
|
+ ' Next
|
|
|
|
|
|
- '步骤 2:把获取失败的 Mod 从 CurseForge 继续获取
|
|
|
- Dim CurseForgeHashes = ModrinthFailed.Select(Function(m) m.CurseForgeHash).ToList()
|
|
|
- Dim CurseForgeRaw = CType(CType(GetJson(NetRequestRetry("https://api.curseforge.com/v1/fingerprints/432/", "POST",
|
|
|
- $"{{""fingerprints"": [{CurseForgeHashes.Join(",")}]}}", "application/json")), JObject)("data")("exactMatches"), JContainer)
|
|
|
- Log($"[Export] 从 CurseForge 获取到 {CurseForgeRaw.Count} 个本地 Mod 的对应信息")
|
|
|
+ ' '步骤 2:把获取失败的 Mod 从 CurseForge 继续获取
|
|
|
+ ' Dim CurseForgeHashes = ModrinthFailed.Select(Function(m) m.CurseForgeHash).ToList()
|
|
|
+ ' Dim CurseForgeRaw = CType(CType(GetJson(NetRequestRetry("https://api.curseforge.com/v1/fingerprints/432/", "POST",
|
|
|
+ ' $"{{""fingerprints"": [{CurseForgeHashes.Join(",")}]}}", "application/json")), JObject)("data")("exactMatches"), JContainer)
|
|
|
+ ' Log($"[Export] 从 CurseForge 获取到 {CurseForgeRaw.Count} 个本地 Mod 的对应信息")
|
|
|
|
|
|
|
|
|
- Dim CurseForgeMapping As New Dictionary(Of String, JObject) 'CurseForge 获取到的 Mod
|
|
|
- For Each m In CurseForgeRaw
|
|
|
- Dim hash As String = ""
|
|
|
- For Each h In m("file")("hashes") '获取 Modrinth Hash
|
|
|
- If h("algo").ToString = 1 Then
|
|
|
- hash = h("value")
|
|
|
- Exit For
|
|
|
- End If
|
|
|
- Next
|
|
|
- If String.IsNullOrEmpty(hash) OrElse String.IsNullOrEmpty(m("file")("downloadUrl")) Then Continue For
|
|
|
+ ' Dim CurseForgeMapping As New Dictionary(Of String, JObject) 'CurseForge 获取到的 Mod
|
|
|
+ ' For Each m In CurseForgeRaw
|
|
|
+ ' Dim hash As String = ""
|
|
|
+ ' For Each h In m("file")("hashes") '获取 Modrinth Hash
|
|
|
+ ' If h("algo").ToString = 1 Then
|
|
|
+ ' hash = h("value")
|
|
|
+ ' Exit For
|
|
|
+ ' End If
|
|
|
+ ' Next
|
|
|
+ ' If String.IsNullOrEmpty(hash) OrElse String.IsNullOrEmpty(m("file")("downloadUrl")) Then Continue For
|
|
|
|
|
|
- m("file")("ModrinthHash") = hash
|
|
|
- CurseForgeMapping.Add(m("file")("fileName"), m("file"))
|
|
|
- For Each file In ModrinthFailed
|
|
|
- If file.ModrinthHash = hash Then
|
|
|
- ModrinthFailed.Remove(file)
|
|
|
- Exit For
|
|
|
- End If
|
|
|
- Next
|
|
|
- Next
|
|
|
+ ' m("file")("ModrinthHash") = hash
|
|
|
+ ' CurseForgeMapping.Add(m("file")("fileName"), m("file"))
|
|
|
+ ' For Each file In ModrinthFailed
|
|
|
+ ' If file.ModrinthHash = hash Then
|
|
|
+ ' ModrinthFailed.Remove(file)
|
|
|
+ ' Exit For
|
|
|
+ ' End If
|
|
|
+ ' Next
|
|
|
+ ' Next
|
|
|
|
|
|
- '步骤 3:写入 Json 文件
|
|
|
- '获取作为检查目标的加载器和版本
|
|
|
- Dim ModLoaders = GetTargetModLoaders()
|
|
|
- Dim McVersion = Version.Version.McName
|
|
|
- Log($"[Export] 目标加载器:{ModLoaders.Join("/")},版本:{McVersion}")
|
|
|
+ ' '步骤 3:写入 Json 文件
|
|
|
+ ' '获取作为检查目标的加载器和版本
|
|
|
+ ' Dim ModLoaders = GetTargetModLoaders()
|
|
|
+ ' Dim McVersion = Version.Version.McName
|
|
|
+ ' Log($"[Export] 目标加载器:{ModLoaders.Join("/")},版本:{McVersion}")
|
|
|
|
|
|
- Dim files As New JArray
|
|
|
- For Each m In ModrinthMapping
|
|
|
- files.Add(New JObject From {
|
|
|
- {"path", $"mods/{m.Key}"},
|
|
|
- {"hashes", m.Value("hashes")},
|
|
|
- {"env", New JObject From {{"client", "required"}, {"server", "required"}}},
|
|
|
- {"downloads", New JArray From {m.Value("url")}},
|
|
|
- {"fileSize", m.Value("size")}
|
|
|
- })
|
|
|
- Next
|
|
|
- For Each m In CurseForgeMapping
|
|
|
- files.Add(New JObject From {
|
|
|
- {"path", $"mods/{m.Key}"},
|
|
|
- {"hashes", New JObject From {{"sha1", m.Value("ModrinthHash").ToString}}},
|
|
|
- {"env", New JObject From {{"client", "required"}, {"server", "required"}}},
|
|
|
- {"downloads", New JArray From {m.Value("downloadUrl")}},
|
|
|
- {"fileSize", m.Value("fileLength")}
|
|
|
- })
|
|
|
- Next
|
|
|
+ ' Dim files As New JArray
|
|
|
+ ' For Each m In ModrinthMapping
|
|
|
+ ' files.Add(New JObject From {
|
|
|
+ ' {"path", $"mods/{m.Key}"},
|
|
|
+ ' {"hashes", m.Value("hashes")},
|
|
|
+ ' {"env", New JObject From {{"client", "required"}, {"server", "required"}}},
|
|
|
+ ' {"downloads", New JArray From {m.Value("url")}},
|
|
|
+ ' {"fileSize", m.Value("size")}
|
|
|
+ ' })
|
|
|
+ ' Next
|
|
|
+ ' For Each m In CurseForgeMapping
|
|
|
+ ' files.Add(New JObject From {
|
|
|
+ ' {"path", $"mods/{m.Key}"},
|
|
|
+ ' {"hashes", New JObject From {{"sha1", m.Value("ModrinthHash").ToString}}},
|
|
|
+ ' {"env", New JObject From {{"client", "required"}, {"server", "required"}}},
|
|
|
+ ' {"downloads", New JArray From {m.Value("downloadUrl")}},
|
|
|
+ ' {"fileSize", m.Value("fileLength")}
|
|
|
+ ' })
|
|
|
+ ' Next
|
|
|
|
|
|
- Dim depend As New JObject From {{"minecraft", McVersion}}
|
|
|
- If Version.Version.HasForge Then depend.Add("forge", Version.Version.ForgeVersion)
|
|
|
- If Version.Version.HasFabric Then depend.Add("fabric-loader", Version.Version.FabricVersion)
|
|
|
- If Version.Version.HasNeoForge Then depend.Add("neoforge", Version.Version.NeoForgeVersion)
|
|
|
+ ' Dim depend As New JObject From {{"minecraft", McVersion}}
|
|
|
+ ' If Version.Version.HasForge Then depend.Add("forge", Version.Version.ForgeVersion)
|
|
|
+ ' If Version.Version.HasFabric Then depend.Add("fabric-loader", Version.Version.FabricVersion)
|
|
|
+ ' If Version.Version.HasNeoForge Then depend.Add("neoforge", Version.Version.NeoForgeVersion)
|
|
|
|
|
|
- Dim json As New JObject From {
|
|
|
- {"game", "minecraft"},
|
|
|
- {"formatVersion", 1},
|
|
|
- {"versionId", VerID},
|
|
|
- {"name", If(String.IsNullOrEmpty(Name), Version.Name, Name)},
|
|
|
- {"summary", Version.Info},
|
|
|
- {"files", files},
|
|
|
- {"dependencies", depend}
|
|
|
- }
|
|
|
+ ' Dim json As New JObject From {
|
|
|
+ ' {"game", "minecraft"},
|
|
|
+ ' {"formatVersion", 1},
|
|
|
+ ' {"versionId", VerID},
|
|
|
+ ' {"name", If(String.IsNullOrEmpty(Name), Version.Name, Name)},
|
|
|
+ ' {"summary", Version.Info},
|
|
|
+ ' {"files", files},
|
|
|
+ ' {"dependencies", depend}
|
|
|
+ ' }
|
|
|
|
|
|
- File.WriteAllText(tempDir & "modrinth.index.json", json.ToString)
|
|
|
+ ' File.WriteAllText(tempDir & "modrinth.index.json", json.ToString)
|
|
|
|
|
|
- '步骤 4:将获取不到的保存到 overrides 目录
|
|
|
- For Each m In ModrinthFailed
|
|
|
- CopyFile(m.Path, tempDir & "overrides\mods\" & m.FileName)
|
|
|
- Next
|
|
|
+ ' '步骤 4:将获取不到的保存到 overrides 目录
|
|
|
+ ' For Each m In ModrinthFailed
|
|
|
+ ' CopyFile(m.Path, tempDir & "overrides\mods\" & m.FileName)
|
|
|
+ ' Next
|
|
|
|
|
|
'额外文件
|
|
|
For Each p In Additional
|
|
|
If String.IsNullOrWhiteSpace(p) Then Continue For '传空字串进去会直接把整个版本文件夹拷过去
|
|
|
- If Not p.StartsWithF(Version.Path, IgnoreCase:=True) Then Continue For
|
|
|
- Dim relative As String = p.Replace(Version.Path, "")
|
|
|
+ If Not p.StartsWithF(GetPathFromFullPath(GetPathFromFullPath(Version.Path)), IgnoreCase:=True) Then Continue For
|
|
|
+ Dim relative As String = p.Replace(Version.Path, "").Replace(GetPathFromFullPath(GetPathFromFullPath(Version.Path)), "")
|
|
|
If File.Exists(p) AndAlso Not IsVerRedundant(p) Then
|
|
|
CopyFile(p, $"{tempDir}overrides\{relative}")
|
|
|
End If
|