mirror of
https://github.com/ViaVersion/ViaVersion.git
synced 2024-10-31 23:59:33 +01:00
inject into velocity backend (currently broken)
Add client-side mode for UserConnection remove unused code fix duplicate method on rebase
This commit is contained in:
parent
69c8cf8ffb
commit
4813cc3077
@ -61,7 +61,7 @@ public class BukkitEncodeHandler extends MessageToByteEncoder implements ViaHand
|
||||
|
||||
@Override
|
||||
public void transform(ByteBuf bytebuf) throws Exception {
|
||||
info.checkOutgoingPacket();
|
||||
if (!info.checkOutgoingPacket()) throw CancelEncoderException.generate(null);
|
||||
if (!info.shouldTransformPacket()) return;
|
||||
info.transformOutgoing(bytebuf, CancelEncoderException::generate);
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ public class BungeeEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
|
||||
|
||||
@Override
|
||||
protected void encode(final ChannelHandlerContext ctx, ByteBuf bytebuf, List<Object> out) throws Exception {
|
||||
info.checkOutgoingPacket();
|
||||
if (!info.checkOutgoingPacket()) throw CancelEncoderException.generate(null);
|
||||
if (!info.shouldTransformPacket()) {
|
||||
out.add(bytebuf.retain());
|
||||
return;
|
||||
|
@ -18,7 +18,6 @@ import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.util.PipelineUtil;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.Function;
|
||||
@ -29,6 +28,7 @@ public class UserConnection {
|
||||
private final Channel channel;
|
||||
private ProtocolInfo protocolInfo;
|
||||
Map<Class, StoredObject> storedObjects = new ConcurrentHashMap<>();
|
||||
private final boolean clientSide;
|
||||
private boolean active = true;
|
||||
private boolean pendingDisconnect;
|
||||
private Object lastPacket;
|
||||
@ -42,8 +42,23 @@ public class UserConnection {
|
||||
private int secondsObserved;
|
||||
private int warnings;
|
||||
|
||||
public UserConnection(@Nullable Channel channel) {
|
||||
/**
|
||||
* Creates an UserConnection. When it's a client-side connection, some method behaviors are modified.
|
||||
* @param channel netty channel.
|
||||
* @param clientSide true if it's a client-side connection
|
||||
*/
|
||||
public UserConnection(@Nullable Channel channel, boolean clientSide) {
|
||||
this.channel = channel;
|
||||
this.clientSide = clientSide;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see #UserConnection(Channel, boolean)
|
||||
* @param channel
|
||||
*/
|
||||
public UserConnection(@Nullable Channel channel) {
|
||||
this(channel, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -91,12 +106,24 @@ public class UserConnection {
|
||||
* @param packet The raw packet to send
|
||||
* @param currentThread Should it run in the same thread
|
||||
*/
|
||||
public void sendRawPacket(ByteBuf packet, boolean currentThread) {
|
||||
ChannelHandler handler = channel.pipeline().get(Via.getManager().getInjector().getEncoderName());
|
||||
if (currentThread) {
|
||||
channel.pipeline().context(handler).writeAndFlush(packet);
|
||||
public void sendRawPacket(final ByteBuf packet, boolean currentThread) {
|
||||
Runnable act;
|
||||
if (clientSide) {
|
||||
// We'll just assume that Via decoder isn't wrapping the original decoder
|
||||
act = () -> getChannel().pipeline()
|
||||
.context(Via.getManager().getInjector().getDecoderName()).fireChannelRead(packet);
|
||||
} else {
|
||||
channel.eventLoop().submit(() -> channel.pipeline().context(handler).writeAndFlush(packet));
|
||||
act = () -> channel.pipeline().context(Via.getManager().getInjector().getEncoderName()).writeAndFlush(packet);
|
||||
}
|
||||
if (currentThread) {
|
||||
act.run();
|
||||
} else {
|
||||
try {
|
||||
channel.eventLoop().submit(act);
|
||||
} catch (Throwable e) {
|
||||
packet.release(); // Couldn't schedule
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,11 +133,25 @@ public class UserConnection {
|
||||
* @param packet The raw packet to send
|
||||
* @return ChannelFuture of the packet being sent
|
||||
*/
|
||||
public ChannelFuture sendRawPacketFuture(ByteBuf packet) {
|
||||
ChannelHandler handler = channel.pipeline().get(Via.getManager().getInjector().getEncoderName());
|
||||
public ChannelFuture sendRawPacketFuture(final ByteBuf packet) {
|
||||
if (clientSide) {
|
||||
return sendRawPacketFutureClientSide(packet);
|
||||
} else {
|
||||
return sendRawPacketFutureServerSide(packet);
|
||||
}
|
||||
}
|
||||
|
||||
private ChannelFuture sendRawPacketFutureServerSide(final ByteBuf packet) {
|
||||
final ChannelHandler handler = channel.pipeline().get(Via.getManager().getInjector().getEncoderName());
|
||||
return channel.pipeline().context(handler).writeAndFlush(packet);
|
||||
}
|
||||
|
||||
private ChannelFuture sendRawPacketFutureClientSide(final ByteBuf packet) {
|
||||
// Assume that decoder isn't wrapping
|
||||
getChannel().pipeline().context(Via.getManager().getInjector().getDecoderName()).fireChannelRead(packet);
|
||||
return getChannel().newSucceededFuture();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a raw packet to the player (netty thread).
|
||||
*
|
||||
@ -156,6 +197,7 @@ public class UserConnection {
|
||||
* @see #incrementReceived()
|
||||
*/
|
||||
public boolean exceedsMaxPPS() {
|
||||
if (clientSide) return false; // Don't apply PPS limiting for client-side
|
||||
ViaVersionConfig conf = Via.getConfig();
|
||||
// Max PPS Checker
|
||||
if (conf.getMaxPPS() > 0) {
|
||||
@ -195,14 +237,8 @@ public class UserConnection {
|
||||
if (!channel.isOpen() || pendingDisconnect) return;
|
||||
|
||||
pendingDisconnect = true;
|
||||
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))) {
|
||||
if (!Via.getPlatform().disconnect(this, ChatColor.translateAlternateColorCodes('&', reason))) {
|
||||
channel.close(); // =)
|
||||
}
|
||||
});
|
||||
@ -214,9 +250,20 @@ public class UserConnection {
|
||||
* @param packet Raw packet to be sent
|
||||
* @param currentThread If {@code true} executes immediately, {@code false} submits a task to EventLoop
|
||||
*/
|
||||
public void sendRawPacketToServer(ByteBuf packet, boolean currentThread) {
|
||||
ByteBuf buf = packet.alloc().buffer();
|
||||
public void sendRawPacketToServer(final ByteBuf packet, boolean currentThread) {
|
||||
if (clientSide) {
|
||||
sendRawPacketToServerClientSide(packet, currentThread);
|
||||
} else {
|
||||
sendRawPacketToServerServerSide(packet, currentThread);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendRawPacketToServerServerSide(final ByteBuf packet, boolean currentThread) {
|
||||
final ByteBuf buf = packet.alloc().buffer();
|
||||
try {
|
||||
// We'll use passing through because there are some encoder wrappers
|
||||
ChannelHandlerContext context = PipelineUtil
|
||||
.getPreviousContext(Via.getManager().getInjector().getDecoderName(), channel.pipeline());
|
||||
try {
|
||||
Type.VAR_INT.writePrimitive(buf, PacketWrapper.PASSTHROUGH_ID);
|
||||
} catch (Exception e) {
|
||||
@ -224,23 +271,18 @@ public class UserConnection {
|
||||
Via.getPlatform().getLogger().warning("Type.VAR_INT.write thrown an exception: " + e);
|
||||
}
|
||||
buf.writeBytes(packet);
|
||||
ChannelHandlerContext context = PipelineUtil
|
||||
.getPreviousContext(Via.getManager().getInjector().getDecoderName(), channel.pipeline());
|
||||
if (currentThread) {
|
||||
Runnable act = () -> {
|
||||
if (context != null) {
|
||||
context.fireChannelRead(buf);
|
||||
} else {
|
||||
channel.pipeline().fireChannelRead(buf);
|
||||
}
|
||||
};
|
||||
if (currentThread) {
|
||||
act.run();
|
||||
} else {
|
||||
try {
|
||||
channel.eventLoop().submit(() -> {
|
||||
if (context != null) {
|
||||
context.fireChannelRead(buf);
|
||||
} else {
|
||||
channel.pipeline().fireChannelRead(buf);
|
||||
}
|
||||
});
|
||||
channel.eventLoop().submit(act);
|
||||
} catch (Throwable t) {
|
||||
// Couldn't schedule
|
||||
buf.release();
|
||||
@ -252,6 +294,21 @@ public class UserConnection {
|
||||
}
|
||||
}
|
||||
|
||||
private void sendRawPacketToServerClientSide(final ByteBuf packet, boolean currentThread) {
|
||||
Runnable act = () -> getChannel().pipeline()
|
||||
.context(Via.getManager().getInjector().getEncoderName()).writeAndFlush(packet);
|
||||
if (currentThread) {
|
||||
act.run();
|
||||
} else {
|
||||
try {
|
||||
getChannel().eventLoop().submit(act);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
packet.release(); // Couldn't schedule
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a raw packet to the server. It will submit a task to EventLoop.
|
||||
*
|
||||
@ -262,11 +319,24 @@ public class UserConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Monitors serverbound packets.
|
||||
* Monitors incoming packets
|
||||
*
|
||||
* @return false if this packet should be cancelled
|
||||
*/
|
||||
public boolean checkIncomingPacket() {
|
||||
if (clientSide) {
|
||||
return checkClientBound();
|
||||
} else {
|
||||
return checkServerBound();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkClientBound() {
|
||||
incrementSent();
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean checkServerBound() {
|
||||
// Ignore if pending disconnect
|
||||
if (pendingDisconnect) return false;
|
||||
// Increment received + Check PPS
|
||||
@ -274,10 +344,16 @@ public class UserConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Monitors clientbound packets.
|
||||
* Monitors outgoing packets
|
||||
*
|
||||
* @return false if this packet should be cancelled
|
||||
*/
|
||||
public void checkOutgoingPacket() {
|
||||
incrementSent();
|
||||
public boolean checkOutgoingPacket() {
|
||||
if (clientSide) {
|
||||
return checkServerBound();
|
||||
} else {
|
||||
return checkClientBound();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -290,7 +366,8 @@ public class UserConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the clientbound packet contained in an outgoing ByteBuf.
|
||||
* Transforms the outgoing packet contained in ByteBuf. When clientSide is true, this packet is considered
|
||||
* serverbound.
|
||||
*
|
||||
* @param buf ByteBuf with packet id and packet contents
|
||||
* @param cancelSupplier Function called with original CancelException for generating the Exception used when
|
||||
@ -301,11 +378,12 @@ public class UserConnection {
|
||||
*/
|
||||
public void transformOutgoing(ByteBuf buf, Function<Throwable, Exception> cancelSupplier) throws Exception {
|
||||
if (!buf.isReadable()) return;
|
||||
transform(buf, Direction.OUTGOING, cancelSupplier);
|
||||
transform(buf, clientSide ? Direction.INCOMING : Direction.OUTGOING, cancelSupplier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the serverbound packet contained in an incoming ByteBuf.
|
||||
* Transforms the incoming packet contained in ByteBuf. When clientSide is true, this packet is considered
|
||||
* clientbound
|
||||
*
|
||||
* @param buf ByteBuf with packet id and packet contents
|
||||
* @param cancelSupplier Function called with original CancelException for generating the Exception used when
|
||||
@ -316,7 +394,7 @@ public class UserConnection {
|
||||
*/
|
||||
public void transformIncoming(ByteBuf buf, Function<Throwable, Exception> cancelSupplier) throws Exception {
|
||||
if (!buf.isReadable()) return;
|
||||
transform(buf, Direction.INCOMING, cancelSupplier);
|
||||
transform(buf, clientSide ? Direction.OUTGOING : Direction.INCOMING, cancelSupplier);
|
||||
}
|
||||
|
||||
private void transform(ByteBuf buf, Direction direction, Function<Throwable, Exception> cancelSupplier) throws Exception {
|
||||
@ -459,4 +537,12 @@ public class UserConnection {
|
||||
public int hashCode() {
|
||||
return Long.hashCode(id);
|
||||
}
|
||||
|
||||
public boolean isClientSide() {
|
||||
return clientSide;
|
||||
}
|
||||
|
||||
public boolean shouldApplyBlockProtocol() {
|
||||
return !clientSide; // Don't apply protocol blocking on client-side
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,13 @@
|
||||
package us.myles.ViaVersion.api.platform;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.ViaAPI;
|
||||
import us.myles.ViaVersion.api.ViaVersionConfig;
|
||||
import us.myles.ViaVersion.api.command.ViaCommandSender;
|
||||
import us.myles.ViaVersion.api.configuration.ConfigurationProvider;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.UUID;
|
||||
@ -121,6 +124,20 @@ public interface ViaPlatform<T> {
|
||||
*/
|
||||
boolean kickPlayer(UUID uuid, String message);
|
||||
|
||||
/**
|
||||
* Disconnects an UserConnection for a reason
|
||||
*
|
||||
* @param connection The UserConnection
|
||||
* @param message The message to kick them with
|
||||
* @return True if it was successful
|
||||
*/
|
||||
default boolean disconnect(UserConnection connection, String message) {
|
||||
if (connection.isClientSide()) return false;
|
||||
UUID uuid = connection.get(ProtocolInfo.class).getUuid();
|
||||
if (uuid == null) return false;
|
||||
return kickPlayer(uuid, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the plugin is enabled.
|
||||
*
|
||||
|
@ -165,6 +165,7 @@ public class BaseProtocol1_7 extends SimpleProtocol {
|
||||
int protocol = wrapper.user().getProtocolInfo().getProtocolVersion();
|
||||
if (Via.getConfig().getBlockedProtocols().contains(protocol)) {
|
||||
if (!wrapper.user().getChannel().isOpen()) return;
|
||||
if (!wrapper.user().shouldApplyBlockProtocol()) return;
|
||||
|
||||
PacketWrapper disconnectPacket = new PacketWrapper(0x00, null, wrapper.user()); // Disconnect Packet
|
||||
Protocol1_9To1_8.FIX_JSON.write(disconnectPacket, ChatColor.translateAlternateColorCodes('&', Via.getConfig().getBlockedDisconnectMsg()));
|
||||
|
@ -42,7 +42,7 @@ public class SpongeEncodeHandler extends MessageToByteEncoder<Object> implements
|
||||
|
||||
@Override
|
||||
public void transform(ByteBuf bytebuf) throws Exception {
|
||||
info.checkOutgoingPacket();
|
||||
if (!info.checkOutgoingPacket()) throw CancelEncoderException.generate(null);
|
||||
if (!info.shouldTransformPacket()) return;
|
||||
info.transformOutgoing(bytebuf, CancelEncoderException::generate);
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ public class VelocityPlugin implements ViaPlatform<Player> {
|
||||
api = new VelocityViaAPI();
|
||||
conf = new VelocityViaConfig(configDir.toFile());
|
||||
logger = new LoggerWrapper(loggerslf4j);
|
||||
connectionManager = new ViaConnectionManager();
|
||||
connectionManager = new VelocityConnectionManager();
|
||||
Via.init(ViaManager.builder()
|
||||
.platform(this)
|
||||
.commandHandler(commandHandler)
|
||||
|
@ -7,12 +7,14 @@ import us.myles.ViaVersion.api.protocol.ProtocolPipeline;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class VelocityChannelInitializer extends ChannelInitializer {
|
||||
private final ChannelInitializer original;
|
||||
public class VelocityChannelInitializer extends ChannelInitializer<Channel> {
|
||||
private final ChannelInitializer<?> original;
|
||||
private final boolean clientSide;
|
||||
private static Method initChannel;
|
||||
|
||||
public VelocityChannelInitializer(ChannelInitializer original) {
|
||||
public VelocityChannelInitializer(ChannelInitializer<?> original, boolean clientSide) {
|
||||
this.original = original;
|
||||
this.clientSide = clientSide;
|
||||
}
|
||||
|
||||
static {
|
||||
@ -28,7 +30,7 @@ public class VelocityChannelInitializer extends ChannelInitializer {
|
||||
protected void initChannel(Channel channel) throws Exception {
|
||||
initChannel.invoke(original, channel);
|
||||
|
||||
UserConnection user = new UserConnection(channel);
|
||||
UserConnection user = new UserConnection(channel, clientSide);
|
||||
new ProtocolPipeline(user);
|
||||
|
||||
// We need to add a separated handler because Velocity uses pipeline().get(MINECRAFT_DECODER)
|
||||
|
@ -3,16 +3,22 @@ package us.myles.ViaVersion.velocity.handlers;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToByteEncoder;
|
||||
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.CancelDecoderException;
|
||||
import us.myles.ViaVersion.exception.CancelCodecException;
|
||||
import us.myles.ViaVersion.util.PipelineUtil;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
public class VelocityDecodeHandler extends MessageToMessageDecoder<ByteBuf> {
|
||||
private final UserConnection info;
|
||||
boolean handledCompression;
|
||||
|
||||
public VelocityDecodeHandler(UserConnection info) {
|
||||
this.info = info;
|
||||
@ -28,13 +34,55 @@ public class VelocityDecodeHandler extends MessageToMessageDecoder<ByteBuf> {
|
||||
|
||||
ByteBuf transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
|
||||
try {
|
||||
info.transformIncoming(transformedBuf, CancelDecoderException::generate);
|
||||
out.add(transformedBuf.retain());
|
||||
boolean needsCompress = handleCompressionOrder(ctx, draft);
|
||||
|
||||
info.transformIncoming(draft, CancelDecoderException::generate);
|
||||
|
||||
if (needsCompress) {
|
||||
recompress(ctx, draft);
|
||||
}
|
||||
out.add(draft.retain());
|
||||
} finally {
|
||||
transformedBuf.release();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean handleCompressionOrder(ChannelHandlerContext ctx, ByteBuf draft) throws InvocationTargetException {
|
||||
//if (handledCompression) return false;
|
||||
|
||||
int decoderIndex = ctx.pipeline().names().indexOf("compression-decoder");
|
||||
if (decoderIndex == -1) return false;
|
||||
handledCompression = true;
|
||||
if (decoderIndex > ctx.pipeline().names().indexOf("via-decoder")) {
|
||||
System.out.println("bad decoder order");
|
||||
// Need to decompress this packet due to bad order
|
||||
ByteBuf decompressed = (ByteBuf) PipelineUtil.callDecode((MessageToMessageDecoder<?>) ctx.pipeline().get("compression-decoder"), ctx, draft).get(0);
|
||||
try {
|
||||
draft.clear().writeBytes(decompressed);
|
||||
} finally {
|
||||
decompressed.release();
|
||||
}
|
||||
ChannelHandler encoder = ctx.pipeline().get("via-encoder");
|
||||
ChannelHandler decoder = ctx.pipeline().get("via-decoder");
|
||||
ctx.pipeline().remove(encoder);
|
||||
ctx.pipeline().remove(decoder);
|
||||
ctx.pipeline().addAfter("compression-encoder", "via-encoder", encoder);
|
||||
ctx.pipeline().addAfter("compression-decoder", "via-decoder", decoder);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void recompress(ChannelHandlerContext ctx, ByteBuf draft) throws Exception {
|
||||
ByteBuf compressed = ctx.alloc().buffer();
|
||||
try {
|
||||
PipelineUtil.callEncode((MessageToByteEncoder<?>) ctx.pipeline().get("compression-encoder"), ctx, draft, compressed);
|
||||
draft.clear().writeBytes(compressed);
|
||||
} finally {
|
||||
compressed.release();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
if (cause instanceof CancelCodecException) return;
|
||||
|
@ -25,7 +25,7 @@ public class VelocityEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
|
||||
|
||||
@Override
|
||||
protected void encode(final ChannelHandlerContext ctx, ByteBuf bytebuf, List<Object> out) throws Exception {
|
||||
info.checkOutgoingPacket();
|
||||
if (!info.checkOutgoingPacket()) throw CancelEncoderException.generate(null);
|
||||
if (!info.shouldTransformPacket()) {
|
||||
out.add(bytebuf.retain());
|
||||
return;
|
||||
@ -46,10 +46,14 @@ public class VelocityEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
|
||||
}
|
||||
}
|
||||
|
||||
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")) {
|
||||
private boolean handleCompressionOrder(ChannelHandlerContext ctx, ByteBuf draft) throws InvocationTargetException {
|
||||
//if (handledCompression) return false;
|
||||
|
||||
int encoderIndex = ctx.pipeline().names().indexOf("compression-encoder");
|
||||
if (encoderIndex == -1) return false;
|
||||
handledCompression = true;
|
||||
if (encoderIndex > ctx.pipeline().names().indexOf("via-encoder")) {
|
||||
System.out.println("bad decoder order");
|
||||
// Need to decompress this packet due to bad order
|
||||
ByteBuf decompressed = (ByteBuf) PipelineUtil.callDecode((MessageToMessageDecoder<?>) ctx.pipeline().get("compression-decoder"), ctx, buf).get(0);
|
||||
try {
|
||||
@ -63,10 +67,9 @@ public class VelocityEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
|
||||
ctx.pipeline().remove(decoder);
|
||||
ctx.pipeline().addAfter("compression-encoder", "via-encoder", encoder);
|
||||
ctx.pipeline().addAfter("compression-decoder", "via-decoder", decoder);
|
||||
needsCompress = true;
|
||||
handledCompression = true;
|
||||
return true;
|
||||
}
|
||||
return needsCompress;
|
||||
return false;
|
||||
}
|
||||
|
||||
private void recompress(ChannelHandlerContext ctx, ByteBuf buf) throws InvocationTargetException {
|
||||
|
@ -0,0 +1,33 @@
|
||||
package us.myles.ViaVersion.velocity.platform;
|
||||
|
||||
import io.netty.channel.ServerChannel;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.platform.ViaConnectionManager;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class VelocityConnectionManager extends ViaConnectionManager {
|
||||
@Override
|
||||
public void onLoginSuccess(UserConnection connection) {
|
||||
if (connection.isClientSide()) {
|
||||
System.out.println("backend connect!");
|
||||
Objects.requireNonNull(connection, "connection is null!");
|
||||
connections.add(connection);
|
||||
} else {
|
||||
System.out.println("frontend connect!");
|
||||
super.onLoginSuccess(connection);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnect(UserConnection connection) {
|
||||
if (connection.isClientSide()) {
|
||||
System.out.println("backend disconnect!");
|
||||
Objects.requireNonNull(connection, "connection is null!");
|
||||
connections.remove(connection);
|
||||
} else {
|
||||
System.out.println("frontend disconnect!");
|
||||
super.onDisconnect(connection);
|
||||
}
|
||||
}
|
||||
}
|
@ -30,13 +30,25 @@ public class VelocityViaInjector implements ViaInjector {
|
||||
return (ChannelInitializer) ReflectionUtil.invoke(channelInitializerHolder, "get");
|
||||
}
|
||||
|
||||
private ChannelInitializer getBackendInitializer() throws Exception {
|
||||
Object connectionManager = ReflectionUtil.get(VelocityPlugin.PROXY, "cm", Object.class);
|
||||
Object channelInitializerHolder = ReflectionUtil.invoke(connectionManager, "getBackendChannelInitializer");
|
||||
return (ChannelInitializer) ReflectionUtil.invoke(channelInitializerHolder, "get");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inject() throws Exception {
|
||||
Object connectionManager = ReflectionUtil.get(VelocityPlugin.PROXY, "cm", Object.class);
|
||||
Object channelInitializerHolder = ReflectionUtil.invoke(connectionManager, "getServerChannelInitializer");
|
||||
ChannelInitializer originalInitializer = getInitializer();
|
||||
channelInitializerHolder.getClass().getMethod("set", ChannelInitializer.class)
|
||||
.invoke(channelInitializerHolder, new VelocityChannelInitializer(originalInitializer));
|
||||
.invoke(channelInitializerHolder, new VelocityChannelInitializer(originalInitializer, false));
|
||||
|
||||
|
||||
Object backendInitializerHolder = ReflectionUtil.invoke(connectionManager, "getBackendChannelInitializer");
|
||||
ChannelInitializer backendInitializer = getBackendInitializer();
|
||||
backendInitializerHolder.getClass().getMethod("set", ChannelInitializer.class)
|
||||
.invoke(backendInitializerHolder, new VelocityChannelInitializer(backendInitializer, true));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -26,7 +26,7 @@ public class VelocityViaLoader implements ViaPlatformLoader {
|
||||
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getVersion()) {
|
||||
Via.getManager().getProviders().use(MovementTransmitterProvider.class, new VelocityMovementTransmitter());
|
||||
Via.getManager().getProviders().use(BossBarProvider.class, new VelocityBossBarProvider());
|
||||
VelocityPlugin.PROXY.getEventManager().register(plugin, new ElytraPatch());
|
||||
//VelocityPlugin.PROXY.getEventManager().register(plugin, new ElytraPatch());
|
||||
}
|
||||
|
||||
Via.getManager().getProviders().use(VersionProvider.class, new VelocityVersionProvider());
|
||||
@ -34,7 +34,7 @@ public class VelocityViaLoader implements ViaPlatformLoader {
|
||||
// We don't need main hand patch because Join Game packet makes client send hand data again
|
||||
|
||||
VelocityPlugin.PROXY.getEventManager().register(plugin, new UpdateListener());
|
||||
VelocityPlugin.PROXY.getEventManager().register(plugin, new VelocityServerHandler());
|
||||
//VelocityPlugin.PROXY.getEventManager().register(plugin, new VelocityServerHandler());
|
||||
|
||||
int pingInterval = ((VelocityViaConfig) Via.getPlatform().getConf()).getVelocityPingInterval();
|
||||
if (pingInterval > 0) {
|
||||
|
@ -1,20 +1,46 @@
|
||||
package us.myles.ViaVersion.velocity.providers;
|
||||
|
||||
import com.velocitypowered.api.proxy.ServerConnection;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ServerChannel;
|
||||
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.VersionProvider;
|
||||
import us.myles.ViaVersion.velocity.platform.VelocityViaInjector;
|
||||
import us.myles.ViaVersion.velocity.service.ProtocolDetectorService;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class VelocityVersionProvider extends VersionProvider {
|
||||
private static Method getAssociation;
|
||||
|
||||
static {
|
||||
try {
|
||||
getAssociation = Class.forName("com.velocitypowered.proxy.connection.MinecraftConnection").getMethod("getAssociation");
|
||||
} catch (NoSuchMethodException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getServerProtocol(UserConnection user) throws Exception {
|
||||
int playerVersion = user.getProtocolInfo().getProtocolVersion();
|
||||
return user.isClientSide() ? getBackProtocol(user) : getFrontProtocol(user);
|
||||
}
|
||||
|
||||
private int getBackProtocol(UserConnection user) throws Exception {
|
||||
System.out.println("backend protocol!");
|
||||
ChannelHandler mcHandler = user.getChannel().pipeline().get("handler");
|
||||
return ProtocolDetectorService.getProtocolId(
|
||||
((ServerConnection) getAssociation.invoke(mcHandler)).getServerInfo().getName());
|
||||
}
|
||||
|
||||
private int getFrontProtocol(UserConnection user) throws Exception {
|
||||
System.out.println("frontend protocol!");
|
||||
int playerVersion = user.get(ProtocolInfo.class).getProtocolVersion();
|
||||
|
||||
IntStream versions = com.velocitypowered.api.network.ProtocolVersion.SUPPORTED_VERSIONS.stream()
|
||||
.mapToInt(com.velocitypowered.api.network.ProtocolVersion::getProtocol);
|
||||
|
Loading…
Reference in New Issue
Block a user