Repository: HMCL-dev/HMCL (language: java)

Issue:
[Bug] Unable to install 1.7.10-pre4 Forge instance
### 平台 | Platform

Windows 11

### 问题描述 | Problem Description

_**RELATED:**_
- #3131
- #3133

Although the version list can now be fetched, unfortunately, the game cannot be installed further.

<details>
<summary>Preview</summary>

![](https://github.com/HMCL-dev/HMCL/assets/158490944/82282eba-2616-4746-82b8-5063567c1ebb)


</details>

Through observation and comparison, it seems that for this version of the game, the file names provided by MinecraftForge do not follow the routine.

You need to use the following link to download the file successfully.

```
https://bmclapi2.bangbang93.com/forge/download?mcversion=1.7.10_pre4&version=10.12.2.1149-prerelease&category=installer&format=jar
```

### 启动器崩溃报告 / 启动器日志文件 | Launcher Crash Report / Launcher Log File

_(Deleted)_


Discussion / hints:
Could you provide the launcher log file?
> Could you provide the launcher log file?

Later.
@burningtnt

Now available.
After discussing with BangBang93, the developer of the OpenBMCLAPI Project, we are sure that this is Forge's strange behavior. Another hardcode solution will be involved. Thanks for your testing!

Fix patch:
diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeBMCLVersionList.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeBMCLVersionList.java
index cd0cfcd109..ef37315eee 100644
--- a/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeBMCLVersionList.java
+++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeBMCLVersionList.java
@@ -21,6 +21,7 @@
 import com.google.gson.reflect.TypeToken;
 import org.jackhuang.hmcl.download.VersionList;
 import org.jackhuang.hmcl.util.Immutable;
+import org.jackhuang.hmcl.util.Lang;
 import org.jackhuang.hmcl.util.StringUtils;
 import org.jackhuang.hmcl.util.gson.Validation;
 import org.jackhuang.hmcl.util.io.HttpRequest;
@@ -66,12 +67,19 @@ public CompletableFuture<?> refreshAsync() {
         throw new UnsupportedOperationException("ForgeBMCLVersionList does not support loading the entire Forge remote version list.");
     }
 
-    public String toLookupVersion(String version) {
-        return "1.7.10-pre4".equals(version) ? "1.7.10_pre4" : version;
+    private static String toLookupVersion(String gameVersion) {
+        return "1.7.10-pre4".equals(gameVersion) ? "1.7.10_pre4" : gameVersion;
     }
 
-    public String fromLookupVersion(String version) {
-        return "1.7.10_pre4".equals(version) ? "1.7.10-pre4" : version;
+    private static String fromLookupVersion(String lookupVersion) {
+        return "1.7.10_pre4".equals(lookupVersion) ? "1.7.10-pre4" : lookupVersion;
+    }
+
+    private static String toLookupBranch(String gameVersion, String branch) {
+        if ("1.7.10-pre4".equals(gameVersion)) {
+            return "prerelease";
+        }
+        return Lang.requireNonNullElse(branch, "");
     }
 
     @Override
@@ -93,8 +101,9 @@ public CompletableFuture<?> refreshAsync(String gameVersion) {
                             List<String> urls = new ArrayList<>();
                             for (ForgeVersion.File file : version.getFiles())
                                 if ("installer".equals(file.getCategory()) && "jar".equals(file.getFormat())) {
-                                    String classifier = lookupVersion + "-" + version.getVersion()
-                                            + (StringUtils.isNotBlank(version.getBranch()) ? "-" + version.getBranch() : "");
+                                    String branch = toLookupBranch(gameVersion, version.getBranch());
+
+                                    String classifier = lookupVersion + "-" + version.getVersion() + (branch.isEmpty() ? "" : '-' + branch);
                                     String fileName1 = "forge-" + classifier + "-" + file.getCategory() + "." + file.getFormat();
                                     String fileName2 = "forge-" + classifier + "-" + lookupVersion + "-" + file.getCategory() + "." + file.getFormat();
                                     urls.add("https://files.minecraftforge.net/maven/net/minecraftforge/forge/" + classifier + "/" + fileName1);
@@ -102,7 +111,7 @@ public CompletableFuture<?> refreshAsync(String gameVersion) {
                                     urls.add(NetworkUtils.withQuery("https://bmclapi2.bangbang93.com/forge/download", mapOf(
                                             pair("mcversion", version.getGameVersion()),
                                             pair("version", version.getVersion()),
-                                            pair("branch", version.getBranch()),
+                                            pair("branch", branch),
                                             pair("category", file.getCategory()),
                                             pair("format", file.getFormat())
                                     )));


Test patch: