Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba72ec37c6 | ||
|
|
9bfb696c9d | ||
|
|
4a9848f51d | ||
|
|
383eacc814 | ||
|
|
860b80e2c2 | ||
|
|
0259bc8d9d | ||
|
|
37238e1226 | ||
|
|
c51880941b | ||
|
|
451bbe7597 | ||
|
|
d99e20d95e | ||
|
|
5eca22a9df | ||
|
|
c4d6b26986 | ||
|
|
197acc4d2f | ||
|
|
da5a5cf15a | ||
|
|
0797df24d2 | ||
|
|
7fca4ac8d6 | ||
|
|
0516513c67 | ||
|
|
4603794436 | ||
|
|
a5bbe4047b | ||
|
|
770a2d3287 | ||
|
|
3bd4b82d94 | ||
|
|
218b2d7782 | ||
|
|
76a08e6c12 | ||
|
|
4d28a58dcb |
No files matched your search
@@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>io.github.retrooper</groupId>
|
||||
<artifactId>packetevents</artifactId>
|
||||
<version>1.6.8</version>
|
||||
<version>1.6.9</version>
|
||||
|
||||
<!-- You can build the project with this: "mvn clean compile assembly:single" -->
|
||||
<build>
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
|
||||
public class PEVersion {
|
||||
private final int[] version = new int[4];
|
||||
|
||||
public PEVersion(int... version) throws IllegalArgumentException {
|
||||
if (version.length > 4) {
|
||||
throw new IllegalArgumentException("You are not allowed to have more than 4 arguments!");
|
||||
} else if (version.length < 2) {
|
||||
throw new IllegalArgumentException("You need atleast two arguments.");
|
||||
}
|
||||
int len = version.length;
|
||||
if (len < 4) {
|
||||
this.version[0] = version[0];
|
||||
this.version[1] = version[1];
|
||||
if (len == 3) {
|
||||
this.version[2] = version[2];
|
||||
} else {
|
||||
this.version[2] = 0;
|
||||
this.version[3] = 0;
|
||||
}
|
||||
} else {
|
||||
System.arraycopy(version, 0, this.version, 0, version.length);
|
||||
}
|
||||
}
|
||||
|
||||
public PEVersion(String text) {
|
||||
this(stringConstructor(text));
|
||||
}
|
||||
|
||||
private static int[] stringConstructor(String text) {
|
||||
//1.2.3.4
|
||||
text += ".";
|
||||
|
||||
int dotCount = 0;
|
||||
for (char c : text.toCharArray()) {
|
||||
if (c == '.') {
|
||||
dotCount++;
|
||||
}
|
||||
}
|
||||
|
||||
//1.2.3.4.
|
||||
int arrayIndex = 0;
|
||||
int[] version = new int[4];
|
||||
|
||||
// String t = "1.2.3.4";
|
||||
for (int i = 0; i < text.toCharArray().length; i++) {
|
||||
char c = text.toCharArray()[i];
|
||||
|
||||
if (c == '.') {
|
||||
version[arrayIndex++] =
|
||||
Integer.parseInt(Character.toString(text.toCharArray()[i - 1]));
|
||||
}
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
public boolean isNewer(PEVersion other) {
|
||||
//The version length if guaranteed to be 4.
|
||||
for (int i = 0; i < version.length; i++) {
|
||||
if (version[i] > other.getVersionAsByteArray()[i]) {
|
||||
return true;
|
||||
} else if (version[i] < other.getVersionAsByteArray()[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//If they are equal, they aren't newer nor older.
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isOlder(PEVersion other) {
|
||||
//The version length if guaranteed to be 4.
|
||||
for (int i = 0; i < version.length; i++) {
|
||||
if (version[i] < other.getVersionAsByteArray()[i]) {
|
||||
return true;
|
||||
} else if (version[i] > other.getVersionAsByteArray()[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//If they are equal, they aren't newer nor older.
|
||||
return false;
|
||||
}
|
||||
|
||||
public final int[] getVersionAsByteArray() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public final int[] getVersionAsByteArrayShortened() {
|
||||
List<Integer> versionBoxed = new ArrayList<>();
|
||||
if (version[3] == 0) {
|
||||
versionBoxed.add(version[0]);
|
||||
versionBoxed.add(version[1]);
|
||||
versionBoxed.add(version[2]);
|
||||
|
||||
if (version[2] == 0) {
|
||||
versionBoxed.clear();
|
||||
versionBoxed.add(version[0]);
|
||||
versionBoxed.add(version[1]);
|
||||
}
|
||||
return convertIntListToIntArray(versionBoxed);
|
||||
} else {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
|
||||
private int[] convertIntListToIntArray(List<Integer> list) {
|
||||
int[] versionArray = new int[list.size()];
|
||||
for (int i = 0; i < versionArray.length; i++) {
|
||||
versionArray[i] = list.get(i);
|
||||
}
|
||||
return versionArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
int[] shortenedVersion = getVersionAsByteArrayShortened();
|
||||
StringBuilder text = new StringBuilder();
|
||||
for (int v : shortenedVersion) {
|
||||
text.append(".").append(v);
|
||||
}
|
||||
return text.substring(1);
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,7 @@ public final class PacketEvents implements Listener {
|
||||
private static final PacketEvents instance = new PacketEvents();
|
||||
private static final ArrayList<Plugin> plugins = new ArrayList<Plugin>(1);
|
||||
private static boolean loaded, initialized, isBungee;
|
||||
private static final PEVersion version = new PEVersion(1, 6, 9);
|
||||
|
||||
/**
|
||||
* This loads the PacketEvents API.
|
||||
@@ -85,8 +86,6 @@ public final class PacketEvents implements Listener {
|
||||
|
||||
EntityFinderUtils.load();
|
||||
|
||||
ClientVersion.prepareLookUp();
|
||||
|
||||
WrappedPacket.loadAllWrappers();
|
||||
loaded = true;
|
||||
}
|
||||
@@ -124,6 +123,15 @@ public final class PacketEvents implements Listener {
|
||||
} catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
|
||||
isBungee = false;
|
||||
}
|
||||
|
||||
if (PacketEvents.getAPI().getSettings().shouldCheckForUpdates()) {
|
||||
Bukkit.getScheduler().runTask(pl, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
new UpdateChecker().handleUpdate();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,6 +194,10 @@ public final class PacketEvents implements Listener {
|
||||
return PacketEvents.getAPI().getSettings();
|
||||
}
|
||||
|
||||
public static PEVersion getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(final PlayerJoinEvent e) {
|
||||
if (!VersionLookupUtils.hasLoaded()) {
|
||||
@@ -194,12 +206,12 @@ public final class PacketEvents implements Listener {
|
||||
//for now we don't support bungee, rather handle it than have it FALSE
|
||||
//and return the version of the server.
|
||||
if (isBungee) {
|
||||
PacketEvents.getAPI().getPlayerUtils().clientVersionsMap.put(e.getPlayer().getUniqueId(), ClientVersion.ACCESS_FAILURE);
|
||||
PacketEvents.getAPI().getPlayerUtils().clientVersionsMap.put(e.getPlayer().getUniqueId(), ClientVersion.UNKNOWN);
|
||||
} else {
|
||||
ClientVersion version = ClientVersion.fromProtocolVersion(VersionLookupUtils.getProtocolVersion(e.getPlayer()));
|
||||
ClientVersion version = ClientVersion.getClientVersion(VersionLookupUtils.getProtocolVersion(e.getPlayer()));
|
||||
PacketEvents.getAPI().getPlayerUtils().clientVersionsMap.put(e.getPlayer().getUniqueId(), version);
|
||||
PacketEvents.getAPI().getPlayerUtils().injectPlayer(e.getPlayer());
|
||||
}
|
||||
PacketEvents.getAPI().getPlayerUtils().injectPlayer(e.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package io.github.retrooper.packetevents;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
||||
public class UpdateChecker {
|
||||
public void handleUpdate() {
|
||||
try {
|
||||
String line = readLatestVersion();
|
||||
PEVersion newVersion = new PEVersion(line);
|
||||
PEVersion localVersion = PacketEvents.getVersion();
|
||||
if (localVersion.isOlder(newVersion)) {
|
||||
inform("[PacketEvents] There is an update available for the PacketEvents API! (" + newVersion.toString() + ")");
|
||||
}
|
||||
else if(localVersion.equals(newVersion)) {
|
||||
inform("[PacketEvents] You are on the latest released version of PacketEvents. (" + newVersion.toString() + ")");
|
||||
}
|
||||
else if(localVersion.isNewer(newVersion)) {
|
||||
inform("[PacketEvents] You are on a dev or pre released build of PacketEvents. Your build: (" + localVersion.toString() + ") | Last released build: (" + newVersion.toString() + ")");
|
||||
}
|
||||
} catch (IOException ignored) {
|
||||
//Thats fine, Not important
|
||||
}
|
||||
}
|
||||
|
||||
private void inform(String message) {
|
||||
Bukkit.getLogger().info(message);
|
||||
}
|
||||
|
||||
private String readLatestVersion() throws IOException {
|
||||
URLConnection connection = new URL("https://api.spigotmc.org/legacy/update.php?resource=80279").openConnection();
|
||||
connection.addRequestProperty("User-Agent", "Mozilla/4.0");
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
|
||||
return reader.readLine();
|
||||
}
|
||||
}
|
||||
@@ -30,101 +30,106 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum ClientVersion {
|
||||
LESS_THAN_V_1_7_10, v_1_7_10, v_1_8, v_1_9, v_1_9_1, v_1_9_2, v_1_9_3, v_1_10, v_1_11, v_1_11_1, v_1_12, v_1_12_1, v_1_12_2,
|
||||
v_1_13, v_1_13_1, v_1_13_2, v_1_14, v_1_14_1, v_1_14_2, v_1_14_3, v_1_14_4, v_1_15_PRE_1, v_1_15_PRE_2, v_1_15_PRE_3, v_1_15_PRE_4, v_1_15_PRE_5, v_1_15_PRE_6, v_1_15_PRE_7,
|
||||
v_1_15, v_1_15_1, v_1_15_2, v_1_16, v_1_16_PRE_1, v_1_16_PRE_2, v_1_16_PRE_3, v_1_16_PRE_4, v_1_16_PRE_5, v_1_16_PRE_6, v_1_16_PRE_7, v_1_16_PRE_8, v_1_16_RC_1, v_1_16_1, v_1_16_2, HIGHER_THAN_V_1_16_2, INVALID, ACCESS_FAILURE;
|
||||
LOWER_THAN_SUPPORTED_VERSIONS(4),
|
||||
v_1_7_10(5),
|
||||
v_1_8(47),
|
||||
v_1_9(107),
|
||||
v_1_9_1(108),
|
||||
v_1_9_2(109),
|
||||
v_1_9_3(110),
|
||||
v_1_10(210),
|
||||
v_1_11(315),
|
||||
v_1_11_1(316),
|
||||
v_1_12(335),
|
||||
v_1_12_1(338),
|
||||
v_1_12_2(340),
|
||||
v_1_13(393),
|
||||
v_1_13_1(401),
|
||||
v_1_13_2(404),
|
||||
v_1_14(477),
|
||||
v_1_14_1(480),
|
||||
v_1_14_2(485),
|
||||
v_1_14_3(490),
|
||||
v_1_14_4(498),
|
||||
v_1_15(573),
|
||||
v_1_15_1(575),
|
||||
v_1_15_2(578),
|
||||
v_1_16(735),
|
||||
v_1_16_1(736),
|
||||
v_1_16_2(751),
|
||||
v_1_16_3(753),
|
||||
HIGHER_THAN_SUPPORTED_VERSIONS(754),
|
||||
/**
|
||||
* Pre releases just aren't supported, we would end up with so many enum constants.
|
||||
*/
|
||||
ANY_PRE_RELEASE_VERSION(0),
|
||||
|
||||
private static final Map<Integer, ClientVersion> VERSION_LOOKUP = new HashMap<Integer, ClientVersion>();
|
||||
UNKNOWN(-1);
|
||||
|
||||
public static void prepareLookUp() {
|
||||
VERSION_LOOKUP.put(-1, ACCESS_FAILURE);
|
||||
VERSION_LOOKUP.put(1, LESS_THAN_V_1_7_10);
|
||||
VERSION_LOOKUP.put(2, LESS_THAN_V_1_7_10);
|
||||
VERSION_LOOKUP.put(3, LESS_THAN_V_1_7_10);
|
||||
VERSION_LOOKUP.put(4, LESS_THAN_V_1_7_10);
|
||||
VERSION_LOOKUP.put(5, v_1_7_10);
|
||||
VERSION_LOOKUP.put(47, v_1_8);
|
||||
VERSION_LOOKUP.put(107, v_1_9);
|
||||
VERSION_LOOKUP.put(108, v_1_9_1);
|
||||
VERSION_LOOKUP.put(109, v_1_9_2);
|
||||
VERSION_LOOKUP.put(110, v_1_9_3);
|
||||
VERSION_LOOKUP.put(210, v_1_10);
|
||||
VERSION_LOOKUP.put(315, v_1_11);
|
||||
VERSION_LOOKUP.put(316, v_1_11_1);
|
||||
VERSION_LOOKUP.put(335, v_1_12);
|
||||
VERSION_LOOKUP.put(338, v_1_12_1);
|
||||
VERSION_LOOKUP.put(340, v_1_12_2);
|
||||
VERSION_LOOKUP.put(393, v_1_13);
|
||||
VERSION_LOOKUP.put(401, v_1_13_1);
|
||||
VERSION_LOOKUP.put(404, v_1_13_2);
|
||||
VERSION_LOOKUP.put(477, v_1_14);
|
||||
VERSION_LOOKUP.put(480, v_1_14_1);
|
||||
VERSION_LOOKUP.put(485, v_1_14_2);
|
||||
VERSION_LOOKUP.put(490, v_1_14_3);
|
||||
VERSION_LOOKUP.put(498, v_1_14_4);
|
||||
VERSION_LOOKUP.put(565, v_1_15_PRE_1);
|
||||
VERSION_LOOKUP.put(566, v_1_15_PRE_2);
|
||||
VERSION_LOOKUP.put(567, v_1_15_PRE_3);
|
||||
VERSION_LOOKUP.put(569, v_1_15_PRE_4);
|
||||
VERSION_LOOKUP.put(570, v_1_15_PRE_5);
|
||||
VERSION_LOOKUP.put(571, v_1_15_PRE_6);
|
||||
VERSION_LOOKUP.put(572, v_1_15_PRE_7);
|
||||
VERSION_LOOKUP.put(573, v_1_15);
|
||||
VERSION_LOOKUP.put(575, v_1_15_1);
|
||||
VERSION_LOOKUP.put(578, v_1_15_2);
|
||||
VERSION_LOOKUP.put(721, v_1_16_PRE_1);
|
||||
VERSION_LOOKUP.put(722, v_1_16_PRE_2);
|
||||
VERSION_LOOKUP.put(725, v_1_16_PRE_3);
|
||||
VERSION_LOOKUP.put(727, v_1_16_PRE_4);
|
||||
VERSION_LOOKUP.put(729, v_1_16_PRE_5);
|
||||
VERSION_LOOKUP.put(730, v_1_16_PRE_6);
|
||||
VERSION_LOOKUP.put(732, v_1_16_PRE_7);
|
||||
VERSION_LOOKUP.put(733, v_1_16_PRE_8);
|
||||
VERSION_LOOKUP.put(734, v_1_16_RC_1);
|
||||
VERSION_LOOKUP.put(735, v_1_16);
|
||||
VERSION_LOOKUP.put(736, v_1_16_1);
|
||||
VERSION_LOOKUP.put(737, v_1_16_2);
|
||||
private final int protocolVersion;
|
||||
|
||||
private static final int lowestSupportedProtocolVersion = 5;
|
||||
private static final int highestSupportedProtocolVersion = 753;
|
||||
ClientVersion(int protocolVersion) {
|
||||
this.protocolVersion = protocolVersion;
|
||||
}
|
||||
|
||||
public int getProtocolVersion() {
|
||||
return protocolVersion;
|
||||
}
|
||||
|
||||
public static boolean isHigherThan(ClientVersion a, ClientVersion b) {
|
||||
return a.getProtocolVersion() > b.getProtocolVersion();
|
||||
}
|
||||
|
||||
public static boolean isLowerThan(ClientVersion a, ClientVersion b) {
|
||||
return a.getProtocolVersion() < b.getProtocolVersion();
|
||||
}
|
||||
|
||||
public boolean isHigherThan(ClientVersion target) {
|
||||
return protocolVersion > target.getProtocolVersion();
|
||||
}
|
||||
|
||||
public boolean isLowerThan(ClientVersion target) {
|
||||
return protocolVersion < target.getProtocolVersion();
|
||||
}
|
||||
|
||||
public boolean equals(ClientVersion target) {
|
||||
return protocolVersion == target.getProtocolVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Added for now just to have backwards compatibility.
|
||||
* @param protocolVersion
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public static ClientVersion fromProtocolVersion(int protocolVersion) {
|
||||
if (protocolVersion == -1 && PacketEvents.getSettings().doAutoResolveClientProtocolVersion()) {
|
||||
protocolVersion = ServerVersion.getVersion().toProtocolVersion();
|
||||
}
|
||||
final ClientVersion lookedUp = VERSION_LOOKUP.get(protocolVersion);
|
||||
if (lookedUp != null) {
|
||||
return lookedUp;
|
||||
}
|
||||
return protocolVersion > 737 ? HIGHER_THAN_V_1_16_2 : INVALID;
|
||||
return getClientVersion(protocolVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the client's version is more up to date than the argument passed version
|
||||
*
|
||||
* @param version The version to compare to the client's value.
|
||||
* @return True if the supplied version is lower, false if it is equal or higher than the client's version.
|
||||
*/
|
||||
public boolean isHigherThan(final ClientVersion version) {
|
||||
if (this == version) return false;
|
||||
return !isLowerThan(version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the client's version is more outdated than the argument passed version
|
||||
*
|
||||
* @param version The version to compare to the client's value.
|
||||
* @return True if the supplied version is higher, false if it is equal or lower than the client's version.
|
||||
*/
|
||||
public boolean isLowerThan(final ClientVersion version) {
|
||||
if (this == version) return false;
|
||||
final int len = ClientVersion.values().length;
|
||||
for (byte i = 0; i < len; i++) {
|
||||
final ClientVersion v = ClientVersion.values()[i];
|
||||
if (v == this) {
|
||||
return true;
|
||||
} else if (v == version) {
|
||||
return false;
|
||||
public static ClientVersion getClientVersion(int protocolVersion) {
|
||||
if(protocolVersion == -1 && PacketEvents.getAPI().getSettings().doAutoResolveClientProtocolVersion()) {
|
||||
protocolVersion = PacketEvents.getAPI().getServerUtils().getVersion().toProtocolVersion();
|
||||
}
|
||||
for(ClientVersion version : ClientVersion.values()) {
|
||||
if(version.protocolVersion > protocolVersion) {
|
||||
break;
|
||||
}
|
||||
else if(version.protocolVersion == protocolVersion) {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
if(protocolVersion < lowestSupportedProtocolVersion) {
|
||||
return LOWER_THAN_SUPPORTED_VERSIONS;
|
||||
}
|
||||
else if(protocolVersion > highestSupportedProtocolVersion) {
|
||||
return HIGHER_THAN_SUPPORTED_VERSIONS;
|
||||
}
|
||||
else if(protocolVersion > lowestSupportedProtocolVersion
|
||||
&& protocolVersion < highestSupportedProtocolVersion) {
|
||||
return ANY_PRE_RELEASE_VERSION;
|
||||
}
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ public enum ServerVersion {
|
||||
v_1_9, v_1_9_2, v_1_9_4, v_1_10, v_1_10_2, v_1_11, v_1_11_1, v_1_11_2,
|
||||
v_1_12, v_1_12_1, v_1_12_2, v_1_13, v_1_13_1, v_1_13_2, v_1_14, v_1_14_1,
|
||||
v_1_14_2, v_1_14_3, v_1_14_4, v_1_15, v_1_15_1, v_1_15_2, v_1_16, v_1_16_1,
|
||||
v_1_16_2, ERROR, EMPTY;
|
||||
v_1_16_2, v_1_16_3, ERROR, EMPTY;
|
||||
|
||||
private static final String nmsVersionSuffix = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
|
||||
public static ServerVersion[] reversedValues = new ServerVersion[values().length];
|
||||
@@ -193,8 +193,10 @@ public enum ServerVersion {
|
||||
return 736;
|
||||
case v_1_16_2:
|
||||
return 751;
|
||||
case v_1_16_3:
|
||||
return 753;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,12 +25,7 @@
|
||||
package io.github.retrooper.packetevents.example;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.annotations.PacketHandler;
|
||||
import io.github.retrooper.packetevents.event.PacketListener;
|
||||
import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.packetwrappers.in.updatesign.WrappedPacketInUpdateSign;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.entityvelocity.WrappedPacketOutEntityVelocity;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class MainExample extends JavaPlugin implements PacketListener {
|
||||
@@ -42,16 +37,6 @@ public class MainExample extends JavaPlugin implements PacketListener {
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
//Deprecated, as it is no longer needed.
|
||||
/*
|
||||
*
|
||||
* PacketEvents will generate a random identifier for you if you do not set one
|
||||
* before initializing PacketEvents
|
||||
*
|
||||
*/
|
||||
|
||||
PacketEvents.getSettings().setIdentifier("official_api");
|
||||
|
||||
PacketEvents.init(this);
|
||||
PacketEvents.getAPI().getEventManager().registerListener(this);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.PacketSendEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.PlayerInjectEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.PlayerUninjectEvent;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
@@ -36,7 +37,7 @@ import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public class NettyPacketHandler {
|
||||
private static boolean v1_7_nettyMode = false;
|
||||
public static boolean v1_7_nettyMode = false;
|
||||
private static final ExecutorService singleThreadedExecutor = Executors.newSingleThreadExecutor();
|
||||
|
||||
static {
|
||||
@@ -75,6 +76,8 @@ public class NettyPacketHandler {
|
||||
* @return {@link java.util.concurrent.Future}
|
||||
*/
|
||||
public static Future<?> injectPlayerAsync(final Player player) {
|
||||
//Make sure we cache the channel SYNCHRONOUSLY
|
||||
Object channel = NMSUtils.getChannel(player);
|
||||
return singleThreadedExecutor.submit(() -> {
|
||||
try {
|
||||
final PlayerInjectEvent injectEvent = new PlayerInjectEvent(player, true);
|
||||
@@ -98,6 +101,7 @@ public class NettyPacketHandler {
|
||||
* @param player
|
||||
*/
|
||||
public static void ejectPlayer(final Player player) {
|
||||
NMSUtils.channelCache.remove(player.getUniqueId());
|
||||
try {
|
||||
final PlayerUninjectEvent uninjectEvent = new PlayerUninjectEvent(player);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(uninjectEvent);
|
||||
@@ -120,7 +124,8 @@ public class NettyPacketHandler {
|
||||
* @return {@link java.util.concurrent.Future}
|
||||
*/
|
||||
public static Future<?> ejectPlayerAsync(final Player player) {
|
||||
return singleThreadedExecutor.submit(() -> {
|
||||
NMSUtils.channelCache.remove(player.getUniqueId());
|
||||
Future<?> f = singleThreadedExecutor.submit(() -> {
|
||||
try {
|
||||
final PlayerUninjectEvent uninjectEvent = new PlayerUninjectEvent(player, true);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(uninjectEvent);
|
||||
@@ -135,6 +140,7 @@ public class NettyPacketHandler {
|
||||
|
||||
}
|
||||
});
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+3
-2
@@ -31,6 +31,7 @@ import net.minecraft.util.io.netty.channel.ChannelDuplexHandler;
|
||||
import net.minecraft.util.io.netty.channel.ChannelHandlerContext;
|
||||
import net.minecraft.util.io.netty.channel.ChannelPipeline;
|
||||
import net.minecraft.util.io.netty.channel.ChannelPromise;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
final class NettyPacketHandler_7 {
|
||||
@@ -68,9 +69,9 @@ final class NettyPacketHandler_7 {
|
||||
* @param player
|
||||
*/
|
||||
public static void ejectPlayer(final Player player) {
|
||||
Channel channel = (Channel) NMSUtils.getChannel(player);
|
||||
Channel channel = (Channel) NMSUtils.getChannelNoCache(player);
|
||||
channel.pipeline().remove(PacketEvents.getHandlerName(player.getName()));
|
||||
NMSUtils.channelCache.remove(player.getUniqueId());
|
||||
//Make sure we are removing the cache synchronously
|
||||
}
|
||||
|
||||
public static void sendPacket(Object rawChannel, Object packet) {
|
||||
|
||||
+10
-2
@@ -31,6 +31,7 @@ import io.netty.channel.ChannelDuplexHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
final class NettyPacketHandler_8 {
|
||||
@@ -67,9 +68,16 @@ final class NettyPacketHandler_8 {
|
||||
* @param player
|
||||
*/
|
||||
public static void ejectPlayer(final Player player) {
|
||||
final Channel channel = (Channel) NMSUtils.getChannel(player);
|
||||
final Channel channel = (Channel) NMSUtils.getChannelNoCache(player);
|
||||
channel.pipeline().remove(PacketEvents.getHandlerName(player.getName()));
|
||||
NMSUtils.channelCache.remove(player.getUniqueId());
|
||||
//Make sure we are removing the cache synchronously
|
||||
Bukkit.getScheduler().runTask(PacketEvents.getPlugins().get(0), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//Make sure we are removing the cache SYNCHRONOUSLY
|
||||
NMSUtils.channelCache.remove(player.getUniqueId());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void sendPacket(Object rawChannel, Object packet) {
|
||||
|
||||
@@ -46,6 +46,7 @@ import io.github.retrooper.packetevents.packetwrappers.in.windowclick.WrappedPac
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.abilities.WrappedPacketOutAbilities;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.animation.WrappedPacketOutAnimation;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.chat.WrappedPacketOutChat;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.custompayload.WrappedPacketOutCustomPayload;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.entity.WrappedPacketOutEntity;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.entityvelocity.WrappedPacketOutEntityVelocity;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.gamestatechange.WrappedPacketOutGameStateChange;
|
||||
@@ -58,12 +59,11 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class WrappedPacket implements WrapperPacketReader {
|
||||
protected final List<Field> fields = new ArrayList<>();
|
||||
private static final HashMap<Class<?>, HashMap<Class<?>, Field[]>> fieldCache = new HashMap<>();
|
||||
public static ServerVersion version;
|
||||
protected final Player player;
|
||||
protected Object packet;
|
||||
@@ -88,9 +88,130 @@ public class WrappedPacket implements WrapperPacketReader {
|
||||
} else if (packet.getClass().getSuperclass().equals(PacketTypeClasses.Server.ENTITY)) {
|
||||
packetClass = PacketTypeClasses.Server.ENTITY;
|
||||
}
|
||||
for (Field f : packetClass.getDeclaredFields()) {
|
||||
f.setAccessible(true);
|
||||
fields.add(f);
|
||||
|
||||
|
||||
if (!fieldCache.containsKey(packetClass)) {
|
||||
final Field[] declaredFields = packetClass.getDeclaredFields();
|
||||
List<Field> boolFields = new ArrayList<>();
|
||||
List<Field> byteFields = new ArrayList<>();
|
||||
List<Field> shortFields = new ArrayList<>();
|
||||
List<Field> intFields = new ArrayList<>();
|
||||
List<Field> longFields = new ArrayList<>();
|
||||
List<Field> floatFields = new ArrayList<>();
|
||||
List<Field> doubleFields = new ArrayList<>();
|
||||
List<Field> stringFields = new ArrayList<>();
|
||||
|
||||
List<Field> boolArrayFields = new ArrayList<>();
|
||||
List<Field> byteArrayFields = new ArrayList<>();
|
||||
List<Field> shortArrayFields = new ArrayList<>();
|
||||
List<Field> intArrayFields = new ArrayList<>();
|
||||
List<Field> longArrayFields = new ArrayList<>();
|
||||
List<Field> floatArrayFields = new ArrayList<>();
|
||||
List<Field> doubleArrayFields = new ArrayList<>();
|
||||
List<Field> stringArrayFields = new ArrayList<>();
|
||||
|
||||
for (Field f : declaredFields) {
|
||||
f.setAccessible(true);
|
||||
if (f.getType().equals(boolean.class)) {
|
||||
boolFields.add(f);
|
||||
} else if (f.getType().equals(byte.class)) {
|
||||
byteFields.add(f);
|
||||
} else if (f.getType().equals(short.class)) {
|
||||
shortFields.add(f);
|
||||
} else if (f.getType().equals(int.class)) {
|
||||
intFields.add(f);
|
||||
} else if (f.getType().equals(long.class)) {
|
||||
longFields.add(f);
|
||||
} else if (f.getType().equals(float.class)) {
|
||||
floatFields.add(f);
|
||||
} else if (f.getType().equals(double.class)) {
|
||||
doubleFields.add(f);
|
||||
} else if (f.getType().equals(String.class)) {
|
||||
stringFields.add(f);
|
||||
} else if (f.getType().equals(boolean[].class)) {
|
||||
boolArrayFields.add(f);
|
||||
} else if (f.getType().equals(byte[].class)) {
|
||||
byteArrayFields.add(f);
|
||||
} else if (f.getType().equals(short[].class)) {
|
||||
shortArrayFields.add(f);
|
||||
} else if (f.getType().equals(int[].class)) {
|
||||
intArrayFields.add(f);
|
||||
} else if (f.getType().equals(long[].class)) {
|
||||
longArrayFields.add(f);
|
||||
} else if (f.getType().equals(float[].class)) {
|
||||
floatArrayFields.add(f);
|
||||
} else if (f.getType().equals(double[].class)) {
|
||||
doubleArrayFields.add(f);
|
||||
} else if (f.getType().equals(String[].class)) {
|
||||
stringArrayFields.add(f);
|
||||
}
|
||||
}
|
||||
|
||||
HashMap<Class<?>, Field[]> map = new HashMap<>();
|
||||
if (!boolFields.isEmpty()) {
|
||||
map.put(boolean.class, boolFields.toArray(new Field[0]));
|
||||
}
|
||||
|
||||
if (!byteFields.isEmpty()) {
|
||||
map.put(byte.class, byteFields.toArray(new Field[0]));
|
||||
}
|
||||
|
||||
if (!shortFields.isEmpty()) {
|
||||
map.put(short.class, shortFields.toArray(new Field[0]));
|
||||
}
|
||||
|
||||
if (!intFields.isEmpty()) {
|
||||
map.put(int.class, intFields.toArray(new Field[0]));
|
||||
}
|
||||
|
||||
if (!longFields.isEmpty()) {
|
||||
map.put(long.class, longFields.toArray(new Field[0]));
|
||||
}
|
||||
|
||||
if (!floatFields.isEmpty()) {
|
||||
map.put(float.class, floatFields.toArray(new Field[0]));
|
||||
}
|
||||
|
||||
if (!doubleFields.isEmpty()) {
|
||||
map.put(double.class, doubleFields.toArray(new Field[0]));
|
||||
}
|
||||
|
||||
if (!stringFields.isEmpty()) {
|
||||
map.put(String.class, stringFields.toArray(new Field[0]));
|
||||
}
|
||||
|
||||
if (!boolArrayFields.isEmpty()) {
|
||||
map.put(boolean[].class, boolArrayFields.toArray(new Field[0]));
|
||||
}
|
||||
|
||||
if (!byteArrayFields.isEmpty()) {
|
||||
map.put(byte[].class, byteArrayFields.toArray(new Field[0]));
|
||||
}
|
||||
|
||||
if (!shortArrayFields.isEmpty()) {
|
||||
map.put(short[].class, shortArrayFields.toArray(new Field[0]));
|
||||
}
|
||||
|
||||
if (!intArrayFields.isEmpty()) {
|
||||
map.put(int[].class, intArrayFields.toArray(new Field[0]));
|
||||
}
|
||||
|
||||
if (!longArrayFields.isEmpty()) {
|
||||
map.put(long[].class, longArrayFields.toArray(new Field[0]));
|
||||
}
|
||||
|
||||
if (!floatArrayFields.isEmpty()) {
|
||||
map.put(float[].class, floatArrayFields.toArray(new Field[0]));
|
||||
}
|
||||
|
||||
if (!doubleArrayFields.isEmpty()) {
|
||||
map.put(double[].class, doubleArrayFields.toArray(new Field[0]));
|
||||
}
|
||||
|
||||
if (!stringArrayFields.isEmpty()) {
|
||||
map.put(String[].class, stringArrayFields.toArray(new Field[0]));
|
||||
}
|
||||
fieldCache.put(packetClass, map);
|
||||
}
|
||||
this.player = player;
|
||||
this.packet = packet;
|
||||
@@ -129,7 +250,7 @@ public class WrappedPacket implements WrapperPacketReader {
|
||||
WrappedPacketOutTransaction.load();
|
||||
WrappedPacketOutUpdateHealth.load();
|
||||
WrappedPacketOutGameStateChange.load();
|
||||
//WrappedPacketOutCustomPayload.load();
|
||||
WrappedPacketOutCustomPayload.load();
|
||||
}
|
||||
|
||||
protected void setup() {
|
||||
@@ -138,45 +259,102 @@ public class WrappedPacket implements WrapperPacketReader {
|
||||
|
||||
@Override
|
||||
public boolean readBoolean(int index) {
|
||||
return (boolean) readObject(index, boolean.class);
|
||||
if (fieldCache.containsKey(packetClass)) {
|
||||
try {
|
||||
return fieldCache.get(packetClass).get(boolean.class)[index].getBoolean(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte readByte(int index) {
|
||||
return (byte) readObject(index, byte.class);
|
||||
if (fieldCache.containsKey(packetClass)) {
|
||||
try {
|
||||
return fieldCache.get(packetClass).get(byte.class)[index].getByte(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short readShort(int index) {
|
||||
return (short) readObject(index, short.class);
|
||||
if (fieldCache.containsKey(packetClass)) {
|
||||
try {
|
||||
return fieldCache.get(packetClass).get(short.class)[index].getShort(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readInt(int index) {
|
||||
return (int) readObject(index, int.class);
|
||||
if (fieldCache.containsKey(packetClass)) {
|
||||
try {
|
||||
return fieldCache.get(packetClass).get(int.class)[index].getInt(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long readLong(int index) {
|
||||
return (long) readObject(index, long.class);
|
||||
if (fieldCache.containsKey(packetClass)) {
|
||||
try {
|
||||
return fieldCache.get(packetClass).get(long.class)[index].getLong(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float readFloat(int index) {
|
||||
return (float) readObject(index, float.class);
|
||||
if (fieldCache.containsKey(packetClass)) {
|
||||
try {
|
||||
return fieldCache.get(packetClass).get(float.class)[index].getFloat(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double readDouble(int index) {
|
||||
return (double) readObject(index, double.class);
|
||||
if (fieldCache.containsKey(packetClass)) {
|
||||
try {
|
||||
return fieldCache.get(packetClass).get(double.class)[index].getDouble(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean[] readBooleanArray(int index) {
|
||||
if (fieldCache.containsKey(packetClass)) {
|
||||
try {
|
||||
return (boolean[]) fieldCache.get(packetClass).get(boolean[].class)[index].get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
int currentIndex = 0;
|
||||
for(Field f : fields) {
|
||||
for (Field f : packetClass.getDeclaredFields()) {
|
||||
f.setAccessible(true);
|
||||
if (boolean[].class.isAssignableFrom(f.getType())) {
|
||||
if(index == currentIndex++) {
|
||||
if (index == currentIndex++) {
|
||||
try {
|
||||
return (boolean[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
@@ -190,10 +368,18 @@ public class WrappedPacket implements WrapperPacketReader {
|
||||
|
||||
@Override
|
||||
public byte[] readByteArray(int index) {
|
||||
if (fieldCache.containsKey(packetClass)) {
|
||||
try {
|
||||
return (byte[]) fieldCache.get(packetClass).get(byte[].class)[index].get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
int currentIndex = 0;
|
||||
for(Field f : fields) {
|
||||
for (Field f : packetClass.getDeclaredFields()) {
|
||||
f.setAccessible(true);
|
||||
if (byte[].class.isAssignableFrom(f.getType())) {
|
||||
if(index == currentIndex++) {
|
||||
if (index == currentIndex++) {
|
||||
try {
|
||||
return (byte[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
@@ -207,10 +393,18 @@ public class WrappedPacket implements WrapperPacketReader {
|
||||
|
||||
@Override
|
||||
public short[] readShortArray(int index) {
|
||||
if (fieldCache.containsKey(packetClass)) {
|
||||
try {
|
||||
return (short[]) fieldCache.get(packetClass).get(short[].class)[index].get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
int currentIndex = 0;
|
||||
for(Field f : fields) {
|
||||
for (Field f : packetClass.getDeclaredFields()) {
|
||||
f.setAccessible(true);
|
||||
if (short[].class.isAssignableFrom(f.getType())) {
|
||||
if(index == currentIndex++) {
|
||||
if (index == currentIndex++) {
|
||||
try {
|
||||
return (short[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
@@ -224,10 +418,18 @@ public class WrappedPacket implements WrapperPacketReader {
|
||||
|
||||
@Override
|
||||
public int[] readIntArray(int index) {
|
||||
if (fieldCache.containsKey(packetClass)) {
|
||||
try {
|
||||
return (int[]) fieldCache.get(packetClass).get(int[].class)[index].get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
int currentIndex = 0;
|
||||
for(Field f : fields) {
|
||||
for (Field f : packetClass.getDeclaredFields()) {
|
||||
f.setAccessible(true);
|
||||
if (int[].class.isAssignableFrom(f.getType())) {
|
||||
if(index == currentIndex++) {
|
||||
if (index == currentIndex++) {
|
||||
try {
|
||||
return (int[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
@@ -241,10 +443,18 @@ public class WrappedPacket implements WrapperPacketReader {
|
||||
|
||||
@Override
|
||||
public long[] readLongArray(int index) {
|
||||
if (fieldCache.containsKey(packetClass)) {
|
||||
try {
|
||||
return (long[]) fieldCache.get(packetClass).get(long[].class)[index].get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
int currentIndex = 0;
|
||||
for(Field f : fields) {
|
||||
for (Field f : packetClass.getDeclaredFields()) {
|
||||
f.setAccessible(true);
|
||||
if (long[].class.isAssignableFrom(f.getType())) {
|
||||
if(index == currentIndex++) {
|
||||
if (index == currentIndex++) {
|
||||
try {
|
||||
return (long[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
@@ -258,10 +468,18 @@ public class WrappedPacket implements WrapperPacketReader {
|
||||
|
||||
@Override
|
||||
public float[] readFloatArray(int index) {
|
||||
if (fieldCache.containsKey(packetClass)) {
|
||||
try {
|
||||
return (float[]) fieldCache.get(packetClass).get(float[].class)[index].get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
int currentIndex = 0;
|
||||
for(Field f : fields) {
|
||||
for (Field f : packetClass.getDeclaredFields()) {
|
||||
f.setAccessible(true);
|
||||
if (float.class.isAssignableFrom(f.getType())) {
|
||||
if(index == currentIndex++) {
|
||||
if (index == currentIndex++) {
|
||||
try {
|
||||
return (float[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
@@ -275,10 +493,18 @@ public class WrappedPacket implements WrapperPacketReader {
|
||||
|
||||
@Override
|
||||
public double[] readDoubleArray(int index) {
|
||||
if (fieldCache.containsKey(packetClass)) {
|
||||
try {
|
||||
return (double[]) fieldCache.get(packetClass).get(double[].class)[index].get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
int currentIndex = 0;
|
||||
for(Field f : fields) {
|
||||
for (Field f : packetClass.getDeclaredFields()) {
|
||||
f.setAccessible(true);
|
||||
if (double[].class.isAssignableFrom(f.getType())) {
|
||||
if(index == currentIndex++) {
|
||||
if (index == currentIndex++) {
|
||||
try {
|
||||
return (double[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
@@ -292,66 +518,70 @@ public class WrappedPacket implements WrapperPacketReader {
|
||||
|
||||
@Override
|
||||
public String[] readStringArray(int index) {
|
||||
Object[] array = readObjectArray(index, String[].class);
|
||||
int len = array.length;
|
||||
String[] stringArray = new String[len];
|
||||
for(int i = 0; i < len; i++) {
|
||||
stringArray[i] = array[i].toString();
|
||||
}
|
||||
return stringArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] readObjectArray(int index, Class<?> type) {
|
||||
int currentIndex = 0;
|
||||
for(Field f : fields) {
|
||||
if (type.isAssignableFrom(f.getType())) {
|
||||
if(index == currentIndex++) {
|
||||
try {
|
||||
return (Object[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (fieldCache.containsKey(packetClass)) {
|
||||
try {
|
||||
Object[] array = (Object[]) fieldCache.get(packetClass).get(String[].class)[index].get(packet);
|
||||
int len = array.length;
|
||||
String[] stringArray = new String[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
stringArray[i] = array[i].toString();
|
||||
}
|
||||
return stringArray;
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return new Object[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readObject(int index, Class<?> type) {
|
||||
int currentIndex = 0;
|
||||
for (Field f : fields) {
|
||||
if (type.isAssignableFrom(f.getType())) {
|
||||
if (index == currentIndex++) {
|
||||
try {
|
||||
return f.get(packet);
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readAnyObject(int index) {
|
||||
int currentIndex = 0;
|
||||
for (Field f : fields) {
|
||||
if (index == currentIndex++) {
|
||||
try {
|
||||
return f.get(packet);
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readString(int index) {
|
||||
return readObject(index, String.class).toString();
|
||||
if (fieldCache.containsKey(packetClass)) {
|
||||
try {
|
||||
Field[] fields = fieldCache.get(packetClass).get(String.class);
|
||||
Object obj = fields[index].get(packet);
|
||||
return obj.toString();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public Object readAnyObject(int index) {
|
||||
return packetClass.getDeclaredFields()[index];
|
||||
}
|
||||
|
||||
public Object readObject(int index, Class<?> type) {
|
||||
if (fieldCache.containsKey(packetClass)) {
|
||||
HashMap<Class<?>, Field[]> map = fieldCache.get(packetClass);
|
||||
if (!map.containsKey(type)) {
|
||||
List<Field> typeFields = new ArrayList<>();
|
||||
for (Field f : packetClass.getDeclaredFields()) {
|
||||
f.setAccessible(true);
|
||||
if (f.getType().equals(type)) {
|
||||
typeFields.add(f);
|
||||
}
|
||||
}
|
||||
if (!typeFields.isEmpty()) {
|
||||
map.put(type, typeFields.toArray(new Field[0]));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
try {
|
||||
return fieldCache.get(packetClass).get(type)[index].get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object[] readObjectArray(int index, Class<?> type) {
|
||||
Object res = readObject(index, type);
|
||||
if (res == null) {
|
||||
return new Object[0];
|
||||
}
|
||||
return (Object[]) res;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -56,11 +56,11 @@ public interface WrapperPacketReader {
|
||||
|
||||
String[] readStringArray(int index);
|
||||
|
||||
Object[] readObjectArray(int index, Class<?> type);
|
||||
String readString(int index);
|
||||
|
||||
Object readObject(int index, Class<?> type);
|
||||
|
||||
Object readAnyObject(int index);
|
||||
|
||||
String readString(int index);
|
||||
Object[] readObjectArray(int index, Class<?> type);
|
||||
}
|
||||
+50
-23
@@ -27,25 +27,25 @@ package io.github.retrooper.packetevents.packetwrappers.out.custompayload;
|
||||
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.bytebuf.ByteBufUtil;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
class WrappedPacketOutCustomPayload extends WrappedPacket implements SendableWrapper {
|
||||
//TODO load the outcustompayload wrapper
|
||||
|
||||
public class WrappedPacketOutCustomPayload extends WrappedPacket implements SendableWrapper {
|
||||
private static Class<?> packetClass;
|
||||
private static Constructor<?> constructor;
|
||||
private static Constructor<?> packetDataSerializerConstructor;
|
||||
private static Constructor<?> minecraftKeyConstructor;
|
||||
private static Class<?> byteBufClass;
|
||||
private static Class<?> unpooledClass;
|
||||
private static Class<?> packetDataSerializerClass;
|
||||
private static Class<?> minecraftKeyClass;
|
||||
private static int minecraftKeyIndexInClass;
|
||||
|
||||
private static byte constructorMode = 1;
|
||||
private static byte constructorMode = 0;
|
||||
|
||||
public static void load() {
|
||||
packetClass = PacketTypeClasses.Server.CUSTOM_PAYLOAD;
|
||||
@@ -53,21 +53,22 @@ class WrappedPacketOutCustomPayload extends WrappedPacket implements SendableWra
|
||||
minecraftKeyClass = NMSUtils.getNMSClassWithoutException("MinecraftKey");
|
||||
|
||||
try {
|
||||
unpooledClass = NMSUtils.getNettyClass("buffer.Unpooled");
|
||||
byteBufClass = NMSUtils.getNettyClass("buffer.ByteBuf");
|
||||
} catch (ClassNotFoundException e) {
|
||||
|
||||
}
|
||||
try {
|
||||
packetDataSerializerConstructor = packetDataSerializerClass.getConstructor(NMSUtils.getNettyClass("ByteBuf"));
|
||||
packetDataSerializerConstructor = packetDataSerializerClass.getConstructor(byteBufClass);
|
||||
} catch (NullPointerException e) {
|
||||
//Nothing
|
||||
} catch (NoSuchMethodException | ClassNotFoundException e) {
|
||||
} catch (NoSuchMethodException e) {
|
||||
//also nothing
|
||||
}
|
||||
|
||||
try {
|
||||
minecraftKeyConstructor = minecraftKeyClass.getConstructor(String.class);
|
||||
if (minecraftKeyClass != null) {
|
||||
minecraftKeyConstructor = minecraftKeyClass.getConstructor(String.class);
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
//Nothing
|
||||
}
|
||||
@@ -91,6 +92,15 @@ class WrappedPacketOutCustomPayload extends WrappedPacket implements SendableWra
|
||||
} catch (NoSuchMethodException e2) {
|
||||
//That's fine, just an even newer version
|
||||
try {
|
||||
//Minecraft key exists
|
||||
|
||||
for (int i = 0; i < packetClass.getDeclaredFields().length; i++) {
|
||||
Field f = packetClass.getDeclaredFields()[i];
|
||||
if (!Modifier.isStatic(f.getModifiers())) {
|
||||
minecraftKeyIndexInClass = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
constructor = packetClass.getConstructor(minecraftKeyClass, packetDataSerializerClass);
|
||||
constructorMode = 2;
|
||||
} catch (NoSuchMethodException e3) {
|
||||
@@ -109,15 +119,38 @@ class WrappedPacketOutCustomPayload extends WrappedPacket implements SendableWra
|
||||
}
|
||||
|
||||
|
||||
/* public WrappedPacketOutCustomPayload(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
public WrappedPacketOutCustomPayload(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
@Override
|
||||
protected void setup() {
|
||||
switch (constructorMode) {
|
||||
case 0:
|
||||
this.tag = readString(0);
|
||||
this.data = readByteArray(0);
|
||||
break;
|
||||
case 1:
|
||||
this.tag = readString(0);
|
||||
Object dataSerializer = readObject(0, packetDataSerializerClass);
|
||||
WrappedPacket byteBufWrapper = new WrappedPacket(dataSerializer);
|
||||
|
||||
Object byteBuf = byteBufWrapper.readObject(0, byteBufClass);
|
||||
|
||||
this.data = ByteBufUtil.getBytes(byteBuf);
|
||||
break;
|
||||
case 2:
|
||||
Object minecraftKey = readObject(minecraftKeyIndexInClass, minecraftKeyClass);
|
||||
WrappedPacket minecraftKeyWrapper = new WrappedPacket(minecraftKey);
|
||||
this.tag = minecraftKeyWrapper.readString(1);
|
||||
Object dataSerializer2 = readObject(0, packetDataSerializerClass);
|
||||
WrappedPacket byteBuf2Wrapper = new WrappedPacket(dataSerializer2);
|
||||
Object byteBuf2 = byteBuf2Wrapper.readObject(0, byteBufClass);
|
||||
this.data = ByteBufUtil.getBytes(byteBuf2);
|
||||
break;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
@@ -128,13 +161,7 @@ class WrappedPacketOutCustomPayload extends WrappedPacket implements SendableWra
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
Object byteBufObject = null;
|
||||
try {
|
||||
byteBufObject = Reflection.getMethod(unpooledClass, "copiedBuffer", 0).invoke(null, data);
|
||||
} catch (InvocationTargetException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Object byteBufObject = ByteBufUtil.copiedBuffer(data);
|
||||
switch (constructorMode) {
|
||||
case 0:
|
||||
try {
|
||||
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.playerinfo;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import org.bukkit.GameMode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class WrappedPacketOutPlayerInfo extends WrappedPacket implements SendableWrapper {
|
||||
//TODO load this wrapper
|
||||
|
||||
private PlayerInfoAction action;
|
||||
private List<PlayerInfoData> playerInfoDataList = new ArrayList<>();
|
||||
|
||||
private static byte mode = 0; //0 = 1.7.10
|
||||
|
||||
public static void load() {
|
||||
|
||||
}
|
||||
|
||||
public WrappedPacketOutPlayerInfo(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public WrappedPacketOutPlayerInfo(PlayerInfoAction action, Object gameProfile,
|
||||
int ping, GameMode gameMode, String displayName) {
|
||||
this.action = action;
|
||||
playerInfoDataList.add(new PlayerInfoData(gameProfile, ping, gameMode, displayName));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
switch (mode) {
|
||||
case 0:
|
||||
int actionInteger= readInt(0);
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public PlayerInfoAction getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public List<PlayerInfoData> getPlayerInfoData() {
|
||||
return playerInfoDataList;
|
||||
}
|
||||
|
||||
public enum PlayerInfoAction {
|
||||
ADD_PLAYER, UPDATE_GAME_MODE, UPDATE_LATENCY, UPDATE_DISPLAY_NAME, REMOVE_PLAYER;
|
||||
}
|
||||
|
||||
public class PlayerInfoData {
|
||||
private final int ping;
|
||||
private final GameMode gameMode;
|
||||
private final Object gameProfile;
|
||||
private final String displayName;
|
||||
|
||||
public PlayerInfoData(Object gameProfile, int ping,
|
||||
GameMode gameMode, String displayName) {
|
||||
this.ping = ping;
|
||||
this.gameMode = gameMode;
|
||||
this.gameProfile = gameProfile;
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public int getPing() {
|
||||
return ping;
|
||||
}
|
||||
|
||||
public GameMode getGameMode() {
|
||||
return gameMode;
|
||||
}
|
||||
|
||||
public Object getGameProfile() {
|
||||
return gameProfile;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,12 +25,13 @@
|
||||
package io.github.retrooper.packetevents.settings;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class PacketEventsSettings {
|
||||
|
||||
private ServerVersion defaultServerVersion = ServerVersion.v_1_7_10;
|
||||
private ServerVersion backupServerVersion = ServerVersion.v_1_7_10;
|
||||
private String identifier = "";
|
||||
private boolean autoResolveClientProtocolVersion = false;
|
||||
private boolean uninjectAsync = true;
|
||||
@@ -40,20 +41,30 @@ public class PacketEventsSettings {
|
||||
|
||||
/**
|
||||
* If PacketEvents fails to detect your server version, it will use the recommended version
|
||||
*
|
||||
* @deprecated Use {@link #getBackupServerVersion()}
|
||||
* @return Recommended version
|
||||
*/
|
||||
@Deprecated
|
||||
public ServerVersion getDefaultServerVersion() {
|
||||
return this.defaultServerVersion;
|
||||
return this.backupServerVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default version
|
||||
*
|
||||
* @deprecated Use {@link #setBackupServerVersion(ServerVersion)}
|
||||
* @param version ServerVersion
|
||||
*/
|
||||
@Deprecated
|
||||
public void setDefaultServerVersion(final ServerVersion version) {
|
||||
this.defaultServerVersion = version;
|
||||
this.backupServerVersion = version;
|
||||
}
|
||||
|
||||
public void setBackupServerVersion(ServerVersion version) {
|
||||
this.backupServerVersion = version;
|
||||
}
|
||||
|
||||
public ServerVersion getBackupServerVersion() {
|
||||
return backupServerVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,29 +95,48 @@ public class PacketEventsSettings {
|
||||
* Set a unique Identifier (Usually something that represents your plugin, For example: MyPluginPacketHandler)
|
||||
* If another present plugin uses the same Identifier, It will cause incompatibilities.
|
||||
*
|
||||
* This function is now unneeded as PacketEvents generates a random identifier for you already.
|
||||
* @param identifier Unique string
|
||||
* @deprecated This method is deprecated as you no longer need to set an identifier,
|
||||
* a unique identifier is already automatically generated for you.
|
||||
*/
|
||||
public void setIdentifier(final String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public boolean shouldAutoResolveClientProtocolVersion() {
|
||||
return autoResolveClientProtocolVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #shouldAutoResolveClientProtocolVersion()}
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean doAutoResolveClientProtocolVersion() {
|
||||
return autoResolveClientProtocolVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #setShouldAutoResolveClientProtocolVersion(boolean)}
|
||||
* @param autoResolveClientProtocolVersion
|
||||
*/
|
||||
@Deprecated
|
||||
public void setDoAutoResolveClientProtocolVersion(boolean autoResolveClientProtocolVersion) {
|
||||
this.autoResolveClientProtocolVersion = autoResolveClientProtocolVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* If PacketEvents fails to detect a client's version
|
||||
* (when ViaVersion, ProtocolLib or ProtocolSupport can't be found on the server),
|
||||
* should it assume that the client is using the same version as the server?
|
||||
* Returns ACCESS_FAILURE if this is set to FALSE(default value is false).
|
||||
*
|
||||
* @param autoResolveClientProtocolVersion boolean
|
||||
* @param val boolean
|
||||
*/
|
||||
public void setDoAutoResolveClientProtocolVersion(boolean autoResolveClientProtocolVersion) {
|
||||
this.autoResolveClientProtocolVersion = autoResolveClientProtocolVersion;
|
||||
public void setShouldAutoResolveClientProtocolVersion(boolean val) {
|
||||
this.autoResolveClientProtocolVersion = val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Would you like PacketEvents to Uninject players Asynchronously?
|
||||
@@ -154,11 +184,16 @@ public class PacketEventsSettings {
|
||||
this.useProtocolLibIfAvailable = val;
|
||||
}
|
||||
|
||||
/*public void setShouldCheckForUpdates(boolean val) {
|
||||
this.checkForUpdates = val;
|
||||
}
|
||||
|
||||
public boolean shouldCheckForUpdates() {
|
||||
return checkForUpdates;
|
||||
}*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Would you like PacketEvents to Check for Updates on startup?
|
||||
*
|
||||
* @param checkForUpdates boolean
|
||||
*/
|
||||
public void setShouldCheckForUpdates(boolean checkForUpdates) {
|
||||
this.checkForUpdates = checkForUpdates;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.utils.bytebuf;
|
||||
|
||||
import io.github.retrooper.packetevents.nettyhandler.NettyPacketHandler;
|
||||
|
||||
public class ByteBufUtil {
|
||||
public static Object copiedBuffer(byte[] bytes) {
|
||||
if (NettyPacketHandler.v1_7_nettyMode) {
|
||||
return ByteBufUtil_7.copiedBuffer(bytes);
|
||||
} else {
|
||||
return ByteBufUtil_8.copiedBuffer(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] getBytes(Object byteBuf) {
|
||||
if(NettyPacketHandler.v1_7_nettyMode) {
|
||||
return ByteBufUtil_7.getBytes(byteBuf);
|
||||
}
|
||||
else {
|
||||
return ByteBufUtil_8.getBytes(byteBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.utils.bytebuf;
|
||||
|
||||
import net.minecraft.util.io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.util.io.netty.buffer.Unpooled;
|
||||
|
||||
class ByteBufUtil_7 {
|
||||
public static Object copiedBuffer(byte[] bytes) {
|
||||
return Unpooled.copiedBuffer(bytes);
|
||||
}
|
||||
|
||||
public static byte[] getBytes(Object byteBuf) {
|
||||
ByteBuf bb = (ByteBuf)byteBuf;
|
||||
byte[] bytes;
|
||||
if (bb.hasArray()) {
|
||||
bytes = bb.array();
|
||||
} else {
|
||||
bytes = new byte[bb.readableBytes()];
|
||||
bb.getBytes(bb.readerIndex(), bytes);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.utils.bytebuf;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
class ByteBufUtil_8 {
|
||||
public static Object copiedBuffer(byte[] bytes) {
|
||||
return Unpooled.copiedBuffer(bytes);
|
||||
}
|
||||
|
||||
public static byte[] getBytes(Object byteBuf) {
|
||||
ByteBuf bb = (ByteBuf)byteBuf;
|
||||
byte[] bytes;
|
||||
if (bb.hasArray()) {
|
||||
bytes = bb.array();
|
||||
} else {
|
||||
bytes = new byte[bb.readableBytes()];
|
||||
bb.getBytes(bb.readerIndex(), bytes);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.utils.gameprofile;
|
||||
|
||||
import io.github.retrooper.packetevents.nettyhandler.NettyPacketHandler;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class GameProfileUtil {
|
||||
public static Object getGameProfile(UUID uuid, String username) {
|
||||
if(NettyPacketHandler.v1_7_nettyMode) {
|
||||
return GameProfileUtil_7.getGameProfile(uuid, username);
|
||||
}
|
||||
else {
|
||||
return GameProfileUtil_8.getGameProfile(uuid, username);
|
||||
}
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.utils.gameprofile;
|
||||
|
||||
import net.minecraft.util.com.mojang.authlib.GameProfile;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
class GameProfileUtil_7 {
|
||||
public static Object getGameProfile(UUID uuid, String username) {
|
||||
return new GameProfile(uuid, username);
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.utils.gameprofile;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
class GameProfileUtil_8 {
|
||||
public static Object getGameProfile(UUID uuid, String username) {
|
||||
return new GameProfile(uuid, username);
|
||||
}
|
||||
}
|
||||
@@ -28,8 +28,10 @@ import io.github.retrooper.packetevents.annotations.Nullable;
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.nettyhandler.NettyPacketHandler;
|
||||
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.entityfinder.EntityFinderUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -46,14 +48,14 @@ public final class NMSUtils {
|
||||
private static final String nmsDir = ServerVersion.getNMSDirectory();
|
||||
private static final String obcDir = ServerVersion.getOBCDirectory();
|
||||
public static String nettyPrefix = "io.netty";
|
||||
public static Class<?> minecraftServerClass, craftWorldsClass,
|
||||
packetClass, entityPlayerClass, playerConnectionClass,
|
||||
public static Class<?> minecraftServerClass, craftWorldClass, playerInteractManagerClass,
|
||||
packetClass, entityPlayerClass, playerConnectionClass, craftServerClass,
|
||||
craftPlayerClass, serverConnectionClass, craftEntityClass,
|
||||
craftItemStack, nmsItemStackClass, networkManagerClass, nettyChannelClass;
|
||||
private static Method getCraftWorldHandleMethod, getServerConnection, getCraftPlayerHandle, getCraftEntityHandle, sendPacketMethod, asBukkitCopy;
|
||||
private static Method craftWorldGetHandle,getCraftWorldHandleMethod, getServerConnection, getCraftPlayerHandle, getCraftEntityHandle, sendPacketMethod, asBukkitCopy;
|
||||
private static Field entityPlayerPingField, playerConnectionField;
|
||||
|
||||
public static final HashMap<UUID, Object> channelCache = new HashMap<UUID, Object>();
|
||||
public static final HashMap<UUID, Object> channelCache = new HashMap<>();
|
||||
|
||||
public static void load() {
|
||||
try {
|
||||
@@ -69,8 +71,9 @@ public final class NMSUtils {
|
||||
try {
|
||||
nettyChannelClass = getNettyClass("channel.Channel");
|
||||
minecraftServerClass = getNMSClass("MinecraftServer");
|
||||
craftWorldsClass = getOBCClass("CraftWorld");
|
||||
craftWorldClass = getOBCClass("CraftWorld");
|
||||
craftPlayerClass = getOBCClass("entity.CraftPlayer");
|
||||
craftServerClass = getOBCClass("CraftServer");
|
||||
entityPlayerClass = getNMSClass("EntityPlayer");
|
||||
packetClass = getNMSClass("Packet");
|
||||
playerConnectionClass = getNMSClass("PlayerConnection");
|
||||
@@ -79,18 +82,20 @@ public final class NMSUtils {
|
||||
craftItemStack = getOBCClass("inventory.CraftItemStack");
|
||||
nmsItemStackClass = getNMSClass("ItemStack");
|
||||
networkManagerClass = getNMSClass("NetworkManager");
|
||||
playerInteractManagerClass = getNMSClass("PlayerInteractManager");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
//METHODS
|
||||
try {
|
||||
getCraftWorldHandleMethod = craftWorldsClass.getMethod("getHandle");
|
||||
getCraftWorldHandleMethod = craftWorldClass.getMethod("getHandle");
|
||||
getCraftPlayerHandle = craftPlayerClass.getMethod("getHandle");
|
||||
getCraftEntityHandle = craftEntityClass.getMethod("getHandle");
|
||||
sendPacketMethod = playerConnectionClass.getMethod("sendPacket", packetClass);
|
||||
getServerConnection = minecraftServerClass.getMethod("getServerConnection");
|
||||
asBukkitCopy = craftItemStack.getMethod("asBukkitCopy", nmsItemStackClass);
|
||||
craftWorldGetHandle = craftWorldClass.getMethod("getHandle");
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -197,17 +202,21 @@ public final class NMSUtils {
|
||||
|
||||
public static Object getChannel(final Player player) {
|
||||
UUID uuid = player.getUniqueId();
|
||||
if(!channelCache.containsKey(uuid)) {
|
||||
try {
|
||||
Object channel = Reflection.getField(networkManagerClass, nettyChannelClass, 0).get(getNetworkManager(player));
|
||||
channelCache.put(uuid, channel);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (!channelCache.containsKey(uuid)) {
|
||||
channelCache.put(uuid, getChannelNoCache(player));
|
||||
}
|
||||
return channelCache.get(uuid);
|
||||
}
|
||||
|
||||
public static Object getChannelNoCache(final Player player) {
|
||||
try {
|
||||
return Reflection.getField(networkManagerClass, nettyChannelClass, 0).get(getNetworkManager(player));
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int getPlayerPing(final Player player) {
|
||||
Object entityPlayer = getEntityPlayer(player);
|
||||
try {
|
||||
@@ -227,6 +236,50 @@ public final class NMSUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object convertBukkitServerToNMSServer(Server server) {
|
||||
Object craftServer = craftServerClass.cast(server);
|
||||
WrappedPacket wrapper = new WrappedPacket(craftServer);
|
||||
return wrapper.readObject(0, minecraftServerClass);
|
||||
}
|
||||
|
||||
public static Object convertBukkitWorldToNMSWorld(World world) {
|
||||
Object craftWorld = craftWorldClass.cast(world);
|
||||
|
||||
Object worldServer = null;
|
||||
try {
|
||||
worldServer = craftWorldGetHandle.invoke(craftWorld);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return worldServer;
|
||||
}
|
||||
|
||||
public static Object createNewEntityPlayer(Server server, World world, Object gameProfile) {
|
||||
Object nmsServer = convertBukkitServerToNMSServer(server);
|
||||
Object nmsWorld = convertBukkitWorldToNMSWorld(world);
|
||||
return privateCreateNewEntityPlayer(nmsServer, nmsWorld, gameProfile);
|
||||
}
|
||||
|
||||
private static Object privateCreateNewEntityPlayer(Object nmsServer, Object nmsWorld, Object gameProfile) {
|
||||
Object playerInteractManager = null;
|
||||
try {
|
||||
playerInteractManager = playerInteractManagerClass.getConstructor(nmsWorld.getClass()).newInstance(nmsWorld);
|
||||
} catch (InstantiationException | IllegalAccessException
|
||||
| InvocationTargetException | NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
return entityPlayerClass.getConstructor(nmsServer.getClass(), nmsWorld.getClass(),
|
||||
gameProfile.getClass(), playerConnectionClass).
|
||||
newInstance(nmsServer, nmsWorld, gameProfile, playerInteractManager);
|
||||
} catch (InstantiationException | IllegalAccessException
|
||||
| InvocationTargetException | NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void sendSendableWrapper(final Player player, final SendableWrapper sendableWrapper) {
|
||||
NMSUtils.sendNMSPacket(player, sendableWrapper.asNMSPacket());
|
||||
}
|
||||
|
||||
@@ -84,6 +84,16 @@ public final class Reflection {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> cls, Class<?> returning, int index, Class<?>... params) {
|
||||
int currentIndex = 0;
|
||||
for(Method m : getMethods(cls)) {
|
||||
if(Arrays.equals(m.getParameterTypes(), params) && m.getReturnType().equals(returning) && index == currentIndex++) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Method getMethod(final Class<?> cls, final String name, Class<?> returning, Class<?>... params) {
|
||||
for (final Method m : getMethods(cls)) {
|
||||
if (m.getName().equals(name) && Arrays.equals(m.getParameterTypes(), params) && m.getReturnType().equals(returning)) {
|
||||
@@ -106,7 +116,7 @@ public final class Reflection {
|
||||
public static Method getMethod(final Class<?> cls, final Class<?> returning, final int index) {
|
||||
int currentIndex = 0;
|
||||
for (final Method m : getMethods(cls)) {
|
||||
if (m.getReturnType().equals(returning) && index == currentIndex++) {
|
||||
if (returning.equals(m.getReturnType()) && index == currentIndex++) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user