Compare commits

...
51 Commits
Author SHA1 Message Date
Myles fd0bd53826 Bump version to 0.4.6 2016-03-03 13:07:57 +00:00
Myles e11c8320f0 Merge pull request #83 from StamBoom/master
Fix unmount
2016-03-03 12:56:54 +00:00
Myles 624595e9f6 Merge pull request #84 from HugoDaBosss/patch-4
Fix animals appearing as babies instead of parents
2016-03-03 12:56:37 +00:00
HugoDaBosss cc813545d8 Formatting 2016-03-03 12:22:54 +01:00
HugoDaBosss e1ba6e07c2 Fix animals appearing as babies instead of parent 2016-03-03 12:20:19 +01:00
Mats 1bf49b1f0b Fix unmount 2016-03-03 12:18:23 +01:00
HugoDaBosss 5e34fda7e4 Merge pull request #4 from MylesIsCool/master
Merge from master
2016-03-03 12:17:06 +01:00
Myles aa70ab8b78 Extra line 2016-03-03 10:37:43 +00:00
Myles 186ba22dc8 Update README with chat, and change issue template 2016-03-03 10:37:10 +00:00
Myles b10aa30d9b Change error correction to use super, should restore default functionality to errors. 2016-03-03 10:24:01 +00:00
Myles 615b9f847c Merge pull request #77 from HugoDaBosss/patch-2
Don't send malformed JSON anymore, preventing kicks.
2016-03-03 10:04:54 +00:00
Myles 8f132fed14 Merge pull request #64 from HugoDaBosss/master
Fixed double placing sound and small packet finding optimization. (I suck at github)
2016-03-03 10:04:33 +00:00
HugoDaBosss 854e24f8fc More formatting 2016-03-03 10:47:22 +01:00
HugoDaBosss ff0544f29a Eclipse is changing my bracket markup x.x 2016-03-03 10:46:38 +01:00
HugoDaBosss 72ae12bc77 Don't send malformed JSON anymore, preventing kicks. 2016-03-03 10:44:57 +01:00
HugoDaBosss 29d2334ef0 Fixed bracket markup ;) 2016-03-03 10:09:38 +01:00
HugoDaBosss afb96c4878 Fixed double break sound 2016-03-03 10:06:24 +01:00
HugoDaBosss e4346611c9 Small optimization 2016-03-03 01:40:24 +01:00
BuildTools f15e11272a Merge branch 'master' of https://github.com/HugoDaBosss/ViaVersion 2016-03-03 01:37:25 +01:00
HugoDaBosss 8764d24a16 Merge pull request #3 from MylesIsCool/master
Update from Fork
2016-03-03 01:37:25 +01:00
Myles 86d543d700 Add new contributor, update version to 0.4.5 :) 2016-03-03 00:13:53 +00:00
Myles 99fd01c359 Merge pull request #63 from gigosaurus/patch-1
Fix player entity meta data
2016-03-03 00:12:03 +00:00
gigosaurus 573dcc10b1 Fix player entity meta data
I'm not 100% confident that what I'm doing here is correct, but looking at http://wiki.vg/Pre-release_protocol#Spawn_Player I think I'm doing it right.

fixes #58
2016-03-03 00:06:13 +00:00
Myles 3e30d989a0 Print out stack traces instead of throwing them move. 2016-03-02 23:20:57 +00:00
Myles fc00dd2b38 Merge pull request #56 from gigosaurus/master
Fix PLAY_USE_BED's old ID
2016-03-02 23:08:57 +00:00
gigosaurus 2e9987373d Fix PLAY_USE_BED's old ID 2016-03-02 22:16:58 +00:00
Myles 27c2f4c076 Bump version 2016-03-02 22:01:16 +00:00
Myles e9b61a8e91 Merge pull request #50 from Mystalion/awesome-metadata
Rewrite Metadata system to read the data from the bytebuf instead of
2016-03-02 20:57:33 +00:00
Paulomart 222dee6fda Rewrite Metadata system to read the data from the bytebuf instead of
using the last sent packet.
2016-03-02 21:39:37 +01:00
Myles e8cc25baad Should fix any ClosedConnection output 2016-03-02 20:19:47 +00:00
Myles 785f0664da Fix wither & add more debug info to missing metaindex 2016-03-02 19:42:14 +00:00
Myles ea6c648e4f Fix spam, update to version 0.4.3 2016-03-02 19:12:38 +00:00
Myles 4cdfd72700 Ensure no bytes are left on the bytebufs and ensure it is cancelled properly. Update Version to 0.4.2 2016-03-02 18:41:47 +00:00
Myles ccd6987f11 Bump to 0.4.1, Fixes bungee issues :) (Some chunk stuff, me being an idiot) 2016-03-02 17:03:32 +00:00
Myles 6c96271925 Bump the version, we now support ProtocolLib (hopefully it works properly) 2016-03-02 15:26:32 +00:00
Myles 318db73f3c This is a huge commit, adds ProtocolLib support. (To the best extent I can):
Channels now work as proxies for the minecraft encoder and decoder, this allows better compatibility when transforming packets.
ConnectionInfo now holds an activate state to deactivate.
Now only 2 handlers
We now use info.getChannel().pipeline().writeAndFlush to ensure we catch it ourselves.
Fix EntityMetadata from last commit so it sends empty metadata instead of cancelling whole packet.
Warn if they reload and don't reinject.
2016-03-02 15:21:07 +00:00
Myles b5b0117fa9 Merge pull request #36 from Mystalion/drop-metadata
Drop MetadataPacket where metadata could not be rewritten
2016-03-02 14:45:50 +00:00
Paulomart 79e5555d42 Drop MetadataPacket where metadata could not be rewritten 2016-03-02 13:31:15 +01:00
HugoDaBosss b6c2a46a86 Merge pull request #2 from MylesIsCool/master
Update From Original #2
2016-03-02 11:44:24 +01:00
Myles 114a7b6bd6 Format some lines properly 2016-03-02 10:19:36 +00:00
Myles 8e6d76296d Update contributors 2016-03-02 10:16:27 +00:00
Myles 153a68bf06 Credits to @SanderGielisse, change how netty information is stored so it's not constant and is now attached to ConnectionInfo 2016-03-02 10:12:43 +00:00
Myles 6199e1d8ce Correct last commit to make it work. 2016-03-02 10:09:04 +00:00
Myles 0db43e612e Merge pull request #25 from HugoDaBosss/master
Fix USE_ITEM using correct item. Fix SPAWN_OBJECT velocity.
2016-03-02 10:07:09 +00:00
Myles 06296ead77 Merge pull request #32 from StamBoom/master
Fix TabList header/footer gives (By non-json Strings) MalformedJsonException
2016-03-02 10:05:26 +00:00
Mats dac9bd58e5 Fix TabList header/footer gives (By non-json Strings) MalformedJsonException 2016-03-02 10:27:17 +01:00
Myles 8e0833ca6b Fix nether & end #30 bump to 0.3.7 2016-03-02 00:23:33 +00:00
Myles 88086e00d0 Bump to 0.3.6 2016-03-02 00:09:12 +00:00
Myles 9368347b56 Fix chat which is not got proper JSON 2016-03-01 23:35:16 +00:00
HugoDaBosss db9cd296ee Fix USE_ITEM using correct item. Fix SPAWN_OBJECT velocity. 2016-03-01 19:56:48 +01:00
HugoDaBosss 442d4de74b Merge pull request #1 from MylesIsCool/master
Update From Original
2016-03-01 15:47:15 +01:00
20 changed files with 537 additions and 417 deletions

No files matched your search

+10
View File
@@ -0,0 +1,10 @@
### What version of ViaVersion are you using? Type /ver viaversion
### What version of Spigot are you using? Type /ver
### What plugins are you using? /plugins
### How does this error happen? login? using an item?
### Is there an error in the console? Use pastebin.com. Is there a kick message?
+12 -5
View File
@@ -1,9 +1,9 @@
# ViaVersion 0.3.5
# ViaVersion 0.4.6
**Allows the connection of 1.8 clients to 1.9**
This plugin modifies netty to allow connection of 1.9 clients to 1.8,
**Don't use late bind nor ProtocolLib**
**Don't use late bind*
**As of this point it doesn't have everything, I need to fix:**
@@ -28,10 +28,15 @@ Contributors:
--------
**Myself** (harhar)
**Matsv/StamBoom**
**HugoDaBosss**
**SanderGielisse**
**Paulomart**
**gigosaurus**
**Chat: ** https://gitter.im/MylesIsCool/ViaVersion
We use it to collaborate and solve errors, sign in with github.
License:
--------
@@ -39,4 +44,6 @@ License:
You may modify this work, all rights are still owned by myself excluding any files in the spacebase package as they belong to the respected contributors. Please credit the original author (myself) when forking etc. (or if it helped you understand the new protocol or netty!)
Thanks!
Thanks!
@@ -39,7 +39,7 @@ public class NetUtil {
public static Column readOldChunkData(int x, int z, boolean isFullChunk, int bitmask, byte[] input, boolean checkForSky, boolean hasSkyLight) {
int pos = 0;
int expected = 0;
int expected = isFullChunk ? 256 : 0;
boolean sky = false;
ShortBuffer buf = ByteBuffer.wrap(input).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer();
// 0 = Calculate expected length and determine if the packet has skylight.
@@ -85,7 +85,7 @@ public class NetUtil {
}
if(pass == 3) {
if(chunks[ind].getSkyLight() != null) {
if(sky) {
NibbleArray3d skylight = chunks[ind].getSkyLight();
System.arraycopy(input, pos, skylight.getData(), 0, skylight.getData().length);
pos += skylight.getData().length;
@@ -1,5 +1,6 @@
package us.myles.ViaVersion;
import io.netty.channel.socket.SocketChannel;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import us.myles.ViaVersion.packets.State;
@@ -7,11 +8,17 @@ import us.myles.ViaVersion.packets.State;
import java.util.UUID;
public class ConnectionInfo {
private int protocol = 0;
private State state = State.HANDSHAKE;
private int compression = 0;
private final SocketChannel channel;
private Object lastPacket;
private java.util.UUID UUID;
private State state = State.HANDSHAKE;
private int protocol = 0;
private int compression = 0;
private boolean active = true;
public ConnectionInfo(SocketChannel socketChannel) {
this.channel = socketChannel;
}
public int getProtocol() {
return protocol;
@@ -56,4 +63,16 @@ public class ConnectionInfo {
public Player getPlayer() {
return UUID == null ? null : Bukkit.getPlayer(UUID);
}
public SocketChannel getChannel() {
return channel;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
}
@@ -6,7 +6,6 @@ import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@@ -34,14 +33,17 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
@Override
public void onEnable() {
ViaVersion.setInstance(this);
System.out.println("ViaVersion enabled, injecting. (Allows 1.8 to be accessed via 1.9)");
if(System.getProperty("ViaVersion") != null){
getLogger().severe("ViaVersion is already loaded, we don't support reloads. Please reboot if you wish to update.");
return;
}
getLogger().info("ViaVersion enabled, injecting. (Allows 1.8 to be accessed via 1.9)");
try {
injectPacketHandler();
System.setProperty("ViaVersion", getDescription().getVersion());
} catch (Exception e) {
if(Bukkit.getPluginManager().getPlugin("ProtocolLib") != null){
System.out.println("This plugin is not compatible with protocol lib.");
}
System.out.println("Unable to inject handlers, are you on 1.8? ");
getLogger().severe("Unable to inject handlers, are you on 1.8? ");
e.printStackTrace();
}
Bukkit.getPluginManager().registerEvents(new Listener() {
@@ -59,7 +61,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
List<ChannelFuture> futures = ReflectionUtil.get(connection, "g", List.class);
if (futures.size() == 0) {
throw new Exception("Could not find server to inject (late bind?)");
throw new Exception("Could not find server to inject (Please ensure late-bind in your spigot.yml is false)");
}
for (ChannelFuture future : futures) {
@@ -84,28 +86,6 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
}
}
public static Entity getEntity(final UUID player, final int id) {
try {
return Bukkit.getScheduler().callSyncMethod(getPlugin(ViaVersionPlugin.class), new Callable<Entity>() {
@Override
public Entity call() throws Exception {
Player p = Bukkit.getPlayer(player);
if (p == null) return null;
for (Entity e : p.getWorld().getEntities()) {
if (e.getEntityId() == id) {
return e;
}
}
return null;
}
}).get(10, TimeUnit.SECONDS);
} catch (Exception e) {
System.out.println("Error fetching entity ");
e.printStackTrace();
return null;
}
}
public static ItemStack getHandItem(final ConnectionInfo info) {
try {
return Bukkit.getScheduler().callSyncMethod(getPlugin(ViaVersionPlugin.class), new Callable<ItemStack>() {
@@ -0,0 +1,56 @@
package us.myles.ViaVersion.handlers;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import us.myles.ViaVersion.CancelException;
import us.myles.ViaVersion.ConnectionInfo;
import us.myles.ViaVersion.transformers.IncomingTransformer;
import us.myles.ViaVersion.util.PacketUtil;
import java.util.List;
public class ViaDecodeHandler extends ByteToMessageDecoder {
private final IncomingTransformer incomingTransformer;
private final ByteToMessageDecoder minecraftDecoder;
private final ConnectionInfo info;
public ViaDecodeHandler(ConnectionInfo info, ByteToMessageDecoder minecraftDecoder) {
this.info = info;
this.minecraftDecoder = minecraftDecoder;
this.incomingTransformer = new IncomingTransformer(info);
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf bytebuf, List<Object> list) throws Exception {
// use transformers
if (bytebuf.readableBytes() > 0) {
if (info.isActive()) {
int id = PacketUtil.readVarInt(bytebuf);
// Transform
ByteBuf newPacket = ctx.alloc().buffer();
try {
incomingTransformer.transform(id, bytebuf, newPacket);
bytebuf = newPacket;
} catch (CancelException e) {
bytebuf.readBytes(bytebuf.readableBytes());
throw e;
}
}
// call minecraft decoder
list.addAll(PacketUtil.callDecode(this.minecraftDecoder, ctx, bytebuf));
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
if (!(cause.getCause().getCause() instanceof CancelException)) {
if (!(cause.getCause() instanceof CancelException)) {
if (!(cause instanceof CancelException)) {
super.exceptionCaught(ctx, cause);
}
}
}
}
}
@@ -0,0 +1,83 @@
package us.myles.ViaVersion.handlers;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import us.myles.ViaVersion.CancelException;
import us.myles.ViaVersion.ConnectionInfo;
import us.myles.ViaVersion.transformers.OutgoingTransformer;
import us.myles.ViaVersion.util.PacketUtil;
import us.myles.ViaVersion.util.ReflectionUtil;
import java.lang.reflect.Constructor;
import java.nio.channels.ClosedChannelException;
public class ViaEncodeHandler extends MessageToByteEncoder {
private final ConnectionInfo info;
private final MessageToByteEncoder minecraftEncoder;
private final OutgoingTransformer outgoingTransformer;
public ViaEncodeHandler(ConnectionInfo info, MessageToByteEncoder minecraftEncoder) {
this.info = info;
this.minecraftEncoder = minecraftEncoder;
this.outgoingTransformer = new OutgoingTransformer(info);
}
@Override
protected void encode(ChannelHandlerContext ctx, Object o, ByteBuf bytebuf) throws Exception {
// handle the packet type
if (!(o instanceof ByteBuf)) {
info.setLastPacket(o);
/* This transformer is more for fixing issues which we find hard at packet level :) */
if (o.getClass().getName().endsWith("PacketPlayOutMapChunkBulk") && info.isActive()) {
int[] locX = ReflectionUtil.get(o, "a", int[].class);
int[] locZ = ReflectionUtil.get(o, "b", int[].class);
Object world = ReflectionUtil.get(o, "world", ReflectionUtil.nms("World"));
Class<?> mapChunk = ReflectionUtil.nms("PacketPlayOutMapChunk");
Constructor constructor = mapChunk.getDeclaredConstructor(ReflectionUtil.nms("Chunk"), boolean.class, int.class);
for (int i = 0; i < locX.length; i++) {
int x = locX[i];
int z = locZ[i];
// world invoke function
Object chunk = ReflectionUtil.nms("World").getDeclaredMethod("getChunkAt", int.class, int.class).invoke(world, x, z);
Object packet = constructor.newInstance(chunk, true, 65535);
ctx.pipeline().writeAndFlush(packet);
}
bytebuf.readBytes(bytebuf.readableBytes());
throw new CancelException();
}
// call minecraft encoder
PacketUtil.callEncode(this.minecraftEncoder, ctx, o, bytebuf);
}
if (bytebuf.readableBytes() == 0) {
throw new CancelException();
}
if (info.isActive()) {
int id = PacketUtil.readVarInt(bytebuf);
// Transform
ByteBuf oldPacket = bytebuf.copy();
bytebuf.clear();
try {
outgoingTransformer.transform(id, oldPacket, bytebuf);
} catch (CancelException e) {
bytebuf.readBytes(bytebuf.readableBytes());
throw e;
} finally {
oldPacket.release();
}
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
if (!(cause.getCause().getCause() instanceof CancelException)) {
if (!(cause.getCause() instanceof CancelException)) {
if (!(cause instanceof CancelException)) {
super.exceptionCaught(ctx, cause);
}
}
}
}
}
@@ -1,53 +0,0 @@
package us.myles.ViaVersion.handlers;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import us.myles.ViaVersion.CancelException;
import us.myles.ViaVersion.ConnectionInfo;
import us.myles.ViaVersion.util.PacketUtil;
import us.myles.ViaVersion.transformers.IncomingTransformer;
@ChannelHandler.Sharable
public class ViaInboundHandler extends ChannelInboundHandlerAdapter {
private final IncomingTransformer incomingTransformer;
private final ViaVersionInitializer init;
public ViaInboundHandler(Channel c, ConnectionInfo info, ViaVersionInitializer init) {
this.init = init;
this.incomingTransformer = new IncomingTransformer(c, info, init);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
boolean compression = ctx.pipeline().get("compress") != null;
if (msg instanceof ByteBuf) {
ByteBuf bytebuf = (ByteBuf) msg;
if (compression) {
// decompress :)
bytebuf = PacketUtil.decompress(ctx, bytebuf);
}
int id = PacketUtil.readVarInt(bytebuf);
// Transform
ByteBuf newPacket = ctx.alloc().buffer();
try {
incomingTransformer.transform(id, bytebuf, newPacket);
} catch (CancelException e) {
return;
} finally {
bytebuf.release();
}
if (compression) {
// recompress :)
newPacket = PacketUtil.compress(ctx, newPacket);
}
msg = newPacket;
}
super.channelRead(ctx, msg);
}
}
@@ -1,53 +0,0 @@
package us.myles.ViaVersion.handlers;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import us.myles.ViaVersion.CancelException;
import us.myles.ViaVersion.ConnectionInfo;
import us.myles.ViaVersion.util.PacketUtil;
import us.myles.ViaVersion.transformers.OutgoingTransformer;
@ChannelHandler.Sharable
public class ViaOutboundHandler extends ChannelOutboundHandlerAdapter {
private final OutgoingTransformer outgoingTransformer;
private final ViaVersionInitializer init;
public ViaOutboundHandler(Channel c, ConnectionInfo info, ViaVersionInitializer init) {
this.init = init;
this.outgoingTransformer = new OutgoingTransformer(c, info, init);
}
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise channelPromise) throws Exception {
try {
if (channelPromise.isDone()) return; // don't break any <3s
boolean compression = ctx.pipeline().get("compress") != null;
if (msg instanceof ByteBuf) {
ByteBuf bytebuf = (ByteBuf) msg;
if (compression) {
// decompress :)
bytebuf = PacketUtil.decompress(ctx, bytebuf);
}
int id = PacketUtil.readVarInt(bytebuf);
// Transform
ByteBuf newPacket = ctx.alloc().buffer();
try {
outgoingTransformer.transform(id, bytebuf, newPacket);
} catch (CancelException e) {
return;
} finally {
bytebuf.release();
}
if (compression) {
// recompress :)
newPacket = PacketUtil.compress(ctx, newPacket);
}
msg = newPacket;
}
super.write(ctx, msg, channelPromise);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -1,43 +0,0 @@
package us.myles.ViaVersion.handlers;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import us.myles.ViaVersion.ConnectionInfo;
import us.myles.ViaVersion.util.ReflectionUtil;
import java.lang.reflect.Constructor;
@ChannelHandler.Sharable
public class ViaOutboundPacketHandler extends ChannelOutboundHandlerAdapter {
private final ConnectionInfo info;
public ViaOutboundPacketHandler(Channel c, ConnectionInfo info) {
this.info = info;
}
@Override
public void write(ChannelHandlerContext channelHandlerContext, Object o, ChannelPromise channelPromise) throws Exception {
if (!(o instanceof ByteBuf)) {
info.setLastPacket(o);
/* This transformer is more for fixing issues which we find hard at byte level :) */
if (o.getClass().getName().endsWith("PacketPlayOutMapChunkBulk")) {
int[] locX = ReflectionUtil.get(o, "a", int[].class);
int[] locZ = ReflectionUtil.get(o, "b", int[].class);
Object world = ReflectionUtil.get(o, "world", ReflectionUtil.nms("World"));
Class<?> mapChunk = ReflectionUtil.nms("PacketPlayOutMapChunk");
Constructor constructor = mapChunk.getDeclaredConstructor(ReflectionUtil.nms("Chunk"), boolean.class, int.class);
for (int i = 0; i < locX.length; i++) {
int x = locX[i];
int z = locZ[i];
// world invoke function
Object chunk = ReflectionUtil.nms("World").getDeclaredMethod("getChunkAt", int.class, int.class).invoke(world, x, z);
Object packet = constructor.newInstance(chunk, true, 65535);
channelHandlerContext.write(packet);
}
return;
}
}
super.write(channelHandlerContext, o, channelPromise);
}
}
@@ -3,6 +3,8 @@ package us.myles.ViaVersion.handlers;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.MessageToByteEncoder;
import us.myles.ViaVersion.ConnectionInfo;
import java.lang.reflect.Method;
@@ -10,11 +12,6 @@ import java.lang.reflect.Method;
public class ViaVersionInitializer extends ChannelInitializer<SocketChannel> {
private final ChannelInitializer<SocketChannel> oldInit;
private Method method;
private ConnectionInfo info;
private ViaInboundHandler inbound;
private ViaOutboundHandler outbound;
private SocketChannel socketChannel;
private ViaOutboundPacketHandler outbound2;
public ViaVersionInitializer(ChannelInitializer<SocketChannel> oldInit) {
this.oldInit = oldInit;
@@ -28,24 +25,14 @@ public class ViaVersionInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
info = new ConnectionInfo();
ConnectionInfo info = new ConnectionInfo(socketChannel);
// Add originals
this.method.invoke(this.oldInit, socketChannel);
// Add our transformers
this.socketChannel = socketChannel;
this.inbound = new ViaInboundHandler(socketChannel, info, this);
this.outbound = new ViaOutboundHandler(socketChannel, info, this);
this.outbound2 = new ViaOutboundPacketHandler(socketChannel, info);
socketChannel.pipeline().addBefore("decoder", "via_incoming", this.inbound);
socketChannel.pipeline().addBefore("packet_handler", "via_outgoing2", this.outbound2);
socketChannel.pipeline().addBefore("encoder", "via_outgoing", this.outbound);
ViaEncodeHandler encoder = new ViaEncodeHandler(info, (MessageToByteEncoder) socketChannel.pipeline().get("encoder"));
ViaDecodeHandler decoder = new ViaDecodeHandler(info, (ByteToMessageDecoder) socketChannel.pipeline().get("decoder"));
socketChannel.pipeline().replace("encoder", "encoder", encoder);
socketChannel.pipeline().replace("decoder", "decoder", decoder);
}
public void remove(){
socketChannel.pipeline().remove("via_incoming");
socketChannel.pipeline().remove("via_outgoing");
socketChannel.pipeline().remove("via_outgoing2");
}
}
@@ -88,6 +88,8 @@ public enum MetaIndex {
WITHER_TARGET2(Wither.class, 18, Type.Int, 12, NewType.VarInt),
WITHER_TARGET3(Wither.class, 19, Type.Int, 13, NewType.VarInt),
WITHER_INVULN_TIME(Wither.class, 20, Type.Int, 14, NewType.VarInt),
// wither skull
WITHERSKULL_INVULN(WitherSkull.class, 10, Type.Byte, 5, NewType.Boolean),
// guardian
GUARDIAN_INFO(Guardian.class, 16, Type.Int, 11, NewType.Byte),
GUARDIAN_TARGET(Guardian.class, 17, Type.Int, 12, NewType.VarInt),
@@ -0,0 +1,186 @@
package us.myles.ViaVersion.metadata;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import org.bukkit.entity.EntityType;
import org.bukkit.util.EulerAngle;
import org.bukkit.util.Vector;
import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion.util.PacketUtil;
public class MetadataRewriter {
public static void writeMetadata1_9(EntityType type, List<Entry> list, ByteBuf output) {
short id = -1;
int data = -1;
Iterator<Entry> iterator = list.iterator();
while (iterator.hasNext()) {
Entry entry = iterator.next(); //
MetaIndex metaIndex = entry.index;
try {
if (metaIndex.getNewType() != NewType.Discontinued) {
if (metaIndex.getNewType() != NewType.BlockID || id != -1 && data == -1 || id == -1 && data != -1) { // block ID is only written if we have both parts
output.writeByte(metaIndex.getNewIndex());
output.writeByte(metaIndex.getNewType().getTypeID());
}
Object value = entry.value;
switch (metaIndex.getNewType()) {
case Byte:
// convert from int, byte
if (metaIndex.getOldType() == Type.Byte) {
output.writeByte(((Byte) value).byteValue());
}
if (metaIndex.getOldType() == Type.Int) {
output.writeByte(((Integer) value).byteValue());
}
break;
case OptUUID:
String owner = (String) value;
UUID toWrite = null;
if (owner.length() != 0) {
try {
toWrite = UUID.fromString(owner);
} catch (Exception ignored) {
}
}
output.writeBoolean(toWrite != null);
if (toWrite != null)
PacketUtil.writeUUID((UUID) toWrite, output);
break;
case BlockID:
// if we have both sources :))
if (metaIndex.getOldType() == Type.Byte) {
data = ((Byte) value).byteValue();
}
if (metaIndex.getOldType() == Type.Short) {
id = ((Short) value).shortValue();
}
if (id != -1 && data != -1) {
int combined = id << 4 | data;
data = -1;
id = -1;
PacketUtil.writeVarInt(combined, output);
}
break;
case VarInt:
// convert from int, short, byte
if (metaIndex.getOldType() == Type.Byte) {
PacketUtil.writeVarInt(((Byte) value).intValue(), output);
}
if (metaIndex.getOldType() == Type.Short) {
PacketUtil.writeVarInt(((Short) value).intValue(), output);
}
if (metaIndex.getOldType() == Type.Int) {
PacketUtil.writeVarInt(((Integer) value).intValue(), output);
}
break;
case Float:
output.writeFloat(((Float) value).floatValue());
break;
case String:
PacketUtil.writeString((String) value, output);
break;
case Boolean:
if(metaIndex == MetaIndex.AGEABLE_AGE)
output.writeBoolean(((Byte) value).byteValue() < 0);
else
output.writeBoolean(((Byte) value).byteValue() != 0);
break;
case Slot:
PacketUtil.writeItem(value, output);
break;
case Position:
Vector vector = (Vector) value;
output.writeInt((int) vector.getX());
output.writeInt((int) vector.getY());
output.writeInt((int) vector.getZ());
break;
case Vector3F:
EulerAngle angle = (EulerAngle) value;
output.writeFloat((float) angle.getX());
output.writeFloat((float) angle.getY());
output.writeFloat((float) angle.getZ());
break;
default:
System.out.println("[Out] Unhandled MetaDataType: " + metaIndex.getNewType());
break;
}
}
} catch (Exception e) {
if (type != null) {
System.out.println("An error occurred with entity meta data for " + type);
if (metaIndex != null) {
System.out.println("Old ID: " + metaIndex.getIndex() + " New ID: " + metaIndex.getNewIndex());
System.out.println("Old Type: " + metaIndex.getOldType() + " New Type: " + metaIndex.getNewType());
}
}
e.printStackTrace();
}
}
output.writeByte(255);
}
public static List<Entry> readMetadata1_8(EntityType entityType, ByteBuf buf) {
List<Entry> entries = new ArrayList<>();
byte item;
while ((item = buf.readByte()) != 127) {
Type type = Type.byId((item & 0xE0) >> 5);
int id = item & 0x1F;
MetaIndex index = MetaIndex.getIndex(entityType, id);
switch (type) {
case Byte:
entries.add(new Entry(index, buf.readByte()));
break;
case Short:
entries.add(new Entry(index, buf.readShort()));
break;
case Int:
entries.add(new Entry(index, buf.readInt()));
break;
case Float:
entries.add(new Entry(index, buf.readFloat()));
break;
case String:
entries.add(new Entry(index, PacketUtil.readString(buf)));
break;
case Slot:
entries.add(new Entry(index, PacketUtil.readItem(buf)));
break;
case Position: {
int x = buf.readInt();
int y = buf.readInt();
int z = buf.readInt();
entries.add(new Entry(index, new Vector(x, y, z)));
break;
}
case Rotation: {
float x = buf.readFloat();
float y = buf.readFloat();
float z = buf.readFloat();
entries.add(new Entry(index, new EulerAngle(x, y, z)));
break;
}
default:
System.out.println("[Out] Unhandled MetaDataType: " + type);
break;
}
}
return entries;
}
public static class Entry {
private MetaIndex index;
private Object value;
private Entry(MetaIndex index, Object value) {
this.index = index;
this.value = value;
}
}
}
@@ -18,4 +18,8 @@ public enum Type {
public int getTypeID() {
return typeID;
}
public static Type byId(int id) {
return values()[id];
}
}
@@ -20,7 +20,7 @@ public enum PacketType {
/* Play serverbound */
PLAY_TP_CONFIRM(State.PLAY, Direction.INCOMING, -1, 0x00),
PLAY_TAB_COMPLETE_REQUEST(State.PLAY, Direction.INCOMING, 0x14, 0x01),
PLAY_CLICHAT_MESSAGE_CLIENT(State.PLAY, Direction.INCOMING, 0x01, 0x02),
PLAY_CHAT_MESSAGE_CLIENT(State.PLAY, Direction.INCOMING, 0x01, 0x02),
PLAY_CLIENT_STATUS(State.PLAY, Direction.INCOMING, 0x16, 0x03),
PLAY_CLIENT_SETTINGS(State.PLAY, Direction.INCOMING, 0x15, 0x04),
PLAY_CONFIRM_TRANS(State.PLAY, Direction.INCOMING, 0x0F, 0x05),
@@ -96,7 +96,7 @@ public enum PacketType {
PLAY_COMBAT_EVENT(State.PLAY, Direction.OUTGOING, 0x42, 0x2C),
PLAY_PLAYER_LIST_ITEM(State.PLAY, Direction.OUTGOING, 0x38, 0x2D),
PLAY_PLAYER_POSITION_LOOK(State.PLAY, Direction.OUTGOING, 0x08, 0x2E),
PLAY_USE_BED(State.PLAY, Direction.OUTGOING, 0x2F, 0x2F),
PLAY_USE_BED(State.PLAY, Direction.OUTGOING, 0x0A, 0x2F),
PLAY_DESTROY_ENTITIES(State.PLAY, Direction.OUTGOING, 0x13, 0x30),
PLAY_REMOVE_ENTITY_EFFECT(State.PLAY, Direction.OUTGOING, 0x1E, 0x31),
PLAY_RESOURCE_PACK_SEND(State.PLAY, Direction.OUTGOING, 0x48, 0x32),
@@ -170,7 +170,7 @@ public enum PacketType {
if(id == -1)
return null;
for (PacketType pt : values()) {
if (pt.getNewPacketID() == id && id != -1
if (pt.getNewPacketID() == id
&& pt.getState() == state
&& pt.getDirection() == direction)
return pt;
@@ -182,7 +182,7 @@ public enum PacketType {
if(id == -1)
return null;
for (PacketType pt : values()) {
if (pt.getPacketID() == id && id != -1
if (pt.getPacketID() == id
&& pt.getState() == state
&& pt.getDirection() == direction)
return pt;
@@ -252,11 +252,13 @@ public enum SoundEffect {
private String name;
private String newname;
private SoundCategory cat;
private boolean breaksound;
SoundEffect(String name, String newname, SoundCategory cat) {
this.cat = cat;
this.newname = newname;
this.name = name;
this.breaksound = name.startsWith("dig.");
}
public static SoundEffect getByName(String name) {
@@ -279,5 +281,9 @@ public enum SoundEffect {
public SoundCategory getCategory() {
return cat;
}
public boolean isBreakPlaceSound() {
return breaksound;
}
}
@@ -1,10 +1,10 @@
package us.myles.ViaVersion.transformers;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import org.bukkit.inventory.ItemStack;
import us.myles.ViaVersion.*;
import us.myles.ViaVersion.handlers.ViaVersionInitializer;
import us.myles.ViaVersion.CancelException;
import us.myles.ViaVersion.ConnectionInfo;
import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.packets.PacketType;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.util.PacketUtil;
@@ -14,14 +14,10 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class IncomingTransformer {
private final Channel channel;
private final ConnectionInfo info;
private final ViaVersionInitializer init;
public IncomingTransformer(Channel channel, ConnectionInfo info, ViaVersionInitializer init) {
this.channel = channel;
public IncomingTransformer(ConnectionInfo info) {
this.info = info;
this.init = init;
}
public void transform(int packetID, ByteBuf input, ByteBuf output) throws CancelException {
@@ -48,8 +44,8 @@ public class IncomingTransformer {
PacketUtil.writeVarInt(protVer <= 102 ? protVer : 47, output); // pretend to be older
if (protVer <= 102) {
// Not 1.9 remove pipes
this.init.remove();
// not 1.9, remove pipes
info.setActive(false);
}
String serverAddress = PacketUtil.readString(input);
PacketUtil.writeString(serverAddress, output);
@@ -91,11 +87,8 @@ public class IncomingTransformer {
throw new CancelException();
}
output.writeByte(status);
// read position
Long pos = input.readLong();
output.writeLong(pos);
short face = input.readUnsignedByte();
output.writeByte(face);
// write remaining bytes
output.writeBytes(input);
return;
}
if (packet == PacketType.PLAY_CLICK_WINDOW) {
@@ -110,7 +103,7 @@ public class IncomingTransformer {
try {
Class<?> setSlot = ReflectionUtil.nms("PacketPlayOutSetSlot");
Object setSlotPacket = setSlot.getConstructors()[1].newInstance(windowID, slot, null);
channel.writeAndFlush(setSlotPacket); // slot is empty
info.getChannel().pipeline().writeAndFlush(setSlotPacket); // slot is empty
slot = -999; // we're evil, they'll throw item on the ground
} catch (ClassNotFoundException e) {
e.printStackTrace();
@@ -210,9 +203,23 @@ public class IncomingTransformer {
PacketUtil.writeVarInt(PacketType.PLAY_PLAYER_BLOCK_PLACEMENT.getPacketID(), output);
// Simulate using item :)
output.writeLong(-1L);
output.writeByte(-1);
output.writeByte(255);
// write item in hand
output.writeShort(-1);
ItemStack inHand = ViaVersionPlugin.getHandItem(info);
Object item = null;
try {
Method m = ReflectionUtil.obc("inventory.CraftItemStack").getDeclaredMethod("asNMSCopy", ItemStack.class);
item = m.invoke(null, inHand);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
PacketUtil.writeItem(item, output);
output.writeByte(-1);
output.writeByte(-1);
@@ -2,20 +2,19 @@ package us.myles.ViaVersion.transformers;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.sun.xml.internal.bind.v2.runtime.reflect.Lister;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import org.bukkit.entity.EntityType;
import org.json.simple.parser.JSONParser;
import org.spacehq.mc.protocol.data.game.chunk.Column;
import org.spacehq.mc.protocol.util.NetUtil;
import us.myles.ViaVersion.CancelException;
import us.myles.ViaVersion.ConnectionInfo;
import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.handlers.ViaVersionInitializer;
import us.myles.ViaVersion.metadata.MetaIndex;
import us.myles.ViaVersion.metadata.NewType;
import us.myles.ViaVersion.metadata.Type;
import us.myles.ViaVersion.metadata.MetadataRewriter;
import us.myles.ViaVersion.packets.PacketType;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.sounds.SoundEffect;
@@ -24,25 +23,21 @@ import us.myles.ViaVersion.util.PacketUtil;
import us.myles.ViaVersion.util.ReflectionUtil;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import static us.myles.ViaVersion.util.PacketUtil.*;
public class OutgoingTransformer {
private static Gson gson = new Gson();
private final Channel channel;
private final ConnectionInfo info;
private final ViaVersionInitializer init;
private final ViaVersionPlugin plugin = (ViaVersionPlugin) ViaVersion.getInstance();
private boolean cancel = false;
private Map<Integer, UUID> uuidMap = new HashMap<Integer, UUID>();
private Map<Integer, EntityType> clientEntityTypes = new HashMap<Integer, EntityType>();
private Map<Integer, Integer> vehicleMap = new HashMap<>();
public OutgoingTransformer(Channel channel, ConnectionInfo info, ViaVersionInitializer init) {
this.channel = channel;
public OutgoingTransformer(ConnectionInfo info) {
this.info = info;
this.init = init;
}
public void transform(int packetID, ByteBuf input, ByteBuf output) throws CancelException {
@@ -69,6 +64,11 @@ public class OutgoingTransformer {
int catid = 0;
String newname = name;
if (effect != null) {
if(effect.isBreakPlaceSound()) {
input.readBytes(input.readableBytes());
output.clear();
return;
}
catid = effect.getCategory().getId();
newname = effect.getNewName();
}
@@ -83,8 +83,17 @@ public class OutgoingTransformer {
if (!lead) {
output.clear();
writeVarInt(PacketType.PLAY_SET_PASSENGERS.getNewPacketID(), output);
writeVarInt(vehicle, output);
writeVarIntArray(Collections.singletonList(passenger), output);
if (vehicle == -1) {
if (!vehicleMap.containsKey(passenger))
throw new CancelException();
vehicle = vehicleMap.remove(passenger);
writeVarInt(vehicle,output);
writeVarIntArray(Collections.<Integer>emptyList(), output);
} else{
writeVarInt(vehicle, output);
writeVarIntArray(Collections.singletonList(passenger), output);
vehicleMap.put(passenger,vehicle);
}
return;
}
output.writeInt(passenger);
@@ -106,6 +115,13 @@ public class OutgoingTransformer {
output.writeBytes(input);
return;
}
if (packet == PacketType.PLAY_PLAYER_LIST_HEADER_FOOTER) {
String header = readString(input);
String footer = readString(input);
writeString(fixJson(header), output);
writeString(fixJson(footer), output);
return;
}
if (packet == PacketType.PLAY_ENTITY_TELEPORT) {
// Port this so that it relative moves :P
int id = PacketUtil.readVarInt(input);
@@ -211,17 +227,10 @@ public class OutgoingTransformer {
int id = PacketUtil.readVarInt(input);
PacketUtil.writeVarInt(id, output);
try {
List dw = ReflectionUtil.get(info.getLastPacket(), "b", List.class);
// get entity via entityID, not preferred but we need it.
transformMetadata(id, dw, output);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
transformMetadata(id, input, output);
return;
}
if (packet == PacketType.PLAY_SPAWN_GLOBAL_ENTITY) {
int id = PacketUtil.readVarInt(input);
PacketUtil.writeVarInt(id, output);
@@ -273,11 +282,14 @@ public class OutgoingTransformer {
int data = input.readInt();
output.writeInt(data);
short vX = input.readableBytes() >= 16 ? input.readShort() : 0;
short vX = 0, vY = 0, vZ = 0;
if (data > 0) {
vX = input.readShort();
vY = input.readShort();
vZ = input.readShort();
}
output.writeShort(vX);
short vY = input.readableBytes() >= 16 ? input.readShort() : 0;
output.writeShort(vY);
short vZ = input.readableBytes() >= 16 ? input.readShort() : 0;
output.writeShort(vZ);
return;
@@ -286,7 +298,6 @@ public class OutgoingTransformer {
int id = PacketUtil.readVarInt(input);
clientEntityTypes.put(id, EntityType.EXPERIENCE_ORB);
PacketUtil.writeVarInt(id, output);
double x = input.readInt();
output.writeDouble(x / 32D);
double y = input.readInt();
@@ -305,7 +316,6 @@ public class OutgoingTransformer {
PacketUtil.writeVarInt(id, output);
PacketUtil.writeUUID(getUUID(id), output);
String title = PacketUtil.readString(input);
PacketUtil.writeString(title, output);
@@ -356,16 +366,8 @@ public class OutgoingTransformer {
output.writeShort(vY);
short vZ = input.readShort();
output.writeShort(vZ);
try {
Object dataWatcher = ReflectionUtil.get(info.getLastPacket(), "l", ReflectionUtil.nms("DataWatcher"));
transformMetadata(id, dataWatcher, output);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
transformMetadata(id, input, output);
return;
}
if (packet == PacketType.PLAY_UPDATE_SIGN) {
@@ -376,6 +378,14 @@ public class OutgoingTransformer {
PacketUtil.writeString(fixJson(line), output);
}
}
if (packet == PacketType.PLAY_CHAT_MESSAGE) {
String chat = PacketUtil.readString(input);
PacketUtil.writeString(fixJson(chat), output);
byte pos = input.readByte();
output.writeByte(pos);
return;
}
if (packet == PacketType.PLAY_JOIN_GAME) {
int id = input.readInt();
clientEntityTypes.put(id, EntityType.PLAYER);
@@ -401,16 +411,11 @@ public class OutgoingTransformer {
output.writeByte(pitch);
byte yaw = input.readByte();
output.writeByte(yaw);
try {
Object dataWatcher = ReflectionUtil.get(info.getLastPacket(), "i", ReflectionUtil.nms("DataWatcher"));
transformMetadata(id, dataWatcher, output);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// next field is Current Item, this was removed in 1.9 so we'll ignore it
input.readShort();
transformMetadata(id, input, output);
return;
}
@@ -501,139 +506,25 @@ public class OutgoingTransformer {
if (line.startsWith("\""))
line = "{\"text\":" + line + "}";
}
try {
new JSONParser().parse(line);
}
catch (org.json.simple.parser.ParseException e) {
System.out.println("Invalid JSON String: \"" + line + "\" Please report this issue to the ViaVersion Github!");
return "{\"text\":\"\"}";
}
return line;
}
private void transformMetadata(int entityID, Object dw, ByteBuf output) {
// get entity
try {
transformMetadata(entityID, (List) ReflectionUtil.invoke(dw, "b"), output);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
private void transformMetadata(int entityID, List dw, ByteBuf output) {
private void transformMetadata(int entityID, ByteBuf input, ByteBuf output) throws CancelException {
EntityType type = clientEntityTypes.get(entityID);
if (type == null) {
System.out.println("Unable to get entity for ID: " + entityID);
output.writeByte(255);
return;
}
if (dw != null) {
short id = -1;
int data = -1;
Iterator iterator = dw.iterator();
while (iterator.hasNext()) {
Object watchableObj = iterator.next(); //
MetaIndex metaIndex = null;
try {
metaIndex = MetaIndex.getIndex(type, (int) ReflectionUtil.invoke(watchableObj, "a"));
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
try {
if (metaIndex.getNewType() != NewType.Discontinued) {
if (metaIndex.getNewType() != NewType.BlockID || id != -1 && data == -1 || id == -1 && data != -1) { // block ID is only written if we have both parts
output.writeByte(metaIndex.getNewIndex());
output.writeByte(metaIndex.getNewType().getTypeID());
}
Object value = ReflectionUtil.invoke(watchableObj, "b");
switch (metaIndex.getNewType()) {
case Byte:
// convert from int, byte
if (metaIndex.getOldType() == Type.Byte) {
output.writeByte(((Byte) value).byteValue());
}
if (metaIndex.getOldType() == Type.Int) {
output.writeByte(((Integer) value).byteValue());
}
break;
case OptUUID:
String owner = (String) value;
UUID toWrite = null;
if (owner.length() != 0) {
try {
toWrite = UUID.fromString(owner);
} catch (Exception ignored) {
}
}
output.writeBoolean(toWrite != null);
if (toWrite != null)
PacketUtil.writeUUID((UUID) toWrite, output);
break;
case BlockID:
// if we have both sources :))
if (metaIndex.getOldType() == Type.Byte) {
data = ((Byte) value).byteValue();
}
if (metaIndex.getOldType() == Type.Short) {
id = ((Short) value).shortValue();
}
if (id != -1 && data != -1) {
int combined = id << 4 | data;
data = -1;
id = -1;
PacketUtil.writeVarInt(combined, output);
}
break;
case VarInt:
// convert from int, short, byte
if (metaIndex.getOldType() == Type.Byte) {
PacketUtil.writeVarInt(((Byte) value).intValue(), output);
}
if (metaIndex.getOldType() == Type.Short) {
PacketUtil.writeVarInt(((Short) value).intValue(), output);
}
if (metaIndex.getOldType() == Type.Int) {
PacketUtil.writeVarInt(((Integer) value).intValue(), output);
}
break;
case Float:
output.writeFloat(((Float) value).floatValue());
break;
case String:
PacketUtil.writeString((String) value, output);
break;
case Boolean:
output.writeBoolean(((Byte) value).byteValue() != 0);
break;
case Slot:
PacketUtil.writeItem(value, output);
break;
case Position:
output.writeInt((int) ReflectionUtil.invoke(value, "getX"));
output.writeInt((int) ReflectionUtil.invoke(value, "getY"));
output.writeInt((int) ReflectionUtil.invoke(value, "getZ"));
break;
case Vector3F:
output.writeFloat((float) ReflectionUtil.invoke(value, "getX"));
output.writeFloat((float) ReflectionUtil.invoke(value, "getY"));
output.writeFloat((float) ReflectionUtil.invoke(value, "getZ"));
}
}
} catch (Exception e) {
if (type != null) {
System.out.println("An error occurred with entity meta data for " + type);
System.out.println("Old ID: " + metaIndex.getIndex() + " New ID: " + metaIndex.getNewIndex());
System.out.println("Old Type: " + metaIndex.getOldType() + " New Type: " + metaIndex.getNewType());
}
e.printStackTrace();
}
}
}
output.writeByte(255);
List<MetadataRewriter.Entry> list = MetadataRewriter.readMetadata1_8(type, input);
MetadataRewriter.writeMetadata1_9(type, list, output);
}
@@ -42,29 +42,38 @@ public class PacketUtil {
}
}
public static ByteBuf decompress(ChannelHandlerContext ctx, ByteBuf msg) {
ByteToMessageDecoder x = (ByteToMessageDecoder) ctx.pipeline().get("decompress");
public static List<Object> callDecode(ByteToMessageDecoder decoder, ChannelHandlerContext ctx, Object input) {
List<Object> output = new ArrayList<Object>();
try {
PacketUtil.DECODE_METHOD.invoke(x, ctx, msg, output);
PacketUtil.DECODE_METHOD.invoke(decoder, ctx, input, output);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return output;
}
public static void callEncode(MessageToByteEncoder encoder, ChannelHandlerContext ctx, Object msg, ByteBuf output) {
try {
PacketUtil.ENCODE_METHOD.invoke(encoder, ctx, msg, output);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
public static ByteBuf decompress(ChannelHandlerContext ctx, ByteBuf msg) {
ByteToMessageDecoder x = (ByteToMessageDecoder) ctx.pipeline().get("decompress");
List<Object> output = callDecode(x, ctx, msg);
return output.size() == 0 ? null : (ByteBuf) output.get(0);
}
public static ByteBuf compress(ChannelHandlerContext ctx, ByteBuf msg) {
MessageToByteEncoder x = (MessageToByteEncoder) ctx.pipeline().get("compress");
ByteBuf output = ctx.alloc().buffer();
try {
PacketUtil.ENCODE_METHOD.invoke(x, ctx, msg, output);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
callEncode(x, ctx, msg, output);
return output;
}
@@ -185,9 +194,9 @@ public class PacketUtil {
}
public static void writeVarIntArray(List<Integer> integers, ByteBuf output) {
writeVarInt(integers.size(),output);
for (Integer i : integers){
writeVarInt(i,output);
writeVarInt(integers.size(), output);
for (Integer i : integers) {
writeVarInt(i, output);
}
}
@@ -364,6 +373,26 @@ public class PacketUtil {
}
}
public static Object readItem(ByteBuf output) {
try {
Class<?> serializer = ReflectionUtil.nms("PacketDataSerializer");
Object init = serializer.getDeclaredConstructor(ByteBuf.class).newInstance(output);
Method toCall = init.getClass().getDeclaredMethod("i");
return toCall.invoke(init);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
public static long[] readBlockPosition(ByteBuf buf) {
long val = buf.readLong();
long x = (val >> 38); // signed
+3 -1
View File
@@ -1,4 +1,6 @@
name: ViaVersion
main: us.myles.ViaVersion.ViaVersionPlugin
author: _MylesC
version: 0.3.5
version: 0.4.6
load: startup
loadbefore: [ProtocolLib, ProxyPipe]