Skip to content

Commit 343c09b

Browse files
authored
修复无法获取部分远古版本版本号的问题 (#4775)
1 parent 1bbc6ef commit 343c09b

1 file changed

Lines changed: 118 additions & 13 deletions

File tree

HMCLCore/src/main/java/org/jackhuang/hmcl/game/GameVersion.java

Lines changed: 118 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package org.jackhuang.hmcl.game;
1919

2020
import com.google.gson.JsonParseException;
21+
import org.jackhuang.hmcl.util.DigestUtils;
2122
import org.jackhuang.hmcl.util.gson.JsonUtils;
2223
import org.jenkinsci.constant_pool_scanner.ConstantPool;
2324
import org.jenkinsci.constant_pool_scanner.ConstantPoolScanner;
@@ -31,7 +32,7 @@
3132
import java.util.List;
3233
import java.util.Map;
3334
import java.util.Optional;
34-
import java.util.stream.Collectors;
35+
import java.util.regex.Pattern;
3536
import java.util.stream.StreamSupport;
3637
import java.util.zip.ZipEntry;
3738
import java.util.zip.ZipFile;
@@ -45,6 +46,96 @@ final class GameVersion {
4546
private GameVersion() {
4647
}
4748

49+
// For Minecraft 1.0 rc versions and versions earlier than Alpha 1.0.6,
50+
// it is difficult to obtain the game version from the JAR.
51+
// For these versions, we get the version number based on their SHA-1 hash.
52+
private static final Map<String, String> KNOWN_VERSIONS = Map.<String, String>ofEntries(
53+
Map.entry("4df7880d26414b400640f0b8e54344df2b66c51a", "1.0.0-rc1"),
54+
Map.entry("9e04e60eef3fb4657b406dcb3ad5e3a675ecf6af", "1.0.0-rc2-1"),
55+
Map.entry("6a6b67d34149afc47cf9608b3967582639097df9", "1.0.0-rc2-2"),
56+
Map.entry("6e54fbe19b7797f3e3a2cb9feb5da41a40926db8", "1.0.0-rc2-3"),
57+
Map.entry("fe189e91a3e7166d46fad8ce53ba0ce34b4c5f97", "a1.0.5"),
58+
Map.entry("73f569bf5556580979606049204835ae1a54f04d", "a1.0.5_01"),
59+
Map.entry("e5838277b3bb193e58408713f1fc6e005c5f3c0c", "a1.0.4"),
60+
Map.entry("31e9736457ef3e0bfea69c720137a1bd8ba7caae", "a1.0.3"),
61+
Map.entry("4f9ce27cfc6394af533fde11a90b6a233dd908bf", "a1.0.2_02"),
62+
Map.entry("7457e763ad81eee1e63628d628647f53806dab7c", "a1.0.2_01"),
63+
Map.entry("02c57723da508aab36455782904bfd6e3e1023e6", "a1.0.1_01"),
64+
Map.entry("88c1931650b0e5be349017e124a7785a745111e9", "inf-20100630-2"),
65+
Map.entry("121fff417950ad72005ca4d882ca6269e874547b", "inf-20100630-1"),
66+
Map.entry("eb50bce3cb542488b3039aa0f4c3c0ec7595ab24", "inf-20100629"),
67+
Map.entry("4d31259a71c5886b987b9eca6034ca5552079eed", "inf-20100627"),
68+
Map.entry("d9fc6416186e1454945ab135f37c730c7d2c1adc", "inf-20100625-2"),
69+
Map.entry("990b531a26ae8e475032915938763c12cdb2dcf9", "inf-20100625-1"),
70+
Map.entry("644c050e846035e06a6637bffa2afee1e5769c8c", "inf-20100624"),
71+
Map.entry("d3eb1dce5a6c86dd0d6483ba56223276dcf32c30", "inf-20100617-3"),
72+
Map.entry("06641eca013fe5032a5f1a9d1289599f0970a735", "inf-20100617-2"),
73+
Map.entry("89eab2c1a353707cc00f074dffba9cb7a4f5e304", "inf-20100618"),
74+
Map.entry("47518a623da068728b50b4b53436dea4621b7bf8", "inf-20100615"),
75+
Map.entry("421318a554f17463a56a271d08e9597941d066d9", "inf-20100611"),
76+
Map.entry("a9efb36c142bf835d3d410150856dc9ceeaae81b", "inf-20100608"),
77+
Map.entry("7bbf38d53dd47753af266be4e1c5865342a26974", "inf-20100607"),
78+
Map.entry("27010a5137abd2c8d8df85e99c14f5406ec197b3", "inf-20100420"),
79+
Map.entry("a91c9d8e0184eda610213b1a5425fbfa078cb191", "inf-20100415"),
80+
Map.entry("86dd3b1558352b38d4d15c7ec51b9131bd7aed4b", "inf-20100414"),
81+
Map.entry("7b39167f14d9f0ce7af6819433856be7b82d2412", "inf-20100413"),
82+
Map.entry("a74c8ee1ecd57999e242952697bbde6cc0904f99", "inf-20100330"),
83+
Map.entry("47b1b32430a211520993552ba0a5e00c1af44724", "inf-20100327"),
84+
Map.entry("99da3b55b4db292faca59824e3ec76bf53a7eae6", "inf-20100325"),
85+
Map.entry("2c89471a81858d37ab0b01e042131878b6853b38", "inf-20100321"),
86+
Map.entry("7f1c48fc6d61dd0cbfd41b84fb0b0a22944aa02c", "inf-20100320"),
87+
Map.entry("ad7b3cd706098ac05c7dba61dacb40bafcd47db6", "inf-20100316"),
88+
Map.entry("65a00a10001978538ab8eef1a2533f47d4ecbe23", "inf-20100313"),
89+
Map.entry("801ce486bb7fd1b43a56bc5d226dfb1370c08678", "in-20100223"),
90+
Map.entry("af3d7f95ca75e130a9c5c74be0a9c09600a15686", "in-20100219"),
91+
Map.entry("2ba9e9a2bdac1e8af6a36819e9bb01375889b078", "in-20100218"),
92+
Map.entry("dcbe38d0e4ac2caec7e5c0f9ebcb0ec9179dcdff", "in-20100214-2"),
93+
Map.entry("e6bb9306dab60626ba6ffd24fc9742fd272f5acb", "in-20100214-1"),
94+
Map.entry("f1ae7e37e52b33753b35402e581eb65dc5bba877", "in-20100212-2"),
95+
Map.entry("5275aaf68d6388ef8278b575e95ae83ad641fe3e", "in-20100212-1"),
96+
Map.entry("fa8525be5612d00f6001be7d4cdb764b66e88f9d", "in-20100207-2"),
97+
Map.entry("054e3d3f4e2c0463f80aa323767e018e6c23c1cd", "in-20100207-1"),
98+
Map.entry("049b002cdd164e5c5e9b78780b12ab4dc2e80120", "in-20100206-2103"),
99+
Map.entry("b2abb22e001abf01ca7555ced5d6024350955d70", "in-20100203"),
100+
Map.entry("38d4df5132077ac60f0bdf67564f5fff4ee309e2", "in-20100201-3"),
101+
Map.entry("1f2ca31fc761207bcabc07f0cf4b725a9a3286e4", "in-20100201-2"),
102+
Map.entry("c871e820d5356b88b3ad854789162f8b9227c80c", "in-20100130"),
103+
Map.entry("03b858d31c090b629f406aa1d548ac7b25341f02", "in-20100129"),
104+
Map.entry("3f2418f906d438b26ae6c9dbbadf3942f5845504", "in-20100128-2304"),
105+
Map.entry("baf0c7b1e231f0984e1c35e27f38eea2743f8ee2", "in-20100125-2"),
106+
Map.entry("2cd03bcfc26c95bcf31b5d5e1d4dda7dc071ca6a", "in-20100125-1"),
107+
Map.entry("a0b58472ebf12f7e562b09b8a51dcb4cacc57005", "in-20100111-1"),
108+
Map.entry("38958105bfe0f7064b3c4996905cb6978d4d4b0b", "in-20100105"),
109+
Map.entry("3161652a6835c61817fda6fe13245c57528ed418", "in-20091231-2"),
110+
Map.entry("94ee2e7aa7d093fa8dfc684baa8bd8afe002580f", "in-20091223-2"),
111+
Map.entry("54622801f5ef1bcc1549a842c5b04cb5d5583005", "c0.30_01c"),
112+
Map.entry("51bc951530207b538596941a6f353f87dfc24233", "c0.30-2"),
113+
Map.entry("619ea74c6d0ae5c0125d1e31e299105e100139ab", "c0.30-1"),
114+
Map.entry("6a6f92b691f9d6b7ca991a6db8a1cfc6e319815b", "c0.29_02"),
115+
Map.entry("bb5e7f1c231f45fd630f30a75570937c103f5b55", "c0.29_01"),
116+
Map.entry("7ccde270abacd028d3618be99537ccf7071a605b", "c0.28_01"),
117+
Map.entry("aff4060249dd6152012218e120d7aad5e758de83", "c0.27_st"),
118+
Map.entry("349630cb1b895335c38b499f84dc28d9f8a38513", "c0.25_05_st"),
119+
Map.entry("0b387d2087edda894fae4af00de5ac202dbffa7c", "c0.24_st_03"),
120+
Map.entry("85159cea8663ed720be88ca0ee008a5830b0829a", "c0.0.22a_05"),
121+
Map.entry("83b6483feb88136b6b4662b553d8f80f5f88efa5", "c0.0.21a"),
122+
Map.entry("c2f8fddde4691d7c567c0c049ad4d03eb6b9e61c", "c0.0.20a_01"),
123+
Map.entry("e2b248f1013933af9f801729418409fb7198de1b", "c0.0.19a_06-2"),
124+
Map.entry("a78468abd491d6c661c000f60d6270a692ba4710", "c0.0.18a_02"),
125+
Map.entry("ca840460a6589552c9d1978ca121bf3e7c16a010", "c0.0.17a"),
126+
Map.entry("741eb3f84097fdcc0327230e018a0f8cd39addfb", "c0.0.16a_02"),
127+
Map.entry("936d575b1ab1a04a341ad43d76e441e88d2cd987", "c0.0.13a"),
128+
Map.entry("e8aa74a5bee547097375d44ffb2e407b2ea8ee4d", "c0.0.14a_08"),
129+
Map.entry("b9884f960f2b28a36b34db3447963f1ff4058aa4", "c0.0.23a_01"),
130+
Map.entry("7ba9e63aec8a15a99ecd47900c848cdce8a51a03", "c0.0.13a_03"),
131+
Map.entry("501ea8a6274faffe0144d3b24ed56797ce0765ff", "c0.0.12a_03"),
132+
Map.entry("3a799f179b6dcac5f3a46846d687ebbd95856984", "c0.0.11a"),
133+
Map.entry("6323bd14ed7f83852e17ebc8ec418e55c97ddfe4", "rd-161348"),
134+
Map.entry("b100be8097195b6c9112046dc6a80d326c8df839", "rd-160052"),
135+
Map.entry("12dace5a458617d3f90337a7ebde86c0593a6899", "rd-132328"),
136+
Map.entry("393e8d4b4d708587e2accd7c5221db65365e1075", "rd-132211")
137+
);
138+
48139
private static Optional<String> getVersionFromJson(InputStream versionJson) {
49140
try {
50141
Map<?, ?> version = JsonUtils.fromNonNullJsonFully(versionJson, Map.class);
@@ -59,21 +150,23 @@ private static Optional<String> getVersionFromJson(InputStream versionJson) {
59150
}
60151

61152
private static Optional<String> getVersionOfClassMinecraft(InputStream bytecode) throws IOException {
153+
final String constantPrefix = "Minecraft Minecraft ";
62154
ConstantPool pool = ConstantPoolScanner.parse(bytecode, ConstantType.STRING);
63-
64-
return StreamSupport.stream(pool.list(StringConstant.class).spliterator(), false)
65-
.map(StringConstant::get)
66-
.filter(s -> s.startsWith("Minecraft Minecraft "))
67-
.map(s -> s.substring("Minecraft Minecraft ".length()))
68-
.findFirst();
155+
for (StringConstant constant : pool.list(StringConstant.class)) {
156+
String value = constant.get();
157+
if (value.startsWith(constantPrefix)) {
158+
return Optional.of(value.substring(constantPrefix.length()));
159+
}
160+
}
161+
return Optional.empty();
69162
}
70163

71164
private static Optional<String> getVersionFromClassMinecraftServer(InputStream bytecode) throws IOException {
72165
ConstantPool pool = ConstantPoolScanner.parse(bytecode, ConstantType.STRING);
73166

74167
List<String> list = StreamSupport.stream(pool.list(StringConstant.class).spliterator(), false)
75168
.map(StringConstant::get)
76-
.collect(Collectors.toList());
169+
.toList();
77170

78171
int idx = -1;
79172

@@ -83,8 +176,9 @@ private static Optional<String> getVersionFromClassMinecraftServer(InputStream b
83176
break;
84177
}
85178

179+
Pattern pattern = Pattern.compile(".*[0-9].*");
86180
for (int i = idx - 1; i >= 0; --i)
87-
if (list.get(i).matches(".*[0-9].*"))
181+
if (pattern.matcher(list.get(i)).matches())
88182
return Optional.of(list.get(i));
89183

90184
return Optional.empty();
@@ -108,10 +202,16 @@ public static Optional<String> minecraftVersion(Path file) {
108202
Optional<String> result = getVersionOfClassMinecraft(is);
109203
if (result.isPresent()) {
110204
String version = result.get();
111-
if (version.startsWith("Beta ")) {
112-
result = Optional.of("b" + version.substring("Beta ".length()));
205+
// For Minecraft 1.0 rc1/rc2-1/rc2-2, this value is "RC1"
206+
// For Minecraft 1.0 rc2-3, this value is "RC2"
207+
if (!version.equals("RC1") && !version.equals("RC2")) {
208+
if (version.startsWith("Beta ")) {
209+
result = Optional.of("b" + version.substring("Beta ".length()));
210+
} else if (version.startsWith("Alpha v")) {
211+
result = Optional.of("a" + version.substring("Alpha v".length()));
212+
}
213+
return result;
113214
}
114-
return result;
115215
}
116216
}
117217
}
@@ -122,7 +222,12 @@ public static Optional<String> minecraftVersion(Path file) {
122222
return getVersionFromClassMinecraftServer(is);
123223
}
124224
}
125-
return Optional.empty();
225+
} catch (IOException ignored) {
226+
}
227+
228+
try {
229+
String digest = DigestUtils.digestToString("SHA-1", file);
230+
return Optional.ofNullable(KNOWN_VERSIONS.get(digest));
126231
} catch (IOException e) {
127232
return Optional.empty();
128233
}

0 commit comments

Comments
 (0)