Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-11-03 14:50:30 +01:00
Merge pull request #1505 from creeper123123321/nettyhandlerabstraction
Netty handler tidy
Dieser Commit ist enthalten in:
Commit
2f9c66eafb
@ -17,7 +17,7 @@ public class BukkitBlockConnectionProvider extends BlockConnectionProvider {
|
||||
|
||||
@Override
|
||||
public int getWorldBlockData(UserConnection user, int bx, int by, int bz) {
|
||||
UUID uuid = user.get(ProtocolInfo.class).getUuid();
|
||||
UUID uuid = user.getProtocolInfo().getUuid();
|
||||
Player player = Bukkit.getPlayer(uuid);
|
||||
if (player != null) {
|
||||
World world = player.getWorld();
|
||||
|
@ -17,12 +17,18 @@ import us.myles.ViaVersion.api.platform.ViaPlatform;
|
||||
import us.myles.ViaVersion.bukkit.classgenerator.ClassGenerator;
|
||||
import us.myles.ViaVersion.bukkit.commands.BukkitCommandHandler;
|
||||
import us.myles.ViaVersion.bukkit.commands.BukkitCommandSender;
|
||||
import us.myles.ViaVersion.bukkit.platform.*;
|
||||
import us.myles.ViaVersion.bukkit.platform.BukkitTaskId;
|
||||
import us.myles.ViaVersion.bukkit.platform.BukkitViaAPI;
|
||||
import us.myles.ViaVersion.bukkit.platform.BukkitViaConfig;
|
||||
import us.myles.ViaVersion.bukkit.platform.BukkitViaInjector;
|
||||
import us.myles.ViaVersion.bukkit.platform.BukkitViaLoader;
|
||||
import us.myles.ViaVersion.bukkit.util.NMSUtil;
|
||||
import us.myles.ViaVersion.dump.PluginInfo;
|
||||
import us.myles.ViaVersion.util.GsonUtil;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform<Player> {
|
||||
private static ViaVersionPlugin instance;
|
||||
@ -54,15 +60,6 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform<Player>
|
||||
|
||||
// Check if we're using protocol support too
|
||||
protocolSupport = Bukkit.getPluginManager().getPlugin("ProtocolSupport") != null;
|
||||
|
||||
if (protocolSupport) {
|
||||
getLogger().info("Hooking into ProtocolSupport, to prevent issues!");
|
||||
try {
|
||||
BukkitViaInjector.patchLists();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3,19 +3,15 @@ package us.myles.ViaVersion.bukkit.handlers;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.exception.CancelException;
|
||||
import us.myles.ViaVersion.packets.Direction;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.bukkit.util.NMSUtil;
|
||||
import us.myles.ViaVersion.exception.CancelDecoderException;
|
||||
import us.myles.ViaVersion.util.PipelineUtil;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
|
||||
public class BukkitDecodeHandler extends ByteToMessageDecoder {
|
||||
|
||||
private final ByteToMessageDecoder minecraftDecoder;
|
||||
private final UserConnection info;
|
||||
|
||||
@ -26,64 +22,40 @@ public class BukkitDecodeHandler extends ByteToMessageDecoder {
|
||||
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, ByteBuf bytebuf, List<Object> list) throws Exception {
|
||||
// use transformers
|
||||
if (bytebuf.readableBytes() > 0) {
|
||||
// Ignore if pending disconnect
|
||||
if (info.isPendingDisconnect()) {
|
||||
return;
|
||||
}
|
||||
// Increment received
|
||||
boolean second = info.incrementReceived();
|
||||
// Check PPS
|
||||
if (second) {
|
||||
if (info.handlePPS())
|
||||
return;
|
||||
if (!info.checkIncomingPacket()) {
|
||||
bytebuf.clear(); // Don't accumulate
|
||||
throw CancelDecoderException.generate(null);
|
||||
}
|
||||
|
||||
ByteBuf transformedBuf = null;
|
||||
try {
|
||||
if (info.shouldTransformPacket()) {
|
||||
transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
|
||||
info.transformIncoming(transformedBuf, CancelDecoderException::generate);
|
||||
}
|
||||
|
||||
if (info.isActive()) {
|
||||
// Handle ID
|
||||
int id = Type.VAR_INT.read(bytebuf);
|
||||
// Transform
|
||||
ByteBuf newPacket = ctx.alloc().buffer();
|
||||
try {
|
||||
if (id == PacketWrapper.PASSTHROUGH_ID) {
|
||||
newPacket.writeBytes(bytebuf);
|
||||
} else {
|
||||
PacketWrapper wrapper = new PacketWrapper(id, bytebuf, info);
|
||||
ProtocolInfo protInfo = info.get(ProtocolInfo.class);
|
||||
protInfo.getPipeline().transform(Direction.INCOMING, protInfo.getState(), wrapper);
|
||||
wrapper.writeToBuffer(newPacket);
|
||||
}
|
||||
|
||||
bytebuf.clear();
|
||||
bytebuf = newPacket;
|
||||
} catch (Exception e) {
|
||||
// Clear Buffer
|
||||
bytebuf.clear();
|
||||
// Release Packet, be free!
|
||||
newPacket.release();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// call minecraft decoder
|
||||
try {
|
||||
list.addAll(PipelineUtil.callDecode(this.minecraftDecoder, ctx, bytebuf));
|
||||
list.addAll(PipelineUtil.callDecode(this.minecraftDecoder, ctx, transformedBuf == null ? bytebuf : transformedBuf));
|
||||
} catch (InvocationTargetException e) {
|
||||
if (e.getCause() instanceof Exception) {
|
||||
throw (Exception) e.getCause();
|
||||
} else if (e.getCause() instanceof Error) {
|
||||
throw (Error) e.getCause();
|
||||
}
|
||||
} finally {
|
||||
if (info.isActive()) {
|
||||
bytebuf.release();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (transformedBuf != null) {
|
||||
transformedBuf.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
if (PipelineUtil.containsCause(cause, CancelException.class)) return;
|
||||
if (PipelineUtil.containsCause(cause, CancelDecoderException.class)) return; // ProtocolLib compat
|
||||
super.exceptionCaught(ctx, cause);
|
||||
if (!NMSUtil.isDebugPropertySet()) {
|
||||
cause.printStackTrace(); // Print if CB doesn't already do it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,22 +3,18 @@ package us.myles.ViaVersion.bukkit.handlers;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToByteEncoder;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.bukkit.util.NMSUtil;
|
||||
import us.myles.ViaVersion.exception.CancelException;
|
||||
import us.myles.ViaVersion.exception.CancelEncoderException;
|
||||
import us.myles.ViaVersion.handlers.ChannelHandlerContextWrapper;
|
||||
import us.myles.ViaVersion.handlers.ViaHandler;
|
||||
import us.myles.ViaVersion.packets.Direction;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.util.PipelineUtil;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class BukkitEncodeHandler extends MessageToByteEncoder implements ViaHandler {
|
||||
private static Field versionField = null;
|
||||
private static Field versionField;
|
||||
|
||||
static {
|
||||
try {
|
||||
@ -51,6 +47,8 @@ public class BukkitEncodeHandler extends MessageToByteEncoder implements ViaHand
|
||||
} catch (InvocationTargetException e) {
|
||||
if (e.getCause() instanceof Exception) {
|
||||
throw (Exception) e.getCause();
|
||||
} else if (e.getCause() instanceof Error) {
|
||||
throw (Error) e.getCause();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -58,36 +56,19 @@ public class BukkitEncodeHandler extends MessageToByteEncoder implements ViaHand
|
||||
transform(bytebuf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transform(ByteBuf bytebuf) throws Exception {
|
||||
if (bytebuf.readableBytes() == 0) {
|
||||
return; // Someone Already Decoded It!
|
||||
}
|
||||
// Increment sent
|
||||
info.incrementSent();
|
||||
if (info.isActive()) {
|
||||
// Handle ID
|
||||
int id = Type.VAR_INT.read(bytebuf);
|
||||
// Transform
|
||||
ByteBuf oldPacket = bytebuf.copy();
|
||||
bytebuf.clear();
|
||||
|
||||
try {
|
||||
PacketWrapper wrapper = new PacketWrapper(id, oldPacket, info);
|
||||
ProtocolInfo protInfo = info.get(ProtocolInfo.class);
|
||||
protInfo.getPipeline().transform(Direction.OUTGOING, protInfo.getState(), wrapper);
|
||||
wrapper.writeToBuffer(bytebuf);
|
||||
} catch (Exception e) {
|
||||
bytebuf.clear();
|
||||
throw e;
|
||||
} finally {
|
||||
oldPacket.release();
|
||||
}
|
||||
}
|
||||
info.checkOutgoingPacket();
|
||||
if (!info.shouldTransformPacket()) return;
|
||||
info.transformOutgoing(bytebuf, CancelEncoderException::generate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
if (PipelineUtil.containsCause(cause, CancelException.class)) return;
|
||||
if (PipelineUtil.containsCause(cause, CancelEncoderException.class)) return; // ProtocolLib compat
|
||||
super.exceptionCaught(ctx, cause);
|
||||
if (!NMSUtil.isDebugPropertySet()) {
|
||||
cause.printStackTrace(); // Print if CB doesn't already do it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ public class BukkitPacketHandler extends MessageToMessageEncoder {
|
||||
info.setLastPacket(o);
|
||||
/* This transformer is more for fixing issues which we find hard at packet level :) */
|
||||
if (info.isActive()) {
|
||||
if (info.get(ProtocolInfo.class).getPipeline().filter(o, list)) {
|
||||
if (info.getProtocolInfo().getPipeline().filter(o, list)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ public class PlayerSneakListener extends ViaBukkitListener {
|
||||
Player player = event.getPlayer();
|
||||
UserConnection userConnection = getUserConnection(player);
|
||||
if (userConnection == null) return;
|
||||
ProtocolInfo info = userConnection.get(ProtocolInfo.class);
|
||||
ProtocolInfo info = userConnection.getProtocolInfo();
|
||||
if (info == null) return;
|
||||
|
||||
int protocolVersion = info.getProtocolVersion();
|
||||
|
@ -35,7 +35,7 @@ public class BukkitViaAPI implements ViaAPI<Player> {
|
||||
public int getPlayerVersion(UUID uuid) {
|
||||
if (!isInjected(uuid))
|
||||
return getExternalVersion(Bukkit.getPlayer(uuid));
|
||||
return Via.getManager().getConnection(uuid).get(ProtocolInfo.class).getProtocolVersion();
|
||||
return Via.getManager().getConnection(uuid).getProtocolInfo().getProtocolVersion();
|
||||
}
|
||||
|
||||
private int getExternalVersion(Player player) {
|
||||
|
@ -12,17 +12,17 @@ import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.platform.ViaInjector;
|
||||
import us.myles.ViaVersion.bukkit.handlers.BukkitChannelInitializer;
|
||||
import us.myles.ViaVersion.bukkit.util.NMSUtil;
|
||||
import us.myles.ViaVersion.util.ConcurrentList;
|
||||
import us.myles.ViaVersion.util.ListWrapper;
|
||||
import us.myles.ViaVersion.util.ReflectionUtil;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BukkitViaInjector implements ViaInjector {
|
||||
private final List<ChannelFuture> injectedFutures = new ConcurrentList<>();
|
||||
private final List<Pair<Field, Object>> injectedLists = new ConcurrentList<>();
|
||||
private final List<ChannelFuture> injectedFutures = new ArrayList<>();
|
||||
private final List<Pair<Field, Object>> injectedLists = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void inject() throws Exception {
|
||||
@ -231,25 +231,6 @@ public class BukkitViaInjector implements ViaInjector {
|
||||
return connection;
|
||||
}
|
||||
|
||||
public static void patchLists() throws Exception {
|
||||
Object connection = getServerConnection();
|
||||
if (connection == null) {
|
||||
Via.getPlatform().getLogger().warning("We failed to find the core component 'ServerConnection', please file an issue on our GitHub.");
|
||||
return;
|
||||
}
|
||||
for (Field field : connection.getClass().getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
final Object value = field.get(connection);
|
||||
if (value instanceof List) {
|
||||
if (!(value instanceof ConcurrentList)) {
|
||||
ConcurrentList list = new ConcurrentList();
|
||||
list.addAll((List) value);
|
||||
field.set(connection, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isBinded() {
|
||||
try {
|
||||
Object connection = getServerConnection();
|
||||
|
@ -120,11 +120,11 @@ public class BukkitViaLoader implements ViaPlatformLoader {
|
||||
@Override
|
||||
public Item getHandItem(final UserConnection info) {
|
||||
if (handItemCache != null) {
|
||||
return handItemCache.getHandItem(info.get(ProtocolInfo.class).getUuid());
|
||||
return handItemCache.getHandItem(info.getProtocolInfo().getUuid());
|
||||
}
|
||||
try {
|
||||
return Bukkit.getScheduler().callSyncMethod(Bukkit.getPluginManager().getPlugin("ViaVersion"), () -> {
|
||||
UUID playerUUID = info.get(ProtocolInfo.class).getUuid();
|
||||
UUID playerUUID = info.getProtocolInfo().getUuid();
|
||||
Player player = Bukkit.getPlayer(playerUUID);
|
||||
if (player != null) {
|
||||
return HandItemCache.convert(player.getItemInHand());
|
||||
|
@ -63,7 +63,7 @@ public class BukkitInventoryQuickMoveProvider extends InventoryQuickMoveProvider
|
||||
}
|
||||
}
|
||||
}
|
||||
ProtocolInfo info = userConnection.get(ProtocolInfo.class);
|
||||
ProtocolInfo info = userConnection.getProtocolInfo();
|
||||
UUID uuid = info.getUuid();
|
||||
BukkitInventoryUpdateTask updateTask = updateTasks.get(uuid);
|
||||
final boolean registered = updateTask != null;
|
||||
|
@ -81,7 +81,7 @@ public class BukkitViaMovementTransmitter extends MovementTransmitterProvider {
|
||||
@Override
|
||||
public void sendPlayer(UserConnection info) {
|
||||
if (USE_NMS) {
|
||||
Player player = Bukkit.getPlayer(info.get(ProtocolInfo.class).getUuid());
|
||||
Player player = Bukkit.getPlayer(info.getProtocolInfo().getUuid());
|
||||
if (player != null) {
|
||||
try {
|
||||
// Tick player
|
||||
|
@ -5,6 +5,17 @@ import org.bukkit.Bukkit;
|
||||
public class NMSUtil {
|
||||
private static final String BASE = Bukkit.getServer().getClass().getPackage().getName();
|
||||
private static final String NMS = BASE.replace("org.bukkit.craftbukkit", "net.minecraft.server");
|
||||
private static final boolean DEBUG_PROPERTY = loadDebugProperty();
|
||||
|
||||
private static boolean loadDebugProperty() {
|
||||
try {
|
||||
Class<?> serverClass = nms("MinecraftServer");
|
||||
Object server = serverClass.getDeclaredMethod("getServer").invoke(null);
|
||||
return (boolean) serverClass.getMethod("isDebugging").invoke(server);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static Class<?> nms(String className) throws ClassNotFoundException {
|
||||
return Class.forName(NMS + "." + className);
|
||||
@ -17,4 +28,11 @@ public class NMSUtil {
|
||||
public static String getVersion() {
|
||||
return BASE.substring(BASE.lastIndexOf('.') + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if debug=true is set in the server.properties (added by CB)
|
||||
*/
|
||||
public static boolean isDebugPropertySet() {
|
||||
return DEBUG_PROPERTY;
|
||||
}
|
||||
}
|
||||
|
@ -4,19 +4,13 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.exception.CancelException;
|
||||
import us.myles.ViaVersion.packets.Direction;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.util.PipelineUtil;
|
||||
import us.myles.ViaVersion.exception.CancelDecoderException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
public class BungeeDecodeHandler extends MessageToMessageDecoder<ByteBuf> {
|
||||
|
||||
private final UserConnection info;
|
||||
|
||||
public BungeeDecodeHandler(UserConnection info) {
|
||||
@ -25,55 +19,24 @@ public class BungeeDecodeHandler extends MessageToMessageDecoder<ByteBuf> {
|
||||
|
||||
@Override
|
||||
protected void decode(final ChannelHandlerContext ctx, ByteBuf bytebuf, List<Object> out) throws Exception {
|
||||
// use transformers
|
||||
if (bytebuf.readableBytes() > 0) {
|
||||
// Ignore if pending disconnect
|
||||
if (info.isPendingDisconnect()) {
|
||||
return;
|
||||
}
|
||||
// Increment received
|
||||
boolean second = info.incrementReceived();
|
||||
// Check PPS
|
||||
if (second) {
|
||||
if (info.handlePPS())
|
||||
return;
|
||||
}
|
||||
if (!info.checkIncomingPacket()) throw CancelDecoderException.generate(null);
|
||||
if (!info.shouldTransformPacket()) {
|
||||
out.add(bytebuf.retain());
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.isActive()) {
|
||||
// Handle ID
|
||||
int id = Type.VAR_INT.read(bytebuf);
|
||||
// Transform
|
||||
ByteBuf newPacket = ctx.alloc().buffer();
|
||||
try {
|
||||
if (id == PacketWrapper.PASSTHROUGH_ID) {
|
||||
newPacket.writeBytes(bytebuf);
|
||||
} else {
|
||||
PacketWrapper wrapper = new PacketWrapper(id, bytebuf, info);
|
||||
ProtocolInfo protInfo = info.get(ProtocolInfo.class);
|
||||
protInfo.getPipeline().transform(Direction.INCOMING, protInfo.getState(), wrapper);
|
||||
wrapper.writeToBuffer(newPacket);
|
||||
}
|
||||
|
||||
bytebuf.clear();
|
||||
bytebuf = newPacket;
|
||||
} catch (Throwable e) {
|
||||
// Clear Buffer
|
||||
bytebuf.clear();
|
||||
// Release Packet, be free!
|
||||
newPacket.release();
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
bytebuf.retain();
|
||||
}
|
||||
|
||||
out.add(bytebuf);
|
||||
ByteBuf transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
|
||||
try {
|
||||
info.transformIncoming(transformedBuf, CancelDecoderException::generate);
|
||||
out.add(transformedBuf.retain());
|
||||
} finally {
|
||||
transformedBuf.release();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
if (PipelineUtil.containsCause(cause, CancelException.class)) return;
|
||||
if (cause instanceof CancelDecoderException) return;
|
||||
super.exceptionCaught(ctx, cause);
|
||||
}
|
||||
}
|
||||
|
@ -4,84 +4,80 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageEncoder;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.bungee.util.BungeePipelineUtil;
|
||||
import us.myles.ViaVersion.exception.CancelException;
|
||||
import us.myles.ViaVersion.packets.Direction;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.util.PipelineUtil;
|
||||
import us.myles.ViaVersion.exception.CancelEncoderException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
public class BungeeEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
|
||||
private final UserConnection info;
|
||||
private boolean handledCompression = false;
|
||||
private boolean handledCompression;
|
||||
|
||||
public BungeeEncodeHandler(UserConnection info) {
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void encode(final ChannelHandlerContext ctx, ByteBuf bytebuf, List<Object> out) throws Exception {
|
||||
if (bytebuf.readableBytes() == 0) {
|
||||
throw Via.getManager().isDebug() ? new CancelException() : CancelException.CACHED;
|
||||
info.checkOutgoingPacket();
|
||||
if (!info.shouldTransformPacket()) {
|
||||
out.add(bytebuf.retain());
|
||||
return;
|
||||
}
|
||||
|
||||
ByteBuf transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
|
||||
try {
|
||||
boolean needsCompress = handleCompressionOrder(ctx, transformedBuf);
|
||||
info.transformOutgoing(transformedBuf, CancelEncoderException::generate);
|
||||
|
||||
if (needsCompress) {
|
||||
recompress(ctx, transformedBuf);
|
||||
}
|
||||
|
||||
out.add(transformedBuf.retain());
|
||||
} finally {
|
||||
transformedBuf.release();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean handleCompressionOrder(ChannelHandlerContext ctx, ByteBuf buf) {
|
||||
boolean needsCompress = false;
|
||||
if (!handledCompression) {
|
||||
if (ctx.pipeline().names().indexOf("compress") > ctx.pipeline().names().indexOf("via-encoder")) {
|
||||
// Need to decompress this packet due to bad order
|
||||
bytebuf = BungeePipelineUtil.decompress(ctx, bytebuf);
|
||||
ChannelHandler encoder = ctx.pipeline().get("via-decoder");
|
||||
ChannelHandler decoder = ctx.pipeline().get("via-encoder");
|
||||
ctx.pipeline().remove(encoder);
|
||||
ctx.pipeline().remove(decoder);
|
||||
ctx.pipeline().addAfter("decompress", "via-decoder", encoder);
|
||||
ctx.pipeline().addAfter("compress", "via-encoder", decoder);
|
||||
ByteBuf decompressed = BungeePipelineUtil.decompress(ctx, buf);
|
||||
try {
|
||||
buf.clear().writeBytes(decompressed);
|
||||
} finally {
|
||||
decompressed.release();
|
||||
}
|
||||
ChannelHandler dec = ctx.pipeline().get("via-decoder");
|
||||
ChannelHandler enc = ctx.pipeline().get("via-encoder");
|
||||
ctx.pipeline().remove(dec);
|
||||
ctx.pipeline().remove(enc);
|
||||
ctx.pipeline().addAfter("decompress", "via-decoder", dec);
|
||||
ctx.pipeline().addAfter("compress", "via-encoder", enc);
|
||||
needsCompress = true;
|
||||
handledCompression = true;
|
||||
}
|
||||
}
|
||||
// Increment sent
|
||||
info.incrementSent();
|
||||
return needsCompress;
|
||||
}
|
||||
|
||||
if (info.isActive()) {
|
||||
// Handle ID
|
||||
int id = Type.VAR_INT.read(bytebuf);
|
||||
// Transform
|
||||
ByteBuf oldPacket = bytebuf.copy();
|
||||
bytebuf.clear();
|
||||
|
||||
try {
|
||||
PacketWrapper wrapper = new PacketWrapper(id, oldPacket, info);
|
||||
ProtocolInfo protInfo = info.get(ProtocolInfo.class);
|
||||
protInfo.getPipeline().transform(Direction.OUTGOING, protInfo.getState(), wrapper);
|
||||
wrapper.writeToBuffer(bytebuf);
|
||||
} catch (Throwable e) {
|
||||
bytebuf.clear();
|
||||
throw e;
|
||||
} finally {
|
||||
oldPacket.release();
|
||||
}
|
||||
}
|
||||
|
||||
if (needsCompress) {
|
||||
ByteBuf old = bytebuf;
|
||||
bytebuf = BungeePipelineUtil.compress(ctx, bytebuf);
|
||||
old.release();
|
||||
out.add(bytebuf);
|
||||
} else {
|
||||
out.add(bytebuf.retain());
|
||||
private void recompress(ChannelHandlerContext ctx, ByteBuf buf) {
|
||||
ByteBuf compressed = BungeePipelineUtil.compress(ctx, buf);
|
||||
try {
|
||||
buf.clear().writeBytes(compressed);
|
||||
} finally {
|
||||
compressed.release();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
if (PipelineUtil.containsCause(cause, CancelException.class)) return;
|
||||
if (cause instanceof CancelEncoderException) return;
|
||||
super.exceptionCaught(ctx, cause);
|
||||
}
|
||||
}
|
||||
|
@ -77,13 +77,13 @@ public class BungeeServerHandler implements Listener {
|
||||
}
|
||||
|
||||
int protocolId = ProtocolDetectorService.getProtocolId(e.getTarget().getName());
|
||||
List<Pair<Integer, Protocol>> protocols = ProtocolRegistry.getProtocolPath(user.get(ProtocolInfo.class).getProtocolVersion(), protocolId);
|
||||
List<Pair<Integer, Protocol>> protocols = ProtocolRegistry.getProtocolPath(user.getProtocolInfo().getProtocolVersion(), protocolId);
|
||||
|
||||
// Check if ViaVersion can support that version
|
||||
try {
|
||||
//Object pendingConnection = getPendingConnection.invoke(e.getPlayer());
|
||||
Object handshake = getHandshake.invoke(e.getPlayer().getPendingConnection());
|
||||
setProtocol.invoke(handshake, protocols == null ? user.get(ProtocolInfo.class).getProtocolVersion() : protocolId);
|
||||
setProtocol.invoke(handshake, protocols == null ? user.getProtocolInfo().getProtocolVersion() : protocolId);
|
||||
} catch (InvocationTargetException | IllegalAccessException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
@ -145,7 +145,7 @@ public class BungeeServerHandler implements Listener {
|
||||
if (storage.getBossbar() != null) {
|
||||
// TODO: Verify whether this packet needs to be sent when 1.8 -> 1.9 protocol isn't present in the pipeline
|
||||
// This ensures we can encode it properly as only the 1.9 protocol is currently implemented.
|
||||
if (user.get(ProtocolInfo.class).getPipeline().contains(Protocol1_9To1_8.class)) {
|
||||
if (user.getProtocolInfo().getPipeline().contains(Protocol1_9To1_8.class)) {
|
||||
for (UUID uuid : storage.getBossbar()) {
|
||||
PacketWrapper wrapper = new PacketWrapper(0x0C, null, user);
|
||||
wrapper.write(Type.UUID, uuid);
|
||||
@ -157,12 +157,12 @@ public class BungeeServerHandler implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
ProtocolInfo info = user.get(ProtocolInfo.class);
|
||||
ProtocolInfo info = user.getProtocolInfo();
|
||||
int previousServerProtocol = info.getServerProtocolVersion();
|
||||
|
||||
// Refresh the pipes
|
||||
List<Pair<Integer, Protocol>> protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), protocolId);
|
||||
ProtocolPipeline pipeline = user.get(ProtocolInfo.class).getPipeline();
|
||||
ProtocolPipeline pipeline = user.getProtocolInfo().getPipeline();
|
||||
user.clearStoredObjects();
|
||||
pipeline.cleanPipes();
|
||||
if (protocols == null) {
|
||||
|
@ -28,7 +28,7 @@ public class ElytraPatch implements Listener {
|
||||
if (user == null) return;
|
||||
|
||||
try {
|
||||
if (user.get(ProtocolInfo.class).getPipeline().contains(Protocol1_9To1_8.class)) {
|
||||
if (user.getProtocolInfo().getPipeline().contains(Protocol1_9To1_8.class)) {
|
||||
int entityId = user.get(EntityTracker1_9.class).getProvidedEntityId();
|
||||
|
||||
PacketWrapper wrapper = new PacketWrapper(0x39, null, user);
|
||||
|
@ -26,7 +26,7 @@ public class BungeeViaAPI implements ViaAPI<ProxiedPlayer> {
|
||||
if (conn == null) {
|
||||
return player.getPendingConnection().getVersion();
|
||||
}
|
||||
return conn.get(ProtocolInfo.class).getProtocolVersion();
|
||||
return conn.getProtocolInfo().getProtocolVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -26,7 +26,7 @@ public class BungeeMainHandProvider extends MainHandProvider {
|
||||
|
||||
@Override
|
||||
public void setMainHand(UserConnection user, int hand) {
|
||||
ProtocolInfo info = user.get(ProtocolInfo.class);
|
||||
ProtocolInfo info = user.getProtocolInfo();
|
||||
if (info == null || info.getUuid() == null) return;
|
||||
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(info.getUuid());
|
||||
if (player == null) return;
|
||||
|
@ -21,7 +21,7 @@ public class BungeeMovementTransmitter extends MovementTransmitterProvider {
|
||||
}
|
||||
|
||||
public void sendPlayer(UserConnection userConnection) {
|
||||
if (userConnection.get(ProtocolInfo.class).getState() == State.PLAY) {
|
||||
if (userConnection.getProtocolInfo().getState() == State.PLAY) {
|
||||
PacketWrapper wrapper = new PacketWrapper(0x03, null, userConnection);
|
||||
wrapper.write(Type.BOOLEAN, userConnection.get(MovementTracker.class).isGround());
|
||||
try {
|
||||
|
@ -34,7 +34,7 @@ public class BungeeVersionProvider extends VersionProvider {
|
||||
List<Integer> sorted = new ArrayList<>(list);
|
||||
Collections.sort(sorted);
|
||||
|
||||
ProtocolInfo info = user.get(ProtocolInfo.class);
|
||||
ProtocolInfo info = user.getProtocolInfo();
|
||||
|
||||
// Bungee supports it
|
||||
if (sorted.contains(info.getProtocolVersion()))
|
||||
|
@ -319,7 +319,7 @@ public class PacketWrapper {
|
||||
*/
|
||||
private ByteBuf constructPacket(Class<? extends Protocol> packetProtocol, boolean skipCurrentPipeline, Direction direction) throws Exception {
|
||||
// Apply current pipeline
|
||||
List<Protocol> protocols = new ArrayList<>(user().get(ProtocolInfo.class).getPipeline().pipes());
|
||||
List<Protocol> protocols = new ArrayList<>(user().getProtocolInfo().getPipeline().pipes());
|
||||
if (direction == Direction.OUTGOING) {
|
||||
// Other way if outgoing
|
||||
Collections.reverse(protocols);
|
||||
@ -337,7 +337,7 @@ public class PacketWrapper {
|
||||
resetReader();
|
||||
|
||||
// Apply other protocols
|
||||
apply(direction, user().get(ProtocolInfo.class).getState(), index, protocols);
|
||||
apply(direction, user().getProtocolInfo().getState(), index, protocols);
|
||||
// Send
|
||||
ByteBuf output = inputBuffer == null ? user().getChannel().alloc().buffer() : inputBuffer.alloc().buffer();
|
||||
writeToBuffer(output);
|
||||
|
@ -35,7 +35,7 @@ public abstract class ViaListener {
|
||||
protected boolean isOnPipe(UUID uuid) {
|
||||
UserConnection userConnection = getUserConnection(uuid);
|
||||
return userConnection != null &&
|
||||
(requiredPipeline == null || userConnection.get(ProtocolInfo.class).getPipeline().contains(requiredPipeline));
|
||||
(requiredPipeline == null || userConnection.getProtocolInfo().getPipeline().contains(requiredPipeline));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -11,6 +11,8 @@ import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.ViaVersionConfig;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.exception.CancelException;
|
||||
import us.myles.ViaVersion.packets.Direction;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.util.PipelineUtil;
|
||||
|
||||
@ -18,11 +20,13 @@ import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class UserConnection {
|
||||
private static final AtomicLong IDS = new AtomicLong();
|
||||
private final long id = IDS.incrementAndGet();
|
||||
private final Channel channel;
|
||||
private ProtocolInfo protocolInfo;
|
||||
Map<Class, StoredObject> storedObjects = new ConcurrentHashMap<>();
|
||||
private boolean active = true;
|
||||
private boolean pendingDisconnect;
|
||||
@ -42,7 +46,7 @@ public class UserConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object from the storage
|
||||
* Get an object from the storage.
|
||||
*
|
||||
* @param objectClass The class of the object to get
|
||||
* @param <T> The type of the class you want to get.
|
||||
@ -54,7 +58,7 @@ public class UserConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the storage has an object
|
||||
* Check if the storage has an object.
|
||||
*
|
||||
* @param objectClass The object class to check
|
||||
* @return True if the object is in the storage
|
||||
@ -64,7 +68,7 @@ public class UserConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Put an object into the stored objects based on class
|
||||
* Put an object into the stored objects based on class.
|
||||
*
|
||||
* @param object The object to store.
|
||||
*/
|
||||
@ -73,7 +77,7 @@ public class UserConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all the stored objects
|
||||
* Clear all the stored objects.
|
||||
* Used for bungee when switching servers.
|
||||
*/
|
||||
public void clearStoredObjects() {
|
||||
@ -81,7 +85,7 @@ public class UserConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a raw packet to the player
|
||||
* Send a raw packet to the player.
|
||||
*
|
||||
* @param packet The raw packet to send
|
||||
* @param currentThread Should it run in the same thread
|
||||
@ -96,7 +100,7 @@ public class UserConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a raw packet to the player with returning the future
|
||||
* Send a raw packet to the player with returning the future.
|
||||
*
|
||||
* @param packet The raw packet to send
|
||||
* @return ChannelFuture of the packet being sent
|
||||
@ -107,7 +111,7 @@ public class UserConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a raw packet to the player (netty thread)
|
||||
* Send a raw packet to the player (netty thread).
|
||||
*
|
||||
* @param packet The packet to send
|
||||
*/
|
||||
@ -116,16 +120,16 @@ public class UserConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for incrementing the number of packets sent to the client
|
||||
* Used for incrementing the number of packets sent to the client.
|
||||
*/
|
||||
public void incrementSent() {
|
||||
this.sentPackets++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for incrementing the number of packets received from the client
|
||||
* Used for incrementing the number of packets received from the client.
|
||||
*
|
||||
* @return True if the interval has reset
|
||||
* @return true if the interval has reset and can now be checked for the packets sent
|
||||
*/
|
||||
public boolean incrementReceived() {
|
||||
// handle stats
|
||||
@ -143,7 +147,14 @@ public class UserConnection {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean handlePPS() {
|
||||
/**
|
||||
* Checks for packet flood with the packets sent in the last second.
|
||||
* ALWAYS check for {@link #incrementReceived()} before using this method.
|
||||
*
|
||||
* @return true if the packet should be cancelled
|
||||
* @see #incrementReceived()
|
||||
*/
|
||||
public boolean exceedsMaxPPS() {
|
||||
ViaVersionConfig conf = Via.getConfig();
|
||||
// Max PPS Checker
|
||||
if (conf.getMaxPPS() > 0) {
|
||||
@ -175,26 +186,29 @@ public class UserConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect a connection
|
||||
* Disconnect a connection.
|
||||
*
|
||||
* @param reason The reason to use, not used if player is not active.
|
||||
*/
|
||||
public void disconnect(String reason) {
|
||||
if (!channel.isOpen()) return;
|
||||
if (pendingDisconnect) return;
|
||||
if (!channel.isOpen() || pendingDisconnect) return;
|
||||
|
||||
pendingDisconnect = true;
|
||||
if (get(ProtocolInfo.class).getUuid() != null) {
|
||||
UUID uuid = get(ProtocolInfo.class).getUuid();
|
||||
Via.getPlatform().runSync(() -> {
|
||||
if (!Via.getPlatform().kickPlayer(uuid, ChatColor.translateAlternateColorCodes('&', reason))) {
|
||||
channel.close(); // =)
|
||||
}
|
||||
});
|
||||
UUID uuid = protocolInfo.getUuid();
|
||||
if (uuid == null) {
|
||||
channel.close(); // Just disconnect, we don't know what the connection is
|
||||
return;
|
||||
}
|
||||
|
||||
Via.getPlatform().runSync(() -> {
|
||||
if (!Via.getPlatform().kickPlayer(uuid, ChatColor.translateAlternateColorCodes('&', reason))) {
|
||||
channel.close(); // =)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a raw packet to the server
|
||||
* Sends a raw packet to the server.
|
||||
*
|
||||
* @param packet Raw packet to be sent
|
||||
* @param currentThread If {@code true} executes immediately, {@code false} submits a task to EventLoop
|
||||
@ -238,7 +252,7 @@ public class UserConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a raw packet to the server. It will submit a task to EventLoop
|
||||
* Sends a raw packet to the server. It will submit a task to EventLoop.
|
||||
*
|
||||
* @param packet Raw packet to be sent
|
||||
*/
|
||||
@ -246,6 +260,80 @@ public class UserConnection {
|
||||
sendRawPacketToServer(packet, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Monitors serverbound packets.
|
||||
*
|
||||
* @return false if this packet should be cancelled
|
||||
*/
|
||||
public boolean checkIncomingPacket() {
|
||||
// Ignore if pending disconnect
|
||||
if (pendingDisconnect) return false;
|
||||
// Increment received + Check PPS
|
||||
return !incrementReceived() || !exceedsMaxPPS();
|
||||
}
|
||||
|
||||
/**
|
||||
* Monitors clientbound packets.
|
||||
*/
|
||||
public void checkOutgoingPacket() {
|
||||
incrementSent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if packets needs transforming.
|
||||
*
|
||||
* @return if packets should be passed through
|
||||
*/
|
||||
public boolean shouldTransformPacket() {
|
||||
return active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the clientbound packet contained in an outgoing ByteBuf.
|
||||
*
|
||||
* @param buf ByteBuf with packet id and packet contents
|
||||
* @param cancelSupplier Function called with original CancelException for generating the Exception used when
|
||||
* packet is cancelled
|
||||
* @throws Exception when transforming failed or this packet is cancelled
|
||||
*/
|
||||
public void transformOutgoing(ByteBuf buf, Function<Throwable, Exception> cancelSupplier) throws Exception {
|
||||
if (!buf.isReadable()) return;
|
||||
transform(buf, Direction.OUTGOING, cancelSupplier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the serverbound packet contained in an incoming ByteBuf.
|
||||
*
|
||||
* @param buf ByteBuf with packet id and packet contents
|
||||
* @param cancelSupplier Function called with original CancelException for generating the Exception used when
|
||||
* packet is cancelled
|
||||
* @throws Exception when transforming failed or this packet is cancelled
|
||||
*/
|
||||
public void transformIncoming(ByteBuf buf, Function<Throwable, Exception> cancelSupplier) throws Exception {
|
||||
if (!buf.isReadable()) return;
|
||||
transform(buf, Direction.INCOMING, cancelSupplier);
|
||||
}
|
||||
|
||||
private void transform(ByteBuf buf, Direction direction, Function<Throwable, Exception> cancelSupplier) throws Exception {
|
||||
int id = Type.VAR_INT.read(buf);
|
||||
if (id == PacketWrapper.PASSTHROUGH_ID) return;
|
||||
|
||||
PacketWrapper wrapper = new PacketWrapper(id, buf, this);
|
||||
try {
|
||||
protocolInfo.getPipeline().transform(direction, protocolInfo.getState(), wrapper);
|
||||
} catch (CancelException ex) {
|
||||
throw cancelSupplier.apply(ex);
|
||||
}
|
||||
|
||||
ByteBuf transformed = buf.alloc().buffer();
|
||||
try {
|
||||
wrapper.writeToBuffer(transformed);
|
||||
buf.clear().writeBytes(transformed);
|
||||
} finally {
|
||||
transformed.release();
|
||||
}
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
@ -255,6 +343,20 @@ public class UserConnection {
|
||||
return channel;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ProtocolInfo getProtocolInfo() {
|
||||
return protocolInfo;
|
||||
}
|
||||
|
||||
public void setProtocolInfo(@Nullable ProtocolInfo protocolInfo) {
|
||||
this.protocolInfo = protocolInfo;
|
||||
if (protocolInfo != null) {
|
||||
storedObjects.put(ProtocolInfo.class, protocolInfo);
|
||||
} else {
|
||||
storedObjects.remove(ProtocolInfo.class);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Class, StoredObject> getStoredObjects() {
|
||||
return storedObjects;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ public class ViaConnectionManager {
|
||||
|
||||
public void onLoginSuccess(UserConnection connection) {
|
||||
Objects.requireNonNull(connection, "connection is null!");
|
||||
UUID id = connection.get(ProtocolInfo.class).getUuid();
|
||||
UUID id = connection.getProtocolInfo().getUuid();
|
||||
connections.add(connection);
|
||||
clients.put(id, connection);
|
||||
|
||||
@ -28,7 +28,7 @@ public class ViaConnectionManager {
|
||||
|
||||
public void onDisconnect(UserConnection connection) {
|
||||
Objects.requireNonNull(connection, "connection is null!");
|
||||
UUID id = connection.get(ProtocolInfo.class).getUuid();
|
||||
UUID id = connection.getProtocolInfo().getUuid();
|
||||
connections.remove(connection);
|
||||
clients.remove(id);
|
||||
}
|
||||
|
@ -422,23 +422,28 @@ public abstract class Protocol<C1 extends ClientboundPacketType, C2 extends Clie
|
||||
throw e;
|
||||
}
|
||||
|
||||
Class<? extends PacketType> packetTypeClass = direction == Direction.OUTGOING ? oldClientboundPacketEnum : newServerboundPacketEnum;
|
||||
Class<? extends PacketType> packetTypeClass = state == State.PLAY ? (direction == Direction.OUTGOING ? oldClientboundPacketEnum : newServerboundPacketEnum) : null;
|
||||
if (packetTypeClass != null) {
|
||||
PacketType[] enumConstants = packetTypeClass.getEnumConstants();
|
||||
PacketType packetType = oldId < enumConstants.length && oldId >= 0 ? enumConstants[oldId] : null;
|
||||
Via.getPlatform().getLogger().warning("ERROR IN " + getClass().getSimpleName() + " IN REMAP OF " + packetType + " (" + oldId + ")");
|
||||
Via.getPlatform().getLogger().warning("ERROR IN " + getClass().getSimpleName() + " IN REMAP OF " + packetType + " (" + toNiceHex(oldId) + ")");
|
||||
} else {
|
||||
Via.getPlatform().getLogger().warning("ERROR IN " + getClass().getSimpleName()
|
||||
+ " IN REMAP OF 0x" + Integer.toHexString(oldId) + "->0x" + Integer.toHexString(newId));
|
||||
+ " IN REMAP OF 0x" + toNiceHex(oldId) + "->0x" + toNiceHex(newId));
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
if (packetWrapper.isCancelled()) {
|
||||
throw Via.getManager().isDebug() ? new CancelException() : CancelException.CACHED;
|
||||
throw CancelException.generate();
|
||||
}
|
||||
}
|
||||
|
||||
private String toNiceHex(int id) {
|
||||
String hex = Integer.toHexString(id).toUpperCase();
|
||||
return (hex.length() == 1 ? "0x0" : "0x") + hex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param packetType packet type
|
||||
* @param isValid expression to check the packet's validity
|
||||
|
@ -37,7 +37,7 @@ public class ProtocolPipeline extends SimpleProtocol {
|
||||
ProtocolInfo protocolInfo = new ProtocolInfo(userConnection);
|
||||
protocolInfo.setPipeline(this);
|
||||
|
||||
userConnection.put(protocolInfo);
|
||||
userConnection.setProtocolInfo(protocolInfo);
|
||||
|
||||
/* Init through all our pipes */
|
||||
for (Protocol protocol : protocolList) {
|
||||
@ -83,11 +83,11 @@ public class ProtocolPipeline extends SimpleProtocol {
|
||||
|
||||
if (Via.getManager().isDebug()) {
|
||||
// Debug packet
|
||||
int serverProtocol = userConnection.get(ProtocolInfo.class).getServerProtocolVersion();
|
||||
int clientProtocol = userConnection.get(ProtocolInfo.class).getProtocolVersion();
|
||||
int serverProtocol = userConnection.getProtocolInfo().getServerProtocolVersion();
|
||||
int clientProtocol = userConnection.getProtocolInfo().getProtocolVersion();
|
||||
ViaPlatform platform = Via.getPlatform();
|
||||
|
||||
String actualUsername = packetWrapper.user().get(ProtocolInfo.class).getUsername();
|
||||
String actualUsername = packetWrapper.user().getProtocolInfo().getUsername();
|
||||
String username = actualUsername != null ? actualUsername + " " : "";
|
||||
|
||||
platform.getLogger().log(Level.INFO, "{0}{1} {2}: {3} (0x{4}) -> {5} (0x{6}) [{7}] {8}",
|
||||
|
@ -0,0 +1,43 @@
|
||||
package us.myles.ViaVersion.exception;
|
||||
|
||||
import io.netty.handler.codec.DecoderException;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
|
||||
/**
|
||||
* Thrown during packet decoding when an incoming packet should be cancelled.
|
||||
* Specifically extends {@link DecoderException} to prevent netty from wrapping the exception.
|
||||
*/
|
||||
public class CancelDecoderException extends DecoderException {
|
||||
public static final CancelDecoderException CACHED = new CancelDecoderException("CACHED") {
|
||||
@Override
|
||||
public Throwable fillInStackTrace() {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
public CancelDecoderException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public CancelDecoderException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public CancelDecoderException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public CancelDecoderException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cached CancelDecoderException or a new instance when {@link us.myles.ViaVersion.ViaManager#isDebug()} is true.
|
||||
*
|
||||
* @param cause cause for being used when a new instance is creeated
|
||||
* @return a CancelDecoderException instance
|
||||
*/
|
||||
public static CancelDecoderException generate(Throwable cause) {
|
||||
return Via.getManager().isDebug() ? new CancelDecoderException(cause) : CACHED;
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package us.myles.ViaVersion.exception;
|
||||
|
||||
import io.netty.handler.codec.EncoderException;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
|
||||
/**
|
||||
* Thrown during packet encoding when an outgoing packet should be cancelled.
|
||||
* Specifically extends {@link EncoderException} to prevent netty from wrapping the exception.
|
||||
*/
|
||||
public class CancelEncoderException extends EncoderException {
|
||||
public static final CancelEncoderException CACHED = new CancelEncoderException("CACHED") {
|
||||
@Override
|
||||
public Throwable fillInStackTrace() {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
public CancelEncoderException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public CancelEncoderException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public CancelEncoderException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public CancelEncoderException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cached CancelEncoderException or a new instance when {@link us.myles.ViaVersion.ViaManager#isDebug()} is true.
|
||||
*
|
||||
* @param cause cause for being used when a new instance is creeated
|
||||
* @return a CancelEncoderException instance
|
||||
*/
|
||||
public static CancelEncoderException generate(Throwable cause) {
|
||||
return Via.getManager().isDebug() ? new CancelEncoderException(cause) : CACHED;
|
||||
}
|
||||
}
|
@ -1,9 +1,16 @@
|
||||
package us.myles.ViaVersion.exception;
|
||||
|
||||
import io.netty.handler.codec.CodecException;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
|
||||
/**
|
||||
* Thrown during packet transformation to cancel the packet.
|
||||
* Internally catched to then throw the appropriate {@link CodecException} for Netty's handler.
|
||||
*/
|
||||
public class CancelException extends Exception {
|
||||
public static final CancelException CACHED = new CancelException("Cached - Enable /viaver debug to not use cached exception") {
|
||||
@Override
|
||||
public synchronized Throwable fillInStackTrace() {
|
||||
public Throwable fillInStackTrace() {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
@ -26,4 +33,13 @@ public class CancelException extends Exception {
|
||||
public CancelException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cached CancelException or a new instance when {@link us.myles.ViaVersion.ViaManager#isDebug()} is true.
|
||||
*
|
||||
* @return a CancelException instance
|
||||
*/
|
||||
public static CancelException generate() {
|
||||
return Via.getManager().isDebug() ? new CancelException() : CACHED;
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,8 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
|
||||
public interface ViaHandler {
|
||||
public void transform(ByteBuf bytebuf) throws Exception;
|
||||
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception;
|
||||
void transform(ByteBuf bytebuf) throws Exception;
|
||||
|
||||
void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception;
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ public class BaseProtocol extends SimpleProtocol {
|
||||
int protVer = wrapper.get(Type.VAR_INT, 0);
|
||||
int state = wrapper.get(Type.VAR_INT, 1);
|
||||
|
||||
ProtocolInfo info = wrapper.user().get(ProtocolInfo.class);
|
||||
ProtocolInfo info = wrapper.user().getProtocolInfo();
|
||||
info.setProtocolVersion(protVer);
|
||||
// Ensure the server has a version provider
|
||||
if (Via.getManager().getProviders().get(VersionProvider.class) == null) {
|
||||
@ -55,7 +55,7 @@ public class BaseProtocol extends SimpleProtocol {
|
||||
protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), protocol);
|
||||
}
|
||||
|
||||
ProtocolPipeline pipeline = wrapper.user().get(ProtocolInfo.class).getPipeline();
|
||||
ProtocolPipeline pipeline = wrapper.user().getProtocolInfo().getPipeline();
|
||||
if (protocols != null) {
|
||||
for (Pair<Integer, Protocol> prot : protocols) {
|
||||
pipeline.add(prot.getValue());
|
||||
|
@ -38,7 +38,7 @@ public class BaseProtocol1_7 extends SimpleProtocol {
|
||||
handler(new PacketHandler() {
|
||||
@Override
|
||||
public void handle(PacketWrapper wrapper) throws Exception {
|
||||
ProtocolInfo info = wrapper.user().get(ProtocolInfo.class);
|
||||
ProtocolInfo info = wrapper.user().getProtocolInfo();
|
||||
String originalStatus = wrapper.get(Type.STRING, 0);
|
||||
try {
|
||||
JsonElement json = GsonUtil.getGson().fromJson(originalStatus, JsonElement.class);
|
||||
@ -113,7 +113,7 @@ public class BaseProtocol1_7 extends SimpleProtocol {
|
||||
handler(new PacketHandler() {
|
||||
@Override
|
||||
public void handle(PacketWrapper wrapper) throws Exception {
|
||||
ProtocolInfo info = wrapper.user().get(ProtocolInfo.class);
|
||||
ProtocolInfo info = wrapper.user().getProtocolInfo();
|
||||
info.setState(State.PLAY);
|
||||
|
||||
if (info.getServerProtocolVersion() >= ProtocolVersion.v1_16.getId()) {
|
||||
@ -170,7 +170,7 @@ public class BaseProtocol1_7 extends SimpleProtocol {
|
||||
handler(new PacketHandler() {
|
||||
@Override
|
||||
public void handle(final PacketWrapper wrapper) throws Exception {
|
||||
int protocol = wrapper.user().get(ProtocolInfo.class).getProtocolVersion();
|
||||
int protocol = wrapper.user().getProtocolInfo().getProtocolVersion();
|
||||
if (Via.getConfig().getBlockedProtocols().contains(protocol)) {
|
||||
if (!wrapper.user().getChannel().isOpen()) return;
|
||||
|
||||
|
@ -2,14 +2,14 @@ package us.myles.ViaVersion.protocols.protocol1_13to1_12_2;
|
||||
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.TabCompleteTracker;
|
||||
|
||||
public class TabCompleteThread implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
for (UserConnection info : Via.getManager().getConnections()) {
|
||||
if (info.has(ProtocolInfo.class) && info.get(ProtocolInfo.class).getPipeline().contains(Protocol1_13To1_12_2.class)) {
|
||||
if (info.getProtocolInfo() == null) continue;
|
||||
if (info.getProtocolInfo().getPipeline().contains(Protocol1_13To1_12_2.class)) {
|
||||
if (info.getChannel().isOpen()) {
|
||||
info.get(TabCompleteTracker.class).sendPacketToServer();
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ public abstract class AbstractFenceConnectionHandler extends ConnectionHandler {
|
||||
|
||||
protected byte getStates(UserConnection user, Position position, int blockState) {
|
||||
byte states = 0;
|
||||
boolean pre1_12 = user.get(ProtocolInfo.class).getServerProtocolVersion() < ProtocolVersion.v1_12.getId();
|
||||
boolean pre1_12 = user.getProtocolInfo().getServerProtocolVersion() < ProtocolVersion.v1_12.getId();
|
||||
if (connects(BlockFace.EAST, getBlockData(user, position.getRelative(BlockFace.EAST)), pre1_12)) states |= 1;
|
||||
if (connects(BlockFace.NORTH, getBlockData(user, position.getRelative(BlockFace.NORTH)), pre1_12)) states |= 2;
|
||||
if (connects(BlockFace.SOUTH, getBlockData(user, position.getRelative(BlockFace.SOUTH)), pre1_12)) states |= 4;
|
||||
|
@ -41,7 +41,7 @@ public class GlassConnectionHandler extends AbstractFenceConnectionHandler {
|
||||
byte states = super.getStates(user, position, blockState);
|
||||
if (states != 0) return states;
|
||||
|
||||
ProtocolInfo protocolInfo = user.get(ProtocolInfo.class);
|
||||
ProtocolInfo protocolInfo = user.getProtocolInfo();
|
||||
return protocolInfo.getServerProtocolVersion() <= 47
|
||||
&& protocolInfo.getServerProtocolVersion() != -1 ? 0xF : states;
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ import us.myles.ViaVersion.api.type.PartialType;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.api.type.types.minecraft.BaseChunkType;
|
||||
import us.myles.ViaVersion.api.type.types.version.Types1_9;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.protocol1_10to1_9_3.Protocol1_10To1_9_3_4;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
|
||||
|
||||
@ -26,7 +25,7 @@ public class Chunk1_9_1_2Type extends PartialType<Chunk, ClientWorld> {
|
||||
|
||||
@Override
|
||||
public Chunk read(ByteBuf input, ClientWorld world) throws Exception {
|
||||
boolean replacePistons = world.getUser().get(ProtocolInfo.class).getPipeline().contains(Protocol1_10To1_9_3_4.class) && Via.getConfig().isReplacePistons();
|
||||
boolean replacePistons = world.getUser().getProtocolInfo().getPipeline().contains(Protocol1_10To1_9_3_4.class) && Via.getConfig().isReplacePistons();
|
||||
int replacementId = Via.getConfig().getPistonReplacementId();
|
||||
|
||||
int chunkX = input.readInt();
|
||||
|
@ -10,7 +10,7 @@ public class ViaIdleThread implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
for (UserConnection info : Via.getManager().getConnections()) {
|
||||
ProtocolInfo protocolInfo = info.get(ProtocolInfo.class);
|
||||
ProtocolInfo protocolInfo = info.getProtocolInfo();
|
||||
if (protocolInfo != null && protocolInfo.getPipeline().contains(Protocol1_9To1_8.class)) {
|
||||
long nextIdleUpdate = info.get(MovementTracker.class).getNextIdlePacket();
|
||||
if (nextIdleUpdate <= System.currentTimeMillis()) {
|
||||
|
@ -126,7 +126,7 @@ public class PlayerPackets {
|
||||
if (mode == 0 || mode == 3 || mode == 4) {
|
||||
String[] players = wrapper.passthrough(Type.STRING_ARRAY); // Players
|
||||
final EntityTracker1_9 entityTracker = wrapper.user().get(EntityTracker1_9.class);
|
||||
String myName = wrapper.user().get(ProtocolInfo.class).getUsername();
|
||||
String myName = wrapper.user().getProtocolInfo().getUsername();
|
||||
String teamName = wrapper.get(Type.STRING, 0);
|
||||
for (String player : players) {
|
||||
if (entityTracker.isAutoTeam() && player.equalsIgnoreCase(myName)) {
|
||||
|
@ -191,7 +191,7 @@ public class EntityTracker1_9 extends EntityTracker {
|
||||
}
|
||||
}
|
||||
}
|
||||
UUID uuid = getUser().get(ProtocolInfo.class).getUuid();
|
||||
UUID uuid = getUser().getProtocolInfo().getUuid();
|
||||
// Boss bar
|
||||
if (Via.getConfig().isBossbarPatch()) {
|
||||
if (type == EntityType.ENDER_DRAGON || type == EntityType.WITHER) {
|
||||
@ -256,7 +256,7 @@ public class EntityTracker1_9 extends EntityTracker {
|
||||
} else {
|
||||
wrapper.write(Type.BYTE, (byte) 3);
|
||||
}
|
||||
wrapper.write(Type.STRING_ARRAY, new String[]{getUser().get(ProtocolInfo.class).getUsername()});
|
||||
wrapper.write(Type.STRING_ARRAY, new String[]{getUser().getProtocolInfo().getUsername()});
|
||||
} else {
|
||||
wrapper.write(Type.BYTE, (byte) 1); // remove team
|
||||
}
|
||||
@ -283,7 +283,7 @@ public class EntityTracker1_9 extends EntityTracker {
|
||||
PacketWrapper wrapper = new PacketWrapper(0x39, null, getUser());
|
||||
wrapper.write(Type.VAR_INT, entityId);
|
||||
wrapper.write(Types1_9.METADATA_LIST, metadataList);
|
||||
getUser().get(ProtocolInfo.class).getPipeline().getProtocol(Protocol1_9To1_8.class).get(MetadataRewriter1_9To1_8.class)
|
||||
getUser().getProtocolInfo().getPipeline().getProtocol(Protocol1_9To1_8.class).get(MetadataRewriter1_9To1_8.class)
|
||||
.handleMetadata(entityId, metadataList, getUser());
|
||||
handleMetadata(entityId, metadataList);
|
||||
if (!metadataList.isEmpty()) {
|
||||
|
@ -48,7 +48,7 @@ public class Chunk1_9to1_8Type extends PartialType<Chunk, ClientChunks> {
|
||||
|
||||
@Override
|
||||
public Chunk read(ByteBuf input, ClientChunks param) throws Exception {
|
||||
boolean replacePistons = param.getUser().get(ProtocolInfo.class).getPipeline().contains(Protocol1_10To1_9_3_4.class) && Via.getConfig().isReplacePistons();
|
||||
boolean replacePistons = param.getUser().getProtocolInfo().getPipeline().contains(Protocol1_10To1_9_3_4.class) && Via.getConfig().isReplacePistons();
|
||||
int replacementId = Via.getConfig().getPistonReplacementId();
|
||||
|
||||
int chunkX = input.readInt();
|
||||
|
@ -1,276 +0,0 @@
|
||||
package us.myles.ViaVersion.util;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* Created by wea_ondara licensed under MIT
|
||||
* Same license as in LICENSE
|
||||
* <p>
|
||||
* Taken from:
|
||||
* https://github.com/weaondara/BungeePerms/blob/master/src/main/java/net/alpenblock/bungeeperms/util/ConcurrentList.java
|
||||
*
|
||||
* @param <E> List Type
|
||||
*/
|
||||
public class ConcurrentList<E> extends ArrayList<E> {
|
||||
|
||||
private final Object lock = new Object();
|
||||
|
||||
@Override
|
||||
public boolean add(E e) {
|
||||
synchronized (lock) {
|
||||
return super.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, E element) {
|
||||
synchronized (lock) {
|
||||
super.add(index, element);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends E> c) {
|
||||
synchronized (lock) {
|
||||
return super.addAll(c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(int index, Collection<? extends E> c) {
|
||||
synchronized (lock) {
|
||||
return super.addAll(index, c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
synchronized (lock) {
|
||||
super.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
synchronized (lock) {
|
||||
try {
|
||||
ConcurrentList<E> clist = (ConcurrentList<E>) super.clone();
|
||||
clist.modCount = 0;
|
||||
Field f = ArrayList.class.getDeclaredField("elementData");
|
||||
f.setAccessible(true);
|
||||
f.set(clist, Arrays.copyOf((Object[]) f.get(this), this.size()));
|
||||
|
||||
return clist;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
synchronized (lock) {
|
||||
return super.contains(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ensureCapacity(int minCapacity) {
|
||||
synchronized (lock) {
|
||||
super.ensureCapacity(minCapacity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public E get(int index) {
|
||||
synchronized (lock) {
|
||||
return super.get(index);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object o) {
|
||||
synchronized (lock) {
|
||||
return super.indexOf(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object o) {
|
||||
synchronized (lock) {
|
||||
return super.lastIndexOf(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public E remove(int index) {
|
||||
synchronized (lock) {
|
||||
return super.remove(index);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
synchronized (lock) {
|
||||
return super.remove(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
synchronized (lock) {
|
||||
return super.removeAll(c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
synchronized (lock) {
|
||||
return super.retainAll(c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public E set(int index, E element) {
|
||||
synchronized (lock) {
|
||||
return super.set(index, element);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<E> subList(int fromIndex, int toIndex) {
|
||||
synchronized (lock) {
|
||||
return super.subList(fromIndex, toIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
synchronized (lock) {
|
||||
return super.toArray();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(T[] a) {
|
||||
synchronized (lock) {
|
||||
return super.toArray(a);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trimToSize() {
|
||||
synchronized (lock) {
|
||||
super.trimToSize();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator<E> listIterator() {
|
||||
return new ListItr(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
return new Itr();
|
||||
}
|
||||
|
||||
private class Itr implements Iterator<E> {
|
||||
|
||||
protected int cursor;
|
||||
protected int lastRet;
|
||||
final ConcurrentList l;
|
||||
|
||||
public Itr() {
|
||||
cursor = 0;
|
||||
lastRet = -1;
|
||||
l = (ConcurrentList) ConcurrentList.this.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return cursor < l.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E next() {
|
||||
int i = cursor;
|
||||
if (i >= l.size()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
cursor = i + 1;
|
||||
return (E) l.get(lastRet = i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
if (lastRet < 0) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
l.remove(lastRet);
|
||||
ConcurrentList.this.remove(lastRet);
|
||||
cursor = lastRet;
|
||||
lastRet = -1;
|
||||
}
|
||||
}
|
||||
|
||||
public class ListItr extends Itr implements ListIterator<E> {
|
||||
|
||||
ListItr(int index) {
|
||||
super();
|
||||
cursor = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrevious() {
|
||||
return cursor > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextIndex() {
|
||||
return cursor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int previousIndex() {
|
||||
return cursor - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E previous() {
|
||||
int i = cursor - 1;
|
||||
if (i < 0) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
cursor = i;
|
||||
return (E) l.get(lastRet = i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(E e) {
|
||||
if (lastRet < 0) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
l.set(lastRet, e);
|
||||
ConcurrentList.this.set(lastRet, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(E e) {
|
||||
int i = cursor;
|
||||
l.add(i, e);
|
||||
ConcurrentList.this.add(i, e);
|
||||
cursor = i + 1;
|
||||
lastRet = -1;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,12 +3,8 @@ package us.myles.ViaVersion.sponge.handlers;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.exception.CancelException;
|
||||
import us.myles.ViaVersion.packets.Direction;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.exception.CancelDecoderException;
|
||||
import us.myles.ViaVersion.util.PipelineUtil;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@ -26,64 +22,37 @@ public class SpongeDecodeHandler extends ByteToMessageDecoder {
|
||||
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, ByteBuf bytebuf, List<Object> list) throws Exception {
|
||||
// use transformers
|
||||
if (bytebuf.readableBytes() > 0) {
|
||||
// Ignore if pending disconnect
|
||||
if (info.isPendingDisconnect()) {
|
||||
return;
|
||||
}
|
||||
// Increment received
|
||||
boolean second = info.incrementReceived();
|
||||
// Check PPS
|
||||
if (second) {
|
||||
if (info.handlePPS())
|
||||
return;
|
||||
if (!info.checkIncomingPacket()) {
|
||||
bytebuf.clear(); // Don't accumulate
|
||||
throw CancelDecoderException.generate(null);
|
||||
}
|
||||
|
||||
ByteBuf transformedBuf = null;
|
||||
try {
|
||||
if (info.shouldTransformPacket()) {
|
||||
transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
|
||||
info.transformIncoming(transformedBuf, CancelDecoderException::generate);
|
||||
}
|
||||
|
||||
if (info.isActive()) {
|
||||
// Handle ID
|
||||
int id = Type.VAR_INT.read(bytebuf);
|
||||
// Transform
|
||||
ByteBuf newPacket = ctx.alloc().buffer();
|
||||
try {
|
||||
if (id == PacketWrapper.PASSTHROUGH_ID) {
|
||||
newPacket.writeBytes(bytebuf);
|
||||
} else {
|
||||
PacketWrapper wrapper = new PacketWrapper(id, bytebuf, info);
|
||||
ProtocolInfo protInfo = info.get(ProtocolInfo.class);
|
||||
protInfo.getPipeline().transform(Direction.INCOMING, protInfo.getState(), wrapper);
|
||||
wrapper.writeToBuffer(newPacket);
|
||||
}
|
||||
|
||||
bytebuf.clear();
|
||||
bytebuf = newPacket;
|
||||
} catch (Throwable e) {
|
||||
// Clear Buffer
|
||||
bytebuf.clear();
|
||||
// Release Packet, be free!
|
||||
newPacket.release();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// call minecraft decoder
|
||||
try {
|
||||
list.addAll(PipelineUtil.callDecode(this.minecraftDecoder, ctx, bytebuf));
|
||||
list.addAll(PipelineUtil.callDecode(this.minecraftDecoder, ctx, transformedBuf == null ? bytebuf : transformedBuf));
|
||||
} catch (InvocationTargetException e) {
|
||||
if (e.getCause() instanceof Exception) {
|
||||
throw (Exception) e.getCause();
|
||||
} else if (e.getCause() instanceof Error) {
|
||||
throw (Error) e.getCause();
|
||||
}
|
||||
} finally {
|
||||
if (info.isActive()) {
|
||||
bytebuf.release();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (transformedBuf != null) {
|
||||
transformedBuf.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
if (PipelineUtil.containsCause(cause, CancelException.class)) return;
|
||||
if (cause instanceof CancelDecoderException) return;
|
||||
super.exceptionCaught(ctx, cause);
|
||||
}
|
||||
}
|
||||
|
@ -3,69 +3,52 @@ package us.myles.ViaVersion.sponge.handlers;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToByteEncoder;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.exception.CancelException;
|
||||
import us.myles.ViaVersion.packets.Direction;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.exception.CancelEncoderException;
|
||||
import us.myles.ViaVersion.handlers.ChannelHandlerContextWrapper;
|
||||
import us.myles.ViaVersion.handlers.ViaHandler;
|
||||
import us.myles.ViaVersion.util.PipelineUtil;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class SpongeEncodeHandler extends MessageToByteEncoder {
|
||||
public class SpongeEncodeHandler extends MessageToByteEncoder<Object> implements ViaHandler {
|
||||
private final UserConnection info;
|
||||
private final MessageToByteEncoder minecraftEncoder;
|
||||
private final MessageToByteEncoder<?> minecraftEncoder;
|
||||
|
||||
public SpongeEncodeHandler(UserConnection info, MessageToByteEncoder minecraftEncoder) {
|
||||
public SpongeEncodeHandler(UserConnection info, MessageToByteEncoder<?> minecraftEncoder) {
|
||||
this.info = info;
|
||||
this.minecraftEncoder = minecraftEncoder;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void encode(final ChannelHandlerContext ctx, Object o, final ByteBuf bytebuf) throws Exception {
|
||||
// handle the packet type
|
||||
if (!(o instanceof ByteBuf)) {
|
||||
// call minecraft encoder
|
||||
try {
|
||||
PipelineUtil.callEncode(this.minecraftEncoder, ctx, o, bytebuf);
|
||||
PipelineUtil.callEncode(this.minecraftEncoder, new ChannelHandlerContextWrapper(ctx, this), o, bytebuf);
|
||||
} catch (InvocationTargetException e) {
|
||||
if (e.getCause() instanceof Exception) {
|
||||
throw (Exception) e.getCause();
|
||||
} else if (e.getCause() instanceof Error) {
|
||||
throw (Error) e.getCause();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bytebuf.readableBytes() == 0) {
|
||||
throw Via.getManager().isDebug() ? new CancelException() : CancelException.CACHED;
|
||||
}
|
||||
// Increment sent
|
||||
info.incrementSent();
|
||||
if (info.isActive()) {
|
||||
// Handle ID
|
||||
int id = Type.VAR_INT.read(bytebuf);
|
||||
// Transform
|
||||
ByteBuf oldPacket = bytebuf.copy();
|
||||
bytebuf.clear();
|
||||
|
||||
try {
|
||||
PacketWrapper wrapper = new PacketWrapper(id, oldPacket, info);
|
||||
ProtocolInfo protInfo = info.get(ProtocolInfo.class);
|
||||
protInfo.getPipeline().transform(Direction.OUTGOING, protInfo.getState(), wrapper);
|
||||
wrapper.writeToBuffer(bytebuf);
|
||||
} catch (Throwable e) {
|
||||
bytebuf.clear();
|
||||
throw e;
|
||||
} finally {
|
||||
oldPacket.release();
|
||||
}
|
||||
}
|
||||
transform(bytebuf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transform(ByteBuf bytebuf) throws Exception {
|
||||
info.checkOutgoingPacket();
|
||||
if (!info.shouldTransformPacket()) return;
|
||||
info.transformOutgoing(bytebuf, CancelEncoderException::generate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
if (PipelineUtil.containsCause(cause, CancelException.class)) return;
|
||||
if (cause instanceof CancelEncoderException) return;
|
||||
super.exceptionCaught(ctx, cause);
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ public class SpongePacketHandler extends MessageToMessageEncoder {
|
||||
info.setLastPacket(o);
|
||||
/* This transformer is more for fixing issues which we find hard at packet level :) */
|
||||
if (info.isActive()) {
|
||||
if (info.get(ProtocolInfo.class).getPipeline().filter(o, list)) {
|
||||
if (info.getProtocolInfo().getPipeline().filter(o, list)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ public class SpongeViaAPI implements ViaAPI<Player> {
|
||||
public int getPlayerVersion(UUID uuid) {
|
||||
if (!isInjected(uuid))
|
||||
return ProtocolRegistry.SERVER_PROTOCOL;
|
||||
return Via.getManager().getConnection(uuid).get(ProtocolInfo.class).getProtocolVersion();
|
||||
return Via.getManager().getConnection(uuid).getProtocolInfo().getProtocolVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -76,7 +76,7 @@ public class SpongeViaLoader implements ViaPlatformLoader {
|
||||
@Override
|
||||
public Item getHandItem(final UserConnection info) {
|
||||
if (HandItemCache.CACHE) {
|
||||
return HandItemCache.getHandItem(info.get(ProtocolInfo.class).getUuid());
|
||||
return HandItemCache.getHandItem(info.getProtocolInfo().getUuid());
|
||||
} else {
|
||||
return super.getHandItem(info);
|
||||
}
|
||||
|
@ -4,13 +4,8 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.exception.CancelException;
|
||||
import us.myles.ViaVersion.packets.Direction;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.util.PipelineUtil;
|
||||
import us.myles.ViaVersion.exception.CancelDecoderException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -24,54 +19,24 @@ public class VelocityDecodeHandler extends MessageToMessageDecoder<ByteBuf> {
|
||||
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, ByteBuf bytebuf, List<Object> out) throws Exception {
|
||||
// use transformers
|
||||
if (bytebuf.readableBytes() > 0) {
|
||||
// Ignore if pending disconnect
|
||||
if (info.isPendingDisconnect()) {
|
||||
return;
|
||||
}
|
||||
// Increment received
|
||||
boolean second = info.incrementReceived();
|
||||
// Check PPS
|
||||
if (second) {
|
||||
if (info.handlePPS())
|
||||
return;
|
||||
}
|
||||
if (info.isActive()) {
|
||||
// Handle ID
|
||||
int id = Type.VAR_INT.read(bytebuf);
|
||||
// Transform
|
||||
ByteBuf newPacket = ctx.alloc().buffer();
|
||||
try {
|
||||
if (id == PacketWrapper.PASSTHROUGH_ID) {
|
||||
newPacket.writeBytes(bytebuf);
|
||||
} else {
|
||||
PacketWrapper wrapper = new PacketWrapper(id, bytebuf, info);
|
||||
ProtocolInfo protInfo = info.get(ProtocolInfo.class);
|
||||
protInfo.getPipeline().transform(Direction.INCOMING, protInfo.getState(), wrapper);
|
||||
wrapper.writeToBuffer(newPacket);
|
||||
}
|
||||
if (!info.checkIncomingPacket()) throw CancelDecoderException.generate(null);
|
||||
if (!info.shouldTransformPacket()) {
|
||||
out.add(bytebuf.retain());
|
||||
return;
|
||||
}
|
||||
|
||||
bytebuf.clear();
|
||||
bytebuf = newPacket;
|
||||
} catch (Throwable e) {
|
||||
// Clear Buffer
|
||||
bytebuf.clear();
|
||||
// Release Packet, be free!
|
||||
newPacket.release();
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
bytebuf.retain();
|
||||
}
|
||||
|
||||
out.add(bytebuf);
|
||||
ByteBuf transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
|
||||
try {
|
||||
info.transformIncoming(transformedBuf, CancelDecoderException::generate);
|
||||
out.add(transformedBuf.retain());
|
||||
} finally {
|
||||
transformedBuf.release();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
if (PipelineUtil.containsCause(cause, CancelException.class)) return;
|
||||
if (cause instanceof CancelDecoderException) return;
|
||||
super.exceptionCaught(ctx, cause);
|
||||
}
|
||||
}
|
||||
|
@ -6,15 +6,11 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToByteEncoder;
|
||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||
import io.netty.handler.codec.MessageToMessageEncoder;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.exception.CancelException;
|
||||
import us.myles.ViaVersion.packets.Direction;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.exception.CancelEncoderException;
|
||||
import us.myles.ViaVersion.util.PipelineUtil;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
@ -28,14 +24,38 @@ public class VelocityEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
|
||||
|
||||
@Override
|
||||
protected void encode(final ChannelHandlerContext ctx, ByteBuf bytebuf, List<Object> out) throws Exception {
|
||||
if (bytebuf.readableBytes() == 0) {
|
||||
throw Via.getManager().isDebug() ? new CancelException() : CancelException.CACHED;
|
||||
info.checkOutgoingPacket();
|
||||
if (!info.shouldTransformPacket()) {
|
||||
out.add(bytebuf.retain());
|
||||
return;
|
||||
}
|
||||
|
||||
ByteBuf transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
|
||||
try {
|
||||
boolean needsCompress = handleCompressionOrder(ctx, transformedBuf);
|
||||
|
||||
info.transformOutgoing(transformedBuf, CancelEncoderException::generate);
|
||||
|
||||
if (needsCompress) {
|
||||
recompress(ctx, transformedBuf);
|
||||
}
|
||||
out.add(transformedBuf.retain());
|
||||
} finally {
|
||||
transformedBuf.release();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean handleCompressionOrder(ChannelHandlerContext ctx, ByteBuf buf) throws InvocationTargetException {
|
||||
boolean needsCompress = false;
|
||||
if (!handledCompression
|
||||
&& ctx.pipeline().names().indexOf("compression-encoder") > ctx.pipeline().names().indexOf("via-encoder")) {
|
||||
// Need to decompress this packet due to bad order
|
||||
bytebuf = (ByteBuf) PipelineUtil.callDecode((MessageToMessageDecoder) ctx.pipeline().get("compression-decoder"), ctx, bytebuf).get(0);
|
||||
ByteBuf decompressed = (ByteBuf) PipelineUtil.callDecode((MessageToMessageDecoder<?>) ctx.pipeline().get("compression-decoder"), ctx, buf).get(0);
|
||||
try {
|
||||
buf.clear().writeBytes(decompressed);
|
||||
} finally {
|
||||
decompressed.release();
|
||||
}
|
||||
ChannelHandler encoder = ctx.pipeline().get("via-encoder");
|
||||
ChannelHandler decoder = ctx.pipeline().get("via-decoder");
|
||||
ctx.pipeline().remove(encoder);
|
||||
@ -44,51 +64,23 @@ public class VelocityEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
|
||||
ctx.pipeline().addAfter("compression-decoder", "via-decoder", decoder);
|
||||
needsCompress = true;
|
||||
handledCompression = true;
|
||||
} else {
|
||||
bytebuf.retain();
|
||||
}
|
||||
// Increment sent
|
||||
info.incrementSent();
|
||||
return needsCompress;
|
||||
}
|
||||
|
||||
|
||||
if (info.isActive()) {
|
||||
// Handle ID
|
||||
int id = Type.VAR_INT.read(bytebuf);
|
||||
// Transform
|
||||
ByteBuf newPacket = bytebuf.alloc().buffer();
|
||||
try {
|
||||
PacketWrapper wrapper = new PacketWrapper(id, bytebuf, info);
|
||||
ProtocolInfo protInfo = info.get(ProtocolInfo.class);
|
||||
protInfo.getPipeline().transform(Direction.OUTGOING, protInfo.getState(), wrapper);
|
||||
|
||||
wrapper.writeToBuffer(newPacket);
|
||||
|
||||
bytebuf.clear();
|
||||
bytebuf.release();
|
||||
bytebuf = newPacket;
|
||||
} catch (Throwable e) {
|
||||
bytebuf.clear();
|
||||
bytebuf.release();
|
||||
newPacket.release();
|
||||
throw e;
|
||||
}
|
||||
private void recompress(ChannelHandlerContext ctx, ByteBuf buf) throws InvocationTargetException {
|
||||
ByteBuf compressed = ctx.alloc().buffer();
|
||||
try {
|
||||
PipelineUtil.callEncode((MessageToByteEncoder<?>) ctx.pipeline().get("compression-encoder"), ctx, buf, compressed);
|
||||
buf.clear().writeBytes(compressed);
|
||||
} finally {
|
||||
compressed.release();
|
||||
}
|
||||
|
||||
if (needsCompress) {
|
||||
ByteBuf old = bytebuf;
|
||||
bytebuf = ctx.alloc().buffer();
|
||||
try {
|
||||
PipelineUtil.callEncode((MessageToByteEncoder) ctx.pipeline().get("compression-encoder"), ctx, old, bytebuf);
|
||||
} finally {
|
||||
old.release();
|
||||
}
|
||||
}
|
||||
out.add(bytebuf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
if (PipelineUtil.containsCause(cause, CancelException.class)) return;
|
||||
if (cause instanceof CancelEncoderException) return;
|
||||
super.exceptionCaught(ctx, cause);
|
||||
}
|
||||
}
|
||||
|
@ -26,8 +26,6 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class VelocityServerHandler {
|
||||
private static Method setProtocolVersion;
|
||||
@ -62,12 +60,12 @@ public class VelocityServerHandler {
|
||||
}
|
||||
|
||||
int protocolId = ProtocolDetectorService.getProtocolId(e.getOriginalServer().getServerInfo().getName());
|
||||
List<Pair<Integer, Protocol>> protocols = ProtocolRegistry.getProtocolPath(user.get(ProtocolInfo.class).getProtocolVersion(), protocolId);
|
||||
List<Pair<Integer, Protocol>> protocols = ProtocolRegistry.getProtocolPath(user.getProtocolInfo().getProtocolVersion(), protocolId);
|
||||
|
||||
// Check if ViaVersion can support that version
|
||||
Object connection = getMinecraftConnection.invoke(e.getPlayer());
|
||||
setNextProtocolVersion.invoke(connection, ProtocolVersion.getProtocolVersion(protocols == null
|
||||
? user.get(ProtocolInfo.class).getProtocolVersion()
|
||||
? user.getProtocolInfo().getProtocolVersion()
|
||||
: protocolId));
|
||||
|
||||
} catch (IllegalAccessException | InvocationTargetException e1) {
|
||||
@ -105,7 +103,7 @@ public class VelocityServerHandler {
|
||||
if (storage.getBossbar() != null) {
|
||||
// TODO: Verify whether this packet needs to be sent when 1.8 -> 1.9 protocol isn't present in the pipeline
|
||||
// This ensures we can encode it properly as only the 1.9 protocol is currently implemented.
|
||||
if (user.get(ProtocolInfo.class).getPipeline().contains(Protocol1_9To1_8.class)) {
|
||||
if (user.getProtocolInfo().getPipeline().contains(Protocol1_9To1_8.class)) {
|
||||
for (UUID uuid : storage.getBossbar()) {
|
||||
PacketWrapper wrapper = new PacketWrapper(0x0C, null, user);
|
||||
wrapper.write(Type.UUID, uuid);
|
||||
@ -117,12 +115,12 @@ public class VelocityServerHandler {
|
||||
}
|
||||
}
|
||||
|
||||
ProtocolInfo info = user.get(ProtocolInfo.class);
|
||||
ProtocolInfo info = user.getProtocolInfo();
|
||||
int previousServerProtocol = info.getServerProtocolVersion();
|
||||
|
||||
// Refresh the pipes
|
||||
List<Pair<Integer, Protocol>> protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), protocolId);
|
||||
ProtocolPipeline pipeline = user.get(ProtocolInfo.class).getPipeline();
|
||||
ProtocolPipeline pipeline = info.getPipeline();
|
||||
user.clearStoredObjects();
|
||||
pipeline.cleanPipes();
|
||||
if (protocols == null) {
|
||||
|
@ -27,7 +27,7 @@ public class ElytraPatch {
|
||||
if (user == null) return;
|
||||
|
||||
try {
|
||||
if (user.get(ProtocolInfo.class).getPipeline().contains(Protocol1_9To1_8.class)) {
|
||||
if (user.getProtocolInfo().getPipeline().contains(Protocol1_9To1_8.class)) {
|
||||
int entityId = user.get(EntityTracker1_9.class).getProvidedEntityId();
|
||||
|
||||
PacketWrapper wrapper = new PacketWrapper(0x39, null, user);
|
||||
|
@ -22,7 +22,7 @@ public class VelocityViaAPI implements ViaAPI<Player> {
|
||||
public int getPlayerVersion(Player player) {
|
||||
if (!isInjected(player.getUniqueId()))
|
||||
return player.getProtocolVersion().getProtocol();
|
||||
return Via.getManager().getConnection(player.getUniqueId()).get(ProtocolInfo.class).getProtocolVersion();
|
||||
return Via.getManager().getConnection(player.getUniqueId()).getProtocolInfo().getProtocolVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -4,7 +4,6 @@ import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.packets.State;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.MovementTracker;
|
||||
@ -21,7 +20,7 @@ public class VelocityMovementTransmitter extends MovementTransmitterProvider {
|
||||
}
|
||||
|
||||
public void sendPlayer(UserConnection userConnection) {
|
||||
if (userConnection.get(ProtocolInfo.class).getState() == State.PLAY) {
|
||||
if (userConnection.getProtocolInfo().getState() == State.PLAY) {
|
||||
PacketWrapper wrapper = new PacketWrapper(0x03, null, userConnection);
|
||||
wrapper.write(Type.BOOLEAN, userConnection.get(MovementTracker.class).isGround());
|
||||
try {
|
||||
|
@ -4,7 +4,6 @@ import us.myles.ViaVersion.VelocityPlugin;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.base.VersionProvider;
|
||||
import us.myles.ViaVersion.velocity.platform.VelocityViaInjector;
|
||||
|
||||
@ -15,7 +14,7 @@ public class VelocityVersionProvider extends VersionProvider {
|
||||
|
||||
@Override
|
||||
public int getServerProtocol(UserConnection user) throws Exception {
|
||||
int playerVersion = user.get(ProtocolInfo.class).getProtocolVersion();
|
||||
int playerVersion = user.getProtocolInfo().getProtocolVersion();
|
||||
|
||||
IntStream versions = com.velocitypowered.api.network.ProtocolVersion.SUPPORTED_VERSIONS.stream()
|
||||
.mapToInt(com.velocitypowered.api.network.ProtocolVersion::getProtocol);
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren