Compare commits

..
26 Commits
Author SHA1 Message Date
retrooper 85dab8eb7a 1.7.6 release
1.7.6 release
2020-11-15 12:48:42 +01:00
retrooper 5fb8634880 * PacketEventsNMSCachedEntityNotFoundException exception created and is thrown when the cached nms entity isn't found.
WrappedPacketOutBlockChange wrapper TODO
2020-11-15 12:08:42 +01:00
retrooper e551421867 Reverted to old legacy event manager code
* Lower event priorities aren't called before higher ones on the legacy event system.
* PacketEvents.getSettings().useProtocolLibIfAvailable temporarily removed, currently unsupported so has been removed.
It is recommended to slowly update to the new event system, the current might get cut off soon!
2020-11-15 11:27:19 +01:00
retrooper 3dfb1ce0b5 * EventManagerLegacy isn't working, about to revert to the old event manager code, keeping this just incase.
When joining the server I instantly get kicked for "Disconnected".
2020-11-15 11:08:25 +01:00
retrooper aca321c332 Small bug fix for event systems
* Using MONITOR event priority now works
2020-11-15 10:36:21 +01:00
retrooper e0f4891a72 * Legacy and Dynamic event system ATTEMPT
API wise working, contains debugs, but UNTESTED!!!
The legacy(last event listener system) has been deprecated!
2020-11-15 10:27:31 +01:00
retrooper 08b207d80a Cleaner errors with PacketEvents
* PacketEventsLoadFailureException exception thrown if PacketEvents fails to load.
* PacketEventsMethodAccessException exception thrown if PacketEvents fails to access a method of a PacketListener for invoking.
* PacketEventsMethodInvokeException exception thrown if an exception is thrown from the invoked method in the PacketListener.
2020-11-15 08:43:29 +01:00
Retrooper 6121349a6f bug fixes
* resolving clientversion on bungee servers issue fixed
* read me cleaned up
* Via and ProtocolSupport utils removed
2020-11-15 15:09:46 +08:00
Retrooper 2b58a9ad97 small bug fixes
* Bungee channel name changed from "packetevents" to "packetevents:channel"
* NPE when accessing player version with viaversion onJoin sometimes
2020-11-14 00:44:55 +08:00
Retrooper 8e922a7676 Merge branch 'dev' of https://github.com/retrooper/packetevents
 Conflicts:
	src/main/java/io/github/retrooper/packetevents/example/MainExample.java
2020-11-13 23:45:49 +08:00
Retrooper 7967b6851f a 2020-11-13 23:42:55 +08:00
retrooper 18b37abf5b Merge pull request #64 from LIWKK/patch-13
Return 0 instead of -1 in blockplace wrapper 1.9
2020-11-11 22:25:49 +01:00
retrooper 53b713f574 Merge pull request #63 from LIWKK/patch-12
Return 0 instead of -1 in blockplace wrapper 1.8
2020-11-11 22:24:58 +01:00
Johannes 655f162272 Return 0 instead of -1 to not fuckup (1.9) 2020-11-11 23:22:01 +02:00
Johannes 686c50a7bb Return 0 instead of -1 to not fuckup other things. 2020-11-11 23:21:14 +02:00
retrooper a88e95e116 Merge pull request #62 from retrooper/dev
1.7.5 release
2020-11-09 07:21:41 +01:00
retrooper 7c583bf8ec 1.7.5 release 2020-11-09 07:21:06 +01:00
retrooper c3911483a5 Fix of WrappedPacketInBlockPlace returning -1 on 1.8 servers (By @LIWKK) 2020-11-08 22:12:03 +01:00
Johannes f37d7f4040 Fixxxxx 2020-11-08 23:10:14 +02:00
retrooper c39c9691a8 * Attempt to fix a bug to do with block place on 1.9+ 2020-11-08 17:39:11 +01:00
retrooper a1c591a616 Merge pull request #60 from retrooper/dev
1.7.4 Release
2020-11-08 15:17:16 +01:00
retrooper 999e21bf77 1.7.4
* PacketEvents.getSettings().packetHandlingThreadCount(int) setting added, basically lets you decide how many threads packetevents should use when asynchronously injecting/ejecting players, processing packets(packetevents' end) and event calling(processing on your end).
PacketEvents' current default settings are the most recommended settings.
Having more than one thread doing all that processing might cause you (or packetevents, as that feature hasn't been tested that much) some concurrency issues where multiple threads are accessing/modifying the same data at the same time!
2020-11-08 15:15:19 +01:00
retrooper c8e5a37472 Bug fix
* paper(and it's forks) 1.16 bug fix(unsure if this bug also existed in spigot or lower versions)
2020-11-08 14:44:02 +01:00
retrooper c6fffca506 Bug fixes
* WrappedPacketInUpdateSign error when reading Text Lines fixed
* WrappedPacketOutHeldItemSlot wrapper created
2020-11-08 12:33:46 +01:00
retrooper f1206a1fc6 * Block dig wrapper fixed
* Update sign wrapper fixed
* NPEs in Packet Receive/Send event fixed
2020-11-05 20:52:44 +01:00
terrarier2111 29a4280b50 Improved MUCH 2020-11-04 18:29:00 +01:00
69 changed files with 1048 additions and 998 deletions

No files matched your search

+2 -8
View File
@@ -1,14 +1,10 @@
# packetevents
A Spigot packet API with some nice utlities.
A spigot Packet API with some nice utlities.
## About
This packetlistener is **only** supported on Spigot servers and has been tested to work on these Spigot forks: PaperMC, Tuinity
* No dependencies
* Licensed under the MIT license
This API is **only** supported on Spigot servers and has been tested to work on these Spigot forks: Paper, Tuinity, Purpur
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
@@ -16,5 +12,3 @@ Our discord server: https://discord.me/packetevents
[![](https://jitpack.io/v/retrooper/packetevents.svg)](https://jitpack.io/#retrooper/packetevents)
[![](https://jitci.com/gh/retrooper/packetevents/svg)](https://jitci.com/gh/retrooper/packetevents)
+1 -16
View File
@@ -6,7 +6,7 @@
<groupId>io.github.retrooper</groupId>
<artifactId>packetevents</artifactId>
<version>1.7.3</version>
<version>1.7.6</version>
<!-- You can build the project with this: "mvn clean compile assembly:single" -->
<build>
@@ -122,21 +122,6 @@
<version>4.5.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>us.myles</groupId>
<artifactId>viaversion</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.ProtocolSupport</groupId>
<artifactId>ProtocolSupport</artifactId>
<version>4fdd683</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
@@ -26,8 +26,8 @@ package io.github.retrooper.packetevents;
import io.github.retrooper.packetevents.bungee.BungeePluginMessageListener;
import io.github.retrooper.packetevents.event.PacketEvent;
import io.github.retrooper.packetevents.exceptions.PacketEventsLoadFailureException;
import io.github.retrooper.packetevents.packetmanager.PacketManager;
import io.github.retrooper.packetevents.packetmanager.netty.NettyPacketManager;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.settings.PacketEventsSettings;
@@ -37,10 +37,11 @@ import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.player.ClientVersion;
import io.github.retrooper.packetevents.utils.server.PEVersion;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import io.github.retrooper.packetevents.utils.versionlookup.VersionLookupUtils;
import io.github.retrooper.packetevents.utils.v_1_7_10.ProtocolVersionAccessor_v_1_7;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerLoginEvent;
@@ -48,6 +49,8 @@ import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public final class PacketEvents implements Listener {
@@ -55,9 +58,15 @@ public final class PacketEvents implements Listener {
private static final PacketEvents instance = new PacketEvents();
private static final ArrayList<Plugin> plugins = new ArrayList<>(1);
private static boolean loaded, initialized;
private static final PEVersion version = new PEVersion(1, 7, 3);
private static final PEVersion version = new PEVersion(1, 7, 6);
private static PacketEventsSettings settings = new PacketEventsSettings();
/**
* General executor service, basically for anything that the packet executor service doesn't do.
*/
public static ExecutorService generalExecutorService = Executors.newSingleThreadExecutor();
//Executor used for player injecting/ejecting and for packet processing/event calling
public static ExecutorService packetHandlingExecutorService = Executors.newSingleThreadExecutor();
/**
* This loads the PacketEvents API.
@@ -98,7 +107,7 @@ public final class PacketEvents implements Listener {
WrappedPacket.loadAllWrappers();
} catch (Exception ex) {
throw new IllegalStateException("PacketEvents failed to successfully load...", ex);
throw new PacketEventsLoadFailureException();
}
loaded = true;
}
@@ -128,6 +137,14 @@ public final class PacketEvents implements Listener {
load();
if (!initialized) {
settings = packetEventsSettings;
int packetHandlingThreadCount = settings.getPacketHandlingThreadCount();
//if the count is 1 or is invalid
if(packetHandlingThreadCount == 1 || packetHandlingThreadCount < 0) {
packetHandlingExecutorService = Executors.newSingleThreadExecutor();
}
else {
packetHandlingExecutorService = Executors.newFixedThreadPool(packetHandlingThreadCount);
}
plugins.add(pl);
//Register Bukkit listener
@@ -139,12 +156,7 @@ public final class PacketEvents implements Listener {
}
if (settings.shouldCheckForUpdates()) {
Future<?> future = NettyPacketManager.executorService.submit(new Runnable() {
@Override
public void run() {
new UpdateChecker().handleUpdate();
}
});
PacketEvents.generalExecutorService.execute(() -> new UpdateChecker().handleUpdate());
}
if (getAPI().getServerUtils().isBungeeCordEnabled()) {
@@ -169,7 +181,8 @@ public final class PacketEvents implements Listener {
PacketEvents.getAPI().packetManager.tinyProtocol.unregisterChannelHandler();
}
getAPI().getEventManager().unregisterAllListeners();
NettyPacketManager.executorService.shutdownNow();
PacketEvents.generalExecutorService.shutdownNow();
PacketEvents.packetHandlingExecutorService.shutdownNow();
initialized = false;
}
}
@@ -203,7 +216,7 @@ public final class PacketEvents implements Listener {
return version;
}
@EventHandler
@EventHandler(priority = EventPriority.LOW)
public void onLogin(PlayerLoginEvent e) {
if (PacketEvents.getSettings().shouldInjectEarly()) {
assert getAPI().packetManager.tinyProtocol != null;
@@ -217,20 +230,14 @@ public final class PacketEvents implements Listener {
}
}
@EventHandler
@EventHandler(priority = EventPriority.LOW)
public void onJoin(final PlayerJoinEvent e) {
if (!VersionLookupUtils.hasHandledLoadedDependencies()) {
VersionLookupUtils.handleLoadedDependencies();
if(PacketEvents.getAPI().getServerUtils().getVersion() == ServerVersion.v_1_7_10) {
Object channel = NMSUtils.getChannel(e.getPlayer());
ClientVersion version = ClientVersion.getClientVersion(ProtocolVersionAccessor_v_1_7.getProtocolVersion(e.getPlayer()));
PacketEvents.getAPI().getPlayerUtils().clientVersionsMap.put(channel, version);
}
Object channel = NMSUtils.getChannel(e.getPlayer());
//Waiting for the BungeeCord server to send their plugin message with your version,
//So we leave bungee alone
if (!PacketEvents.getAPI().getServerUtils().isBungeeCordEnabled()) {
if (VersionLookupUtils.isDependencyAvailable()) {
ClientVersion version = ClientVersion.getClientVersion(VersionLookupUtils.getProtocolVersion(e.getPlayer()));
PacketEvents.getAPI().getPlayerUtils().clientVersionsMap.put(channel, version);
}
}
if (!PacketEvents.getSettings().shouldInjectEarly()) {
if (getAPI().packetManager.canInject(e.getPlayer())) {
PacketEvents.getAPI().packetManager.injectPlayer(e.getPlayer());
@@ -239,7 +246,7 @@ public final class PacketEvents implements Listener {
}
@EventHandler
@EventHandler(priority = EventPriority.HIGHEST)
public void onQuit(final PlayerQuitEvent e) {
PacketEvents.getAPI().getPlayerUtils().clientVersionsMap.remove(e.getPlayer().getUniqueId());
}
@@ -35,7 +35,7 @@ import org.bukkit.plugin.messaging.PluginMessageListener;
import java.util.UUID;
public class BungeePluginMessageListener implements PluginMessageListener {
public static String tagName = "packetevents";
public static String tagName = "packetevents:channel";
@Override
public void onPluginMessageReceived(String tag, Player player, byte[] bytes) {
@@ -25,15 +25,33 @@
package io.github.retrooper.packetevents.enums;
public enum Direction {
DOWN, UP, NORTH, SOUTH, WEST, EAST, NORTH_EAST,
NORTH_WEST, SOUTH_EAST,
SOUTH_WEST, WEST_NORTH_WEST,
NORTH_NORTH_WEST, NORTH_NORTH_EAST,
EAST_NORTH_EAST, EAST_SOUTH_EAST,
SOUTH_SOUTH_EAST, SOUTH_SOUTH_WEST,
WEST_SOUTH_WEST, SELF, NULL;
/**
* -Y offset
*/
DOWN,
public static Direction get(final int i) {
return values()[i];
}
/**
* +Y offset
*/
UP,
/**
* -Z offset
*/
NORTH,
/**
* +Z offset
*/
SOUTH,
/**
* -X offset
*/
WEST,
/**
* +X offset
*/
EAST;
}
@@ -28,5 +28,6 @@ package io.github.retrooper.packetevents.event;
* A Packet listener.
* Implement this interface in your listeners.
*/
@Deprecated
public interface PacketListener {
}
@@ -22,13 +22,44 @@
* SOFTWARE.
*/
package io.github.retrooper.packetevents.utils.protocolsupport;
package io.github.retrooper.packetevents.event;
import org.bukkit.entity.Player;
import protocolsupport.api.ProtocolSupportAPI;
import io.github.retrooper.packetevents.event.impl.*;
class ProtocolSupportAPIAccessor {
public static int getProtocolVersion(final Player player) {
return ProtocolSupportAPI.getProtocolVersion(player).getId();
public abstract class PacketListenerDynamic {
private final byte priority;
public PacketListenerDynamic(final byte priority) {
this.priority = priority;
}
public final byte getPriority() {
return priority;
}
public void onPacketStatus(PacketStatusEvent event) {
}
public void onPacketLogin(PacketLoginEvent event) {
}
public void onPacketReceive(PacketReceiveEvent event) {
}
public void onPacketSend(PacketSendEvent event) {
}
public void onPostPacketReceive(PostPacketReceiveEvent event) {
}
public void onPostPacketSend(PostPacketSendEvent event) {
}
public void onPlayerInject(PlayerInjectEvent event) {
}
public void onPlayerEject(PlayerEjectEvent event) {
}
public void onPacketEvent(PacketEvent event) {
}
}
@@ -26,14 +26,10 @@ package io.github.retrooper.packetevents.event.annotation;
import io.github.retrooper.packetevents.event.priority.PacketEventPriority;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface PacketHandler {
byte priority() default PacketEventPriority.NORMAL;
}
@@ -24,98 +24,57 @@
package io.github.retrooper.packetevents.event.manager;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.event.PacketEvent;
import io.github.retrooper.packetevents.event.PacketListener;
import io.github.retrooper.packetevents.event.annotation.PacketHandler;
import io.github.retrooper.packetevents.event.eventtypes.CancellableEvent;
import io.github.retrooper.packetevents.event.priority.PacketEventPriority;
import io.github.retrooper.packetevents.utils.protocollib.ProtocolLibAPIListener;
import io.github.retrooper.packetevents.utils.protocollib.ProtocolLibUtils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import io.github.retrooper.packetevents.event.PacketListenerDynamic;
public final class EventManager {
private final ConcurrentHashMap<PacketListener, ConcurrentLinkedQueue<Method>> registeredMethods = new ConcurrentHashMap<>();
private final EventManagerLegacy legacyEventManager = new EventManagerLegacy();
private final EventManagerDynamic dynamicEventManager = new EventManagerDynamic();
public void callEvent(final PacketEvent e) {
for (final PacketListener listener : registeredMethods.keySet()) {
ConcurrentLinkedQueue<Method> methods = registeredMethods.get(listener);
final boolean[] isCancelled = {false};
final byte[] eventPriority = {PacketEventPriority.LOWEST};
for (Method method : methods) {
Class<?> parameterType = method.getParameterTypes()[0];
if (parameterType.equals(PacketEvent.class)
|| parameterType.isInstance(e)) {
PacketHandler annotation = method.getAnnotation(PacketHandler.class);
try {
method.invoke(listener, e);
} catch (IllegalAccessException | InvocationTargetException ex) {
ex.printStackTrace();
}
if (e instanceof CancellableEvent) {
CancellableEvent ce = (CancellableEvent) e;
if (annotation.priority() >= eventPriority[0]) {
eventPriority[0] = annotation.priority();
isCancelled[0] = ce.isCancelled();
}
}
if (e instanceof CancellableEvent) {
CancellableEvent cancellableEvent = (CancellableEvent) e;
cancellableEvent.setCancelled(isCancelled[0]);
}
}
}
}
public void callEvent(PacketEvent event) {
dynamicEventManager.callEvent(event);
legacyEventManager.callEvent(event);
}
public void registerListener(final PacketListener listener) {
final ConcurrentLinkedQueue<Method> methods = new ConcurrentLinkedQueue<>();
for (final Method m : listener.getClass().getDeclaredMethods()) {
if (!m.isAccessible()) {
m.setAccessible(true);
}
if (m.isAnnotationPresent(PacketHandler.class)
&& m.getParameterTypes().length == 1) {
methods.add(m);
}
}
if (!methods.isEmpty()) {
if (ProtocolLibUtils.isAvailable()
&& PacketEvents.getSettings().shouldUseProtocolLibIfAvailable()) {
ProtocolLibAPIListener.registerProtocolLibListener(listener, methods);
} else {
registeredMethods.put(listener, methods);
}
}
@Deprecated
public void registerListener(PacketListener listener) {
legacyEventManager.registerListener(listener);
}
public void registerListeners(final PacketListener... listeners) {
for (final PacketListener listener : listeners) {
registerListener(listener);
}
@Deprecated
public void registerListeners(PacketListener... listeners) {
legacyEventManager.registerListeners(listeners);
}
public void unregisterListener(final PacketListener e) {
registeredMethods.remove(e);
@Deprecated
public void unregisterListener(PacketListener listener) {
legacyEventManager.unregisterListener(listener);
}
public void unregisterListeners(final PacketListener... listeners) {
for (final PacketListener listener : listeners) {
unregisterListener(listener);
}
@Deprecated
public void unregisterListeners(PacketListener... listeners) {
legacyEventManager.unregisterListeners(listeners);
}
public void registerListener(PacketListenerDynamic listener) {
dynamicEventManager.registerListener(listener);
}
public void registerListeners(PacketListenerDynamic... listeners) {
dynamicEventManager.registerListeners(listeners);
}
public void unregisterListener(PacketListenerDynamic listener) {
dynamicEventManager.unregisterListener(listener);
}
public void unregisterListeners(PacketListenerDynamic... listeners) {
dynamicEventManager.unregisterListeners(listeners);
}
public void unregisterAllListeners() {
registeredMethods.clear();
}
public boolean isRegistered(final PacketListener listener) {
return registeredMethods.containsKey(listener);
dynamicEventManager.unregisterAllListeners();
legacyEventManager.unregisterAllListeners();
}
}
@@ -0,0 +1,120 @@
/*
* 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.event.manager;
import io.github.retrooper.packetevents.event.PacketEvent;
import io.github.retrooper.packetevents.event.PacketListenerDynamic;
import io.github.retrooper.packetevents.event.eventtypes.CancellableEvent;
import io.github.retrooper.packetevents.event.impl.*;
import io.github.retrooper.packetevents.event.priority.PacketEventPriority;
import io.github.retrooper.packetevents.exceptions.PacketEventsMethodInvokeException;
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
class EventManagerDynamic {
private final Map<Byte, List<PacketListenerDynamic>> map = new HashMap<>();
public void callEvent(PacketEvent event) {
boolean isCancelled = false;
for (byte i = PacketEventPriority.LOWEST; i <= PacketEventPriority.MONITOR; i++) {
if (map.get(i) != null) {
for (PacketListenerDynamic listener : map.get(i)) {
try {
listener.onPacketEvent(event);
if (event instanceof PacketStatusEvent) {
listener.onPacketStatus((PacketStatusEvent) event);
} else if (event instanceof PacketLoginEvent) {
listener.onPacketLogin((PacketLoginEvent) event);
} else if (event instanceof PacketReceiveEvent) {
listener.onPacketReceive((PacketReceiveEvent) event);
} else if (event instanceof PacketSendEvent) {
listener.onPacketSend((PacketSendEvent) event);
} else if (event instanceof PostPacketReceiveEvent) {
listener.onPostPacketReceive((PostPacketReceiveEvent) event);
} else if (event instanceof PostPacketSendEvent) {
listener.onPostPacketSend((PostPacketSendEvent) event);
} else if (event instanceof PlayerInjectEvent) {
listener.onPlayerInject((PlayerInjectEvent) event);
} else if (event instanceof PlayerEjectEvent) {
listener.onPlayerEject((PlayerEjectEvent) event);
}
} catch (Exception ex) {
throw new PacketEventsMethodInvokeException("PacketEvents " +
"failed to call an event method in the " +
"dynamic packet listener. Event type: "
+ ClassUtil.getClassSimpleName(event.getClass()));
}
if (event instanceof CancellableEvent) {
CancellableEvent ce = (CancellableEvent) event;
isCancelled = ce.isCancelled();
}
}
}
}
if (event instanceof CancellableEvent) {
CancellableEvent ce = (CancellableEvent) event;
ce.setCancelled(isCancelled);
}
}
public void registerListener(PacketListenerDynamic listener) {
List<PacketListenerDynamic> listeners = map.get(listener.getPriority());
if (listeners == null) {
map.put(listener.getPriority(), new ArrayList<>());
listeners = map.get(listener.getPriority());
}
listeners.add(listener);
}
public void registerListeners(PacketListenerDynamic... listeners) {
for (PacketListenerDynamic listener : listeners) {
registerListener(listener);
}
}
public void unregisterListener(PacketListenerDynamic listener) {
List<PacketListenerDynamic> listeners = map.get(listener.getPriority());
if (listeners == null) {
return;
}
listeners.remove(listener);
}
public void unregisterListeners(PacketListenerDynamic... listeners) {
for (PacketListenerDynamic listener : listeners) {
unregisterListener(listener);
}
}
public void unregisterAllListeners() {
map.clear();
}
}
@@ -0,0 +1,112 @@
/*
* 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.event.manager;
import io.github.retrooper.packetevents.event.PacketEvent;
import io.github.retrooper.packetevents.event.PacketListener;
import io.github.retrooper.packetevents.event.annotation.PacketHandler;
import io.github.retrooper.packetevents.event.eventtypes.CancellableEvent;
import io.github.retrooper.packetevents.event.priority.PacketEventPriority;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
class EventManagerLegacy {
private final Map<PacketListener, List<Method>> staticRegisteredMethods = new HashMap<>();
public void callEvent(final PacketEvent e) {
boolean isCancelled = false;
byte eventPriority = PacketEventPriority.LOWEST;
//STATIC LISTENERS
for (final PacketListener listener : staticRegisteredMethods.keySet()) {
List<Method> methods = staticRegisteredMethods.get(listener);
for (Method method : methods) {
Class<?> parameterType = method.getParameterTypes()[0];
if (parameterType.equals(PacketEvent.class)
|| parameterType.isInstance(e)) {
PacketHandler annotation = method.getAnnotation(PacketHandler.class);
try {
method.invoke(listener, e);
} catch (IllegalAccessException | InvocationTargetException ex) {
ex.printStackTrace();
}
if (e instanceof CancellableEvent) {
CancellableEvent ce = (CancellableEvent) e;
if (annotation.priority() >= eventPriority) {
eventPriority = annotation.priority();
isCancelled = ce.isCancelled();
}
}
}
}
}
if(e instanceof CancellableEvent) {
CancellableEvent ce = (CancellableEvent)e;
ce.setCancelled(isCancelled);
}
}
public void registerListener(final PacketListener listener) {
final List<Method> methods = new ArrayList<>();
for (final Method m : listener.getClass().getDeclaredMethods()) {
if (!m.isAccessible()) {
m.setAccessible(true);
}
if (m.isAnnotationPresent(PacketHandler.class)
&& m.getParameterTypes().length == 1) {
methods.add(m);
}
}
if (!methods.isEmpty()) {
staticRegisteredMethods.put(listener, methods);
}
}
public void registerListeners(final PacketListener... listeners) {
for (final PacketListener listener : listeners) {
registerListener(listener);
}
}
public void unregisterListener(final PacketListener e) {
staticRegisteredMethods.remove(e);
}
public void unregisterListeners(final PacketListener... listeners) {
for (final PacketListener listener : listeners) {
unregisterListener(listener);
}
}
public void unregisterAllListeners() {
staticRegisteredMethods.clear();
}
}
@@ -25,16 +25,10 @@
package io.github.retrooper.packetevents.example;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.event.PacketListener;
import io.github.retrooper.packetevents.event.annotation.PacketHandler;
import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent;
import io.github.retrooper.packetevents.packettype.PacketType;
import io.github.retrooper.packetevents.packetwrappers.in.chat.WrappedPacketInChat;
import io.github.retrooper.packetevents.utils.player.ClientVersion;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import org.bukkit.plugin.java.JavaPlugin;
public class MainExample extends JavaPlugin implements PacketListener {
public class MainExample extends JavaPlugin {
@Override
public void onLoad() {
@@ -44,9 +38,13 @@ public class MainExample extends JavaPlugin implements PacketListener {
@Override
public void onEnable() {
PacketEvents.getSettings().injectAsync(true).ejectAsync(true)
.backupServerVersion(ServerVersion.v_1_7_10).
useProtocolLibIfAvailable(true).checkForUpdates(true).injectEarly(true);
PacketEvents.getAPI().getEventManager().registerListener(this);
.backupServerVersion(ServerVersion.v_1_7_10).checkForUpdates(true).injectEarly(true).
packetHandlingThreadCount(1);
PacketEvents.init(this);
}
@Override
public void onDisable() {
PacketEvents.stop();
}
}
@@ -22,12 +22,14 @@
* SOFTWARE.
*/
package io.github.retrooper.packetevents.utils.protocollib;
package io.github.retrooper.packetevents.exceptions;
import org.bukkit.Bukkit;
public class PacketEventsLoadFailureException extends RuntimeException {
public PacketEventsLoadFailureException(String message) {
super(message);
}
public class ProtocolLibUtils {
public static boolean isAvailable() {
return Bukkit.getPluginManager().isPluginEnabled("ProtocolLib");
public PacketEventsLoadFailureException() {
this("PacketEvents failed to successfully load...");
}
}
@@ -22,17 +22,20 @@
* SOFTWARE.
*/
package io.github.retrooper.packetevents.utils.protocolsupport;
package io.github.retrooper.packetevents.exceptions;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import io.github.retrooper.packetevents.event.PacketListener;
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
public class ProtocolSupportUtils {
public static boolean isAvailable() {
return Bukkit.getPluginManager().isPluginEnabled("ProtocolSupport");
import java.lang.reflect.Method;
public class PacketEventsMethodAccessException extends RuntimeException {
public PacketEventsMethodAccessException(String message) {
super(message);
}
public static int getProtocolVersion(final Player player) {
return ProtocolSupportAPIAccessor.getProtocolVersion(player);
public PacketEventsMethodAccessException(Method method, PacketListener listener) {
this("PacketEvents failed to access the "
+ method.getName() + " method in " + ClassUtil.getClassSimpleName(listener.getClass()));
}
}
@@ -22,18 +22,20 @@
* SOFTWARE.
*/
package io.github.retrooper.packetevents.utils.viaversion;
package io.github.retrooper.packetevents.exceptions;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import io.github.retrooper.packetevents.event.PacketListener;
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
import java.lang.reflect.Method;
public class ViaUtils {
public static int getProtocolVersion(final Player player) {
return ViaAPIAccessor.getProtocolVersion(player);
public class PacketEventsMethodInvokeException extends RuntimeException {
public PacketEventsMethodInvokeException(String message) {
super(message);
}
public static boolean isAvailable() {
return Bukkit.getPluginManager().isPluginEnabled("ViaVersion");
public PacketEventsMethodInvokeException(Method method, PacketListener listener) {
this("PacketEvents failed to call the " + method.getName() + " method in "
+ ClassUtil.getClassSimpleName(listener.getClass()));
}
}
@@ -22,19 +22,14 @@
* SOFTWARE.
*/
package io.github.retrooper.packetevents.utils.viaversion;
package io.github.retrooper.packetevents.exceptions;
import org.bukkit.entity.Player;
import us.myles.ViaVersion.api.Via;
import java.util.UUID;
class ViaAPIAccessor {
public static int getProtocolVersion(final Player player) {
return getProtocolVersion(player.getUniqueId());
public class PacketEventsNMSCachedEntityNotFoundException extends RuntimeException {
public PacketEventsNMSCachedEntityNotFoundException(String message) {
super(message);
}
public static int getProtocolVersion(final UUID uuid) {
return Via.getAPI().getPlayerVersion(uuid);
public PacketEventsNMSCachedEntityNotFoundException(int entityID) {
this("PacketEvents failed to find an entity with ID " + entityID + " in NMS' entity cache map!");
}
}
@@ -30,27 +30,25 @@ import io.github.retrooper.packetevents.packetmanager.netty.NettyPacketManager;
import io.github.retrooper.packetevents.packetmanager.tinyprotocol.TinyProtocol;
import io.github.retrooper.packetevents.packettype.PacketType;
import io.github.retrooper.packetevents.packetwrappers.login.in.WrappedPacketLoginHandshake;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.player.ClientVersion;
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
import io.github.retrooper.packetevents.utils.versionlookup.VersionLookupUtils;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
public class PacketManager {
private static AtomicInteger handlerID = new AtomicInteger(0);
private int handlerNumber = handlerID.getAndIncrement();
private static final AtomicInteger handlerID = new AtomicInteger();
private final int handlerNumber = handlerID.getAndIncrement();
private final Plugin plugin;
private final boolean tinyProtocolMode;
public final TinyProtocol tinyProtocol;
public final NettyPacketManager nettyProtocol;
private final HashMap<UUID, Long> keepAliveMap = new HashMap<>();
public final ConcurrentLinkedQueue<Object> queuedEjectionChannels = new ConcurrentLinkedQueue<>();
public PacketManager(Plugin plugin, boolean tinyProtocolMode) {
this.plugin = plugin;
@@ -72,10 +70,6 @@ public class PacketManager {
}
}
public void schedulePlayerEjection(Player player) {
queuedEjectionChannels.add(NMSUtils.getChannel(player));
}
public void ejectPlayer(Player player) {
if (PacketEvents.getSettings().shouldEjectAsync()) {
ejectPlayerAsync(player);
@@ -135,28 +129,25 @@ public class PacketManager {
}
public void ejectChannel(Object channel) {
if(!PacketEvents.getSettings().shouldEjectAsync()) {
ejectChannelSync(channel);
}
else {
if (!PacketEvents.getSettings().shouldEjectAsync()) {
ejectChannelSync(channel);
} else {
ejectChannelAsync(channel);
}
}
public void ejectChannelSync(Object channel) {
if(tinyProtocolMode) {
if (tinyProtocolMode) {
tinyProtocol.ejectChannelSync(channel);
}
else {
} else {
nettyProtocol.ejectChannelSync(channel);
}
}
public void ejectChannelAsync(Object channel) {
if(tinyProtocolMode) {
if (tinyProtocolMode) {
tinyProtocol.ejectChannelAsync(channel);
}
else {
} else {
nettyProtocol.ejectChannelAsync(channel);
}
}
@@ -170,11 +161,7 @@ public class PacketManager {
}
public boolean canInject(Player player) {
Object channel = NMSUtils.getChannel(player);
if(channel == null) {
return true;
}
return !queuedEjectionChannels.contains(channel);
return true;
}
public String getNettyHandlerName() {
@@ -182,70 +169,65 @@ public class PacketManager {
}
public Object read(Player player, Object channel, Object packet) {
switch (ClassUtil.getClassSimpleName(packet.getClass())) {
case "PacketHandshakingInSetProtocol":
case "PacketLoginInCustomPayload":
case "PacketLoginInStart":
case "PacketLoginInEncryptionBegin":
final PacketLoginEvent packetLoginEvent = new PacketLoginEvent(channel, packet);
PacketEvents.getAPI().getEventManager().callEvent(packetLoginEvent);
interceptLogin(packetLoginEvent);
if (packetLoginEvent.isCancelled()) {
packet = null;
}
break;
case "PacketStatusInPing":
if (player == null) {
String simpleClassName = ClassUtil.getClassSimpleName(packet.getClass());
//Status packet
if (simpleClassName.startsWith("PacketS")) {
final PacketStatusEvent packetStatusEvent = new PacketStatusEvent(channel, packet);
PacketEvents.getAPI().getEventManager().callEvent(packetStatusEvent);
interceptStatus(packetStatusEvent);
if (packetStatusEvent.isCancelled()) {
packet = null;
}
break;
default:
final PacketReceiveEvent packetReceiveEvent = new PacketReceiveEvent(player, packet);
PacketEvents.getAPI().getEventManager().callEvent(packetReceiveEvent);
interceptRead(packetReceiveEvent);
if (packetReceiveEvent.isCancelled()) {
} else {
//Login packet
final PacketLoginEvent packetLoginEvent = new PacketLoginEvent(channel, packet);
PacketEvents.getAPI().getEventManager().callEvent(packetLoginEvent);
interceptLogin(packetLoginEvent);
if (packetLoginEvent.isCancelled()) {
packet = null;
}
break;
}
} else {
final PacketReceiveEvent packetReceiveEvent = new PacketReceiveEvent(player, packet);
PacketEvents.getAPI().getEventManager().callEvent(packetReceiveEvent);
interceptRead(packetReceiveEvent);
if (packetReceiveEvent.isCancelled()) {
packet = null;
}
}
return packet;
}
public Object write(Player player, Object channel, Object packet) {
switch (ClassUtil.getClassSimpleName(packet.getClass())) {
case "PacketLoginOutDisconnect":
case "PacketLoginOutEncryptionBegin":
case "PacketLoginOutSetCompression":
case "PacketLoginOutSuccess":
final PacketLoginEvent packetLoginEvent = new PacketLoginEvent(channel, packet);
PacketEvents.getAPI().getEventManager().callEvent(packetLoginEvent);
interceptLogin(packetLoginEvent);
if (packetLoginEvent.isCancelled()) {
packet = null;
}
break;
case "PacketStatusOutPong":
case "PacketStatusOutServerInfo":
if (player == null) {
String simpleClassName = ClassUtil.getClassSimpleName(packet.getClass());
//Status packet
if (simpleClassName.startsWith("PacketS")) {
final PacketStatusEvent packetStatusEvent = new PacketStatusEvent(channel, packet);
PacketEvents.getAPI().getEventManager().callEvent(packetStatusEvent);
interceptStatus(packetStatusEvent);
if (packetStatusEvent.isCancelled()) {
packet = null;
}
break;
default:
final PacketSendEvent packetSendEvent = new PacketSendEvent(player, packet);
PacketEvents.getAPI().getEventManager().callEvent(packetSendEvent);
interceptWrite(packetSendEvent);
if (packetSendEvent.isCancelled()) {
}
//Login packet
else {
final PacketLoginEvent packetLoginEvent = new PacketLoginEvent(channel, packet);
PacketEvents.getAPI().getEventManager().callEvent(packetLoginEvent);
interceptLogin(packetLoginEvent);
if (packetLoginEvent.isCancelled()) {
packet = null;
}
break;
}
} else {
final PacketSendEvent packetSendEvent = new PacketSendEvent(player, packet);
PacketEvents.getAPI().getEventManager().callEvent(packetSendEvent);
interceptWrite(packetSendEvent);
if (packetSendEvent.isCancelled()) {
packet = null;
}
}
return packet;
}
@@ -285,7 +267,7 @@ public class PacketManager {
long timestamp = keepAliveMap.getOrDefault(uuid, event.getTimestamp());
long currentTime = event.getTimestamp();
long ping = currentTime - timestamp;
long smoothedPing = ((PacketEvents.getAPI().getPlayerUtils().getSmoothedPing(event.getPlayer()) * 3) + ping) / 4;
long smoothedPing = (PacketEvents.getAPI().getPlayerUtils().getSmoothedPing(event.getPlayer()) * 3 + ping) / 4;
PacketEvents.getAPI().getPlayerUtils().playerPingMap.put(uuid, (short) ping);
PacketEvents.getAPI().getPlayerUtils().playerSmoothedPingMap.put(uuid, (short) smoothedPing);
}
@@ -298,13 +280,12 @@ public class PacketManager {
}
private void interceptLogin(PacketLoginEvent event) {
if (event.getPacketId() == PacketType.Login.HANDSHAKE) {
if (!VersionLookupUtils.isDependencyAvailable()) {
if (event.getPacketId() == PacketType.Login.HANDSHAKE &&
PacketEvents.getAPI().getServerUtils().getVersion() != ServerVersion.v_1_7_10) {
WrappedPacketLoginHandshake handshake = new WrappedPacketLoginHandshake(event.getNMSPacket());
int protocolVersion = handshake.getProtocolVersion();
ClientVersion version = ClientVersion.getClientVersion(protocolVersion);
PacketEvents.getAPI().getPlayerUtils().clientVersionsMap.put(event.getChannel(), version);
}
}
}
@@ -24,6 +24,7 @@
package io.github.retrooper.packetevents.packetmanager.netty;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
@@ -33,9 +34,6 @@ import java.util.concurrent.Executors;
public class NettyPacketManager {
public static final boolean v1_7_nettyMode;
public static final ExecutorService
executorService =
Executors.newFixedThreadPool(Math.max(Runtime.getRuntime().availableProcessors(), 64));
static {
boolean v1_7_nettyMode1;
@@ -48,11 +46,9 @@ public class NettyPacketManager {
v1_7_nettyMode = v1_7_nettyMode1;
}
private Plugin plugin;
private Object npm;
private final Object npm;
public NettyPacketManager(Plugin plugin) {
this.plugin = plugin;
if (v1_7_nettyMode) {
npm = new NettyPacketManager_7();
} else {
@@ -83,7 +79,7 @@ public class NettyPacketManager {
public void injectPlayerAsync(final Player player) {
//Redundant channel variable created just so we can cache it synchronously.
Object channel = NMSUtils.getChannel(player);
executorService.execute(() -> {
PacketEvents.packetHandlingExecutorService.execute(() -> {
if (v1_7_nettyMode) {
NettyPacketManager_7 npm_7 = (NettyPacketManager_7) npm;
npm_7.injectPlayer(player);
@@ -115,7 +111,7 @@ public class NettyPacketManager {
* @param player
*/
public void ejectPlayerAsync(final Player player) {
executorService.execute(() -> {
PacketEvents.packetHandlingExecutorService.execute(() -> {
if (v1_7_nettyMode) {
NettyPacketManager_7 npm_7 = (NettyPacketManager_7) npm;
npm_7.ejectPlayer(player);
@@ -137,7 +133,7 @@ public class NettyPacketManager {
}
public void ejectChannelAsync(Object channel) {
executorService.execute(() -> {
PacketEvents.packetHandlingExecutorService.execute(() -> {
if (v1_7_nettyMode) {
NettyPacketManager_7 npm_7 = (NettyPacketManager_7) npm;
npm_7.ejectChannel(channel);
@@ -68,18 +68,18 @@ final class NettyPacketManager_7 {
}
public void ejectPlayer(Player player) {
Channel channel = (Channel)NMSUtils.getChannel(player);
Channel channel = (Channel) NMSUtils.getChannel(player);
assert channel != null;
ejectChannel(channel);
}
public void ejectChannel(Object ch) {
Channel channel = (Channel)ch;
Channel channel = (Channel) ch;
channel.pipeline().remove(PacketEvents.getAPI().packetManager.getNettyHandlerName());
}
public void sendPacket(Object rawChannel, Object packet) {
Channel channel = (Channel)rawChannel;
Channel channel = (Channel) rawChannel;
channel.pipeline().writeAndFlush(packet);
}
}
@@ -24,7 +24,6 @@
package io.github.retrooper.packetevents.packetmanager.tinyprotocol;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.packetmanager.netty.NettyPacketManager;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
@@ -1,24 +1,6 @@
/*
* This file is part of Hawk Anticheat.
* Copyright (C) 2018 Hawk Development Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package io.github.retrooper.packetevents.packetmanager.tinyprotocol;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.packetmanager.netty.NettyPacketManager;
import io.github.retrooper.packetevents.packetmanager.tinyprotocol.Reflection.FieldAccessor;
import io.github.retrooper.packetevents.packetmanager.tinyprotocol.Reflection.MethodInvoker;
import net.minecraft.util.com.google.common.collect.Lists;
@@ -27,12 +9,12 @@ import net.minecraft.util.com.mojang.authlib.GameProfile;
import net.minecraft.util.io.netty.channel.*;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
@@ -68,20 +50,19 @@ public class TinyProtocol7 {
private static final FieldAccessor<GameProfile> getGameProfile = Reflection.getField(PACKET_LOGIN_IN_START, GameProfile.class, 0);
// Speedup channel/protocol lookup
private Map<String, Channel> channelLookup = new MapMaker().weakValues().makeMap();
private Listener listener;
private final Map<String, Channel> channelLookup = new MapMaker().weakValues().makeMap();
// List of network markers
private List<Object> networkManagers;
// Injected channel handlers
private List<Channel> serverChannels = Lists.newArrayList();
private final List<Channel> serverChannels = Lists.newArrayList();
private ChannelInboundHandlerAdapter serverChannelHandler;
private ChannelInitializer<Channel> beginInitProtocol;
private ChannelInitializer<Channel> endInitProtocol;
// Current handler name
private String handlerName;
private final String handlerName;
protected volatile boolean closed;
protected Plugin plugin;
@@ -371,7 +352,7 @@ public class TinyProtocol7 {
if (interceptor == null) {
interceptor = new PacketInterceptor();
final PacketInterceptor pi = interceptor;
NettyPacketManager.executorService.execute(new Runnable() {
PacketEvents.packetHandlingExecutorService.execute(new Runnable() {
@Override
public void run() {
channel.pipeline().addBefore("packet_handler", handlerName, pi);
@@ -421,11 +402,11 @@ public class TinyProtocol7 {
}
public void ejectChannelSync(Object ch) {
uninjectChannel((Channel)ch);
uninjectChannel((Channel) ch);
}
public void ejectChannelAsync(Object ch) {
uninjectChannelAsync((Channel)ch);
uninjectChannelAsync((Channel) ch);
}
/**
@@ -442,7 +423,7 @@ public class TinyProtocol7 {
public void uninjectChannelAsync(Channel channel) {
// See ChannelInjector in ProtocolLib, line 590
NettyPacketManager.executorService.execute(new Runnable() {
PacketEvents.packetHandlingExecutorService.execute(new Runnable() {
@Override
public void run() {
channel.pipeline().remove(handlerName);
@@ -489,11 +470,7 @@ public class TinyProtocol7 {
final Channel channel = ctx.channel();
handleLoginStart(channel, msg);
try {
msg = onPacketInAsync(player, channel, msg);
} catch (Exception e) {
plugin.getLogger().log(Level.SEVERE, "Error in onPacketInAsync().", e);
}
msg = onPacketInAsync(player, channel, msg);
if (msg != null) {
super.channelRead(ctx, msg);
@@ -503,12 +480,7 @@ public class TinyProtocol7 {
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
try {
msg = onPacketOutAsync(player, ctx.channel(), msg);
} catch (Exception e) {
plugin.getLogger().log(Level.SEVERE, "Error in onPacketOutAsync().", e);
}
msg = onPacketOutAsync(player, ctx.channel(), msg);
if (msg != null) {
super.write(ctx, msg, promise);
PacketEvents.getAPI().packetManager.postWrite(player, msg);
@@ -1,39 +1,21 @@
/*
* This file is part of Hawk Anticheat.
* Copyright (C) 2018 Hawk Development Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package io.github.retrooper.packetevents.packetmanager.tinyprotocol;
import com.google.common.collect.Lists;
import com.google.common.collect.MapMaker;
import com.mojang.authlib.GameProfile;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.packetmanager.netty.NettyPacketManager;
import io.github.retrooper.packetevents.packetmanager.tinyprotocol.Reflection.FieldAccessor;
import io.github.retrooper.packetevents.packetmanager.tinyprotocol.Reflection.MethodInvoker;
import io.netty.channel.*;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
@@ -61,30 +43,36 @@ public class TinyProtocol8 {
private static final Class<Object> serverConnectionClass = Reflection.getUntypedClass("{nms}.ServerConnection");
private static final FieldAccessor<Object> getMinecraftServer = Reflection.getField("{obc}.CraftServer", minecraftServerClass, 0);
private static final FieldAccessor<Object> getServerConnection = Reflection.getField(minecraftServerClass, serverConnectionClass, 0);
private static final MethodInvoker getNetworkMarkers = Reflection.getTypedMethod(serverConnectionClass, null, List.class, serverConnectionClass);
private static final MethodInvoker getNetworkMarkers;
// Packets we have to intercept
private static final Class<?> PACKET_LOGIN_IN_START = Reflection.getMinecraftClass("PacketLoginInStart");
private static final Class<?> PACKET_HANDSHAKING_IN_SET_PROTOCOL = Reflection.getMinecraftClass("PacketHandshakingInSetProtocol");
private static final FieldAccessor<GameProfile> getGameProfile = Reflection.getField(PACKET_LOGIN_IN_START, GameProfile.class, 0);
private static final FieldAccessor<Integer> protocolId = Reflection.getField(PACKET_HANDSHAKING_IN_SET_PROTOCOL, int.class, 0);
private static final FieldAccessor<Enum> protocolType = Reflection.getField(PACKET_HANDSHAKING_IN_SET_PROTOCOL, Enum.class, 0);
static {
MethodInvoker tempNetworkMarkers;
try {
tempNetworkMarkers = Reflection.getTypedMethod(serverConnectionClass, null, List.class, serverConnectionClass);
} catch (Exception ex) {
tempNetworkMarkers = null;
}
getNetworkMarkers = tempNetworkMarkers;
}
// Speedup channel/protocol lookup
private Map<String, Channel> channelLookup = new MapMaker().weakValues().makeMap();
private Listener listener;
private final Map<String, Channel> channelLookup = new MapMaker().weakValues().makeMap();
// List of network markers
private List<Object> networkManagers;
// Injected channel handlers
private List<Channel> serverChannels = Lists.newArrayList();
private final List<Channel> serverChannels = Lists.newArrayList();
private ChannelInboundHandlerAdapter serverChannelHandler;
private ChannelInitializer<Channel> beginInitProtocol;
private ChannelInitializer<Channel> endInitProtocol;
// Current handler name
private String handlerName;
private final String handlerName;
protected volatile boolean closed;
protected Plugin plugin;
@@ -135,7 +123,7 @@ public class TinyProtocol8 {
}
}
} catch (Exception e) {
plugin.getLogger().log(Level.SEVERE, "Cannot inject incomming channel " + channel, e);
plugin.getLogger().log(Level.SEVERE, "Cannot inject incoming channel " + channel, e);
}
}
@@ -176,7 +164,11 @@ public class TinyProtocol8 {
boolean looking = true;
// We need to synchronize against this list
networkManagers = (List<Object>) getNetworkMarkers.invoke(null, serverConnection);
if (getNetworkMarkers != null) {
networkManagers = (List<Object>) getNetworkMarkers.invoke(null, serverConnection);
} else {
networkManagers = new ArrayList<>();
}
createServerChannelHandler();
// Find the correct list, or implicitly throw an exception
@@ -377,7 +369,7 @@ public class TinyProtocol8 {
if (interceptor == null) {
interceptor = new PacketInterceptor();
final PacketInterceptor pi = interceptor;
NettyPacketManager.executorService.execute(new Runnable() {
PacketEvents.packetHandlingExecutorService.execute(new Runnable() {
@Override
public void run() {
channel.pipeline().addBefore("packet_handler", handlerName, pi);
@@ -427,12 +419,13 @@ public class TinyProtocol8 {
}
public void ejectChannelSync(Object ch) {
uninjectChannel((Channel)ch);
uninjectChannel((Channel) ch);
}
public void ejectChannelAsync(Object ch) {
uninjectChannelAsync((Channel)ch);
uninjectChannelAsync((Channel) ch);
}
/**
* Uninject a specific channel.
* <p>
@@ -447,7 +440,7 @@ public class TinyProtocol8 {
public void uninjectChannelAsync(Channel channel) {
// See ChannelInjector in ProtocolLib, line 590
NettyPacketManager.executorService.execute(new Runnable() {
PacketEvents.packetHandlingExecutorService.execute(new Runnable() {
@Override
public void run() {
channel.pipeline().remove(handlerName);
@@ -489,7 +482,6 @@ public class TinyProtocol8 {
}
// Clean up Bukkit
HandlerList.unregisterAll(listener);
unregisterChannelHandler();
}
}
@@ -509,11 +501,7 @@ public class TinyProtocol8 {
final Channel channel = ctx.channel();
handleLoginStart(channel, msg);
try {
msg = onPacketInAsync(player, channel, msg);
} catch (Exception e) {
plugin.getLogger().log(Level.SEVERE, "Error in onPacketInAsync().", e);
}
msg = onPacketInAsync(player, channel, msg);
if (msg != null) {
super.channelRead(ctx, msg);
@@ -523,11 +511,7 @@ public class TinyProtocol8 {
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
try {
msg = onPacketOutAsync(player, ctx.channel(), msg);
} catch (Exception e) {
plugin.getLogger().log(Level.SEVERE, "Error in onPacketOutAsync().", e);
}
msg = onPacketOutAsync(player, ctx.channel(), msg);
if (msg != null) {
super.write(ctx, msg, promise);
@@ -30,19 +30,21 @@ import java.util.Map;
public class PacketType {
public static class Status {
public static final Map<Class<?>, Byte> packetIds = new HashMap<>();
public static final byte PING = 0, PONG = 1, SERVER_INFO = 2;
public static final byte IN_START = 0, PING = 1, PONG = 2, SERVER_INFO = 3;
public static void init() {
packetIds.put(PacketTypeClasses.Status.IN_START, IN_START);
packetIds.put(PacketTypeClasses.Status.PING, PING);
packetIds.put(PacketTypeClasses.Status.PONG, PONG);
packetIds.put(PacketTypeClasses.Status.SERVER_INFO, SERVER_INFO);
}
}
public static class Login {
public static final Map<Class<?>, Byte> packetIds = new HashMap<>();
public static final byte HANDSHAKE = 0,
IN_CUSTOM_PAYLOAD = 1, OUT_CUSTOM_PAYLOAD = 2,IN_START = 3, IN_ENCRYPTION_BEGIN = 4,
DISCONNECT = 5, OUT_ENCRYPTION_BEGIN = 6, OUT_SUCCESS = 7;
IN_CUSTOM_PAYLOAD = 1, OUT_CUSTOM_PAYLOAD = 2, IN_START = 3, IN_ENCRYPTION_BEGIN = 4,
DISCONNECT = 5, OUT_ENCRYPTION_BEGIN = 6, OUT_SUCCESS = 7;
public static void init() {
packetIds.put(PacketTypeClasses.Login.HANDSHAKE, HANDSHAKE);
@@ -29,23 +29,25 @@ import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
public class PacketTypeClasses {
public static class Status {
public static Class<?> PING, PONG, SERVER_INFO;
public static Class<?> IN_START, PING, PONG, SERVER_INFO;
public static void load() {
IN_START = NMSUtils.getNMSClassWithoutException("PacketStatusInStart");
PING = NMSUtils.getNMSClassWithoutException("PacketStatusInPing");
PONG = NMSUtils.getNMSClassWithoutException("PacketStatusOutPong");
SERVER_INFO = NMSUtils.getNMSClassWithoutException("PacketStatusOutServerInfo");
PacketType.Status.init();
}
}
public static class Login {
public static Class<?> HANDSHAKE,
IN_CUSTOM_PAYLOAD, OUT_CUSTOM_PAYLOAD,IN_START, IN_ENCRYPTION_BEGIN,
public static Class<?> HANDSHAKE,
IN_CUSTOM_PAYLOAD, OUT_CUSTOM_PAYLOAD, IN_START, IN_ENCRYPTION_BEGIN,
DISCONNECT, OUT_ENCRYPTION_BEGIN, OUT_SUCCESS;
public static void load() {
HANDSHAKE = NMSUtils.getNMSClassWithoutException("PacketHandshakingInSetProtocol");
//In and Out custom payload login packets have been here since AROUND 1.13.2?
//In and Out custom payload login packets have been here since AROUND 1.13.2.
IN_CUSTOM_PAYLOAD = NMSUtils.getNMSClassWithoutException("PacketLoginInCustomPayload");
OUT_CUSTOM_PAYLOAD = NMSUtils.getNMSClassWithoutException("PacketLoginOutCustomPayload");
IN_START = NMSUtils.getNMSClassWithoutException("PacketLoginInStart");
@@ -138,12 +140,8 @@ public class PacketTypeClasses {
try {
BLOCK_PLACE = NMSUtils.getNMSClass(c + "BlockPlace");
} catch (ClassNotFoundException e) {
}
try {
USE_ITEM = NMSUtils.getNMSClass(c + "UseItem");
} catch (ClassNotFoundException e2) {
} catch (ClassNotFoundException ignored) {
}
@@ -47,6 +47,7 @@ import io.github.retrooper.packetevents.packetwrappers.out.entityvelocity.Wrappe
import io.github.retrooper.packetevents.packetwrappers.out.experience.WrappedPacketOutExperience;
import io.github.retrooper.packetevents.packetwrappers.out.explosion.WrappedPacketOutExplosion;
import io.github.retrooper.packetevents.packetwrappers.out.gamestatechange.WrappedPacketOutGameStateChange;
import io.github.retrooper.packetevents.packetwrappers.out.helditemslot.WrappedPacketOutHeldItemSlot;
import io.github.retrooper.packetevents.packetwrappers.out.keepalive.WrappedPacketOutKeepAlive;
import io.github.retrooper.packetevents.packetwrappers.out.kickdisconnect.WrappedPacketOutKickDisconnect;
import io.github.retrooper.packetevents.packetwrappers.out.position.WrappedPacketOutPosition;
@@ -54,7 +55,6 @@ import io.github.retrooper.packetevents.packetwrappers.out.transaction.WrappedPa
import io.github.retrooper.packetevents.packetwrappers.out.updatehealth.WrappedPacketOutUpdateHealth;
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import org.bukkit.entity.Player;
import java.lang.reflect.Field;
import java.util.ArrayList;
@@ -65,31 +65,18 @@ import java.util.Map;
public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
private static final Map<Class<?>, Map<Class<?>, Field[]>> fieldCache = new HashMap<>();
public static ServerVersion version;
protected final Player player;
protected Object packet;
private Class<?> packetClass;
public WrappedPacket() {
this.player = null;
}
public WrappedPacket(final Object packet) {
this(packet, packet.getClass());
}
public WrappedPacket(final Object packet, final Class<?> packetClass) {
this(null, packet, packetClass);
}
public WrappedPacket(final Player player, final Object packet) {
this(player, packet, packet.getClass());
}
public WrappedPacket(final Player player, final Object packet, Class<?> packetClass) {
if (packet == null) {
this.player = null;
return;
}
public WrappedPacket(final Object packet, Class<?> packetClass) {
if (packet.getClass().getSuperclass().equals(PacketTypeClasses.Client.FLYING)) {
packetClass = PacketTypeClasses.Client.FLYING;
} else if (packet.getClass().getSuperclass().equals(PacketTypeClasses.Server.ENTITY)) {
@@ -100,128 +87,108 @@ public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
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);
}
}
List<Field> boolFields = getFields(boolean.class, declaredFields);
List<Field> byteFields = getFields(byte.class, declaredFields);
List<Field> shortFields = getFields(short.class, declaredFields);
List<Field> intFields = getFields(int.class, declaredFields);
;
List<Field> longFields = getFields(long.class, declaredFields);
;
List<Field> floatFields = getFields(float.class, declaredFields);
;
List<Field> doubleFields = getFields(double.class, declaredFields);
;
List<Field> stringFields = getFields(String.class, declaredFields);
;
List<Field> boolArrayFields = getFields(boolean[].class, declaredFields);
;
List<Field> byteArrayFields = getFields(byte[].class, declaredFields);
;
List<Field> shortArrayFields = getFields(short[].class, declaredFields);
;
List<Field> intArrayFields = getFields(int[].class, declaredFields);
;
List<Field> longArrayFields = getFields(long[].class, declaredFields);
;
List<Field> floatArrayFields = getFields(float[].class, declaredFields);
;
List<Field> doubleArrayFields = getFields(double[].class, declaredFields);
;
List<Field> stringArrayFields = getFields(String[].class, declaredFields);
;
Field[] tmp = new Field[0];
Map<Class<?>, Field[]> map = new HashMap<>();
if (!boolFields.isEmpty()) {
map.put(boolean.class, boolFields.toArray(new Field[0]));
if (boolFields != null) {
map.put(boolean.class, boolFields.toArray(tmp));
}
if (!byteFields.isEmpty()) {
map.put(byte.class, byteFields.toArray(new Field[0]));
if (byteFields != null) {
map.put(byte.class, byteFields.toArray(tmp));
}
if (!shortFields.isEmpty()) {
map.put(short.class, shortFields.toArray(new Field[0]));
if (shortFields != null) {
map.put(short.class, shortFields.toArray(tmp));
}
if (!intFields.isEmpty()) {
map.put(int.class, intFields.toArray(new Field[0]));
if (intFields != null) {
map.put(int.class, intFields.toArray(tmp));
}
if (!longFields.isEmpty()) {
map.put(long.class, longFields.toArray(new Field[0]));
if (longFields != null) {
map.put(long.class, longFields.toArray(tmp));
}
if (!floatFields.isEmpty()) {
map.put(float.class, floatFields.toArray(new Field[0]));
if (floatFields != null) {
map.put(float.class, floatFields.toArray(tmp));
}
if (!doubleFields.isEmpty()) {
map.put(double.class, doubleFields.toArray(new Field[0]));
if (doubleFields != null) {
map.put(double.class, doubleFields.toArray(tmp));
}
if (!stringFields.isEmpty()) {
map.put(String.class, stringFields.toArray(new Field[0]));
if (stringFields != null) {
map.put(String.class, stringFields.toArray(tmp));
}
if (!boolArrayFields.isEmpty()) {
map.put(boolean[].class, boolArrayFields.toArray(new Field[0]));
if (boolArrayFields != null) {
map.put(boolean[].class, boolArrayFields.toArray(tmp));
}
if (!byteArrayFields.isEmpty()) {
map.put(byte[].class, byteArrayFields.toArray(new Field[0]));
if (byteArrayFields != null) {
map.put(byte[].class, byteArrayFields.toArray(tmp));
}
if (!shortArrayFields.isEmpty()) {
map.put(short[].class, shortArrayFields.toArray(new Field[0]));
if (shortArrayFields != null) {
map.put(short[].class, shortArrayFields.toArray(tmp));
}
if (!intArrayFields.isEmpty()) {
map.put(int[].class, intArrayFields.toArray(new Field[0]));
if (intArrayFields != null) {
map.put(int[].class, intArrayFields.toArray(tmp));
}
if (!longArrayFields.isEmpty()) {
map.put(long[].class, longArrayFields.toArray(new Field[0]));
if (longArrayFields != null) {
map.put(long[].class, longArrayFields.toArray(tmp));
}
if (!floatArrayFields.isEmpty()) {
map.put(float[].class, floatArrayFields.toArray(new Field[0]));
if (floatArrayFields != null) {
map.put(float[].class, floatArrayFields.toArray(tmp));
}
if (!doubleArrayFields.isEmpty()) {
map.put(double[].class, doubleArrayFields.toArray(new Field[0]));
if (doubleArrayFields != null) {
map.put(double[].class, doubleArrayFields.toArray(tmp));
}
if (!stringArrayFields.isEmpty()) {
map.put(String[].class, stringArrayFields.toArray(new Field[0]));
if (stringArrayFields != null) {
map.put(String[].class, stringArrayFields.toArray(tmp));
}
fieldCache.put(packetClass, map);
}
this.player = player;
this.packet = packet;
setup();
}
@@ -256,6 +223,7 @@ public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
WrappedPacketOutExplosion.load();
WrappedPacketOutEntityStatus.load();
WrappedPacketOutExperience.load();
WrappedPacketOutHeldItemSlot.load();
}
protected void setup() {
@@ -500,7 +468,7 @@ public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
@Override
public String readString(int index) {
return (String) read(String.class, index);
return (String) read(String.class, index);
}
public Object readAnyObject(int index) {
@@ -523,7 +491,8 @@ public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
public Object readObject(int index, Class<?> type) {
Map<Class<?>, Field[]> cached = fieldCache.get(packetClass);
if (cached != null) {
if (!cached.containsKey(type)) {
Field[] cachedFields = cached.get(type);
if (cachedFields == null) {
List<Field> typeFields = new ArrayList<>();
for (Field f : packetClass.getDeclaredFields()) {
f.setAccessible(true);
@@ -533,20 +502,30 @@ public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
}
if (!typeFields.isEmpty()) {
cached.put(type, typeFields.toArray(new Field[0]));
cachedFields = cached.get(type);
}
else {
throw new WrapperFieldNotFoundException("The class you are trying to read fields from does not contain any fields!");
}
}
}
try {
return cached.get(type)[index].get(packet);
} catch (IllegalAccessException e) {
e.printStackTrace();
try {
return cachedFields[index].get(packet);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
throw new WrapperFieldNotFoundException(packetClass, type, index);
}
public Object[] readObjectArray(int index, Class<?> type) {
return (Object[]) readObject(index, type);
if (type.equals(String.class)) {
return readStringArray(index);
}
try {
return (Object[]) readObject(index, getArrayClass(type));
} catch (ClassNotFoundException e) {
throw new IllegalStateException("PacketEvents failed to find the array class of type " + type.getName());
}
}
@Override
@@ -591,7 +570,7 @@ public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
private void write(Class<?> type, int index, Object value) throws WrapperFieldNotFoundException {
Field field = getField(type, index);
if(field == null) {
if (field == null) {
throw new WrapperFieldNotFoundException(packetClass, type, index);
}
try {
@@ -603,7 +582,7 @@ public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
private Object read(Class<?> type, int index) throws WrapperFieldNotFoundException {
Field field = getField(type, index);
if(field == null) {
if (field == null) {
throw new WrapperFieldNotFoundException(packetClass, type, index);
}
try {
@@ -626,4 +605,42 @@ public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
return null;
}
private List<Field> getFields(Class<?> type, Field[] fields) {
List<Field> ret = new ArrayList<>();
for (Field field : fields) {
if (field.getType() == type) {
ret.add(field);
}
}
return ret;
}
private Class<?> getArrayClass(Class<?> componentType) throws ClassNotFoundException {
ClassLoader classLoader = componentType.getClassLoader();
String name;
if (componentType.isArray()) {
// just add a leading "["
name = "[" + componentType.getName();
} else if (componentType == boolean.class) {
name = "[Z";
} else if (componentType == byte.class) {
name = "[B";
} else if (componentType == char.class) {
name = "[C";
} else if (componentType == double.class) {
name = "[D";
} else if (componentType == float.class) {
name = "[F";
} else if (componentType == int.class) {
name = "[I";
} else if (componentType == long.class) {
name = "[J";
} else if (componentType == short.class) {
name = "[S";
} else {
// must be an object non-array class
name = "[L" + componentType.getName() + ";";
}
return classLoader != null ? classLoader.loadClass(name) : Class.forName(name);
}
}
@@ -26,7 +26,7 @@ package io.github.retrooper.packetevents.packetwrappers;
public interface WrapperPacketWriter {
//TODO write for the arrays
// TODO write for the arrays
void writeBoolean(int index, boolean value);
void writeByte(int index, byte value);
@@ -26,9 +26,7 @@ package io.github.retrooper.packetevents.packetwrappers.in.abilities;
import io.github.retrooper.packetevents.annotations.NotNull;
import io.github.retrooper.packetevents.annotations.Nullable;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
public final class WrappedPacketInAbilities extends WrappedPacket {
@@ -25,17 +25,21 @@
package io.github.retrooper.packetevents.packetwrappers.in.blockdig;
import io.github.retrooper.packetevents.enums.Direction;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import java.lang.reflect.InvocationTargetException;
public final class WrappedPacketInBlockDig extends WrappedPacket {
private static Class<?> blockDigClass, blockPositionClass, enumDirectionClass, digTypeClass;
private static boolean isVersionLowerThan_v_1_8;
private Object blockPosObj, enumDirObj, digTypeObj;
private Object blockPosObj;
private Object enumDirObj;
public WrappedPacketInBlockDig(Object packet) {
super(packet);
}
@@ -74,8 +78,12 @@ public final class WrappedPacketInBlockDig extends WrappedPacket {
if(blockPosObj == null) {
blockPosObj = readObject(0, blockPositionClass);
}
WrappedPacket blockPosWrapper = new WrappedPacket(blockPosObj);
return blockPosWrapper.readInt(0);
try {
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getX", 0).invoke(blockPosObj);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return -1;
}
}
@@ -91,8 +99,12 @@ public final class WrappedPacketInBlockDig extends WrappedPacket {
if(blockPosObj == null) {
blockPosObj = readObject(0, blockPositionClass);
}
WrappedPacket blockPosWrapper = new WrappedPacket(blockPosObj);
return blockPosWrapper.readInt(1);
try {
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getY", 0).invoke(blockPosObj);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return -1;
}
}
@@ -108,19 +120,22 @@ public final class WrappedPacketInBlockDig extends WrappedPacket {
if(blockPosObj == null) {
blockPosObj = readObject(0, blockPositionClass);
}
WrappedPacket blockPosWrapper = new WrappedPacket(blockPosObj);
return blockPosWrapper.readInt(2);
try {
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getZ", 0).invoke(blockPosObj);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return -1;
}
}
/**
* Get the direction
* Is Direction.NULL on 1.7.10 FOR NOW
* Get the direction / Get the face.
* @return Direction
*/
public Direction getDirection() {
if(isVersionLowerThan_v_1_8) {
return Direction.NULL;
return Direction.values()[readInt(3)];
}
else {
if(enumDirObj == null) {
@@ -24,115 +24,75 @@
package io.github.retrooper.packetevents.packetwrappers.in.blockplace;
import io.github.retrooper.packetevents.enums.Direction;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public final class WrappedPacketInBlockPlace extends WrappedPacket {
private static boolean isHigherThan_v_1_8_8, isHigherThan_v_1_7_10;
private WrappedPacket cachedWrappedPacket;
public WrappedPacketInBlockPlace(final Player player, final Object packet) {
super(player, packet);
public WrappedPacketInBlockPlace(final Object packet) {
super(packet);
}
public static void load() {
isHigherThan_v_1_8_8 = version.isHigherThan(ServerVersion.v_1_8_8);
isHigherThan_v_1_7_10 = version.isHigherThan(ServerVersion.v_1_7_10);
if (isHigherThan_v_1_7_10) {
WrappedPacketInBlockPlace_1_8.load();
}
WrappedPacketInBlockPlace_1_9.load();
}
public Player getPlayer() {
return player;
public Direction getDirection() {
if (isHigherThan_v_1_8_8) {
WrappedPacketInBlockPlace_1_9 blockPlace_1_9 = new WrappedPacketInBlockPlace_1_9(packet);
return Direction.valueOf(((Enum) blockPlace_1_9.getEnumDirectionObject()).name());
} else if (isHigherThan_v_1_7_10) {
WrappedPacketInBlockPlace_1_8 blockPlace_1_8 = new WrappedPacketInBlockPlace_1_8(packet);
return Direction.values()[blockPlace_1_8.getFace()];
} else {
WrappedPacketInBlockPlace_1_7_10 blockPlace_1_7_10 = new WrappedPacketInBlockPlace_1_7_10(packet);
return Direction.values()[blockPlace_1_7_10.face];
}
}
public int getX() {
if (isHigherThan_v_1_8_8) {
if (cachedWrappedPacket == null) {
WrappedPacketInBlockPlace_1_9 blockPlace_1_9 = new WrappedPacketInBlockPlace_1_9(getPlayer(), packet);
cachedWrappedPacket = blockPlace_1_9;
return blockPlace_1_9.getBlock().getX();
}
return ((WrappedPacketInBlockPlace_1_9)cachedWrappedPacket).getBlock().getX();
WrappedPacketInBlockPlace_1_9 blockPlace_1_9 = new WrappedPacketInBlockPlace_1_9(packet);
return blockPlace_1_9.getX();
} else if (isHigherThan_v_1_7_10) {
if(cachedWrappedPacket == null) {
WrappedPacketInBlockPlace_1_8 blockPlace_1_8 = new WrappedPacketInBlockPlace_1_8(packet);
cachedWrappedPacket = blockPlace_1_8;
return blockPlace_1_8.getX();
}
WrappedPacketInBlockPlace_1_8 blockPlace_1_8 = new WrappedPacketInBlockPlace_1_8(packet);
return blockPlace_1_8.getX();
} else {
WrappedPacketInBlockPlace_1_7_10 blockPlace_1_7_10 = new WrappedPacketInBlockPlace_1_7_10(packet);
return blockPlace_1_7_10.x;
}
return 0;
}
public int getY() {
if (isHigherThan_v_1_8_8) {
if (cachedWrappedPacket == null) {
WrappedPacketInBlockPlace_1_9 blockPlace_1_9 = new WrappedPacketInBlockPlace_1_9(getPlayer(), packet);
cachedWrappedPacket = blockPlace_1_9;
return blockPlace_1_9.getBlock().getY();
}
return ((WrappedPacketInBlockPlace_1_9)cachedWrappedPacket).getBlock().getX();
WrappedPacketInBlockPlace_1_9 blockPlace_1_9 = new WrappedPacketInBlockPlace_1_9(packet);
return blockPlace_1_9.getY();
} else if (isHigherThan_v_1_7_10) {
if(cachedWrappedPacket == null) {
WrappedPacketInBlockPlace_1_8 blockPlace_1_8 = new WrappedPacketInBlockPlace_1_8(packet);
cachedWrappedPacket = blockPlace_1_8;
return blockPlace_1_8.getY();
}
WrappedPacketInBlockPlace_1_8 blockPlace_1_8 = new WrappedPacketInBlockPlace_1_8(packet);
return blockPlace_1_8.getY();
} else {
WrappedPacketInBlockPlace_1_7_10 blockPlace_1_7_10 = new WrappedPacketInBlockPlace_1_7_10(packet);
return blockPlace_1_7_10.y;
}
return 0;
}
public int getZ() {
if (isHigherThan_v_1_8_8) {
if (cachedWrappedPacket == null) {
WrappedPacketInBlockPlace_1_9 blockPlace_1_9 = new WrappedPacketInBlockPlace_1_9(getPlayer(), packet);
cachedWrappedPacket = blockPlace_1_9;
return blockPlace_1_9.getBlock().getZ();
}
return ((WrappedPacketInBlockPlace_1_9)cachedWrappedPacket).getBlock().getX();
WrappedPacketInBlockPlace_1_9 blockPlace_1_9 = new WrappedPacketInBlockPlace_1_9(packet);
return blockPlace_1_9.getZ();
} else if (isHigherThan_v_1_7_10) {
if(cachedWrappedPacket == null) {
WrappedPacketInBlockPlace_1_8 blockPlace_1_8 = new WrappedPacketInBlockPlace_1_8(packet);
cachedWrappedPacket = blockPlace_1_8;
return blockPlace_1_8.getZ();
}
WrappedPacketInBlockPlace_1_8 blockPlace_1_8 = new WrappedPacketInBlockPlace_1_8(packet);
return blockPlace_1_8.getZ();
} else {
WrappedPacketInBlockPlace_1_7_10 blockPlace_1_7_10 = new WrappedPacketInBlockPlace_1_7_10(packet);
return blockPlace_1_7_10.z;
}
return 0;
}
public ItemStack getItemStack() {
if (isHigherThan_v_1_8_8) {
if (cachedWrappedPacket == null) {
WrappedPacketInBlockPlace_1_9 blockPlace_1_9 = new WrappedPacketInBlockPlace_1_9(getPlayer(), packet);
cachedWrappedPacket = blockPlace_1_9;
return new ItemStack(blockPlace_1_9.getBlock().getType());
}
return new ItemStack(((WrappedPacketInBlockPlace_1_9)cachedWrappedPacket).getBlock().getType());
} else if (isHigherThan_v_1_7_10) {
if(cachedWrappedPacket == null) {
WrappedPacketInBlockPlace_1_8 blockPlace_1_8 = new WrappedPacketInBlockPlace_1_8(packet);
cachedWrappedPacket = blockPlace_1_8;
return blockPlace_1_8.getItemStack();
}
} else {
WrappedPacketInBlockPlace_1_7_10 blockPlace_1_7_10 = new WrappedPacketInBlockPlace_1_7_10(packet);
return blockPlace_1_7_10.itemStack;
}
return null;
}
}
@@ -25,14 +25,12 @@
package io.github.retrooper.packetevents.packetwrappers.in.blockplace;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import net.minecraft.server.v1_7_R4.PacketPlayInBlockPlace;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
final class WrappedPacketInBlockPlace_1_7_10 extends WrappedPacket {
public int x, y, z;
public ItemStack itemStack;
public int blockFace;
public int face;
WrappedPacketInBlockPlace_1_7_10(final Object packet) {
super(packet);
@@ -41,13 +39,14 @@ final class WrappedPacketInBlockPlace_1_7_10 extends WrappedPacket {
@Override
protected void setup() {
final PacketPlayInBlockPlace blockPlace = (PacketPlayInBlockPlace) packet;
final net.minecraft.server.v1_7_R4.PacketPlayInBlockPlace blockPlace =
(net.minecraft.server.v1_7_R4.PacketPlayInBlockPlace) packet;
x = blockPlace.c();
y = blockPlace.d();
z = blockPlace.e();
this.blockFace = blockPlace.d();
this.face = blockPlace.d();
net.minecraft.server.v1_7_R4.ItemStack stack = blockPlace.getItemStack();
this.itemStack = org.bukkit.craftbukkit.v1_7_R4.inventory.CraftItemStack.asBukkitCopy(stack);
@@ -24,8 +24,6 @@
package io.github.retrooper.packetevents.packetwrappers.in.blockplace;
import io.github.retrooper.packetevents.exceptions.WrapperFieldNotFoundException;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
@@ -34,41 +32,31 @@ import org.bukkit.inventory.ItemStack;
import java.lang.reflect.InvocationTargetException;
final class WrappedPacketInBlockPlace_1_8 extends WrappedPacket {
private static Class<?> blockPlaceClass, blockPositionClass, blockPositionSuperClass;
private Object blockPosObj;
WrappedPacketInBlockPlace_1_8(final Object packet) {
super(packet);
}
protected static void load() {
blockPlaceClass = PacketTypeClasses.Client.BLOCK_PLACE;
try {
blockPositionClass = NMSUtils.getNMSClass("BlockPosition");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
blockPositionSuperClass = blockPositionClass.getSuperclass();
}
public int getX() {
if(blockPosObj == null) {
blockPosObj = new WrappedPacket(packet).readObject(0, blockPositionClass);
blockPosObj = readObject(1, NMSUtils.blockPosClass);
}
try {
return (int)Reflection.getMethod(blockPositionSuperClass, "getX", 0).invoke(blockPosObj);
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getX", 0).invoke(blockPosObj);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return 0;
}
public int getY() {
if(blockPosObj == null) {
blockPosObj = new WrappedPacket(packet).readObject(0, blockPositionClass);
blockPosObj = readObject(1, NMSUtils.blockPosClass);
}
try {
return (int)Reflection.getMethod(blockPositionSuperClass, "getY", 0).invoke(blockPosObj);
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getY", 0).invoke(blockPosObj);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
@@ -77,10 +65,10 @@ final class WrappedPacketInBlockPlace_1_8 extends WrappedPacket {
public int getZ() {
if(blockPosObj == null) {
blockPosObj = new WrappedPacket(packet).readObject(0, blockPositionClass);
blockPosObj = readObject(1, NMSUtils.blockPosClass);
}
try {
return (int)Reflection.getMethod(blockPositionSuperClass, "getZ", 0).invoke(blockPosObj);
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getZ", 0).invoke(blockPosObj);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
@@ -90,4 +78,8 @@ final class WrappedPacketInBlockPlace_1_8 extends WrappedPacket {
public ItemStack getItemStack() {
return NMSUtils.toBukkitItemStack(readObject(0, NMSUtils.nmsItemStackClass));
}
public int getFace() {
return readInt(0);
}
}
@@ -26,20 +26,84 @@ package io.github.retrooper.packetevents.packetwrappers.in.blockplace;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.utils.BlockIteratorUtils;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
import java.lang.reflect.InvocationTargetException;
final class WrappedPacketInBlockPlace_1_9 extends WrappedPacket {
public WrappedPacketInBlockPlace_1_9(final Player player, final Object packet) {
super(player, packet);
private Object blockPosObj;
private static Class<?> movingObjectPositionBlockClass;
public static void load() {
movingObjectPositionBlockClass = NMSUtils.getNMSClassWithoutException("MovingObjectPositionBlock");
}
public Player getPlayer() {
return this.player;
public WrappedPacketInBlockPlace_1_9(final Object packet) {
super(packet);
}
public Block getBlock() {
return BlockIteratorUtils.getBlockLookingAt(getPlayer(),3);
public int getX() {
if (blockPosObj == null) {
if (movingObjectPositionBlockClass == null) {
blockPosObj = readObject(0, NMSUtils.blockPosClass);
} else {
Object movingObjectPos = readObject(0, movingObjectPositionBlockClass);
WrappedPacket movingObjectPosWrapper = new WrappedPacket(movingObjectPos);
blockPosObj = movingObjectPosWrapper.readObject(0, NMSUtils.blockPosClass);
}
}
try {
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getX", 0).invoke(blockPosObj);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return 0;
}
public int getY() {
if (blockPosObj == null) {
if (movingObjectPositionBlockClass == null) {
blockPosObj = readObject(0, NMSUtils.blockPosClass);
} else {
Object movingObjectPos = readObject(0, movingObjectPositionBlockClass);
WrappedPacket movingObjectPosWrapper = new WrappedPacket(movingObjectPos);
blockPosObj = movingObjectPosWrapper.readObject(0, NMSUtils.blockPosClass);
}
}
try {
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getY", 0).invoke(blockPosObj);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return 0;
}
public int getZ() {
if (blockPosObj == null) {
if (movingObjectPositionBlockClass == null) {
blockPosObj = readObject(0, NMSUtils.blockPosClass);
} else {
Object movingObjectPos = readObject(0, movingObjectPositionBlockClass);
WrappedPacket movingObjectPosWrapper = new WrappedPacket(movingObjectPos);
blockPosObj = movingObjectPosWrapper.readObject(0, NMSUtils.blockPosClass);
}
}
try {
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getZ", 0).invoke(blockPosObj);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return 0;
}
public Object getEnumDirectionObject() {
if (movingObjectPositionBlockClass == null) {
return readObject(0, NMSUtils.enumDirectionClass);
} else {
Object movingObjectPos = readObject(0, movingObjectPositionBlockClass);
WrappedPacket movingObjectPosWrapper = new WrappedPacket(movingObjectPos);
return movingObjectPosWrapper.readObject(0, NMSUtils.enumDirectionClass);
}
}
}
@@ -46,7 +46,7 @@ public final class WrappedPacketInCustomPayload extends WrappedPacket {
packetDataSerializerClass = NMSUtils.getNMSClassWithoutException("PacketDataSerializer");
try {
byteBufClass = NMSUtils.getNettyClass("buffer.ByteBuf");
} catch (ClassNotFoundException e) {
} catch (ClassNotFoundException ignored) {
}
try {
@@ -34,14 +34,13 @@ import org.bukkit.entity.Entity;
import java.util.HashMap;
public final class WrappedPacketInEntityAction extends WrappedPacket {
private static final HashMap<String, PlayerAction> cachedPlayerActionNames = new HashMap<String, PlayerAction>();
private static final HashMap<Integer, PlayerAction> cachedPlayerActionIDs = new HashMap<Integer, PlayerAction>();
private static final HashMap<String, PlayerAction> cachedPlayerActionNames = new HashMap<>();
private static final HashMap<Integer, PlayerAction> cachedPlayerActionIDs = new HashMap<>();
@Nullable
private static Class<?> enumPlayerActionClass;
private static boolean isLowerThan_v_1_8;
private Entity entity;
private int entityId = -1;
private PlayerAction action;
public WrappedPacketInEntityAction(final Object packet) {
super(packet);
@@ -91,10 +90,10 @@ public final class WrappedPacketInEntityAction extends WrappedPacket {
* @return Entity ID
*/
public int getEntityId() {
if(entityId != -1) {
return entityId;
if(entityId == -1) {
entityId = readInt(0);
}
return readInt(0);
return entityId;
}
/**
@@ -24,7 +24,6 @@
package io.github.retrooper.packetevents.packetwrappers.in.helditemslot;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
public final class WrappedPacketInHeldItemSlot extends WrappedPacket {
@@ -29,16 +29,14 @@ import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
public final class WrappedPacketInKeepAlive extends WrappedPacket {
private static Class<?> packetClass;
private static boolean integerPresentInIndex0;
private long id;
public WrappedPacketInKeepAlive(final Object packet) {
super(packet);
}
public static void load() {
packetClass = PacketTypeClasses.Client.KEEP_ALIVE;
Class<?> packetClass = PacketTypeClasses.Client.KEEP_ALIVE;
integerPresentInIndex0 = Reflection.getField(packetClass, int.class, 0) != null;
}
@@ -25,7 +25,6 @@
package io.github.retrooper.packetevents.packetwrappers.in.settings;
import io.github.retrooper.packetevents.annotations.Nullable;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
@@ -45,7 +44,6 @@ public class WrappedPacketInSettings extends WrappedPacket {
}
public static void load() {
Class<?> packetClass = PacketTypeClasses.Client.SETTINGS;
isLowerThan_v_1_8 = version.isLowerThan(ServerVersion.v_1_8);
@@ -30,6 +30,8 @@ import io.github.retrooper.packetevents.packetwrappers.out.chat.WrappedPacketOut
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
import java.lang.reflect.InvocationTargetException;
public class WrappedPacketInUpdateSign extends WrappedPacket {
private static boolean v_1_7_mode, strArrayMode;
private static Class<?> blockPosClass, iChatBaseComponentClass;
@@ -59,45 +61,54 @@ public class WrappedPacketInUpdateSign extends WrappedPacket {
}
public int getX() {
if(v_1_7_mode) {
if (v_1_7_mode) {
return readInt(0);
}
else {
if(blockPosObj == null) {
} else {
if (blockPosObj == null) {
blockPosObj = readObject(0, blockPosClass);
WrappedPacket blockPosWrapper = new WrappedPacket(blockPosObj);
return blockPosWrapper.readInt(0);
}
try {
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getX", 0).invoke(blockPosObj);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return -1;
}
return 0;
}
public int getY() {
if(v_1_7_mode) {
if (v_1_7_mode) {
return readInt(1);
}
else {
if(blockPosObj == null) {
} else {
if (blockPosObj == null) {
blockPosObj = readObject(0, blockPosClass);
WrappedPacket blockPosWrapper = new WrappedPacket(blockPosObj);
return blockPosWrapper.readInt(1);
}
try {
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getY", 0).invoke(blockPosObj);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return -1;
}
return 0;
}
public int getZ() {
if(v_1_7_mode) {
if (v_1_7_mode) {
return readInt(2);
}
else {
if(blockPosObj == null) {
} else {
if (blockPosObj == null) {
blockPosObj = readObject(0, blockPosClass);
WrappedPacket blockPosWrapper = new WrappedPacket(blockPosObj);
return blockPosWrapper.readInt(2);
}
try {
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getZ", 0).invoke(blockPosObj);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return -1;
}
return 0;
}
public String[] getTextLines() {
@@ -106,7 +117,7 @@ public class WrappedPacketInUpdateSign extends WrappedPacket {
return readStringArray(0);
} else {
//1.8 uses this for example
Object[] iChatComponents = readObjectArray(0, iChatBaseComponentClass);
Object[] iChatComponents = (Object[]) readAnyObject(1);
String[] lines = new String[iChatComponents.length];
for (int i = 0; i < iChatComponents.length; i++) {
lines[i] = WrappedPacketOutChat.
@@ -35,10 +35,11 @@ import java.util.Arrays;
import java.util.HashMap;
public class WrappedPacketInWindowClick extends WrappedPacket {
private static final HashMap<String, Integer> invClickTypeMapCache = new HashMap<String, Integer>();
private static final HashMap<Integer, ArrayList<WindowClickType>> windowClickTypeCache = new HashMap<Integer, ArrayList<WindowClickType>>();
private static Class<?> packetClass, invClickTypeClass;
private static boolean isClickModePrimitive = false;
private static final HashMap<String, Integer> invClickTypeMapCache = new HashMap<>();
private static final HashMap<Integer, ArrayList<WindowClickType>> windowClickTypeCache = new HashMap<>();
private static Class<?> invClickTypeClass;
private static boolean isClickModePrimitive;
// TODO: All the fields below are useless cuz there is never a value assigned to them - change this
private int id;
private int slot;
private int button;
@@ -51,7 +52,7 @@ public class WrappedPacketInWindowClick extends WrappedPacket {
}
public static void load() {
packetClass = PacketTypeClasses.Client.WINDOW_CLICK;
Class<?> packetClass = PacketTypeClasses.Client.WINDOW_CLICK;
invClickTypeClass = NMSUtils.getNMSClassWithoutException("InventoryClickType");
invClickTypeMapCache.put("PICKUP", 0);
@@ -156,6 +157,7 @@ public class WrappedPacketInWindowClick extends WrappedPacket {
return WindowClickType.UNKNOWN;
}
// TODO: This has no use cuz the fields used are never getting assigned a value to them
if (mode == 4) {
if (slot == -999) {
if (button == 0) {
@@ -25,7 +25,6 @@
package io.github.retrooper.packetevents.packetwrappers.out.abilities;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import java.lang.reflect.Constructor;
@@ -32,9 +32,8 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public final class WrappedPacketOutAbilities extends WrappedPacket implements SendableWrapper {
private static Class<?> packetClass;
private static Constructor<?> packetConstructor;
private boolean isListening = false;
private boolean isListening;
private boolean vulnerable, flying, allowFlight, instantBuild;
private float flySpeed, walkSpeed;
@@ -55,7 +54,7 @@ public final class WrappedPacketOutAbilities extends WrappedPacket implements Se
}
public static void load() {
packetClass = PacketTypeClasses.Server.ABILITIES;
Class<?> packetClass = PacketTypeClasses.Server.ABILITIES;
try {
packetConstructor = packetClass.getConstructor(PlayerAbilitiesUtils.playerAbilitiesClass);
@@ -33,13 +33,14 @@ import org.bukkit.entity.Entity;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
public final class WrappedPacketOutAnimation extends WrappedPacket implements SendableWrapper {
private static Class<?> animationClass, nmsEntityClass;
private static Class<?> nmsEntityClass;
private static Constructor<?> animationConstructor;
private static final HashMap<Integer, EntityAnimationType> cachedAnimationIDS = new HashMap<Integer, EntityAnimationType>();
private static final HashMap<EntityAnimationType, Integer> cachedAnimations = new HashMap<EntityAnimationType, Integer>();
private static final Map<Integer, EntityAnimationType> cachedAnimationIDS = new HashMap<>();
private static final Map<EntityAnimationType, Integer> cachedAnimations = new HashMap<>();
private Entity entity;
private int entityID = -1;
private EntityAnimationType type;
@@ -58,7 +59,7 @@ public final class WrappedPacketOutAnimation extends WrappedPacket implements Se
}
public static void load() {
animationClass = PacketTypeClasses.Server.ANIMATION;
Class<?> animationClass = PacketTypeClasses.Server.ANIMATION;
try {
nmsEntityClass = NMSUtils.getNMSClass("Entity");
} catch (ClassNotFoundException e) {
@@ -0,0 +1,53 @@
/*
* 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.blockchange;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
class WrappedPacketOutBlockChange extends WrappedPacket {
public WrappedPacketOutBlockChange(Object packet) {
super(packet);
}
//to-do load
@Override
protected void setup() {
//1.7 - int, int, int, Block, int data
//1.8+ - BlockPosition, IBlockData
//Constructors
//1.7 - int, int, int, World
//1.8->~1.12.2(World, BlockPosition)
//~1.13->~1.14(IBlockAccess, BlockPosition)
//1.16+(BlockPosition, IBlockData)
net.minecraft.server.v1_7_R4.PacketPlayOutBlockChange bc;
net.minecraft.server.v1_8_R3.PacketPlayOutBlockChange bc1;
net.minecraft.server.v1_9_R1.PacketPlayOutBlockChange bc2;
net.minecraft.server.v1_12_R1.PacketPlayOutBlockChange bc3;
net.minecraft.server.v1_13_R2.PacketPlayOutBlockChange bc4;
net.minecraft.server.v1_16_R2.PacketPlayOutBlockChange bc5;
}
}
@@ -25,12 +25,11 @@
package io.github.retrooper.packetevents.packetwrappers.out.chat;
import io.github.retrooper.packetevents.annotations.Beta;
import io.github.retrooper.packetevents.annotations.NotNull;
import io.github.retrooper.packetevents.packettype.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.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
import java.lang.reflect.Constructor;
@@ -56,9 +55,9 @@ public final class WrappedPacketOutChat extends WrappedPacket implements Sendabl
//0 = Byte
//1 = Byte, Boolean
private static byte chatTypeMessageEnumConstructorMode;
private static final HashMap<ChatPosition, Byte> cachedChatPositions = new HashMap<ChatPosition, Byte>();
private static final HashMap<Byte, ChatPosition> cachedChatPositionIntegers = new HashMap<Byte, ChatPosition>();
private static final HashMap<String, Byte> cachedChatMessageTypeIntegers = new HashMap<String, Byte>();
private static final HashMap<ChatPosition, Byte> cachedChatPositions = new HashMap<>();
private static final HashMap<Byte, ChatPosition> cachedChatPositionIntegers = new HashMap<>();
private static final HashMap<String, Byte> cachedChatMessageTypeIntegers = new HashMap<>();
private String message;
private ChatPosition chatPosition;
private UUID uuid;
@@ -36,7 +36,6 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
public class WrappedPacketOutCustomPayload extends WrappedPacket implements SendableWrapper {
private static Class<?> packetClass;
private static Constructor<?> constructor;
private static Constructor<?> packetDataSerializerConstructor;
private static Constructor<?> minecraftKeyConstructor;
@@ -49,13 +48,13 @@ public class WrappedPacketOutCustomPayload extends WrappedPacket implements Send
private boolean isListening = false;
public static void load() {
packetClass = PacketTypeClasses.Server.CUSTOM_PAYLOAD;
Class<?> packetClass = PacketTypeClasses.Server.CUSTOM_PAYLOAD;
packetDataSerializerClass = NMSUtils.getNMSClassWithoutException("PacketDataSerializer");
minecraftKeyClass = NMSUtils.getNMSClassWithoutException("MinecraftKey");
try {
byteBufClass = NMSUtils.getNettyClass("buffer.ByteBuf");
} catch (ClassNotFoundException e) {
} catch (ClassNotFoundException ignored) {
}
try {
@@ -36,14 +36,13 @@ import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class WrappedPacketOutEntity extends WrappedPacket implements SendableWrapper {
private static Class<?> packetClass;
//Byte = 1.7.10->1.8.8, Int = 1.9->1.15.x, Short = 1.16.x
private static byte mode = 0; //byte = 0, int = 1, short = 2
private static double dXYZDivisor = 0.0;
private static int yawByteIndex = 0;
private static byte mode; //byte = 0, int = 1, short = 2
private static double dXYZDivisor;
private static int yawByteIndex;
private static int pitchByteIndex = 1;
private Entity entity;
private boolean isListening = false;
private boolean isListening;
private static Constructor<?> entityPacketConstructor;
private int entityID;
private double deltaX, deltaY, deltaZ;
@@ -75,7 +74,7 @@ public class WrappedPacketOutEntity extends WrappedPacket implements SendableWra
}
public static void load() {
packetClass = PacketTypeClasses.Server.ENTITY;
Class<?> packetClass = PacketTypeClasses.Server.ENTITY;
Field dxField = Reflection.getField(packetClass, 1);
assert dxField != null;
@@ -27,8 +27,7 @@ package io.github.retrooper.packetevents.packetwrappers.out.entitymetadata;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
public class WrappedPacketOutEntityMetadata extends WrappedPacket {
private boolean isListening = false;
private int entityID;
private boolean isListening;
public WrappedPacketOutEntityMetadata(Object packet) {
super(packet);
isListening = true;
@@ -38,7 +37,7 @@ public class WrappedPacketOutEntityMetadata extends WrappedPacket {
if (isListening) {
return readInt(0);
} else {
return entityID;
return 0;
}
}
}
@@ -35,8 +35,8 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class WrappedPacketOutEntityTeleport extends WrappedPacket implements SendableWrapper {
private static boolean legacyVersionMode = false;
private static boolean ultraLegacyVersionMode = false;
private static boolean legacyVersionMode;
private static boolean ultraLegacyVersionMode;
private boolean listeningMode = false;
private static final float rotationMultiplier = 256.0F / 360.0F;
private static Constructor<?> constructor;
@@ -36,12 +36,12 @@ import java.lang.reflect.InvocationTargetException;
public final class WrappedPacketOutEntityVelocity extends WrappedPacket implements SendableWrapper {
private static Constructor<?> velocityConstructor, vec3dConstructor;
private static Class<?> velocityClass, vec3dClass;
private static Class<?> vec3dClass;
private static boolean isVec3dPresent;
private int entityID = -1;
private double velocityX, velocityY, velocityZ;
private Entity entity;
private boolean isListening = false;
private boolean isListening;
public WrappedPacketOutEntityVelocity(final Object packet) {
super(packet);
@@ -69,7 +69,7 @@ public final class WrappedPacketOutEntityVelocity extends WrappedPacket implemen
* 1.14+ use int, Vec3D style
*/
public static void load() {
velocityClass = PacketTypeClasses.Server.ENTITY_VELOCITY;
Class<?> velocityClass = PacketTypeClasses.Server.ENTITY_VELOCITY;
if (version.isHigherThan(ServerVersion.v_1_13_2)) {
try {
vec3dClass = NMSUtils.getNMSClass("Vec3D");
@@ -36,14 +36,13 @@ import java.util.ArrayList;
import java.util.List;
public class WrappedPacketOutExplosion extends WrappedPacket implements SendableWrapper {
private static Class<?> chunkPosClass, blockPosClass, vec3DClass;
private static Constructor<?> chunkPosConstructor, blockPosConstructor, packetConstructor, vec3dConstructor;
public static void load() {
chunkPosClass = NMSUtils.getNMSClassWithoutException("ChunkPosition");
blockPosClass = NMSUtils.getNMSClassWithoutException("BlockPosition");
Class<?> chunkPosClass = NMSUtils.getNMSClassWithoutException("ChunkPosition");
Class<?> blockPosClass = NMSUtils.getNMSClassWithoutException("BlockPosition");
Class<?> packetClass = NMSUtils.getNMSClassWithoutException("PacketPlayOutExplosion");
vec3DClass = NMSUtils.getNMSClassWithoutException("Vec3D");
Class<?> vec3DClass = NMSUtils.getNMSClassWithoutException("Vec3D");
try {
packetConstructor = packetClass.getConstructor(double.class, double.class, double.class, float.class, List.class, vec3DClass);
vec3dConstructor = vec3DClass.getDeclaredConstructor(double.class, double.class, double.class);
@@ -0,0 +1,71 @@
/*
* 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.helditemslot;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class WrappedPacketOutHeldItemSlot extends WrappedPacket implements SendableWrapper {
private static Constructor<?> packetConstructor;
public static void load() {
try {
packetConstructor = PacketTypeClasses.Server.HELD_ITEM_SLOT.getConstructor(int.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
private int slot;
public WrappedPacketOutHeldItemSlot(Object packet) {
super(packet);
}
public WrappedPacketOutHeldItemSlot(int slot) {
this.slot = slot;
}
public int getCurrentSelectedSlot() {
if(packet == null){
return slot;
}
return readInt(0);
}
@Override
public Object asNMSPacket() {
try {
return packetConstructor.newInstance(slot);
} catch (InstantiationException |
IllegalAccessException |
InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
@@ -33,11 +33,10 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class WrappedPacketOutKeepAlive extends WrappedPacket implements SendableWrapper {
private static Class<?> packetClass;
private static Constructor<?> keepAliveConstructor;
private static boolean integerMode;
private long id;
private boolean isListening = false;
private boolean isListening;
public WrappedPacketOutKeepAlive(Object packet) {
super(packet);
@@ -45,11 +44,11 @@ public class WrappedPacketOutKeepAlive extends WrappedPacket implements Sendable
}
public WrappedPacketOutKeepAlive(long id) {
super();
this.id = id;
}
public static void load() {
packetClass = PacketTypeClasses.Server.KEEP_ALIVE;
Class<?> packetClass = PacketTypeClasses.Server.KEEP_ALIVE;
integerMode = Reflection.getField(packetClass, int.class, 0) != null;
if (integerMode) {
@@ -91,7 +90,7 @@ public class WrappedPacketOutKeepAlive extends WrappedPacket implements Sendable
public Object asNMSPacket() {
if (integerMode) {
try {
return keepAliveConstructor.newInstance((int) id);
return keepAliveConstructor.newInstance(id);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
@@ -34,10 +34,10 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public final class WrappedPacketOutKickDisconnect extends WrappedPacket implements SendableWrapper {
private static Class<?> packetClass, iChatBaseComponentClass;
private static Class<?> iChatBaseComponentClass;
private static Constructor<?> kickDisconnectConstructor;
private String kickMessage;
private boolean isListening = false;
private boolean isListening;
public WrappedPacketOutKickDisconnect(final Object packet) {
super(packet);
@@ -50,7 +50,7 @@ public final class WrappedPacketOutKickDisconnect extends WrappedPacket implemen
}
public static void load() {
packetClass = PacketTypeClasses.Server.KICK_DISCONNECT;
Class<?> packetClass = PacketTypeClasses.Server.KICK_DISCONNECT;
try {
iChatBaseComponentClass = NMSUtils.getNMSClass("IChatBaseComponent");
} catch (ClassNotFoundException e) {
@@ -24,27 +24,22 @@
package io.github.retrooper.packetevents.packetwrappers.out.position;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
public final class WrappedPacketOutPosition extends WrappedPacket {
private static Class<?> packetClass;
private double x;
private double y;
private double z;
private float yaw;
private float pitch;
private boolean isListening = false;
private final boolean isListening = true;
public WrappedPacketOutPosition(Object packet) {
super(packet);
isListening = true;
}
public static void load() {
packetClass = PacketTypeClasses.Server.POSITION;
}
public static void load() {}
@Override
protected void setup() {
@@ -32,7 +32,6 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class WrappedPacketOutTransaction extends WrappedPacket implements SendableWrapper {
private static Class<?> packetClass;
private static Constructor<?> packetConstructor;
private int windowId;
private short actionNumber;
@@ -51,7 +50,7 @@ public class WrappedPacketOutTransaction extends WrappedPacket implements Sendab
}
public static void load() {
packetClass = PacketTypeClasses.Server.TRANSACTION;
Class<?> packetClass = PacketTypeClasses.Server.TRANSACTION;
try {
packetConstructor = packetClass.getConstructor(int.class, short.class, boolean.class);
@@ -33,11 +33,10 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public final class WrappedPacketOutUpdateHealth extends WrappedPacket implements SendableWrapper {
private static Class<?> packetClass;
private static Constructor<?> packetConstructor;
private float health, foodSaturation;
private int food;
private boolean isListening = false;
private boolean isListening;
public WrappedPacketOutUpdateHealth(final Object packet) {
super(packet);
@@ -59,7 +58,7 @@ public final class WrappedPacketOutUpdateHealth extends WrappedPacket implements
}
public static void load() {
packetClass = PacketTypeClasses.Server.UPDATE_HEALTH;
Class<?> packetClass = PacketTypeClasses.Server.UPDATE_HEALTH;
try {
packetConstructor = packetClass.getConstructor(float.class, int.class, float.class);
@@ -25,14 +25,15 @@
package io.github.retrooper.packetevents.settings;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import net.minecraft.server.v1_8_R3.Packet;
public class PacketEventsSettings {
private ServerVersion backupServerVersion = ServerVersion.v_1_7_10;
private boolean injectAsync = true;
private boolean ejectAsync = true;
private boolean useProtocolLibIfAvailable = false;
private boolean checkForUpdates = true;
private boolean injectEarly = true;
private int packetHandlingThreadCount = 1;
public PacketEventsSettings backupServerVersion(ServerVersion serverVersion) {
this.backupServerVersion = serverVersion;
@@ -50,11 +51,6 @@ public class PacketEventsSettings {
return this;
}
public PacketEventsSettings useProtocolLibIfAvailable(boolean useProtocolLibIfAvailable) {
this.useProtocolLibIfAvailable = useProtocolLibIfAvailable;
return this;
}
public PacketEventsSettings checkForUpdates(boolean checkForUpdates) {
this.checkForUpdates = checkForUpdates;
return this;
@@ -66,6 +62,11 @@ public class PacketEventsSettings {
return this;
}
public PacketEventsSettings packetHandlingThreadCount(int threadCount) {
this.packetHandlingThreadCount = threadCount;
return this;
}
public ServerVersion getBackupServerVersion() {
return backupServerVersion;
}
@@ -78,10 +79,6 @@ public class PacketEventsSettings {
return ejectAsync;
}
public boolean shouldUseProtocolLibIfAvailable() {
return useProtocolLibIfAvailable;
}
public boolean shouldCheckForUpdates() {
return checkForUpdates;
}
@@ -89,4 +86,8 @@ public class PacketEventsSettings {
public boolean shouldInjectEarly() {
return injectEarly;
}
public int getPacketHandlingThreadCount() {
return packetHandlingThreadCount;
}
}
@@ -37,30 +37,31 @@ import java.net.URLConnection;
public class UpdateChecker {
public void handleUpdate() {
inform("Checking for an update, please wait...");
PEVersion localVersion = PacketEvents.getVersion();
try {
String line = readLatestVersion();
PEVersion newVersion = new PEVersion(line);
if (localVersion.isOlder(newVersion)) {
inform("[PacketEvents] There is an update available for the PacketEvents API! (" + newVersion.toString() + ")");
inform("There is an update available for the PacketEvents API! Your build: (" + localVersion.toString() + ") | Update: (" + newVersion.toString() + ")");
}
else if(localVersion.equals(newVersion)) {
inform("[PacketEvents] You are on the latest released version of PacketEvents. (" + newVersion.toString() + ")");
inform("You are on the latest released version of PacketEvents. Your build: (" + 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() + ")");
inform("You are on a dev or pre released build of PacketEvents. Your build: (" + localVersion.toString() + ") | Last released build: (" + newVersion.toString() + ")");
}
} catch (IOException ignored) {
report("[PacketEvents] We failed to find the latest released version of PacketEvents. Your build: (" + localVersion.toString() + ")");
} catch (IOException exception) {
report("We failed to find the latest released version of PacketEvents. Your build: (" + localVersion.toString() + ")");
}
}
private void inform(String message) {
Bukkit.getLogger().info(message);
Bukkit.getLogger().info("[PacketEvents] " + message);
}
private void report(String message) {
Bukkit.getLogger().info(ChatColor.DARK_RED + message);
Bukkit.getLogger().info(ChatColor.DARK_RED + "[PacketEvents] " + message);
}
private String readLatestVersion() throws IOException {
@@ -68,7 +69,6 @@ public class UpdateChecker {
connection.addRequestProperty("User-Agent", "Mozilla/4.0");
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
return reader.readLine();
}
}
@@ -1,42 +0,0 @@
/*
* 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;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.util.BlockIterator;
public class BlockIteratorUtils {
public static Block getBlockLookingAt(final Player player, final int distance) {
final Location location = player.getEyeLocation();
final BlockIterator blocksToAdd = new BlockIterator(location, 0.0D, distance);
Block block = null;
while (blocksToAdd.hasNext()) {
block = blocksToAdd.next();
}
return block;
}
}
@@ -25,6 +25,7 @@
package io.github.retrooper.packetevents.utils.entityfinder;
import io.github.retrooper.packetevents.annotations.Nullable;
import io.github.retrooper.packetevents.exceptions.PacketEventsNMSCachedEntityNotFoundException;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import org.bukkit.Bukkit;
@@ -72,7 +73,7 @@ public final class EntityFinderUtils {
return entity;
}
}
return null;
throw new PacketEventsNMSCachedEntityNotFoundException(id);
}
/**
@@ -88,7 +89,7 @@ public final class EntityFinderUtils {
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
throw new PacketEventsNMSCachedEntityNotFoundException(id);
}
public static Object getNMSEntityByIdWithWorld(final World world, final int id) {
@@ -112,6 +113,9 @@ public final class EntityFinderUtils {
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
if(nmsEntity == null) {
throw new PacketEventsNMSCachedEntityNotFoundException(id);
}
return nmsEntity;
}
@@ -133,7 +137,7 @@ public final class EntityFinderUtils {
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
throw new PacketEventsNMSCachedEntityNotFoundException(id);
}
/**
@@ -61,9 +61,7 @@ public class WrappedGameProfile {
return false;
}
}
return true;
} else {
return true;
}
return true;
}
}
@@ -49,8 +49,12 @@ public final class NMSUtils {
public static String nettyPrefix = "io.netty";
public static Class<?> nmsEntityClass, minecraftServerClass, craftWorldClass, playerInteractManagerClass, entityPlayerClass, playerConnectionClass, craftServerClass,
craftPlayerClass, serverConnectionClass, craftEntityClass,
craftItemStack, nmsItemStackClass, networkManagerClass, nettyChannelClass, gameProfileClass, iChatBaseComponentClass;
private static Method craftWorldGetHandle, getCraftWorldHandleMethod, getServerConnection, getCraftPlayerHandle, getCraftEntityHandle, asBukkitCopy;
craftItemStack, nmsItemStackClass, networkManagerClass, nettyChannelClass, gameProfileClass, iChatBaseComponentClass,
blockPosClass, enumDirectionClass;
private static Method craftWorldGetHandle;
private static Method getCraftPlayerHandle;
private static Method getCraftEntityHandle;
private static Method asBukkitCopy;
private static Field entityPlayerPingField, playerConnectionField;
public static final HashMap<UUID, Object> channelCache = new HashMap<>();
@@ -90,13 +94,12 @@ public final class NMSUtils {
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
blockPosClass = NMSUtils.getNMSClassWithoutException("BlockPosition");
enumDirectionClass = NMSUtils.getNMSClassWithoutException("EnumDirection");
//METHODS
try {
getCraftWorldHandleMethod = craftWorldClass.getMethod("getHandle");
getCraftPlayerHandle = craftPlayerClass.getMethod("getHandle");
getCraftEntityHandle = craftEntityClass.getMethod("getHandle");
getServerConnection = minecraftServerClass.getMethod("getServerConnection");
asBukkitCopy = craftItemStack.getMethod("asBukkitCopy", nmsItemStackClass);
craftWorldGetHandle = craftWorldClass.getMethod("getHandle");
} catch (NoSuchMethodException e) {
@@ -24,8 +24,6 @@
package io.github.retrooper.packetevents.utils.player;
import io.github.retrooper.packetevents.PacketEvents;
public enum ClientVersion {
LOWER_THAN_SUPPORTED_VERSIONS(4),
v_1_7_10(5),
@@ -26,10 +26,8 @@ package io.github.retrooper.packetevents.utils.player;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.event.impl.PlayerEjectEvent;
import io.github.retrooper.packetevents.packetmanager.netty.NettyPacketManager;
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.versionlookup.VersionLookupUtils;
import org.bukkit.entity.Player;
import java.util.HashMap;
@@ -1,143 +0,0 @@
/*
* 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.protocollib;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketEvent;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.event.PacketListener;
import io.github.retrooper.packetevents.event.annotation.PacketHandler;
import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent;
import io.github.retrooper.packetevents.event.impl.PacketSendEvent;
import io.github.retrooper.packetevents.event.priority.PacketEventPriority;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
public class ProtocolLibAPIListener {
public static void registerProtocolLibListener(PacketListener listener, ConcurrentLinkedQueue<Method> methods) {
if (ProtocolLibUtils.isAvailable()) {
for (Method m : methods) {
if (m.getParameterTypes()[0].equals(PacketReceiveEvent.class)) {
PacketHandler annotation = m.getAnnotation(PacketHandler.class);
ListenerPriority priority;
switch (annotation.priority()) {
case PacketEventPriority.LOWEST:
priority = ListenerPriority.LOWEST;
break;
case PacketEventPriority.LOW:
priority = ListenerPriority.LOW;
break;
case PacketEventPriority.HIGH:
priority = ListenerPriority.HIGH;
break;
case PacketEventPriority.HIGHEST:
priority = ListenerPriority.HIGHEST;
break;
case PacketEventPriority.MONITOR:
priority = ListenerPriority.MONITOR;
break;
default:
priority = ListenerPriority.NORMAL;
break;
}
Set<PacketType> clientValues = new HashSet<>();
for(PacketType type : PacketType.Play.Client.getInstance().values()) {
if(type.isSupported()) {
clientValues.add(type);
}
}
ProtocolLibrary.getProtocolManager().
addPacketListener(new PacketAdapter(PacketEvents.getPlugins().get(0),
priority, clientValues) {
@Override
public void onPacketReceiving(PacketEvent event) {
event.setReadOnly(false);
PacketReceiveEvent receiveEvent = new PacketReceiveEvent(event.getPlayer(), event.getPacket().getHandle());
try {
m.invoke(listener, receiveEvent);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
event.setCancelled(receiveEvent.isCancelled());
}
});
} else if (m.getParameterTypes()[0].equals(PacketSendEvent.class)) {
PacketHandler annotation = m.getAnnotation(PacketHandler.class);
ListenerPriority priority;
switch (annotation.priority()) {
case PacketEventPriority.LOWEST:
priority = ListenerPriority.LOWEST;
break;
case PacketEventPriority.LOW:
priority = ListenerPriority.LOW;
break;
case PacketEventPriority.HIGH:
priority = ListenerPriority.HIGH;
break;
case PacketEventPriority.HIGHEST:
priority = ListenerPriority.HIGHEST;
break;
case PacketEventPriority.MONITOR:
priority = ListenerPriority.MONITOR;
break;
default:
priority = ListenerPriority.NORMAL;
break;
}
Set<PacketType> serverValues = new HashSet<>();
for(PacketType serverType : PacketType.Play.Server.getInstance().values()) {
if(serverType.isSupported()) {
serverValues.add(serverType);
}
}
ProtocolLibrary.getProtocolManager().
addPacketListener(new PacketAdapter(PacketEvents.getPlugins().get(0),
priority, serverValues) {
@Override
public void onPacketSending(PacketEvent event) {
event.setReadOnly(false);
PacketSendEvent sendEvent = new PacketSendEvent(event.getPlayer(), event.getPacket().getHandle());
try {
m.invoke(listener, sendEvent);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
event.setCancelled(sendEvent.isCancelled());
}
});
}
}
}
}
}
@@ -28,7 +28,7 @@ import java.util.HashMap;
import java.util.Map;
public class ClassUtil {
private static final Map<String, String> classSimpleNameCache = new HashMap<String, String>();
private static final Map<String, String> classSimpleNameCache = new HashMap<>();
public static String getClassSimpleName(Class<?> cls) {
String simpleClassName = classSimpleNameCache.get(cls.getName());
@@ -48,13 +48,7 @@ public class PEVersion {
//1.2.3.4
text += ".";
int dotCount = 0;
char[] chars = text.toCharArray();
for (char c : chars) {
if (c == '.') {
dotCount++;
}
}
//1.2.3.4.
int arrayIndex = 0;
@@ -26,9 +26,7 @@ package io.github.retrooper.packetevents.utils.vector;
public class Vector3i {
public int x, y, z;
public Vector3i() {
}
public Vector3i() {}
public Vector3i(int x, int y, int z) {
this.x = x;
@@ -1,76 +0,0 @@
/*
* 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.versionlookup;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.utils.protocolsupport.ProtocolSupportUtils;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import io.github.retrooper.packetevents.utils.v_1_7_10.ProtocolVersionAccessor_v_1_7;
import io.github.retrooper.packetevents.utils.viaversion.ViaUtils;
import org.bukkit.entity.Player;
public class VersionLookupUtils {
private static byte protocolAccessMode = -2;
public static void handleLoadedDependencies() {
protocolAccessMode = (byte) (ViaUtils.isAvailable() ?
0 : ProtocolSupportUtils.isAvailable() ?
1 : PacketEvents.getAPI().getServerUtils().getVersion() == ServerVersion.v_1_7_10 ?
2 : -1);
}
public static boolean hasHandledLoadedDependencies() {
return protocolAccessMode != -2;
}
public static boolean isDependencyAvailable() {
return ViaUtils.isAvailable()
|| ProtocolSupportUtils.isAvailable();
}
/**
* If ViaVersion is present, we get the protocol version with the ViaVersion API.
* If ProtocolSupport is present, we get the protocol version with the ProtocolSupport API.
* If ProtocolLib is present, we get the protocol version with the ProtocolLib API.
* Otherwise return -1
*
* @param player target player
* @return protocol version of the player if ViaVersion or ProtocolSupport or ProtocolLib is present. Otherwise -1
*/
public static int getProtocolVersion(final Player player) {
switch (protocolAccessMode) {
case 0:
return ViaUtils.getProtocolVersion(player);
case 1:
return ProtocolSupportUtils.getProtocolVersion(player);
case 2:
return ProtocolVersionAccessor_v_1_7.getProtocolVersion(player);
default:
return -1;
}
}
}