Skip to content

Commit dbf3da2

Browse files
committed
Initial commit
0 parents  commit dbf3da2

File tree

6 files changed

+1234
-0
lines changed

6 files changed

+1234
-0
lines changed

pom.xml

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>me.croabeast</groupId>
8+
<artifactId>PrismaticAPI</artifactId>
9+
<version>1.0</version>
10+
<packaging>jar</packaging>
11+
12+
<name>PrismaticAPI</name>
13+
14+
<properties>
15+
<java.version>17</java.version>
16+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
17+
</properties>
18+
19+
<build>
20+
<defaultGoal>clean package</defaultGoal>
21+
<plugins>
22+
<plugin>
23+
<groupId>org.apache.maven.plugins</groupId>
24+
<artifactId>maven-compiler-plugin</artifactId>
25+
<version>3.13.0</version>
26+
<configuration>
27+
<source>1.8</source>
28+
<target>1.8</target>
29+
<compilerArgs>
30+
<arg>-Xlint:-options</arg>
31+
</compilerArgs>
32+
</configuration>
33+
</plugin>
34+
35+
<plugin>
36+
<groupId>org.apache.maven.plugins</groupId>
37+
<artifactId>maven-source-plugin</artifactId>
38+
<version>3.3.1</version>
39+
<executions>
40+
<execution>
41+
<id>attach-sources</id>
42+
<phase>prepare-package</phase>
43+
<goals>
44+
<goal>jar</goal>
45+
</goals>
46+
</execution>
47+
</executions>
48+
</plugin>
49+
50+
<plugin>
51+
<groupId>org.apache.maven.plugins</groupId>
52+
<artifactId>maven-shade-plugin</artifactId>
53+
<version>3.5.3</version>
54+
<executions>
55+
<execution>
56+
<phase>package</phase>
57+
<goals>
58+
<goal>shade</goal>
59+
</goals>
60+
<configuration>
61+
<createDependencyReducedPom>false</createDependencyReducedPom>
62+
</configuration>
63+
</execution>
64+
</executions>
65+
66+
<configuration>
67+
<filters>
68+
<filter>
69+
<artifact>*:*</artifact>
70+
<excludes>
71+
<exclude>META-INF/**</exclude>
72+
</excludes>
73+
</filter>
74+
</filters>
75+
</configuration>
76+
</plugin>
77+
78+
<plugin>
79+
<groupId>org.apache.maven.plugins</groupId>
80+
<artifactId>maven-javadoc-plugin</artifactId>
81+
<version>3.5.0</version>
82+
<configuration>
83+
<additionalOptions>-Xdoclint:none</additionalOptions>
84+
</configuration>
85+
<executions>
86+
<execution>
87+
<id>attach-javadocs</id>
88+
<goals>
89+
<goal>jar</goal>
90+
</goals>
91+
</execution>
92+
</executions>
93+
</plugin>
94+
</plugins>
95+
96+
<resources>
97+
<resource>
98+
<directory>src/main/resources</directory>
99+
<filtering>true</filtering>
100+
</resource>
101+
</resources>
102+
</build>
103+
104+
<repositories>
105+
<repository>
106+
<id>spigotmc-repo</id>
107+
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
108+
</repository>
109+
110+
<repository>
111+
<id>sonatype</id>
112+
<url>https://oss.sonatype.org/content/groups/public/</url>
113+
</repository>
114+
115+
<repository>
116+
<id>viaversion-repo</id>
117+
<url>https://repo.viaversion.com</url>
118+
</repository>
119+
</repositories>
120+
121+
<dependencies>
122+
<dependency>
123+
<groupId>org.jetbrains</groupId>
124+
<artifactId>annotations</artifactId>
125+
<version>26.0.1</version>
126+
<scope>provided</scope>
127+
</dependency>
128+
129+
<dependency>
130+
<groupId>org.projectlombok</groupId>
131+
<artifactId>lombok</artifactId>
132+
<version>1.18.36</version>
133+
<scope>provided</scope>
134+
</dependency>
135+
136+
<dependency>
137+
<groupId>org.spigotmc</groupId>
138+
<artifactId>spigot-api</artifactId>
139+
<version>1.16.5-R0.1-SNAPSHOT</version>
140+
<scope>provided</scope>
141+
</dependency>
142+
143+
<dependency>
144+
<groupId>com.viaversion</groupId>
145+
<artifactId>viaversion-api</artifactId>
146+
<version>5.3.1</version>
147+
<scope>provided</scope>
148+
<exclusions>
149+
<exclusion>
150+
<groupId>*</groupId>
151+
<artifactId>*</artifactId>
152+
</exclusion>
153+
</exclusions>
154+
</dependency>
155+
</dependencies>
156+
</project>
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
package me.croabeast.prismatic;
2+
3+
import com.google.common.collect.Lists;
4+
import com.viaversion.viaversion.api.Via;
5+
import org.bukkit.Bukkit;
6+
import org.bukkit.entity.Player;
7+
8+
import java.util.ArrayList;
9+
import java.util.Arrays;
10+
import java.util.List;
11+
import java.util.regex.Matcher;
12+
import java.util.regex.Pattern;
13+
14+
/**
15+
* Provides a mapping between Minecraft client protocol versions and a simplified major version.
16+
* <p>
17+
* The {@code ClientVersion} class is used to determine the major client version from a player's protocol
18+
* version, which is helpful when implementing version-specific features or handling legacy clients.
19+
* It maintains an internal list of {@code ClientVersion} instances, each corresponding to a range of protocol
20+
* numbers. If no matching version is found, it returns an unknown version.
21+
* </p>
22+
* <p>
23+
* This class also offers utility methods to check if a client is considered legacy.
24+
* </p>
25+
* <p>
26+
* Example usage:
27+
* <pre><code>
28+
* int majorVersion = ClientVersion.getClientVersion(player);
29+
* boolean isLegacy = ClientVersion.isLegacy(player);
30+
* System.out.println("Player client major version: " + majorVersion);
31+
* </code></pre>
32+
* </p>
33+
*
34+
* @see Via
35+
*/
36+
public final class ClientVersion {
37+
38+
/**
39+
* A list of all registered client version mappings.
40+
*/
41+
private static final List<ClientVersion> PROTOCOL_LIST = new ArrayList<>();
42+
43+
/**
44+
* Represents an unknown client version.
45+
*/
46+
private static final ClientVersion UNKNOWN = new ClientVersion(0, 0, 0);
47+
48+
static final double SERVER_VERSION;
49+
50+
static {
51+
double main = 0.0;
52+
53+
Pattern p = Pattern.compile("1\\.(\\d+(\\.\\d+)?)");
54+
Matcher m = p.matcher(Bukkit.getVersion());
55+
56+
if (m.find())
57+
try {
58+
main = Double.parseDouble(m.group(1));
59+
} catch (Exception ignored) {
60+
}
61+
62+
SERVER_VERSION = main;
63+
64+
new ClientVersion(7, 0, 5);
65+
new ClientVersion(8, 6, 47);
66+
new ClientVersion(9, 48, 110);
67+
new ClientVersion(10, 201, 210, fromInts(206, 209));
68+
new ClientVersion(11, 301, 316);
69+
new ClientVersion(12, 317, 340);
70+
new ClientVersion(13, 341, 404);
71+
new ClientVersion(14, 441, 500, fromInts(499));
72+
new ClientVersion(15, 550, 578);
73+
new ClientVersion(16, 701, 754);
74+
new ClientVersion(17, 755, 756);
75+
new ClientVersion(18, 757, 758);
76+
new ClientVersion(19, 759, 762);
77+
new ClientVersion(20, 763, 766);
78+
new ClientVersion(21, 767, 770);
79+
}
80+
81+
/**
82+
* The major version number for this client version.
83+
*/
84+
private final int version;
85+
86+
/**
87+
* A list of protocol numbers associated with this major client version.
88+
*/
89+
private final List<Integer> protocols;
90+
91+
/**
92+
* Creates a list of integers representing a range from the given start to end (inclusive).
93+
*
94+
* @param numbers an array of two integers where the first is the start and the second is the end of the range
95+
* @return a list of protocol numbers in the specified range
96+
*/
97+
private static List<Integer> fromInts(Integer... numbers) {
98+
if (numbers.length != 2)
99+
return Lists.newArrayList(numbers);
100+
int z = numbers[1], y = numbers[0];
101+
Integer[] array = new Integer[(z - y) + 1];
102+
int index = 0;
103+
for (int i = y; i <= z; i++) {
104+
array[index] = i;
105+
index++;
106+
}
107+
return new ArrayList<>(Arrays.asList(array));
108+
}
109+
110+
/**
111+
* Constructs a new {@code ClientVersion} with the specified major version and protocol range,
112+
* optionally excluding certain protocol numbers.
113+
*
114+
* @param version the major version number
115+
* @param start the starting protocol number (inclusive)
116+
* @param end the ending protocol number (inclusive)
117+
* @param ignore a list of protocol numbers to ignore; may be {@code null} or empty
118+
*/
119+
private ClientVersion(int version, int start, int end, List<Integer> ignore) {
120+
this.version = version;
121+
List<Integer> range = fromInts(start, end);
122+
if (ignore == null || ignore.isEmpty()) {
123+
protocols = range;
124+
PROTOCOL_LIST.add(this);
125+
return;
126+
}
127+
range.removeIf(ignore::contains);
128+
protocols = range;
129+
PROTOCOL_LIST.add(this);
130+
}
131+
132+
/**
133+
* Constructs a new {@code ClientVersion} with the specified major version and protocol range.
134+
*
135+
* @param version the major version number
136+
* @param start the starting protocol number (inclusive)
137+
* @param end the ending protocol number (inclusive)
138+
*/
139+
private ClientVersion(int version, int start, int end) {
140+
this(version, start, end, null);
141+
}
142+
143+
/**
144+
* Returns a string representation of the client version.
145+
* <p>
146+
* For unknown versions, it returns "UNKNOWN_CLIENT:0". Otherwise, it returns "CLIENT:" followed by the major version number.
147+
* </p>
148+
*
149+
* @return a string representing the client version
150+
*/
151+
@Override
152+
public String toString() {
153+
return version == 0 ? "UNKNOWN_CLIENT:0" : ("CLIENT:" + version);
154+
}
155+
156+
/**
157+
* Returns an array containing all registered {@code ClientVersion} instances.
158+
*
159+
* @return an array of {@code ClientVersion} objects
160+
*/
161+
public static ClientVersion[] values() {
162+
return PROTOCOL_LIST.toArray(new ClientVersion[0]);
163+
}
164+
165+
/**
166+
* Determines the major client version for the given player based on their protocol version.
167+
* <p>
168+
* If ViaVersion is not enabled or the player is {@code null}, the server's version is returned.
169+
* Otherwise, the player's protocol version is retrieved, and the corresponding major version is determined.
170+
* </p>
171+
*
172+
* @param player the player whose client version is to be determined; may be {@code null}
173+
* @return the major client version number, or {@code 0} for unknown versions
174+
*/
175+
public static int getClientVersion(Player player) {
176+
if (player == null)
177+
return (int) SERVER_VERSION;
178+
179+
if (!Bukkit.getPluginManager().isPluginEnabled("ViaVersion"))
180+
return (int) SERVER_VERSION;
181+
182+
int i = Via.getAPI().getPlayerVersion(player.getUniqueId());
183+
for (ClientVersion p : values()) {
184+
if (p == UNKNOWN) continue;
185+
if (p.protocols.contains(i)) return p.version;
186+
}
187+
188+
return UNKNOWN.version;
189+
}
190+
191+
/**
192+
* Checks whether the specified player's client is considered legacy.
193+
* <p>
194+
* A legacy client is defined as one with a major version of 15 or lower.
195+
* </p>
196+
*
197+
* @param player the player whose client version is to be checked
198+
* @return {@code true} if the player's client is legacy; {@code false} otherwise
199+
*/
200+
public static boolean isLegacy(Player player) {
201+
return getClientVersion(player) <= 15;
202+
}
203+
}

0 commit comments

Comments
 (0)