Cut off 1.7.10 injector. We still support 1.7.10 protocol, just not 1.7.10 server software!!!
Attempted reload support again. (Tested on 1.8.8) PacketSide#getOpposite added
This commit is contained in:
1 parent
d966013b69
commit
58f6cf5411
29 files changed
+123
-1352
No files matched your search
@@ -79,7 +79,7 @@ public abstract class ProtocolPacketEvent<T> extends PacketEvent implements Play
|
||||
this.packetType = PacketType.getById(packetSide, user.getConnectionState(),
|
||||
version, packetID);
|
||||
if (this.packetType == null) {
|
||||
throw new PacketProcessException("Failed to map the Packet ID " + packetID + " to a PacketType constant. Packet Side: " + packetSide + ", Connection state: " + user.getConnectionState() + ", Server version: " + serverVersion.getReleaseName());
|
||||
throw new PacketProcessException("Failed to map the Packet ID " + packetID + " to a PacketType constant. Bound: " + packetSide.getOpposite() + ", Connection state: " + user.getConnectionState() + ", Server version: " + serverVersion.getReleaseName());
|
||||
}
|
||||
this.connectionState = user.getConnectionState();
|
||||
}
|
||||
|
||||
@@ -19,5 +19,14 @@
|
||||
package com.github.retrooper.packetevents.protocol;
|
||||
|
||||
public enum PacketSide {
|
||||
CLIENT, SERVER
|
||||
CLIENT, SERVER;
|
||||
|
||||
public PacketSide getOpposite() {
|
||||
if (this == CLIENT) {
|
||||
return SERVER;
|
||||
}
|
||||
else {
|
||||
return CLIENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
+25
@@ -31,6 +31,7 @@ import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class PacketType {
|
||||
private static boolean PREPARED = false;
|
||||
//TODO UPDATE Update packet type mappings (clientbound pt. 1)
|
||||
private static final VersionMapper CLIENTBOUND_PLAY_VERSION_MAPPER = new VersionMapper(
|
||||
ClientVersion.V_1_7_10,
|
||||
@@ -63,6 +64,16 @@ public final class PacketType {
|
||||
ClientVersion.V_1_16_2,
|
||||
ClientVersion.V_1_17);
|
||||
|
||||
public static void prepare() {
|
||||
PacketType.Play.Client.load();
|
||||
PacketType.Play.Server.load();
|
||||
PREPARED = true;
|
||||
}
|
||||
|
||||
public static boolean isPrepared() {
|
||||
return PREPARED;
|
||||
}
|
||||
|
||||
public static PacketTypeCommon getById(PacketSide side, ConnectionState state, ClientVersion version, int packetID) {
|
||||
switch (state) {
|
||||
case HANDSHAKING:
|
||||
@@ -305,6 +316,9 @@ public final class PacketType {
|
||||
|
||||
@Nullable
|
||||
public static PacketTypeCommon getById(ClientVersion version, int packetId) {
|
||||
if (!PREPARED) {
|
||||
PacketType.prepare();
|
||||
}
|
||||
int index = SERVERBOUND_PLAY_VERSION_MAPPER.getIndex(version);
|
||||
Map<Integer, PacketTypeCommon> packetIdMap = PACKET_TYPE_ID_MAP.computeIfAbsent((byte)index, k -> new HashMap<>());
|
||||
return packetIdMap.get(packetId);
|
||||
@@ -324,6 +338,7 @@ public final class PacketType {
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
INDEX = 0;
|
||||
loadPacketIds(ServerboundPacketType_1_7_10.values());
|
||||
loadPacketIds(ServerboundPacketType_1_8.values());
|
||||
loadPacketIds(ServerboundPacketType_1_9.values());
|
||||
@@ -339,6 +354,9 @@ public final class PacketType {
|
||||
}
|
||||
|
||||
public int getId(ClientVersion version) {
|
||||
if (!PREPARED) {
|
||||
PacketType.prepare();
|
||||
}
|
||||
int index = SERVERBOUND_PLAY_VERSION_MAPPER.getIndex(version);
|
||||
return ids[index];
|
||||
}
|
||||
@@ -467,12 +485,18 @@ public final class PacketType {
|
||||
private final int[] ids = new int[CLIENTBOUND_PLAY_VERSION_MAPPER.getVersions().length];
|
||||
|
||||
public int getId(ClientVersion version) {
|
||||
if (!PREPARED) {
|
||||
PacketType.prepare();
|
||||
}
|
||||
int index = CLIENTBOUND_PLAY_VERSION_MAPPER.getIndex(version);
|
||||
return ids[index];
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PacketTypeCommon getById(ClientVersion version, int packetId) {
|
||||
if (!PREPARED) {
|
||||
PacketType.prepare();
|
||||
}
|
||||
int index = CLIENTBOUND_PLAY_VERSION_MAPPER.getIndex(version);
|
||||
Map<Integer, PacketTypeCommon> map = PACKET_TYPE_ID_MAP.get((byte) index);
|
||||
return map.get(packetId);
|
||||
@@ -491,6 +515,7 @@ public final class PacketType {
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
INDEX = 0;
|
||||
loadPacketIds(ClientboundPacketType_1_7_10.values());
|
||||
loadPacketIds(ClientboundPacketType_1_8.values());
|
||||
loadPacketIds(ClientboundPacketType_1_9.values());
|
||||
|
||||
@@ -74,7 +74,7 @@ public class PacketEventsPlugin extends JavaPlugin {
|
||||
case CHAT_MESSAGE:
|
||||
System.out.println("Running 10 seconds later");
|
||||
WrapperPlayClientChatMessage chatMessage = new WrapperPlayClientChatMessage(event);
|
||||
if (chatMessage.getMessage().equalsIgnoreCase("mrmcyeet")) {
|
||||
if (chatMessage.getMessage().equalsIgnoreCase("keyword")) {
|
||||
System.out.println("pipe: " + ChannelHelper.pipelineHandlerNamesAsString(event.getChannel()));
|
||||
event.setCancelled(true);
|
||||
Particle particle = new Particle(ParticleTypes.ANGRY_VILLAGER);
|
||||
|
||||
+2
-3
@@ -23,7 +23,7 @@ import com.github.retrooper.packetevents.event.UserLoginEvent;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import com.github.retrooper.packetevents.util.PacketEventsImplHelper;
|
||||
import io.github.retrooper.packetevents.injector.SpigotChannelInjector;
|
||||
import io.github.retrooper.packetevents.injector.SpigotChannelInjectorLatest;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@@ -35,7 +35,7 @@ public class InternalBukkitListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onJoin(PlayerJoinEvent e) {
|
||||
Player player = e.getPlayer();
|
||||
SpigotChannelInjector injector = (SpigotChannelInjector) PacketEvents.getAPI().getInjector();
|
||||
SpigotChannelInjectorLatest injector = (SpigotChannelInjectorLatest) PacketEvents.getAPI().getInjector();
|
||||
//By accessing user with the player object, we ensure that a valid user is cached.
|
||||
//In the spigot PlayerManager impl, if there was no user cached,
|
||||
//we will create one with help of the Player object.
|
||||
@@ -45,7 +45,6 @@ public class InternalBukkitListener implements Listener {
|
||||
//if we failed to catch it.(shouldn't ever happen really)
|
||||
//TODO With Via we might have to run this a tick AFTER join event (atleast when via & viabackwards & rewind are present)
|
||||
ClientVersion version = PacketEvents.getAPI().getPlayerManager().getClientVersion(player);
|
||||
|
||||
injector.updatePlayer(user, player);
|
||||
}
|
||||
|
||||
|
||||
+8
-10
@@ -32,15 +32,15 @@ import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import com.github.retrooper.packetevents.settings.PacketEventsSettings;
|
||||
import com.github.retrooper.packetevents.util.LogManager;
|
||||
import io.github.retrooper.packetevents.bstats.Metrics;
|
||||
import io.github.retrooper.packetevents.injector.SpigotChannelInjector;
|
||||
import io.github.retrooper.packetevents.bukkit.InternalBukkitListener;
|
||||
import io.github.retrooper.packetevents.injector.SpigotChannelInjectorLatest;
|
||||
import io.github.retrooper.packetevents.manager.player.PlayerManagerImpl;
|
||||
import io.github.retrooper.packetevents.manager.protocol.ProtocolManagerImpl;
|
||||
import io.github.retrooper.packetevents.manager.server.ServerManagerImpl;
|
||||
import io.github.retrooper.packetevents.bukkit.InternalBukkitListener;
|
||||
import io.github.retrooper.packetevents.netty.NettyManagerImpl;
|
||||
import io.github.retrooper.packetevents.util.BukkitLogManager;
|
||||
import io.github.retrooper.packetevents.util.SpigotReflectionUtil;
|
||||
import io.github.retrooper.packetevents.util.viaversion.CustomPipelineUtil;
|
||||
import io.github.retrooper.packetevents.netty.NettyManagerImpl;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
@@ -78,7 +78,7 @@ public class SpigotPacketEventsBuilder {
|
||||
private final ServerManager serverManager = new ServerManagerImpl();
|
||||
private final PlayerManager playerManager = new PlayerManagerImpl();
|
||||
private final NettyManager nettyManager = new NettyManagerImpl();
|
||||
private SpigotChannelInjector injector;
|
||||
private final SpigotChannelInjectorLatest injector = new SpigotChannelInjectorLatest();
|
||||
private final InternalBukkitListener internalBukkitListener = new InternalBukkitListener();
|
||||
private final LogManager logManager = new BukkitLogManager();
|
||||
private boolean loaded;
|
||||
@@ -103,7 +103,6 @@ public class SpigotPacketEventsBuilder {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
|
||||
injector = new SpigotChannelInjector();
|
||||
//Server hasn't bound to the port yet.
|
||||
lateBind = !injector.isServerBound();
|
||||
//If late-bind is enabled, we will inject a bit later.
|
||||
@@ -111,11 +110,10 @@ public class SpigotPacketEventsBuilder {
|
||||
injector.inject();
|
||||
}
|
||||
|
||||
loaded = true;
|
||||
|
||||
//Register internal packet listener (should be the first listener)
|
||||
//This listener doesn't do any modifications to the packets, just reads data
|
||||
getEventManager().registerListener(new InternalPacketListener());
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,9 +138,9 @@ public class SpigotPacketEventsBuilder {
|
||||
return getVersion().toString() + "-beta";//TODO Cut off "-beta" once 2.0 releases
|
||||
}));
|
||||
}
|
||||
|
||||
PacketType.Play.Client.load();
|
||||
PacketType.Play.Server.load();
|
||||
if (PacketType.isPrepared()) {
|
||||
PacketType.prepare();
|
||||
}
|
||||
//TODO Test reloads
|
||||
Runnable postInjectTask = () -> {
|
||||
Bukkit.getPluginManager().registerEvents(internalBukkitListener, plugin);
|
||||
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2021 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.injector;
|
||||
|
||||
public interface PacketCompressionManager {
|
||||
void decompress(Object pipeline, Object buffer, Object output);
|
||||
|
||||
void compress(Object pipeline, Object buffer, Object output);
|
||||
|
||||
void recompress(Object ctx, Object buffer);
|
||||
|
||||
void relocateHandlers(Object pipeline, Object buffer, Object decompressed);
|
||||
}
|
||||
+2
-20
@@ -18,9 +18,7 @@
|
||||
|
||||
package io.github.retrooper.packetevents.injector;
|
||||
|
||||
import io.github.retrooper.packetevents.injector.legacy.compression.PacketCompressionLegacy;
|
||||
import io.github.retrooper.packetevents.injector.latest.compression.PacketCompressionLatest;
|
||||
import io.github.retrooper.packetevents.util.SpigotReflectionUtil;
|
||||
import io.github.retrooper.packetevents.injector.compression.PacketCompressionHandler;
|
||||
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.zip.Inflater;
|
||||
@@ -34,38 +32,22 @@ public class PacketCompressionUtil {
|
||||
public static int MAXIMUM = 2097152;
|
||||
public static final byte[] COMPRESSED_DATA = new byte[8192];
|
||||
|
||||
public static PacketCompressionManager COMPRESSION_MANAGER = null;
|
||||
|
||||
private static void loadManager() {
|
||||
if (COMPRESSION_MANAGER == null) {
|
||||
if (SpigotReflectionUtil.USE_MODERN_NETTY_PACKAGE) {
|
||||
COMPRESSION_MANAGER = new PacketCompressionLatest();
|
||||
}
|
||||
else {
|
||||
COMPRESSION_MANAGER = new PacketCompressionLegacy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static PacketCompressionHandler COMPRESSION_MANAGER = new PacketCompressionHandler();
|
||||
|
||||
|
||||
public static void decompress(Object pipeline, Object buffer, Object output) {
|
||||
loadManager();
|
||||
COMPRESSION_MANAGER.decompress(pipeline, buffer, output);
|
||||
}
|
||||
|
||||
public static void compress(Object pipeline, Object buffer, Object output) {
|
||||
loadManager();
|
||||
COMPRESSION_MANAGER.compress(pipeline, buffer, output);
|
||||
}
|
||||
|
||||
public static void recompress(Object ctx, Object buffer) {
|
||||
loadManager();
|
||||
COMPRESSION_MANAGER.recompress(ctx, buffer);
|
||||
}
|
||||
|
||||
public static void relocateHandlers(Object pipeline, Object buffer, Object decompressed) {
|
||||
loadManager();
|
||||
COMPRESSION_MANAGER.relocateHandlers(pipeline, buffer, decompressed);
|
||||
}
|
||||
}
|
||||
-87
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2021 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.injector;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.event.UserLoginEvent;
|
||||
import com.github.retrooper.packetevents.injector.ChannelInjector;
|
||||
import com.github.retrooper.packetevents.protocol.ConnectionState;
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import io.github.retrooper.packetevents.injector.latest.SpigotChannelInjectorLatest;
|
||||
import io.github.retrooper.packetevents.injector.legacy.SpigotChannelInjectorLegacy;
|
||||
import io.github.retrooper.packetevents.util.SpigotReflectionUtil;
|
||||
|
||||
public class SpigotChannelInjector implements ChannelInjector {
|
||||
private final ChannelInjector injector;
|
||||
|
||||
public SpigotChannelInjector() {
|
||||
this.injector = SpigotReflectionUtil.USE_MODERN_NETTY_PACKAGE
|
||||
? new SpigotChannelInjectorLatest() //1.8+ injector
|
||||
: new SpigotChannelInjectorLegacy(); //1.7 injector
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isServerBound() {
|
||||
return injector.isServerBound();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inject() {
|
||||
injector.inject();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uninject() {
|
||||
injector.uninject();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUser(Object channel, User user) {
|
||||
injector.updateUser(channel, user);
|
||||
}
|
||||
|
||||
public void updatePlayer(User user, Object player) {
|
||||
PacketEvents.getAPI().getEventManager().callEvent(new UserLoginEvent(user, player));
|
||||
Object channel = user.getChannel();
|
||||
if (channel == null) {
|
||||
channel = PacketEvents.getAPI().getPlayerManager().getChannel(player);
|
||||
}
|
||||
setPlayer(channel, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPlayer(Object player) {
|
||||
return injector.hasPlayer(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUser(Object channel) {
|
||||
return injector.getUser(channel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlayer(Object channel, Object player) {
|
||||
injector.setPlayer(channel, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeConnectionState(Object channel, ConnectionState connectionState) {
|
||||
injector.changeConnectionState(channel, connectionState);
|
||||
}
|
||||
}
|
||||
+15
-5
@@ -16,18 +16,20 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.injector.latest;
|
||||
package io.github.retrooper.packetevents.injector;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.event.UserLoginEvent;
|
||||
import com.github.retrooper.packetevents.injector.ChannelInjector;
|
||||
import com.github.retrooper.packetevents.netty.channel.ChannelHelper;
|
||||
import com.github.retrooper.packetevents.protocol.ConnectionState;
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import com.github.retrooper.packetevents.util.reflection.ClassUtil;
|
||||
import com.github.retrooper.packetevents.util.reflection.ReflectionObject;
|
||||
import io.github.retrooper.packetevents.injector.latest.connection.ServerChannelHandlerLatest;
|
||||
import io.github.retrooper.packetevents.injector.latest.connection.ServerConnectionInitializerLatest;
|
||||
import io.github.retrooper.packetevents.injector.latest.handlers.PacketDecoderLatest;
|
||||
import io.github.retrooper.packetevents.injector.latest.handlers.PacketEncoderLatest;
|
||||
import io.github.retrooper.packetevents.injector.connection.ServerChannelHandlerLatest;
|
||||
import io.github.retrooper.packetevents.injector.connection.ServerConnectionInitializerLatest;
|
||||
import io.github.retrooper.packetevents.injector.handlers.PacketDecoderLatest;
|
||||
import io.github.retrooper.packetevents.injector.handlers.PacketEncoderLatest;
|
||||
import io.github.retrooper.packetevents.util.InjectedList;
|
||||
import io.github.retrooper.packetevents.util.SpigotReflectionUtil;
|
||||
import io.github.retrooper.packetevents.util.protocolsupport.ProtocolSupportUtil;
|
||||
@@ -50,6 +52,14 @@ public class SpigotChannelInjectorLatest implements ChannelInjector {
|
||||
private List<Object> networkManagers;
|
||||
private int connectionChannelsListIndex = -1;
|
||||
|
||||
public void updatePlayer(User user, Object player) {
|
||||
PacketEvents.getAPI().getEventManager().callEvent(new UserLoginEvent(user, player));
|
||||
Object channel = user.getChannel();
|
||||
if (channel == null) {
|
||||
channel = PacketEvents.getAPI().getPlayerManager().getChannel(player);
|
||||
}
|
||||
setPlayer(channel, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isServerBound() {
|
||||
+3
-9
@@ -16,13 +16,12 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.injector.latest.compression;
|
||||
package io.github.retrooper.packetevents.injector.compression;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.netty.buffer.ByteBufHelper;
|
||||
import io.github.retrooper.packetevents.injector.PacketCompressionManager;
|
||||
import io.github.retrooper.packetevents.injector.PacketCompressionUtil;
|
||||
import io.github.retrooper.packetevents.injector.latest.handlers.PacketDecoderLatest;
|
||||
import io.github.retrooper.packetevents.injector.handlers.PacketDecoderLatest;
|
||||
import io.github.retrooper.packetevents.util.SpigotReflectionUtil;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
@@ -31,8 +30,7 @@ import io.netty.channel.ChannelPipeline;
|
||||
|
||||
import java.util.zip.DataFormatException;
|
||||
|
||||
public class PacketCompressionLatest implements PacketCompressionManager {
|
||||
@Override
|
||||
public class PacketCompressionHandler {
|
||||
public void decompress(Object rawPipeline, Object rawBuffer, Object rawOutput) {
|
||||
ChannelPipeline pipeline = (ChannelPipeline) rawPipeline;
|
||||
ByteBuf buffer = (ByteBuf) rawBuffer;
|
||||
@@ -70,7 +68,6 @@ public class PacketCompressionLatest implements PacketCompressionManager {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void compress(Object rawPipeline, Object rawBuffer, Object rawOutput) {
|
||||
ChannelPipeline pipeline = (ChannelPipeline) rawPipeline;
|
||||
ByteBuf buffer = (ByteBuf) rawBuffer;
|
||||
@@ -101,7 +98,6 @@ public class PacketCompressionLatest implements PacketCompressionManager {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recompress(Object rawCtx, Object rawBuffer) {
|
||||
ChannelHandlerContext ctx = (ChannelHandlerContext) rawCtx;
|
||||
ByteBuf buffer = (ByteBuf) rawBuffer;
|
||||
@@ -114,8 +110,6 @@ public class PacketCompressionLatest implements PacketCompressionManager {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void relocateHandlers(Object rawPipeline, Object rawBuffer, Object rawDecompressed) {
|
||||
ChannelPipeline pipeline = (ChannelPipeline) rawPipeline;
|
||||
ByteBuf buffer = (ByteBuf) rawBuffer;
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.injector.latest.connection;
|
||||
package io.github.retrooper.packetevents.injector.connection;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.ConnectionState;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.injector.latest.connection;
|
||||
package io.github.retrooper.packetevents.injector.connection;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.ConnectionState;
|
||||
import io.netty.channel.Channel;
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.injector.latest.connection;
|
||||
package io.github.retrooper.packetevents.injector.connection;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.util.SpigotReflectionUtil;
|
||||
+39
-8
@@ -16,7 +16,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.injector.latest.connection;
|
||||
package io.github.retrooper.packetevents.injector.connection;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.event.UserConnectEvent;
|
||||
@@ -28,8 +28,9 @@ import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import com.github.retrooper.packetevents.protocol.player.UserProfile;
|
||||
import com.github.retrooper.packetevents.util.reflection.ClassUtil;
|
||||
import com.github.retrooper.packetevents.util.reflection.ReflectionObject;
|
||||
import io.github.retrooper.packetevents.injector.latest.handlers.PacketDecoderLatest;
|
||||
import io.github.retrooper.packetevents.injector.latest.handlers.PacketEncoderLatest;
|
||||
import io.github.retrooper.packetevents.injector.handlers.PacketDecoderLatest;
|
||||
import io.github.retrooper.packetevents.injector.handlers.PacketEncoderLatest;
|
||||
import io.github.retrooper.packetevents.util.protocolsupport.ProtocolSupportUtil;
|
||||
import io.github.retrooper.packetevents.util.viaversion.ViaVersionUtil;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
@@ -37,7 +38,6 @@ import io.netty.channel.epoll.EpollSocketChannel;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||
import io.netty.handler.codec.MessageToByteEncoder;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
@@ -48,7 +48,7 @@ public class ServerConnectionInitializerLatest {
|
||||
private static void destroyHandlers(Channel channel) {
|
||||
channel.pipeline().remove(PacketEvents.ENCODER_NAME);
|
||||
ChannelHandler decoder = channel.pipeline().get(PacketEvents.DECODER_NAME);
|
||||
if (decoder instanceof PacketDecoderLatest) {
|
||||
if (decoder != null && ClassUtil.getClassSimpleName(decoder.getClass()).equals("PacketDecoderLatest")) {
|
||||
channel.pipeline().remove(PacketEvents.DECODER_NAME);
|
||||
} else if (ViaVersionUtil.isAvailable()) {
|
||||
decoder = channel.pipeline().get("decoder");
|
||||
@@ -59,8 +59,8 @@ public class ServerConnectionInitializerLatest {
|
||||
if (injectedDecoder instanceof PacketDecoderLatest) {
|
||||
PacketDecoderLatest peDecoder = (PacketDecoderLatest) injectedDecoder;
|
||||
reflectMCDecoder.writeObject(0, peDecoder.mcDecoder);
|
||||
} else if (ClassUtil.getClassSimpleName(injectedDecoder.getClass()).equals("PacketDecoderLatest")
|
||||
|| ClassUtil.getClassSimpleName(injectedDecoder.getClass()).equals("PacketDecoderModern")) {
|
||||
} else if (injectedDecoder != null && (ClassUtil.getClassSimpleName(injectedDecoder.getClass()).equals("PacketDecoderLatest")
|
||||
|| ClassUtil.getClassSimpleName(injectedDecoder.getClass()).equals("PacketDecoderModern"))) {
|
||||
//Some other packetevents instance already injected. Let us find our child decoder somewhere in here.
|
||||
ReflectionObject reflectInjectedDecoder = new ReflectionObject(injectedDecoder);
|
||||
List<Object> decoders = reflectInjectedDecoder.readList(0);
|
||||
@@ -76,9 +76,11 @@ public class ServerConnectionInitializerLatest {
|
||||
!(channel instanceof NioSocketChannel)) {
|
||||
return;
|
||||
}
|
||||
boolean isReload = false;
|
||||
if (channel.pipeline().get(PacketEvents.ENCODER_NAME) != null) {
|
||||
//This is a reload...
|
||||
destroyHandlers(channel);
|
||||
isReload = true;
|
||||
}
|
||||
User user = new User(channel, connectionState, null, new UserProfile(null, null));
|
||||
UserConnectEvent connectEvent = new UserConnectEvent(user);
|
||||
@@ -89,7 +91,36 @@ public class ServerConnectionInitializerLatest {
|
||||
}
|
||||
ProtocolManager.USERS.put(channel, user);
|
||||
try {
|
||||
channel.pipeline().addAfter("splitter", PacketEvents.DECODER_NAME, new PacketDecoderLatest(user));
|
||||
PacketDecoderLatest decoder = new PacketDecoderLatest(user);
|
||||
if (!isReload) {
|
||||
channel.pipeline().addAfter("splitter", PacketEvents.DECODER_NAME, decoder);
|
||||
}
|
||||
else {
|
||||
decoder.handledCompression = true;
|
||||
if (ViaVersionUtil.isAvailable()) {
|
||||
//Inject our decoder into ViaVersion's decoder (because we have to)
|
||||
ChannelHandler viaDecoder = channel.pipeline().get("decoder");
|
||||
ReflectionObject reflectionObject = new ReflectionObject(viaDecoder);
|
||||
ByteToMessageDecoder mcDecoder = reflectionObject.readObject(0, ByteToMessageDecoder.class);
|
||||
String decoderClassName = ClassUtil.getClassSimpleName(mcDecoder.getClass());
|
||||
if (decoderClassName.equals("PacketDecoderModern")
|
||||
|| decoderClassName.equals("PacketDecoderLatest")) {
|
||||
//We aren't the first packetevents instance to inject into ViaVersion's decoder
|
||||
ReflectionObject reflectPacketDecoderModern = new ReflectionObject(mcDecoder);
|
||||
List<ByteToMessageDecoder> decoders = reflectPacketDecoderModern.readList(0);
|
||||
decoders.add(decoder);
|
||||
} else {
|
||||
//We are the first packetevents instance to inject into ViaVersion's decoder
|
||||
decoder.mcDecoder = mcDecoder;
|
||||
reflectionObject.write(ByteToMessageDecoder.class, 0, decoder);
|
||||
}
|
||||
} else if (ProtocolSupportUtil.isAvailable()) {
|
||||
channel.pipeline().addAfter("ps_decoder_transformer", PacketEvents.DECODER_NAME, decoder);
|
||||
}
|
||||
else {
|
||||
channel.pipeline().addAfter("decompress", PacketEvents.DECODER_NAME, decoder);
|
||||
}
|
||||
}
|
||||
} catch (NoSuchElementException ex) {
|
||||
String handlers = ChannelHelper.pipelineHandlerNamesAsString(channel);
|
||||
throw new IllegalStateException("PacketEvents failed to add a decoder to the netty pipeline. Pipeline handlers: " + handlers, ex);
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.injector.latest.handlers;
|
||||
package io.github.retrooper.packetevents.injector.handlers;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.exception.PacketProcessException;
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.injector.latest.handlers;
|
||||
package io.github.retrooper.packetevents.injector.handlers;
|
||||
|
||||
import com.github.retrooper.packetevents.exception.PacketProcessException;
|
||||
import com.github.retrooper.packetevents.protocol.ConnectionState;
|
||||
-235
@@ -1,235 +0,0 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2021 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.injector.legacy;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.injector.ChannelInjector;
|
||||
import com.github.retrooper.packetevents.protocol.ConnectionState;
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import com.github.retrooper.packetevents.util.reflection.ReflectionObject;
|
||||
import io.github.retrooper.packetevents.injector.legacy.handlers.PacketDecoderLegacy;
|
||||
import io.github.retrooper.packetevents.injector.legacy.handlers.PacketEncoderLegacy;
|
||||
import io.github.retrooper.packetevents.injector.legacy.connection.ServerConnectionInitializerLegacy;
|
||||
import io.github.retrooper.packetevents.injector.legacy.connection.ServerChannelHandlerLegacy;
|
||||
import io.github.retrooper.packetevents.util.InjectedList;
|
||||
import io.github.retrooper.packetevents.util.SpigotReflectionUtil;
|
||||
import io.github.retrooper.packetevents.util.protocolsupport.ProtocolSupportUtil;
|
||||
import net.minecraft.util.io.netty.channel.Channel;
|
||||
import net.minecraft.util.io.netty.channel.ChannelFuture;
|
||||
import net.minecraft.util.io.netty.channel.ChannelHandler;
|
||||
import net.minecraft.util.io.netty.channel.ChannelPipeline;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class SpigotChannelInjectorLegacy implements ChannelInjector {
|
||||
//Channels that process connecting clients.
|
||||
private final Set<Channel> injectedConnectionChannels = new HashSet<>();
|
||||
private List<Object> networkManagers;
|
||||
private int connectionChannelsListIndex = -1;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isServerBound() {
|
||||
//We want to check if the server has been bound to the port already.
|
||||
Object serverConnection = SpigotReflectionUtil.getMinecraftServerConnectionInstance();
|
||||
if (serverConnection != null) {
|
||||
ReflectionObject reflectServerConnection = new ReflectionObject(serverConnection);
|
||||
//There should only be 2 lists.
|
||||
for (int i = 0; i < 2; i++) {
|
||||
List<?> list = reflectServerConnection.readList(i);
|
||||
for (Object value : list) {
|
||||
if (value instanceof ChannelFuture) {
|
||||
connectionChannelsListIndex = i;
|
||||
//Found the right list.
|
||||
//It has connection channels, so the server has been bound.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inject() {
|
||||
Object serverConnection = SpigotReflectionUtil.getMinecraftServerConnectionInstance();
|
||||
if (serverConnection != null) {
|
||||
ReflectionObject reflectServerConnection = new ReflectionObject(serverConnection);
|
||||
List<ChannelFuture> connectionChannelFutures = reflectServerConnection.readList(connectionChannelsListIndex);
|
||||
InjectedList<ChannelFuture> wrappedList = new InjectedList<>(connectionChannelFutures, future -> {
|
||||
//Each time a channel future is added, we run this.
|
||||
//This is automatically also ran for the elements already added before we wrapped the list.
|
||||
Channel channel = future.channel();
|
||||
//Inject into the server connection channel.
|
||||
injectServerChannel(channel);
|
||||
//Make sure to store it, so we can uninject later on.
|
||||
injectedConnectionChannels.add(channel);
|
||||
});
|
||||
//Replace the list with our wrapped one.
|
||||
reflectServerConnection.writeList(connectionChannelsListIndex, wrappedList);
|
||||
|
||||
//Player channels might have been registered already. Let us add our handlers. We are a little late though.
|
||||
List<Object> networkManagers = SpigotReflectionUtil.getNetworkManagers();
|
||||
for (Object networkManager : networkManagers) {
|
||||
ReflectionObject networkManagerWrapper = new ReflectionObject(networkManager);
|
||||
Channel channel = networkManagerWrapper.readObject(0, Channel.class);
|
||||
if (channel == null) {
|
||||
continue;
|
||||
}
|
||||
ServerConnectionInitializerLegacy.initChannel(channel, ConnectionState.PLAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uninject() {
|
||||
//Uninject our connection handler from these connection channels.
|
||||
for (Channel connectionChannel : injectedConnectionChannels) {
|
||||
uninjectServerChannel(connectionChannel);
|
||||
}
|
||||
injectedConnectionChannels.clear();
|
||||
Object serverConnection = SpigotReflectionUtil.getMinecraftServerConnectionInstance();
|
||||
if (serverConnection != null) {
|
||||
ReflectionObject reflectServerConnection = new ReflectionObject(serverConnection);
|
||||
List<ChannelFuture> connectionChannelFutures = reflectServerConnection.readList(connectionChannelsListIndex);
|
||||
if (connectionChannelFutures instanceof InjectedList) {
|
||||
//Let us unwrap this. We no longer want to listen to connecting channels.
|
||||
reflectServerConnection.writeList(connectionChannelsListIndex,
|
||||
((InjectedList<ChannelFuture>) connectionChannelFutures).originalList());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void injectServerChannel(Channel serverChannel) {
|
||||
ChannelPipeline pipeline = serverChannel.pipeline();
|
||||
ChannelHandler connectionHandler = pipeline.get(PacketEvents.CONNECTION_HANDLER_NAME);
|
||||
if (connectionHandler != null) {
|
||||
//Why does it already exist?
|
||||
pipeline.remove(PacketEvents.CONNECTION_HANDLER_NAME);
|
||||
}
|
||||
//Make sure we handle connections after ProtocolSupport.
|
||||
if (pipeline.get("SpigotNettyServerChannelHandler#0") != null) {
|
||||
pipeline.addAfter("SpigotNettyServerChannelHandler#0", PacketEvents.CONNECTION_HANDLER_NAME, new ServerChannelHandlerLegacy());
|
||||
}
|
||||
//Make sure we handle connections after Geyser.
|
||||
else if (pipeline.get("floodgate-init") != null) {
|
||||
pipeline.addAfter("floodgate-init", PacketEvents.CONNECTION_HANDLER_NAME, new ServerChannelHandlerLegacy());
|
||||
}
|
||||
//Otherwise, we just don't care and make sure we are last.
|
||||
else {
|
||||
pipeline.addFirst(PacketEvents.CONNECTION_HANDLER_NAME, new ServerChannelHandlerLegacy());
|
||||
}
|
||||
|
||||
if (networkManagers == null) {
|
||||
networkManagers = SpigotReflectionUtil.getNetworkManagers();
|
||||
}
|
||||
//Make sure we handled all connected clients.
|
||||
synchronized (networkManagers) {
|
||||
for (Object networkManager : networkManagers) {
|
||||
ReflectionObject networkManagerWrapper = new ReflectionObject(networkManager);
|
||||
Channel channel = networkManagerWrapper.readObject(0, Channel.class);
|
||||
if (channel.isOpen()) {
|
||||
if (channel.localAddress().equals(serverChannel.localAddress())) {
|
||||
channel.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void uninjectServerChannel(Channel serverChannel) {
|
||||
serverChannel.pipeline().remove(PacketEvents.CONNECTION_HANDLER_NAME);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public User getUser(Object channel) {
|
||||
return getEncoder((Channel) channel).user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeConnectionState(Object ch, @Nullable ConnectionState connectionState) {
|
||||
Channel channel = (Channel) ch;
|
||||
PacketEncoderLegacy encoder = getEncoder(channel);
|
||||
if (encoder != null) {
|
||||
//Change connection state in encoder
|
||||
encoder.user.setConnectionState(connectionState);
|
||||
}
|
||||
|
||||
//On 1.7 this decoder is sharable, we can re-add it to the pipeline without cloning.
|
||||
PacketDecoderLegacy decoder = getDecoder(channel);
|
||||
if (decoder != null) {
|
||||
//Change connection state in decoder
|
||||
decoder.user.setConnectionState(connectionState);
|
||||
if (connectionState == ConnectionState.PLAY) {
|
||||
if (ProtocolSupportUtil.isAvailable()) {
|
||||
channel.pipeline().remove(PacketEvents.DECODER_NAME);
|
||||
channel.pipeline().addAfter("ps_decoder_transformer", PacketEvents.DECODER_NAME, decoder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUser(Object channel, User user) {
|
||||
PacketEncoderLegacy encoder = getEncoder((Channel) channel);
|
||||
if (encoder != null) {
|
||||
encoder.user = user;
|
||||
}
|
||||
|
||||
PacketDecoderLegacy decoder = getDecoder((Channel) channel);
|
||||
if (decoder != null) {
|
||||
decoder.user = user;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlayer(Object channel, Object player) {
|
||||
PacketEncoderLegacy encoder = getEncoder((Channel) channel);
|
||||
if (encoder != null) {
|
||||
encoder.player = (Player) player;
|
||||
}
|
||||
|
||||
PacketDecoderLegacy decoder = getDecoder((Channel) channel);
|
||||
if (decoder != null) {
|
||||
decoder.player = (Player) player;
|
||||
decoder.user.getProfile().setUUID(((Player) player).getUniqueId());
|
||||
decoder.user.getProfile().setName(((Player) player).getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPlayer(Object player) {
|
||||
Object channel = PacketEvents.getAPI().getPlayerManager().getChannel(player);
|
||||
return channel != null && getEncoder((Channel) channel).player != null;
|
||||
}
|
||||
|
||||
private PacketEncoderLegacy getEncoder(Channel channel) {
|
||||
return (PacketEncoderLegacy) channel.pipeline().get(PacketEvents.ENCODER_NAME);
|
||||
}
|
||||
|
||||
private PacketDecoderLegacy getDecoder(Channel channel) {
|
||||
return (PacketDecoderLegacy) channel.pipeline().get(PacketEvents.DECODER_NAME);
|
||||
}
|
||||
|
||||
}
|
||||
-134
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2021 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.injector.legacy.compression;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.netty.buffer.ByteBufHelper;
|
||||
import io.github.retrooper.packetevents.injector.PacketCompressionManager;
|
||||
import io.github.retrooper.packetevents.injector.PacketCompressionUtil;
|
||||
import io.github.retrooper.packetevents.injector.legacy.handlers.PacketDecoderLegacy;
|
||||
import io.github.retrooper.packetevents.util.SpigotReflectionUtil;
|
||||
import net.minecraft.util.io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.util.io.netty.channel.ChannelHandler;
|
||||
import net.minecraft.util.io.netty.channel.ChannelHandlerContext;
|
||||
import net.minecraft.util.io.netty.channel.ChannelPipeline;
|
||||
|
||||
import java.util.zip.DataFormatException;
|
||||
|
||||
public class PacketCompressionLegacy implements PacketCompressionManager {
|
||||
@Override
|
||||
public void decompress(Object rawPipeline, Object rawBuffer, Object rawOutput) {
|
||||
ChannelPipeline pipeline = (ChannelPipeline) rawPipeline;
|
||||
ByteBuf buffer = (ByteBuf) rawBuffer;
|
||||
if (!buffer.isReadable()) return;
|
||||
ByteBuf output = (ByteBuf) rawOutput;
|
||||
ChannelHandler decompressionHandler = pipeline.get("decompress");
|
||||
if (!SpigotReflectionUtil.BYTE_TO_MESSAGE_DECODER.isInstance(decompressionHandler)) {
|
||||
//ViaRewind might have replaced the decompressor with an empty handler, so we can just skip the decompression process.
|
||||
output.writeBytes(buffer);
|
||||
return;
|
||||
}
|
||||
int dataLength = ByteBufHelper.readVarInt(buffer);
|
||||
if (dataLength == 0) {
|
||||
output.writeBytes(buffer.readBytes(buffer.readableBytes()));
|
||||
} else {
|
||||
if (dataLength < PacketCompressionUtil.THRESHOLD) {
|
||||
throw new RuntimeException("Badly compressed packet - size of " + dataLength + " is below server threshold of " + PacketCompressionUtil.THRESHOLD);
|
||||
}
|
||||
|
||||
if (dataLength > PacketCompressionUtil.MAXIMUM) {
|
||||
throw new RuntimeException("Badly compressed packet - size of " + dataLength + " is larger than protocol maximum of " + PacketCompressionUtil.MAXIMUM);
|
||||
}
|
||||
|
||||
byte[] compressedData = new byte[buffer.readableBytes()];
|
||||
buffer.readBytes(compressedData);
|
||||
PacketCompressionUtil.INFLATER.setInput(compressedData);
|
||||
byte[] decompressedData = new byte[dataLength];
|
||||
try {
|
||||
PacketCompressionUtil.INFLATER.inflate(decompressedData);
|
||||
} catch (DataFormatException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
output.writeBytes(decompressedData);
|
||||
PacketCompressionUtil.INFLATER.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void compress(Object rawPipeline, Object rawBuffer, Object rawOutput) {
|
||||
ChannelPipeline pipeline = (ChannelPipeline) rawPipeline;
|
||||
ByteBuf buffer = (ByteBuf) rawBuffer;
|
||||
if (!buffer.isReadable()) return;
|
||||
ByteBuf output = (ByteBuf) rawOutput;
|
||||
ChannelHandler compressionHandler = pipeline.get("compress");
|
||||
if (!SpigotReflectionUtil.MESSAGE_TO_BYTE_ENCODER.isInstance(compressionHandler)) {
|
||||
//ViaRewind might have replaced the compressor with an empty handler, so we can just skip the compression process.
|
||||
output.writeBytes(buffer);
|
||||
return;
|
||||
}
|
||||
int dataLength = buffer.readableBytes();
|
||||
if (dataLength < PacketCompressionUtil.THRESHOLD) {
|
||||
ByteBufHelper.writeVarInt(output, 0);
|
||||
output.writeBytes(buffer);
|
||||
} else {
|
||||
byte[] decompressedData = new byte[dataLength];
|
||||
buffer.readBytes(decompressedData);
|
||||
ByteBufHelper.writeVarInt(output, decompressedData.length);
|
||||
PacketCompressionUtil.DEFLATER.setInput(decompressedData, 0, decompressedData.length);
|
||||
PacketCompressionUtil.DEFLATER.finish();
|
||||
|
||||
while (!PacketCompressionUtil.DEFLATER.finished()) {
|
||||
int deflateResult = PacketCompressionUtil.DEFLATER.deflate(PacketCompressionUtil.COMPRESSED_DATA);
|
||||
output.writeBytes(PacketCompressionUtil.COMPRESSED_DATA, 0, deflateResult);
|
||||
}
|
||||
PacketCompressionUtil.DEFLATER.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recompress(Object rawCtx, Object rawBuffer) {
|
||||
ChannelHandlerContext ctx = (ChannelHandlerContext) rawCtx;
|
||||
ByteBuf buffer = (ByteBuf) rawBuffer;
|
||||
ByteBuf compressed = ctx.alloc().buffer();
|
||||
compress(ctx.pipeline(), buffer, compressed);
|
||||
try {
|
||||
buffer.clear().writeBytes(compressed);
|
||||
} finally {
|
||||
compressed.release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void relocateHandlers(Object rawPipeline, Object rawBuffer, Object rawDecompressed) {
|
||||
ChannelPipeline pipeline = (ChannelPipeline) rawPipeline;
|
||||
ByteBuf buffer = (ByteBuf) rawBuffer;
|
||||
ByteBuf decompressed = (ByteBuf) rawDecompressed;
|
||||
try {
|
||||
buffer.clear().writeBytes(decompressed);
|
||||
} finally {
|
||||
decompressed.release();
|
||||
}
|
||||
ChannelHandler encoder = pipeline.remove(PacketEvents.ENCODER_NAME);
|
||||
pipeline.addAfter("compress", PacketEvents.ENCODER_NAME, encoder);
|
||||
|
||||
PacketDecoderLegacy decoder = (PacketDecoderLegacy) pipeline.remove(PacketEvents.DECODER_NAME);
|
||||
pipeline.addAfter("decompress", PacketEvents.DECODER_NAME, new PacketDecoderLegacy(decoder));
|
||||
}
|
||||
}
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2021 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.injector.legacy.connection;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.protocol.ConnectionState;
|
||||
import net.minecraft.util.io.netty.channel.Channel;
|
||||
import net.minecraft.util.io.netty.channel.ChannelHandlerContext;
|
||||
import net.minecraft.util.io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import net.minecraft.util.io.netty.channel.ChannelInitializer;
|
||||
|
||||
public class ServerChannelHandlerLegacy extends ChannelInboundHandlerAdapter {
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
Channel channel = (Channel) msg;
|
||||
channel.pipeline().addFirst(PacketEvents.SERVER_CHANNEL_HANDLER_NAME, new ChannelInitializer<Channel>() {
|
||||
@Override
|
||||
protected void initChannel(Channel channel) throws Exception {
|
||||
ServerConnectionInitializerLegacy.initChannel(channel, ConnectionState.HANDSHAKING);
|
||||
}
|
||||
});
|
||||
super.channelRead(ctx, msg);
|
||||
}
|
||||
}
|
||||
-74
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2021 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.injector.legacy.connection;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.event.UserConnectEvent;
|
||||
import com.github.retrooper.packetevents.event.UserDisconnectEvent;
|
||||
import com.github.retrooper.packetevents.manager.protocol.ProtocolManager;
|
||||
import com.github.retrooper.packetevents.netty.channel.ChannelHelper;
|
||||
import com.github.retrooper.packetevents.protocol.ConnectionState;
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import com.github.retrooper.packetevents.protocol.player.UserProfile;
|
||||
import io.github.retrooper.packetevents.injector.legacy.handlers.PacketDecoderLegacy;
|
||||
import io.github.retrooper.packetevents.injector.legacy.handlers.PacketEncoderLegacy;
|
||||
import net.minecraft.util.io.netty.channel.Channel;
|
||||
import net.minecraft.util.io.netty.channel.socket.nio.NioSocketChannel;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public class ServerConnectionInitializerLegacy {
|
||||
public static void initChannel(Object ch, ConnectionState connectionState) {
|
||||
Channel channel = (Channel) ch;
|
||||
//1.7 has no EpollSocketChannel
|
||||
if (!(channel instanceof NioSocketChannel)) {
|
||||
return;
|
||||
}
|
||||
User user = new User(channel, connectionState, null, new UserProfile(null, null));
|
||||
UserConnectEvent connectEvent = new UserConnectEvent(user);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(connectEvent);
|
||||
if (connectEvent.isCancelled()) {
|
||||
channel.unsafe().closeForcibly();
|
||||
return;
|
||||
}
|
||||
ProtocolManager.USERS.put(channel, user);
|
||||
try {
|
||||
channel.pipeline().addAfter("splitter", PacketEvents.DECODER_NAME, new PacketDecoderLegacy(user));
|
||||
} catch (NoSuchElementException ex) {
|
||||
String handlers = ChannelHelper.pipelineHandlerNamesAsString(channel);
|
||||
throw new IllegalStateException("PacketEvents failed to add a decoder to the netty pipeline. Pipeline handlers: " + handlers, ex);
|
||||
}
|
||||
//No need to account for ViaVersion, as they don't support 1.7.10
|
||||
channel.pipeline().addBefore("encoder", PacketEvents.ENCODER_NAME, new PacketEncoderLegacy(user));
|
||||
}
|
||||
|
||||
public static void destroyChannel(Object ch) {
|
||||
Channel channel = (Channel) ch;
|
||||
//1.7 has no EpollSocketChannel
|
||||
if (!(channel instanceof NioSocketChannel)) {
|
||||
return;
|
||||
}
|
||||
User user = ProtocolManager.USERS.get(channel);
|
||||
UserDisconnectEvent disconnectEvent = new UserDisconnectEvent(user);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(disconnectEvent);
|
||||
channel.pipeline().remove(PacketEvents.DECODER_NAME);
|
||||
channel.pipeline().remove(PacketEvents.ENCODER_NAME);
|
||||
ProtocolManager.USERS.remove(channel);
|
||||
}
|
||||
}
|
||||
-111
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2021 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.injector.legacy.handlers;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.exception.PacketProcessException;
|
||||
import com.github.retrooper.packetevents.protocol.ConnectionState;
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import com.github.retrooper.packetevents.util.ExceptionUtil;
|
||||
import com.github.retrooper.packetevents.util.PacketEventsImplHelper;
|
||||
import io.github.retrooper.packetevents.injector.PacketCompressionUtil;
|
||||
import io.github.retrooper.packetevents.util.SpigotReflectionUtil;
|
||||
import net.minecraft.util.io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.util.io.netty.channel.ChannelHandler;
|
||||
import net.minecraft.util.io.netty.channel.ChannelHandlerContext;
|
||||
import net.minecraft.util.io.netty.handler.codec.MessageToMessageDecoder;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
public class PacketDecoderLegacy extends MessageToMessageDecoder<ByteBuf> {
|
||||
public volatile Player player;
|
||||
public User user;
|
||||
public boolean handledCompression;
|
||||
private boolean skipDoubleTransform;
|
||||
private final List<Runnable> postTasks = new ArrayList<>();
|
||||
|
||||
public PacketDecoderLegacy(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public PacketDecoderLegacy(PacketDecoderLegacy decoder) {
|
||||
this.player = decoder.player;
|
||||
this.user = decoder.user;
|
||||
this.handledCompression = decoder.handledCompression;
|
||||
this.skipDoubleTransform = decoder.skipDoubleTransform;
|
||||
postTasks.clear();
|
||||
postTasks.addAll(decoder.postTasks);
|
||||
}
|
||||
|
||||
public void read(ChannelHandlerContext ctx, ByteBuf input, List<Object> out) throws Exception {
|
||||
if (skipDoubleTransform) {
|
||||
skipDoubleTransform = false;
|
||||
out.add(input.retain());
|
||||
}
|
||||
ByteBuf outputBuffer = ctx.alloc().buffer().writeBytes(input);
|
||||
try {
|
||||
boolean doRecompression =
|
||||
handleCompressionOrder(ctx, outputBuffer);
|
||||
//TODO Use protocol translation dependencies on spigot!
|
||||
PacketEventsImplHelper.handleServerBoundPacket(ctx.channel(), user, player, outputBuffer, false);
|
||||
if (outputBuffer.isReadable()) {
|
||||
if (doRecompression) {
|
||||
PacketCompressionUtil.recompress(ctx, outputBuffer);
|
||||
skipDoubleTransform = true;
|
||||
}
|
||||
out.add(outputBuffer.retain());
|
||||
}
|
||||
} finally {
|
||||
outputBuffer.release();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> out) throws Exception {
|
||||
read(ctx, byteBuf, out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
super.exceptionCaught(ctx, cause);
|
||||
//Check if the minecraft server will already print our exception for us.
|
||||
if (ExceptionUtil.isException(cause, PacketProcessException.class) && !SpigotReflectionUtil.isMinecraftServerInstanceDebugging()
|
||||
&& (user == null || user.getConnectionState() != ConnectionState.HANDSHAKING)) {
|
||||
cause.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean handleCompressionOrder(ChannelHandlerContext ctx, ByteBuf buffer) {
|
||||
if (handledCompression) return false;
|
||||
int decoderIndex = ctx.pipeline().names().indexOf("decompress");
|
||||
if (decoderIndex == -1) return false;
|
||||
handledCompression = true;
|
||||
if (decoderIndex > ctx.pipeline().names().indexOf(PacketEvents.DECODER_NAME)) {
|
||||
// Need to decompress this packet due to bad order
|
||||
ByteBuf decompressed = ctx.alloc().buffer();
|
||||
PacketCompressionUtil.decompress(ctx.pipeline(), buffer, decompressed);
|
||||
PacketCompressionUtil.relocateHandlers(ctx.pipeline(), buffer, decompressed);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
-97
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2021 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.injector.legacy.handlers;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.event.PacketSendEvent;
|
||||
import com.github.retrooper.packetevents.event.UserDisconnectEvent;
|
||||
import com.github.retrooper.packetevents.exception.PacketProcessException;
|
||||
import com.github.retrooper.packetevents.manager.protocol.ProtocolManager;
|
||||
import com.github.retrooper.packetevents.netty.buffer.ByteBufHelper;
|
||||
import com.github.retrooper.packetevents.protocol.ConnectionState;
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import com.github.retrooper.packetevents.util.EventCreationUtil;
|
||||
import com.github.retrooper.packetevents.util.ExceptionUtil;
|
||||
import com.github.retrooper.packetevents.util.PacketEventsImplHelper;
|
||||
import io.github.retrooper.packetevents.injector.PacketCompressionUtil;
|
||||
import io.github.retrooper.packetevents.util.SpigotReflectionUtil;
|
||||
import net.minecraft.util.io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.util.io.netty.channel.ChannelHandler;
|
||||
import net.minecraft.util.io.netty.channel.ChannelHandlerContext;
|
||||
import net.minecraft.util.io.netty.channel.ChannelPromise;
|
||||
import net.minecraft.util.io.netty.handler.codec.MessageToByteEncoder;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
public class PacketEncoderLegacy extends MessageToByteEncoder<ByteBuf> {
|
||||
public volatile Player player;
|
||||
public User user;
|
||||
private boolean handledCompression;
|
||||
|
||||
public PacketEncoderLegacy(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public void read(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception {
|
||||
boolean doCompression = handleCompressionOrder(ctx, buffer);
|
||||
|
||||
PacketEventsImplHelper.handleClientBoundPacket(ctx.channel(), user, player, buffer, true);
|
||||
if (doCompression && buffer.isReadable()) {
|
||||
PacketCompressionUtil.recompress(ctx, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void encode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception {
|
||||
if (!in.isReadable()) return;
|
||||
read(ctx, in);
|
||||
out.writeBytes(in);
|
||||
}
|
||||
|
||||
private boolean handleCompressionOrder(ChannelHandlerContext ctx, ByteBuf buffer) {
|
||||
if (handledCompression) return false;
|
||||
int encoderIndex = ctx.pipeline().names().indexOf("compress");
|
||||
if (encoderIndex == -1) return false;
|
||||
handledCompression = true;
|
||||
if (encoderIndex > ctx.pipeline().names().indexOf(PacketEvents.ENCODER_NAME)) {
|
||||
// Need to decompress this packet due to bad order
|
||||
ByteBuf decompressed = ctx.alloc().buffer();
|
||||
PacketCompressionUtil.decompress(ctx.pipeline(), buffer, decompressed);
|
||||
PacketCompressionUtil.relocateHandlers(ctx.pipeline(), buffer, decompressed);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
|
||||
PacketEventsImplHelper.handleDisconnection(ctx.channel(), null);
|
||||
super.close(ctx, promise);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
super.exceptionCaught(ctx, cause);
|
||||
//Check if the minecraft server will already print our exception for us.
|
||||
if (ExceptionUtil.isException(cause, PacketProcessException.class) && !SpigotReflectionUtil.isMinecraftServerInstanceDebugging()
|
||||
&& (user == null || user.getConnectionState() != ConnectionState.HANDSHAKING)) {
|
||||
cause.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
-10
@@ -21,7 +21,6 @@ package io.github.retrooper.packetevents.manager.player;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.player.PlayerManager;
|
||||
import com.github.retrooper.packetevents.manager.protocol.ProtocolManager;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.ConnectionState;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.TextureProperty;
|
||||
@@ -31,7 +30,6 @@ import com.github.retrooper.packetevents.util.reflection.Reflection;
|
||||
import com.github.retrooper.packetevents.util.reflection.ReflectionObject;
|
||||
import io.github.retrooper.packetevents.util.PlayerPingAccessorModern;
|
||||
import io.github.retrooper.packetevents.util.SpigotReflectionUtil;
|
||||
import io.github.retrooper.packetevents.util.SpigotVersionLookup_1_7;
|
||||
import io.github.retrooper.packetevents.util.protocolsupport.ProtocolSupportUtil;
|
||||
import io.github.retrooper.packetevents.util.viaversion.ViaVersionUtil;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -69,14 +67,9 @@ public class PlayerManagerImpl implements PlayerManager {
|
||||
PacketEvents.getAPI().getLogManager().debug("Requested ViaVersion for " + player.getName() + "'s protocol version. Protocol version: " + protocolVersion);
|
||||
|
||||
} else {
|
||||
if (PacketEvents.getAPI().getServerManager().getVersion() == ServerVersion.V_1_7_10) {
|
||||
protocolVersion = SpigotVersionLookup_1_7.getProtocolVersion(player);
|
||||
PacketEvents.getAPI().getLogManager().debug("Requested Spigot 1.7.10 for " + player.getName() + "'s protocol version. Protocol version: " + protocolVersion);
|
||||
} else {
|
||||
//No protocol translation plugins available, the client must be the same version as the server.
|
||||
protocolVersion = PacketEvents.getAPI().getServerManager().getVersion().getProtocolVersion();
|
||||
PacketEvents.getAPI().getLogManager().debug("No protocol translation plugins are available. We will assume " + user.getAddress().getHostName() + "'s protocol version is the same as the server's protocol version. Protocol version: " + protocolVersion);
|
||||
}
|
||||
//No protocol translation plugins available, the client must be the same version as the server.
|
||||
protocolVersion = PacketEvents.getAPI().getServerManager().getVersion().getProtocolVersion();
|
||||
PacketEvents.getAPI().getLogManager().debug("No protocol translation plugins are available. We will assume " + user.getAddress().getHostName() + "'s protocol version is the same as the server's protocol version. Protocol version: " + protocolVersion);
|
||||
}
|
||||
ClientVersion version = ClientVersion.getById(protocolVersion);
|
||||
user.setClientVersion(version);
|
||||
@@ -142,6 +135,12 @@ public class PlayerManagerImpl implements PlayerManager {
|
||||
profile.getTextureProperties().add(textureProperty);
|
||||
}
|
||||
}
|
||||
if (profile.getName() == null) {
|
||||
profile.setName(p.getName());
|
||||
}
|
||||
if (profile.getUUID() == null) {
|
||||
profile.setUUID(p.getUniqueId());
|
||||
}
|
||||
return user;
|
||||
}
|
||||
}
|
||||
@@ -27,44 +27,22 @@ import io.github.retrooper.packetevents.netty.buffer.*;
|
||||
import io.github.retrooper.packetevents.netty.channel.*;
|
||||
|
||||
public class NettyManagerImpl implements NettyManager {
|
||||
private static ByteBufOperator BYTE_BUF_OPERATOR;
|
||||
private static ByteBufAllocationOperator BYTE_BUF_ALLOCATION_OPERATOR;
|
||||
private static ChannelOperator CHANNEL_OPERATOR;
|
||||
private static final ByteBufOperator BYTE_BUF_OPERATOR = new ByteBufOperatorModernImpl();
|
||||
private static final ByteBufAllocationOperator BYTE_BUF_ALLOCATION_OPERATOR = new ByteBufAllocationOperatorModernImpl();
|
||||
private static final ChannelOperator CHANNEL_OPERATOR = new ChannelOperatorModernImpl();
|
||||
|
||||
@Override
|
||||
public ChannelOperator getChannelOperator() {
|
||||
if (CHANNEL_OPERATOR == null) {
|
||||
if (SpigotReflectionUtil.USE_MODERN_NETTY_PACKAGE) {
|
||||
CHANNEL_OPERATOR = new ChannelOperatorModernImpl();
|
||||
}
|
||||
else {
|
||||
CHANNEL_OPERATOR = new ChannelOperatorLegacyImpl();
|
||||
}
|
||||
}
|
||||
return CHANNEL_OPERATOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBufOperator getByteBufOperator() {
|
||||
if (BYTE_BUF_OPERATOR == null) {
|
||||
if (SpigotReflectionUtil.USE_MODERN_NETTY_PACKAGE) {
|
||||
BYTE_BUF_OPERATOR = new ByteBufOperatorModernImpl();
|
||||
} else {
|
||||
BYTE_BUF_OPERATOR = new ByteBufOperatorLegacyImpl();
|
||||
}
|
||||
}
|
||||
return BYTE_BUF_OPERATOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBufAllocationOperator getByteBufAllocationOperator() {
|
||||
if (BYTE_BUF_ALLOCATION_OPERATOR == null) {
|
||||
if (SpigotReflectionUtil.USE_MODERN_NETTY_PACKAGE) {
|
||||
BYTE_BUF_ALLOCATION_OPERATOR = new ByteBufAllocationOperatorModernImpl();
|
||||
} else {
|
||||
BYTE_BUF_ALLOCATION_OPERATOR = new ByteBufAllocationOperatorLegacyImpl();
|
||||
}
|
||||
}
|
||||
return BYTE_BUF_ALLOCATION_OPERATOR;
|
||||
}
|
||||
}
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2021 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.netty.buffer;
|
||||
|
||||
import com.github.retrooper.packetevents.netty.buffer.ByteBufAllocationOperator;
|
||||
import net.minecraft.util.io.netty.buffer.Unpooled;
|
||||
|
||||
public class ByteBufAllocationOperatorLegacyImpl implements ByteBufAllocationOperator {
|
||||
@Override
|
||||
public Object wrappedBuffer(byte[] bytes) {
|
||||
return Unpooled.wrappedBuffer(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object copiedBuffer(byte[] bytes) {
|
||||
return Unpooled.copiedBuffer(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object buffer() {
|
||||
return Unpooled.buffer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object directBuffer() {
|
||||
return Unpooled.directBuffer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object compositeBuffer() {
|
||||
return Unpooled.compositeBuffer();
|
||||
}
|
||||
}
|
||||
-227
@@ -1,227 +0,0 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2021 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.netty.buffer;
|
||||
|
||||
import com.github.retrooper.packetevents.netty.buffer.ByteBufOperator;
|
||||
import net.minecraft.util.io.netty.buffer.ByteBuf;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
public class ByteBufOperatorLegacyImpl implements ByteBufOperator {
|
||||
@Override
|
||||
public int readerIndex(Object buffer) {
|
||||
return ((ByteBuf) buffer).readerIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readerIndex(Object buffer, int readerIndex) {
|
||||
return ((ByteBuf) buffer).readerIndex(readerIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writerIndex(Object buffer) {
|
||||
return ((ByteBuf) buffer).writerIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object writerIndex(Object buffer, int writerIndex) {
|
||||
return ((ByteBuf) buffer).writerIndex(writerIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readableBytes(Object buffer) {
|
||||
return ((ByteBuf) buffer).readableBytes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writableBytes(Object buffer) {
|
||||
return ((ByteBuf) buffer).writableBytes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clear(Object buffer) {
|
||||
return ((ByteBuf) buffer).clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte readByte(Object buffer) {
|
||||
return ((ByteBuf) buffer).readByte();
|
||||
}
|
||||
|
||||
@Override
|
||||
public short readShort(Object buffer) {
|
||||
return ((ByteBuf) buffer).readShort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readInt(Object buffer) {
|
||||
return ((ByteBuf) buffer).readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long readUnsignedInt(Object buffer) {
|
||||
return ((ByteBuf) buffer).readUnsignedInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long readLong(Object buffer) {
|
||||
return ((ByteBuf) buffer).readLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeByte(Object buffer, int value) {
|
||||
((ByteBuf) buffer).writeByte(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeShort(Object buffer, int value) {
|
||||
((ByteBuf) buffer).writeShort(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeInt(Object buffer, int value) {
|
||||
((ByteBuf) buffer).writeInt(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeLong(Object buffer, long value) {
|
||||
((ByteBuf) buffer).writeLong(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getBytes(Object buffer, int index, byte[] destination) {
|
||||
return ((ByteBuf)buffer).getBytes(index, destination);
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getUnsignedByte(Object buffer, int index) {
|
||||
return ((ByteBuf)buffer).getUnsignedByte(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadable(Object buffer) {
|
||||
return ((ByteBuf)buffer).isReadable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object copy(Object buffer) {
|
||||
return ((ByteBuf) buffer).copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object duplicate(Object buffer) {
|
||||
return ((ByteBuf) buffer).duplicate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasArray(Object buffer) {
|
||||
return ((ByteBuf) buffer).hasArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] array(Object buffer) {
|
||||
return ((ByteBuf) buffer).array();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object retain(Object buffer) {
|
||||
return ((ByteBuf) buffer).retain();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object retainedDuplicate(Object buffer) {
|
||||
return ((ByteBuf)buffer).duplicate().retain();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readSlice(Object buffer, int length) {
|
||||
return ((ByteBuf)buffer).readSlice(length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readBytes(Object buffer, byte[] destination, int destinationIndex, int length) {
|
||||
return ((ByteBuf)buffer).readBytes(destination, destinationIndex, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readBytes(Object buffer, int length) {
|
||||
return ((ByteBuf) buffer).readBytes(length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readBytes(Object buffer, byte[] bytes) {
|
||||
((ByteBuf) buffer).readBytes(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object writeBytes(Object buffer, Object src) {
|
||||
return ((ByteBuf)buffer).writeBytes((ByteBuf) src);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object writeBytes(Object buffer, byte[] bytes) {
|
||||
return ((ByteBuf)buffer).writeBytes(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object writeBytes(Object buffer, byte[] bytes, int offset, int length) {
|
||||
return ((ByteBuf)buffer).writeBytes(bytes, offset, length);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean release(Object buffer) {
|
||||
return ((ByteBuf) buffer).release();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int refCnt(Object buffer) {
|
||||
return ((ByteBuf) buffer).refCnt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object skipBytes(Object buffer, int length) {
|
||||
return ((ByteBuf) buffer).skipBytes(length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(Object buffer, int index, int length, Charset charset) {
|
||||
return ((ByteBuf) buffer).toString(index, length, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object markReaderIndex(Object buffer) {
|
||||
return ((ByteBuf)buffer).markReaderIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resetReaderIndex(Object buffer) {
|
||||
return ((ByteBuf)buffer).resetReaderIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object markWriterIndex(Object buffer) {
|
||||
return ((ByteBuf)buffer).markWriterIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resetWriterIndex(Object buffer) {
|
||||
return ((ByteBuf)buffer).resetWriterIndex();
|
||||
}
|
||||
}
|
||||
-126
@@ -1,126 +0,0 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2021 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.netty.channel;
|
||||
|
||||
import com.github.retrooper.packetevents.netty.channel.ChannelOperator;
|
||||
import net.minecraft.util.io.netty.channel.Channel;
|
||||
import net.minecraft.util.io.netty.handler.timeout.ReadTimeoutException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketAddress;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ChannelOperatorLegacyImpl implements ChannelOperator {
|
||||
private static Set<Class<? extends Throwable>> IGNORED_HANDLER_EXCEPTIONS = null;
|
||||
|
||||
@Override
|
||||
public Set<Class<? extends Throwable>> getIgnoredHandlerExceptions() {
|
||||
if (IGNORED_HANDLER_EXCEPTIONS == null) {
|
||||
IGNORED_HANDLER_EXCEPTIONS = new HashSet<>();
|
||||
IGNORED_HANDLER_EXCEPTIONS.add(ClosedChannelException.class);
|
||||
IGNORED_HANDLER_EXCEPTIONS.add(ReadTimeoutException.class);
|
||||
IGNORED_HANDLER_EXCEPTIONS.add(IOException.class);
|
||||
//TODO NativeIoException, was thing a thing in 1.7? Only simiarly named class i found was IOExceptionWithCause
|
||||
}
|
||||
return IGNORED_HANDLER_EXCEPTIONS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SocketAddress remoteAddress(Object channel) {
|
||||
return ((Channel) channel).remoteAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SocketAddress localAddress(Object channel) {
|
||||
return ((Channel) channel).localAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen(Object channel) {
|
||||
return ((Channel) channel).isOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object close(Object channel) {
|
||||
return ((Channel) channel).close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object write(Object channel, Object buffer) {
|
||||
return ((Channel) channel).write(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object flush(Object channel) {
|
||||
return ((Channel) channel).flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object writeAndFlush(Object channel, Object buffer) {
|
||||
return ((Channel) channel).writeAndFlush(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object fireChannelRead(Object channel, Object buffer) {
|
||||
return ((Channel) channel).pipeline().fireChannelRead(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object writeInContext(Object channel, String ctx, Object buffer) {
|
||||
return ((Channel) channel).pipeline().context(ctx).write(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object flushInContext(Object channel, String ctx) {
|
||||
return ((Channel) channel).pipeline().context(ctx).flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object writeAndFlushInContext(Object channel, String ctx, Object buffer) {
|
||||
return ((Channel) channel).pipeline().context(ctx).writeAndFlush(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object fireChannelReadInContext(Object channel, String ctx, Object buffer) {
|
||||
return ((Channel) channel).pipeline().context(ctx).fireChannelRead(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> pipelineHandlerNames(Object channel) {
|
||||
return ((Channel) channel).pipeline().names();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPipelineHandler(Object channel, String name) {
|
||||
return ((Channel)channel).pipeline().get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPipelineContext(Object channel, String name) {
|
||||
return ((Channel)channel).pipeline().context(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runInEventLoop(Object channel, Runnable runnable) {
|
||||
((Channel)channel).eventLoop().execute(runnable);
|
||||
}
|
||||
}
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2021 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.util;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class SpigotVersionLookup_1_7 {
|
||||
private static Method getPlayerVersionMethod = null;
|
||||
|
||||
public static int getProtocolVersion(Player player) {
|
||||
if (getPlayerVersionMethod == null) {
|
||||
try {
|
||||
getPlayerVersionMethod = SpigotReflectionUtil.NETWORK_MANAGER_CLASS.getMethod("getVersion");
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Object networkManager = SpigotReflectionUtil.getNetworkManager(player);
|
||||
try {
|
||||
return (int) getPlayerVersionMethod.invoke(networkManager);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user