Compare commits

...
30 Commits
Author SHA1 Message Date
Retrooper d5454b918a 1.6.2 release
* Issues with WrappedPacketInEntityAction on 1.7.10
2020-08-30 16:15:28 +08:00
Retrooper 427a0fff4a * NPE fix for WrappedPacketInEntityAction in 1.8+ 2020-08-30 15:38:17 +08:00
retrooper 7fc446321d Merge pull request #32 from SamJakob/patch-3
Only update JavaDoc on published release
2020-08-29 21:55:13 +02:00
retrooper 4799fb67c4 1.6.1 release 2020-08-28 16:37:26 +02:00
SamJakob 5ed9038f7b Only update JavaDoc on published release 2020-08-28 12:22:33 +01:00
retrooper 8c1cd4b824 Merge pull request #31 from NikV2/master
Hotfix - Mistake patching
2020-08-28 07:37:06 +02:00
Nik 50a09de212 Sorry i just can't watch it be like that:") IT HURTS 2020-08-28 03:54:53 +03:00
Nik e66710f5ed commit 2020-08-28 03:52:50 +03:00
retrooper 33131f4fcd Merge pull request #30 from NikV2/master
Uninjections async are now configurable in the settings(can cause reload bugs), I’d rather have setIdentifier() deprecated for one patch version(1.6.1) then in 1.16.2 we remove it completely, basically if then user doesn’t set identifier to anything, we will generate a random one, low priority for injecting and uninjecting players in PacketEvents class.
2020-08-28 01:57:42 +02:00
Nik 9834787279 commit 2020-08-28 02:46:11 +03:00
retrooper 227b569138 Merge pull request #29 from SamJakob/patch-3
Remove committer from javadoc workflow
2020-08-28 01:37:32 +02:00
SamJakob ad1a8a3dba Remove committer from workflow 2020-08-28 00:32:56 +01:00
Nik 262c470031 commit 2020-08-28 02:22:10 +03:00
retrooper 4c9b9be23f Merge pull request #27 from SamJakob/patch-2
Use GitHub Actions to deploy JavaDocs to GH Pages
2020-08-28 01:14:31 +02:00
SamJakob d1c04d39d2 Use GitHub Actions to deploy JavaDocs to GH Pages 2020-08-28 00:13:58 +01:00
retrooper afbe7b44b6 Merge pull request #26 from SamJakob/master
Add JavaDoc to build (and cleanup)
2020-08-28 00:38:39 +02:00
SamJakob f76f1687fb Add JavaDoc to build and fix JavaDoc HTML entities, add .gitignore (cleanup) 2020-08-27 23:32:37 +01:00
retrooper 8eb4015cab 1.6 release commit 2020-08-27 19:10:53 +02:00
retrooper 3ec44f72da 1.6 stable RELEASE 2020-08-27 19:02:37 +02:00
retrooper 3797c45d98 1.6 pre 6
Stable version, please use this and wait for 1.6 official release, more features coming ;)

* Useless enums deleted: Gamemode.java, Hand.java
* Enums that belong to wrappers have been refactored to be a "subclass" of that wrapper: EntityAnimationType.java, EntityUseAction.java, PlayerAction.java, PlayerDigType.java
* Null pointer fixed in WrappedPacketInCustomPayload for 1.7.10
* Null pointer fixed in WrappedPacketInBlockPlace for 1.7.10
* Bug fixed in WrappedPacketInClientCommand for 1.7.10
* Bug fix in WrappedPacketInWindowClick.getWindowClickType() sometimes throwing a ArrayIndexOutOfBoundsException
* WrappedPacketInEntityAction.PlayerAction missing enum constants for 1.7.10/1.8.x fixed, this enum should now be cross version safe, the RIDING_JUMP doesn't exist on newer versions, so accessing this enum should return START_RIDING_JUMP instead.
This system for the enum should make 1.7/1.8 compatible with newer versions.
2020-08-26 14:38:39 +02:00
retrooper 94b7523774 wrapped packet version initialized 2020-08-25 22:05:20 +02:00
retrooper 6f0de9f01c serverversion is public now 2020-08-25 22:04:06 +02:00
retrooper 16cc63447f not tryna mess stuff up 2020-08-25 21:15:02 +02:00
retrooper bb6661b4eb 1.6 pre v5
added RIDING_JUMP enum constant, for now a simple fix, for some reason 1.8 tries accessing this
2020-08-25 21:05:29 +02:00
retrooper 63a5005257 1.6 pre release v4
RIDING_JUMP enum constant added to support 1.8.x
2020-08-25 20:55:33 +02:00
retrooper 8b4fdd4773 1.6 pre 3
* WrappedPacketInAbilities bug fixed for 1.16.x ONLY
2020-08-25 18:49:36 +02:00
retrooper 333bea795f 1.6 pre 2(still 2)
* pom.xml version of packetevents updated to 1.6
2020-08-25 18:19:53 +02:00
retrooper 3ee972a4ff 1.6 pre 2, WrappedPacketInFlying & WrappedPacketInWindowClick.java bugs fixed 2020-08-25 18:01:37 +02:00
retrooper 94a1f67975 1.6 pre, with debugs, might not work!
* All wrappers optimized, much faster with lots of caching
* All wrappers have a function for loading, now wrappers load stuff when you call PacketEvents#load()
* WrappedPacketOutKeepAlive is now sendable to players
* WrappedPacketOutPosition wrapper created
* WrappedPacketInWindowClick wrapper created
2020-08-25 17:30:19 +02:00
retrooper e00b55842d * WrappedPacketOutPosition created (UNFINISHED, onGround BOOLEAN not done and flags missing) 2020-08-25 13:33:53 +02:00
97 changed files with 1904 additions and 798 deletions

No files matched your search

+30
View File
@@ -0,0 +1,30 @@
name: Generate and deploy JavaDocs
on:
release:
types: [published]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build with Maven
run: mvn install
- name: List target/apidocs
run: ls target/apidocs
- name: GitHub Pages
uses: crazy-max/ghaction-github-pages@v2.1.2
env:
GH_PAT: ${{ secrets.GH_PAT }}
with:
target_branch: javadocs
keep_history: true
build_dir: target/apidocs
commit_message: Update JavaDocs
+113
View File
@@ -0,0 +1,113 @@
#
# JetBrains
#
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
#
# Java
#
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
#
# Maven
#
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
.mvn/wrapper/maven-wrapper.jar
+3
View File
@@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml
+16
View File
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="packetevents" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel>
<module name="packetevents" target="8" />
</bytecodeTargetLevel>
</component>
</project>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
</component>
</project>
+45
View File
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="viaversion-repo" />
<option name="name" value="viaversion-repo" />
<option name="url" value="https://repo.viaversion.com" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jitpack.io" />
<option name="name" value="jitpack.io" />
<option name="url" value="https://jitpack.io" />
</remote-repository>
<remote-repository>
<option name="id" value="spigot-repo" />
<option name="name" value="spigot-repo" />
<option name="url" value="https://hub.spigotmc.org/nexus/content/repositories/snapshots/" />
</remote-repository>
<remote-repository>
<option name="id" value="funkemunky-releases" />
<option name="name" value="funkemunky-releases" />
<option name="url" value="https://nexus.funkemunky.cc/content/repositories/releases/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="dmulloy2-repo" />
<option name="name" value="dmulloy2-repo" />
<option name="url" value="https://repo.dmulloy2.net/nexus/repository/public/" />
</remote-repository>
</component>
</project>
+16
View File
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<list size="1">
<item index="0" class="java.lang.String" itemvalue="org.bukkit.event.EventHandler" />
</list>
</component>
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_13" project-jdk-name="13" project-jdk-type="JavaSDK" />
</project>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/packetevents.iml" filepath="$PROJECT_DIR$/packetevents.iml" />
</modules>
</component>
</project>
Generated
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
+52
View File
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="minecraft" name="Minecraft">
<configuration>
<autoDetectTypes>
<platformType>SPIGOT</platformType>
</autoDetectTypes>
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/.idea/libraries" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.github.spigot:1.8.8:1.8.8" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.github.spigot:1.7.10:1.7.10" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.comphenix.protocol:ProtocolLib:4.5.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: cglib:cglib-nodep:3.2.5" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.comphenix.executors:BukkitExecutors:1.1-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: us.myles:viaversion:3.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: us.myles:viaversion-common:3.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: us.myles:viaversion-bukkit:3.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: us.myles:viaversion-bukkit-legacy:3.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: us.myles:viaversion-bungee:3.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: us.myles:viaversion-fabric:3.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: us.myles:viaversion-sponge:3.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: us.myles:viaversion-sponge-legacy:3.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: us.myles:viaversion-velocity:3.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.md-5:bungeecord-chat:1.15-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.github.ProtocolSupport:ProtocolSupport:4fdd683" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.apache.commons:commons-lang3:3.8.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: it.unimi.dsi:fastutil:8.2.2" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.gson:gson:2.8.5" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.spigotmc:spigot-api:1.8.8-R0.1-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: commons-lang:commons-lang:2.6" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: junit:junit:4.10" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:17.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.avaje:ebean:2.8.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.persistence:persistence-api:1.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.yaml:snakeyaml:1.15" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.bukkit:bukkit:1.8.8-R0.1-SNAPSHOT" level="project" />
</component>
</module>
+13 -3
View File
@@ -6,7 +6,7 @@
<groupId>io.github.retrooper</groupId>
<artifactId>packetevents</artifactId>
<version>1.5.9</version>
<version>1.6.2</version>
<!-- You can build the project with this: "mvn clean compile assembly:single" -->
<build>
@@ -27,6 +27,18 @@
<target>8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<packaging>jar</packaging>
@@ -62,7 +74,6 @@
<dependencies>
<dependency>
<groupId>org.github.spigot</groupId>
<artifactId>1.8.8</artifactId>
@@ -111,6 +122,5 @@
<version>1.8.8-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
@@ -1,17 +1,25 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents;
import io.github.retrooper.packetevents.api.PacketEventsAPI;
import io.github.retrooper.packetevents.enums.ClientVersion;
import io.github.retrooper.packetevents.enums.ServerVersion;
import io.github.retrooper.packetevents.event.PacketEvent;
import io.github.retrooper.packetevents.event.PacketListener;
import io.github.retrooper.packetevents.event.impl.BukkitMoveEvent;
import io.github.retrooper.packetevents.packet.PacketType;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.settings.PacketEventsSettings;
import io.github.retrooper.packetevents.utils.NMSUtils;
import io.github.retrooper.packetevents.utils.nms_entityfinder.EntityFinderUtils;
import io.github.retrooper.packetevents.utils.versionlookup.VersionLookupUtils;
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.PlayerMoveEvent;
@@ -19,6 +27,7 @@ import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.Plugin;
public final class PacketEvents implements PacketListener, Listener {
private static final PacketEventsAPI packetEventsAPI = new PacketEventsAPI();
private static final PacketEvents instance = new PacketEvents();
private static final PacketEventsSettings settings = new PacketEventsSettings();
@@ -27,21 +36,38 @@ public final class PacketEvents implements PacketListener, Listener {
/**
* Call this before start()
*
* Recommended on your onLoad() Bukkit Method
*/
public static void load() {
//SERVER VERSION LOADING
//Server Version reversed values caching
ServerVersion.reversedValues = ServerVersion.reverse(ServerVersion.values());
//Server Version loading
ServerVersion.load();
ServerVersion version = ServerVersion.getVersion();
WrappedPacket.version = version;
PacketEvent.version = version;
NMSUtils.version = version;
EntityFinderUtils.version = version;
NMSUtils.load();
PacketTypeClasses.Client.load();
PacketTypeClasses.Server.load();
EntityFinderUtils.load();
WrappedPacket.loadAllWrappers();
VersionLookupUtils.load();
ClientVersion.prepareLookUp();
hasLoaded = true;
}
/**
* Loads PacketEvents if you haven't already, Sets everything up, injects all players
* @param pl Plugin instance
*/
public static void start(final Plugin pl) {
if (!hasLoaded) {
@@ -67,8 +93,7 @@ public final class PacketEvents implements PacketListener, Listener {
public static void stop() {
if (hasStarted) {
for (final Player p : Bukkit.getOnlinePlayers()) {
getAPI().getPlayerUtils().uninjectPlayerNow(p);
getAPI().getPlayerUtils().uninjectPlayer(p);
}
getAPI().getEventManager().unregisterAllListeners();
@@ -94,23 +119,23 @@ public final class PacketEvents implements PacketListener, Listener {
}
public static String getHandlerName(final String name) {
return "pe-" + getSettings().getIdentifier() + "-" + name;
return "pe-" + settings.getIdentifier() + "-" + name;
}
public static PacketEventsSettings getSettings() {
return settings;
}
@EventHandler
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onJoin(final PlayerJoinEvent e) {
getAPI().getPlayerUtils().injectPlayer(e.getPlayer());
getAPI().getPlayerUtils().setClientVersion(e.getPlayer(), ClientVersion.fromProtocolVersion(VersionLookupUtils.getProtocolVersion(e.getPlayer())));
getAPI().getPlayerUtils().setClientVersion(e.getPlayer(), ClientVersion.fromProtocolVersion((short) VersionLookupUtils.getProtocolVersion(e.getPlayer())));
}
@EventHandler
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onQuit(final PlayerQuitEvent e) {
getAPI().getPlayerUtils().clearClientVersion(e.getPlayer());
getAPI().getPlayerUtils().uninjectPlayerNow(e.getPlayer());
getAPI().getPlayerUtils().uninjectPlayer(e.getPlayer());
}
@EventHandler
@@ -119,4 +144,4 @@ public final class PacketEvents implements PacketListener, Listener {
getAPI().getEventManager().callEvent(moveEvent);
e.setCancelled(moveEvent.isCancelled());
}
}
}
@@ -0,0 +1,17 @@
/*
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* This annotation indicates that something might be unstable.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Beta {
}
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.annotations;
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.annotations;
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.annotations;
import io.github.retrooper.packetevents.enums.EventSynchronization;
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.api;
import io.github.retrooper.packetevents.event.manager.EventManager;
@@ -61,6 +64,4 @@ public final class PacketEventsAPI {
public EventManager getEventManager() {
return eventManager;
}
}
}
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.enums;
import io.github.retrooper.packetevents.PacketEvents;
@@ -62,7 +65,7 @@ public enum ClientVersion {
VERSION_LOOKUP.put(737, v_1_16_2);
}
public static ClientVersion fromProtocolVersion(int protocolVersion) {
public static ClientVersion fromProtocolVersion(short protocolVersion) {
if (protocolVersion == -1 && PacketEvents.getSettings().doAutoResolveClientProtocolVersion()) {
protocolVersion = ServerVersion.getVersion().toProtocolVersion();
}
@@ -76,8 +79,8 @@ public enum ClientVersion {
/**
* Returns if the client's version is more up to date than the argument passed version
*
* @param version
* @return
* @param version The version to compare to the client's value.
* @return True if the supplied version is lower, false if it is equal or higher than the client's version.
*/
public boolean isHigherThan(final ClientVersion version) {
if (this == version) return false;
@@ -87,8 +90,8 @@ public enum ClientVersion {
/**
* Returns if the client's version is more outdated than the argument passed version
*
* @param version
* @return
* @param version The version to compare to the client's value.
* @return True if the supplied version is higher, false if it is equal or lower than the client's version.
*/
public boolean isLowerThan(final ClientVersion version) {
if (this == version) return false;
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.enums;
public enum Direction {
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.enums;
public enum EventSynchronization {
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.enums;
import io.github.retrooper.packetevents.PacketEvents;
@@ -7,14 +10,22 @@ import org.bukkit.Bukkit;
* @author retrooper
*/
public enum ServerVersion {
v_1_7_10, v_1_8, v_1_8_3, v_1_8_8, v_1_9, v_1_9_4, v_1_10, v_1_11, v_1_12, v_1_13, v_1_13_2, v_1_14, v_1_15, v_1_16, v_1_16_1, v_1_16_2,
ERROR, EMPTY;
v_1_7_10, v_1_8, v_1_8_3, v_1_8_4, v_1_8_5, v_1_8_6, v_1_8_7, v_1_8_8,
v_1_9, v_1_9_2, v_1_9_4, v_1_10, v_1_10_2, v_1_11, v_1_11_1, v_1_11_2,
v_1_12, v_1_12_1, v_1_12_2, v_1_13, v_1_13_1, v_1_13_2, v_1_14, v_1_14_1,
v_1_14_2, v_1_14_3, v_1_14_4, v_1_15, v_1_15_1, v_1_15_2, v_1_16, v_1_16_1,
v_1_16_2, ERROR, EMPTY;
private static final String nmsVersionSuffix = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
public static ServerVersion[] reversedValues;
private static ServerVersion cachedVersion;
private static ServerVersion getVers() {
public static void load() {
reversedValues = ServerVersion.reverse(values());
}
private static ServerVersion getVersionNoCache() {
for (final ServerVersion val : reversedValues) {
String valName = val.name().substring(2).replace("_", ".");
if (Bukkit.getBukkitVersion().contains(valName)) {
@@ -28,7 +39,7 @@ public enum ServerVersion {
public static ServerVersion getVersion() {
if (cachedVersion == null) {
cachedVersion = getVers();
cachedVersion = getVersionNoCache();
}
return cachedVersion;
}
@@ -67,8 +78,8 @@ public enum ServerVersion {
/**
* Returns if the current version is more up to date than the argument passed version
*
* @param version
* @return
* @param version The version to compare to the server's value.
* @return True if the supplied version is lower, false if it is equal or higher than the server's version.
*/
public boolean isHigherThan(final ServerVersion version) {
if (this == version) return false;
@@ -78,8 +89,8 @@ public enum ServerVersion {
/**
* Returns if the current version is more outdated than the argument passed version
*
* @param version
* @return
* @param version The version to compare to the server's value.
* @return True if the supplied version is higher, false if it is equal or lower than the server's version.
*/
public boolean isLowerThan(final ServerVersion version) {
if (this == version) return false;
@@ -95,49 +106,73 @@ public enum ServerVersion {
return false;
}
public int toProtocolVersion() {
if (this.equals(ServerVersion.v_1_7_10)) {
return 5;
/**
* Converts the server version to a protocol version.
* Recommended to cache.
* @return protocol version
*/
public short toProtocolVersion() {
switch (this) {
case v_1_7_10:
return 5;
case v_1_8:
case v_1_8_3:
case v_1_8_4:
case v_1_8_5:
case v_1_8_6:
case v_1_8_7:
case v_1_8_8:
return 47;
case v_1_9:
return 107;
case v_1_9_2:
return 109;
case v_1_9_4:
return 110;
case v_1_10:
case v_1_10_2:
return 210;
case v_1_11:
return 315;
case v_1_11_1:
case v_1_11_2:
return 316;
case v_1_12:
return 335;
case v_1_12_1:
return 338;
case v_1_12_2:
return 340;
case v_1_13:
return 393;
case v_1_13_1:
return 401;
case v_1_13_2:
return 404;
case v_1_14:
return 477;
case v_1_14_1:
return 480;
case v_1_14_2:
return 485;
case v_1_14_3:
return 490;
case v_1_14_4:
return 498;
case v_1_15:
return 573;
case v_1_15_1:
return 575;
case v_1_15_2:
return 578;
case v_1_16:
return 735;
case v_1_16_1:
return 736;
case v_1_16_2:
return 751;
default:
return -1;
}
if (this.name().startsWith("v_1_8")) {
return 47;
}
if (this.equals(ServerVersion.v_1_9)) {
return 107;
}
if (this.equals(ServerVersion.v_1_9_4)) {
return 110;
}
if (this.equals(ServerVersion.v_1_10)) {
return 210;
}
if (this.equals(ServerVersion.v_1_11)) {
return 315;
}
if (this.equals(ServerVersion.v_1_12)) {
return 335;
}
if (this.equals(ServerVersion.v_1_13)) {
return 393;
}
if (this.equals(ServerVersion.v_1_13_2)) {
return 404;
}
if (this.equals(ServerVersion.v_1_14)) {
return 477;
}
if (this.equals(ServerVersion.v_1_15)) {
return 573;
}
if (this.equals(ServerVersion.v_1_16)) {
return 735;
}
if (this.equals(ServerVersion.v_1_16_1)) {
return 736;
}
if (this.equals(ServerVersion.v_1_16_2)) {
return 737;
}
return -1;
}
}
}
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.enums;
public enum SystemOS {
@@ -1,19 +0,0 @@
package io.github.retrooper.packetevents.enums.minecraft;
public enum EntityAnimationType {
SWING_MAIN_ARM, DAMAGE, LEAVE_BED, SWING_OFFHAND, CRITICAL_EFFECT, MAGIC_CRITICAL_EFFECT;
public static final EntityAnimationType get(final int i) {
return values()[i];
}
public final int getIndex() {
for (int i = 0; i < values().length; i++) {
final EntityAnimationType curType = values()[0];
if (curType == this) {
return i;
}
}
return -1;
}
}
@@ -1,9 +0,0 @@
package io.github.retrooper.packetevents.enums.minecraft;
public enum EntityUseAction {
INTERACT, INTERACT_AT, ATTACK, INVALID;
public static EntityUseAction get(final int i) {
return values()[i];
}
}
@@ -1,25 +0,0 @@
package io.github.retrooper.packetevents.enums.minecraft;
public enum Gamemode {
NOT_SET(-1, ""),
SURVIVAL(0, "survival"),
CREATIVE(1, "creative"),
ADVENTURE(2, "adventure"),
SPECTATOR(3, "spectator");
int f;
String g;
Gamemode(int var3, String var4) {
this.f = var3;
this.g = var4;
}
public int getId() {
return this.f;
}
public String b() {
return this.g;
}
}
@@ -1,6 +0,0 @@
package io.github.retrooper.packetevents.enums.minecraft;
public enum Hand {
MAIN_HAND,
OFF_HAND
}
@@ -1,59 +0,0 @@
package io.github.retrooper.packetevents.enums.minecraft;
public enum PlayerAction {
START_SNEAKING,
STOP_SNEAKING,
STOP_SLEEPING,
START_SPRINTING,
STOP_SPRINTING,
START_RIDING_JUMP,
STOP_RIDING_JUMP,
OPEN_INVENTORY,
START_FALL_FLYING;
public static PlayerAction get(final int i) {
return values()[i];
}
public int getIndex() {
for (int i = 0; i < values().length; i++) {
final PlayerAction action = values()[i];
if (action == this) {
return i;
}
}
return -1;
}
public enum UpdatedPlayerAction {
PRESS_SHIFT_KEY, RELEASE_SHIFT_KEY, STOP_SLEEPING, START_SPRINTING, STOP_SPRINTING, START_RIDING_JUMP, STOP_RIDING_JUMP, OPEN_INVENTORY, START_FALL_FLYING;
public static UpdatedPlayerAction get(final int index) {
for (int i = 0; i < index + 1; i++) {
final UpdatedPlayerAction action = values()[i];
if (i == index) {
return action;
}
}
return null;
}
public int getIndex() {
for (int i = 0; i < values().length; i++) {
final UpdatedPlayerAction action = values()[i];
if (action == this) {
return i;
}
}
return -1;
}
}
}
@@ -1,26 +0,0 @@
package io.github.retrooper.packetevents.enums.minecraft;
public enum PlayerDigType {
START_DESTROY_BLOCK,
ABORT_DESTROY_BLOCK,
STOP_DESTROY_BLOCK,
DROP_ALL_ITEMS,
DROP_ITEM,
RELEASE_USE_ITEM,
SWAP_HELD_ITEMS,
SWAP_ITEM_WITH_OFFHAND,
WRONG_PACKET;
public static PlayerDigType get(final int i) {
return values()[i];
}
}
@@ -1,8 +0,0 @@
package io.github.retrooper.packetevents.enums.minecraft;
public enum PlayerInfoAction {
ADD_PLAYER, UPDATE_GAME_MODE, UPDATE_LATENCY, UPDATE_DISPLAY_NAME, REMOVE_PLAYER;
PlayerInfoAction() {
}
}
@@ -1,16 +1,19 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.event;
import io.github.retrooper.packetevents.enums.ServerVersion;
public class PacketEvent {
protected static ServerVersion version = ServerVersion.getVersion();
public abstract class PacketEvent {
public static ServerVersion version;
private long timestamp = System.currentTimeMillis();
/**
* Timestamp of the packet
*
* @return
* @return timestamp in milliseconds
*/
public long getTimestamp() {
return timestamp;
@@ -19,4 +22,6 @@ public class PacketEvent {
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public abstract boolean isAsyncByDefault();
}
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.event;
public interface PacketListener {
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.event.impl;
import io.github.retrooper.packetevents.event.PacketEvent;
@@ -45,4 +48,9 @@ public final class BukkitMoveEvent extends PacketEvent {
public void cancel() {
setCancelled(true);
}
@Override
public boolean isAsyncByDefault() {
return false;
}
}
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.event.impl;
import io.github.retrooper.packetevents.event.PacketEvent;
@@ -17,7 +20,7 @@ public final class PacketReceiveEvent extends PacketEvent {
/**
* Get the player sending the packet
*
* @return
* @return player
*/
public Player getPlayer() {
return this.player;
@@ -25,7 +28,8 @@ public final class PacketReceiveEvent extends PacketEvent {
/**
* Get the packet's name (NMS packet class simple name).
* Deprecated, it is recommended not to use this for performance reasons.
* @deprecated It is recommended not to use this, it is an expensive method to call.
* @return Name of the packet
*/
@Deprecated
public String getPacketName() {
@@ -73,9 +77,14 @@ public final class PacketReceiveEvent extends PacketEvent {
/**
* Cancel the packet
*
* @param cancelled
* @param cancelled boolean
*/
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
@Override
public boolean isAsyncByDefault() {
return true;
}
}
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.event.impl;
import io.github.retrooper.packetevents.event.PacketEvent;
@@ -23,7 +26,8 @@ public final class PacketSendEvent extends PacketEvent {
/**
* Get the packet's name (NMS packet class simple name)
* Deprecated, it is recommended not to use this for performance reasons.
* @deprecated It is recommended not to use this, as it is an expensive function to call.
* @return Name of the packet
*/
@Deprecated
public String getPacketName() {
@@ -66,5 +70,10 @@ public final class PacketSendEvent extends PacketEvent {
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
@Override
public boolean isAsyncByDefault() {
return true;
}
}
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.event.impl;
import io.github.retrooper.packetevents.event.PacketEvent;
@@ -26,4 +29,9 @@ public final class PlayerInjectEvent extends PacketEvent {
public Player getPlayer() {
return player;
}
@Override
public boolean isAsyncByDefault() {
return false;
}
}
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.event.impl;
import io.github.retrooper.packetevents.event.PacketEvent;
@@ -47,4 +50,9 @@ public final class PlayerUninjectEvent extends PacketEvent {
public Player getPlayer() {
return player;
}
@Override
public boolean isAsyncByDefault() {
return false;
}
}
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.event.manager;
import io.github.retrooper.packetevents.PacketEvents;
@@ -1,15 +1,18 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.example;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.annotations.PacketHandler;
import io.github.retrooper.packetevents.enums.EventSynchronization;
import io.github.retrooper.packetevents.enums.ServerVersion;
import io.github.retrooper.packetevents.event.PacketListener;
import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent;
import io.github.retrooper.packetevents.event.impl.PacketSendEvent;
import io.github.retrooper.packetevents.packet.PacketType;
import io.github.retrooper.packetevents.packetwrappers.out.entity.WrappedPacketOutEntity;
import org.bukkit.entity.Entity;
import io.github.retrooper.packetevents.packetwrappers.in.useentity.WrappedPacketInUseEntity;
import io.github.retrooper.packetevents.packetwrappers.out.chat.WrappedPacketOutChat;
import org.bukkit.plugin.java.JavaPlugin;
public class MainExample extends JavaPlugin implements PacketListener {
@Override
@@ -19,15 +22,20 @@ public class MainExample extends JavaPlugin implements PacketListener {
@Override
public void onEnable() {
//Make sure you set a unique identifier, if another present plugin has the same identifier, you could run into issues
PacketEvents.getSettings().setIdentifier("official_api");
PacketEvents.getSettings().setDefaultServerVersion(ServerVersion.v_1_7_10);
//ClientVersion cannot be resolved, it is the same as the server's.
//The clientversion can only not be resolved if
// ViaVersion, ProtocolSuppport, or ProtocolLib isn't present.
//ClientVersion might be resolvable if the server version is 1.7.10.
PacketEvents.getSettings().setDoAutoResolveClientProtocolVersion(true);
//Deprecated, as it is no longer needed
//PacketEvents.getSettings().setIdentifier("packetevents_api");
PacketEvents.start(this);
//If PacketEvents cannot detect your server version, it will use the default you specify version
// getAPI().getSettings().setDefaultServerVersion(ServerVersion.v_1_7_10);
// PacketEvents.getAPI().getEventManager().registerListeners(this);
PacketEvents.getAPI().getEventManager().registerListener(this);
}
@Override
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.handler;
import io.github.retrooper.packetevents.PacketEvents;
@@ -32,15 +35,15 @@ public class NettyPacketHandler {
}
}
public static Future<?> uninjectPlayer(final Player player) {
public static Future<?> uninjectPlayerAsync(final Player player) {
try {
final PlayerUninjectEvent uninjectEvent = new PlayerUninjectEvent(player);
PacketEvents.getAPI().getEventManager().callEvent(uninjectEvent);
if (!uninjectEvent.isCancelled()) {
if (v1_7_nettyMode) {
return NettyPacketHandler_7.uninjectPlayer(player);
return NettyPacketHandler_7.uninjectPlayerAsync(player);
} else {
return NettyPacketHandler_8.uninjectPlayer(player);
return NettyPacketHandler_8.uninjectPlayerAsync(player);
}
}
} catch (Exception ignored) {
@@ -49,18 +52,19 @@ public class NettyPacketHandler {
return null;
}
public static void uninjectPlayerNow(final Player player) {
public static void uninjectPlayer(final Player player) {
try {
final PlayerUninjectEvent uninjectEvent = new PlayerUninjectEvent(player);
PacketEvents.getAPI().getEventManager().callEvent(uninjectEvent);
if (!uninjectEvent.isCancelled()) {
if (v1_7_nettyMode) {
NettyPacketHandler_7.uninjectPlayerNow(player);
NettyPacketHandler_7.uninjectPlayer(player);
} else {
NettyPacketHandler_8.uninjectPlayerNow(player);
NettyPacketHandler_8.uninjectPlayer(player);
}
}
} catch (Exception ignored) {
} catch (Exception ex) {
//Failed, but that is alright
}
}
@@ -81,6 +85,4 @@ public class NettyPacketHandler {
}
return null;
}
}
}
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.handler;
import io.github.retrooper.packetevents.PacketEvents;
@@ -33,15 +36,15 @@ final class NettyPacketHandler_7 {
pipeline.addBefore("packet_handler", PacketEvents.getHandlerName(player.getName()), channelDuplexHandler);
}
public static Future<?> uninjectPlayer(final Player player) {
public static void uninjectPlayer(final Player player) {
final Channel channel = (Channel) NMSUtils.getChannel(player);
channel.pipeline().remove(PacketEvents.getHandlerName(player.getName()));
}
public static Future<?> uninjectPlayerAsync(final Player player) {
final Channel channel = (Channel) NMSUtils.getChannel(player);
return channel.eventLoop().submit(() -> {
channel.pipeline().remove(PacketEvents.getHandlerName(player.getName()));
});
}
public static void uninjectPlayerNow(final Player player) {
final Channel channel = (Channel) NMSUtils.getChannel(player);
channel.pipeline().remove(PacketEvents.getHandlerName(player.getName()));
}
}
}
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.handler;
import io.github.retrooper.packetevents.PacketEvents;
@@ -33,15 +36,15 @@ final class NettyPacketHandler_8 {
pipeline.addBefore("packet_handler", PacketEvents.getHandlerName(player.getName()), channelDuplexHandler);
}
public static Future<?> uninjectPlayer(final Player player) {
public static void uninjectPlayer(final Player player) {
final Channel channel = (Channel) NMSUtils.getChannel(player);
channel.pipeline().remove(PacketEvents.getHandlerName(player.getName()));
}
public static Future<?> uninjectPlayerAsync(final Player player) {
final Channel channel = (Channel) NMSUtils.getChannel(player);
return channel.eventLoop().submit(() -> {
channel.pipeline().remove(PacketEvents.getHandlerName(player.getName()));
});
}
public static void uninjectPlayerNow(final Player player) {
final Channel channel = (Channel) NMSUtils.getChannel(player);
channel.pipeline().remove(PacketEvents.getHandlerName(player.getName()));
}
}
}
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packet;
import java.util.HashMap;
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packet;
import io.github.retrooper.packetevents.annotations.Nullable;
@@ -8,7 +11,8 @@ public class PacketTypeClasses {
public static class Client {
private static final String c = "PacketPlayIn";
@Nullable
public static final Class<?> FLYING = NMSUtils.getNMSClassWithoutException(c + "Flying");
public static Class<?> FLYING;
public static Class<?> POSITION, POSITION_LOOK, LOOK, CLIENT_COMMAND,
TRANSACTION, BLOCK_DIG, ENTITY_ACTION, USE_ENTITY,
WINDOW_CLICK, STEER_VEHICLE, CUSTOM_PAYLOAD, ARM_ANIMATION,
@@ -22,6 +26,7 @@ public class PacketTypeClasses {
SET_COMMAND_MINECART, SET_JIGSAW, STRUCT, UPDATE_SIGN, SPECTATE;
public static void load() {
FLYING = NMSUtils.getNMSClassWithoutException(c + "Flying");
try {
POSITION = NMSUtils.getNMSClass(c + "Position");
POSITION_LOOK = NMSUtils.getNMSClass(c + "PositionLook");
@@ -94,10 +99,8 @@ public class PacketTypeClasses {
}
}
PacketType.Client.init();
}
}
public static class Server {
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers;
public interface Sendable {
@@ -1,15 +1,44 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.api;
import io.github.retrooper.packetevents.enums.ServerVersion;
import io.github.retrooper.packetevents.packetwrappers.in.abilities.WrappedPacketInAbilities;
import io.github.retrooper.packetevents.packetwrappers.in.armanimation.WrappedPacketInArmAnimation;
import io.github.retrooper.packetevents.packetwrappers.in.blockdig.WrappedPacketInBlockDig;
import io.github.retrooper.packetevents.packetwrappers.in.blockplace.WrappedPacketInBlockPlace;
import io.github.retrooper.packetevents.packetwrappers.in.chat.WrappedPacketInChat;
import io.github.retrooper.packetevents.packetwrappers.in.clientcommand.WrappedPacketInClientCommand;
import io.github.retrooper.packetevents.packetwrappers.in.custompayload.WrappedPacketInCustomPayload;
import io.github.retrooper.packetevents.packetwrappers.in.entityaction.WrappedPacketInEntityAction;
import io.github.retrooper.packetevents.packetwrappers.in.flying.WrappedPacketInFlying;
import io.github.retrooper.packetevents.packetwrappers.in.helditemslot.WrappedPacketInHeldItemSlot;
import io.github.retrooper.packetevents.packetwrappers.in.keepalive.WrappedPacketInKeepAlive;
import io.github.retrooper.packetevents.packetwrappers.in.settings.WrappedPacketInSettings;
import io.github.retrooper.packetevents.packetwrappers.in.steervehicle.WrappedPacketInSteerVehicle;
import io.github.retrooper.packetevents.packetwrappers.in.transaction.WrappedPacketInTransaction;
import io.github.retrooper.packetevents.packetwrappers.in.useentity.WrappedPacketInUseEntity;
import io.github.retrooper.packetevents.packetwrappers.in.windowclick.WrappedPacketInWindowClick;
import io.github.retrooper.packetevents.packetwrappers.out.abilities.WrappedPacketOutAbilities;
import io.github.retrooper.packetevents.packetwrappers.out.animation.WrappedPacketOutAnimation;
import io.github.retrooper.packetevents.packetwrappers.out.chat.WrappedPacketOutChat;
import io.github.retrooper.packetevents.packetwrappers.out.entity.WrappedPacketOutEntity;
import io.github.retrooper.packetevents.packetwrappers.out.entityvelocity.WrappedPacketOutEntityVelocity;
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;
import io.github.retrooper.packetevents.packetwrappers.out.transaction.WrappedPacketOutTransaction;
import io.github.retrooper.packetevents.packetwrappers.out.updatehealth.WrappedPacketOutUpdateHealth;
import org.bukkit.entity.Player;
public class WrappedPacket {
protected static ServerVersion version = ServerVersion.getVersion();
public static ServerVersion version = null;
protected final Player player;
protected Object packet;
public WrappedPacket() {
this.player= null;
this.player = null;
this.packet = null;
}
@@ -35,6 +64,37 @@ public class WrappedPacket {
}
}
public static void loadAllWrappers() {
//SERVER BOUND
WrappedPacketInAbilities.load();
WrappedPacketInArmAnimation.load();
WrappedPacketInBlockDig.load();
WrappedPacketInBlockPlace.load();
WrappedPacketInChat.load();
WrappedPacketInClientCommand.load();
WrappedPacketInCustomPayload.load();
WrappedPacketInEntityAction.load();
WrappedPacketInFlying.load();
WrappedPacketInHeldItemSlot.load();
WrappedPacketInKeepAlive.load();
WrappedPacketInSettings.load();
WrappedPacketInSteerVehicle.load();
WrappedPacketInTransaction.load();
WrappedPacketInUseEntity.load();
WrappedPacketInWindowClick.load();
//CLIENTBOUND
WrappedPacketOutAbilities.load();
WrappedPacketOutAnimation.load();
WrappedPacketOutChat.load();
WrappedPacketOutEntity.load();
WrappedPacketOutEntityVelocity.load();
WrappedPacketOutKeepAlive.load();
WrappedPacketOutKickDisconnect.load();
WrappedPacketOutPosition.load();
WrappedPacketOutTransaction.load();
WrappedPacketOutUpdateHealth.load();
}
protected void setup() {
@@ -1,47 +1,57 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.in.abilities;
import io.github.retrooper.packetevents.annotations.Nullable;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
import io.github.retrooper.packetevents.utils.NMSUtils;
public final class WrappedPacketInAbilities extends WrappedPacket {
private static Class<?> abilitiesClass;
static {
try {
abilitiesClass = NMSUtils.getNMSClass("PacketPlayInAbilities");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private static boolean isMoreThanOneBoolPresent;
private boolean isVulnerable;
private boolean isFlying;
private boolean allowFly;
private boolean instantBuild;
private float flySpeed;
private float walkSpeed;
public WrappedPacketInAbilities(Object packet) {
super(packet);
}
public static void load() {
abilitiesClass = PacketTypeClasses.Client.ABILITIES;
isMoreThanOneBoolPresent = Reflection.getField(abilitiesClass, boolean.class, 1) != null;
}
@Override
protected void setup() {
try {
this.isVulnerable = Reflection.getField(abilitiesClass, boolean.class, 0).getBoolean(packet);
this.isFlying = Reflection.getField(abilitiesClass, boolean.class, 1).getBoolean(packet);
this.allowFly = Reflection.getField(abilitiesClass, boolean.class, 2).getBoolean(packet);
this.instantBuild = Reflection.getField(abilitiesClass, boolean.class, 3).getBoolean(packet);
this.flySpeed = Reflection.getField(abilitiesClass, float.class, 0).getFloat(packet);
this.walkSpeed = Reflection.getField(abilitiesClass, float.class, 1).getFloat(packet);
if (isMoreThanOneBoolPresent) {
this.isVulnerable = Reflection.getField(abilitiesClass, boolean.class, 0).getBoolean(packet);
this.isFlying = Reflection.getField(abilitiesClass, boolean.class, 1).getBoolean(packet);
this.allowFly = Reflection.getField(abilitiesClass, boolean.class, 2).getBoolean(packet);
this.instantBuild = Reflection.getField(abilitiesClass, boolean.class, 3).getBoolean(packet);
this.flySpeed = Reflection.getField(abilitiesClass, float.class, 0).getFloat(packet);
this.walkSpeed = Reflection.getField(abilitiesClass, float.class, 1).getFloat(packet);
} else {
this.isFlying = Reflection.getField(abilitiesClass, boolean.class, 0).getBoolean(packet);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
public boolean isVulnerable() {
/**
* This will return null if the server version is not available in 1.16.x and above
*
* @return Whether the player is vulnerable to damage or not.
*/
@Deprecated
@Nullable
public Boolean isVulnerable() {
return isVulnerable;
}
@@ -49,19 +59,47 @@ public final class WrappedPacketInAbilities extends WrappedPacket {
return isFlying;
}
public boolean isFlightAllowed() {
/**
* This will return null if the server version is not available in 1.16.x and above
*
* @return Whether or not the player can fly.
*/
@Deprecated
@Nullable
public Boolean isFlightAllowed() {
return allowFly;
}
public boolean canInstantlyBuild() {
/**
* This will return null if the server version is not available in 1.16.x and above
*
* @return Whether or not the player can break blocks instantly.
*/
@Deprecated
@Nullable
public Boolean canInstantlyBuild() {
return instantBuild;
}
public float getFlySpeed() {
/**
* This will return null if the server version is not available in 1.16.x and above
*
* @return The speed at which the player can fly, as a float.
*/
@Deprecated
@Nullable
public Float getFlySpeed() {
return flySpeed;
}
public float getWalkSpeed() {
/**
* This will return null if the server version is not available in 1.16.x and above
*
* @return The speed at which the player can walk, as a float.
*/
@Deprecated
@Nullable
public Float getWalkSpeed() {
return walkSpeed;
}
}
@@ -1,35 +1,26 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.in.armanimation;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.utils.NMSUtils;
//TODO: Test on 1.9, 1.11, 1.13, 1.14
@Deprecated
public final class WrappedPacketInArmAnimation extends WrappedPacket {
private static Class<?> packetClass;
static {
try {
packetClass = NMSUtils.getNMSClass("PacketPlayInArmAnimation");
} catch (Exception e) {
e.printStackTrace();
}
}
private long timeStamp;
public WrappedPacketInArmAnimation(Object packet) {
super(packet);
}
@Override
public void setup() {
//Lazy way, do you really need to get the timestamp in the actual class? Edit by Retrooper: Yes lol
//TODO: Get EnumHand value sent in 1.9+, however not really necessary
timeStamp = System.currentTimeMillis();
public static void load() {
packetClass = PacketTypeClasses.Client.ARM_ANIMATION;
}
public long getTimestamp() {
return timeStamp;
@Override
public void setup() {
}
}
@@ -1,8 +1,11 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.in.blockdig;
import io.github.retrooper.packetevents.enums.Direction;
import io.github.retrooper.packetevents.enums.ServerVersion;
import io.github.retrooper.packetevents.enums.minecraft.PlayerDigType;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
import io.github.retrooper.packetevents.utils.NMSUtils;
@@ -10,11 +13,17 @@ import io.github.retrooper.packetevents.utils.vector.Vector3i;
public final class WrappedPacketInBlockDig extends WrappedPacket {
private static Class<?> blockDigClass, blockPositionClass, enumDirectionClass, digTypeClass;
private static boolean isVersionLowerThan_v_1_8;
private Vector3i blockPosition;
private Direction direction;
private PlayerDigType digType;
public WrappedPacketInBlockDig(Object packet) {
super(packet);
}
static {
public static void load() {
blockDigClass = PacketTypeClasses.Client.BLOCK_DIG;
try {
blockDigClass = NMSUtils.getNMSClass("PacketPlayInBlockDig");
if (version.isHigherThan(ServerVersion.v_1_7_10)) {
blockPositionClass = NMSUtils.getNMSClass("BlockPosition");
enumDirectionClass = NMSUtils.getNMSClass("EnumDirection");
@@ -22,8 +31,9 @@ public final class WrappedPacketInBlockDig extends WrappedPacket {
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
isVersionLowerThan_v_1_8 = version.isLowerThan(ServerVersion.v_1_8);
if (version.isHigherThan(ServerVersion.v_1_7_10)) {
if (version != ServerVersion.v_1_7_10) {
try {
digTypeClass = NMSUtils.getNMSClass("EnumPlayerDigType");
} catch (ClassNotFoundException e) {
@@ -33,14 +43,6 @@ public final class WrappedPacketInBlockDig extends WrappedPacket {
}
}
private Vector3i blockPosition;
private Direction direction;
private PlayerDigType digType;
public WrappedPacketInBlockDig(Object packet) {
super(packet);
}
@Override
protected void setup() {
Direction enumDirection = null;
@@ -48,8 +50,8 @@ public final class WrappedPacketInBlockDig extends WrappedPacket {
int x = 0, y = 0, z = 0;
//1.7.10
try {
if (version.isLowerThan(ServerVersion.v_1_8)) {
enumDigType = PlayerDigType.get(Reflection.getField(blockDigClass, int.class, 4).getInt(packet));
if (isVersionLowerThan_v_1_8) {
enumDigType = PlayerDigType.values()[(Reflection.getField(blockDigClass, int.class, 4).getInt(packet))];
x = Reflection.getField(blockDigClass, int.class, 0).getInt(packet);
y = Reflection.getField(blockDigClass, int.class, 1).getInt(packet);
z = Reflection.getField(blockDigClass, int.class, 2).getInt(packet);
@@ -92,5 +94,26 @@ public final class WrappedPacketInBlockDig extends WrappedPacket {
return digType;
}
public enum PlayerDigType {
START_DESTROY_BLOCK,
ABORT_DESTROY_BLOCK,
STOP_DESTROY_BLOCK,
DROP_ALL_ITEMS,
DROP_ITEM,
RELEASE_USE_ITEM,
SWAP_HELD_ITEMS,
SWAP_ITEM_WITH_OFFHAND,
WRONG_PACKET
}
}
@@ -1,5 +1,9 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.in.blockplace;
import io.github.retrooper.packetevents.annotations.Nullable;
import io.github.retrooper.packetevents.enums.ServerVersion;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.utils.vector.Vector3i;
@@ -9,38 +13,40 @@ import org.bukkit.inventory.ItemStack;
public final class WrappedPacketInBlockPlace extends WrappedPacket {
static {
if (version.isHigherThan(ServerVersion.v_1_7_10)) {
WrappedPacketInBlockPlace_1_8.initStatic();
}
}
private static boolean isHigherThan_v_1_8_8, isHigherThan_v_1_7_10;
private Vector3i blockPosition;
private ItemStack itemStack;
public WrappedPacketInBlockPlace(final Player player, final Object packet) {
super(player, 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();
}
}
@Override
protected void setup() {
//1.7.10
Vector3i position = null;
ItemStack itemStack = null;
try {
if (version.isHigherThan(ServerVersion.v_1_8_8)) {
if (isHigherThan_v_1_8_8) {
final WrappedPacketInBlockPlace_1_9 blockPlace_1_9 = new WrappedPacketInBlockPlace_1_9(getPlayer(), packet);
final Block block = blockPlace_1_9.getBlock();
position = new Vector3i(block.getX(), block.getY(), block.getZ());
itemStack = new ItemStack(block.getType());
} else if (version.isHigherThan(ServerVersion.v_1_7_10)) {
} else if (isHigherThan_v_1_7_10) {
final WrappedPacketInBlockPlace_1_8 blockPlace_1_8 = new WrappedPacketInBlockPlace_1_8(packet);
position = blockPlace_1_8.getBlockPosition();
itemStack = blockPlace_1_8.getItemStack();
} else {
final WrappedPacketInBlockPlace_1_7_10 blockPlace_1_7_10 = new WrappedPacketInBlockPlace_1_7_10(getPlayer(), packet);
position = blockPlace_1_7_10.getBlockPosition();
this.itemStack = blockPlace_1_7_10.getItemStack();
itemStack = blockPlace_1_7_10.getItemStack();
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
@@ -57,6 +63,7 @@ public final class WrappedPacketInBlockPlace extends WrappedPacket {
return blockPosition;
}
@Nullable
public ItemStack getItemStack() {
return itemStack;
}
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.in.blockplace;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
@@ -1,5 +1,9 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.in.blockplace;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
import io.github.retrooper.packetevents.utils.NMSUtils;
@@ -9,7 +13,7 @@ import org.bukkit.inventory.ItemStack;
import java.lang.reflect.InvocationTargetException;
final class WrappedPacketInBlockPlace_1_8 extends WrappedPacket {
private static Class<?> blockPlaceClass, blockPositionClass;
private static Class<?> blockPlaceClass, blockPositionClass, blockPositionSuperClass;
private Vector3i blockPosition;
private ItemStack itemStack;
@@ -17,28 +21,25 @@ final class WrappedPacketInBlockPlace_1_8 extends WrappedPacket {
super(packet);
}
protected static void initStatic() {
protected static void load() {
blockPlaceClass = PacketTypeClasses.Client.BLOCK_PLACE;
try {
blockPlaceClass = NMSUtils.getNMSClass("PacketPlayInBlockPlace");
blockPositionClass = NMSUtils.getNMSClass("BlockPosition");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
blockPositionSuperClass = blockPositionClass.getSuperclass();
}
@Override
protected void setup() {
try {
Object nmsBlockPos = Reflection.getField(blockPlaceClass, blockPositionClass, 1).get(packet);
this.blockPosition = new Vector3i(0, 0, 0);
this.blockPosition.x = (int) Reflection.getMethod(blockPositionSuperClass, "getX", 0).invoke(nmsBlockPos);
this.blockPosition.y = (int) Reflection.getMethod(blockPositionSuperClass, "getY", 0).invoke(nmsBlockPos);
this.blockPosition.z = (int) Reflection.getMethod(blockPositionSuperClass, "getZ", 0).invoke(nmsBlockPos);
final int[] coords = new int[3];
for (int i = 0; i < 3; i++) {
final String s = "get" + (i == 0 ? "X" : i == 1 ? "Y" : "Z");
coords[i] = (int) Reflection.getMethod(blockPositionClass.getSuperclass(), s, 0).invoke(nmsBlockPos);
}
this.blockPosition = new Vector3i(coords[0], coords[1], coords[2]);
this.itemStack = NMSUtils.toBukkitItemStack(Reflection.getField(blockPlaceClass, NMSUtils.nmsItemStackClass, 0).get(packet));
} catch (IllegalAccessException | InvocationTargetException e) {
@@ -46,10 +47,23 @@ final class WrappedPacketInBlockPlace_1_8 extends WrappedPacket {
}
}
@Deprecated
public Vector3i getBlockPosition() {
return blockPosition;
}
public int getBlockPositionX() {
return blockPosition.x;
}
public int getBlockPositionY() {
return blockPosition.y;
}
public int getBlockPositionZ() {
return blockPosition.z;
}
public ItemStack getItemStack() {
return itemStack;
}
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.in.blockplace;
@@ -1,26 +1,23 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.in.chat;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
import io.github.retrooper.packetevents.utils.NMSUtils;
public final class WrappedPacketInChat extends WrappedPacket {
private static Class<?> chatPacketClass;
static {
try {
chatPacketClass = NMSUtils.getNMSClass("PacketPlayInChat");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private String message;
public WrappedPacketInChat(Object packet) {
super(packet);
}
public static void load() {
chatPacketClass = PacketTypeClasses.Client.CHAT;
}
@Override
protected void setup() {
@@ -1,7 +1,11 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.in.clientcommand;
import io.github.retrooper.packetevents.annotations.Nullable;
import io.github.retrooper.packetevents.enums.ServerVersion;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
import io.github.retrooper.packetevents.utils.NMSUtils;
@@ -12,9 +16,18 @@ public final class WrappedPacketInClientCommand extends WrappedPacket {
@Nullable
private static Class<?> enumClientCommandClass;
static {
private static boolean isLowerThan_v_1_8;
private ClientCommand clientCommand;
public WrappedPacketInClientCommand(Object packet) {
super(packet);
}
public static void load() {
packetClass = PacketTypeClasses.Client.CLIENT_COMMAND;
isLowerThan_v_1_8 = version.isLowerThan(ServerVersion.v_1_8);
try {
packetClass = NMSUtils.getNMSClass("PacketPlayInClientCommand");
if (version.isHigherThan(ServerVersion.v_1_7_10)) {
enumClientCommandClass = Reflection.getSubClass(packetClass, "EnumClientCommand");
} else {
@@ -25,21 +38,11 @@ public final class WrappedPacketInClientCommand extends WrappedPacket {
}
}
private ClientCommand clientCommand;
public WrappedPacketInClientCommand(Object packet) {
super(packet);
}
@Override
public void setup() {
try {
if (version.isLowerThan(ServerVersion.v_1_8)) {
clientCommand = ClientCommand.values()[(Reflection.getField(enumClientCommandClass, int.class, 1).getInt(packet))];
} else {
final Object enumObj = Reflection.getField(packetClass, enumClientCommandClass, 0).get(packet);
this.clientCommand = ClientCommand.valueOf(enumObj.toString());
}
Object enumObj = Reflection.getField(packetClass, enumClientCommandClass, 0).get(packet);
this.clientCommand = ClientCommand.valueOf(enumObj.toString());
} catch (Exception e) {
e.printStackTrace();
}
@@ -52,7 +55,7 @@ public final class WrappedPacketInClientCommand extends WrappedPacket {
public enum ClientCommand {
PERFORM_RESPAWN,
REQUEST_STATS,
OPEN_INVENTORY_ACHIEVEMENT;
OPEN_INVENTORY_ACHIEVEMENT
}
}
@@ -1,50 +1,64 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.in.custompayload;
import io.github.retrooper.packetevents.annotations.Nullable;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
import io.github.retrooper.packetevents.utils.NMSUtils;
import java.lang.reflect.Field;
public final class WrappedPacketInCustomPayload extends WrappedPacket {
private static Class<?> packetClass, nmsMinecraftKey, nmsPacketDataSerializer;
static {
private static boolean strPresentInIndex0;
private String data;
private Object minecraftKey, dataSerializer;
public WrappedPacketInCustomPayload(Object packet) {
super(packet);
}
public static void load() {
packetClass = PacketTypeClasses.Client.CUSTOM_PAYLOAD;
strPresentInIndex0 = Reflection.getField(packetClass, String.class, 0) != null;
try {
packetClass = NMSUtils.getNMSClass("PacketPlayInCustomPayload");
nmsPacketDataSerializer = NMSUtils.getNMSClass("PacketDataSerializer");
} catch (Exception e) {
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
//Only on 1.13+
nmsMinecraftKey = NMSUtils.getNMSClass("MinecraftKey");
} catch (Exception e) {
} catch (ClassNotFoundException e) {
//Its okay, this means they are on versions 1.7.10 ~ 1.12.2
}
}
private String data;
private Object minecraftKey, dataSerializer;
public WrappedPacketInCustomPayload(Object packet) {
super(packet);
}
@Override
public void setup() {
if (Reflection.getField(packetClass, String.class, 0) == null) {
if (!strPresentInIndex0) {
try {
this.minecraftKey = Reflection.getField(packetClass, nmsMinecraftKey, 0).get(packet);
this.dataSerializer = Reflection.getField(packetClass, nmsPacketDataSerializer, 0).get(packet);
} catch (Exception e) {
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} else {
Field dataSerializerField = Reflection.getField(packetClass, nmsPacketDataSerializer, 0);
try {
this.data = (String) Reflection.getField(packetClass, String.class, 0).get(packet);
this.dataSerializer = Reflection.getField(packetClass, nmsPacketDataSerializer, 0).get(packet);
} catch (Exception e) {
//intentionally empty, allegedly 1.7.10 produces a NPE?
if (dataSerializerField != null) {
this.dataSerializer = dataSerializerField.get(packet);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
@@ -56,6 +70,7 @@ public final class WrappedPacketInCustomPayload extends WrappedPacket {
return minecraftKey;
}
@Nullable
public Object getDataSerializer() {
return dataSerializer;
}
@@ -1,80 +1,89 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.in.entityaction;
import io.github.retrooper.packetevents.annotations.Nullable;
import io.github.retrooper.packetevents.enums.ServerVersion;
import io.github.retrooper.packetevents.enums.minecraft.PlayerAction;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
import io.github.retrooper.packetevents.utils.NMSUtils;
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 Class<?> entityActionClass;
@Nullable
private static Class<?> enumPlayerActionClass;
static {
try {
entityActionClass = NMSUtils.getNMSClass("PacketPlayInEntityAction");
if (version.isHigherThan(ServerVersion.v_1_7_10)) {
enumPlayerActionClass = Reflection.getSubClass(entityActionClass, "EnumPlayerAction");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private static boolean isLowerThan_v_1_8;
private Entity entity;
private int entityId;
private PlayerAction action;
private int jumpBoost;
public WrappedPacketInEntityAction(final Object packet) {
super(packet);
}
public static void load() {
entityActionClass = PacketTypeClasses.Client.ENTITY_ACTION;
isLowerThan_v_1_8 = version.isLowerThan(ServerVersion.v_1_8);
if (version.isHigherThan(ServerVersion.v_1_7_10)) {
enumPlayerActionClass = Reflection.getSubClass(entityActionClass, "EnumPlayerAction");
}
//All the already existing values
for (PlayerAction val : PlayerAction.values()) {
cachedPlayerActionNames.put(val.name(), val);
}
cachedPlayerActionNames.put("PRESS_SHIFT_KEY", PlayerAction.START_SNEAKING);
cachedPlayerActionNames.put("RELEASE_SHIFT_KEY", PlayerAction.STOP_SNEAKING);
cachedPlayerActionNames.put("RIDING_JUMP", PlayerAction.START_RIDING_JUMP);
cachedPlayerActionIDs.put(1, PlayerAction.START_SNEAKING);
cachedPlayerActionIDs.put(2, PlayerAction.STOP_SNEAKING);
cachedPlayerActionIDs.put(3, PlayerAction.STOP_SLEEPING);
cachedPlayerActionIDs.put(4, PlayerAction.START_SPRINTING);
cachedPlayerActionIDs.put(5, PlayerAction.STOP_SPRINTING);
cachedPlayerActionIDs.put(6, PlayerAction.START_RIDING_JUMP); //riding jump
cachedPlayerActionIDs.put(7, PlayerAction.OPEN_INVENTORY); //horse interaction
}
@Override
protected void setup() {
try {
final int entityId = Reflection.getField(entityActionClass, int.class, 0).getInt(packet);
final int jumpBoost;
if (version.isLowerThan(ServerVersion.v_1_8)) {
if (isLowerThan_v_1_8) {
jumpBoost = Reflection.getField(entityActionClass, int.class, 2).getInt(packet);
} else {
jumpBoost = Reflection.getField(entityActionClass, int.class, 1).getInt(packet);
}
int animationIndex = -1;
//1.7.10
if (version.isLowerThan(ServerVersion.v_1_8)) {
animationIndex = Reflection.getField(entityActionClass, int.class, 1).getInt(packet); // TODO: += if packetdataserializer.version < 16
if (isLowerThan_v_1_8) {
int animationIndex = Reflection.getField(entityActionClass, int.class, 1).getInt(packet); // TODO: += if packetdataserializer.version < 16
this.action = cachedPlayerActionIDs.get(animationIndex);
} else {
final Object enumObj = Reflection.getField(entityActionClass, enumPlayerActionClass, 0).get(packet);
final String enumValue = enumObj.toString();
try {
this.action = PlayerAction.valueOf(enumValue);
} catch (IllegalArgumentException e) {
//They aren't on a legacy version and the enum has changed
final PlayerAction.UpdatedPlayerAction updatedPlayerAction = PlayerAction.UpdatedPlayerAction.valueOf(enumValue);
this.action = PlayerAction.get(updatedPlayerAction.getIndex());
}
final String enumName = enumObj.toString();
this.action = cachedPlayerActionNames.get(enumName);
}
this.entityId = entityId;
this.jumpBoost = jumpBoost;
if (animationIndex != -1) {
this.action = PlayerAction.get(animationIndex);
}
this.entity = NMSUtils.getEntityById(this.entityId);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
public Entity getEntity() {
return entity;
return NMSUtils.getEntityById(this.entityId);
}
public int getEntityId() {
@@ -88,4 +97,17 @@ public final class WrappedPacketInEntityAction extends WrappedPacket {
public int getJumpBoost() {
return jumpBoost;
}
public enum PlayerAction {
START_SNEAKING,
STOP_SNEAKING,
STOP_SLEEPING,
START_SPRINTING,
STOP_SPRINTING,
START_RIDING_JUMP,
STOP_RIDING_JUMP,
OPEN_INVENTORY,
START_FALL_FLYING
}
}
@@ -1,35 +1,31 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.in.flying;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
import io.github.retrooper.packetevents.utils.NMSUtils;
public class WrappedPacketInFlying extends WrappedPacket {
private static Class<?> flyingClass;
static {
try {
flyingClass = NMSUtils.getNMSClass("PacketPlayInFlying");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private double x;
private double y;
private double z;
private float yaw;
private float pitch;
private boolean onGround;
private boolean isPosition;
private boolean isLook;
protected double x;
protected double y;
protected double z;
protected float yaw;
protected float pitch;
protected boolean onGround;
protected boolean isPosition;
protected boolean isLook;
public WrappedPacketInFlying(Object packet) {
super(packet);
}
public static void load() {
flyingClass = PacketTypeClasses.Client.FLYING;
}
@Override
protected void setup() {
try {
@@ -74,63 +70,63 @@ public class WrappedPacketInFlying extends WrappedPacket {
return onGround;
}
public boolean isPosition() {
public final boolean isPosition() {
return isPosition;
}
public boolean isLook() {
public final boolean isLook() {
return isLook;
}
public static class WrappedPacketInPosition extends WrappedPacketInFlying {
public WrappedPacketInPosition(Object packet) {
super(packet);
}
@Override
public boolean isPosition() {
protected void setup() {
try {
return Reflection.getField(flyingClass, boolean.class, 1).getBoolean(packet);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return true;
}
this.x = Reflection.getField(flyingClass, double.class, 0).getDouble(packet);
this.y = Reflection.getField(flyingClass, double.class, 1).getDouble(packet);
this.z = Reflection.getField(flyingClass, double.class, 2).getDouble(packet);
@Override
public boolean isLook() {
try {
return Reflection.getField(flyingClass, boolean.class, 2).getBoolean(packet);
this.yaw = Reflection.getField(flyingClass, float.class, 0).getFloat(packet);
this.pitch = Reflection.getField(flyingClass, float.class, 1).getFloat(packet);
this.onGround = Reflection.getField(flyingClass, boolean.class, 0).getBoolean(packet);
this.isPosition = Reflection.getField(flyingClass, boolean.class, 1).getBoolean(packet);
this.isLook = Reflection.getField(flyingClass, boolean.class, 2).getBoolean(packet);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return false;
}
}
public static class WrappedPacketInPosition_Look extends WrappedPacketInFlying {
public WrappedPacketInPosition_Look(Object packet) {
super(packet);
}
@Override
public boolean isPosition() {
protected void setup() {
try {
return Reflection.getField(flyingClass, boolean.class, 1).getBoolean(packet);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return true;
}
this.x = Reflection.getField(flyingClass, double.class, 0).getDouble(packet);
this.y = Reflection.getField(flyingClass, double.class, 1).getDouble(packet);
this.z = Reflection.getField(flyingClass, double.class, 2).getDouble(packet);
@Override
public boolean isLook() {
try {
return Reflection.getField(flyingClass, boolean.class, 2).getBoolean(packet);
this.yaw = Reflection.getField(flyingClass, float.class, 0).getFloat(packet);
this.pitch = Reflection.getField(flyingClass, float.class, 1).getFloat(packet);
this.onGround = Reflection.getField(flyingClass, boolean.class, 0).getBoolean(packet);
this.isPosition = Reflection.getField(flyingClass, boolean.class, 1).getBoolean(packet);
this.isLook = Reflection.getField(flyingClass, boolean.class, 2).getBoolean(packet);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return true;
}
}
@@ -141,23 +137,22 @@ public class WrappedPacketInFlying extends WrappedPacket {
}
@Override
public boolean isPosition() {
protected void setup() {
try {
return Reflection.getField(flyingClass, boolean.class, 1).getBoolean(packet);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return false;
}
this.x = Reflection.getField(flyingClass, double.class, 0).getDouble(packet);
this.y = Reflection.getField(flyingClass, double.class, 1).getDouble(packet);
this.z = Reflection.getField(flyingClass, double.class, 2).getDouble(packet);
@Override
public boolean isLook() {
try {
return Reflection.getField(flyingClass, boolean.class, 2).getBoolean(packet);
this.yaw = Reflection.getField(flyingClass, float.class, 0).getFloat(packet);
this.pitch = Reflection.getField(flyingClass, float.class, 1).getFloat(packet);
this.onGround = Reflection.getField(flyingClass, boolean.class, 0).getBoolean(packet);
this.isPosition = Reflection.getField(flyingClass, boolean.class, 1).getBoolean(packet);
this.isLook = Reflection.getField(flyingClass, boolean.class, 2).getBoolean(packet);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return true;
}
}
@@ -1,26 +1,24 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.in.helditemslot;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
import io.github.retrooper.packetevents.utils.NMSUtils;
public final class WrappedPacketInHeldItemSlot extends WrappedPacket {
private static Class<?> packetClass;
static {
try {
packetClass = NMSUtils.getNMSClass("PacketPlayInHeldItemSlot");
} catch (Exception e) {
e.printStackTrace();
}
}
private int itemInHandIndex;
public WrappedPacketInHeldItemSlot(Object packet) {
super(packet);
}
public static void load() {
packetClass = PacketTypeClasses.Client.HELD_ITEM_SLOT;
}
@Override
public void setup() {
try {
@@ -1,29 +1,29 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.in.keepalive;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
import io.github.retrooper.packetevents.utils.NMSUtils;
public final class WrappedPacketInKeepAlive extends WrappedPacket {
private static Class<?> packetClass;
static {
try {
packetClass = NMSUtils.getNMSClass("PacketPlayInKeepAlive");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private static boolean integerPresentInIndex0;
private long id;
public WrappedPacketInKeepAlive(final Object packet) {
super(packet);
}
public static void load() {
packetClass = PacketTypeClasses.Client.KEEP_ALIVE;
integerPresentInIndex0 = Reflection.getField(packetClass, int.class, 0) != null;
}
@Override
protected void setup() {
if (Reflection.getField(packetClass, int.class, 0) == null) {
if (!integerPresentInIndex0) {
try {
this.id = Reflection.getField(packetClass, long.class, 0).getLong(packet);
} catch (IllegalAccessException e) {
@@ -39,8 +39,8 @@ public final class WrappedPacketInKeepAlive extends WrappedPacket {
}
/**
* Optionally Cast this long to an integer if you are using 1.7.10->1.12.2!
* In 1.13.2->1.16.1 a long is sent
* Optionally Cast this long to an integer if you are using 1.7.10 -&gt; 1.12.2!
* In 1.13.2 -&gt; 1.16.1 a long is sent
*
* @return response is
*/
@@ -1,7 +1,11 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.in.settings;
import io.github.retrooper.packetevents.annotations.Nullable;
import io.github.retrooper.packetevents.enums.ServerVersion;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
import io.github.retrooper.packetevents.utils.NMSUtils;
@@ -12,12 +16,20 @@ public class WrappedPacketInSettings extends WrappedPacket {
private static Class<?> packetClass;
private static Class<?> chatVisibilityEnumClass;
static {
try {
packetClass = NMSUtils.getNMSClass("PacketPlayInSettings");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
private static boolean isLowerThan_v_1_8;
private String locale;
private byte viewDistance;
private ChatVisibility chatVisibility;
private boolean chatColors;
private HashMap<DisplayedSkinPart, Boolean> displayedSkinParts;
public WrappedPacketInSettings(final Object packet) {
super(packet);
}
public static void load() {
packetClass = PacketTypeClasses.Client.SETTINGS;
isLowerThan_v_1_8 = version.isLowerThan(ServerVersion.v_1_8);
try {
chatVisibilityEnumClass = NMSUtils.getNMSClass("EnumChatVisibility");
@@ -28,15 +40,6 @@ public class WrappedPacketInSettings extends WrappedPacket {
}
}
private String locale;
private byte viewDistance;
private ChatVisibility chatVisibility;
private boolean chatColors;
private HashMap<DisplayedSkinPart, Boolean> displayedSkinParts;
public WrappedPacketInSettings(final Object packet) {
super(packet);
}
public static Class<?> getChatVisibilityEnumClass() {
return chatVisibilityEnumClass;
}
@@ -66,7 +69,7 @@ public class WrappedPacketInSettings extends WrappedPacket {
//DISPLAYED SKIN PARTS
this.displayedSkinParts = new HashMap<DisplayedSkinPart, Boolean>();
if (version.isLowerThan(ServerVersion.v_1_8)) {
if (isLowerThan_v_1_8) {
//in 1.7.10 only the cape display skin part is sent
boolean capeEnabled = Reflection.getField(packetClass, boolean.class, 1).getBoolean(packet);
displayedSkinParts.put(DisplayedSkinPart.CAPE, capeEnabled);
@@ -108,6 +111,8 @@ public class WrappedPacketInSettings extends WrappedPacket {
* It is possible for some keys to not exist.
* If that is the case, the server version is 1.7.10.
* 1.7.10 only sends the cape skin part.
*
* @return A map associating skin parts with whether or not they are enabled.
*/
@Nullable
public HashMap<DisplayedSkinPart, Boolean> getDisplayedSkinPartsMap() {
@@ -118,8 +123,8 @@ public class WrappedPacketInSettings extends WrappedPacket {
* On 1.7.10, some skin parts will default to 'false' as 1.7.10
* only sends the 'cape' skin part.
*
* @param part
* @return
* @param part The skin part to check the status of.
* @return True if the specified skin part is enabled, otherwise false.
*/
public boolean isDisplaySkinPartEnabled(DisplayedSkinPart part) {
//1.7.10, we will default the other skin parts to return false.
@@ -1,27 +1,24 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.in.steervehicle;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
import io.github.retrooper.packetevents.utils.NMSUtils;
public class WrappedPacketInSteerVehicle extends WrappedPacket {
private static Class<?> packetClass;
static {
try {
packetClass = NMSUtils.getNMSClass("PacketPlayInSteerVehicle");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private float side, forward;
private boolean jump, unmount;
public WrappedPacketInSteerVehicle(Object packet) {
super(packet);
}
public static void load() {
packetClass = PacketTypeClasses.Client.STEER_VEHICLE;
}
@Override
protected void setup() {
try {
@@ -1,28 +1,25 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.in.transaction;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
import io.github.retrooper.packetevents.utils.NMSUtils;
public final class WrappedPacketInTransaction extends WrappedPacket {
private static Class<?> packetClass;
static {
try {
packetClass = NMSUtils.getNMSClass("PacketPlayInTransaction");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private int windowId;
private short actionNumber;
private boolean accepted;
public WrappedPacketInTransaction(final Object packet) {
super(packet);
}
public static void load() {
packetClass = PacketTypeClasses.Client.TRANSACTION;
}
@Override
protected void setup() {
try {
@@ -1,43 +1,34 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.in.useentity;
import io.github.retrooper.packetevents.enums.minecraft.EntityUseAction;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
import io.github.retrooper.packetevents.utils.NMSUtils;
import org.bukkit.entity.Entity;
public final class WrappedPacketInUseEntity extends WrappedPacket {
private static Class<?> useEntityClass, entityClass, enumEntityUseActionClass;
private static Class<?> useEntityClass;
private static Class<?> enumEntityUseActionClass;
private int entityId;
private EntityUseAction action;
public WrappedPacketInUseEntity(final Object packet) {
super(packet);
}
static {
try {
useEntityClass = NMSUtils.getNMSClass("PacketPlayInUseEntity");
entityClass = NMSUtils.getNMSClass("Entity");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
public static void load() {
useEntityClass = PacketTypeClasses.Client.USE_ENTITY;
try {
enumEntityUseActionClass = NMSUtils.getNMSClass("EnumEntityUseAction");
} catch (ClassNotFoundException e) {
//That is fine, it is probably a subclass
for (final Class<?> sub : useEntityClass.getDeclaredClasses()) {
if (sub.getSimpleName().equals("EnumEntityUseAction")) {
enumEntityUseActionClass = sub;
break;
}
}
enumEntityUseActionClass = Reflection.getSubClass(useEntityClass, "EnumEntityUseAction");
}
}
private int entityId;
private EntityUseAction action;
public WrappedPacketInUseEntity(final Object packet) {
super(packet);
}
@Override
protected void setup() {
try {
@@ -60,4 +51,8 @@ public final class WrappedPacketInUseEntity extends WrappedPacket {
public EntityUseAction getAction() {
return action;
}
public enum EntityUseAction {
INTERACT, INTERACT_AT, ATTACK, INVALID
}
}
@@ -0,0 +1,188 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.in.windowclick;
import io.github.retrooper.packetevents.annotations.Nullable;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
import io.github.retrooper.packetevents.utils.NMSUtils;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
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 int id;
private int slot;
private int button;
private short actionNumber;
private int mode;
private ItemStack clickedItem;
public WrappedPacketInWindowClick(Object packet) {
super(packet);
}
public static void load() {
packetClass = PacketTypeClasses.Client.WINDOW_CLICK;
invClickTypeClass = NMSUtils.getNMSClassWithoutException("InventoryClickType");
invClickTypeMapCache.put("PICKUP", 0);
invClickTypeMapCache.put("QUICK_MOVE", 1);
invClickTypeMapCache.put("SWAP", 2);
invClickTypeMapCache.put("CLONE", 3);
invClickTypeMapCache.put("THROW", 4);
invClickTypeMapCache.put("QUICK_CRAFT", 5);
invClickTypeMapCache.put("PICKUP_ALL", 6);
//MODE 0
windowClickTypeCache.put(0, getArrayListOfWindowClickTypes(WindowClickType.LEFT_MOUSE_CLICK,
WindowClickType.RIGHT_MOUSE_CLICK));
//MODE 1
windowClickTypeCache.put(1, getArrayListOfWindowClickTypes(WindowClickType.SHIFT_LEFT_MOUSE_CLICK,
WindowClickType.SHIFT_RIGHT_MOUSE_CLICK));
//MODE 2
windowClickTypeCache.put(2, getArrayListOfWindowClickTypes(
WindowClickType.KEY_NUMBER1,
WindowClickType.KEY_NUMBER2,
WindowClickType.KEY_NUMBER3,
WindowClickType.KEY_NUMBER4,
WindowClickType.KEY_NUMBER5,
WindowClickType.KEY_NUMBER6,
WindowClickType.KEY_NUMBER7,
WindowClickType.KEY_NUMBER8,
WindowClickType.KEY_NUMBER9));
//MODE 3
windowClickTypeCache.put(3, getArrayListOfWindowClickTypes(WindowClickType.UNKNOWN, WindowClickType.UNKNOWN, WindowClickType.CREATIVE_MIDDLE_CLICK));
//MODE 4
windowClickTypeCache.put(4, getArrayListOfWindowClickTypes(WindowClickType.KEY_DROP,
WindowClickType.KEY_DROP_STACK));
//MODE 5
windowClickTypeCache.put(5, getArrayListOfWindowClickTypes(
WindowClickType.STARTING_LEFT_MOUSE_DRAG,
WindowClickType.ADD_SLOT_LEFT_MOUSE_DRAG,
WindowClickType.ENDING_LEFT_MOUSE_DRAG,
WindowClickType.UNKNOWN,
WindowClickType.STARTING_RIGHT_MOUSE_DRAG,
WindowClickType.ADD_SLOT_RIGHT_MOUSE_DRAG,
WindowClickType.CREATIVE_STARTING_MIDDLE_MOUSE_DRAG,
WindowClickType.ADD_SLOT_MIDDLE_MOUSE_DRAG,
WindowClickType.ENDING_MIDDLE_MOUSE_DRAG));
windowClickTypeCache.put(6, getArrayListOfWindowClickTypes(WindowClickType.DOUBLE_CLICK));
isClickModePrimitive = Reflection.getField(packetClass, int.class, 3) != null;
}
private static ArrayList<WindowClickType> getArrayListOfWindowClickTypes(WindowClickType... types) {
ArrayList<WindowClickType> arrayList = new ArrayList<WindowClickType>(types.length);
arrayList.addAll(Arrays.asList(types));
return arrayList;
}
@Override
protected void setup() {
try {
this.id = Reflection.getField(packetClass, int.class, 0).getInt(packet);
this.slot = Reflection.getField(packetClass, int.class, 1).getInt(packet);
this.button = Reflection.getField(packetClass, int.class, 2).getInt(packet);
this.actionNumber = Reflection.getField(packetClass, short.class, 0).getShort(packet);
Object nmsItemStack = Reflection.getField(packetClass, NMSUtils.nmsItemStackClass, 0).get(packet);
this.clickedItem = NMSUtils.toBukkitItemStack(nmsItemStack);
Object clickMode = Reflection.getField(packetClass, 5).get(packet);
if (isClickModePrimitive) {
mode = (int) clickMode;
} else {
mode = invClickTypeMapCache.get(clickMode.toString());
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
public int getWindowID() {
return id;
}
public int getWindowSlot() {
return slot;
}
public int getWindowButton() {
return button;
}
public short getActionNumber() {
return actionNumber;
}
@Nullable
public WindowClickType getWindowClickType() {
if (windowClickTypeCache.get(mode) == null) {
return WindowClickType.UNKNOWN;
}
if (button + 1 > windowClickTypeCache.size()) {
return WindowClickType.UNKNOWN;
}
if (mode == 4) {
if (slot == -999) {
if (button == 0) {
return WindowClickType.LEFT_CLICK_OUTSIDE_WINDOW_HOLDING_NOTHING;
} else if (button == 1) {
return WindowClickType.RIGHT_CLICK_OUTSIDE_WINDOW_HOLDING_NOTHING;
}
}
}
return windowClickTypeCache.get(mode).get(button);
}
public int getMode() {
return mode;
}
public ItemStack getClickedItem() {
return clickedItem;
}
public enum WindowClickType {
LEFT_MOUSE_CLICK, RIGHT_MOUSE_CLICK,
SHIFT_LEFT_MOUSE_CLICK, SHIFT_RIGHT_MOUSE_CLICK,
CREATIVE_MIDDLE_CLICK, CREATIVE_STARTING_MIDDLE_MOUSE_DRAG,
KEY_NUMBER1, KEY_NUMBER2, KEY_NUMBER3, KEY_NUMBER4,
KEY_NUMBER5, KEY_NUMBER6, KEY_NUMBER7, KEY_NUMBER8,
KEY_NUMBER9, KEY_DROP, KEY_DROP_STACK,
LEFT_CLICK_OUTSIDE_WINDOW_HOLDING_NOTHING,
RIGHT_CLICK_OUTSIDE_WINDOW_HOLDING_NOTHING,
STARTING_LEFT_MOUSE_DRAG,
STARTING_RIGHT_MOUSE_DRAG,
ADD_SLOT_LEFT_MOUSE_DRAG,
ADD_SLOT_RIGHT_MOUSE_DRAG,
ADD_SLOT_MIDDLE_MOUSE_DRAG,
ENDING_LEFT_MOUSE_DRAG,
ENDING_RIGHT_MOUSE_DRAG,
ENDING_MIDDLE_MOUSE_DRAG,
DOUBLE_CLICK,
UNKNOWN
}
}
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.out.abilities;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
@@ -1,9 +1,12 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.out.abilities;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.Sendable;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
import io.github.retrooper.packetevents.utils.NMSUtils;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
@@ -11,24 +14,8 @@ import java.lang.reflect.InvocationTargetException;
public final class WrappedPacketOutAbilities extends WrappedPacket implements Sendable {
private static Class<?> packetClass;
private static Constructor<?> packetConstructor;
static {
try {
packetClass = NMSUtils.getNMSClass("PacketPlayOutAbilities");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
packetConstructor = packetClass.getConstructor(PlayerAbilitiesUtils.playerAbilitiesClass);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
private boolean vulnerable, flying, allowFlight, instantBuild;
private float flySpeed, walkSpeed;
public WrappedPacketOutAbilities(final Object packet) {
super(packet);
}
@@ -44,6 +31,16 @@ public final class WrappedPacketOutAbilities extends WrappedPacket implements Se
this.walkSpeed = walkSpeed;
}
public static void load() {
packetClass = PacketTypeClasses.Server.ABILITIES;
try {
packetConstructor = packetClass.getConstructor(PlayerAbilitiesUtils.playerAbilitiesClass);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
@Override
protected void setup() {
try {
@@ -1,6 +1,9 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.out.animation;
import io.github.retrooper.packetevents.enums.minecraft.EntityAnimationType;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.Sendable;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
@@ -9,30 +12,17 @@ import org.bukkit.entity.Entity;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
public final class WrappedPacketOutAnimation extends WrappedPacket implements Sendable {
private static Class<?> animationClass, nmsEntityClass;
private static Constructor<?> animationConstructor;
static {
try {
animationClass = NMSUtils.getNMSClass("PacketPlayOutAnimation");
nmsEntityClass = NMSUtils.getNMSClass("Entity");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
animationConstructor = animationClass.getConstructor(nmsEntityClass, int.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
private static final HashMap<Integer, EntityAnimationType> cachedAnimationIDS = new HashMap<Integer, EntityAnimationType>();
private static final HashMap<EntityAnimationType, Integer> cachedAnimations = new HashMap<EntityAnimationType, Integer>();
private Entity entity;
private int entityID;
private EntityAnimationType type;
public WrappedPacketOutAnimation(final Object packet) {
super(packet);
}
@@ -44,14 +34,42 @@ public final class WrappedPacketOutAnimation extends WrappedPacket implements Se
this.type = type;
}
public static void load() {
animationClass = PacketTypeClasses.Server.ANIMATION;
try {
nmsEntityClass = NMSUtils.getNMSClass("Entity");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
animationConstructor = animationClass.getConstructor(nmsEntityClass, int.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
cachedAnimationIDS.put(0, EntityAnimationType.SWING_MAIN_ARM);
cachedAnimationIDS.put(1, EntityAnimationType.TAKE_DAMAGE);
cachedAnimationIDS.put(2, EntityAnimationType.LEAVE_BED);
cachedAnimationIDS.put(3, EntityAnimationType.SWING_OFFHAND);
cachedAnimationIDS.put(4, EntityAnimationType.CRITICAL_EFFECT);
cachedAnimationIDS.put(5, EntityAnimationType.MAGIC_CRITICAL_EFFECT);
cachedAnimations.put(EntityAnimationType.SWING_MAIN_ARM, 0);
cachedAnimations.put(EntityAnimationType.TAKE_DAMAGE, 1);
cachedAnimations.put(EntityAnimationType.LEAVE_BED, 2);
cachedAnimations.put(EntityAnimationType.SWING_OFFHAND, 3);
cachedAnimations.put(EntityAnimationType.CRITICAL_EFFECT, 4);
cachedAnimations.put(EntityAnimationType.MAGIC_CRITICAL_EFFECT, 5);
}
@Override
protected void setup() {
try {
//a - ID
//b - TYPE
this.entityID = Reflection.getField(animationClass, int.class, 0).getInt(packet);
this.entity = NMSUtils.getEntityById(this.entityID);
this.type = EntityAnimationType.get(Reflection.getField(animationClass, int.class, 1).getInt(packet));
int animationID = Reflection.getField(animationClass, int.class, 1).getInt(packet);
this.type = cachedAnimationIDS.get(animationID);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
@@ -59,7 +77,7 @@ public final class WrappedPacketOutAnimation extends WrappedPacket implements Se
}
public Entity getEntity() {
return this.entity;
return NMSUtils.getEntityById(this.entityID);
}
public int getEntityId() {
@@ -73,7 +91,7 @@ public final class WrappedPacketOutAnimation extends WrappedPacket implements Se
@Override
public Object asNMSPacket() {
final Object nmsEntity = NMSUtils.getNMSEntity(this.entity);
final int index = type.getIndex();
final int index = cachedAnimations.get(type);
try {
return animationConstructor.newInstance(nmsEntity, index);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
@@ -81,4 +99,8 @@ public final class WrappedPacketOutAnimation extends WrappedPacket implements Se
}
return null;
}
public enum EntityAnimationType {
SWING_MAIN_ARM, TAKE_DAMAGE, LEAVE_BED, SWING_OFFHAND, CRITICAL_EFFECT, MAGIC_CRITICAL_EFFECT
}
}
@@ -1,5 +1,10 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.out.chat;
import io.github.retrooper.packetevents.annotations.Beta;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.Sendable;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
@@ -7,14 +12,57 @@ import io.github.retrooper.packetevents.utils.NMSUtils;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.UUID;
/**
* This wrapper MIGHT not be stable
*/
@Beta
public final class WrappedPacketOutChat extends WrappedPacket implements Sendable {
private static Constructor<?> chatClassConstructor;
private static Class<?> chatClass, iChatBaseComponentClass, chatSerializerClass;
private static Class<?> packetClass, iChatBaseComponentClass, chatSerializerClass, chatMessageTypeEnum;
private static Method chatMessageTypeCreatorMethod;
//0 = IChatBaseComponent, Byte
//1 = IChatBaseComponent, Int
//2 = IChatBaseComponent, ChatMessageType
//3 = IChatBaseComponent, ChatMessageType, UUID
private static byte constructorMode;
static {
//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 String message;
private ChatPosition chatPosition;
private UUID uuid;
public WrappedPacketOutChat(final Object packet) {
super(packet);
}
public WrappedPacketOutChat(String message, UUID uuid) {
this(message, ChatPosition.CHAT, uuid);
}
public WrappedPacketOutChat(String message, ChatPosition chatPosition, UUID uuid) {
super();
this.uuid = uuid;
this.message = message;
this.chatPosition = chatPosition;
}
public enum ChatPosition {
CHAT, SYSTEM_MESSAGE, GAME_INFO
}
public static void load() {
try {
chatClass = NMSUtils.getNMSClass("PacketPlayOutChat");
packetClass = PacketTypeClasses.Server.CHAT;
iChatBaseComponentClass = NMSUtils.getNMSClass("IChatBaseComponent");
} catch (ClassNotFoundException e) {
e.printStackTrace();
@@ -28,24 +76,62 @@ public final class WrappedPacketOutChat extends WrappedPacket implements Sendabl
chatSerializerClass = Reflection.getSubClass(iChatBaseComponentClass, "ChatSerializer");
}
boolean isVeryOutdated = false;
try {
chatClassConstructor = chatClass.getConstructor(iChatBaseComponentClass);
} catch (NoSuchMethodException e) {
e.printStackTrace();
chatMessageTypeEnum = NMSUtils.getNMSClass("ChatMessageType");
} catch (ClassNotFoundException e) {
isVeryOutdated = true;
}
if (!isVeryOutdated) {
chatMessageTypeCreatorMethod = Reflection.getMethod(chatMessageTypeEnum, 0, byte.class);
try {
chatClassConstructor = packetClass.getConstructor(iChatBaseComponentClass, chatMessageTypeEnum);
constructorMode = 2;
} catch (NoSuchMethodException e) {
//Just a much newer version(1.16.x and above right now)
try {
chatClassConstructor = packetClass.getConstructor(iChatBaseComponentClass, chatMessageTypeEnum, UUID.class);
constructorMode = 3;
} catch (NoSuchMethodException e2) {
//Failed to resolve the constructor
e2.printStackTrace();
}
}
} else {
try {
chatClassConstructor = packetClass.getConstructor(iChatBaseComponentClass, byte.class);
constructorMode = 0;
} catch (NoSuchMethodException e) {
//That is fine, they are most likely on an older version.
try {
chatClassConstructor = packetClass.getConstructor(iChatBaseComponentClass, int.class);
constructorMode = 1;
} catch (NoSuchMethodException e2) {
e2.printStackTrace();
}
}
}
cachedChatPositions.put(ChatPosition.CHAT, (byte) 0);
cachedChatPositions.put(ChatPosition.SYSTEM_MESSAGE, (byte) 1);
cachedChatPositions.put(ChatPosition.GAME_INFO, (byte) 2);
cachedChatPositionIntegers.put((byte) 0, ChatPosition.CHAT);
cachedChatPositionIntegers.put((byte) 1, ChatPosition.SYSTEM_MESSAGE);
cachedChatPositionIntegers.put((byte) 2, ChatPosition.GAME_INFO);
cachedChatMessageTypeIntegers.put("CHAT", (byte) 0);
cachedChatMessageTypeIntegers.put("SYSTEM", (byte) 1);
cachedChatMessageTypeIntegers.put("GAME_INFO", (byte) 2);
}
private String message;
public WrappedPacketOutChat(final Object packet) {
super(packet);
}
public WrappedPacketOutChat(final String message) {
super();
this.message = "{\"text\": \"" + message + "\"}";
public static String fromStringToJSON(String message) {
return "{\"text\": \"" + "use entity action name: " + message + "\"}";
}
public static String toStringFromIChatBaseComponent(Object obj) {
@@ -70,11 +156,27 @@ public final class WrappedPacketOutChat extends WrappedPacket implements Sendabl
@Override
protected void setup() {
try {
final Object iChatBaseObj = Reflection.getField(chatClass, iChatBaseComponentClass, 0).get(packet);
final Object iChatBaseObj = Reflection.getField(packetClass, iChatBaseComponentClass, 0).get(packet);
final Object contentString = Reflection.getMethod(iChatBaseComponentClass, String.class, 0).invoke(iChatBaseObj);
this.message = contentString.toString();
byte chatPosInteger = 0;
switch (constructorMode) {
case 0:
chatPosInteger = Reflection.getField(packetClass, byte.class, 0).getByte(packet);
break;
case 1:
chatPosInteger = (byte) Reflection.getField(packetClass, int.class, 0).getInt(packet);
break;
case 2:
case 3:
Object chatTypeEnumInstance = Reflection.getField(packetClass, chatMessageTypeEnum, 0).get(packet);
chatPosInteger = cachedChatMessageTypeIntegers.get(chatTypeEnumInstance.toString());
break;
}
this.chatPosition = cachedChatPositionIntegers.get(chatPosInteger);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
@@ -82,16 +184,64 @@ public final class WrappedPacketOutChat extends WrappedPacket implements Sendabl
@Override
public Object asNMSPacket() {
try {
return chatClassConstructor.newInstance(toIChatBaseComponent(this.message));
} catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
int integerChatPos = cachedChatPositions.get(chatPosition);
Object chatMessageTypeInstance = null;
if (chatMessageTypeEnum != null) {
if (chatTypeMessageEnumConstructorMode == 0) {
try {
chatMessageTypeInstance = chatMessageTypeCreatorMethod.invoke(null, (byte) integerChatPos);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
} else if (chatTypeMessageEnumConstructorMode == 1) {
try {
chatMessageTypeInstance = chatMessageTypeCreatorMethod.invoke(null, (byte) integerChatPos);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
switch (constructorMode) {
case 0:
try {
return chatClassConstructor.newInstance(toIChatBaseComponent(this.message), (byte) integerChatPos);
} catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
break;
case 1:
try {
return chatClassConstructor.newInstance(toIChatBaseComponent(this.message), integerChatPos);
} catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
break;
case 2:
try {
return chatClassConstructor.newInstance(toIChatBaseComponent(this.message), chatMessageTypeInstance);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
break;
case 3:
try {
return chatClassConstructor.newInstance(toIChatBaseComponent(this.message), chatMessageTypeInstance, uuid);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
break;
}
return null;
}
public String getMessage() {
return this.message;
}
public ChatPosition getChatPosition() {
if(this.chatPosition == null) {
this.chatPosition = ChatPosition.CHAT;
}
return this.chatPosition;
}
}
@@ -1,5 +1,9 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.out.entity;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
import io.github.retrooper.packetevents.utils.NMSUtils;
@@ -9,17 +13,22 @@ import java.lang.reflect.Field;
public class WrappedPacketOutEntity extends WrappedPacket {
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 int entityID;
private double deltaX, deltaY, deltaZ;
private byte yaw, pitch;
private boolean onGround;
public WrappedPacketOutEntity(Object packet) {
super(packet);
}
static {
try {
packetClass = NMSUtils.getNMSClass("PacketPlayOutEntity");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
public static void load() {
packetClass = PacketTypeClasses.Server.ENTITY;
Field dxField = Reflection.getField(packetClass, 1);
assert dxField != null;
if (dxField.equals(Reflection.getField(packetClass, byte.class, 0))) {
mode = 0;
} else if (dxField.equals(Reflection.getField(packetClass, int.class, 1))) {
@@ -36,23 +45,12 @@ public class WrappedPacketOutEntity extends WrappedPacket {
}
private int entityID;
private double deltaX, deltaY, deltaZ;
private byte yaw, pitch;
private boolean onGround;
public WrappedPacketOutEntity(Object packet) {
super(packet);
}
@Override
protected void setup() {
try {
this.entityID = Reflection.getField(packetClass, int.class, 0).getInt(packet);
this.onGround = Reflection.getField(packetClass, boolean.class, 0).getBoolean(packet);
int dX = 1, dY = 1, dZ = 1;
switch (mode) {
case 0:
dX = Reflection.getField(packetClass, byte.class, 0).getByte(packet);
@@ -82,7 +80,6 @@ public class WrappedPacketOutEntity extends WrappedPacket {
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
public byte getPitch() {
@@ -1,6 +1,10 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.out.entityvelocity;
import io.github.retrooper.packetevents.enums.ServerVersion;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.Sendable;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
@@ -13,42 +17,10 @@ import java.lang.reflect.InvocationTargetException;
public final class WrappedPacketOutEntityVelocity extends WrappedPacket implements Sendable {
private static Constructor<?> velocityConstructor, vec3dConstructor;
private static Class<?> velocityClass, vec3dClass;
/**
* Velocity Constructor parameter types:
* 1.7.10->1.13.2 use int, double, double, double style,
* 1.14+ use int, Vec3D style
*/
static {
try {
velocityClass = NMSUtils.getNMSClass("PacketPlayOutEntityVelocity");
if (version.isHigherThan(ServerVersion.v_1_13_2)) {
vec3dClass = NMSUtils.getNMSClass("Vec3D");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
velocityConstructor = velocityClass.getConstructor(int.class, double.class, double.class, double.class);
} catch (NoSuchMethodException e) {
//That is fine, just a newer version
try {
velocityConstructor = velocityClass.getConstructor(int.class, vec3dClass);
//vec3d constructor
vec3dConstructor = vec3dClass.getConstructor(double.class, double.class, double.class);
} catch (NoSuchMethodException e2) {
e2.printStackTrace();
}
}
}
private Entity entity;
private static boolean isVec3dPresent;
private int entityId;
private double velocityX, velocityY, velocityZ;
private Entity entity;
public WrappedPacketOutEntityVelocity(final Object packet) {
super(packet);
}
@@ -62,19 +34,48 @@ public final class WrappedPacketOutEntityVelocity extends WrappedPacket implemen
this.velocityZ = velocityZ;
}
/**
* Velocity Constructor parameter types:
* 1.7.10 -&gt; 1.13.2 use int, double, double, double style,
* 1.14+ use int, Vec3D style
*/
public static void load() {
velocityClass = PacketTypeClasses.Server.ENTITY_VELOCITY;
if (version.isHigherThan(ServerVersion.v_1_13_2)) {
try {
vec3dClass = NMSUtils.getNMSClass("Vec3D");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
try {
velocityConstructor = velocityClass.getConstructor(int.class, double.class, double.class, double.class);
} catch (NoSuchMethodException e) {
//That is fine, just a newer version
try {
velocityConstructor = velocityClass.getConstructor(int.class, vec3dClass);
isVec3dPresent = true;
//vec3d constructor
vec3dConstructor = vec3dClass.getConstructor(double.class, double.class, double.class);
} catch (NoSuchMethodException e2) {
e2.printStackTrace();
}
}
}
@Override
protected void setup() {
try {
int i = 0;
final int entityId = Reflection.getField(velocityClass, int.class, 0).getInt(packet);
//ENTITY ID
this.entityId = Reflection.getField(velocityClass, int.class, 0).getInt(packet);
final int x = Reflection.getField(velocityClass, int.class, 1).getInt(packet);
final int y = Reflection.getField(velocityClass, int.class, 2).getInt(packet);
final int z = Reflection.getField(velocityClass, int.class, 3).getInt(packet);
this.entityId = entityId;
this.entity = NMSUtils.getEntityById(this.entityId);
int x = Reflection.getField(velocityClass, int.class, 1).getInt(packet);
int y = Reflection.getField(velocityClass, int.class, 2).getInt(packet);
int z = Reflection.getField(velocityClass, int.class, 3).getInt(packet);
//VELOCITY XYZ
this.velocityX = x / 8000.0D;
this.velocityY = y / 8000.0D;
this.velocityZ = z / 8000.0D;
@@ -88,7 +89,11 @@ public final class WrappedPacketOutEntityVelocity extends WrappedPacket implemen
}
public Entity getEntity() {
return entity;
if (entity == null) {
return NMSUtils.getEntityById(this.entityId);
} else {
return entity;
}
}
public double getVelocityX() {
@@ -105,7 +110,7 @@ public final class WrappedPacketOutEntityVelocity extends WrappedPacket implemen
@Override
public Object asNMSPacket() {
if (version.isLowerThan(ServerVersion.v_1_14)) {
if (!isVec3dPresent) {
try {
return velocityConstructor.newInstance(entityId, velocityX, velocityY, velocityZ);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
@@ -1,39 +1,52 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.out.keepalive;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.Sendable;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
import io.github.retrooper.packetevents.utils.NMSUtils;
public class WrappedPacketOutKeepAlive extends WrappedPacket {
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class WrappedPacketOutKeepAlive extends WrappedPacket implements Sendable {
private static Class<?> packetClass;
static {
try {
packetClass = NMSUtils.getNMSClass("PacketPlayOutKeepAlive");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private static Constructor<?> keepAliveConstructor;
private static boolean integerMode;
private long id;
public WrappedPacketOutKeepAlive(Object packet) {
super(packet);
}
/**
* Optionally Cast this long to an integer if you are using 1.7.10->1.12.2!
* In 1.13.2->1.16.1 a long is sent
*
* @return response is
*/
public long getId() {
return id;
public WrappedPacketOutKeepAlive(long id) {
super();
}
public static void load() {
packetClass = PacketTypeClasses.Server.KEEP_ALIVE;
integerMode = Reflection.getField(packetClass, int.class, 0) != null;
if (integerMode) {
try {
keepAliveConstructor = packetClass.getConstructor(int.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
} else {
try {
keepAliveConstructor = packetClass.getConstructor(long.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
@Override
protected void setup() {
if (Reflection.getField(packetClass, int.class, 0) == null) {
if (!integerMode) {
try {
this.id = Reflection.getField(packetClass, long.class, 0).getLong(packet);
} catch (IllegalAccessException e) {
@@ -47,4 +60,32 @@ public class WrappedPacketOutKeepAlive extends WrappedPacket {
}
}
}
/**
* You can cast this long to an integer if you are using 1.7.10 -&gt; 1.12.2!
* In 1.13.2 -&gt; 1.16.2 a long is sent
*
* @return Keep Alive ID
*/
public long getId() {
return id;
}
@Override
public Object asNMSPacket() {
if (integerMode) {
try {
return keepAliveConstructor.newInstance((int) id);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
} else {
try {
return keepAliveConstructor.newInstance(id);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
return null;
}
}
@@ -1,5 +1,9 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.out.kickdisconnect;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.Sendable;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.packetwrappers.out.chat.WrappedPacketOutChat;
@@ -12,10 +16,20 @@ import java.lang.reflect.InvocationTargetException;
public final class WrappedPacketOutKickDisconnect extends WrappedPacket implements Sendable {
private static Class<?> packetClass, iChatBaseComponentClass;
private static Constructor<?> kickDisconnectConstructor;
private String kickMessage;
static {
public WrappedPacketOutKickDisconnect(final Object packet) {
super(packet);
}
public WrappedPacketOutKickDisconnect(final String kickMessage) {
super();
this.kickMessage = kickMessage;
}
public static void load() {
packetClass = PacketTypeClasses.Server.KICK_DISCONNECT;
try {
packetClass = NMSUtils.getNMSClass("PacketPlayOutKickDisconnect");
iChatBaseComponentClass = NMSUtils.getNMSClass("IChatBaseComponent");
} catch (ClassNotFoundException e) {
e.printStackTrace();
@@ -28,17 +42,6 @@ public final class WrappedPacketOutKickDisconnect extends WrappedPacket implemen
}
}
private String kickMessage;
public WrappedPacketOutKickDisconnect(final Object packet) {
super(packet);
}
public WrappedPacketOutKickDisconnect(final String kickMessage) {
super();
this.kickMessage = kickMessage;
}
@Override
protected void setup() {
try {
@@ -0,0 +1,60 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.out.position;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
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;
public WrappedPacketOutPosition(Object packet) {
super(packet);
}
public static void load() {
packetClass = PacketTypeClasses.Server.POSITION;
}
@Override
protected void setup() {
//TODO boolean onGround and flags
try {
this.x = Reflection.getField(packetClass, double.class, 0).getDouble(packet);
this.y = Reflection.getField(packetClass, double.class, 1).getDouble(packet);
this.z = Reflection.getField(packetClass, double.class, 2).getDouble(packet);
this.yaw = Reflection.getField(packetClass, float.class, 0).getFloat(packet);
this.pitch = Reflection.getField(packetClass, float.class, 1).getFloat(packet);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public double getZ() {
return z;
}
public float getYaw() {
return yaw;
}
public float getPitch() {
return pitch;
}
}
@@ -1,9 +1,12 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.out.transaction;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.Sendable;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
import io.github.retrooper.packetevents.utils.NMSUtils;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
@@ -11,25 +14,9 @@ import java.lang.reflect.InvocationTargetException;
public class WrappedPacketOutTransaction extends WrappedPacket implements Sendable {
private static Class<?> packetClass;
private static Constructor<?> packetConstructor;
static {
try {
packetClass = NMSUtils.getNMSClass("PacketPlayOutTransaction");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
packetConstructor = packetClass.getConstructor(int.class, short.class, boolean.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
private int windowId;
private short actionNumber;
private boolean accepted;
public WrappedPacketOutTransaction(final Object packet) {
super(packet);
}
@@ -41,6 +28,16 @@ public class WrappedPacketOutTransaction extends WrappedPacket implements Sendab
this.accepted = accepted;
}
public static void load() {
packetClass = PacketTypeClasses.Server.TRANSACTION;
try {
packetConstructor = packetClass.getConstructor(int.class, short.class, boolean.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
@Override
protected void setup() {
try {
@@ -1,9 +1,12 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.packetwrappers.out.updatehealth;
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.Sendable;
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
import io.github.retrooper.packetevents.reflectionutils.Reflection;
import io.github.retrooper.packetevents.utils.NMSUtils;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
@@ -11,24 +14,8 @@ import java.lang.reflect.InvocationTargetException;
public final class WrappedPacketOutUpdateHealth extends WrappedPacket implements Sendable {
private static Class<?> packetClass;
private static Constructor<?> packetConstructor;
static {
try {
packetClass = NMSUtils.getNMSClass("PacketPlayOutUpdateHealth");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
packetConstructor = packetClass.getConstructor(float.class, int.class, float.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
private float health, foodSaturation;
private int food;
public WrappedPacketOutUpdateHealth(final Object packet) {
super(packet);
}
@@ -36,9 +23,9 @@ public final class WrappedPacketOutUpdateHealth extends WrappedPacket implements
/**
* See https://wiki.vg/Protocol#Update_Health
*
* @param health
* @param food
* @param foodSaturation
* @param health 0 or less = dead, 20 = full HP
* @param food 0–20
* @param foodSaturation Seems to vary from 0.0 to 5.0 in integer increments
*/
public WrappedPacketOutUpdateHealth(final float health, final int food, final float foodSaturation) {
super();
@@ -47,6 +34,16 @@ public final class WrappedPacketOutUpdateHealth extends WrappedPacket implements
this.foodSaturation = foodSaturation;
}
public static void load() {
packetClass = PacketTypeClasses.Server.UPDATE_HEALTH;
try {
packetConstructor = packetClass.getConstructor(float.class, int.class, float.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
@Override
protected void setup() {
try {
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.reflectionutils;
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.reflectionutils.fielddata;
import java.util.Objects;
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.reflectionutils.fielddata;
import java.util.Objects;
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.reflectionutils.fielddata;
import java.util.Objects;
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.reflectionutils.methoddata;
import java.util.Objects;
@@ -1,11 +1,18 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.settings;
import io.github.retrooper.packetevents.enums.ServerVersion;
import java.util.Random;
public class PacketEventsSettings {
private ServerVersion defaultServerVersion;
private String identifier = "";
private boolean autoResolveClientProtocolVersion;
private boolean uninjectAsync = false;
/**
* If PacketEvents fails to detect your server version, it will use the recommended version
@@ -13,28 +20,50 @@ public class PacketEventsSettings {
* @return Recommended version
*/
public ServerVersion getDefaultServerVersion() {
return defaultServerVersion;
return this.defaultServerVersion;
}
/**
* Set the recommended version
* Set the default version
*
* @param version
* @param version ServerVersion
*/
public void setDefaultServerVersion(final ServerVersion version) {
defaultServerVersion = version;
this.defaultServerVersion = version;
}
/**
* The identifier is a unique string that is used to generate a player's handler name.
* Two plugins cannot have the same handler name.
* If you manually set the identifier using its setter '#setIdentifier(String)'.
* We will use that identifier to generate each player's handler name.
* If you do not set the identifier manually, we automatically generate one for you.
* @return stored identifier or new generated identifier
*/
public String getIdentifier() {
return identifier;
if (this.identifier.isEmpty()) {
String alphabet = "abcdefghijklmnopqrstuvwxyz";
StringBuilder sb = new StringBuilder();
Random random = new Random();
while (sb.length() < 13) {
int index = (int) (random.nextFloat() * alphabet.length());
sb.append(alphabet.charAt(index));
}
this.identifier = sb.toString();
}
return this.identifier;
}
/**
* Set a unique Identifier (Usually something that represents your plugin, For example: MyPluginPacketHandler)
* If another present plugin uses the same Identifier, It might cause incompatibilities
* If another present plugin uses the same Identifier, It will cause incompatibilities.
*
* @param identifier
* @param identifier Unique string
* @deprecated This method is deprecated as you no longer need to set an identifier,
* a unique identifier is already automatically generated for you.
*/
@Deprecated
public void setIdentifier(final String identifier) {
this.identifier = identifier;
}
@@ -45,13 +74,26 @@ public class PacketEventsSettings {
/**
* If PacketEvents fails to detect a client's version
* Should it assume that the client is using the same version that the server is?
* <p>
* Returns ACCESS_FAILURE if false
*
* @param autoResolveClientProtocolVersion
* (when ViaVersion, ProtocolLib or ProtocolSupport can't be found on the server),
* should it assume that the client is using the same version as the server?
* Returns ACCESS_FAILURE if this is set to FALSE(default value is false).
* @param autoResolveClientProtocolVersion boolean
*/
public void setDoAutoResolveClientProtocolVersion(boolean autoResolveClientProtocolVersion) {
this.autoResolveClientProtocolVersion = autoResolveClientProtocolVersion;
}
}
/**
* Would you like PacketEvents to Uninject players Asynchronously?
* WARNING! This might make reloading unsupported
*
* @param uninjectAsync boolean
*/
public void setUninjectAsync(boolean uninjectAsync) {
this.uninjectAsync = uninjectAsync;
}
public boolean isUninjectAsync() {
return this.uninjectAsync;
}
}
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.utils;
import org.bukkit.Location;
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.utils;
import io.github.retrooper.packetevents.annotations.Nullable;
@@ -15,7 +18,7 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public final class NMSUtils {
private static final ServerVersion version = ServerVersion.getVersion();
public static ServerVersion version;
private static final String nmsDir = ServerVersion.getNMSDirectory();
private static final String obcDir = ServerVersion.getOBCDirectory();
public static String nettyPrefix;
@@ -26,7 +29,7 @@ public final class NMSUtils {
private static Method getCraftWorldHandleMethod, getServerConnection, getCraftPlayerHandle, getCraftEntityHandle, sendPacketMethod, asBukkitCopy;
private static Field entityPlayerPingField, playerConnectionField;
static {
public static void load() {
try {
nettyPrefix = "io.netty";
Class.forName("io.netty.channel.Channel");
@@ -188,13 +191,8 @@ public final class NMSUtils {
return null;
}
public static boolean is_1_8() {
return version.isHigherThan(ServerVersion.v_1_7_10)
&& version.isLowerThan(ServerVersion.v_1_9);
}
public static void sendSendableWrapper(final Player player, final Sendable sendable) {
sendNMSPacket(player, sendable.asNMSPacket());
NMSUtils.sendNMSPacket(player, sendable.asNMSPacket());
}
public static void sendNMSPacket(final Player player, final Object nmsPacket) {
@@ -1,16 +1,23 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.utils.api;
import io.github.retrooper.packetevents.enums.ClientVersion;
import io.github.retrooper.packetevents.handler.NettyPacketHandler;
import io.github.retrooper.packetevents.packetwrappers.Sendable;
import io.github.retrooper.packetevents.settings.PacketEventsSettings;
import io.github.retrooper.packetevents.utils.NMSUtils;
import io.github.retrooper.packetevents.utils.versionlookup.VersionLookupUtils;
import org.bukkit.entity.Player;
import java.util.HashMap;
import java.util.UUID;
public final class PlayerUtils {
private final HashMap<UUID, ClientVersion> clientVersionsMap = new HashMap<UUID, ClientVersion>();
private final PacketEventsSettings settings = new PacketEventsSettings();
public int getPing(final Player player) {
return NMSUtils.getPlayerPing(player);
@@ -20,6 +27,10 @@ public final class PlayerUtils {
return clientVersionsMap.get(uuid);
}
public int getProtocolVersion(Player player) {
return VersionLookupUtils.getProtocolVersion(player);
}
public ClientVersion getClientVersion(final Player player) {
return getClientVersion(player.getUniqueId());
}
@@ -45,14 +56,18 @@ public final class PlayerUtils {
}
public void uninjectPlayer(final Player player) {
NettyPacketHandler.uninjectPlayer(player);
}
public void uninjectPlayerNow(final Player player) {
NettyPacketHandler.uninjectPlayerNow(player);
if (settings.isUninjectAsync()) {
NettyPacketHandler.uninjectPlayerAsync(player);
} else {
NettyPacketHandler.uninjectPlayer(player);
}
}
public void sendPacket(final Player player, final Sendable sendable) {
NMSUtils.sendSendableWrapper(player, sendable);
}
}
public void sendNMSPacket(final Player player, Object nmsPacket) {
NMSUtils.sendNMSPacket(player, nmsPacket);
}
}
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.utils.api;
import io.github.retrooper.packetevents.enums.ServerVersion;
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.utils.nms_entityfinder;
import io.github.retrooper.packetevents.annotations.Nullable;
@@ -12,7 +15,7 @@ import java.lang.reflect.Method;
public final class EntityFinderUtils {
@Nullable
private static final ServerVersion version = ServerVersion.getVersion();
public static ServerVersion version;
private static Class<?> worldServerClass;
private static Class<?> craftWorldClass;
private static Class<?> entityClass;
@@ -20,7 +23,10 @@ public final class EntityFinderUtils {
private static Method craftWorldGetHandle;
private static Method getBukkitEntity;
static {
private static boolean isServerVersion_v_1_8_x;
public static void load() {
isServerVersion_v_1_8_x = version.isHigherThan(ServerVersion.v_1_7_10) && version.isLowerThan(ServerVersion.v_1_9);
try {
worldServerClass = NMSUtils.getNMSClass("WorldServer");
craftWorldClass = NMSUtils.getOBCClass("CraftWorld");
@@ -30,7 +36,7 @@ public final class EntityFinderUtils {
}
try {
getEntityByIdMethod = worldServerClass.getMethod(getEntityByNameMethodName(), int.class);
getEntityByIdMethod = worldServerClass.getMethod(getEntityByIDMethodName(), int.class);
craftWorldGetHandle = craftWorldClass.getMethod("getHandle");
getBukkitEntity = entityClass.getMethod("getBukkitEntity");
} catch (NoSuchMethodException e) {
@@ -53,6 +59,10 @@ public final class EntityFinderUtils {
if (world == null) {
return null;
}
else if(craftWorldClass == null) {
System.out.println("Craft World class is null wtf");
return null;
}
Object craftWorld = craftWorldClass.cast(world);
Object worldServer = null;
@@ -79,8 +89,13 @@ public final class EntityFinderUtils {
return null;
}
public static String getEntityByNameMethodName() {
if (version.isHigherThan(ServerVersion.v_1_7_10) && version.isLowerThan(ServerVersion.v_1_9)) {
/**
* 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";
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.utils.vector;
public final class Vector3d {
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.utils.vector;
public final class Vector3f {
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.utils.vector;
public final class Vector3i {
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.utils.versionlookup;
import com.comphenix.protocol.ProtocolLibrary;
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.utils.versionlookup;
import org.bukkit.Bukkit;
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.utils.versionlookup;
import org.bukkit.entity.Player;
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.utils.versionlookup;
import org.bukkit.Bukkit;
@@ -0,0 +1,14 @@
/*
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.utils.versionlookup;
import org.bukkit.entity.Player;
public class ProtocolVersionAccessor_v_1_7 {
public static int getProtocolVersion(Player player) {
net.minecraft.server.v1_7_R4.EntityPlayer entityPlayer = ((org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer) player).getHandle();
return entityPlayer.playerConnection.networkManager.getVersion();
}
}
@@ -1,25 +1,46 @@
/*
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.utils.versionlookup;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.enums.ServerVersion;
import org.bukkit.entity.Player;
public class VersionLookupUtils {
private static byte protocolAccessMode;
public static void load() {
protocolAccessMode = (byte) (ViaUtils.isAvailable() ?
0 : ProtocolSupportUtils.isAvailable() ?
1 : ProtocolLibUtils.isAvailable() ?
2 : PacketEvents.getAPI().getServerUtils().getVersion() == ServerVersion.v_1_7_10 ?
3 : -1);
}
/**
* 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
* @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) {
if (ViaUtils.isAvailable()) {
return ViaUtils.getProtocolVersion(player);
} else if (ProtocolSupportUtils.isAvailable()) {
return ProtocolSupportUtils.getProtocolVersion(player);
} else if (ProtocolLibUtils.isAvailable()) {
return ProtocolLibUtils.getProtocolVersion(player);
switch(protocolAccessMode) {
case 0:
return ViaUtils.getProtocolVersion(player);
case 1:
return ProtocolSupportUtils.getProtocolVersion(player);
case 2:
return ProtocolLibUtils.getProtocolVersion(player);
case 3:
return ProtocolVersionAccessor_v_1_7.getProtocolVersion(player);
default:
return -1;
}
return -1;
}
}
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.utils.versionlookup;
import org.bukkit.entity.Player;
@@ -1,3 +1,6 @@
/**
* Copyright (c) 2020 retrooper
*/
package io.github.retrooper.packetevents.utils.versionlookup;
import org.bukkit.Bukkit;