Deprecate old MinecraftVersion enum and create new ProtocolVersion class which automatically update the version list on startup
This commit is contained in:
parent
436c9b9381
commit
edd5b06a46
@ -0,0 +1,24 @@
|
|||||||
|
package fr.pandacube.lib.core.mc_version;
|
||||||
|
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
public record MinecraftVersionList(
|
||||||
|
Map<String, Integer> protocolOfVersion,
|
||||||
|
Map<Integer, List<String>> versionsOfProtocol
|
||||||
|
) {
|
||||||
|
public MinecraftVersionList() {
|
||||||
|
this(new TreeMap<>(MinecraftVersionUtil::compareVersions), new TreeMap<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(String versionId, int protocolVersion) {
|
||||||
|
protocolOfVersion.put(versionId, protocolVersion);
|
||||||
|
List<String> versions = versionsOfProtocol.computeIfAbsent(protocolVersion, p -> new ArrayList<>());
|
||||||
|
versions.add(versionId);
|
||||||
|
versions.sort(MinecraftVersionUtil::compareVersions);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,102 @@
|
|||||||
|
package fr.pandacube.lib.core.mc_version;
|
||||||
|
|
||||||
|
import fr.pandacube.lib.util.StringUtil;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
public class MinecraftVersionUtil {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static int compareVersions(String v1, String v2) {
|
||||||
|
int[] v1Int = decomposedVersion(v1);
|
||||||
|
int[] v2Int = decomposedVersion(v2);
|
||||||
|
|
||||||
|
for (int i = 0; i < Math.min(v1Int.length, v2Int.length); i++) {
|
||||||
|
int cmp = Integer.compare(v1Int[i], v2Int[i]);
|
||||||
|
if (cmp != 0)
|
||||||
|
return cmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Integer.compare(v1Int.length, v2Int.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static int[] decomposedVersion(String v) {
|
||||||
|
try {
|
||||||
|
return Arrays.stream(v.split("\\.")).mapToInt(Integer::parseInt).toArray();
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new IllegalArgumentException("Invalid version format: '" + v + "'.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean areConsecutives(String v1, String v2) {
|
||||||
|
int[] v1Int = decomposedVersion(v1);
|
||||||
|
int[] v2Int = decomposedVersion(v2);
|
||||||
|
|
||||||
|
if (v1Int.length == v2Int.length) {
|
||||||
|
for (int i = 0; i < v1Int.length - 1; i++) {
|
||||||
|
if (v1Int[i] != v2Int[i])
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return v1Int[v1Int.length - 1] + 1 == v2Int[v2Int.length - 1];
|
||||||
|
}
|
||||||
|
else if (v1Int.length == v2Int.length - 1) {
|
||||||
|
for (int i = 0; i < v1Int.length; i++) {
|
||||||
|
if (v1Int[i] != v2Int[i])
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return v2Int[v2Int.length - 1] == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static String toString(List<String> versions, String finalWordSeparator) {
|
||||||
|
if (versions.isEmpty())
|
||||||
|
return "";
|
||||||
|
// put them in order and remove duplicates
|
||||||
|
versions = new ArrayList<>(toOrderedSet(versions));
|
||||||
|
List<String> keptVersions = new ArrayList<>(versions.size());
|
||||||
|
|
||||||
|
for (int i = 0, firstConsec = 0; i < versions.size(); i++) {
|
||||||
|
if (i == versions.size() - 1 || !areConsecutives(versions.get(i), versions.get(i + 1))) {
|
||||||
|
if (firstConsec == i) {
|
||||||
|
keptVersions.add(versions.get(i));
|
||||||
|
firstConsec++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// merge
|
||||||
|
if (i - firstConsec > 1)
|
||||||
|
keptVersions.add(versions.get(firstConsec) + "-" + versions.get(i));
|
||||||
|
else {
|
||||||
|
keptVersions.add(versions.get(firstConsec));
|
||||||
|
keptVersions.add(versions.get(i));
|
||||||
|
}
|
||||||
|
firstConsec = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return StringUtil.joinGrammatically(", ", " " + finalWordSeparator + " ", keptVersions);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static Set<String> toOrderedSet(List<String> versions) {
|
||||||
|
Set<String> set = new TreeSet<>(MinecraftVersionUtil::compareVersions);
|
||||||
|
set.addAll(versions);
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
package fr.pandacube.lib.core.mc_version;
|
||||||
|
|
||||||
|
import fr.pandacube.lib.core.json.Json;
|
||||||
|
import fr.pandacube.lib.util.Log;
|
||||||
|
import org.jetbrains.annotations.ApiStatus.Internal;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.http.HttpClient;
|
||||||
|
import java.net.http.HttpRequest;
|
||||||
|
import java.net.http.HttpResponse;
|
||||||
|
import java.net.http.HttpResponse.BodyHandlers;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
public class ProtocolVersion {
|
||||||
|
|
||||||
|
private static final String ONLINE_DATA_URL = "https://api.pandacube.fr/rest/mcversion";
|
||||||
|
|
||||||
|
private static final AtomicReference<MinecraftVersionList> versionList = new AtomicReference<>();
|
||||||
|
|
||||||
|
private static void initIfNecessary() {
|
||||||
|
synchronized (versionList) {
|
||||||
|
if (versionList.get() == null) {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void setRawData(MinecraftVersionList data) {
|
||||||
|
versionList.set(data);
|
||||||
|
}
|
||||||
|
public static MinecraftVersionList getRawData() {
|
||||||
|
initIfNecessary();
|
||||||
|
return versionList.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void init() {
|
||||||
|
// try online source first
|
||||||
|
try {
|
||||||
|
HttpResponse<String> response = HttpClient.newHttpClient()
|
||||||
|
.send(HttpRequest.newBuilder(URI.create(ONLINE_DATA_URL)).build(),
|
||||||
|
BodyHandlers.ofString()
|
||||||
|
);
|
||||||
|
if (response.statusCode() == 200) {
|
||||||
|
MinecraftVersionList data = Json.gson.fromJson(response.body(), MinecraftVersionList.class);
|
||||||
|
versionList.set(data);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.warning(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (versionList.get() != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.warning("Unable to get minecraft version data from API. Using local data instead.");
|
||||||
|
// try local source
|
||||||
|
try (InputStream is = ProtocolVersion.class.getResourceAsStream("mcversion.json");
|
||||||
|
InputStreamReader isr = new InputStreamReader(is)) {
|
||||||
|
MinecraftVersionList data = Json.gson.fromJson(isr, MinecraftVersionList.class);
|
||||||
|
versionList.set(data);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.severe("Unable to get Minecraft versions data from classpath. Using empty data instead.");
|
||||||
|
versionList.set(new MinecraftVersionList());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static int ofVersion(String versionId) {
|
||||||
|
initIfNecessary();
|
||||||
|
Integer v = versionList.get().protocolOfVersion().get(versionId);
|
||||||
|
return v == null ? -1 : v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static List<String> getVersionsOfProtocol(int protocolVersion) {
|
||||||
|
initIfNecessary();
|
||||||
|
return versionList.get().versionsOfProtocol().get(protocolVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -15,15 +15,17 @@ import java.util.Set;
|
|||||||
* "1.16-1.16.3", "1.8.x and 1.9", "1.18.1 or 1.18.2")
|
* "1.16-1.16.3", "1.8.x and 1.9", "1.18.1 or 1.18.2")
|
||||||
* <p>
|
* <p>
|
||||||
* Note that this enum uses one value to represent every Minecraft version using the same protocol version number.
|
* Note that this enum uses one value to represent every Minecraft version using the same protocol version number.
|
||||||
|
* @deprecated This class may not be updated. Use the class ProtocolVersion in pandalib-core module instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public enum MinecraftVersion {
|
public enum MinecraftVersion {
|
||||||
/** Minecraft versions 1.7.2 to 1.7.5, protocol version 4. */
|
/** Minecraft versions 1.7.2 to 1.7.5, protocol version 4. */
|
||||||
v1_7_2_to_1_7_5(4, "1.7.2-1.7.5"),
|
v1_7_2_to_1_7_5(4, "1.7.2", "1.7.3", "1.7.4", "1.7.5"),
|
||||||
/** Minecraft versions 1.7.6 to 1.7.10, protocol version 5. */
|
/** Minecraft versions 1.7.6 to 1.7.10, protocol version 5. */
|
||||||
v1_7_6_to_1_7_10(5, "1.7.6-1.7.10"),
|
v1_7_6_to_1_7_10(5, "1.7.6", "1.7.7", "1.7.8", "1.7.9", "1.7.10"),
|
||||||
|
|
||||||
/** Minecraft versions 1.8.x, protocol version 47. */
|
/** Minecraft versions 1.8.x, protocol version 47. */
|
||||||
v1_8(47, "1.8.x"),
|
v1_8(47, "1.8", "1.8.1", "1.8.2", "1.8.3", "1.8.4", "1.8.5", "1.8.6", "1.8.7", "1.8.8", "1.8.9"),
|
||||||
|
|
||||||
/** Minecraft version 1.9, protocol version 107. */
|
/** Minecraft version 1.9, protocol version 107. */
|
||||||
v1_9(107, "1.9"),
|
v1_9(107, "1.9"),
|
||||||
@ -35,7 +37,7 @@ public enum MinecraftVersion {
|
|||||||
v1_9_3_to_1_9_4(110, "1.9.3", "1.9.4"),
|
v1_9_3_to_1_9_4(110, "1.9.3", "1.9.4"),
|
||||||
|
|
||||||
/** Minecraft versions 1.10.x, protocol version 210. */
|
/** Minecraft versions 1.10.x, protocol version 210. */
|
||||||
v1_10(210, "1.10.x"),
|
v1_10(210, "1.10", "1.10.1", "1.10.2"),
|
||||||
|
|
||||||
/** Minecraft version 1.11, protocol version 315. */
|
/** Minecraft version 1.11, protocol version 315. */
|
||||||
v1_11(315, "1.11"),
|
v1_11(315, "1.11"),
|
||||||
|
Loading…
Reference in New Issue
Block a user