Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a743895c3f | ||
|
|
f65666b7a6 | ||
|
|
3a217503fc | ||
|
|
c71b75e13b | ||
|
|
0c890c3a30 | ||
|
|
f38bb0ca22 | ||
|
|
2144fa1837 | ||
|
|
fc4a617da7 | ||
|
|
126ee6e03f | ||
|
|
498867032f | ||
|
|
aef8eca790 | ||
|
|
d8bbb51721 | ||
|
|
6e4fd5a63b | ||
|
|
e7bd6245c2 | ||
|
|
6242cb0b47 | ||
|
|
bf5072e1cf | ||
|
|
c24b673550 | ||
|
|
dfc1e1cf51 | ||
|
|
c600ab6dd1 | ||
|
|
29754c0787 | ||
|
|
9144980474 | ||
|
|
6a449f8db1 | ||
|
|
3780210f76 | ||
|
|
67bad0dec8 | ||
|
|
79291fd7d9 | ||
|
|
ee9d8d6365 | ||
|
|
cc354db464 | ||
|
|
2b29d27b0d | ||
|
|
75db62ee6f | ||
|
|
7cd7b5ba24 | ||
|
|
a3bfcefdca |
No files matched your search
@@ -1,4 +1,4 @@
|
||||
# ViaVersion 0.5.7
|
||||
# ViaVersion 0.5.9
|
||||
[](https://travis-ci.org/MylesIsCool/ViaVersion)
|
||||
**Allows the connection of 1.9 clients to 1.8**
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>us.myles</groupId>
|
||||
<artifactId>viaversion</artifactId>
|
||||
<version>0.5.8-SNAPSHOT</version>
|
||||
<version>0.6.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>ViaVersion</name>
|
||||
|
||||
@@ -47,18 +47,21 @@ public class NetUtil {
|
||||
// 2 = Get block light.
|
||||
// 3 = Get sky light.
|
||||
Chunk[] chunks = new Chunk[16];
|
||||
|
||||
int chunkCount = 0;
|
||||
for (int pass = 0; pass < 4; pass++) {
|
||||
if(pass == 1){
|
||||
if(chunkCount == 0) return null;
|
||||
}
|
||||
for (int ind = 0; ind < 16; ind++) {
|
||||
if ((bitmask & 1 << ind) != 0) {
|
||||
if (pass == 0) {
|
||||
chunkCount++;
|
||||
// Block length + Blocklight length
|
||||
expected += (4096 * 2) + 2048;
|
||||
}
|
||||
|
||||
if (pass == 1) {
|
||||
chunks[ind] = new Chunk(sky || hasSkyLight);
|
||||
|
||||
buf.position(pos / 2);
|
||||
int buffPos = buf.position();
|
||||
// convert short array to new one
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
package us.myles.ViaVersion;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.*;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import us.myles.ViaVersion.packets.State;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class ConnectionInfo {
|
||||
private final SocketChannel channel;
|
||||
private Object lastPacket;
|
||||
@@ -17,6 +19,7 @@ public class ConnectionInfo {
|
||||
private String openWindow;
|
||||
private int protocol = 0;
|
||||
private int compression = 0;
|
||||
private int entityID;
|
||||
private boolean active = true;
|
||||
private String username;
|
||||
|
||||
@@ -24,89 +27,33 @@ public class ConnectionInfo {
|
||||
this.channel = socketChannel;
|
||||
}
|
||||
|
||||
public int getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
public void setProtocol(int protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public State getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(State state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public int getCompression() {
|
||||
return compression;
|
||||
}
|
||||
|
||||
public void setCompression(int compression) {
|
||||
this.compression = compression;
|
||||
}
|
||||
|
||||
public Object getLastPacket() {
|
||||
return lastPacket;
|
||||
}
|
||||
|
||||
public void setLastPacket(Object lastPacket) {
|
||||
this.lastPacket = lastPacket;
|
||||
}
|
||||
|
||||
public java.util.UUID getUUID() {
|
||||
return UUID;
|
||||
}
|
||||
|
||||
public void setUUID(UUID UUID) {
|
||||
this.UUID = UUID;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public void sendRawPacket(final ByteBuf packet) {
|
||||
public void sendRawPacket(final ByteBuf packet, boolean currentThread) {
|
||||
final ChannelHandler handler = channel.pipeline().get("encoder");
|
||||
channel.eventLoop().submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
channel.pipeline().context(handler).writeAndFlush(packet);
|
||||
}
|
||||
});
|
||||
if (currentThread) {
|
||||
channel.pipeline().context(handler).writeAndFlush(packet);
|
||||
} else {
|
||||
channel.eventLoop().submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
channel.pipeline().context(handler).writeAndFlush(packet);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public String getOpenWindow() {
|
||||
return openWindow;
|
||||
}
|
||||
|
||||
public void setOpenWindow(String openWindow) {
|
||||
this.openWindow = openWindow;
|
||||
public void sendRawPacket(final ByteBuf packet) {
|
||||
sendRawPacket(packet, false);
|
||||
}
|
||||
|
||||
public void closeWindow() {
|
||||
this.openWindow = null;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -25,9 +24,11 @@ import us.myles.ViaVersion.handlers.ViaVersionInitializer;
|
||||
import us.myles.ViaVersion.listeners.CommandBlockListener;
|
||||
import us.myles.ViaVersion.update.UpdateListener;
|
||||
import us.myles.ViaVersion.update.UpdateUtil;
|
||||
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.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
@@ -53,8 +54,9 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
||||
}
|
||||
}).get(10, TimeUnit.SECONDS);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error fetching hand item ");
|
||||
e.printStackTrace();
|
||||
System.out.println("Error fetching hand item: " + e.getClass().getName());
|
||||
if (ViaVersion.getInstance().isDebug())
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -70,13 +72,8 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
||||
}
|
||||
|
||||
getLogger().info("ViaVersion " + getDescription().getVersion() + " is now enabled, injecting. (Allows 1.8 to be accessed via 1.9)");
|
||||
try {
|
||||
injectPacketHandler();
|
||||
System.setProperty("ViaVersion", getDescription().getVersion());
|
||||
} catch (Exception e) {
|
||||
getLogger().severe("Unable to inject handlers, are you on 1.8? ");
|
||||
e.printStackTrace();
|
||||
}
|
||||
injectPacketHandler();
|
||||
|
||||
if (getConfig().getBoolean("checkforupdates"))
|
||||
UpdateUtil.sendUpdateMessage(this);
|
||||
|
||||
@@ -94,39 +91,75 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
||||
getCommand("viaversion").setExecutor(new ViaVersionCommand(this));
|
||||
}
|
||||
|
||||
public void injectPacketHandler() throws Exception {
|
||||
Class<?> serverClazz = ReflectionUtil.nms("MinecraftServer");
|
||||
Object server = ReflectionUtil.invokeStatic(serverClazz, "getServer");
|
||||
Object connection = serverClazz.getDeclaredMethod("getServerConnection").invoke(server);
|
||||
// loop through all fields checking if list
|
||||
boolean injected = false;
|
||||
for (Field field : connection.getClass().getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
Object value = field.get(connection);
|
||||
if (value instanceof List) {
|
||||
for (Object o : (List) value) {
|
||||
if (o instanceof ChannelFuture) {
|
||||
ChannelFuture future = (ChannelFuture) o;
|
||||
ChannelPipeline pipeline = future.channel().pipeline();
|
||||
ChannelHandler bootstrapAcceptor = pipeline.first();
|
||||
try {
|
||||
ChannelInitializer<SocketChannel> oldInit = ReflectionUtil.get(bootstrapAcceptor, "childHandler", ChannelInitializer.class);
|
||||
ChannelInitializer newInit = new ViaVersionInitializer(oldInit);
|
||||
|
||||
ReflectionUtil.set(bootstrapAcceptor, "childHandler", newInit);
|
||||
} catch (NoSuchFieldException e) {
|
||||
// field not found
|
||||
throw new Exception("Unable to find childHandler, blame " + bootstrapAcceptor.getClass().getName());
|
||||
public void injectPacketHandler() {
|
||||
try {
|
||||
Class<?> serverClazz = ReflectionUtil.nms("MinecraftServer");
|
||||
Object server = ReflectionUtil.invokeStatic(serverClazz, "getServer");
|
||||
Object connection = serverClazz.getDeclaredMethod("getServerConnection").invoke(server);
|
||||
if (connection == null) {
|
||||
System.out.println("connection is null!!");
|
||||
//try others
|
||||
for (Method m : serverClazz.getDeclaredMethods()) {
|
||||
if (m.getReturnType() != null && !m.getName().equals("getServerConnection")) {
|
||||
if (m.getReturnType().getSimpleName().equals("ServerConnection")) {
|
||||
if (m.getParameterTypes().length == 0) {
|
||||
connection = m.invoke(server);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (connection == null) {
|
||||
getLogger().warning("We failed to find the ServerConnection? :(");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (connection != null) {
|
||||
for (Field field : connection.getClass().getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
Object value = field.get(connection);
|
||||
if (value instanceof List) {
|
||||
// Inject the list
|
||||
field.set(connection, new ListWrapper((List) value) {
|
||||
@Override
|
||||
public void handleAdd(Object o) {
|
||||
if (o instanceof ChannelFuture) {
|
||||
inject((ChannelFuture) o);
|
||||
}
|
||||
}
|
||||
});
|
||||
// Iterate through current list
|
||||
for (Object o : (List) value) {
|
||||
if (o instanceof ChannelFuture) {
|
||||
inject((ChannelFuture) o);
|
||||
} else {
|
||||
break; // not the right list.
|
||||
}
|
||||
}
|
||||
injected = true;
|
||||
} else {
|
||||
break; // not the right list.
|
||||
}
|
||||
}
|
||||
}
|
||||
System.setProperty("ViaVersion", getDescription().getVersion());
|
||||
} catch (Exception e) {
|
||||
getLogger().severe("Unable to inject handlers, are you on 1.8? ");
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (!injected) {
|
||||
throw new Exception("Could not find server to inject (Please ensure late-bind in your spigot.yml is false)");
|
||||
}
|
||||
|
||||
private void inject(ChannelFuture future) {
|
||||
try {
|
||||
ChannelHandler bootstrapAcceptor = future.channel().pipeline().first();
|
||||
try {
|
||||
ChannelInitializer<SocketChannel> oldInit = ReflectionUtil.get(bootstrapAcceptor, "childHandler", ChannelInitializer.class);
|
||||
ChannelInitializer newInit = new ViaVersionInitializer(oldInit);
|
||||
|
||||
ReflectionUtil.set(bootstrapAcceptor, "childHandler", newInit);
|
||||
} catch (NoSuchFieldException e) {
|
||||
// field not found
|
||||
throw new Exception("Unable to find childHandler, blame " + bootstrapAcceptor.getClass().getName());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
getLogger().severe("Have you got late-bind enabled with something else? (ProtocolLib?)");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,6 +217,10 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
||||
return getConfig().getBoolean("prevent-collision", true);
|
||||
}
|
||||
|
||||
public boolean isSuppressMetadataErrors() {
|
||||
return getConfig().getBoolean("suppress-metadata-errors", false);
|
||||
}
|
||||
|
||||
public boolean isAutoTeam() {
|
||||
// Collision has to be enabled first
|
||||
if (!isPreventCollision()) return false;
|
||||
@@ -211,8 +248,9 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
||||
f.get(10, TimeUnit.SECONDS);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Failed to run task.");
|
||||
e.printStackTrace();
|
||||
System.out.println("Failed to run task: " + e.getClass().getName());
|
||||
if (ViaVersion.getInstance().isDebug())
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,13 @@ public interface BossBar {
|
||||
*/
|
||||
void setTitle(String title);
|
||||
|
||||
/**
|
||||
* Get the current title
|
||||
*
|
||||
* @return the title
|
||||
*/
|
||||
String getTitle();
|
||||
|
||||
/**
|
||||
* Change the health
|
||||
*
|
||||
@@ -21,11 +28,11 @@ public interface BossBar {
|
||||
void setHealth(float health);
|
||||
|
||||
/**
|
||||
* Get the bossbar color
|
||||
* Get the health
|
||||
*
|
||||
* @return
|
||||
* @return float between 0F - 1F
|
||||
*/
|
||||
BossColor getColor();
|
||||
float getHealth();
|
||||
|
||||
/**
|
||||
* Yay colors!
|
||||
@@ -34,6 +41,13 @@ public interface BossBar {
|
||||
*/
|
||||
void setColor(BossColor color);
|
||||
|
||||
/**
|
||||
* Get the bossbar color
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
BossColor getColor();
|
||||
|
||||
/**
|
||||
* Change the bosbar style
|
||||
*
|
||||
@@ -41,6 +55,13 @@ public interface BossBar {
|
||||
*/
|
||||
void setStyle(BossStyle style);
|
||||
|
||||
/**
|
||||
* Get the bosbar style
|
||||
*
|
||||
* @return BossStyle
|
||||
*/
|
||||
BossStyle getStyle();
|
||||
|
||||
/**
|
||||
* Show the bossbar to a player.
|
||||
*
|
||||
|
||||
@@ -20,16 +20,11 @@ public class ViaVersionCommand implements CommandExecutor {
|
||||
|
||||
private final ViaVersionPlugin plugin;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
|
||||
if (sender.hasPermission("viaversion.admin")) {
|
||||
if (args.length == 0) {
|
||||
sender.sendMessage(color("&aViaVersion &c" + ViaVersion.getInstance().getVersion()));
|
||||
sender.sendMessage(color("&6Commands:"));
|
||||
sender.sendMessage(color("&2/viaversion list &7- &6Shows lists of all 1.9 clients and 1.8 clients."));
|
||||
sender.sendMessage(color("&2/viaversion autoteam &7- &6Toggle automatically teaming to prevent colliding."));
|
||||
sender.sendMessage(color("&2/viaversion dontbugme &7- &6Toggle checking for updates."));
|
||||
sendHelp(sender);
|
||||
} else if (args.length == 1) {
|
||||
if (args[0].equalsIgnoreCase("list")) {
|
||||
List<String> portedPlayers = new ArrayList<>();
|
||||
@@ -44,24 +39,22 @@ public class ViaVersionCommand implements CommandExecutor {
|
||||
|
||||
sender.sendMessage(color("&8[&61.9&8]: &b" + portedPlayers.toString()));
|
||||
sender.sendMessage(color("&8[&61.8&8]: &b" + normalPlayers.toString()));
|
||||
}
|
||||
if (args[0].equalsIgnoreCase("debug")) {
|
||||
} else if (args[0].equalsIgnoreCase("debug")) {
|
||||
plugin.setDebug(!plugin.isDebug());
|
||||
sender.sendMessage(color("&6Debug mode is now " + (plugin.isDebug() ? "&aenabled" : "&cdisabled")));
|
||||
}
|
||||
if (args[0].equalsIgnoreCase("dontbugme")) {
|
||||
} else if (args[0].equalsIgnoreCase("dontbugme")) {
|
||||
boolean newValue = !plugin.getConfig().getBoolean("checkforupdates", true);
|
||||
plugin.getConfig().set("checkforupdates", newValue);
|
||||
plugin.saveConfig();
|
||||
sender.sendMessage(color("&6We will " + (newValue ? "&anotify you about updates." : "&cnot tell you about updates.")));
|
||||
}
|
||||
if (args[0].equalsIgnoreCase("autoteam")) {
|
||||
} else if (args[0].equalsIgnoreCase("autoteam")) {
|
||||
boolean newValue = !plugin.getConfig().getBoolean("auto-team", true);
|
||||
plugin.getConfig().set("auto-team", newValue);
|
||||
plugin.saveConfig();
|
||||
sender.sendMessage(color("&6We will " + (newValue ? "&aautomatically team players" : "&cno longer auto team players")));
|
||||
sender.sendMessage(color("&6All players will need to re-login for the change to take place."));
|
||||
|
||||
} else {
|
||||
sendHelp(sender);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +62,15 @@ public class ViaVersionCommand implements CommandExecutor {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void sendHelp(CommandSender sender){
|
||||
sender.sendMessage(color("&aViaVersion &c" + ViaVersion.getInstance().getVersion()));
|
||||
sender.sendMessage(color("&6Commands:"));
|
||||
sender.sendMessage(color("&2/viaversion list &7- &6Shows lists of all 1.9 clients and 1.8 clients."));
|
||||
sender.sendMessage(color("&2/viaversion debug &7- &6Toggle debug mode"));
|
||||
sender.sendMessage(color("&2/viaversion autoteam &7- &6Toggle automatically teaming to prevent colliding."));
|
||||
sender.sendMessage(color("&2/viaversion dontbugme &7- &6Toggle checking for updates."));
|
||||
}
|
||||
|
||||
public String color(String string) {
|
||||
return string.replace("&", "§");
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public class ViaDecodeHandler extends ByteToMessageDecoder {
|
||||
incomingTransformer.transform(id, bytebuf, newPacket);
|
||||
bytebuf.clear();
|
||||
bytebuf = newPacket;
|
||||
} catch (CancelException e) {
|
||||
} catch (Exception e) {
|
||||
bytebuf.clear();
|
||||
throw e;
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ public class ViaEncodeHandler extends MessageToByteEncoder {
|
||||
bytebuf.clear();
|
||||
try {
|
||||
outgoingTransformer.transform(id, oldPacket, bytebuf);
|
||||
} catch (CancelException e) {
|
||||
} catch (Exception e) {
|
||||
bytebuf.clear();
|
||||
throw e;
|
||||
} finally {
|
||||
|
||||
@@ -33,6 +33,7 @@ public enum MetaIndex {
|
||||
PLAYER_HUMAN_BYTE(HumanEntity.class, 16, Type.Byte, NewType.Discontinued), // unused on 1.8
|
||||
PLAYER_ADDITIONAL_HEARTS(HumanEntity.class, 17, Type.Float, 10, NewType.Float),
|
||||
PLAYER_SCORE(HumanEntity.class, 18, Type.Int, 11, NewType.VarInt),
|
||||
PLAYER_HAND(HumanEntity.class, -1, Type.NonExistent, 5, NewType.Byte), // new in 1.9
|
||||
// horse
|
||||
HORSE_INFO(Horse.class, 16, Type.Int, 12, NewType.Byte),
|
||||
HORSE_TYPE(Horse.class, 19, Type.Byte, 13, NewType.VarInt),
|
||||
|
||||
@@ -6,6 +6,8 @@ import lombok.Setter;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.util.EulerAngle;
|
||||
import org.bukkit.util.Vector;
|
||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||
import us.myles.ViaVersion.api.ViaVersion;
|
||||
import us.myles.ViaVersion.slot.ItemSlotRewriter;
|
||||
import us.myles.ViaVersion.slot.ItemSlotRewriter.ItemStack;
|
||||
import us.myles.ViaVersion.transformers.OutgoingTransformer;
|
||||
@@ -38,6 +40,16 @@ public class MetadataRewriter {
|
||||
if (metaIndex.getOldType() == Type.Int) {
|
||||
output.writeByte(((Integer) value).byteValue());
|
||||
}
|
||||
// After writing the last one
|
||||
if (metaIndex == MetaIndex.ENTITY_STATUS && type == EntityType.PLAYER) {
|
||||
output.writeByte(MetaIndex.PLAYER_HAND.getNewIndex());
|
||||
output.writeByte(MetaIndex.PLAYER_HAND.getNewType().getTypeID());
|
||||
if ((((Byte) value) & 0x10) == 0x10) { // Player eating/aiming/drinking
|
||||
output.writeByte(1); // Using main hand
|
||||
} else {
|
||||
output.writeByte(0); // Not using any hand to stop animation
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OptUUID:
|
||||
String owner = (String) value;
|
||||
@@ -117,16 +129,18 @@ public class MetadataRewriter {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("INCLUDE THIS IN YOUR ERROR LOG!");
|
||||
if (type != null)
|
||||
System.out.println("An error occurred with entity meta data for " + type + " OldID: " + entry.oldID);
|
||||
else
|
||||
System.out.println("An error occurred with entity meta data for UNKOWN_ENTITY OldID: " + entry.oldID);
|
||||
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());
|
||||
if (!((ViaVersionPlugin) ViaVersion.getInstance()).isSuppressMetadataErrors()) {
|
||||
System.out.println("INCLUDE THIS IN YOUR ERROR LOG!");
|
||||
if (type != null)
|
||||
System.out.println("An error occurred with entity meta data for " + type + " OldID: " + entry.oldID);
|
||||
else
|
||||
System.out.println("An error occurred with entity meta data for UNKNOWN_ENTITY OldID: " + entry.oldID);
|
||||
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();
|
||||
}
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
output.writeByte(255);
|
||||
|
||||
@@ -13,7 +13,8 @@ public enum Type {
|
||||
String(4),
|
||||
Slot(5),
|
||||
Position(6),
|
||||
Rotation(7);
|
||||
Rotation(7),
|
||||
NonExistent(-1);
|
||||
private final int typeID;
|
||||
|
||||
public static Type byId(int id) {
|
||||
|
||||
@@ -17,6 +17,7 @@ import java.io.IOException;
|
||||
|
||||
public class IncomingTransformer {
|
||||
private final ConnectionInfo info;
|
||||
private boolean startedBlocking = false;
|
||||
|
||||
public IncomingTransformer(ConnectionInfo info) {
|
||||
this.info = info;
|
||||
@@ -87,14 +88,30 @@ public class IncomingTransformer {
|
||||
}
|
||||
if (packet == PacketType.PLAY_PLAYER_DIGGING) {
|
||||
int status = input.readByte() & 0xFF; // unsign
|
||||
if (status == 5 && startedBlocking) {
|
||||
// stopped blocking
|
||||
startedBlocking = false;
|
||||
sendSecondHandItem(null);
|
||||
}
|
||||
if (status == 6) { // item swap
|
||||
throw new CancelException();
|
||||
}
|
||||
output.writeByte(status);
|
||||
// write remaining bytes
|
||||
output.writeBytes(input);
|
||||
Long position = input.readLong();
|
||||
output.writeLong(position);
|
||||
|
||||
int face = input.readUnsignedByte();
|
||||
output.writeByte(face);
|
||||
return;
|
||||
}
|
||||
if (packet == PacketType.PLAY_HELD_ITEM_CHANGE_REQUEST) {
|
||||
if (startedBlocking) {
|
||||
// stopped blocking
|
||||
startedBlocking = false;
|
||||
sendSecondHandItem(null);
|
||||
}
|
||||
}
|
||||
if (packet == PacketType.PLAY_CLICK_WINDOW) {
|
||||
// if placed in new slot, reject :)
|
||||
int windowID = input.readUnsignedByte();
|
||||
@@ -258,16 +275,16 @@ public class IncomingTransformer {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
short curX = input.readUnsignedByte();
|
||||
output.writeByte(curX);
|
||||
short curY = input.readUnsignedByte();
|
||||
output.writeByte(curY);
|
||||
short curZ = input.readUnsignedByte();
|
||||
output.writeByte(curZ);
|
||||
return;
|
||||
short curX = input.readUnsignedByte();
|
||||
output.writeByte(curX);
|
||||
short curY = input.readUnsignedByte();
|
||||
output.writeByte(curY);
|
||||
short curZ = input.readUnsignedByte();
|
||||
output.writeByte(curZ);
|
||||
return;
|
||||
}
|
||||
if (packet == PacketType.PLAY_USE_ITEM) {
|
||||
int hand = PacketUtil.readVarInt(input);
|
||||
output.clear();
|
||||
PacketUtil.writeVarInt(PacketType.PLAY_PLAYER_BLOCK_PLACEMENT.getPacketID(), output);
|
||||
// Simulate using item :)
|
||||
@@ -275,6 +292,22 @@ public class IncomingTransformer {
|
||||
output.writeByte(255);
|
||||
// write item in hand
|
||||
ItemStack inHand = ViaVersionPlugin.getHandItem(info);
|
||||
if (inHand != null) {
|
||||
if (inHand.getType().name().endsWith("SWORD")) {
|
||||
// blocking?
|
||||
if (hand == 0) {
|
||||
if (!startedBlocking) {
|
||||
startedBlocking = true;
|
||||
ItemSlotRewriter.ItemStack shield = new ItemSlotRewriter.ItemStack();
|
||||
shield.id = 442;
|
||||
shield.amount = 1;
|
||||
shield.data = 0;
|
||||
sendSecondHandItem(shield);
|
||||
}
|
||||
throw new CancelException();
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
ItemSlotRewriter.ItemStack item = ItemSlotRewriter.ItemStack.fromBukkit(inHand);
|
||||
ItemSlotRewriter.fixIdsFrom1_9To1_8(item);
|
||||
@@ -283,9 +316,9 @@ public class IncomingTransformer {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
output.writeByte(-1);
|
||||
output.writeByte(-1);
|
||||
output.writeByte(-1);
|
||||
output.writeByte(0); //Is zero in 1.8, not -1
|
||||
output.writeByte(0);
|
||||
output.writeByte(0);
|
||||
return;
|
||||
}
|
||||
if (packet == PacketType.PLAY_CREATIVE_INVENTORY_ACTION) {
|
||||
@@ -296,4 +329,18 @@ public class IncomingTransformer {
|
||||
}
|
||||
output.writeBytes(input);
|
||||
}
|
||||
|
||||
private void sendSecondHandItem(ItemSlotRewriter.ItemStack o) {
|
||||
ByteBuf buf = info.getChannel().alloc().buffer();
|
||||
PacketUtil.writeVarInt(PacketType.PLAY_ENTITY_EQUIPMENT.getNewPacketID(), buf);
|
||||
PacketUtil.writeVarInt(info.getEntityID(), buf);
|
||||
PacketUtil.writeVarInt(1, buf); // slot
|
||||
// write shield
|
||||
try {
|
||||
ItemSlotRewriter.writeItemStack(o, buf);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
info.sendRawPacket(buf);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,13 @@
|
||||
package us.myles.ViaVersion.transformers;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufInputStream;
|
||||
import io.netty.buffer.ByteBufOutputStream;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
import org.spacehq.mc.protocol.data.game.chunk.Column;
|
||||
import org.spacehq.mc.protocol.util.NetUtil;
|
||||
import org.spacehq.opennbt.NBTIO;
|
||||
import org.spacehq.opennbt.tag.builtin.ByteTag;
|
||||
import org.spacehq.opennbt.tag.builtin.CompoundTag;
|
||||
import org.spacehq.opennbt.tag.builtin.StringTag;
|
||||
@@ -26,8 +24,6 @@ import us.myles.ViaVersion.util.EntityUtil;
|
||||
import us.myles.ViaVersion.util.PacketUtil;
|
||||
import us.myles.ViaVersion.util.ReflectionUtil;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
@@ -42,6 +38,7 @@ public class OutgoingTransformer {
|
||||
private final Map<Integer, UUID> uuidMap = new HashMap<>();
|
||||
private final Map<Integer, EntityType> clientEntityTypes = new HashMap<>();
|
||||
private final Map<Integer, Integer> vehicleMap = new HashMap<>();
|
||||
private final Set<Integer> validBlocking = new HashSet<>();
|
||||
private boolean autoTeam = false;
|
||||
|
||||
public OutgoingTransformer(ConnectionInfo info) {
|
||||
@@ -106,8 +103,10 @@ public class OutgoingTransformer {
|
||||
}
|
||||
if (packet == PacketType.PLAY_EFFECT) {
|
||||
int effectid = input.readInt();
|
||||
if (effectid >= 1000 && effectid < 2000) //Sound effect
|
||||
if (effectid >= 1000 && effectid < 2000 && effectid != 1005) //Sound effect
|
||||
throw new CancelException();
|
||||
if (effectid == 1005) //Fix jukebox
|
||||
effectid = 1010;
|
||||
output.writeInt(effectid);
|
||||
}
|
||||
if (packet == PacketType.PLAY_ATTACH_ENTITY) {
|
||||
@@ -320,7 +319,24 @@ public class OutgoingTransformer {
|
||||
slot += 1; // add 1 so it's now 2-5
|
||||
}
|
||||
PacketUtil.writeVarInt(slot, output);
|
||||
|
||||
if (slot == 0) {
|
||||
// Read aheat for sword
|
||||
input.markReaderIndex();
|
||||
short itemID = input.readShort();
|
||||
if (itemID != -1) {
|
||||
Material m = Material.getMaterial(itemID);
|
||||
if (m != null) {
|
||||
if (m.name().endsWith("SWORD")) {
|
||||
validBlocking.add(id);
|
||||
} else {
|
||||
validBlocking.remove(id);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
validBlocking.remove(id);
|
||||
}
|
||||
input.resetReaderIndex();
|
||||
}
|
||||
ItemSlotRewriter.rewrite1_8To1_9(input, output);
|
||||
return;
|
||||
}
|
||||
@@ -566,6 +582,7 @@ public class OutgoingTransformer {
|
||||
if (packet == PacketType.PLAY_JOIN_GAME) {
|
||||
int id = input.readInt();
|
||||
clientEntityTypes.put(id, EntityType.PLAYER);
|
||||
info.setEntityID(id);
|
||||
output.writeInt(id);
|
||||
output.writeBytes(input);
|
||||
return;
|
||||
@@ -683,12 +700,12 @@ public class OutgoingTransformer {
|
||||
CompoundTag spawn = new CompoundTag("SpawnData");
|
||||
spawn.put(new StringTag("id", entity));
|
||||
tag.put(spawn);
|
||||
PacketUtil.writeNBT(output,tag);
|
||||
PacketUtil.writeNBT(output, tag);
|
||||
} else if (tag != null) { // EntityID does not exist
|
||||
CompoundTag spawn = new CompoundTag("SpawnData");
|
||||
spawn.put(new StringTag("id", "AreaEffectCloud")); //Make spawners show up as empty when no EntityId is given.
|
||||
tag.put(spawn);
|
||||
PacketUtil.writeNBT(output,spawn);
|
||||
PacketUtil.writeNBT(output, spawn);
|
||||
} else { //There doesn't exist any NBT tag
|
||||
input.readerIndex(index);
|
||||
output.writeBytes(input, input.readableBytes());
|
||||
@@ -753,6 +770,9 @@ public class OutgoingTransformer {
|
||||
}
|
||||
}
|
||||
Column read = NetUtil.readOldChunkData(chunkX, chunkZ, groundUp, bitMask, data, true, sk);
|
||||
if (read == null) {
|
||||
throw new CancelException();
|
||||
}
|
||||
// Write chunk section array :((
|
||||
ByteBuf temp = output.alloc().buffer();
|
||||
try {
|
||||
@@ -798,9 +818,34 @@ public class OutgoingTransformer {
|
||||
return;
|
||||
}
|
||||
List<MetadataRewriter.Entry> list = MetadataRewriter.readMetadata1_8(type, input);
|
||||
for (MetadataRewriter.Entry entry : list) {
|
||||
handleMetadata(entityID, entry, type);
|
||||
}
|
||||
MetadataRewriter.writeMetadata1_9(type, list, output);
|
||||
}
|
||||
|
||||
private void handleMetadata(int entityID, MetadataRewriter.Entry entry, EntityType type) {
|
||||
// This handles old IDs
|
||||
if (type == EntityType.PLAYER) {
|
||||
if (entry.getOldID() == 0) {
|
||||
// Byte
|
||||
byte data = (byte) entry.getValue();
|
||||
|
||||
if ((data & 0x10) == 0x10) {
|
||||
if (validBlocking.contains(entityID)) {
|
||||
ItemSlotRewriter.ItemStack shield = new ItemSlotRewriter.ItemStack();
|
||||
shield.id = 442;
|
||||
shield.amount = 1;
|
||||
shield.data = 0;
|
||||
sendSecondHandItem(entityID, shield);
|
||||
}
|
||||
} else {
|
||||
sendSecondHandItem(entityID, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private UUID getUUID(int id) {
|
||||
if (uuidMap.containsKey(id)) {
|
||||
@@ -812,4 +857,18 @@ public class OutgoingTransformer {
|
||||
}
|
||||
}
|
||||
|
||||
private void sendSecondHandItem(int entityID, ItemSlotRewriter.ItemStack o) {
|
||||
|
||||
ByteBuf buf = info.getChannel().alloc().buffer();
|
||||
PacketUtil.writeVarInt(PacketType.PLAY_ENTITY_EQUIPMENT.getNewPacketID(), buf);
|
||||
PacketUtil.writeVarInt(entityID, buf);
|
||||
PacketUtil.writeVarInt(1, buf); // slot
|
||||
// write shield
|
||||
try {
|
||||
ItemSlotRewriter.writeItemStack(o, buf);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
info.sendRawPacket(buf, true);
|
||||
}
|
||||
}
|
||||
@@ -98,7 +98,7 @@ public class UpdateUtil {
|
||||
URL url = new URL(URL + PLUGIN + "?" + System.currentTimeMillis());
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setUseCaches(true);
|
||||
connection.addRequestProperty("User-Agent", "Mozilla/4.76");
|
||||
connection.addRequestProperty("User-Agent", "ViaVersion " + ViaVersion.getInstance().getVersion());
|
||||
connection.setDoOutput(true);
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
String input;
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
package us.myles.ViaVersion.util;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
public abstract class ListWrapper implements List {
|
||||
private final List list;
|
||||
|
||||
public ListWrapper(List inputList) {
|
||||
this.list = inputList;
|
||||
}
|
||||
|
||||
public abstract void handleAdd(Object o);
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return this.list.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return this.list.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
return this.list.contains(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator iterator() {
|
||||
return this.list.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
return this.list.toArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(Object o) {
|
||||
handleAdd(o);
|
||||
return this.list.add(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
return this.list.remove(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection c) {
|
||||
for (Object o : c) {
|
||||
handleAdd(o);
|
||||
}
|
||||
return this.list.addAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(int index, Collection c) {
|
||||
for (Object o : c) {
|
||||
handleAdd(o);
|
||||
}
|
||||
return this.list.addAll(index, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.list.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(int index) {
|
||||
return this.list.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object set(int index, Object element) {
|
||||
return this.list.set(index, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, Object element) {
|
||||
this.list.add(index, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object remove(int index) {
|
||||
return this.list.remove(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object o) {
|
||||
return this.list.indexOf(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object o) {
|
||||
return this.list.lastIndexOf(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator listIterator() {
|
||||
return this.list.listIterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator listIterator(int index) {
|
||||
return this.listIterator(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List subList(int fromIndex, int toIndex) {
|
||||
return this.list.subList(fromIndex, toIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(Collection c) {
|
||||
return this.list.retainAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(Collection c) {
|
||||
return this.list.removeAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection c) {
|
||||
return this.list.containsAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray(Object[] a) {
|
||||
return this.list.toArray(a);
|
||||
}
|
||||
}
|
||||
@@ -8,3 +8,5 @@ sync-chunks: true
|
||||
prevent-collision: true
|
||||
# If the above is true, should we automatically team players until you do?
|
||||
auto-team: true
|
||||
# When enabled if certain metadata can't be read we won't tell you about it
|
||||
suppress-metadata-errors: false
|
||||
Reference in new issue
Block a user