Compare commits

...
19 Commits
Author SHA1 Message Date
retrooper c9d58e08c9 1.7.8 release 2020-11-17 15:34:56 +01:00
retrooper 24eda2b3a5 1.7.8 release
* Official 1.16.4 support
ClientVersion.v_1_16_4, ServerVersion.v_1_16_4 created
* Unfortunately PacketEvents.getSettings().useProtocolLibIfAvailable(boolean) setting most likely won't be coming back
* Bungee client version resolving bug fixed
* Recommended to have ViaVersion, ProtocolSupport or ProtocolLib on your spigot server, as PacketEvents makes use of them to resolve client version ONLY if they are available.
They are required on the spigot server ONLY if you have a bungee network.
* Interruption of PacketEvents.stop() protected
2020-11-17 15:32:37 +01:00
retrooper 38c4f3234d Merge pull request #66 from retrooper/dev
1.7.7 release
2020-11-16 17:55:11 +01:00
retrooper e94b6f24dc 1.7.7 release
* Accessing Entity by ID on servers with more than one world ERROR FIX
* In the WrappedPacketOutChat(String, ChatPosition, UUID) constructor, the String(=message) shouldn't be passed in JSON string format, it can be passed in as an ordinary string message!
Example:
WrappedPacketOutChat packet = new WrappedPacketOutChat("Hello", ChatPosition.CHAT, uuid);
2020-11-16 17:52:37 +01:00
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
36 changed files with 620 additions and 532 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)
+2 -3
View File
@@ -6,7 +6,7 @@
<groupId>io.github.retrooper</groupId>
<artifactId>packetevents</artifactId>
<version>1.7.5</version>
<version>1.7.8</version>
<!-- You can build the project with this: "mvn clean compile assembly:single" -->
<build>
@@ -133,8 +133,7 @@
<dependency>
<groupId>com.github.ProtocolSupport</groupId>
<artifactId>ProtocolSupport</artifactId>
<version>4fdd683</version>
<scope>provided</scope>
<version>3d24efeda6</version>
</dependency>
<dependency>
@@ -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;
@@ -38,9 +38,11 @@ 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.versionlookup.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;
@@ -56,13 +58,13 @@ public final class PacketEvents implements Listener {
private static final PacketEventsAPI packetEventsAPI = new PacketEventsAPI();
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, 5);
private static boolean loading, loaded, initialized, initializing, uninitializing;
private static final PEVersion version = new PEVersion(1, 7, 8);
private static PacketEventsSettings settings = new PacketEventsSettings();
/** General executor service, basically for anything that the packet executor service doesn't do.
/**
* General executor service, basically for anything that the packet executor service doesn't do.
*/
public static ExecutorService generalExecutorService = Executors.newCachedThreadPool();
public static ExecutorService generalExecutorService = Executors.newSingleThreadExecutor();
//Executor used for player injecting/ejecting and for packet processing/event calling
public static ExecutorService packetHandlingExecutorService = Executors.newSingleThreadExecutor();
@@ -86,7 +88,8 @@ public final class PacketEvents implements Listener {
* All PacketEvents' wrappers are setup and do all loading they need to do.
*/
public static void load() {
if (!loaded) {
if (!loaded && !loading) {
loading = true;
ServerVersion version = ServerVersion.getVersion();
WrappedPacket.version = version;
PacketEvent.version = version;
@@ -105,9 +108,11 @@ public final class PacketEvents implements Listener {
WrappedPacket.loadAllWrappers();
} catch (Exception ex) {
throw new IllegalStateException("PacketEvents failed to successfully load...", ex);
loading = false;
throw new PacketEventsLoadFailureException();
}
loaded = true;
loading = false;
}
}
@@ -133,14 +138,14 @@ public final class PacketEvents implements Listener {
*/
public static void init(final Plugin pl, PacketEventsSettings packetEventsSettings) {
load();
if (!initialized) {
if (!initialized && !initializing) {
initializing = true;
settings = packetEventsSettings;
int packetHandlingThreadCount = settings.getPacketHandlingThreadCount();
//if the count is 1 or is invalid
if(packetHandlingThreadCount == 1 || packetHandlingThreadCount < 0) {
if (packetHandlingThreadCount == 1 || packetHandlingThreadCount < 0) {
packetHandlingExecutorService = Executors.newSingleThreadExecutor();
}
else {
} else {
packetHandlingExecutorService = Executors.newFixedThreadPool(packetHandlingThreadCount);
}
plugins.add(pl);
@@ -150,11 +155,17 @@ public final class PacketEvents implements Listener {
PacketEvents.getAPI().packetManager = new PacketManager(plugins.get(0), settings.shouldInjectEarly());
for (final Player p : Bukkit.getOnlinePlayers()) {
getAPI().getPlayerUtils().injectPlayer(p);
try {
getAPI().getPlayerUtils().injectPlayer(p);
} catch (Exception ex) {
p.kickPlayer("Failed to inject you, please rejoin the server!");
}
}
if (settings.shouldCheckForUpdates()) {
PacketEvents.generalExecutorService.execute(() -> new UpdateChecker().handleUpdate());
Future<?> future =
PacketEvents.generalExecutorService
.submit(() -> new UpdateChecker().handleUpdate());
}
if (getAPI().getServerUtils().isBungeeCordEnabled()) {
@@ -163,6 +174,7 @@ public final class PacketEvents implements Listener {
}
initialized = true;
initializing = false;
}
}
@@ -170,7 +182,8 @@ public final class PacketEvents implements Listener {
*
*/
public static void stop() {
if (initialized) {
if (initialized && !uninitializing) {
uninitializing = true;
for (Player player : Bukkit.getOnlinePlayers()) {
PacketEvents.getAPI().packetManager.ejectPlayer(player);
}
@@ -182,6 +195,7 @@ public final class PacketEvents implements Listener {
PacketEvents.generalExecutorService.shutdownNow();
PacketEvents.packetHandlingExecutorService.shutdownNow();
initialized = false;
uninitializing = true;
}
}
@@ -214,44 +228,43 @@ 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;
try {
if (getAPI().packetManager.canInject(e.getPlayer())) {
getAPI().packetManager.injectPlayer(e.getPlayer());
}
getAPI().packetManager.injectPlayer(e.getPlayer());
} catch (Exception ex) {
e.disallow(PlayerLoginEvent.Result.KICK_OTHER, "We are unable to inject you. Please try again!");
}
}
}
@EventHandler
@EventHandler(priority = EventPriority.LOW)
public void onJoin(final PlayerJoinEvent e) {
if (!VersionLookupUtils.hasHandledLoadedDependencies()) {
VersionLookupUtils.handleLoadedDependencies();
}
Object channel = NMSUtils.getChannel(e.getPlayer());
if (PacketEvents.getAPI().getServerUtils().getVersion() == ServerVersion.v_1_7_10) {
ClientVersion version = ClientVersion.getClientVersion(ProtocolVersionAccessor_v_1_7.getProtocolVersion(e.getPlayer()));
PacketEvents.getAPI().getPlayerUtils().clientVersionsMap.put(channel, version);
} else if (VersionLookupUtils.isDependencyAvailable()) {
int protocolVersion = VersionLookupUtils.getProtocolVersion(e.getPlayer());
ClientVersion version = ClientVersion.getClientVersion(protocolVersion);
PacketEvents.getAPI().getPlayerUtils().clientVersionsMap.put(channel, version);
}
//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())) {
try {
PacketEvents.getAPI().packetManager.injectPlayer(e.getPlayer());
} catch (Exception ex) {
e.getPlayer().kickPlayer("There was an issue injecting you. Please try again!");
}
}
}
@EventHandler
@EventHandler(priority = EventPriority.HIGHEST)
public void onQuit(final PlayerQuitEvent e) {
PacketEvents.getAPI().getPlayerUtils().clientVersionsMap.remove(e.getPlayer().getUniqueId());
Object channel = NMSUtils.getChannelNoCache(e.getPlayer());
PacketEvents.getAPI().getPlayerUtils().clientVersionsMap.remove(channel);
}
}
}
@@ -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) {
@@ -28,5 +28,6 @@ package io.github.retrooper.packetevents.event;
* A Packet listener.
* Implement this interface in your listeners.
*/
@Deprecated
public interface PacketListener {
}
@@ -0,0 +1,65 @@
/*
* 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;
import io.github.retrooper.packetevents.event.impl.*;
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,99 +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.impl.*;
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.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import io.github.retrooper.packetevents.event.PacketListenerDynamic;
public final class EventManager {
private final Map<PacketListener, List<Method>> staticRegisteredMethods = new HashMap<>();
public void callEvent(final PacketEvent e) {
//STATIC LISTENERS
for (final PacketListener listener : staticRegisteredMethods.keySet()) {
List<Method> methods = staticRegisteredMethods.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)) {
private final EventManagerLegacy legacyEventManager = new EventManagerLegacy();
private final EventManagerDynamic dynamicEventManager = new EventManagerDynamic();
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();
}
}
}
}
}
public void callEvent(PacketEvent event) {
dynamicEventManager.callEvent(event);
legacyEventManager.callEvent(event);
}
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()) {
if (ProtocolLibUtils.isAvailable()
&& PacketEvents.getSettings().shouldUseProtocolLibIfAvailable()) {
ProtocolLibAPIListener.registerProtocolLibListener(listener, methods);
} else {
staticRegisteredMethods.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) {
staticRegisteredMethods.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() {
staticRegisteredMethods.clear();
}
public boolean isRegistered(final PacketListener listener) {
return staticRegisteredMethods.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,19 +25,16 @@
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.PacketListenerDynamic;
import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent;
import io.github.retrooper.packetevents.event.impl.PlayerEjectEvent;
import io.github.retrooper.packetevents.event.impl.PlayerInjectEvent;
import io.github.retrooper.packetevents.event.priority.PacketEventPriority;
import io.github.retrooper.packetevents.packettype.PacketType;
import io.github.retrooper.packetevents.packetwrappers.in.chat.WrappedPacketInChat;
import io.github.retrooper.packetevents.packetwrappers.out.helditemslot.WrappedPacketOutHeldItemSlot;
import io.github.retrooper.packetevents.utils.player.ClientVersion;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
public class MainExample extends JavaPlugin implements PacketListener {
public class MainExample extends JavaPlugin {
@Override
public void onLoad() {
@@ -46,10 +43,9 @@ 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).packetHandlingThreadCount(1);
PacketEvents.getAPI().getEventManager().registerListener(this);
PacketEvents.getSettings().injectAsync(true).ejectAsync(true)
.backupServerVersion(ServerVersion.v_1_7_10).checkForUpdates(true).injectEarly(true).
packetHandlingThreadCount(1);
PacketEvents.init(this);
}
@@ -22,13 +22,14 @@
* SOFTWARE.
*/
package io.github.retrooper.packetevents.utils.protocolsupport;
package io.github.retrooper.packetevents.exceptions;
import org.bukkit.entity.Player;
import protocolsupport.api.ProtocolSupportAPI;
public class PacketEventsLoadFailureException extends RuntimeException {
public PacketEventsLoadFailureException(String message) {
super(message);
}
class ProtocolSupportAPIAccessor {
public static int getProtocolVersion(final Player player) {
return ProtocolSupportAPI.getProtocolVersion(player).getId();
public PacketEventsLoadFailureException() {
this("PacketEvents failed to successfully load...");
}
}
@@ -0,0 +1,41 @@
/*
* 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.exceptions;
import io.github.retrooper.packetevents.event.PacketListener;
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
import java.lang.reflect.Method;
public class PacketEventsMethodAccessException extends RuntimeException {
public PacketEventsMethodAccessException(String message) {
super(message);
}
public PacketEventsMethodAccessException(Method method, PacketListener listener) {
this("PacketEvents failed to access the "
+ method.getName() + " method in " + ClassUtil.getClassSimpleName(listener.getClass()));
}
}
@@ -0,0 +1,41 @@
/*
* 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.exceptions;
import io.github.retrooper.packetevents.event.PacketListener;
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
import java.lang.reflect.Method;
public class PacketEventsMethodInvokeException extends RuntimeException {
public PacketEventsMethodInvokeException(String message) {
super(message);
}
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 + "!");
}
}
@@ -30,22 +30,17 @@ 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 final AtomicInteger handlerID = new AtomicInteger();
private final int handlerNumber = handlerID.getAndIncrement();
private final Plugin plugin;
private final boolean tinyProtocolMode;
public final TinyProtocol tinyProtocol;
@@ -59,8 +54,8 @@ public class PacketManager {
tinyProtocol = new TinyProtocol(plugin);
nettyProtocol = null;
} else {
tinyProtocol = null;
nettyProtocol = new NettyPacketManager(plugin);
tinyProtocol = null;
}
}
@@ -97,8 +92,10 @@ public class PacketManager {
PacketEvents.getAPI().getEventManager().callEvent(injectEvent);
if (!injectEvent.isCancelled()) {
if (tinyProtocolMode) {
assert tinyProtocol != null;
tinyProtocol.injectPlayerAsync(player);
} else {
assert nettyProtocol != null;
nettyProtocol.injectPlayerAsync(player);
}
}
@@ -162,12 +159,8 @@ public class PacketManager {
}
}
public boolean canInject(Player player) {
return true;
}
public String getNettyHandlerName() {
return "pe-" + plugin.getName() + "-" + handlerNumber;
return "pe-" + plugin.getName();
}
public Object read(Player player, Object channel, Object packet) {
@@ -269,7 +262,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);
}
@@ -282,13 +275,13 @@ public class PacketManager {
}
private void interceptLogin(PacketLoginEvent event) {
if (event.getPacketId() == PacketType.Login.HANDSHAKE) {
if (!VersionLookupUtils.isDependencyAvailable()) {
WrappedPacketLoginHandshake handshake = new WrappedPacketLoginHandshake(event.getNMSPacket());
int protocolVersion = handshake.getProtocolVersion();
ClientVersion version = ClientVersion.getClientVersion(protocolVersion);
PacketEvents.getAPI().getPlayerUtils().clientVersionsMap.put(event.getChannel(), version);
}
if (event.getPacketId() == PacketType.Login.HANDSHAKE
&& PacketEvents.getAPI().getServerUtils().getVersion() != ServerVersion.v_1_7_10
&& !PacketEvents.getAPI().getServerUtils().isBungeeCordEnabled()) {
WrappedPacketLoginHandshake handshake = new WrappedPacketLoginHandshake(event.getNMSPacket());
int protocolVersion = handshake.getProtocolVersion();
ClientVersion version = ClientVersion.getClientVersion(protocolVersion);
PacketEvents.getAPI().getPlayerUtils().clientVersionsMap.put(event.getChannel(), version);
}
}
@@ -1,7 +1,6 @@
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;
@@ -10,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;
@@ -403,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);
}
/**
@@ -471,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);
@@ -485,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);
@@ -4,7 +4,6 @@ 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.*;
@@ -165,9 +164,9 @@ public class TinyProtocol8 {
boolean looking = true;
// We need to synchronize against this list
if(getNetworkMarkers != null) {
networkManagers = (List<Object>) getNetworkMarkers.invoke(null, serverConnection);}
else {
if (getNetworkMarkers != null) {
networkManagers = (List<Object>) getNetworkMarkers.invoke(null, serverConnection);
} else {
networkManagers = new ArrayList<>();
}
createServerChannelHandler();
@@ -502,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);
@@ -516,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);
@@ -39,11 +39,12 @@ public class PacketType {
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);
@@ -39,9 +39,10 @@ public class PacketTypeClasses {
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() {
@@ -47,7 +47,7 @@ final class WrappedPacketInBlockPlace_1_8 extends WrappedPacket {
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return -1;
return 0;
}
@@ -60,7 +60,7 @@ final class WrappedPacketInBlockPlace_1_8 extends WrappedPacket {
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return -1;
return 0;
}
public int getZ() {
@@ -72,7 +72,7 @@ final class WrappedPacketInBlockPlace_1_8 extends WrappedPacket {
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return -1;
return 0;
}
public ItemStack getItemStack() {
@@ -58,7 +58,7 @@ final class WrappedPacketInBlockPlace_1_9 extends WrappedPacket {
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return -1;
return 0;
}
public int getY() {
@@ -76,7 +76,7 @@ final class WrappedPacketInBlockPlace_1_9 extends WrappedPacket {
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return -1;
return 0;
}
public int getZ() {
@@ -94,7 +94,7 @@ final class WrappedPacketInBlockPlace_1_9 extends WrappedPacket {
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return -1;
return 0;
}
public Object getEnumDirectionObject() {
@@ -38,11 +38,7 @@ public final class WrappedPacketInUseEntity extends WrappedPacket {
}
public static void load() {
//System.out.println("USE ENTITY HAS BEEN LOADED BROOOIOII");
Class<?> useEntityClass = NMSUtils.getNMSClassWithoutException("PacketPlayInUseEntity");
/*if(useEntityClass == null) {
System.out.println("failed to init use entity wtfffff");
}*/
try {
enumEntityUseActionClass = NMSUtils.getNMSClass("EnumEntityUseAction");
} catch (ClassNotFoundException e) {
@@ -79,7 +79,7 @@ public final class WrappedPacketOutChat extends WrappedPacket implements Sendabl
public WrappedPacketOutChat(String message, ChatPosition chatPosition, UUID uuid) {
this.uuid = uuid;
this.message = message;
this.message = fromStringToJSON(message);
this.chatPosition = chatPosition;
}
@@ -25,13 +25,11 @@
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;
private boolean checkForUpdates = true;
private boolean injectEarly = true;
private int packetHandlingThreadCount = 1;
@@ -52,11 +50,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;
@@ -85,10 +78,6 @@ public class PacketEventsSettings {
return ejectAsync;
}
public boolean shouldUseProtocolLibIfAvailable() {
return useProtocolLibIfAvailable;
}
public boolean shouldCheckForUpdates() {
return checkForUpdates;
}
@@ -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;
@@ -39,10 +40,8 @@ public final class EntityFinderUtils {
public static ServerVersion version;
private static Class<?> worldServerClass;
private static Class<?> craftWorldClass;
private static Class<?> entityClass;
private static Method getEntityByIdMethod;
private static Method craftWorldGetHandle;
private static Method getBukkitEntity;
private static boolean isServerVersion_v_1_8_x;
@@ -51,15 +50,13 @@ public final class EntityFinderUtils {
try {
worldServerClass = NMSUtils.getNMSClass("WorldServer");
craftWorldClass = NMSUtils.getOBCClass("CraftWorld");
entityClass = NMSUtils.getNMSClass("Entity");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
getEntityByIdMethod = worldServerClass.getMethod(getEntityByIDMethodName(), int.class);
getEntityByIdMethod = worldServerClass.getMethod(isServerVersion_v_1_8_x ? "a" : "getEntity", int.class);
craftWorldGetHandle = craftWorldClass.getMethod("getHandle");
getBukkitEntity = entityClass.getMethod("getBukkitEntity");
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
@@ -72,7 +69,15 @@ public final class EntityFinderUtils {
return entity;
}
}
return null;
//Entity has not been found in the NMS entity cache map...
for(World world : Bukkit.getWorlds()) {
for(Entity entity : world.getEntities()) {
if(entity.getEntityId() == id) {
return NMSUtils.getNMSEntity(entity);
}
}
}
throw new PacketEventsNMSCachedEntityNotFoundException(id);
}
/**
@@ -82,13 +87,21 @@ public final class EntityFinderUtils {
* @return Entity
*/
public static Entity getEntityById(final int id) {
Object nmsEntity = getNMSEntityById(id);
try {
return (Entity) getBukkitEntity.invoke(nmsEntity);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
for (final World world : Bukkit.getWorlds()) {
final Object entity = getNMSEntityByIdWithWorld(world, id);
if (entity != null) {
return NMSUtils.getBukkitEntity(entity);
}
}
return null;
//Entity has not been found in the NMS entity cache map...
for(World world : Bukkit.getWorlds()) {
for(Entity entity : world.getEntities()) {
if(entity.getEntityId() == id) {
return entity;
}
}
}
throw new PacketEventsNMSCachedEntityNotFoundException(id);
}
public static Object getNMSEntityByIdWithWorld(final World world, final int id) {
@@ -97,22 +110,19 @@ public final class EntityFinderUtils {
} else if (craftWorldClass == null) {
throw new IllegalStateException("PacketEvents failed to locate the CraftWorld class.");
}
Object craftWorld = craftWorldClass.cast(world);
Object worldServer = null;
try {
worldServer = craftWorldGetHandle.invoke(craftWorld);
worldServer = craftWorldGetHandle.invoke(world);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
Object nmsEntity = null;
try {
nmsEntity = getEntityByIdMethod.invoke(worldServer, id);
return getEntityByIdMethod.invoke(worldServer, id);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return nmsEntity;
return null;
}
/**
@@ -125,27 +135,6 @@ public final class EntityFinderUtils {
@Nullable
public static Entity getEntityByIdWithWorld(final World world, final int id) {
Object nmsEntity = getNMSEntityByIdWithWorld(world, id);
if (nmsEntity == null) {
return null;
}
try {
return (Entity) getBukkitEntity.invoke(nmsEntity);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
/**
* This is the name of the method that returns the NMS entity when you pass in its ID.
* On 1.8-1.8.8 the function name is called 'a', on 1.7.10 and 1.9 and above the name is called 'getEntity'.
*
* @return entity by ID method name
*/
public static String getEntityByIDMethodName() {
if (isServerVersion_v_1_8_x) {
return "a";
}
return "getEntity";
return NMSUtils.getBukkitEntity(nmsEntity);
}
}
@@ -55,6 +55,7 @@ public final class NMSUtils {
private static Method getCraftPlayerHandle;
private static Method getCraftEntityHandle;
private static Method asBukkitCopy;
private static Method getBukkitEntity;
private static Field entityPlayerPingField, playerConnectionField;
public static final HashMap<UUID, Object> channelCache = new HashMap<>();
@@ -102,6 +103,7 @@ public final class NMSUtils {
getCraftEntityHandle = craftEntityClass.getMethod("getHandle");
asBukkitCopy = craftItemStack.getMethod("asBukkitCopy", nmsItemStackClass);
craftWorldGetHandle = craftWorldClass.getMethod("getHandle");
getBukkitEntity = nmsEntityClass.getMethod("getBukkitEntity");
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
@@ -196,6 +198,15 @@ public final class NMSUtils {
return null;
}
public static Entity getBukkitEntity(final Object nmsEntity) {
try {
return (Entity) getBukkitEntity.invoke(nmsEntity);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
public static Object getCraftPlayer(final Player player) {
return craftPlayerClass.cast(player);
}
@@ -53,7 +53,8 @@ public enum ClientVersion {
v_1_16_1(736),
v_1_16_2(751),
v_1_16_3(753),
HIGHER_THAN_SUPPORTED_VERSIONS(754),
v_1_16_4(754),
HIGHER_THAN_SUPPORTED_VERSIONS(755),
/**
* Pre releases just aren't supported, we would end up with so many enum constants.
*/
@@ -65,6 +66,7 @@ public enum ClientVersion {
private static final int lowestSupportedProtocolVersion = 5;
private static final int highestSupportedProtocolVersion = 753;
ClientVersion(int protocolVersion) {
this.protocolVersion = protocolVersion;
}
@@ -94,24 +96,21 @@ public enum ClientVersion {
}
public static ClientVersion getClientVersion(int protocolVersion) {
if(protocolVersion == -1) {
return ClientVersion.UNRESOLVED;
if (protocolVersion == -1) {
return ClientVersion.UNRESOLVED;
}
for(ClientVersion version : ClientVersion.values()) {
if(version.protocolVersion > protocolVersion) {
for (ClientVersion version : ClientVersion.values()) {
if (version.protocolVersion > protocolVersion) {
break;
}
else if(version.protocolVersion == protocolVersion) {
} else if (version.protocolVersion == protocolVersion) {
return version;
}
}
if(protocolVersion < lowestSupportedProtocolVersion) {
if (protocolVersion < lowestSupportedProtocolVersion) {
return LOWER_THAN_SUPPORTED_VERSIONS;
}
else if(protocolVersion > highestSupportedProtocolVersion) {
} else if (protocolVersion > highestSupportedProtocolVersion) {
return HIGHER_THAN_SUPPORTED_VERSIONS;
}
else if(protocolVersion > lowestSupportedProtocolVersion
} else if (protocolVersion > lowestSupportedProtocolVersion
&& protocolVersion < highestSupportedProtocolVersion) {
return ANY_PRE_RELEASE_VERSION;
}
@@ -1,144 +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.List;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
public class ProtocolLibAPIListener {
public static void registerProtocolLibListener(PacketListener listener, List<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());
}
});
}
}
}
}
}
@@ -38,7 +38,7 @@ public enum ServerVersion {
v_1_11_2((short) 316), v_1_12((short) 335), v_1_12_1((short) 338), v_1_12_2((short) 340), v_1_13((short) 393),
v_1_13_1((short) 401), v_1_13_2((short) 404), v_1_14((short) 477), v_1_14_1((short) 480), v_1_14_2((short) 485),
v_1_14_3((short) 490), v_1_14_4((short) 498), v_1_15((short) 573), v_1_15_1((short) 575), v_1_15_2((short) 578),
v_1_16((short) 735), v_1_16_1((short) 736), v_1_16_2((short) 751), v_1_16_3((short) 753), ERROR((short) -1), EMPTY((short) -1);
v_1_16((short) 735), v_1_16_1((short) 736), v_1_16_2((short) 751), v_1_16_3((short) 753), v_1_16_4((short)754),ERROR((short) -1);
private static final String nmsVersionSuffix = Bukkit.getServer().getClass().getPackage().getName()
.replace(".", ",").split(",")[3];
@@ -58,6 +58,9 @@ public enum ServerVersion {
if (reversedValues[0] == null) {
reversedValues = ServerVersion.reverse(values());
}
if(reversedValues == null) {
throw new IllegalStateException("Failed to reverse the ServerVersion enum constant values.");
}
for (final ServerVersion val : reversedValues) {
String valName = val.name().substring(2).replace("_", ".");
if (Bukkit.getBukkitVersion().contains(valName)) {
@@ -125,7 +128,7 @@ public enum ServerVersion {
* @return True if the supplied version is lower or equal, false if it is higher
* than the server's version.
*/
public boolean isAtLeast(final ServerVersion version) {
public boolean isHigherThanOrEquals(final ServerVersion version) {
return protocolId >= version.protocolId;
}
@@ -149,7 +152,7 @@ public enum ServerVersion {
* @return True if the supplied version is higher or equal, false if it is lower
* than the server's version.
*/
public boolean isAtMost(final ServerVersion version) {
public boolean isLowerThanOrEquals(final ServerVersion version) {
return version.protocolId >= protocolId;
}
}
@@ -24,53 +24,25 @@
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 io.github.retrooper.packetevents.utils.versionlookup.protocollib.ProtocolLibVersionLookupUtils;
import io.github.retrooper.packetevents.utils.versionlookup.protocolsupport.ProtocolSupportVersionLookupUtils;
import io.github.retrooper.packetevents.utils.versionlookup.viaversion.ViaVersionLookupUtils;
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();
return ViaVersionLookupUtils.isAvailable() || ProtocolSupportVersionLookupUtils.isAvailable()
|| ProtocolLibVersionLookupUtils.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;
public static int getProtocolVersion(Player player) {
if (ViaVersionLookupUtils.isAvailable()) {
return ViaVersionLookupUtils.getProtocolVersion(player);
} else if (ProtocolSupportVersionLookupUtils.isAvailable()) {
return ProtocolSupportVersionLookupUtils.getProtocolVersion(player);
} else if (ProtocolLibVersionLookupUtils.isAvailable()) {
return ProtocolLibVersionLookupUtils.getProtocolVersion(player);
}
return -1;
}
}
@@ -22,12 +22,18 @@
* SOFTWARE.
*/
package io.github.retrooper.packetevents.utils.protocollib;
package io.github.retrooper.packetevents.utils.versionlookup.protocollib;
import com.comphenix.protocol.ProtocolLibrary;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
public class ProtocolLibUtils {
public class ProtocolLibVersionLookupUtils {
public static boolean isAvailable() {
return Bukkit.getPluginManager().isPluginEnabled("ProtocolLib");
}
public static int getProtocolVersion(Player player) {
return ProtocolLibrary.getProtocolManager().getProtocolVersion(player);
}
}
@@ -22,17 +22,18 @@
* SOFTWARE.
*/
package io.github.retrooper.packetevents.utils.protocolsupport;
package io.github.retrooper.packetevents.utils.versionlookup.protocolsupport;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import protocolsupport.api.ProtocolSupportAPI;
public class ProtocolSupportUtils {
public class ProtocolSupportVersionLookupUtils {
public static boolean isAvailable() {
return Bukkit.getPluginManager().isPluginEnabled("ProtocolSupport");
}
public static int getProtocolVersion(final Player player) {
return ProtocolSupportAPIAccessor.getProtocolVersion(player);
public static int getProtocolVersion(Player player) {
return ProtocolSupportAPI.getProtocolVersion(player).getId();
}
}
@@ -22,7 +22,7 @@
* SOFTWARE.
*/
package io.github.retrooper.packetevents.utils.v_1_7_10;
package io.github.retrooper.packetevents.utils.versionlookup.v_1_7_10;
import org.bukkit.entity.Player;
@@ -22,18 +22,18 @@
* SOFTWARE.
*/
package io.github.retrooper.packetevents.utils.viaversion;
package io.github.retrooper.packetevents.utils.versionlookup.viaversion;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import us.myles.ViaVersion.api.Via;
public class ViaUtils {
public static int getProtocolVersion(final Player player) {
return ViaAPIAccessor.getProtocolVersion(player);
}
public class ViaVersionLookupUtils {
public static boolean isAvailable() {
return Bukkit.getPluginManager().isPluginEnabled("ViaVersion");
}
public static int getProtocolVersion(Player player) {
return Via.getAPI().getPlayerVersion(player.getUniqueId());
}
}