package fr.pandacube.lib.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Enumeration of all known, post Netty-rewrite (1.7.2+), stable Minecraft Java versions.
*
* It provides various utility methods to nicely display a set of Minecraft version (for instance "1.13.x",
* "1.16-1.16.3", "1.8.x and 1.9", "1.18.1 or 1.18.2")
*
* Note that this enum uses one value to represent every Minecraft version using the same protocol version number.
*/
public enum MinecraftVersion {
/** 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"),
/** 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"),
/** Minecraft versions 1.8.x, protocol version 47. */
v1_8(47, "1.8.x"),
/** Minecraft version 1.9, protocol version 107. */
v1_9(107, "1.9"),
/** Minecraft version 1.9.1, protocol version 108. */
v1_9_1(108, "1.9.1"),
/** Minecraft version 1.9.2, protocol version 109. */
v1_9_2(109, "1.9.2"),
/** Minecraft versions 1.9.3 and 1.9.4, protocol version 110. */
v1_9_3_to_1_9_4(110, "1.9.3", "1.9.4"),
/** Minecraft versions 1.10.x, protocol version 210. */
v1_10(210, "1.10.x"),
/** Minecraft version 1.11, protocol version 315. */
v1_11(315, "1.11"),
/** Minecraft versions 1.11.1 and 1.11.2, protocol version 316. */
v1_11_1_to_1_11_2(316, "1.11.1", "1.11.2"),
/** Minecraft version 1.12, protocol version 335. */
v1_12(335, "1.12"),
/** Minecraft version 1.12.1, protocol version 338. */
v1_12_1(338, "1.12.1"),
/** Minecraft version 1.12.2, protocol version 340. */
v1_12_2(340, "1.12.2"),
/** Minecraft version 1.13, protocol version 393. */
v1_13(393, "1.13"),
/** Minecraft version 1.13.1, protocol version 401. */
v1_13_1(401, "1.13.1"),
/** Minecraft version 1.13.2, protocol version 404. */
v1_13_2(404, "1.13.2"),
/** Minecraft version 1.14, protocol version 477. */
v1_14(477, "1.14"),
/** Minecraft version 1.14.1, protocol version 480. */
v1_14_1(480, "1.14.1"),
/** Minecraft version 1.14.2, protocol version 485. */
v1_14_2(485, "1.14.2"),
/** Minecraft version 1.14.3, protocol version 490. */
v1_14_3(490, "1.14.3"),
/** Minecraft version 1.14.4, protocol version 498. */
v1_14_4(498, "1.14.4"),
/** Minecraft version 1.15, protocol version 573. */
v1_15(573, "1.15"),
/** Minecraft version 1.15.1, protocol version 575. */
v1_15_1(575, "1.15.1"),
/** Minecraft version 1.15.2, protocol version 578. */
v1_15_2(578, "1.15.2"),
/** Minecraft version 1.16, protocol version 735. */
v1_16(735, "1.16"),
/** Minecraft version 1.16.1, protocol version 736. */
v1_16_1(736, "1.16.1"),
/** Minecraft version 1.16.2, protocol version 751. */
v1_16_2(751, "1.16.2"),
/** Minecraft version 1.16.3, protocol version 753. */
v1_16_3(753, "1.16.3"),
/** Minecraft versions 1.16.4 and 1.16.5, protocol version 754. */
v1_16_4_to_1_16_5(754, "1.16.4", "1.16.5"),
/** Minecraft version 1.17, protocol version 755. */
v1_17(755, "1.17"),
/** Minecraft version 1.17.1, protocol version 756. */
v1_17_1(756, "1.17.1"),
/** Minecraft versions 1.18 and 1.18.1, protocol version 757. */
v1_18_to_1_18_1(757, "1.18", "1.18.1"),
/** Minecraft version 1.18.2, protocol version 758. */
v1_18_2(758, "1.18.2"),
/** Minecraft version 1.19, protocol version 759. */
v1_19(759, "1.19"),
/** Minecraft versions 1.19.1 and 1.19.2, protocol version 760. */
v1_19_1_to_1_19_2(760, "1.19.1", "1.19.2"),
/** Minecraft versions 1.19.3, protocol version 761. */
v1_19_3(761, "1.19.3");
// IMPORTANT: don't forget to update the versionMergeDisplay value when adding a new version;
private static final Map, List> versionMergeDisplay;
static {
versionMergeDisplay = new HashMap<>();
versionMergeDisplay.put(EnumSet.of(v1_7_2_to_1_7_5, v1_7_6_to_1_7_10),
List.of("1.7.2-1.7.10"));
versionMergeDisplay.put(EnumSet.of(v1_9, v1_9_1, v1_9_2, v1_9_3_to_1_9_4),
List.of("1.9.x"));
versionMergeDisplay.put(EnumSet.of(v1_9, v1_9_1, v1_9_2),
List.of("1.9-1.9.2"));
versionMergeDisplay.put(EnumSet.of(v1_9, v1_9_1),
List.of("1.9", "1.9.1"));
versionMergeDisplay.put(EnumSet.of(v1_9_1, v1_9_2, v1_9_3_to_1_9_4),
List.of("1.9.1-1.9.4"));
versionMergeDisplay.put(EnumSet.of(v1_9_1, v1_9_2),
List.of("1.9.1", "1.9.2"));
versionMergeDisplay.put(EnumSet.of(v1_9_2, v1_9_3_to_1_9_4),
List.of("1.9.2-1.9.4"));
versionMergeDisplay.put(EnumSet.of(v1_11, v1_11_1_to_1_11_2),
List.of("1.11.x"));
versionMergeDisplay.put(EnumSet.of(v1_12, v1_12_1, v1_12_2),
List.of("1.12.x"));
versionMergeDisplay.put(EnumSet.of(v1_12, v1_12_1),
List.of("1.12", "1.12.1"));
versionMergeDisplay.put(EnumSet.of(v1_12_1, v1_12_2),
List.of("1.12.1", "1.12.2"));
versionMergeDisplay.put(EnumSet.of(v1_13, v1_13_1, v1_13_2),
List.of("1.13.x"));
versionMergeDisplay.put(EnumSet.of(v1_13, v1_13_1),
List.of("1.13", "1.13.1"));
versionMergeDisplay.put(EnumSet.of(v1_13_1, v1_13_2),
List.of("1.13.1", "1.13.2"));
versionMergeDisplay.put(EnumSet.of(v1_14, v1_14_1, v1_14_2, v1_14_3, v1_14_4),
List.of("1.14.x"));
versionMergeDisplay.put(EnumSet.of(v1_14, v1_14_1, v1_14_2, v1_14_3),
List.of("1.14-1.14.3"));
versionMergeDisplay.put(EnumSet.of(v1_14_1, v1_14_2, v1_14_3, v1_14_4),
List.of("1.14.1-1.14.4"));
versionMergeDisplay.put(EnumSet.of(v1_14, v1_14_1, v1_14_2),
List.of("1.14-1.14.2"));
versionMergeDisplay.put(EnumSet.of(v1_14_1, v1_14_2, v1_14_3),
List.of("1.14.1-1.14.3"));
versionMergeDisplay.put(EnumSet.of(v1_14_2, v1_14_3, v1_14_4),
List.of("1.14.2-1.14.4"));
versionMergeDisplay.put(EnumSet.of(v1_14, v1_14_1),
List.of("1.14", "1.14.1"));
versionMergeDisplay.put(EnumSet.of(v1_14_1, v1_14_2),
List.of("1.14.1", "1.14.2"));
versionMergeDisplay.put(EnumSet.of(v1_14_2, v1_14_3),
List.of("1.14.2", "1.14.3"));
versionMergeDisplay.put(EnumSet.of(v1_14_3, v1_14_4),
List.of("1.14.3", "1.14.4"));
versionMergeDisplay.put(EnumSet.of(v1_15, v1_15_1, v1_15_2),
List.of("1.15.x"));
versionMergeDisplay.put(EnumSet.of(v1_15, v1_15_1),
List.of("1.15", "1.15.1"));
versionMergeDisplay.put(EnumSet.of(v1_15_1, v1_15_2),
List.of("1.15.1", "1.15.2"));
versionMergeDisplay.put(EnumSet.of(v1_16, v1_16_1, v1_16_2, v1_16_3, v1_16_4_to_1_16_5),
List.of("1.16.x"));
versionMergeDisplay.put(EnumSet.of(v1_16, v1_16_1, v1_16_2, v1_16_3),
List.of("1.16-1.16.3"));
versionMergeDisplay.put(EnumSet.of(v1_16_1, v1_16_2, v1_16_3, v1_16_4_to_1_16_5),
List.of("1.16.1-1.16.5"));
versionMergeDisplay.put(EnumSet.of(v1_16, v1_16_1, v1_16_2),
List.of("1.16-1.16.2"));
versionMergeDisplay.put(EnumSet.of(v1_16_1, v1_16_2, v1_16_3),
List.of("1.16.1-1.16.3"));
versionMergeDisplay.put(EnumSet.of(v1_16_2, v1_16_3, v1_16_4_to_1_16_5),
List.of("1.16.2-1.16.5"));
versionMergeDisplay.put(EnumSet.of(v1_16, v1_16_1),
List.of("1.16", "1.16.1"));
versionMergeDisplay.put(EnumSet.of(v1_16_1, v1_16_2),
List.of("1.16.1", "1.16.2"));
versionMergeDisplay.put(EnumSet.of(v1_16_2, v1_16_3),
List.of("1.16.2", "1.16.3"));
versionMergeDisplay.put(EnumSet.of(v1_16_3, v1_16_4_to_1_16_5),
List.of("1.16.3-1.16.5"));
versionMergeDisplay.put(EnumSet.of(v1_17, v1_17_1),
List.of("1.17.x"));
versionMergeDisplay.put(EnumSet.of(v1_18_to_1_18_1, v1_18_2),
List.of("1.18.x"));
versionMergeDisplay.put(EnumSet.of(v1_19, v1_19_1_to_1_19_2, v1_19_3),
List.of("1.19.x"));
versionMergeDisplay.put(EnumSet.of(v1_19, v1_19_1_to_1_19_2),
List.of("1.19-1.19.2"));
versionMergeDisplay.put(EnumSet.of(v1_19_1_to_1_19_2, v1_19_3),
List.of("1.19.1-1.19.3"));
}
/**
* The protocol version number of this Minecraft version.
*/
public final int protocolVersionNumber;
/**
* All Minecraft version supported by this protocol version number.
*/
public final List versionsDisplay;
MinecraftVersion(int protocolVersionNumber, String... versionsDisplay) {
this.protocolVersionNumber = protocolVersionNumber;
this.versionsDisplay = Arrays.asList(versionsDisplay);
}
@Override
public String toString() {
return name() + "{protocol=" + protocolVersionNumber + ", toString(\"and\")=" + toString("and") + "}";
}
/**
* Returns a string representation of all the Minecraft version of this enum value, using
* {@link StringUtil#joinGrammatically(CharSequence, CharSequence, List)}.
*
* @param finalWordSeparator the word separator between the two last versions in the returned string, like "and",
* "or" or any other word of any language. The spaces before and after are already
* concatenated.
* @return a string representation of this {@link MinecraftVersion}.
*/
public String toString(String finalWordSeparator) {
return StringUtil.joinGrammatically(", ", " " + finalWordSeparator + " ", versionsDisplay);
}
/**
* Returns a string representation of all the Minecraft version of this enum value, using
* {@link StringUtil#joinGrammatically(CharSequence, CharSequence, List)} with the gramatical word "et"
* ("and" in french).
*
* @return a string representation of this {@link MinecraftVersion}.
* @deprecated it uses the hardcoded french word "et" as the final word separator.
* Use {@link #displayOptimizedListOfVersions(List, String)} with "et" as the last parameter instead.
*/
@Deprecated
public String toStringAnd() {
return toString("et");
}
/**
* Returns a string representation of all the Minecraft version of this enum value, using
* {@link StringUtil#joinGrammatically(CharSequence, CharSequence, List)} with the gramatical word "ou"
* ("or" in french).
*
* @return a string representation of this {@link MinecraftVersion}.
* @deprecated it uses the hardcoded french word "ou" as the final word separator.
* Use {@link #displayOptimizedListOfVersions(List, String)} with "ou" as the last parameter instead.
*/
@Deprecated
public String toStringOr() {
return toString("ou");
}
/**
* Gets the {@link MinecraftVersion} instance associated with the provided protocol version number.
*
* @param protocolVersionNumber the protocol version number
* @return the {@link MinecraftVersion} instance associated with the provided protocol version number, or null if
* there is none.
*/
public static MinecraftVersion getVersion(int protocolVersionNumber) {
for (MinecraftVersion mcV : values())
if (mcV.protocolVersionNumber == protocolVersionNumber) return mcV;
return null;
}
/**
* Generate a string representation of the provided list of version, using
* {@link StringUtil#joinGrammatically(CharSequence, CharSequence, List)}.
*
* @param versions the minecraft versions to list
* @param finalWordSeparator the word separator between the two last versions in the returned string, like "and",
* "or" or any other word of any language. The spaces before and after are already
* concatenated.
* @return a string representation of the provided list of version.
*/
public static String displayOptimizedListOfVersions(List versions, String finalWordSeparator) {
return StringUtil.joinGrammatically(", ", " " + finalWordSeparator + " ", getVersionsDisplayList(versions));
}
/**
* Generate a string representation of the provided list of version, using
* {@link StringUtil#joinGrammatically(CharSequence, CharSequence, List)} with the gramatical word "et"
* ("and" in french).
*
* @param versions the minecraft versions to list
* @return a string representation of the provided list of version.
* @deprecated it uses the hardcoded french word "et" as the final word separator.
* Use {@link #displayOptimizedListOfVersions(List, String)} with "et" as the last parameter instead.
*/
@Deprecated
public static String displayOptimizedListOfVersionsAnd(List versions) {
return displayOptimizedListOfVersions(versions, "et");
}
/**
* Generate a string representation of the provided list of version, using
* {@link StringUtil#joinGrammatically(CharSequence, CharSequence, List)} with the gramatical word "ou"
* ("or" in french).
*
* @param versions the minecraft versions to list
* @return a string representation of the provided list of version.
* @deprecated it uses the hardcoded french word "ou" as the final word separator.
* Use {@link #displayOptimizedListOfVersions(List, String)} with "ou" as the last parameter instead.
*/
@Deprecated
public static String displayOptimizedListOfVersionsOr(List versions) {
return displayOptimizedListOfVersions(versions, "ou");
}
/**
* Returns an optimized list of string representation of Minecraft version, that represent the provided list of
* Minecraft version.
*
* This methods try to merge successive Minecraft version into a single string: for instance, all versions from 1.18
* to 1.18.2 are represented by the string "1.18.x"; all version from 1.14.1 to 1.14.4 are represented by the string
* "1.14.1-1.14.4".
*
* All possible merges of {@link MinecraftVersion} are listed in the static initializer of this enum.
*
* @param vList the {@link List} of {@link MinecraftVersion}
* @return an optimized list of string representation of Minecraft version.
*/
public static List getVersionsDisplayList(List vList) {
if (vList == null)
return new ArrayList<>();
Set vSet = EnumSet.copyOf(vList);
List ret = new ArrayList<>();
for (int i = 0; i < values().length; i++) {
if (!vSet.contains(values()[i]))
continue;
EnumSet vSubSet = EnumSet.of(values()[i]);
while (i + 1 < values().length && vSet.contains(values()[i + 1])) {
i++;
vSubSet.add(values()[i]);
if (!versionMergeDisplay.containsKey(vSubSet)) {
vSubSet.remove(values()[i]);
i--;
break;
}
}
if (vSubSet.size() == 1) {
ret.addAll(values()[i].versionsDisplay);
}
else {
ret.addAll(versionMergeDisplay.get(vSubSet));
}
}
return ret;
}
}