getSupportedVersions();
-
- /**
- * Gets if the server uses spigot
- *
- * Note: Will only work after ViaVersion load
- *
- * @return True if spigot
- */
- boolean isSpigot();
-
- /**
- * Gets if protocol support is also being used.
- *
- * @return True if it is being used.
- */
- boolean isProtocolSupport();
-}
+package us.myles.ViaVersion.api;
+
+import io.netty.buffer.ByteBuf;
+import org.bukkit.entity.Player;
+import us.myles.ViaVersion.api.boss.BossBar;
+import us.myles.ViaVersion.api.boss.BossColor;
+import us.myles.ViaVersion.api.boss.BossStyle;
+import us.myles.ViaVersion.api.command.ViaVersionCommand;
+import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
+
+import java.util.SortedSet;
+import java.util.UUID;
+
+@Deprecated
+public interface ViaVersionAPI extends ViaAPI {
+ /**
+ * Is the player connection modified by ViaVersion?
+ *
+ * @param player Bukkit player object
+ * @return True if the client is modified (At the moment it also means version 1.9 and higher)
+ * @deprecated As of 0.9.9, because all players are ported use {@link #getPlayerVersion(Player)}
+ */
+ boolean isPorted(Player player);
+
+ /**
+ * Get protocol number from a player
+ * Will also retrieve version from ProtocolSupport if it's being used.
+ *
+ * @param player Bukkit player object
+ * @return Protocol ID, For example (47=1.8-1.8.8, 107=1.9, 108=1.9.1)
+ */
+ int getPlayerVersion(Player player);
+
+ /**
+ * Get protocol number from a player
+ *
+ * @param uuid UUID of a player
+ * @return Protocol ID, For example (47=1.8-1.8.8, 107=1.9, 108=1.9.1)
+ */
+ int getPlayerVersion(UUID uuid);
+
+ /**
+ * Is player using 1.9?
+ *
+ * @param playerUUID UUID of a player
+ * @return True if the client is on 1.9
+ * @deprecated As of 0.9.9, because all players are ported use {@link #getPlayerVersion(UUID)}
+ */
+ @Deprecated
+ boolean isPorted(UUID playerUUID);
+
+ /**
+ * Get the version of the plugin
+ *
+ * @return Plugin version
+ */
+ String getVersion();
+
+ /**
+ * Send a raw packet to the player (Use new IDs)
+ *
+ * @param player The player to send packet
+ * @param packet The packet, you need a VarInt ID then the packet contents.
+ * @throws IllegalArgumentException If not on 1.9 throws IllegalArg
+ */
+ void sendRawPacket(Player player, ByteBuf packet) throws IllegalArgumentException;
+
+ /**
+ * Send a raw packet to the player (Use new IDs)
+ *
+ * @param uuid The uuid from the player to send packet
+ * @param packet The packet, you need a VarInt ID then the packet contents.
+ * @throws IllegalArgumentException If not on 1.9 throws IllegalArg
+ */
+ void sendRawPacket(UUID uuid, ByteBuf packet) throws IllegalArgumentException;
+
+ /**
+ * Create a new bossbar instance
+ *
+ * @param title The title
+ * @param color The color
+ * @param style The style
+ * @return BossBar instance
+ */
+ BossBar createBossBar(String title, BossColor color, BossStyle style);
+
+ /**
+ * Create a new bossbar instance
+ *
+ * @param title The title
+ * @param health Number between 0 and 1
+ * @param color The color
+ * @param style The style
+ * @return BossBar instance
+ */
+ BossBar createBossBar(String title, float health, BossColor color, BossStyle style);
+
+ /**
+ * Get if global debug is enabled
+ *
+ * @return true if debug is enabled
+ */
+ boolean isDebug();
+
+ /**
+ * Get ViaVersions commands handler
+ *
+ * @return commands handler
+ */
+ ViaVersionCommand getCommandHandler();
+
+ /**
+ * Get if this version is a compatibility build for spigot.
+ * Eg. 1.9.1 / 1.9.2 allow certain versions to connect
+ *
+ * @return True if it is
+ */
+ boolean isCompatSpigotBuild();
+
+ /**
+ * Get the supported protocol versions
+ * This method removes any blocked protocol versions.
+ *
+ * @return a list of protocol versions
+ * @see ProtocolRegistry#getSupportedVersions() for full list.
+ */
+ SortedSet getSupportedVersions();
+
+ /**
+ * Gets if the server uses spigot
+ *
+ * Note: Will only work after ViaVersion load
+ *
+ * @return True if spigot
+ */
+ boolean isSpigot();
+
+ /**
+ * Gets if protocol support is also being used.
+ *
+ * @return True if it is being used.
+ */
+ boolean isProtocolSupport();
+}
diff --git a/bukkit/src/main/java/us/myles/ViaVersion/boss/ViaBossBar.java b/bukkit/src/main/java/us/myles/ViaVersion/boss/ViaBossBar.java
new file mode 100644
index 000000000..7083ac7d8
--- /dev/null
+++ b/bukkit/src/main/java/us/myles/ViaVersion/boss/ViaBossBar.java
@@ -0,0 +1,34 @@
+package us.myles.ViaVersion.boss;
+
+import lombok.Getter;
+import org.bukkit.entity.Player;
+import us.myles.ViaVersion.api.boss.BossBar;
+import us.myles.ViaVersion.api.boss.BossColor;
+import us.myles.ViaVersion.api.boss.BossStyle;
+
+@Getter
+public class ViaBossBar extends CommonBoss {
+
+ public ViaBossBar(String title, float health, BossColor color, BossStyle style) {
+ super(title, health, color, style);
+ }
+
+ @Override
+ public BossBar addPlayer(Player player) {
+ addPlayer(player.getUniqueId());
+ return this;
+ }
+
+ @Override
+ public BossBar addPlayers(Player... players) {
+ for (Player p : players)
+ addPlayer(p);
+ return this;
+ }
+
+ @Override
+ public BossBar removePlayer(Player player) {
+ removePlayer(player.getUniqueId());
+ return this;
+ }
+}
diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/classgenerator/BasicHandlerConstructor.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/classgenerator/BasicHandlerConstructor.java
new file mode 100644
index 000000000..d7908de01
--- /dev/null
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/classgenerator/BasicHandlerConstructor.java
@@ -0,0 +1,19 @@
+package us.myles.ViaVersion.bukkit.classgenerator;
+
+import io.netty.handler.codec.ByteToMessageDecoder;
+import io.netty.handler.codec.MessageToByteEncoder;
+import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.bukkit.handlers.BukkitDecodeHandler;
+import us.myles.ViaVersion.bukkit.handlers.BukkitEncodeHandler;
+
+public class BasicHandlerConstructor implements HandlerConstructor {
+ @Override
+ public BukkitEncodeHandler newEncodeHandler(UserConnection info, MessageToByteEncoder minecraftEncoder) {
+ return new BukkitEncodeHandler(info, minecraftEncoder);
+ }
+
+ @Override
+ public BukkitDecodeHandler newDecodeHandler(UserConnection info, ByteToMessageDecoder minecraftDecoder) {
+ return new BukkitDecodeHandler(info, minecraftDecoder);
+ }
+}
diff --git a/src/main/java/us/myles/ViaVersion/classgenerator/ClassGenerator.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/classgenerator/ClassGenerator.java
similarity index 88%
rename from src/main/java/us/myles/ViaVersion/classgenerator/ClassGenerator.java
rename to bukkit/src/main/java/us/myles/ViaVersion/bukkit/classgenerator/ClassGenerator.java
index d29089d02..ea4137a0a 100644
--- a/src/main/java/us/myles/ViaVersion/classgenerator/ClassGenerator.java
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/classgenerator/ClassGenerator.java
@@ -1,4 +1,4 @@
-package us.myles.ViaVersion.classgenerator;
+package us.myles.ViaVersion.bukkit.classgenerator;
import javassist.*;
import javassist.expr.ConstructorCall;
@@ -6,9 +6,9 @@ import javassist.expr.ExprEditor;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import us.myles.ViaVersion.api.ViaVersion;
-import us.myles.ViaVersion.handlers.ViaDecodeHandler;
-import us.myles.ViaVersion.handlers.ViaEncodeHandler;
-import us.myles.ViaVersion.util.ReflectionUtil;
+import us.myles.ViaVersion.bukkit.handlers.BukkitDecodeHandler;
+import us.myles.ViaVersion.bukkit.handlers.BukkitEncodeHandler;
+import us.myles.ViaVersion.bukkit.util.NMSUtil;
public class ClassGenerator {
private static HandlerConstructor constructor = new BasicHandlerConstructor();
@@ -27,17 +27,17 @@ public class ClassGenerator {
}
if (ViaVersion.getInstance().isCompatSpigotBuild()) {
- Class decodeSuper = ReflectionUtil.nms("PacketDecoder");
- Class encodeSuper = ReflectionUtil.nms("PacketEncoder");
+ Class decodeSuper = NMSUtil.nms("PacketDecoder");
+ Class encodeSuper = NMSUtil.nms("PacketEncoder");
// Generate the classes
- addSpigotCompatibility(pool, ViaDecodeHandler.class, decodeSuper);
- addSpigotCompatibility(pool, ViaEncodeHandler.class, encodeSuper);
+ addSpigotCompatibility(pool, BukkitDecodeHandler.class, decodeSuper);
+ addSpigotCompatibility(pool, BukkitEncodeHandler.class, encodeSuper);
} else {
Class decodeSuper = Class.forName(getPSPackage() + ".wrapped.WrappedDecoder");
Class encodeSuper = Class.forName(getPSPackage() + ".wrapped.WrappedEncoder");
// Generate the classes
- addPSCompatibility(pool, ViaDecodeHandler.class, decodeSuper);
- addPSCompatibility(pool, ViaEncodeHandler.class, encodeSuper);
+ addPSCompatibility(pool, BukkitDecodeHandler.class, decodeSuper);
+ addPSCompatibility(pool, BukkitEncodeHandler.class, encodeSuper);
}
@@ -53,10 +53,10 @@ public class ClassGenerator {
pool.importPackage("io.netty.handler.codec");
// Implement Methods
generated.addMethod(CtMethod.make("public MessageToByteEncoder newEncodeHandler(UserConnection info, MessageToByteEncoder minecraftEncoder) {\n" +
- " return new ViaEncodeHandler(info, minecraftEncoder);\n" +
+ " return new BukkitEncodeHandler(info, minecraftEncoder);\n" +
" }", generated));
generated.addMethod(CtMethod.make("public ByteToMessageDecoder newDecodeHandler(UserConnection info, ByteToMessageDecoder minecraftDecoder) {\n" +
- " return new ViaDecodeHandler(info, minecraftDecoder);\n" +
+ " return new BukkitDecodeHandler(info, minecraftDecoder);\n" +
" }", generated));
constructor = (HandlerConstructor) generated.toClass(HandlerConstructor.class.getClassLoader()).newInstance();
diff --git a/src/main/java/us/myles/ViaVersion/classgenerator/HandlerConstructor.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/classgenerator/HandlerConstructor.java
similarity index 89%
rename from src/main/java/us/myles/ViaVersion/classgenerator/HandlerConstructor.java
rename to bukkit/src/main/java/us/myles/ViaVersion/bukkit/classgenerator/HandlerConstructor.java
index 19a5423c4..ab16e9967 100644
--- a/src/main/java/us/myles/ViaVersion/classgenerator/HandlerConstructor.java
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/classgenerator/HandlerConstructor.java
@@ -1,4 +1,4 @@
-package us.myles.ViaVersion.classgenerator;
+package us.myles.ViaVersion.bukkit.classgenerator;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.MessageToByteEncoder;
diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/commands/BukkitCommandHandler.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/commands/BukkitCommandHandler.java
new file mode 100644
index 000000000..11bf9771f
--- /dev/null
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/commands/BukkitCommandHandler.java
@@ -0,0 +1,21 @@
+package us.myles.ViaVersion.bukkit.commands;
+
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
+import us.myles.ViaVersion.commands.ViaCommandHandler;
+
+import java.util.List;
+
+public class BukkitCommandHandler extends ViaCommandHandler implements CommandExecutor, TabExecutor {
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ return onCommand(new BukkitCommandSender(sender), args);
+ }
+
+ @Override
+ public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+ return onTabComplete(new BukkitCommandSender(sender), args);
+ }
+}
diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/commands/BukkitCommandSender.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/commands/BukkitCommandSender.java
new file mode 100644
index 000000000..e1288ca29
--- /dev/null
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/commands/BukkitCommandSender.java
@@ -0,0 +1,37 @@
+package us.myles.ViaVersion.bukkit.commands;
+
+import lombok.AllArgsConstructor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import us.myles.ViaVersion.api.command.ViaCommandSender;
+
+import java.util.UUID;
+
+@AllArgsConstructor
+public class BukkitCommandSender implements ViaCommandSender {
+ private CommandSender sender;
+
+ @Override
+ public boolean hasPermission(String permission) {
+ return sender.hasPermission(permission);
+ }
+
+ @Override
+ public void sendMessage(String msg) {
+ sender.sendMessage(msg);
+ }
+
+ @Override
+ public UUID getUUID() {
+ if (sender instanceof Player) {
+ return ((Player) sender).getUniqueId();
+ } else {
+ return UUID.fromString(getName());
+ }
+ }
+
+ @Override
+ public String getName() {
+ return sender.getName();
+ }
+}
diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaVersionInitializer.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/handlers/BukkitChannelInitializer.java
similarity index 81%
rename from src/main/java/us/myles/ViaVersion/handlers/ViaVersionInitializer.java
rename to bukkit/src/main/java/us/myles/ViaVersion/bukkit/handlers/BukkitChannelInitializer.java
index ccd70da1e..a4529ad3a 100644
--- a/src/main/java/us/myles/ViaVersion/handlers/ViaVersionInitializer.java
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/handlers/BukkitChannelInitializer.java
@@ -1,4 +1,4 @@
-package us.myles.ViaVersion.handlers;
+package us.myles.ViaVersion.bukkit.handlers;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
@@ -7,17 +7,17 @@ import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.MessageToByteEncoder;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.protocol.ProtocolPipeline;
-import us.myles.ViaVersion.classgenerator.ClassGenerator;
-import us.myles.ViaVersion.classgenerator.HandlerConstructor;
+import us.myles.ViaVersion.bukkit.classgenerator.ClassGenerator;
+import us.myles.ViaVersion.bukkit.classgenerator.HandlerConstructor;
import java.lang.reflect.Method;
-public class ViaVersionInitializer extends ChannelInitializer {
+public class BukkitChannelInitializer extends ChannelInitializer {
private final ChannelInitializer original;
private Method method;
- public ViaVersionInitializer(ChannelInitializer oldInit) {
+ public BukkitChannelInitializer(ChannelInitializer oldInit) {
this.original = oldInit;
try {
this.method = ChannelInitializer.class.getDeclaredMethod("initChannel", Channel.class);
@@ -43,7 +43,7 @@ public class ViaVersionInitializer extends ChannelInitializer {
// Add our transformers
MessageToByteEncoder encoder = constructor.newEncodeHandler(info, (MessageToByteEncoder) socketChannel.pipeline().get("encoder"));
ByteToMessageDecoder decoder = constructor.newDecodeHandler(info, (ByteToMessageDecoder) socketChannel.pipeline().get("decoder"));
- ViaPacketHandler chunkHandler = new ViaPacketHandler(info);
+ BukkitPacketHandler chunkHandler = new BukkitPacketHandler(info);
socketChannel.pipeline().replace("encoder", "encoder", encoder);
socketChannel.pipeline().replace("decoder", "decoder", decoder);
diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/handlers/BukkitDecodeHandler.java
similarity index 86%
rename from src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java
rename to bukkit/src/main/java/us/myles/ViaVersion/bukkit/handlers/BukkitDecodeHandler.java
index c7122233e..59f2f3e18 100644
--- a/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/handlers/BukkitDecodeHandler.java
@@ -1,11 +1,9 @@
-package us.myles.ViaVersion.handlers;
+package us.myles.ViaVersion.bukkit.handlers;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
-import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.PacketWrapper;
-import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.exception.CancelException;
@@ -16,13 +14,12 @@ import us.myles.ViaVersion.util.PipelineUtil;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
-public class ViaDecodeHandler extends ByteToMessageDecoder {
+public class BukkitDecodeHandler extends ByteToMessageDecoder {
private final ByteToMessageDecoder minecraftDecoder;
private final UserConnection info;
- public static int PASSTHROUGH_ID = 1000;
- public ViaDecodeHandler(UserConnection info, ByteToMessageDecoder minecraftDecoder) {
+ public BukkitDecodeHandler(UserConnection info, ByteToMessageDecoder minecraftDecoder) {
this.info = info;
this.minecraftDecoder = minecraftDecoder;
}
@@ -39,7 +36,7 @@ public class ViaDecodeHandler extends ByteToMessageDecoder {
boolean second = info.incrementReceived();
// Check PPS
if (second) {
- if (((ViaVersionPlugin) ViaVersion.getInstance()).handlePPS(info))
+ if (info.handlePPS())
return;
}
@@ -49,7 +46,7 @@ public class ViaDecodeHandler extends ByteToMessageDecoder {
// Transform
ByteBuf newPacket = ctx.alloc().buffer();
try {
- if (id == ViaDecodeHandler.PASSTHROUGH_ID) {
+ if (id == PacketWrapper.PASSTHROUGH_ID) {
newPacket.writeBytes(bytebuf);
} else {
PacketWrapper wrapper = new PacketWrapper(id, bytebuf, info);
diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/handlers/BukkitEncodeHandler.java
similarity index 87%
rename from src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java
rename to bukkit/src/main/java/us/myles/ViaVersion/bukkit/handlers/BukkitEncodeHandler.java
index fd0f5d2e2..e22a8b359 100644
--- a/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/handlers/BukkitEncodeHandler.java
@@ -1,10 +1,11 @@
-package us.myles.ViaVersion.handlers;
+package us.myles.ViaVersion.bukkit.handlers;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
+import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.PacketWrapper;
-import us.myles.ViaVersion.api.ViaVersion;
+import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.exception.CancelException;
@@ -15,11 +16,11 @@ import us.myles.ViaVersion.util.PipelineUtil;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
-public class ViaEncodeHandler extends MessageToByteEncoder {
+public class BukkitEncodeHandler extends MessageToByteEncoder {
private final UserConnection info;
private final MessageToByteEncoder minecraftEncoder;
- public ViaEncodeHandler(UserConnection info, MessageToByteEncoder minecraftEncoder) {
+ public BukkitEncodeHandler(UserConnection info, MessageToByteEncoder minecraftEncoder) {
this.info = info;
this.minecraftEncoder = minecraftEncoder;
}
@@ -27,7 +28,7 @@ public class ViaEncodeHandler extends MessageToByteEncoder {
@Override
protected void encode(final ChannelHandlerContext ctx, Object o, final ByteBuf bytebuf) throws Exception {
- if (ViaVersion.getInstance().isCompatSpigotBuild()) {
+ if (((ViaVersionPlugin) Via.getPlatform()).isCompatSpigotBuild()) {
Field ver = minecraftEncoder.getClass().getDeclaredField("version");
ver.setAccessible(true);
ver.set(minecraftEncoder, ver.get(this));
diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaPacketHandler.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/handlers/BukkitPacketHandler.java
similarity index 87%
rename from src/main/java/us/myles/ViaVersion/handlers/ViaPacketHandler.java
rename to bukkit/src/main/java/us/myles/ViaVersion/bukkit/handlers/BukkitPacketHandler.java
index a0205a8b5..d3b352dac 100644
--- a/src/main/java/us/myles/ViaVersion/handlers/ViaPacketHandler.java
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/handlers/BukkitPacketHandler.java
@@ -1,4 +1,4 @@
-package us.myles.ViaVersion.handlers;
+package us.myles.ViaVersion.bukkit.handlers;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
@@ -8,10 +8,10 @@ import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import java.util.List;
-public class ViaPacketHandler extends MessageToMessageEncoder {
+public class BukkitPacketHandler extends MessageToMessageEncoder {
private final UserConnection info;
- public ViaPacketHandler(UserConnection info) {
+ public BukkitPacketHandler(UserConnection info) {
this.info = info;
}
diff --git a/src/main/java/us/myles/ViaVersion/update/UpdateListener.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/UpdateListener.java
similarity index 52%
rename from src/main/java/us/myles/ViaVersion/update/UpdateListener.java
rename to bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/UpdateListener.java
index 965e142ac..3d7f74eb9 100644
--- a/src/main/java/us/myles/ViaVersion/update/UpdateListener.java
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/UpdateListener.java
@@ -1,23 +1,18 @@
-package us.myles.ViaVersion.update;
-
-import lombok.RequiredArgsConstructor;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
-import org.bukkit.event.player.PlayerJoinEvent;
-import us.myles.ViaVersion.ViaVersionPlugin;
-import us.myles.ViaVersion.api.ViaVersion;
-
-@RequiredArgsConstructor
-public class UpdateListener implements Listener {
-
- private final ViaVersionPlugin plugin;
-
- @EventHandler
- public void onJoin(PlayerJoinEvent e) {
- if (e.getPlayer().hasPermission("viaversion.update")
- && ViaVersion.getConfig().isCheckForUpdates()) {
- UpdateUtil.sendUpdateMessage(e.getPlayer().getUniqueId(), plugin);
- }
- }
-
-}
+package us.myles.ViaVersion.bukkit.listeners;
+
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerJoinEvent;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.update.UpdateUtil;
+
+public class UpdateListener implements Listener {
+
+ @EventHandler
+ public void onJoin(PlayerJoinEvent e) {
+ if (e.getPlayer().hasPermission("viaversion.update")
+ && Via.getConfig().isCheckForUpdates()) {
+ UpdateUtil.sendUpdateMessage(e.getPlayer().getUniqueId());
+ }
+ }
+}
diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/ViaBukkitListener.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/ViaBukkitListener.java
new file mode 100644
index 000000000..a94bca5d3
--- /dev/null
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/ViaBukkitListener.java
@@ -0,0 +1,53 @@
+package us.myles.ViaVersion.bukkit.listeners;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.NonNull;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Listener;
+import org.bukkit.plugin.Plugin;
+import us.myles.ViaVersion.ViaVersionPlugin;
+import us.myles.ViaVersion.api.ViaListener;
+import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.api.protocol.Protocol;
+
+@Getter(AccessLevel.PROTECTED)
+public class ViaBukkitListener extends ViaListener implements Listener {
+ private final Plugin plugin;
+
+ public ViaBukkitListener(ViaVersionPlugin plugin, Class extends Protocol> requiredPipeline) {
+ super(requiredPipeline);
+ this.plugin = plugin;
+ }
+
+ /**
+ * Get the UserConnection from a player
+ *
+ * @param player Player object
+ * @return The UserConnection
+ */
+ protected UserConnection getUserConnection(@NonNull Player player) {
+ return getUserConnection(player.getUniqueId());
+ }
+
+ /**
+ * Checks if the player is on the selected pipe
+ *
+ * @param player Player Object
+ * @return True if on pipe
+ */
+ protected boolean isOnPipe(Player player) {
+ return isOnPipe(player.getUniqueId());
+ }
+
+ /**
+ * Register as Bukkit event
+ */
+ @Override
+ public void register() {
+ if (isRegistered()) return;
+
+ plugin.getServer().getPluginManager().registerEvents(this, plugin);
+ setRegistered(true);
+ }
+}
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/listeners/ArmorListener.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/protocol1_9to1_8/ArmorListener.java
similarity index 89%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/listeners/ArmorListener.java
rename to bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/protocol1_9to1_8/ArmorListener.java
index 36e012132..2880f47e4 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/listeners/ArmorListener.java
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/protocol1_9to1_8/ArmorListener.java
@@ -1,4 +1,4 @@
-package us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners;
+package us.myles.ViaVersion.bukkit.listeners.protocol1_9to1_8;
import org.bukkit.Bukkit;
import org.bukkit.entity.HumanEntity;
@@ -12,16 +12,18 @@ import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.inventory.CraftingInventory;
+import org.bukkit.inventory.ItemStack;
import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.PacketWrapper;
-import us.myles.ViaVersion.api.ViaListener;
+import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.type.Type;
+import us.myles.ViaVersion.bukkit.listeners.ViaBukkitListener;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.ArmorType;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
import java.util.UUID;
-public class ArmorListener extends ViaListener {
+public class ArmorListener extends ViaBukkitListener {
private static final UUID ARMOR_ATTRIBUTE = UUID.fromString("2AD3F246-FEE1-4E67-B886-69FD380BB150");
@@ -33,7 +35,11 @@ public class ArmorListener extends ViaListener {
// Ensure that the player is on our pipe
if (!isOnPipe(player)) return;
- int armor = ArmorType.calculateArmorPoints(player.getInventory().getArmorContents());
+
+ int armor = 0;
+ for (ItemStack stack : player.getInventory().getArmorContents()) {
+ armor += ArmorType.findById(stack.getTypeId()).getArmorPoints();
+ }
PacketWrapper wrapper = new PacketWrapper(0x4B, null, getUserConnection(player));
try {
@@ -58,7 +64,7 @@ public class ArmorListener extends ViaListener {
if (human instanceof Player && e.getInventory() instanceof CraftingInventory) {
final Player player = (Player) human;
if (e.getCurrentItem() != null) {
- if (ArmorType.isArmor(e.getCurrentItem().getType())) {
+ if (ArmorType.isArmor(e.getCurrentItem().getTypeId())) {
sendDelayedArmorUpdate(player);
return;
}
@@ -102,7 +108,7 @@ public class ArmorListener extends ViaListener {
public void sendDelayedArmorUpdate(final Player player) {
if (!isOnPipe(player)) return; // Don't start a task if the player is not on the pipe
- Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(), new Runnable() {
+ Via.getPlatform().runSync(new Runnable() {
@Override
public void run() {
sendArmorUpdate(player);
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/listeners/BlockListener.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/protocol1_9to1_8/BlockListener.java
similarity index 83%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/listeners/BlockListener.java
rename to bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/protocol1_9to1_8/BlockListener.java
index 8143caa91..801e406cd 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/listeners/BlockListener.java
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/protocol1_9to1_8/BlockListener.java
@@ -1,16 +1,16 @@
-package us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners;
+package us.myles.ViaVersion.bukkit.listeners.protocol1_9to1_8;
import org.bukkit.block.Block;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockPlaceEvent;
import us.myles.ViaVersion.ViaVersionPlugin;
-import us.myles.ViaVersion.api.ViaListener;
import us.myles.ViaVersion.api.minecraft.Position;
+import us.myles.ViaVersion.bukkit.listeners.ViaBukkitListener;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker;
-public class BlockListener extends ViaListener {
+public class BlockListener extends ViaBukkitListener {
public BlockListener(ViaVersionPlugin plugin) {
super(plugin, Protocol1_9TO1_8.class);
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/listeners/CommandBlockListener.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/protocol1_9to1_8/CommandBlockListener.java
similarity index 90%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/listeners/CommandBlockListener.java
rename to bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/protocol1_9to1_8/CommandBlockListener.java
index a18ec4f27..e75aa3af8 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/listeners/CommandBlockListener.java
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/protocol1_9to1_8/CommandBlockListener.java
@@ -1,4 +1,4 @@
-package us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners;
+package us.myles.ViaVersion.bukkit.listeners.protocol1_9to1_8;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufOutputStream;
@@ -18,10 +18,11 @@ import org.spacehq.opennbt.tag.builtin.ByteTag;
import org.spacehq.opennbt.tag.builtin.CompoundTag;
import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.PacketWrapper;
-import us.myles.ViaVersion.api.ViaListener;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.minecraft.Position;
import us.myles.ViaVersion.api.type.Type;
+import us.myles.ViaVersion.bukkit.listeners.ViaBukkitListener;
+import us.myles.ViaVersion.bukkit.util.NMSUtil;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
import us.myles.ViaVersion.util.ReflectionUtil;
@@ -29,7 +30,7 @@ import java.io.DataOutput;
import java.io.DataOutputStream;
import java.lang.reflect.Method;
-public class CommandBlockListener extends ViaListener {
+public class CommandBlockListener extends ViaBukkitListener {
public CommandBlockListener(ViaVersionPlugin plugin) {
super(plugin, Protocol1_9TO1_8.class);
@@ -88,7 +89,7 @@ public class CommandBlockListener extends ViaListener {
return;
CommandBlock cmd = (CommandBlock) b.getState();
- Object tileEntityCommand = ReflectionUtil.get(cmd, "commandBlock", ReflectionUtil.nms("TileEntityCommand"));
+ Object tileEntityCommand = ReflectionUtil.get(cmd, "commandBlock", NMSUtil.nms("TileEntityCommand"));
Object updatePacket = ReflectionUtil.invoke(tileEntityCommand, "getUpdatePacket");
PacketWrapper wrapper = generatePacket(updatePacket, getUserConnection(player));
@@ -98,12 +99,12 @@ public class CommandBlockListener extends ViaListener {
private PacketWrapper generatePacket(Object updatePacket, UserConnection usr) throws Exception {
PacketWrapper wrapper = new PacketWrapper(0x09, null, usr); // Update block entity
- long[] pos = getPosition(ReflectionUtil.get(updatePacket, "a", ReflectionUtil.nms("BlockPosition")));
+ long[] pos = getPosition(ReflectionUtil.get(updatePacket, "a", NMSUtil.nms("BlockPosition")));
wrapper.write(Type.POSITION, new Position(pos[0], pos[1], pos[2])); //Block position
wrapper.write(Type.BYTE, (byte) 2); // Action id always 2
- CompoundTag nbt = getNBT(ReflectionUtil.get(updatePacket, "c", ReflectionUtil.nms("NBTTagCompound")));
+ CompoundTag nbt = getNBT(ReflectionUtil.get(updatePacket, "c", NMSUtil.nms("NBTTagCompound")));
if (nbt == null) {
wrapper.write(Type.BYTE, (byte) 0); //If nbt is null. Use 0 as nbt
return wrapper;
@@ -125,12 +126,12 @@ public class CommandBlockListener extends ViaListener {
}
private boolean isR1() {
- return ReflectionUtil.getVersion().equals("v1_8_R1");
+ return NMSUtil.getVersion().equals("v1_8_R1");
}
private CompoundTag getNBT(Object obj) throws Exception {
ByteBuf buf = Unpooled.buffer();
- Method m = ReflectionUtil.nms("NBTCompressedStreamTools").getMethod("a", ReflectionUtil.nms("NBTTagCompound"), DataOutput.class);
+ Method m = NMSUtil.nms("NBTCompressedStreamTools").getMethod("a", NMSUtil.nms("NBTTagCompound"), DataOutput.class);
m.invoke(null, obj, new DataOutputStream(new ByteBufOutputStream(buf)));
try {
return Type.NBT.read(buf);
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/listeners/DeathListener.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/protocol1_9to1_8/DeathListener.java
similarity index 87%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/listeners/DeathListener.java
rename to bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/protocol1_9to1_8/DeathListener.java
index 51f91e4d0..5ac730080 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/listeners/DeathListener.java
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/protocol1_9to1_8/DeathListener.java
@@ -1,6 +1,5 @@
-package us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners;
+package us.myles.ViaVersion.bukkit.listeners.protocol1_9to1_8;
-import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -8,12 +7,13 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.PlayerDeathEvent;
import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.PacketWrapper;
-import us.myles.ViaVersion.api.ViaListener;
+import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.api.type.Type;
+import us.myles.ViaVersion.bukkit.listeners.ViaBukkitListener;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
-public class DeathListener extends ViaListener {
+public class DeathListener extends ViaBukkitListener {
public DeathListener(ViaVersionPlugin plugin) {
super(plugin, Protocol1_9TO1_8.class);
}
@@ -34,7 +34,7 @@ public class DeathListener extends ViaListener {
}
private void sendPacket(final Player p, final String msg) {
- Bukkit.getScheduler().runTask(getPlugin(), new Runnable() {
+ Via.getPlatform().runSync(new Runnable() {
@Override
public void run() {
PacketWrapper wrapper = new PacketWrapper(0x2C, null, getUserConnection(p));
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/listeners/HandItemCache.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/protocol1_9to1_8/HandItemCache.java
similarity index 68%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/listeners/HandItemCache.java
rename to bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/protocol1_9to1_8/HandItemCache.java
index ed1791ca7..a7a288982 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/listeners/HandItemCache.java
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/protocol1_9to1_8/HandItemCache.java
@@ -1,7 +1,8 @@
-package us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners;
+package us.myles.ViaVersion.bukkit.listeners.protocol1_9to1_8;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
import us.myles.ViaVersion.api.minecraft.item.Item;
@@ -25,7 +26,7 @@ public class HandItemCache extends BukkitRunnable {
List players = new ArrayList<>(handCache.keySet());
for (Player p : Bukkit.getOnlinePlayers()) {
- handCache.put(p.getUniqueId(), Item.getItem(p.getItemInHand()));
+ handCache.put(p.getUniqueId(), convert(p.getItemInHand()));
players.remove(p.getUniqueId());
}
// Remove offline players
@@ -33,4 +34,9 @@ public class HandItemCache extends BukkitRunnable {
handCache.remove(uuid);
}
}
+
+ public static Item convert(ItemStack itemInHand) {
+ if (itemInHand == null) return new Item((short) 0, (byte) 0, (short) 0, null);
+ return new Item((short) itemInHand.getTypeId(), (byte) itemInHand.getAmount(), itemInHand.getDurability(), null);
+ }
}
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/listeners/PaperPatch.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/protocol1_9to1_8/PaperPatch.java
similarity index 92%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/listeners/PaperPatch.java
rename to bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/protocol1_9to1_8/PaperPatch.java
index bd59d0f2e..5fbd1562a 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/listeners/PaperPatch.java
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/protocol1_9to1_8/PaperPatch.java
@@ -1,4 +1,4 @@
-package us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners;
+package us.myles.ViaVersion.bukkit.listeners.protocol1_9to1_8;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -6,10 +6,10 @@ import org.bukkit.block.BlockFace;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.BlockPlaceEvent;
import us.myles.ViaVersion.ViaVersionPlugin;
-import us.myles.ViaVersion.api.ViaListener;
+import us.myles.ViaVersion.bukkit.listeners.ViaBukkitListener;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
-public class PaperPatch extends ViaListener {
+public class PaperPatch extends ViaBukkitListener {
public PaperPatch(ViaVersionPlugin plugin) {
super(plugin, Protocol1_9TO1_8.class);
diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java
new file mode 100644
index 000000000..54820614e
--- /dev/null
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java
@@ -0,0 +1,179 @@
+package us.myles.ViaVersion.bukkit.platform;
+
+import us.myles.ViaVersion.ViaVersionPlugin;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.ViaVersionConfig;
+import us.myles.ViaVersion.util.Config;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+public class BukkitConfigAPI extends Config implements ViaVersionConfig {
+ private static List UNSUPPORTED = Arrays.asList("bungee-ping-interval", "bungee-ping-save", "bungee-servers");
+
+ public BukkitConfigAPI() {
+ super(new File(((ViaVersionPlugin) Via.getPlatform()).getDataFolder(), "config.yml"));
+ }
+
+ @Override
+ public boolean isCheckForUpdates() {
+ return getBoolean("checkforupdates", true);
+ }
+
+ @Override
+ public boolean isPreventCollision() {
+ return getBoolean("prevent-collision", true);
+ }
+
+ @Override
+ public boolean isNewEffectIndicator() {
+ return getBoolean("use-new-effect-indicator", true);
+ }
+
+ @Override
+ public boolean isShowNewDeathMessages() {
+ return getBoolean("use-new-deathmessages", true);
+ }
+
+ @Override
+ public boolean isSuppressMetadataErrors() {
+ return getBoolean("suppress-metadata-errors", false);
+ }
+
+ @Override
+ public boolean isShieldBlocking() {
+ return getBoolean("shield-blocking", true);
+ }
+
+ @Override
+ public boolean isHologramPatch() {
+ return getBoolean("hologram-patch", false);
+ }
+
+ @Override
+ public boolean isBossbarPatch() {
+ return getBoolean("bossbar-patch", true);
+ }
+
+ @Override
+ public boolean isBossbarAntiflicker() {
+ return getBoolean("bossbar-anti-flicker", false);
+ }
+
+ @Override
+ public boolean isUnknownEntitiesSuppressed() {
+ return false;
+ }
+
+ @Override
+ public double getHologramYOffset() {
+ return getDouble("hologram-y", -0.96D);
+ }
+
+ @Override
+ public boolean isBlockBreakPatch() {
+ return false;
+ }
+
+ @Override
+ public int getMaxPPS() {
+ return getInt("max-pps", 800);
+ }
+
+ @Override
+ public String getMaxPPSKickMessage() {
+ return getString("max-pps-kick-msg", "Sending packets too fast? lag?");
+ }
+
+ @Override
+ public int getTrackingPeriod() {
+ return getInt("tracking-period", 6);
+ }
+
+ @Override
+ public int getWarningPPS() {
+ return getInt("tracking-warning-pps", 120);
+ }
+
+ @Override
+ public int getMaxWarnings() {
+ return getInt("tracking-max-warnings", 3);
+ }
+
+ @Override
+ public String getMaxWarningsKickMessage() {
+ return getString("tracking-max-kick-msg", "You are sending too many packets, :(");
+ }
+
+ @Override
+ public boolean isAntiXRay() {
+ return getBoolean("anti-xray-patch", true);
+ }
+
+ @Override
+ public boolean isSendSupportedVersions() {
+ return getBoolean("send-supported-versions", false);
+ }
+
+ @Override
+ public boolean isStimulatePlayerTick() {
+ return getBoolean("simulate-pt", true);
+ }
+
+ @Override
+ public boolean isItemCache() {
+ return getBoolean("item-cache", true);
+ }
+
+ @Override
+ public boolean isNMSPlayerTicking() {
+ return getBoolean("nms-player-ticking", true);
+ }
+
+ @Override
+ public boolean isReplacePistons() {
+ return getBoolean("replace-pistons", false);
+ }
+
+ @Override
+ public int getPistonReplacementId() {
+ return getInt("replacement-piston-id", 0);
+ }
+
+ public boolean isAutoTeam() {
+ // Collision has to be enabled first
+ return isPreventCollision() && getBoolean("auto-team", true);
+ }
+
+ @Override
+ public boolean isForceJsonTransform() {
+ return getBoolean("force-json-transform", false);
+ }
+
+ @Override
+ public List getBlockedProtocols() {
+ return getIntegerList("block-protocols");
+ }
+
+ @Override
+ public String getBlockedDisconnectMsg() {
+ return getString("block-disconnect-msg", "You are using an unsupported Minecraft version!");
+ }
+
+ @Override
+ public String getReloadDisconnectMsg() {
+ return getString("reload-disconnect-msg", "Server reload, please rejoin!");
+ }
+
+ @Override
+ protected void handleConfig(Map config) {
+ // Nothing currently
+ }
+
+ @Override
+ public List getUnsupportedOptions() {
+ return UNSUPPORTED;
+ }
+}
diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitTaskId.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitTaskId.java
new file mode 100644
index 000000000..50685a297
--- /dev/null
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitTaskId.java
@@ -0,0 +1,11 @@
+package us.myles.ViaVersion.bukkit.platform;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import us.myles.ViaVersion.api.platform.TaskId;
+
+@Getter
+@AllArgsConstructor
+public class BukkitTaskId implements TaskId {
+ private Integer object;
+}
diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaAPI.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaAPI.java
new file mode 100644
index 000000000..d76cece62
--- /dev/null
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaAPI.java
@@ -0,0 +1,127 @@
+package us.myles.ViaVersion.bukkit.platform;
+
+import io.netty.buffer.ByteBuf;
+import lombok.AllArgsConstructor;
+import lombok.NonNull;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import us.myles.ViaVersion.ViaVersionPlugin;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.ViaAPI;
+import us.myles.ViaVersion.api.ViaVersionAPI;
+import us.myles.ViaVersion.api.boss.BossBar;
+import us.myles.ViaVersion.api.boss.BossColor;
+import us.myles.ViaVersion.api.boss.BossStyle;
+import us.myles.ViaVersion.api.command.ViaVersionCommand;
+import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
+import us.myles.ViaVersion.boss.ViaBossBar;
+import us.myles.ViaVersion.bukkit.util.ProtocolSupportUtil;
+import us.myles.ViaVersion.protocols.base.ProtocolInfo;
+
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.UUID;
+
+@AllArgsConstructor
+public class BukkitViaAPI implements ViaAPI, ViaVersionAPI {
+ private ViaVersionPlugin plugin;
+
+ @Override
+ public int getPlayerVersion(@NonNull Player player) {
+ if (!isPorted(player))
+ return getExternalVersion(player);
+ return getPortedPlayers().get(player.getUniqueId()).get(ProtocolInfo.class).getProtocolVersion();
+ }
+
+ @Override
+ public int getPlayerVersion(@NonNull UUID uuid) {
+ if (!isPorted(uuid))
+ return getExternalVersion(Bukkit.getPlayer(uuid));
+ return getPortedPlayers().get(uuid).get(ProtocolInfo.class).getProtocolVersion();
+ }
+
+ private int getExternalVersion(Player player) {
+ if (!isProtocolSupport()) {
+ return ProtocolRegistry.SERVER_PROTOCOL;
+ } else {
+ return ProtocolSupportUtil.getProtocolVersion(player);
+ }
+ }
+
+ @Override
+ public boolean isPorted(Player player) {
+ return isPorted(player.getUniqueId());
+ }
+
+ @Override
+ public boolean isPorted(UUID playerUUID) {
+ return getPortedPlayers().containsKey(playerUUID);
+ }
+
+ @Override
+ public String getVersion() {
+ return plugin.getDescription().getVersion();
+ }
+
+ @Override
+ public void sendRawPacket(UUID uuid, ByteBuf packet) throws IllegalArgumentException {
+ if (!isPorted(uuid)) throw new IllegalArgumentException("This player is not controlled by ViaVersion!");
+ UserConnection ci = getPortedPlayers().get(uuid);
+ ci.sendRawPacket(packet);
+ }
+
+ @Override
+ public void sendRawPacket(Player player, ByteBuf packet) throws IllegalArgumentException {
+ sendRawPacket(player.getUniqueId(), packet);
+ }
+
+ @Override
+ public BossBar createBossBar(String title, BossColor color, BossStyle style) {
+ return new ViaBossBar(title, 1F, color, style);
+ }
+
+ @Override
+ public BossBar createBossBar(String title, float health, BossColor color, BossStyle style) {
+ return new ViaBossBar(title, health, color, style);
+ }
+
+ @Override
+ public boolean isDebug() {
+ return Via.getManager().isDebug();
+ }
+
+ @Override
+ public ViaVersionCommand getCommandHandler() {
+ return Via.getManager().getCommandHandler();
+ }
+
+ @Override
+ public SortedSet getSupportedVersions() {
+ SortedSet outputSet = new TreeSet<>(ProtocolRegistry.getSupportedVersions());
+ outputSet.removeAll(Via.getPlatform().getConf().getBlockedProtocols());
+
+ return outputSet;
+ }
+
+ @Override
+ public boolean isCompatSpigotBuild() {
+ return plugin.isCompatSpigotBuild();
+ }
+
+
+ @Override
+ public boolean isSpigot() {
+ return plugin.isSpigot();
+ }
+
+ @Override
+ public boolean isProtocolSupport() {
+ return plugin.isProtocolSupport();
+ }
+
+ public Map getPortedPlayers() {
+ return Via.getManager().getPortedPlayers();
+ }
+}
diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaInjector.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaInjector.java
new file mode 100644
index 000000000..ef06a642e
--- /dev/null
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaInjector.java
@@ -0,0 +1,247 @@
+package us.myles.ViaVersion.bukkit.platform;
+
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.socket.SocketChannel;
+import org.bukkit.plugin.PluginDescriptionFile;
+import us.myles.ViaVersion.api.Pair;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.platform.ViaInjector;
+import us.myles.ViaVersion.bukkit.handlers.BukkitChannelInitializer;
+import us.myles.ViaVersion.bukkit.util.NMSUtil;
+import us.myles.ViaVersion.util.ConcurrentList;
+import us.myles.ViaVersion.util.ListWrapper;
+import us.myles.ViaVersion.util.ReflectionUtil;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+public class BukkitViaInjector implements ViaInjector {
+ private List injectedFutures = new ArrayList<>();
+ private List> injectedLists = new ArrayList<>();
+
+ @Override
+ public void inject() throws Exception {
+ try {
+ Object connection = getServerConnection();
+ if (connection == null) {
+ throw new Exception("We failed to find the core component 'ServerConnection', please file an issue on our GitHub.");
+ }
+ for (Field field : connection.getClass().getDeclaredFields()) {
+ field.setAccessible(true);
+ final Object value = field.get(connection);
+ if (value instanceof List) {
+ // Inject the list
+ List wrapper = new ListWrapper((List) value) {
+ @Override
+ public synchronized void handleAdd(Object o) {
+ synchronized (this) {
+ if (o instanceof ChannelFuture) {
+ try {
+ injectChannelFuture((ChannelFuture) o);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ };
+ injectedLists.add(new Pair<>(field, connection));
+ field.set(connection, wrapper);
+ // Iterate through current list
+ synchronized (wrapper) {
+ for (Object o : (List) value) {
+ if (o instanceof ChannelFuture) {
+ injectChannelFuture((ChannelFuture) o);
+ } else {
+ break; // not the right list.
+ }
+ }
+ }
+ }
+ }
+
+ } catch (Exception e) {
+ Via.getPlatform().getLogger().severe("Unable to inject ViaVersion, please post these details on our GitHub and ensure you're using a compatible server version.");
+ throw e;
+ }
+ }
+
+ private void injectChannelFuture(ChannelFuture future) throws Exception {
+ try {
+ ChannelHandler bootstrapAcceptor = future.channel().pipeline().first();
+ try {
+ ChannelInitializer oldInit = ReflectionUtil.get(bootstrapAcceptor, "childHandler", ChannelInitializer.class);
+ ChannelInitializer newInit = new BukkitChannelInitializer(oldInit);
+
+ ReflectionUtil.set(bootstrapAcceptor, "childHandler", newInit);
+ injectedFutures.add(future);
+ } catch (NoSuchFieldException e) {
+ // let's find who to blame!
+ ClassLoader cl = bootstrapAcceptor.getClass().getClassLoader();
+ if (cl.getClass().getName().equals("org.bukkit.plugin.java.PluginClassLoader")) {
+ PluginDescriptionFile yaml = ReflectionUtil.get(cl, "description", PluginDescriptionFile.class);
+ throw new Exception("Unable to inject, due to " + bootstrapAcceptor.getClass().getName() + ", try without the plugin " + yaml.getName() + "?");
+ } else {
+ throw new Exception("Unable to find core component 'childHandler', please check your plugins. issue: " + bootstrapAcceptor.getClass().getName());
+ }
+
+ }
+ } catch (Exception e) {
+ Via.getPlatform().getLogger().severe("We failed to inject ViaVersion, have you got late-bind enabled with something else?");
+ throw e;
+ }
+ }
+
+ @Override
+ public void uninject() {
+ // TODO: Uninject from players currently online to prevent protocol lib issues.
+ for (ChannelFuture future : injectedFutures) {
+ ChannelHandler bootstrapAcceptor = future.channel().pipeline().first();
+ try {
+ ChannelInitializer oldInit = ReflectionUtil.get(bootstrapAcceptor, "childHandler", ChannelInitializer.class);
+ if (oldInit instanceof BukkitChannelInitializer) {
+ ReflectionUtil.set(bootstrapAcceptor, "childHandler", ((BukkitChannelInitializer) oldInit).getOriginal());
+ }
+ } catch (Exception e) {
+ System.out.println("Failed to remove injection handler, reload won't work with connections, please reboot!");
+ }
+ }
+ injectedFutures.clear();
+
+ for (Pair pair : injectedLists) {
+ try {
+ Object o = pair.getKey().get(pair.getValue());
+ if (o instanceof ListWrapper) {
+ pair.getKey().set(pair.getValue(), ((ListWrapper) o).getOriginalList());
+ }
+ } catch (IllegalAccessException e) {
+ System.out.println("Failed to remove injection, reload won't work with connections, please reboot!");
+ }
+ }
+
+ injectedLists.clear();
+ }
+
+ @Override
+ public int getServerProtocolVersion() throws Exception {
+ try {
+ Class> serverClazz = NMSUtil.nms("MinecraftServer");
+ Object server = ReflectionUtil.invokeStatic(serverClazz, "getServer");
+ Class> pingClazz = NMSUtil.nms("ServerPing");
+ Object ping = null;
+ // Search for ping method
+ for (Field f : serverClazz.getDeclaredFields()) {
+ if (f.getType() != null) {
+ if (f.getType().getSimpleName().equals("ServerPing")) {
+ f.setAccessible(true);
+ ping = f.get(server);
+ }
+ }
+ }
+ if (ping != null) {
+ Object serverData = null;
+ for (Field f : pingClazz.getDeclaredFields()) {
+ if (f.getType() != null) {
+ if (f.getType().getSimpleName().endsWith("ServerData")) {
+ f.setAccessible(true);
+ serverData = f.get(ping);
+ }
+ }
+ }
+ if (serverData != null) {
+ int protocolVersion = -1;
+ for (Field f : serverData.getClass().getDeclaredFields()) {
+ if (f.getType() != null) {
+ if (f.getType() == int.class) {
+ f.setAccessible(true);
+ protocolVersion = (int) f.get(serverData);
+ }
+ }
+ }
+ if (protocolVersion != -1) {
+ return protocolVersion;
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new Exception("Failed to get server", e);
+ }
+ throw new Exception("Failed to get server");
+ }
+
+ @Override
+ public String getEncoderName() {
+ return "encoder";
+ }
+
+ @Override
+ public String getDecoderName() {
+ return "decoder";
+ }
+
+ public static Object getServerConnection() throws Exception {
+ Class> serverClazz = NMSUtil.nms("MinecraftServer");
+ Object server = ReflectionUtil.invokeStatic(serverClazz, "getServer");
+ Object connection = null;
+ for (Method m : serverClazz.getDeclaredMethods()) {
+ if (m.getReturnType() != null) {
+ if (m.getReturnType().getSimpleName().equals("ServerConnection")) {
+ if (m.getParameterTypes().length == 0) {
+ connection = m.invoke(server);
+ }
+ }
+ }
+ }
+ return connection;
+ }
+
+ public static void patchLists() throws Exception {
+ Object connection = getServerConnection();
+ if (connection == null) {
+ Via.getPlatform().getLogger().warning("We failed to find the core component 'ServerConnection', please file an issue on our GitHub.");
+ return;
+ }
+ for (Field field : connection.getClass().getDeclaredFields()) {
+ field.setAccessible(true);
+ final Object value = field.get(connection);
+ if (value instanceof List) {
+ if (!(value instanceof ConcurrentList)) {
+ ConcurrentList list = new ConcurrentList();
+ list.addAll((List) value);
+ field.set(connection, list);
+ }
+ }
+ }
+ }
+
+ public static boolean isBinded() {
+ try {
+ Object connection = getServerConnection();
+ if (connection == null) {
+ return false;
+ }
+ for (Field field : connection.getClass().getDeclaredFields()) {
+ field.setAccessible(true);
+ final Object value = field.get(connection);
+ if (value instanceof List) {
+ // Inject the list
+ synchronized (value) {
+ for (Object o : (List) value) {
+ if (o instanceof ChannelFuture) {
+ return true;
+ } else {
+ break; // not the right list.
+ }
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ }
+ return false;
+ }
+}
diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaLoader.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaLoader.java
new file mode 100644
index 000000000..28b6f23cf
--- /dev/null
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaLoader.java
@@ -0,0 +1,92 @@
+package us.myles.ViaVersion.bukkit.platform;
+
+import lombok.AllArgsConstructor;
+import org.bukkit.Bukkit;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerQuitEvent;
+import us.myles.ViaVersion.ViaVersionPlugin;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.api.minecraft.item.Item;
+import us.myles.ViaVersion.api.platform.ViaPlatformLoader;
+import us.myles.ViaVersion.bukkit.listeners.UpdateListener;
+import us.myles.ViaVersion.bukkit.listeners.protocol1_9to1_8.*;
+import us.myles.ViaVersion.bukkit.providers.BukkitViaBulkChunkTranslator;
+import us.myles.ViaVersion.bukkit.providers.BukkitViaMovementTransmitter;
+import us.myles.ViaVersion.protocols.base.ProtocolInfo;
+import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
+import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.HandItemProvider;
+import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
+
+import java.util.UUID;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+@AllArgsConstructor
+public class BukkitViaLoader implements ViaPlatformLoader {
+ private ViaVersionPlugin plugin;
+
+ @Override
+ public void load() {
+ // Update Listener
+ Bukkit.getPluginManager().registerEvents(new UpdateListener(), plugin);
+
+ /* Base Protocol */
+ final ViaVersionPlugin plugin = (ViaVersionPlugin) Bukkit.getPluginManager().getPlugin("ViaVersion");
+
+ Bukkit.getPluginManager().registerEvents(new Listener() {
+ @EventHandler
+ public void onPlayerQuit(PlayerQuitEvent e) {
+ Via.getManager().removePortedClient(e.getPlayer().getUniqueId());
+ }
+ }, plugin);
+
+ /* 1.9 client to 1.8 server */
+
+ new ArmorListener(plugin).register();
+ new CommandBlockListener(plugin).register();
+ new DeathListener(plugin).register();
+ new BlockListener(plugin).register();
+
+ if (Bukkit.getVersion().toLowerCase().contains("paper") || Bukkit.getVersion().toLowerCase().contains("taco")) {
+ plugin.getLogger().info("Enabling PaperSpigot/TacoSpigot patch: Fixes block placement.");
+ new PaperPatch(plugin).register();
+ }
+ if (plugin.getConf().isItemCache()) {
+ new HandItemCache().runTaskTimerAsynchronously(plugin, 2L, 2L); // Updates player's items :)
+ HandItemCache.CACHE = true;
+ }
+
+ /* Providers */
+ Via.getManager().getProviders().use(BulkChunkTranslatorProvider.class, new BukkitViaBulkChunkTranslator());
+ Via.getManager().getProviders().use(MovementTransmitterProvider.class, new BukkitViaMovementTransmitter());
+ Via.getManager().getProviders().use(HandItemProvider.class, new HandItemProvider() {
+ @Override
+ public Item getHandItem(final UserConnection info) {
+ if (HandItemCache.CACHE) {
+ return HandItemCache.getHandItem(info.get(ProtocolInfo.class).getUuid());
+ } else {
+ try {
+ return Bukkit.getScheduler().callSyncMethod(Bukkit.getPluginManager().getPlugin("ViaVersion"), new Callable- () {
+ @Override
+ public Item call() throws Exception {
+ UUID playerUUID = info.get(ProtocolInfo.class).getUuid();
+ if (Bukkit.getPlayer(playerUUID) != null) {
+ return HandItemCache.convert(Bukkit.getPlayer(playerUUID).getItemInHand());
+ }
+ return null;
+ }
+ }).get(10, TimeUnit.SECONDS);
+ } catch (Exception e) {
+ System.out.println("Error fetching hand item: " + e.getClass().getName());
+ if (Via.getManager().isDebug())
+ e.printStackTrace();
+ return null;
+ }
+ }
+ }
+ });
+
+ }
+}
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/ClientChunks.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/providers/BukkitViaBulkChunkTranslator.java
similarity index 62%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/ClientChunks.java
rename to bukkit/src/main/java/us/myles/ViaVersion/bukkit/providers/BukkitViaBulkChunkTranslator.java
index bb0395ece..fd4a3a271 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/ClientChunks.java
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/providers/BukkitViaBulkChunkTranslator.java
@@ -1,59 +1,46 @@
-package us.myles.ViaVersion.protocols.protocol1_9to1_8.storage;
+package us.myles.ViaVersion.bukkit.providers;
import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import lombok.Getter;
-import org.bukkit.Bukkit;
-import us.myles.ViaVersion.api.ViaVersion;
-import us.myles.ViaVersion.api.data.StoredObject;
-import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.ViaVersionPlugin;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.bukkit.util.NMSUtil;
+import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
+import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks;
import us.myles.ViaVersion.util.ReflectionUtil;
import java.lang.reflect.Method;
import java.util.List;
-import java.util.Set;
import java.util.logging.Level;
-@Getter
-public class ClientChunks extends StoredObject {
+public class BukkitViaBulkChunkTranslator extends BulkChunkTranslatorProvider {
// Reflection
private static ReflectionUtil.ClassReflection mapChunkBulkRef;
private static ReflectionUtil.ClassReflection mapChunkRef;
private static Method obfuscateRef;
- private static Class> worldRef;
static {
try {
- mapChunkBulkRef = new ReflectionUtil.ClassReflection(ReflectionUtil.nms("PacketPlayOutMapChunkBulk"));
- mapChunkRef = new ReflectionUtil.ClassReflection(ReflectionUtil.nms("PacketPlayOutMapChunk"));
- if (ViaVersion.getInstance().isSpigot()) {
- obfuscateRef = Class.forName("org.spigotmc.AntiXray").getMethod("obfuscate", int.class, int.class, int.class, byte[].class, ReflectionUtil.nms("World"));
- worldRef = ReflectionUtil.nms("World");
+ mapChunkBulkRef = new ReflectionUtil.ClassReflection(NMSUtil.nms("PacketPlayOutMapChunkBulk"));
+ mapChunkRef = new ReflectionUtil.ClassReflection(NMSUtil.nms("PacketPlayOutMapChunk"));
+ if (((ViaVersionPlugin) Via.getPlatform()).isSpigot()) {
+ obfuscateRef = Class.forName("org.spigotmc.AntiXray").getMethod("obfuscate", int.class, int.class, int.class, byte[].class, NMSUtil.nms("World"));
}
+ } catch (ClassNotFoundException e) {
+ // Ignore as server is probably 1.9+
} catch (Exception e) {
- Bukkit.getLogger().log(Level.WARNING, "Failed to initialise chunks reflection", e);
+ Via.getPlatform().getLogger().log(Level.WARNING, "Failed to initialise chunks reflection", e);
}
}
- private final Set
loadedChunks = Sets.newConcurrentHashSet();
- private final Set bulkChunks = Sets.newConcurrentHashSet();
-
- public ClientChunks(UserConnection user) {
- super(user);
- }
-
- private static long toLong(int msw, int lsw) {
- return ((long) msw << 32) + lsw - -2147483648L;
- }
-
- public List transformMapChunkBulk(Object packet) {
+ @Override
+ public List transformMapChunkBulk(Object packet, ClientChunks clientChunks) {
List list = Lists.newArrayList();
try {
int[] xcoords = mapChunkBulkRef.getFieldValue("a", packet, int[].class);
int[] zcoords = mapChunkBulkRef.getFieldValue("b", packet, int[].class);
Object[] chunkMaps = mapChunkBulkRef.getFieldValue("c", packet, Object[].class);
- if (ViaVersion.getConfig().isAntiXRay() && ViaVersion.getInstance().isSpigot()) { //Spigot anti-xray patch
+ if (Via.getConfig().isAntiXRay() && ((ViaVersionPlugin) Via.getPlatform()).isSpigot()) { //Spigot anti-xray patch
try {
Object world = mapChunkBulkRef.getFieldValue("world", packet, Object.class);
@@ -79,12 +66,22 @@ public class ClientChunks extends StoredObject {
mapChunkRef.setFieldValue("b", chunkPacket, z);
mapChunkRef.setFieldValue("c", chunkPacket, chunkMap);
mapChunkRef.setFieldValue("d", chunkPacket, true); // Chunk bulk chunks are always ground-up
- bulkChunks.add(toLong(x, z)); // Store for later
+ clientChunks.getBulkChunks().add(ClientChunks.toLong(x, z)); // Store for later
list.add(chunkPacket);
}
} catch (Exception e) {
- Bukkit.getLogger().log(Level.WARNING, "Failed to transform chunks bulk", e);
+ Via.getPlatform().getLogger().log(Level.WARNING, "Failed to transform chunks bulk", e);
}
return list;
}
+
+ @Override
+ public boolean isFiltered(Class> packetClass) {
+ return packetClass.getName().endsWith("PacketPlayOutMapChunkBulk");
+ }
+
+ @Override
+ public boolean isPacketLevel() {
+ return false;
+ }
}
diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/providers/BukkitViaMovementTransmitter.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/providers/BukkitViaMovementTransmitter.java
new file mode 100644
index 000000000..4c9147d98
--- /dev/null
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/providers/BukkitViaMovementTransmitter.java
@@ -0,0 +1,103 @@
+package us.myles.ViaVersion.bukkit.providers;
+
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.bukkit.util.NMSUtil;
+import us.myles.ViaVersion.protocols.base.ProtocolInfo;
+import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
+import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.MovementTracker;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class BukkitViaMovementTransmitter extends MovementTransmitterProvider {
+ private static boolean USE_NMS = true;
+ // Used for packet mode
+ private Object idlePacket;
+ private Object idlePacket2;
+ // Use for nms
+ private Method getHandle;
+ private Field connection;
+ private Method handleFlying;
+
+ public BukkitViaMovementTransmitter() {
+ USE_NMS = Via.getConfig().isNMSPlayerTicking();
+
+ Class> idlePacketClass;
+ try {
+ idlePacketClass = NMSUtil.nms("PacketPlayInFlying");
+ } catch (ClassNotFoundException e) {
+ return; // We'll hope this is 1.9.4+
+ }
+ try {
+ idlePacket = idlePacketClass.newInstance();
+ idlePacket2 = idlePacketClass.newInstance();
+
+ Field flying = idlePacketClass.getDeclaredField("f");
+ flying.setAccessible(true);
+
+ flying.set(idlePacket2, true);
+ } catch (NoSuchFieldException | InstantiationException | IllegalArgumentException | IllegalAccessException e) {
+ throw new RuntimeException("Couldn't make player idle packet, help!", e);
+ }
+ if (USE_NMS) {
+ try {
+ getHandle = NMSUtil.obc("entity.CraftPlayer").getDeclaredMethod("getHandle");
+ } catch (NoSuchMethodException | ClassNotFoundException e) {
+ throw new RuntimeException("Couldn't find CraftPlayer", e);
+ }
+
+ try {
+ connection = NMSUtil.nms("EntityPlayer").getDeclaredField("playerConnection");
+ } catch (NoSuchFieldException | ClassNotFoundException e) {
+ throw new RuntimeException("Couldn't find Player Connection", e);
+ }
+
+ try {
+ handleFlying = NMSUtil.nms("PlayerConnection").getDeclaredMethod("a", idlePacketClass);
+ } catch (NoSuchMethodException | ClassNotFoundException e) {
+ throw new RuntimeException("Couldn't find CraftPlayer", e);
+ }
+ }
+ }
+
+ @Override
+ public Object getFlyingPacket() {
+ if (idlePacket == null)
+ throw new NullPointerException("Could not locate flying packet");
+ return idlePacket2;
+ }
+
+ @Override
+ public Object getGroundPacket() {
+ if (idlePacket == null)
+ throw new NullPointerException("Could not locate flying packet");
+ return idlePacket;
+ }
+
+ @Override
+ public void sendPlayer(UserConnection info) {
+ if (USE_NMS) {
+ Player player = Bukkit.getPlayer(info.get(ProtocolInfo.class).getUuid());
+ if (player != null) {
+ try {
+ // Tick player
+ Object entityPlayer = getHandle.invoke(player);
+ Object pc = connection.get(entityPlayer);
+ if (pc != null) {
+ handleFlying.invoke(pc, (info.get(MovementTracker.class).isGround() ? idlePacket2 : idlePacket));
+ // Tick world
+ info.get(MovementTracker.class).incrementIdlePacket();
+ }
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ e.printStackTrace();
+ }
+ }
+ } else {
+ super.sendPlayer(info);
+ }
+ }
+}
diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/util/NMSUtil.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/util/NMSUtil.java
new file mode 100644
index 000000000..d01884ecb
--- /dev/null
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/util/NMSUtil.java
@@ -0,0 +1,20 @@
+package us.myles.ViaVersion.bukkit.util;
+
+import org.bukkit.Bukkit;
+
+public class NMSUtil {
+ private static String BASE = Bukkit.getServer().getClass().getPackage().getName();
+ private static String NMS = BASE.replace("org.bukkit.craftbukkit", "net.minecraft.server");
+
+ public static Class> nms(String className) throws ClassNotFoundException {
+ return Class.forName(NMS + "." + className);
+ }
+
+ public static Class> obc(String className) throws ClassNotFoundException {
+ return Class.forName(BASE + "." + className);
+ }
+
+ public static String getVersion() {
+ return BASE.substring(BASE.lastIndexOf('.') + 1);
+ }
+}
diff --git a/src/main/java/us/myles/ViaVersion/util/ProtocolSupportUtil.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/util/ProtocolSupportUtil.java
similarity index 96%
rename from src/main/java/us/myles/ViaVersion/util/ProtocolSupportUtil.java
rename to bukkit/src/main/java/us/myles/ViaVersion/bukkit/util/ProtocolSupportUtil.java
index 66458a0a5..f740893f8 100644
--- a/src/main/java/us/myles/ViaVersion/util/ProtocolSupportUtil.java
+++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/util/ProtocolSupportUtil.java
@@ -1,4 +1,4 @@
-package us.myles.ViaVersion.util;
+package us.myles.ViaVersion.bukkit.util;
import org.bukkit.entity.Player;
diff --git a/src/main/resources/plugin.yml b/bukkit/src/main/resources/plugin.yml
similarity index 73%
rename from src/main/resources/plugin.yml
rename to bukkit/src/main/resources/plugin.yml
index 764d152a8..d2cf3947c 100644
--- a/src/main/resources/plugin.yml
+++ b/bukkit/src/main/resources/plugin.yml
@@ -2,10 +2,11 @@ name: ViaVersion
main: us.myles.ViaVersion.ViaVersionPlugin
authors: [_MylesC, Matsv]
version: ${project.version}
+description: Allow newer Minecraft versions to connect to an older server version.
load: postworld
loadbefore: [ProtocolLib, ProxyPipe, SpigotLib, SkinRestorer]
softdepend: [ProtocolSupport, PacketListenerApi]
commands:
viaversion:
description: Shows ViaVersion Version and more.
- aliases: [viaver]
\ No newline at end of file
+ aliases: [viaver, vvbukkit]
\ No newline at end of file
diff --git a/bungee/pom.xml b/bungee/pom.xml
new file mode 100644
index 000000000..75dfd9844
--- /dev/null
+++ b/bungee/pom.xml
@@ -0,0 +1,43 @@
+
+
+
+ viaversion-parent
+ us.myles
+ 1.0.0-ALPHA-modules
+
+ 4.0.0
+
+ viaversion-bungee
+
+
+
+
+ .
+ true
+ src/main/resources/
+
+ *
+
+
+
+
+
+
+
+
+ net.md-5
+ bungeecord-api
+ 1.10-SNAPSHOT
+ provided
+
+
+
+
+ us.myles
+ viaversion-common
+ 1.0.0-ALPHA-modules
+
+
+
\ No newline at end of file
diff --git a/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java b/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java
new file mode 100644
index 000000000..544f4936a
--- /dev/null
+++ b/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java
@@ -0,0 +1,191 @@
+package us.myles.ViaVersion;
+
+import com.google.gson.JsonObject;
+import net.md_5.bungee.api.ProxyServer;
+import net.md_5.bungee.api.chat.TextComponent;
+import net.md_5.bungee.api.connection.ProxiedPlayer;
+import net.md_5.bungee.api.event.PlayerDisconnectEvent;
+import net.md_5.bungee.api.event.ServerConnectEvent;
+import net.md_5.bungee.api.plugin.Listener;
+import net.md_5.bungee.api.plugin.Plugin;
+import net.md_5.bungee.event.EventHandler;
+import us.myles.ViaVersion.api.Pair;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.ViaAPI;
+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.api.platform.TaskId;
+import us.myles.ViaVersion.api.platform.ViaPlatform;
+import us.myles.ViaVersion.api.protocol.Protocol;
+import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
+import us.myles.ViaVersion.bungee.commands.BungeeCommand;
+import us.myles.ViaVersion.bungee.commands.BungeeCommandHandler;
+import us.myles.ViaVersion.bungee.commands.BungeeCommandSender;
+import us.myles.ViaVersion.bungee.platform.*;
+import us.myles.ViaVersion.bungee.service.ProtocolDetectorService;
+import us.myles.ViaVersion.bungee.storage.BungeeStorage;
+import us.myles.ViaVersion.dump.PluginInfo;
+import us.myles.ViaVersion.protocols.base.ProtocolInfo;
+import us.myles.ViaVersion.util.GsonUtil;
+import us.myles.ViaVersion.util.ReflectionUtil;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+public class BungeePlugin extends Plugin implements ViaPlatform, Listener {
+
+ private BungeeViaAPI api;
+ private BungeeConfigAPI config;
+ private BungeeCommandHandler commandHandler;
+
+ @Override
+ public void onLoad() {
+ api = new BungeeViaAPI();
+ config = new BungeeConfigAPI(getDataFolder());
+ commandHandler = new BungeeCommandHandler();
+ ProxyServer.getInstance().getPluginManager().registerCommand(this, new BungeeCommand(commandHandler));
+ // Init platform
+ Via.init(ViaManager.builder()
+ .platform(this)
+ .injector(new BungeeViaInjector())
+ .loader(new BungeeViaLoader(this))
+ .commandHandler(commandHandler)
+ .build());
+ }
+
+ @Override
+ public void onEnable() {
+ // Inject
+ Via.getManager().init();
+ }
+
+ @Override
+ public String getPlatformName() {
+ return "BungeeCord";
+ }
+
+ @Override
+ public String getPluginVersion() {
+ return getDescription().getVersion();
+ }
+
+ @Override
+ public TaskId runAsync(Runnable runnable) {
+ return new BungeeTaskId(getProxy().getScheduler().runAsync(this, runnable).getId());
+ }
+
+ @Override
+ public TaskId runSync(Runnable runnable) {
+ return runAsync(runnable);
+ }
+
+ @Override
+ public TaskId runRepeatingSync(Runnable runnable, Long ticks) {
+ return new BungeeTaskId(getProxy().getScheduler().schedule(this, runnable, 0, ticks * 50, TimeUnit.MILLISECONDS).getId());
+ }
+
+ @Override
+ public void cancelTask(TaskId taskId) {
+ if (taskId == null) return;
+ if (taskId.getObject() == null) return;
+ if (taskId instanceof BungeeTaskId) {
+ getProxy().getScheduler().cancel((Integer) taskId.getObject());
+ }
+ }
+
+ @Override
+ public ViaCommandSender[] getOnlinePlayers() {
+ ViaCommandSender[] array = new ViaCommandSender[getProxy().getPlayers().size()];
+ int i = 0;
+ for (ProxiedPlayer player : getProxy().getPlayers()) {
+ array[i++] = new BungeeCommandSender(player);
+ }
+ return array;
+ }
+
+ @Override
+ public void sendMessage(UUID uuid, String message) {
+ getProxy().getPlayer(uuid).sendMessage(TextComponent.fromLegacyText(message));
+ }
+
+ @Override
+ public boolean kickPlayer(UUID uuid, String message) {
+ if (getProxy().getPlayer(uuid) != null) {
+ getProxy().getPlayer(uuid).disconnect(TextComponent.fromLegacyText(message));
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isPluginEnabled() {
+ return true;
+ }
+
+ @Override
+ public ViaAPI getApi() {
+ return api;
+ }
+
+ @Override
+ public BungeeConfigAPI getConf() {
+ return config;
+ }
+
+ @Override
+ public ConfigurationProvider getConfigurationProvider() {
+ return config;
+ }
+
+ @Override
+ public void onReload() {
+ // Injector prints a message <3
+ }
+
+ @Override
+ public JsonObject getDump() {
+ JsonObject platformSpecific = new JsonObject();
+
+ List plugins = new ArrayList<>();
+ for (Plugin p : ProxyServer.getInstance().getPluginManager().getPlugins())
+ plugins.add(new PluginInfo(true, p.getDescription().getName(), p.getDescription().getVersion(), p.getDescription().getMain(), Arrays.asList(p.getDescription().getAuthor())));
+
+ platformSpecific.add("plugins", GsonUtil.getGson().toJsonTree(plugins));
+ platformSpecific.add("servers", GsonUtil.getGson().toJsonTree(ProtocolDetectorService.getDetectedIds()));
+ return platformSpecific;
+ }
+
+ @EventHandler
+ public void onQuit(PlayerDisconnectEvent e) {
+ Via.getManager().removePortedClient(e.getPlayer().getUniqueId());
+ }
+
+ // Set the handshake version every time someone connects to any server
+ @EventHandler
+ public void onServerConnect(ServerConnectEvent e) throws NoSuchFieldException, IllegalAccessException {
+ UserConnection user = Via.getManager().getConnection(e.getPlayer().getUniqueId());
+ if (!user.has(BungeeStorage.class)) {
+ user.put(new BungeeStorage(user, e.getPlayer()));
+ }
+
+ int protocolId = ProtocolDetectorService.getProtocolId(e.getTarget().getName());
+ List> protocols = ProtocolRegistry.getProtocolPath(user.get(ProtocolInfo.class).getProtocolVersion(), protocolId);
+
+ // Check if ViaVersion can support that version
+ try {
+ Object pendingConnection = ReflectionUtil.invoke(e.getPlayer(), "getPendingConnection");
+ Object handshake = ReflectionUtil.invoke(pendingConnection, "getHandshake");
+ Method setProtocol = handshake.getClass().getDeclaredMethod("setProtocolVersion", int.class);
+ setProtocol.invoke(handshake, protocols == null ? user.get(ProtocolInfo.class).getProtocolVersion() : protocolId);
+ } catch (NoSuchMethodException | InvocationTargetException e1) {
+ e1.printStackTrace();
+ }
+ }
+
+}
diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/commands/BungeeCommand.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/commands/BungeeCommand.java
new file mode 100644
index 000000000..bdb4cbd51
--- /dev/null
+++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/commands/BungeeCommand.java
@@ -0,0 +1,24 @@
+package us.myles.ViaVersion.bungee.commands;
+
+import net.md_5.bungee.api.CommandSender;
+import net.md_5.bungee.api.plugin.Command;
+import net.md_5.bungee.api.plugin.TabExecutor;
+
+public class BungeeCommand extends Command implements TabExecutor{
+ private final BungeeCommandHandler handler;
+
+ public BungeeCommand(BungeeCommandHandler handler) {
+ super("viaversion", "", "viaver", "vvbungee"); // The CommandHandler will handle the permission
+ this.handler = handler;
+ }
+
+ @Override
+ public void execute(CommandSender commandSender, String[] strings) {
+ handler.onCommand(new BungeeCommandSender(commandSender), strings);
+ }
+
+ @Override
+ public Iterable onTabComplete(CommandSender commandSender, String[] strings) {
+ return handler.onTabComplete(new BungeeCommandSender(commandSender), strings);
+ }
+}
diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/commands/BungeeCommandHandler.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/commands/BungeeCommandHandler.java
new file mode 100644
index 000000000..44c7c5eb0
--- /dev/null
+++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/commands/BungeeCommandHandler.java
@@ -0,0 +1,15 @@
+package us.myles.ViaVersion.bungee.commands;
+
+import us.myles.ViaVersion.bungee.commands.subs.ProbeSubCmd;
+import us.myles.ViaVersion.commands.ViaCommandHandler;
+
+public class BungeeCommandHandler extends ViaCommandHandler {
+ public BungeeCommandHandler() {
+ try {
+ registerSubCommand(new ProbeSubCmd());
+ } catch (Exception e) {
+ System.out.println("Failed to register Bungee subcommands");
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/commands/BungeeCommandSender.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/commands/BungeeCommandSender.java
new file mode 100644
index 000000000..d80a8702e
--- /dev/null
+++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/commands/BungeeCommandSender.java
@@ -0,0 +1,38 @@
+package us.myles.ViaVersion.bungee.commands;
+
+import lombok.AllArgsConstructor;
+import net.md_5.bungee.api.CommandSender;
+import net.md_5.bungee.api.chat.TextComponent;
+import net.md_5.bungee.api.connection.ProxiedPlayer;
+import us.myles.ViaVersion.api.command.ViaCommandSender;
+
+import java.util.UUID;
+
+@AllArgsConstructor
+public class BungeeCommandSender implements ViaCommandSender {
+ private CommandSender sender;
+
+ @Override
+ public boolean hasPermission(String permission) {
+ return sender.hasPermission(permission);
+ }
+
+ @Override
+ public void sendMessage(String msg) {
+ sender.sendMessage(new TextComponent(msg));
+ }
+
+ @Override
+ public UUID getUUID() {
+ if (sender instanceof ProxiedPlayer) {
+ return ((ProxiedPlayer) sender).getUniqueId();
+ } else {
+ return UUID.fromString(getName());
+ }
+ }
+
+ @Override
+ public String getName() {
+ return sender.getName();
+ }
+}
diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/commands/subs/ProbeSubCmd.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/commands/subs/ProbeSubCmd.java
new file mode 100644
index 000000000..fda215417
--- /dev/null
+++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/commands/subs/ProbeSubCmd.java
@@ -0,0 +1,28 @@
+package us.myles.ViaVersion.bungee.commands.subs;
+
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.command.ViaCommandSender;
+import us.myles.ViaVersion.api.command.ViaSubCommand;
+import us.myles.ViaVersion.bungee.platform.BungeeConfigAPI;
+import us.myles.ViaVersion.bungee.service.ProtocolDetectorService;
+
+public class ProbeSubCmd extends ViaSubCommand {
+ @Override
+ public String name() {
+ return "probe";
+ }
+
+ @Override
+ public String description() {
+ return "Forces ViaVersion to scan server protocol versions " +
+ (((BungeeConfigAPI) Via.getConfig()).getBungeePingInterval() == -1 ?
+ "" : "(Also happens at an interval)");
+ }
+
+ @Override
+ public boolean execute(ViaCommandSender sender, String[] args) {
+ ProtocolDetectorService.getInstance().run();
+ sendMessage(sender, "&6Started searching for protocol versions");
+ return true;
+ }
+}
diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeChannelInitializer.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeChannelInitializer.java
new file mode 100644
index 000000000..ceea247f9
--- /dev/null
+++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeChannelInitializer.java
@@ -0,0 +1,41 @@
+package us.myles.ViaVersion.bungee.handlers;
+
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.socket.SocketChannel;
+import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.api.protocol.ProtocolPipeline;
+
+import java.lang.reflect.Method;
+
+public class BungeeChannelInitializer extends ChannelInitializer {
+
+ private final ChannelInitializer original;
+ private Method method;
+
+ public BungeeChannelInitializer(ChannelInitializer oldInit) {
+ this.original = oldInit;
+ try {
+ this.method = ChannelInitializer.class.getDeclaredMethod("initChannel", Channel.class);
+ this.method.setAccessible(true);
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ protected void initChannel(SocketChannel socketChannel) throws Exception {
+ UserConnection info = new UserConnection(socketChannel);
+ // init protocol
+ new ProtocolPipeline(info);
+ // Add originals
+ this.method.invoke(this.original, socketChannel);
+ // Add our transformers
+ BungeeEncodeHandler encoder = new BungeeEncodeHandler(info);
+ BungeeDecodeHandler decoder = new BungeeDecodeHandler(info);
+
+ socketChannel.pipeline().addBefore("packet-encoder", "via-encoder", encoder);
+ socketChannel.pipeline().addBefore("packet-decoder", "via-decoder", decoder);
+
+ }
+}
diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeDecodeHandler.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeDecodeHandler.java
new file mode 100644
index 000000000..898df7d11
--- /dev/null
+++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeDecodeHandler.java
@@ -0,0 +1,79 @@
+package us.myles.ViaVersion.bungee.handlers;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToMessageDecoder;
+import us.myles.ViaVersion.api.PacketWrapper;
+import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.api.type.Type;
+import us.myles.ViaVersion.exception.CancelException;
+import us.myles.ViaVersion.packets.Direction;
+import us.myles.ViaVersion.protocols.base.ProtocolInfo;
+import us.myles.ViaVersion.util.PipelineUtil;
+
+import java.util.List;
+
+@ChannelHandler.Sharable
+public class BungeeDecodeHandler extends MessageToMessageDecoder {
+
+ private final UserConnection info;
+
+ public BungeeDecodeHandler(UserConnection info) {
+ this.info = info;
+ }
+
+ @Override
+ protected void decode(final ChannelHandlerContext ctx, ByteBuf bytebuf, List out) throws Exception {
+ // use transformers
+ if (bytebuf.readableBytes() > 0) {
+ // Ignore if pending disconnect
+ if (info.isPendingDisconnect()) {
+ return;
+ }
+ // Increment received
+ boolean second = info.incrementReceived();
+ // Check PPS
+ if (second) {
+ if (info.handlePPS())
+ return;
+ }
+
+ if (info.isActive()) {
+ // Handle ID
+ int id = Type.VAR_INT.read(bytebuf);
+ // Transform
+ ByteBuf newPacket = ctx.alloc().buffer();
+ try {
+ if (id == PacketWrapper.PASSTHROUGH_ID) {
+ newPacket.writeBytes(bytebuf);
+ } else {
+ PacketWrapper wrapper = new PacketWrapper(id, bytebuf, info);
+ ProtocolInfo protInfo = info.get(ProtocolInfo.class);
+ protInfo.getPipeline().transform(Direction.INCOMING, protInfo.getState(), wrapper);
+ wrapper.writeToBuffer(newPacket);
+ }
+
+ bytebuf.clear();
+ bytebuf = newPacket;
+ } catch (Exception e) {
+ // Clear Buffer
+ bytebuf.clear();
+ // Release Packet, be free!
+ newPacket.release();
+ throw e;
+ }
+ } else {
+ bytebuf.retain();
+ }
+
+ out.add(bytebuf);
+ }
+ }
+
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+ if (PipelineUtil.containsCause(cause, CancelException.class)) return;
+ super.exceptionCaught(ctx, cause);
+ }
+}
diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeEncodeHandler.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeEncodeHandler.java
new file mode 100644
index 000000000..8bc30020d
--- /dev/null
+++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeEncodeHandler.java
@@ -0,0 +1,140 @@
+package us.myles.ViaVersion.bungee.handlers;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToMessageEncoder;
+import net.md_5.bungee.api.connection.ProxiedPlayer;
+import us.myles.ViaVersion.api.PacketWrapper;
+import us.myles.ViaVersion.api.Pair;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.api.protocol.Protocol;
+import us.myles.ViaVersion.api.protocol.ProtocolPipeline;
+import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
+import us.myles.ViaVersion.api.type.Type;
+import us.myles.ViaVersion.bungee.service.ProtocolDetectorService;
+import us.myles.ViaVersion.bungee.storage.BungeeStorage;
+import us.myles.ViaVersion.bungee.util.BungeePipelineUtil;
+import us.myles.ViaVersion.exception.CancelException;
+import us.myles.ViaVersion.packets.Direction;
+import us.myles.ViaVersion.protocols.base.ProtocolInfo;
+import us.myles.ViaVersion.util.PipelineUtil;
+import us.myles.ViaVersion.util.ReflectionUtil;
+
+import java.util.List;
+
+@ChannelHandler.Sharable
+public class BungeeEncodeHandler extends MessageToMessageEncoder {
+ private final UserConnection info;
+ private boolean handledCompression = false;
+
+ public BungeeEncodeHandler(UserConnection info) {
+ this.info = info;
+ }
+
+
+ @Override
+ protected void encode(final ChannelHandlerContext ctx, ByteBuf bytebuf, List out) throws Exception {
+ if (bytebuf.readableBytes() == 0) {
+ throw new CancelException();
+ }
+ boolean needsCompress = false;
+ if (!handledCompression) {
+ if (ctx.pipeline().names().indexOf("compress") > ctx.pipeline().names().indexOf("via-encoder")) {
+ // Need to decompress this packet due to bad order
+ bytebuf = BungeePipelineUtil.decompress(ctx, bytebuf);
+ ChannelHandler encoder = ctx.pipeline().get("via-decoder");
+ ChannelHandler decoder = ctx.pipeline().get("via-encoder");
+ ctx.pipeline().remove(encoder);
+ ctx.pipeline().remove(decoder);
+ ctx.pipeline().addAfter("decompress", "via-decoder", encoder);
+ ctx.pipeline().addAfter("compress", "via-encoder", decoder);
+ needsCompress = true;
+ handledCompression = true;
+ }
+ }
+ // Increment sent
+ info.incrementSent();
+
+ if (info.isActive()) {
+ // Handle ID
+ int id = Type.VAR_INT.read(bytebuf);
+ // Transform
+ ByteBuf oldPacket = bytebuf.copy();
+ bytebuf.clear();
+
+ try {
+ PacketWrapper wrapper = new PacketWrapper(id, oldPacket, info);
+ ProtocolInfo protInfo = info.get(ProtocolInfo.class);
+ protInfo.getPipeline().transform(Direction.OUTGOING, protInfo.getState(), wrapper);
+ wrapper.writeToBuffer(bytebuf);
+ } catch (Exception e) {
+ bytebuf.clear();
+ throw e;
+ } finally {
+ oldPacket.release();
+ }
+ }
+
+ if (needsCompress) {
+ bytebuf = BungeePipelineUtil.compress(ctx, bytebuf);
+ }
+ out.add(bytebuf.retain());
+
+ checkServerChange();
+ }
+
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+ if (PipelineUtil.containsCause(cause, CancelException.class)) return;
+ super.exceptionCaught(ctx, cause);
+ }
+
+ public void checkServerChange() throws Exception {
+ if (info.has(BungeeStorage.class)) {
+ BungeeStorage storage = info.get(BungeeStorage.class);
+ ProxiedPlayer player = storage.getPlayer();
+
+ if (player.getServer() != null) {
+ if (player.getServer() != null && !player.getServer().getInfo().getName().equals(storage.getCurrentServer())) {
+ String serverName = player.getServer().getInfo().getName();
+
+ storage.setCurrentServer(serverName);
+
+ int protocolId = ProtocolDetectorService.getProtocolId(serverName);
+
+ UserConnection viaConnection = Via.getManager().getConnection(player.getUniqueId());
+ ProtocolInfo info = viaConnection.get(ProtocolInfo.class);
+ // Refresh the pipes
+ List> protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), protocolId);
+ ProtocolPipeline pipeline = viaConnection.get(ProtocolInfo.class).getPipeline();
+
+ viaConnection.clearStoredObjects();
+ pipeline.cleanPipes();
+
+ if (protocols != null)
+ for (Pair prot : protocols) {
+ pipeline.add(prot.getValue());
+ }
+
+ viaConnection.put(info);
+ viaConnection.put(storage);
+
+ viaConnection.setActive(protocols != null);
+
+ // Init all protocols TODO check if this can get moved up to the previous for loop, and doesn't require the pipeline to already exist.
+ for (Protocol protocol : pipeline.pipes()) {
+ protocol.init(viaConnection);
+ }
+
+ Object wrapper = ReflectionUtil.get(player, "ch", Object.class);
+ wrapper.getClass().getDeclaredMethod("setVersion", int.class).invoke(wrapper, protocolId);
+
+ Object entityMap = Class.forName("net.md_5.bungee.entitymap.EntityMap").getDeclaredMethod("getEntityMap", int.class).invoke(null, protocolId);
+ ReflectionUtil.set(player, "entityRewrite", entityMap);
+ }
+ }
+ }
+ }
+}
diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/listeners/UpdateListener.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/listeners/UpdateListener.java
new file mode 100644
index 000000000..b27ba57e8
--- /dev/null
+++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/listeners/UpdateListener.java
@@ -0,0 +1,18 @@
+package us.myles.ViaVersion.bungee.listeners;
+
+import net.md_5.bungee.api.event.PostLoginEvent;
+import net.md_5.bungee.api.plugin.Listener;
+import net.md_5.bungee.event.EventHandler;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.update.UpdateUtil;
+
+public class UpdateListener implements Listener {
+
+ @EventHandler
+ public void onJoin(PostLoginEvent e) {
+ if (e.getPlayer().hasPermission("viaversion.update")
+ && Via.getConfig().isCheckForUpdates()) {
+ UpdateUtil.sendUpdateMessage(e.getPlayer().getUniqueId());
+ }
+ }
+}
diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeBossBar.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeBossBar.java
new file mode 100644
index 000000000..538246ec2
--- /dev/null
+++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeBossBar.java
@@ -0,0 +1,34 @@
+package us.myles.ViaVersion.bungee.platform;
+
+import net.md_5.bungee.api.connection.ProxiedPlayer;
+import us.myles.ViaVersion.api.boss.BossBar;
+import us.myles.ViaVersion.api.boss.BossColor;
+import us.myles.ViaVersion.api.boss.BossStyle;
+import us.myles.ViaVersion.boss.CommonBoss;
+
+public class BungeeBossBar extends CommonBoss {
+
+ public BungeeBossBar(String title, float health, BossColor color, BossStyle style) {
+ super(title, health, color, style);
+ }
+
+
+ @Override
+ public BossBar addPlayer(ProxiedPlayer player) {
+ addPlayer(player.getUniqueId());
+ return this;
+ }
+
+ @Override
+ public BossBar addPlayers(ProxiedPlayer... players) {
+ for (ProxiedPlayer p : players)
+ addPlayer(p);
+ return this;
+ }
+
+ @Override
+ public BossBar removePlayer(ProxiedPlayer player) {
+ removePlayer(player.getUniqueId());
+ return this;
+ }
+}
diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java
new file mode 100644
index 000000000..fba410c80
--- /dev/null
+++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java
@@ -0,0 +1,232 @@
+package us.myles.ViaVersion.bungee.platform;
+
+import us.myles.ViaVersion.api.ViaVersionConfig;
+import us.myles.ViaVersion.api.protocol.ProtocolVersion;
+import us.myles.ViaVersion.bungee.providers.BungeeVersionProvider;
+import us.myles.ViaVersion.util.Config;
+
+import java.io.File;
+import java.util.*;
+
+public class BungeeConfigAPI extends Config implements ViaVersionConfig {
+ private static List UNSUPPORTED = Arrays.asList("nms-player-ticking", "item-cache", "anti-xray-patch");
+
+ public BungeeConfigAPI(File configFile) {
+ super(new File(configFile, "config.yml"));
+ }
+
+ @Override
+ protected void handleConfig(Map config) {
+ // Parse servers
+ Map servers;
+ if (!(config.get("bungee-servers") instanceof Map)) {
+ servers = new HashMap<>();
+ } else {
+ servers = (Map) config.get("bungee-servers");
+ }
+ // Convert any bad Protocol Ids
+ for (Map.Entry entry : new HashSet<>(servers.entrySet())) {
+ if (!(entry.getValue() instanceof Integer)) {
+ if (entry.getValue() instanceof String) {
+ ProtocolVersion found = ProtocolVersion.getClosest((String) entry.getValue());
+ if (found != null) {
+ servers.put(entry.getKey(), found.getId());
+ } else {
+ servers.remove(entry.getKey()); // Remove!
+ }
+ } else {
+ servers.remove(entry.getKey()); // Remove!
+ }
+ }
+ }
+ // Ensure default exists
+ if (!servers.containsKey("default")) {
+ servers.put("default", BungeeVersionProvider.getLowestSupportedVersion());
+ }
+ // Put back
+ config.put("bungee-servers", servers);
+ }
+
+ @Override
+ public List getUnsupportedOptions() {
+ return UNSUPPORTED;
+ }
+
+ public boolean isCheckForUpdates() {
+ return getBoolean("checkforupdates", true);
+ }
+
+ @Override
+ public boolean isPreventCollision() {
+ return getBoolean("prevent-collision", true);
+ }
+
+ @Override
+ public boolean isNewEffectIndicator() {
+ return getBoolean("use-new-effect-indicator", true);
+ }
+
+ @Override
+ public boolean isShowNewDeathMessages() {
+ return getBoolean("use-new-deathmessages", true);
+ }
+
+ @Override
+ public boolean isSuppressMetadataErrors() {
+ return getBoolean("suppress-metadata-errors", false);
+ }
+
+ @Override
+ public boolean isShieldBlocking() {
+ return getBoolean("shield-blocking", true);
+ }
+
+ @Override
+ public boolean isHologramPatch() {
+ return getBoolean("hologram-patch", false);
+ }
+
+ @Override
+ public boolean isBossbarPatch() {
+ return getBoolean("bossbar-patch", true);
+ }
+
+ @Override
+ public boolean isBossbarAntiflicker() {
+ return getBoolean("bossbar-anti-flicker", false);
+ }
+
+ @Override
+ public boolean isUnknownEntitiesSuppressed() {
+ return false;
+ }
+
+ @Override
+ public double getHologramYOffset() {
+ return getDouble("hologram-y", -0.96D);
+ }
+
+ @Override
+ public boolean isBlockBreakPatch() {
+ return false;
+ }
+
+ @Override
+ public int getMaxPPS() {
+ return getInt("max-pps", 800);
+ }
+
+ @Override
+ public String getMaxPPSKickMessage() {
+ return getString("max-pps-kick-msg", "Sending packets too fast? lag?");
+ }
+
+ @Override
+ public int getTrackingPeriod() {
+ return getInt("tracking-period", 6);
+ }
+
+ @Override
+ public int getWarningPPS() {
+ return getInt("tracking-warning-pps", 120);
+ }
+
+ @Override
+ public int getMaxWarnings() {
+ return getInt("tracking-max-warnings", 3);
+ }
+
+ @Override
+ public String getMaxWarningsKickMessage() {
+ return getString("tracking-max-kick-msg", "You are sending too many packets, :(");
+ }
+
+ @Override
+ public boolean isAntiXRay() {
+ return false;
+ }
+
+ @Override
+ public boolean isSendSupportedVersions() {
+ return getBoolean("send-supported-versions", false);
+ }
+
+ @Override
+ public boolean isStimulatePlayerTick() {
+ return getBoolean("simulate-pt", true);
+ }
+
+ @Override
+ public boolean isItemCache() {
+ return false;
+ }
+
+ @Override
+ public boolean isNMSPlayerTicking() {
+ return false;
+ }
+
+ @Override
+ public boolean isReplacePistons() {
+ return getBoolean("replace-pistons", false);
+ }
+
+ @Override
+ public int getPistonReplacementId() {
+ return getInt("replacement-piston-id", 0);
+ }
+
+ public boolean isAutoTeam() {
+ // Collision has to be enabled first
+ return isPreventCollision() && getBoolean("auto-team", true);
+ }
+
+ @Override
+ public boolean isForceJsonTransform() {
+ return getBoolean("force-json-transform", false);
+ }
+
+ @Override
+ public List getBlockedProtocols() {
+ return getIntegerList("block-protocols");
+ }
+
+ @Override
+ public String getBlockedDisconnectMsg() {
+ return getString("block-disconnect-msg", "You are using an unsupported Minecraft version!");
+ }
+
+ @Override
+ public String getReloadDisconnectMsg() {
+ return getString("reload-disconnect-msg", "Server reload, please rejoin!");
+ }
+
+ /**
+ * What is the interval for checking servers via ping
+ * -1 for disabled
+ *
+ * @return Ping interval in seconds
+ */
+ public int getBungeePingInterval() {
+ return getInt("bungee-ping-interval", 60);
+ }
+
+ /**
+ * Should the bungee ping be saved to the config on change.
+ *
+ * @return True if it should save
+ */
+ public boolean isBungeePingSave() {
+ return getBoolean("bungee-ping-save", true);
+ }
+
+ /**
+ * Get the listed server protocols in the config.
+ * default will be listed as default.
+ *
+ * @return Map of String, Integer
+ */
+ public Map getBungeeServerProtocols() {
+ return get("bungee-servers", Map.class, new HashMap<>());
+ }
+}
diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeTaskId.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeTaskId.java
new file mode 100644
index 000000000..cde0c6098
--- /dev/null
+++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeTaskId.java
@@ -0,0 +1,11 @@
+package us.myles.ViaVersion.bungee.platform;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import us.myles.ViaVersion.api.platform.TaskId;
+
+@Getter
+@AllArgsConstructor
+public class BungeeTaskId implements TaskId {
+ private Integer object;
+}
diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaAPI.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaAPI.java
new file mode 100644
index 000000000..51b7a9c3e
--- /dev/null
+++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaAPI.java
@@ -0,0 +1,78 @@
+package us.myles.ViaVersion.bungee.platform;
+
+import io.netty.buffer.ByteBuf;
+import lombok.NonNull;
+import net.md_5.bungee.api.connection.ProxiedPlayer;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.ViaAPI;
+import us.myles.ViaVersion.api.boss.BossBar;
+import us.myles.ViaVersion.api.boss.BossColor;
+import us.myles.ViaVersion.api.boss.BossStyle;
+import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
+import us.myles.ViaVersion.protocols.base.ProtocolInfo;
+
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.UUID;
+
+public class BungeeViaAPI implements ViaAPI {
+ @Override
+ public int getPlayerVersion(@NonNull ProxiedPlayer player) {
+ if (!isPorted(player.getUniqueId()))
+ return ProtocolRegistry.SERVER_PROTOCOL;
+ return getPortedPlayers().get(player.getUniqueId()).get(ProtocolInfo.class).getProtocolVersion();
+ }
+
+ @Override
+ public int getPlayerVersion(@NonNull UUID uuid) {
+ if (!isPorted(uuid))
+ return ProtocolRegistry.SERVER_PROTOCOL;
+ return getPortedPlayers().get(uuid).get(ProtocolInfo.class).getProtocolVersion();
+ }
+
+ @Override
+ public boolean isPorted(UUID playerUUID) {
+ return getPortedPlayers().containsKey(playerUUID);
+ }
+
+ @Override
+ public String getVersion() {
+ return Via.getPlatform().getPluginVersion();
+ }
+
+ @Override
+ public void sendRawPacket(UUID uuid, ByteBuf packet) throws IllegalArgumentException {
+ if (!isPorted(uuid)) throw new IllegalArgumentException("This player is not controlled by ViaVersion!");
+ UserConnection ci = getPortedPlayers().get(uuid);
+ ci.sendRawPacket(packet);
+ }
+
+ @Override
+ public void sendRawPacket(ProxiedPlayer player, ByteBuf packet) throws IllegalArgumentException {
+ sendRawPacket(player.getUniqueId(), packet);
+ }
+
+ @Override
+ public BossBar createBossBar(String title, BossColor color, BossStyle style) {
+ return new BungeeBossBar(title, 1F, color, style);
+ }
+
+ @Override
+ public BossBar createBossBar(String title, float health, BossColor color, BossStyle style) {
+ return new BungeeBossBar(title, health, color, style);
+ }
+
+ @Override
+ public SortedSet getSupportedVersions() {
+ SortedSet outputSet = new TreeSet<>(ProtocolRegistry.getSupportedVersions());
+ outputSet.removeAll(Via.getPlatform().getConf().getBlockedProtocols());
+
+ return outputSet;
+ }
+
+ public Map getPortedPlayers() {
+ return Via.getManager().getPortedPlayers();
+ }
+}
diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaInjector.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaInjector.java
new file mode 100644
index 000000000..d8efb2627
--- /dev/null
+++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaInjector.java
@@ -0,0 +1,59 @@
+package us.myles.ViaVersion.bungee.platform;
+
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelInitializer;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.platform.ViaInjector;
+import us.myles.ViaVersion.bungee.handlers.BungeeChannelInitializer;
+import us.myles.ViaVersion.util.ReflectionUtil;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.List;
+
+public class BungeeViaInjector implements ViaInjector {
+ @Override
+ public void inject() throws Exception {
+ try {
+ try {
+
+ Class> pipelineUtils = Class.forName("net.md_5.bungee.netty.PipelineUtils");
+ Field field = pipelineUtils.getDeclaredField("SERVER_CHILD");
+ field.setAccessible(true);
+ // Remove any final stuff
+ Field modifiersField = Field.class.getDeclaredField("modifiers");
+ modifiersField.setAccessible(true);
+ modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
+
+ BungeeChannelInitializer newInit = new BungeeChannelInitializer((ChannelInitializer) field.get(null));
+ field.set(null, newInit);
+ } catch (NoSuchFieldException e) {
+ throw new Exception("Unable to find core component 'childHandler', please check your plugins. issue: ");
+ }
+ } catch (Exception e) {
+ Via.getPlatform().getLogger().severe("Unable to inject ViaVersion, please post these details on our GitHub and ensure you're using a compatible server version.");
+ throw e;
+ }
+ }
+
+ @Override
+ public void uninject() {
+ Via.getPlatform().getLogger().severe("ViaVersion cannot remove itself from Bungee without a reboot!");
+ }
+
+
+ @Override
+ public int getServerProtocolVersion() throws Exception {
+ return (int) ReflectionUtil.getStatic(Class.forName("net.md_5.bungee.protocol.ProtocolConstants"), "SUPPORTED_VERSION_IDS", List.class).get(0);
+ }
+
+ @Override
+ public String getEncoderName() {
+ return "via-encoder";
+ }
+
+ @Override
+ public String getDecoderName() {
+ return "via-decoder";
+ }
+}
diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaLoader.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaLoader.java
new file mode 100644
index 000000000..9ba4e250e
--- /dev/null
+++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaLoader.java
@@ -0,0 +1,34 @@
+package us.myles.ViaVersion.bungee.platform;
+
+import lombok.AllArgsConstructor;
+import net.md_5.bungee.api.ProxyServer;
+import us.myles.ViaVersion.BungeePlugin;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.platform.ViaPlatformLoader;
+import us.myles.ViaVersion.bungee.listeners.UpdateListener;
+import us.myles.ViaVersion.bungee.providers.BungeeMovementTransmitter;
+import us.myles.ViaVersion.bungee.providers.BungeeVersionProvider;
+import us.myles.ViaVersion.bungee.service.ProtocolDetectorService;
+import us.myles.ViaVersion.protocols.base.VersionProvider;
+import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
+
+import java.util.concurrent.TimeUnit;
+
+@AllArgsConstructor
+public class BungeeViaLoader implements ViaPlatformLoader {
+ private BungeePlugin plugin;
+
+ @Override
+ public void load() {
+ // Listeners
+ ProxyServer.getInstance().getPluginManager().registerListener(plugin, plugin);
+ ProxyServer.getInstance().getPluginManager().registerListener(plugin, new UpdateListener());
+
+ // Providers
+ Via.getManager().getProviders().use(MovementTransmitterProvider.class, new BungeeMovementTransmitter());
+ Via.getManager().getProviders().use(VersionProvider.class, new BungeeVersionProvider());
+ if (plugin.getConf().getBungeePingInterval() > 0) {
+ plugin.getProxy().getScheduler().schedule(plugin, new ProtocolDetectorService(plugin), 0, plugin.getConf().getBungeePingInterval(), TimeUnit.SECONDS);
+ }
+ }
+}
diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/providers/BungeeMovementTransmitter.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/providers/BungeeMovementTransmitter.java
new file mode 100644
index 000000000..7f1d37206
--- /dev/null
+++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/providers/BungeeMovementTransmitter.java
@@ -0,0 +1,34 @@
+package us.myles.ViaVersion.bungee.providers;
+
+import us.myles.ViaVersion.api.PacketWrapper;
+import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.api.type.Type;
+import us.myles.ViaVersion.packets.State;
+import us.myles.ViaVersion.protocols.base.ProtocolInfo;
+import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
+import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.MovementTracker;
+
+public class BungeeMovementTransmitter extends MovementTransmitterProvider {
+ @Override
+ public Object getFlyingPacket() {
+ return null;
+ }
+
+ @Override
+ public Object getGroundPacket() {
+ return null;
+ }
+
+ public void sendPlayer(UserConnection userConnection) {
+ if (userConnection.get(ProtocolInfo.class).getState() == State.PLAY) {
+ PacketWrapper wrapper = new PacketWrapper(0x03, null, userConnection);
+ wrapper.write(Type.BOOLEAN, userConnection.get(MovementTracker.class).isGround());
+ try {
+ wrapper.sendToServer();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ // PlayerPackets will increment idle
+ }
+ }
+}
diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/providers/BungeeVersionProvider.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/providers/BungeeVersionProvider.java
new file mode 100644
index 000000000..3dc9be3a1
--- /dev/null
+++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/providers/BungeeVersionProvider.java
@@ -0,0 +1,65 @@
+package us.myles.ViaVersion.bungee.providers;
+
+import com.google.common.collect.Lists;
+import net.md_5.bungee.api.ProxyServer;
+import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.protocols.base.ProtocolInfo;
+import us.myles.ViaVersion.protocols.base.VersionProvider;
+import us.myles.ViaVersion.util.ReflectionUtil;
+
+import java.util.List;
+
+public class BungeeVersionProvider extends VersionProvider {
+ private static Class> ref;
+
+ static {
+ try {
+ ref = Class.forName("net.md_5.bungee.protocol.ProtocolConstants");
+ } catch (Exception e) {
+ System.out.println("Could not detect the ProtocolConstants class");
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public int getServerProtocol(UserConnection user) throws Exception {
+ if (ref == null)
+ return super.getServerProtocol(user);
+ // TODO Have one constant list forever until restart? (Might limit plugins if they change this)
+ List list = ReflectionUtil.getStatic(ref, "SUPPORTED_VERSION_IDS", List.class);
+
+ ProtocolInfo info = user.get(ProtocolInfo.class);
+
+ // Bungee supports it
+ if (list.contains(info.getProtocolVersion()))
+ return info.getProtocolVersion();
+
+ // Older than bungee supports, get the lowest version
+ if (info.getProtocolVersion() < list.get(0)) {
+ return getLowestSupportedVersion();
+ }
+
+ // Loop through all protocols to get the closest protocol id that bungee supports
+ for (Integer protocol : Lists.reverse(list)) {
+ if (info.getProtocolVersion() > protocol)
+ return protocol;
+ }
+
+ System.out.println("Panic, no protocol id found for " + info.getProtocolVersion());
+ return info.getProtocolVersion();
+ }
+
+ public static int getLowestSupportedVersion() {
+ List list;
+ try {
+ list = ReflectionUtil.getStatic(ref, "SUPPORTED_VERSION_IDS", List.class);
+ return list.get(0);
+ } catch (NoSuchFieldException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ // Fallback
+ return ProxyServer.getInstance().getProtocolVersion();
+ }
+}
diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/service/ProtocolDetectorService.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/service/ProtocolDetectorService.java
new file mode 100644
index 000000000..f883e82aa
--- /dev/null
+++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/service/ProtocolDetectorService.java
@@ -0,0 +1,82 @@
+package us.myles.ViaVersion.bungee.service;
+
+import lombok.Getter;
+import net.md_5.bungee.api.Callback;
+import net.md_5.bungee.api.ProxyServer;
+import net.md_5.bungee.api.ServerPing;
+import net.md_5.bungee.api.config.ServerInfo;
+import us.myles.ViaVersion.BungeePlugin;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.bungee.platform.BungeeConfigAPI;
+import us.myles.ViaVersion.bungee.providers.BungeeVersionProvider;
+import us.myles.ViaVersion.util.ReflectionUtil;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class ProtocolDetectorService implements Runnable {
+ private static final Map detectedProtocolIds = new ConcurrentHashMap<>();
+ private BungeePlugin plugin;
+ @Getter
+ private static ProtocolDetectorService instance;
+
+ public ProtocolDetectorService(BungeePlugin plugin) {
+ this.plugin = plugin;
+ instance = this;
+ }
+
+ public static Integer getProtocolId(String serverName) {
+ // Step 1. Check Config
+ Map servers = ((BungeeConfigAPI) Via.getConfig()).getBungeeServerProtocols();
+ if (servers.containsKey(serverName)) {
+ return servers.get(serverName);
+ }
+ // Step 2. Check Detected
+ if (detectedProtocolIds.containsKey(serverName)) {
+ return detectedProtocolIds.get(serverName);
+ }
+ // Step 3. Use Default
+ if (servers.containsKey("default")) {
+ return servers.get("default");
+ }
+ // Step 4: Use bungee lowest supported... *cries*
+ return BungeeVersionProvider.getLowestSupportedVersion();
+ }
+
+ @Override
+ public void run() {
+ for (final Map.Entry lists : plugin.getProxy().getServers().entrySet()) {
+ updateProtocolInfo(lists.getKey(), lists.getValue());
+ }
+ }
+
+ private void updateProtocolInfo(final String key, ServerInfo value) {
+ value.ping(new Callback() {
+ @Override
+ public void done(ServerPing serverPing, Throwable throwable) {
+ if (throwable == null) {
+ detectedProtocolIds.put(key, serverPing.getVersion().getProtocol());
+ if (((BungeeConfigAPI) Via.getConfig()).isBungeePingSave()) {
+ Map servers = ((BungeeConfigAPI) Via.getConfig()).getBungeeServerProtocols();
+ if (servers.containsKey(key)) {
+ if (servers.get(key) == serverPing.getVersion().getProtocol()) {
+ return;
+ }
+ }
+ // Save Server
+ servers.put(key, serverPing.getVersion().getProtocol());
+ // Save
+ Via.getPlatform().getConfigurationProvider().saveConfig();
+ }
+ }
+ }
+ });
+ }
+
+ public static Map getDetectedIds() {
+ return new HashMap<>(detectedProtocolIds);
+ }
+
+}
diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/storage/BungeeStorage.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/storage/BungeeStorage.java
new file mode 100644
index 000000000..683b8230d
--- /dev/null
+++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/storage/BungeeStorage.java
@@ -0,0 +1,20 @@
+package us.myles.ViaVersion.bungee.storage;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import net.md_5.bungee.api.connection.ProxiedPlayer;
+import us.myles.ViaVersion.api.data.StoredObject;
+import us.myles.ViaVersion.api.data.UserConnection;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class BungeeStorage extends StoredObject {
+ private ProxiedPlayer player;
+ private String currentServer;
+
+ public BungeeStorage(UserConnection user, ProxiedPlayer player) {
+ super(user);
+ this.player = player;
+ this.currentServer = "";
+ }
+}
diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/util/BungeePipelineUtil.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/util/BungeePipelineUtil.java
new file mode 100644
index 000000000..5d81f876a
--- /dev/null
+++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/util/BungeePipelineUtil.java
@@ -0,0 +1,71 @@
+package us.myles.ViaVersion.bungee.util;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToByteEncoder;
+import io.netty.handler.codec.MessageToMessageDecoder;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+public class BungeePipelineUtil {
+ private static Method DECODE_METHOD;
+ private static Method ENCODE_METHOD;
+
+ static {
+ try {
+ DECODE_METHOD = MessageToMessageDecoder.class.getDeclaredMethod("decode", ChannelHandlerContext.class, Object.class, List.class);
+ DECODE_METHOD.setAccessible(true);
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ System.out.println("Netty issue?");
+ }
+ try {
+ ENCODE_METHOD = MessageToByteEncoder.class.getDeclaredMethod("encode", ChannelHandlerContext.class, Object.class, ByteBuf.class);
+ ENCODE_METHOD.setAccessible(true);
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ System.out.println("Netty issue?");
+ }
+ }
+
+ public static List callDecode(MessageToMessageDecoder decoder, ChannelHandlerContext ctx, ByteBuf input) throws InvocationTargetException {
+ List output = new ArrayList<>();
+ try {
+ BungeePipelineUtil.DECODE_METHOD.invoke(decoder, ctx, input, output);
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ return output;
+ }
+
+ public static ByteBuf callEncode(MessageToByteEncoder encoder, ChannelHandlerContext ctx, ByteBuf input) throws InvocationTargetException {
+ ByteBuf output = ctx.alloc().buffer();
+ try {
+ BungeePipelineUtil.ENCODE_METHOD.invoke(encoder, ctx, input, output);
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ return output;
+ }
+
+ public static ByteBuf decompress(ChannelHandlerContext ctx, ByteBuf bytebuf) {
+ try {
+ return (ByteBuf) callDecode((MessageToMessageDecoder) ctx.pipeline().get("decompress"), ctx.pipeline().context("decompress"), bytebuf).get(0);
+ } catch (InvocationTargetException e) {
+ e.printStackTrace();
+ return ctx.alloc().buffer();
+ }
+ }
+
+ public static ByteBuf compress(ChannelHandlerContext ctx, ByteBuf bytebuf) {
+ try {
+ return callEncode((MessageToByteEncoder) ctx.pipeline().get("compress"), ctx.pipeline().context("compress"), bytebuf);
+ } catch (InvocationTargetException e) {
+ e.printStackTrace();
+ return ctx.alloc().buffer();
+ }
+ }
+}
diff --git a/bungee/src/main/resources/bungee.yml b/bungee/src/main/resources/bungee.yml
new file mode 100644
index 000000000..37b6dc108
--- /dev/null
+++ b/bungee/src/main/resources/bungee.yml
@@ -0,0 +1,4 @@
+name: ViaVersion
+main: us.myles.ViaVersion.BungeePlugin
+author: _MylesC, Matsv
+version: ${project.version}
\ No newline at end of file
diff --git a/common/pom.xml b/common/pom.xml
new file mode 100644
index 000000000..fa13a94c6
--- /dev/null
+++ b/common/pom.xml
@@ -0,0 +1,24 @@
+
+
+
+ viaversion-parent
+ us.myles
+ 1.0.0-ALPHA-modules
+
+
+ 4.0.0
+
+ viaversion-common
+
+
+
+
+ org.yaml
+ snakeyaml
+ 1.18-SNAPSHOT
+ provided
+
+
+
\ No newline at end of file
diff --git a/common/src/main/java/us/myles/ViaVersion/ViaManager.java b/common/src/main/java/us/myles/ViaVersion/ViaManager.java
new file mode 100644
index 000000000..60a9254aa
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/ViaManager.java
@@ -0,0 +1,117 @@
+package us.myles.ViaVersion;
+
+import lombok.Builder;
+import lombok.Getter;
+import lombok.Setter;
+import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.api.platform.ViaInjector;
+import us.myles.ViaVersion.api.platform.ViaPlatform;
+import us.myles.ViaVersion.api.platform.ViaPlatformLoader;
+import us.myles.ViaVersion.api.platform.providers.ViaProviders;
+import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
+import us.myles.ViaVersion.api.protocol.ProtocolVersion;
+import us.myles.ViaVersion.commands.ViaCommandHandler;
+import us.myles.ViaVersion.protocols.base.ProtocolInfo;
+import us.myles.ViaVersion.update.UpdateUtil;
+
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Getter
+public class ViaManager {
+ private final Map portedPlayers = new ConcurrentHashMap<>();
+ private ViaPlatform platform;
+ private ViaProviders providers = new ViaProviders();
+ @Setter
+ private boolean debug = false;
+ // Internals
+ private ViaInjector injector;
+ private ViaCommandHandler commandHandler;
+ private ViaPlatformLoader loader;
+
+ @Builder
+ public ViaManager(ViaPlatform platform, ViaInjector injector, ViaCommandHandler commandHandler, ViaPlatformLoader loader) {
+ this.platform = platform;
+ this.injector = injector;
+ this.commandHandler = commandHandler;
+ this.loader = loader;
+ }
+
+ public void init() {
+ if (System.getProperty("ViaVersion") != null) {
+ // Reload?
+ platform.onReload();
+ }
+ // Check for updates
+ if (platform.getConf().isCheckForUpdates())
+ UpdateUtil.sendUpdateMessage();
+ // Inject
+ try {
+ injector.inject();
+ } catch (Exception e) {
+ getPlatform().getLogger().severe("ViaVersion failed to inject:");
+ e.printStackTrace();
+ return;
+ }
+ // Mark as injected
+ System.setProperty("ViaVersion", getPlatform().getPluginVersion());
+ // If successful
+ platform.runSync(new Runnable() {
+ @Override
+ public void run() {
+ onServerLoaded();
+ }
+ });
+
+ }
+
+ public void onServerLoaded() {
+ // Load Server Protocol
+ try {
+ ProtocolRegistry.SERVER_PROTOCOL = injector.getServerProtocolVersion();
+ } catch (Exception e) {
+ getPlatform().getLogger().severe("ViaVersion failed to get the server protocol!");
+ e.printStackTrace();
+ }
+ // Check if there are any pipes to this version
+ if (ProtocolRegistry.SERVER_PROTOCOL != -1) {
+ getPlatform().getLogger().info("ViaVersion detected server version: " + ProtocolVersion.getProtocol(ProtocolRegistry.SERVER_PROTOCOL));
+ if (!ProtocolRegistry.isWorkingPipe()) {
+ getPlatform().getLogger().warning("ViaVersion does not have any compatible versions for this server version, please read our resource page carefully.");
+ }
+ }
+ // Load Listeners / Tasks
+ ProtocolRegistry.onServerLoaded();
+
+ // Load Platform
+ loader.load();
+
+ // Refresh Versions
+ ProtocolRegistry.refreshVersions();
+ }
+
+ public void destroy() {
+ // Uninject
+ getPlatform().getLogger().info("ViaVersion is disabling, if this is a reload and you experience issues consider rebooting.");
+ try {
+ injector.uninject();
+ } catch (Exception e) {
+ getPlatform().getLogger().severe("ViaVersion failed to uninject:");
+ e.printStackTrace();
+ }
+ }
+
+ public void addPortedClient(UserConnection info) {
+ portedPlayers.put(info.get(ProtocolInfo.class).getUuid(), info);
+ }
+
+ public void removePortedClient(UUID clientID) {
+ portedPlayers.remove(clientID);
+ }
+
+ public UserConnection getConnection(UUID playerUUID) {
+ return portedPlayers.get(playerUUID);
+ }
+
+}
diff --git a/src/main/java/us/myles/ViaVersion/api/PacketWrapper.java b/common/src/main/java/us/myles/ViaVersion/api/PacketWrapper.java
similarity index 96%
rename from src/main/java/us/myles/ViaVersion/api/PacketWrapper.java
rename to common/src/main/java/us/myles/ViaVersion/api/PacketWrapper.java
index 18d631225..7d4f7730d 100644
--- a/src/main/java/us/myles/ViaVersion/api/PacketWrapper.java
+++ b/common/src/main/java/us/myles/ViaVersion/api/PacketWrapper.java
@@ -12,11 +12,9 @@ import us.myles.ViaVersion.api.remapper.ValueCreator;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.TypeConverter;
import us.myles.ViaVersion.exception.InformativeException;
-import us.myles.ViaVersion.handlers.ViaDecodeHandler;
import us.myles.ViaVersion.packets.Direction;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
-import us.myles.ViaVersion.util.PipelineUtil;
import java.io.IOException;
import java.util.ArrayList;
@@ -25,14 +23,16 @@ import java.util.LinkedList;
import java.util.List;
public class PacketWrapper {
+ public static final int PASSTHROUGH_ID = 1000;
+
private final ByteBuf inputBuffer;
private final UserConnection userConnection;
private boolean send = true;
@Setter
@Getter
private int id = -1;
- private LinkedList> readableObjects = new LinkedList<>();
- private List> packetValues = new ArrayList<>();
+ private final LinkedList> readableObjects = new LinkedList<>();
+ private final List> packetValues = new ArrayList<>();
public PacketWrapper(int packetID, ByteBuf inputBuffer, UserConnection userConnection) {
this.id = packetID;
@@ -357,7 +357,7 @@ public class PacketWrapper {
* Be careful not to send packets twice.
* (Sends it after current)
*
- * This method is no longer used, it's favoured to use send(Protocol) as it will handle the pipeline properly.
+ * This method is no longer used, it's favoured to use {@link #send(Class)} as it will handle the pipeline properly.
*
* @throws Exception if it fails to write
*/
@@ -403,7 +403,7 @@ public class PacketWrapper {
* @param index The index to start from
* @param pipeline The pipeline
* @return The current packetwrapper
- * @throws Exception
+ * @throws Exception If it fails to transform a packet, exception will be thrown
*/
public PacketWrapper apply(Direction direction, State state, int index, List pipeline) throws Exception {
for (int i = index; i < pipeline.size(); i++) { // Copy to prevent from removal.
@@ -454,18 +454,16 @@ public class PacketWrapper {
/**
* Send the current packet to the server.
- * (Ensure the ID is suitable for the server version)
+ * (Ensure the ID is suitable for viaversion)
*
* @throws Exception If it failed to write
*/
public void sendToServer() throws Exception {
if (!isCancelled()) {
ByteBuf output = inputBuffer == null ? Unpooled.buffer() : inputBuffer.alloc().buffer();
- Type.VAR_INT.write(output, ViaDecodeHandler.PASSTHROUGH_ID); // Pass through
-
writeToBuffer(output);
- PipelineUtil.getContextBefore("decompress", user().getChannel().pipeline()).fireChannelRead(output);
+ user().getChannel().pipeline().context(Via.getManager().getInjector().getDecoderName()).fireChannelRead(output);
}
}
diff --git a/src/main/java/us/myles/ViaVersion/api/Pair.java b/common/src/main/java/us/myles/ViaVersion/api/Pair.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/Pair.java
rename to common/src/main/java/us/myles/ViaVersion/api/Pair.java
diff --git a/common/src/main/java/us/myles/ViaVersion/api/Via.java b/common/src/main/java/us/myles/ViaVersion/api/Via.java
new file mode 100644
index 000000000..6339ef84e
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/api/Via.java
@@ -0,0 +1,45 @@
+package us.myles.ViaVersion.api;
+
+import com.google.common.base.Preconditions;
+import lombok.Getter;
+import us.myles.ViaVersion.ViaManager;
+import us.myles.ViaVersion.api.platform.ViaPlatform;
+
+public class Via {
+ @Getter
+ private static ViaPlatform platform;
+ @Getter
+ private static ViaManager manager;
+
+ /**
+ * Register the ViaManager associated with the platform.
+ *
+ * @param viaManager The ViaManager
+ */
+ public static void init(ViaManager viaManager) {
+ Preconditions.checkArgument(manager == null, "ViaManager is already set");
+
+ Via.platform = viaManager.getPlatform();
+ Via.manager = viaManager;
+ }
+
+ /**
+ * Get the API associated with the current platform.
+ *
+ * @return API instance
+ */
+ public static ViaAPI getAPI() {
+ Preconditions.checkArgument(platform != null, "ViaVersion has not loaded the Platform");
+ return Via.platform.getApi();
+ }
+
+ /**
+ * Get the config associated with the current platform.
+ *
+ * @return Config instance
+ */
+ public static ViaVersionConfig getConfig() {
+ Preconditions.checkArgument(platform != null, "ViaVersion has not loaded the Platform");
+ return Via.platform.getConf();
+ }
+}
diff --git a/common/src/main/java/us/myles/ViaVersion/api/ViaAPI.java b/common/src/main/java/us/myles/ViaVersion/api/ViaAPI.java
new file mode 100644
index 000000000..39d58bf01
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/api/ViaAPI.java
@@ -0,0 +1,99 @@
+package us.myles.ViaVersion.api;
+
+import io.netty.buffer.ByteBuf;
+import us.myles.ViaVersion.api.boss.BossBar;
+import us.myles.ViaVersion.api.boss.BossColor;
+import us.myles.ViaVersion.api.boss.BossStyle;
+import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
+
+import java.util.SortedSet;
+import java.util.UUID;
+
+/**
+ * Represents the ViaAPI
+ *
+ * @param The player type for the specific platform, for bukkit it's {@code ViaAPI}
+ */
+public interface ViaAPI {
+ /**
+ * Get protocol number from a player
+ * Will also retrieve version from ProtocolSupport if it's being used.
+ *
+ * @param player Platform player object, eg. Bukkit this is Player
+ * @return Protocol ID, For example (47=1.8-1.8.8, 107=1.9, 108=1.9.1)
+ */
+ int getPlayerVersion(T player);
+
+ /**
+ * Get protocol number from a player
+ *
+ * @param uuid UUID of a player
+ * @return Protocol ID, For example (47=1.8-1.8.8, 107=1.9, 108=1.9.1)
+ */
+ int getPlayerVersion(UUID uuid);
+
+ /**
+ * Is player using 1.9?
+ *
+ * @param playerUUID UUID of a player
+ * @return True if the client is on 1.9
+ * @deprecated As of 0.9.9, because all players are ported use {@link #getPlayerVersion(UUID)}
+ */
+ @Deprecated
+ boolean isPorted(UUID playerUUID);
+
+ /**
+ * Get the version of the plugin
+ *
+ * @return Plugin version
+ */
+ String getVersion();
+
+ /**
+ * Send a raw packet to the player (Use new IDs)
+ *
+ * @param player Platform player object, eg. Bukkit this is Player
+ * @param packet The packet, you need a VarInt ID then the packet contents.
+ * @throws IllegalArgumentException If not on 1.9 throws IllegalArg
+ */
+ void sendRawPacket(T player, ByteBuf packet) throws IllegalArgumentException;
+
+ /**
+ * Send a raw packet to the player (Use new IDs)
+ *
+ * @param uuid The uuid from the player to send packet
+ * @param packet The packet, you need a VarInt ID then the packet contents.
+ * @throws IllegalArgumentException If not on 1.9 throws IllegalArg
+ */
+ void sendRawPacket(UUID uuid, ByteBuf packet) throws IllegalArgumentException;
+
+ /**
+ * Create a new bossbar instance
+ *
+ * @param title The title
+ * @param color The color
+ * @param style The style
+ * @return BossBar instance
+ */
+ BossBar createBossBar(String title, BossColor color, BossStyle style);
+
+ /**
+ * Create a new bossbar instance
+ *
+ * @param title The title
+ * @param health Number between 0 and 1
+ * @param color The color
+ * @param style The style
+ * @return BossBar instance
+ */
+ BossBar createBossBar(String title, float health, BossColor color, BossStyle style);
+
+ /**
+ * Get the supported protocol versions
+ * This method removes any blocked protocol versions.
+ *
+ * @return a list of protocol versions
+ * @see ProtocolRegistry#getSupportedVersions() for full list.
+ */
+ SortedSet getSupportedVersions();
+}
diff --git a/common/src/main/java/us/myles/ViaVersion/api/ViaListener.java b/common/src/main/java/us/myles/ViaVersion/api/ViaListener.java
new file mode 100644
index 000000000..243a00212
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/api/ViaListener.java
@@ -0,0 +1,43 @@
+package us.myles.ViaVersion.api;
+
+import lombok.*;
+import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.api.protocol.Protocol;
+import us.myles.ViaVersion.protocols.base.ProtocolInfo;
+
+import java.util.UUID;
+
+@Getter(AccessLevel.PROTECTED)
+@Setter(AccessLevel.PROTECTED)
+@RequiredArgsConstructor
+public abstract class ViaListener {
+ private final Class extends Protocol> requiredPipeline;
+ private boolean registered = false;
+
+ /**
+ * Get the UserConnection from an UUID
+ *
+ * @param uuid UUID object
+ * @return The UserConnection
+ */
+ protected UserConnection getUserConnection(@NonNull UUID uuid) {
+ return Via.getManager().getConnection(uuid);
+ }
+
+ /**
+ * Checks if the UUID is on the selected pipe
+ *
+ * @param uuid UUID Object
+ * @return True if on pipe
+ */
+ protected boolean isOnPipe(UUID uuid) {
+ UserConnection userConnection = getUserConnection(uuid);
+ return userConnection != null &&
+ userConnection.get(ProtocolInfo.class).getPipeline().contains(requiredPipeline);
+ }
+
+ /**
+ * Register the event
+ */
+ public abstract void register();
+}
diff --git a/src/main/java/us/myles/ViaVersion/api/ViaVersionConfig.java b/common/src/main/java/us/myles/ViaVersion/api/ViaVersionConfig.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/ViaVersionConfig.java
rename to common/src/main/java/us/myles/ViaVersion/api/ViaVersionConfig.java
diff --git a/src/main/java/us/myles/ViaVersion/api/boss/BossBar.java b/common/src/main/java/us/myles/ViaVersion/api/boss/BossBar.java
similarity index 53%
rename from src/main/java/us/myles/ViaVersion/api/boss/BossBar.java
rename to common/src/main/java/us/myles/ViaVersion/api/boss/BossBar.java
index fe9d20489..76737c23b 100644
--- a/src/main/java/us/myles/ViaVersion/api/boss/BossBar.java
+++ b/common/src/main/java/us/myles/ViaVersion/api/boss/BossBar.java
@@ -1,17 +1,17 @@
package us.myles.ViaVersion.api.boss;
-import org.bukkit.entity.Player;
+import us.myles.ViaVersion.api.Via;
import java.util.Set;
import java.util.UUID;
-public interface BossBar {
+public abstract class BossBar {
/**
* Get the current title
*
* @return the title
*/
- String getTitle();
+ public abstract String getTitle();
/**
* Change the title
@@ -19,14 +19,14 @@ public interface BossBar {
* @param title Title can be in either JSON or just text
* @return The BossBar object
*/
- BossBar setTitle(String title);
+ public abstract BossBar setTitle(String title);
/**
* Get the health
*
* @return float between 0F - 1F
*/
- float getHealth();
+ public abstract float getHealth();
/**
* Change the health
@@ -34,14 +34,14 @@ public interface BossBar {
* @param health this float has to be between 0F - 1F
* @return The BossBar object
*/
- BossBar setHealth(float health);
+ public abstract BossBar setHealth(float health);
/**
* Get the bossbar color
*
* @return The colour
*/
- BossColor getColor();
+ public abstract BossColor getColor();
/**
* Yay colors!
@@ -49,14 +49,14 @@ public interface BossBar {
* @param color Whatever color you want!
* @return The BossBar object
*/
- BossBar setColor(BossColor color);
+ public abstract BossBar setColor(BossColor color);
/**
* Get the bosbar style
*
* @return BossStyle
*/
- BossStyle getStyle();
+ public abstract BossStyle getStyle();
/**
* Change the bosbar style
@@ -64,15 +64,19 @@ public interface BossBar {
* @param style BossStyle
* @return The BossBar object
*/
- BossBar setStyle(BossStyle style);
+ public abstract BossBar setStyle(BossStyle style);
/**
* Show the bossbar to a player.
*
* @param player The player
* @return The BossBar object
+ * @deprecated Deprecated use UUID's instead of Player objects {@link #addPlayer(UUID)}
*/
- BossBar addPlayer(Player player);
+ @Deprecated
+ public BossBar addPlayer(T player) {
+ throw new UnsupportedOperationException("This method is not implemented for the platform " + Via.getPlatform().getPlatformName());
+ }
/**
* Show the bossbar to a player (uuid)
@@ -80,23 +84,39 @@ public interface BossBar {
* @param player uuid of the player
* @return The BossBar object
*/
- BossBar addPlayer(UUID player);
+ public abstract BossBar addPlayer(UUID player);
/**
* add multiple players
*
* @param players list of players
* @return The BossBar object
+ * @deprecated Deprecated use UUID's instead of Player objects {@link #addPlayer(UUID)}
*/
- BossBar addPlayers(Player... players);
+ @Deprecated
+ public BossBar addPlayers(T... players) {
+ throw new UnsupportedOperationException("This method is not implemented for the platform " + Via.getPlatform().getPlatformName());
+ }
/**
* Remove the bossbar from a player
*
* @param player The player
* @return The BossBar object
+ * @deprecated Deprecated use UUID's instead of Player objects {@link #removePlayer(UUID)}
*/
- BossBar removePlayer(Player player);
+ @Deprecated
+ public BossBar removePlayer(T player) {
+ throw new UnsupportedOperationException("This method is not implemented for the platform " + Via.getPlatform().getPlatformName());
+ }
+
+ /**
+ * Removes the bossbar from a player
+ *
+ * @param uuid The platers YYUD
+ * @return The BossBar object
+ */
+ public abstract BossBar removePlayer(UUID uuid);
/**
* Add flags
@@ -104,7 +124,7 @@ public interface BossBar {
* @param flag The flag to add
* @return The BossBar object
*/
- BossBar addFlag(BossFlag flag);
+ public abstract BossBar addFlag(BossFlag flag);
/**
* Remove flags.
@@ -112,39 +132,39 @@ public interface BossBar {
* @param flag The flag to remove
* @return The BossBar object
*/
- BossBar removeFlag(BossFlag flag);
+ public abstract BossBar removeFlag(BossFlag flag);
/**
* @param flag The flag to check against
* @return True if it has the flag
*/
- boolean hasFlag(BossFlag flag);
+ public abstract boolean hasFlag(BossFlag flag);
/**
* Get players
*
* @return UUIDS from players (sorry I lied)
*/
- Set getPlayers();
+ public abstract Set getPlayers();
/**
* Show the bossbar to everyone (In the getPlayer set)
*
* @return The BossBar object
*/
- BossBar show();
+ public abstract BossBar show();
/**
* Hide the bossbar from everyone (In the getPlayer set)
*
* @return The BossBar object
*/
- BossBar hide();
+ public abstract BossBar hide();
/**
* Is it visible?
*
* @return visibility changable with show() and hide()
*/
- boolean isVisible();
+ public abstract boolean isVisible();
}
diff --git a/src/main/java/us/myles/ViaVersion/api/boss/BossColor.java b/common/src/main/java/us/myles/ViaVersion/api/boss/BossColor.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/boss/BossColor.java
rename to common/src/main/java/us/myles/ViaVersion/api/boss/BossColor.java
diff --git a/src/main/java/us/myles/ViaVersion/api/boss/BossFlag.java b/common/src/main/java/us/myles/ViaVersion/api/boss/BossFlag.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/boss/BossFlag.java
rename to common/src/main/java/us/myles/ViaVersion/api/boss/BossFlag.java
diff --git a/src/main/java/us/myles/ViaVersion/api/boss/BossStyle.java b/common/src/main/java/us/myles/ViaVersion/api/boss/BossStyle.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/boss/BossStyle.java
rename to common/src/main/java/us/myles/ViaVersion/api/boss/BossStyle.java
diff --git a/common/src/main/java/us/myles/ViaVersion/api/command/ViaCommandSender.java b/common/src/main/java/us/myles/ViaVersion/api/command/ViaCommandSender.java
new file mode 100644
index 000000000..78cf19f7a
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/api/command/ViaCommandSender.java
@@ -0,0 +1,34 @@
+package us.myles.ViaVersion.api.command;
+
+import java.util.UUID;
+
+public interface ViaCommandSender {
+ /**
+ * Check if the sender has a permission.
+ *
+ * @param permission Permission string eg. viaversion.admin
+ * @return True if the sender has the permission
+ */
+ boolean hasPermission(String permission);
+
+ /**
+ * Send a message to the sender
+ *
+ * @param msg The message to send
+ */
+ void sendMessage(String msg);
+
+ /**
+ * Get the senders UUID.
+ *
+ * @return The senders UUID
+ */
+ UUID getUUID();
+
+ /**
+ * Get the senders name.
+ *
+ * @return The senders name
+ */
+ String getName();
+}
diff --git a/src/main/java/us/myles/ViaVersion/api/command/ViaSubCommand.java b/common/src/main/java/us/myles/ViaVersion/api/command/ViaSubCommand.java
similarity index 70%
rename from src/main/java/us/myles/ViaVersion/api/command/ViaSubCommand.java
rename to common/src/main/java/us/myles/ViaVersion/api/command/ViaSubCommand.java
index 000b97d6e..0c206fd10 100644
--- a/src/main/java/us/myles/ViaVersion/api/command/ViaSubCommand.java
+++ b/common/src/main/java/us/myles/ViaVersion/api/command/ViaSubCommand.java
@@ -1,6 +1,5 @@
package us.myles.ViaVersion.api.command;
-import org.bukkit.command.CommandSender;
import us.myles.ViaVersion.commands.ViaCommandHandler;
import java.util.Collections;
@@ -10,14 +9,14 @@ public abstract class ViaSubCommand {
/**
* Subcommand name
*
- * @return The command name
+ * @return The commands name
*/
public abstract String name();
/**
* subcommand description, this'll show in /viaversion list
*
- * @return The command description
+ * @return The commands description
*/
public abstract String description();
@@ -25,7 +24,7 @@ public abstract class ViaSubCommand {
* Usage example:
* "playerversion [name]"
*
- * @return The command usage
+ * @return The commands usage
*/
public String usage() {
return name();
@@ -34,7 +33,7 @@ public abstract class ViaSubCommand {
/**
* Permission, null for everyone
*
- * @return The permission required to use the command
+ * @return The permission required to use the commands
*/
public String permission() {
return "viaversion.admin";
@@ -45,9 +44,9 @@ public abstract class ViaSubCommand {
*
* @param sender Command sender
* @param args Arguments
- * @return command executed succesfully if false, show usage
+ * @return commands executed succesfully if false, show usage
*/
- public abstract boolean execute(CommandSender sender, String[] args);
+ public abstract boolean execute(ViaCommandSender sender, String[] args);
/**
* Yay, possibility to implement tab-completion
@@ -56,7 +55,7 @@ public abstract class ViaSubCommand {
* @param args args
* @return tab complete possibilities
*/
- public List onTabComplete(CommandSender sender, String[] args) {
+ public List onTabComplete(ViaCommandSender sender, String[] args) {
return Collections.emptyList();
}
@@ -67,11 +66,11 @@ public abstract class ViaSubCommand {
/**
* Send message formatted / colored
*
- * @param sender command sender
+ * @param sender commands sender
* @param message string message
* @param args optional objects
*/
- public void sendMessage(CommandSender sender, String message, Object... args) {
+ public void sendMessage(ViaCommandSender sender, String message, Object... args) {
ViaCommandHandler.sendMessage(sender, message, args);
}
}
diff --git a/src/main/java/us/myles/ViaVersion/api/command/ViaVersionCommand.java b/common/src/main/java/us/myles/ViaVersion/api/command/ViaVersionCommand.java
similarity index 59%
rename from src/main/java/us/myles/ViaVersion/api/command/ViaVersionCommand.java
rename to common/src/main/java/us/myles/ViaVersion/api/command/ViaVersionCommand.java
index 707cac6b7..c60037af0 100644
--- a/src/main/java/us/myles/ViaVersion/api/command/ViaVersionCommand.java
+++ b/common/src/main/java/us/myles/ViaVersion/api/command/ViaVersionCommand.java
@@ -1,5 +1,7 @@
package us.myles.ViaVersion.api.command;
+import java.util.List;
+
public interface ViaVersionCommand {
/**
* Register your own subcommand inside ViaVersion
@@ -24,4 +26,22 @@ public interface ViaVersionCommand {
* @return ViaSubCommand instance
*/
ViaSubCommand getSubCommand(String name);
+
+ /**
+ * Executed when the Command sender executes the commands
+ *
+ * @param sender Sender object
+ * @param args arguments provided
+ * @return was successful
+ */
+ boolean onCommand(ViaCommandSender sender, String[] args);
+
+ /**
+ * Executed when the Command sender tab-completes
+ *
+ * @param sender Sender object
+ * @param args arguments provided
+ * @return was successful
+ */
+ List onTabComplete(ViaCommandSender sender, String[] args);
}
diff --git a/common/src/main/java/us/myles/ViaVersion/api/configuration/ConfigurationProvider.java b/common/src/main/java/us/myles/ViaVersion/api/configuration/ConfigurationProvider.java
new file mode 100644
index 000000000..1566598eb
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/api/configuration/ConfigurationProvider.java
@@ -0,0 +1,31 @@
+package us.myles.ViaVersion.api.configuration;
+
+import java.util.Map;
+
+public interface ConfigurationProvider {
+
+ /**
+ * Sets the specified path to the given value.
+ *
+ * @param path Path of the object to set.
+ * @param value New value to set the path to
+ */
+ void set(String path, Object value);
+
+ /**
+ * Saves the config
+ */
+ void saveConfig();
+
+ /**
+ * Reloads the config
+ */
+ void reloadConfig();
+
+ /**
+ * Get all the configuration values
+ *
+ * @return Map with key->values
+ */
+ Map getValues();
+}
diff --git a/src/main/java/us/myles/ViaVersion/api/data/StoredObject.java b/common/src/main/java/us/myles/ViaVersion/api/data/StoredObject.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/data/StoredObject.java
rename to common/src/main/java/us/myles/ViaVersion/api/data/StoredObject.java
diff --git a/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java b/common/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java
similarity index 67%
rename from src/main/java/us/myles/ViaVersion/api/data/UserConnection.java
rename to common/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java
index 28ddac8c1..f6cb5d4f8 100644
--- a/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java
+++ b/common/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java
@@ -5,9 +5,9 @@ import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import io.netty.channel.socket.SocketChannel;
import lombok.Data;
-import org.bukkit.Bukkit;
-import org.bukkit.ChatColor;
-import org.bukkit.entity.Player;
+import net.md_5.bungee.api.ChatColor;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.ViaVersionConfig;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import java.util.Map;
@@ -66,6 +66,14 @@ public class UserConnection {
storedObjects.put(object.getClass(), object);
}
+ /**
+ * Clear all the stored objects
+ * Used for bungee when switching servers.
+ */
+ public void clearStoredObjects() {
+ storedObjects.clear();
+ }
+
/**
* Send a raw packet to the player
*
@@ -73,7 +81,7 @@ public class UserConnection {
* @param currentThread Should it run in the same thread
*/
public void sendRawPacket(final ByteBuf packet, boolean currentThread) {
- final ChannelHandler handler = channel.pipeline().get("encoder");
+ final ChannelHandler handler = channel.pipeline().get(Via.getManager().getInjector().getEncoderName());
if (currentThread) {
channel.pipeline().context(handler).writeAndFlush(packet);
} else {
@@ -93,7 +101,7 @@ public class UserConnection {
* @return ChannelFuture of the packet being sent
*/
public ChannelFuture sendRawPacketFuture(final ByteBuf packet) {
- final ChannelHandler handler = channel.pipeline().get("encoder");
+ final ChannelHandler handler = channel.pipeline().get(Via.getManager().getInjector().getEncoderName());
return channel.pipeline().context(handler).writeAndFlush(packet);
}
@@ -134,6 +142,37 @@ public class UserConnection {
return false;
}
+ public boolean handlePPS() {
+ ViaVersionConfig conf = Via.getConfig();
+ // Max PPS Checker
+ if (conf.getMaxPPS() > 0) {
+ if (getPacketsPerSecond() >= conf.getMaxPPS()) {
+ disconnect(conf.getMaxPPSKickMessage().replace("%pps", ((Long) getPacketsPerSecond()).intValue() + ""));
+ return true; // don't send current packet
+ }
+ }
+
+ // Tracking PPS Checker
+ if (conf.getMaxWarnings() > 0 && conf.getTrackingPeriod() > 0) {
+ if (getSecondsObserved() > conf.getTrackingPeriod()) {
+ // Reset
+ setWarnings(0);
+ setSecondsObserved(1);
+ } else {
+ setSecondsObserved(getSecondsObserved() + 1);
+ if (getPacketsPerSecond() >= conf.getWarningPPS()) {
+ setWarnings(getWarnings() + 1);
+ }
+
+ if (getWarnings() >= conf.getMaxWarnings()) {
+ disconnect(conf.getMaxWarningsKickMessage().replace("%pps", ((Long) getPacketsPerSecond()).intValue() + ""));
+ return true; // don't send current packet
+ }
+ }
+ }
+ return false;
+ }
+
/**
* Disconnect a connection
*
@@ -145,18 +184,15 @@ public class UserConnection {
pendingDisconnect = true;
if (get(ProtocolInfo.class).getUuid() != null) {
final UUID uuid = get(ProtocolInfo.class).getUuid();
- if (Bukkit.getPlayer(uuid) != null) {
- Bukkit.getScheduler().runTask(Bukkit.getPluginManager().getPlugin("ViaVersion"), new Runnable() {
- @Override
- public void run() {
- Player player = Bukkit.getPlayer(uuid);
- if (player != null)
- player.kickPlayer(ChatColor.translateAlternateColorCodes('&', reason));
+ Via.getPlatform().runSync(new Runnable() {
+ @Override
+ public void run() {
+ if (!Via.getPlatform().kickPlayer(uuid, ChatColor.translateAlternateColorCodes('&', reason))) {
+ getChannel().close(); // =)
}
- });
- return;
- }
+ }
+ });
}
- getChannel().close(); // =)
+
}
}
diff --git a/common/src/main/java/us/myles/ViaVersion/api/entities/Entity1_10Types.java b/common/src/main/java/us/myles/ViaVersion/api/entities/Entity1_10Types.java
new file mode 100644
index 000000000..5eb990872
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/api/entities/Entity1_10Types.java
@@ -0,0 +1,187 @@
+package us.myles.ViaVersion.api.entities;
+
+import com.google.common.base.Optional;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import us.myles.ViaVersion.api.Via;
+
+// 1.10 Entity / Object ids
+public class Entity1_10Types {
+
+ public static EntityType getTypeFromId(int typeID, boolean isObject) {
+ Optional type;
+
+ if (isObject)
+ type = ObjectTypes.getPCEntity(typeID);
+ else
+ type = EntityType.findById(typeID);
+
+ if (!type.isPresent()) {
+ Via.getPlatform().getLogger().severe("Could not find type id " + typeID + " isObject=" + isObject);
+ return EntityType.ENTITY; // Fall back to the basic ENTITY
+ }
+
+ return type.get();
+ }
+
+ @AllArgsConstructor
+ @Getter
+ public enum EntityType {
+ ENTITY(-1),
+ DROPPED_ITEM(1, EntityType.ENTITY),
+ EXPERIENCE_ORB(2, EntityType.ENTITY),
+ LEASH_HITCH(8, EntityType.ENTITY), // Actually entity hanging but it doesn't make a lot of difference for metadata
+ PAINTING(9, EntityType.ENTITY), // Actually entity hanging but it doesn't make a lot of difference for metadata
+ ARROW(10, EntityType.ENTITY),
+ SNOWBALL(11, EntityType.ENTITY), // Actually EntityProjectile
+ FIREBALL(12, EntityType.ENTITY),
+ SMALL_FIREBALL(13, EntityType.ENTITY),
+ ENDER_PEARL(14, EntityType.ENTITY), // Actually EntityProjectile
+ ENDER_SIGNAL(15, EntityType.ENTITY),
+ THROWN_EXP_BOTTLE(17, EntityType.ENTITY),
+ ITEM_FRAME(18, EntityType.ENTITY), // Actually EntityHanging
+ WITHER_SKULL(19, EntityType.ENTITY),
+ PRIMED_TNT(20, EntityType.ENTITY),
+ FALLING_BLOCK(21, EntityType.ENTITY),
+ FIREWORK(22, EntityType.ENTITY),
+ TIPPED_ARROW(23, EntityType.ARROW),
+ SPECTRAL_ARROW(24, EntityType.ARROW),
+ SHULKER_BULLET(25, EntityType.ENTITY),
+ DRAGON_FIREBALL(26, EntityType.FIREBALL),
+
+ ENTITY_LIVING(-1, ENTITY),
+ ENTITY_INSENTIENT(-1, ENTITY_LIVING),
+ ENTITY_AGEABLE(-1, ENTITY_INSENTIENT),
+ ENTITY_TAMEABLE_ANIMAL(-1, ENTITY_AGEABLE),
+ ENTITY_HUMAN(-1, ENTITY_LIVING),
+
+ ARMOR_STAND(30, EntityType.ENTITY_LIVING),
+
+ // Vehicles
+ MINECART_ABSTRACT(-1, ENTITY),
+ MINECART_COMMAND(40, MINECART_ABSTRACT),
+ BOAT(41, ENTITY),
+ MINECART_RIDEABLE(42, MINECART_ABSTRACT),
+ MINECART_CHEST(43, MINECART_ABSTRACT),
+ MINECART_FURNACE(44, MINECART_ABSTRACT),
+ MINECART_TNT(45, MINECART_ABSTRACT),
+ MINECART_HOPPER(46, MINECART_ABSTRACT),
+ MINECART_MOB_SPAWNER(47, MINECART_ABSTRACT),
+
+ CREEPER(50, ENTITY_INSENTIENT),
+ SKELETON(51, ENTITY_INSENTIENT),
+ SPIDER(52, ENTITY_INSENTIENT),
+ GIANT(53, ENTITY_INSENTIENT),
+ ZOMBIE(54, ENTITY_INSENTIENT),
+ SLIME(55, ENTITY_INSENTIENT),
+ GHAST(56, ENTITY_INSENTIENT),
+ PIG_ZOMBIE(57, ZOMBIE),
+ ENDERMAN(58, ENTITY_INSENTIENT),
+ CAVE_SPIDER(59, SPIDER),
+ SILVERFISH(60, ENTITY_INSENTIENT),
+ BLAZE(61, ENTITY_INSENTIENT),
+ MAGMA_CUBE(62, SLIME),
+ ENDER_DRAGON(63, ENTITY_INSENTIENT),
+ WITHER(64, ENTITY_INSENTIENT),
+ BAT(65, ENTITY_INSENTIENT),
+ WITCH(66, ENTITY_INSENTIENT),
+ ENDERMITE(67, ENTITY_INSENTIENT),
+ GUARDIAN(68, ENTITY_INSENTIENT),
+ IRON_GOLEM(99, ENTITY_INSENTIENT), // moved up to avoid illegal forward references
+ SHULKER(69, EntityType.IRON_GOLEM),
+ PIG(90, ENTITY_AGEABLE),
+ SHEEP(91, ENTITY_AGEABLE),
+ COW(92, ENTITY_AGEABLE),
+ CHICKEN(93, ENTITY_AGEABLE),
+ SQUID(94, ENTITY_INSENTIENT),
+ WOLF(95, ENTITY_TAMEABLE_ANIMAL),
+ MUSHROOM_COW(96, COW),
+ SNOWMAN(97, EntityType.IRON_GOLEM),
+ OCELOT(98, ENTITY_TAMEABLE_ANIMAL),
+ HORSE(100, ENTITY_AGEABLE),
+ RABBIT(101, ENTITY_AGEABLE),
+ POLAR_BEAR(102, ENTITY_AGEABLE),
+ VILLAGER(120, ENTITY_AGEABLE),
+ ENDER_CRYSTAL(200, ENTITY),
+ SPLASH_POTION(-1, ENTITY),
+ LINGERING_POTION(-1, SPLASH_POTION),
+ AREA_EFFECT_CLOUD(-1, ENTITY),
+ EGG(-1, ENTITY),
+ FISHING_HOOK(-1, ENTITY),
+ LIGHTNING(-1, ENTITY),
+ WEATHER(-1, ENTITY),
+ PLAYER(-1, ENTITY_HUMAN),
+ COMPLEX_PART(-1, ENTITY);
+
+ private final int id;
+ private final EntityType parent;
+
+ EntityType(int id) {
+ this.id = id;
+ this.parent = null;
+ }
+
+ public static Optional findById(int id) {
+ if (id == -1) // Check if this is called
+ return Optional.absent();
+
+ for (EntityType ent : EntityType.values())
+ if (ent.getId() == id)
+ return Optional.of(ent);
+
+ return Optional.absent();
+ }
+ }
+
+ @AllArgsConstructor
+ @Getter
+ public enum ObjectTypes {
+ BOAT(1, EntityType.BOAT),
+ ITEM(2, EntityType.DROPPED_ITEM),
+ AREA_EFFECT_CLOUD(3, EntityType.AREA_EFFECT_CLOUD),
+ MINECART(10, EntityType.MINECART_ABSTRACT),
+ TNT_PRIMED(50, EntityType.PRIMED_TNT),
+ ENDER_CRYSTAL(51, EntityType.ENDER_CRYSTAL),
+ TIPPED_ARROW(60, EntityType.TIPPED_ARROW),
+ SNOWBALL(61, EntityType.SNOWBALL),
+ EGG(62, EntityType.EGG),
+ FIREBALL(63, EntityType.FIREBALL),
+ SMALL_FIREBALL(64, EntityType.SMALL_FIREBALL),
+ ENDER_PEARL(65, EntityType.ENDER_PEARL),
+ WITHER_SKULL(66, EntityType.WITHER_SKULL),
+ SHULKER_BULLET(67, EntityType.SHULKER_BULLET),
+ FALLING_BLOCK(70, EntityType.FALLING_BLOCK),
+ ITEM_FRAME(71, EntityType.ITEM_FRAME),
+ ENDER_SIGNAL(72, EntityType.ENDER_SIGNAL),
+ POTION(73, EntityType.SPLASH_POTION),
+ THROWN_EXP_BOTTLE(75, EntityType.THROWN_EXP_BOTTLE),
+ FIREWORK(76, EntityType.FIREWORK),
+ LEASH(77, EntityType.LEASH_HITCH),
+ ARMOR_STAND(78, EntityType.ARMOR_STAND),
+ FISHIHNG_HOOK(90, EntityType.FISHING_HOOK),
+ SPECTRAL_ARROW(91, EntityType.SPECTRAL_ARROW),
+ DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL);
+
+ private final int id;
+ private final EntityType type;
+
+ public static Optional findById(int id) {
+ if (id == -1)
+ return Optional.absent();
+
+ for (ObjectTypes ent : ObjectTypes.values())
+ if (ent.getId() == id)
+ return Optional.of(ent);
+
+ return Optional.absent();
+ }
+
+ public static Optional getPCEntity(int id) {
+ Optional output = findById(id);
+
+ if (!output.isPresent())
+ return Optional.absent();
+ return Optional.of(output.get().getType());
+ }
+ }
+}
diff --git a/common/src/main/java/us/myles/ViaVersion/api/entities/Entity1_11Types.java b/common/src/main/java/us/myles/ViaVersion/api/entities/Entity1_11Types.java
new file mode 100644
index 000000000..d091f9ba0
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/api/entities/Entity1_11Types.java
@@ -0,0 +1,241 @@
+package us.myles.ViaVersion.api.entities;
+
+import com.google.common.base.Optional;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import us.myles.ViaVersion.api.Via;
+
+// 1.11 Entity / Object ids TODO maybe in the future instead of copying it, some api.
+public class Entity1_11Types {
+ public static EntityType getTypeFromId(int typeID, boolean isObject) {
+ Optional type;
+
+ if (isObject)
+ type = ObjectTypes.getPCEntity(typeID);
+ else
+ type = EntityType.findById(typeID);
+
+ if (!type.isPresent()) {
+ Via.getPlatform().getLogger().severe("Could not find type id " + typeID + " isObject=" + isObject);
+ return EntityType.ENTITY; // Fall back to the basic ENTITY
+ }
+
+ return type.get();
+ }
+
+ @AllArgsConstructor
+ @Getter
+ public enum EntityType {
+ ENTITY(-1),
+ DROPPED_ITEM(1, ENTITY),
+ EXPERIENCE_ORB(2, ENTITY),
+ LEASH_HITCH(8, ENTITY), // Actually entity hanging but it doesn't make a lot of difference for metadata
+ PAINTING(9, ENTITY), // Actually entity hanging but it doesn't make a lot of difference for metadata
+ ARROW(10, ENTITY),
+ SNOWBALL(11, ENTITY), // Actually EntityProjectile
+ FIREBALL(12, ENTITY),
+ SMALL_FIREBALL(13, ENTITY),
+ ENDER_PEARL(14, ENTITY), // Actually EntityProjectile
+ ENDER_SIGNAL(15, ENTITY),
+ THROWN_EXP_BOTTLE(17, ENTITY),
+ ITEM_FRAME(18, ENTITY), // Actually EntityHanging
+ WITHER_SKULL(19, ENTITY),
+ PRIMED_TNT(20, ENTITY),
+ FALLING_BLOCK(21, ENTITY),
+ FIREWORK(22, ENTITY),
+ TIPPED_ARROW(23, ARROW),
+ SPECTRAL_ARROW(24, ARROW),
+ SHULKER_BULLET(25, ENTITY),
+ DRAGON_FIREBALL(26, FIREBALL),
+ EVOCATION_FANGS(33, ENTITY),
+
+
+ ENTITY_LIVING(-1, ENTITY),
+ ENTITY_INSENTIENT(-1, ENTITY_LIVING),
+ ENTITY_AGEABLE(-1, ENTITY_INSENTIENT),
+ ENTITY_TAMEABLE_ANIMAL(-1, ENTITY_AGEABLE),
+ ENTITY_HUMAN(-1, ENTITY_LIVING),
+
+ ARMOR_STAND(30, ENTITY_LIVING),
+ EVOCATION_ILLAGER(34, ENTITY_INSENTIENT),
+ VEX(35, ENTITY_INSENTIENT),
+ VINDICATION_ILLAGER(36, ENTITY_INSENTIENT),
+
+ // Vehicles
+ MINECART_ABSTRACT(-1, ENTITY),
+ MINECART_COMMAND(40, MINECART_ABSTRACT),
+ BOAT(41, ENTITY),
+ MINECART_RIDEABLE(42, MINECART_ABSTRACT),
+ MINECART_CHEST(43, MINECART_ABSTRACT),
+ MINECART_FURNACE(44, MINECART_ABSTRACT),
+ MINECART_TNT(45, MINECART_ABSTRACT),
+ MINECART_HOPPER(46, MINECART_ABSTRACT),
+ MINECART_MOB_SPAWNER(47, MINECART_ABSTRACT),
+
+ CREEPER(50, ENTITY_INSENTIENT),
+
+ ABSTRACT_SKELETON(-1, ENTITY_INSENTIENT),
+ SKELETON(51, ABSTRACT_SKELETON),
+ WITHER_SKELETON(5, ABSTRACT_SKELETON),
+ STRAY(6, ABSTRACT_SKELETON),
+
+ SPIDER(52, ENTITY_INSENTIENT),
+ GIANT(53, ENTITY_INSENTIENT),
+
+ ZOMBIE(54, ENTITY_INSENTIENT),
+ HUSK(23, ZOMBIE),
+ ZOMBIE_VILLAGER(27, ZOMBIE),
+
+ SLIME(55, ENTITY_INSENTIENT),
+ GHAST(56, ENTITY_INSENTIENT),
+ PIG_ZOMBIE(57, ZOMBIE),
+ ENDERMAN(58, ENTITY_INSENTIENT),
+ CAVE_SPIDER(59, SPIDER),
+ SILVERFISH(60, ENTITY_INSENTIENT),
+ BLAZE(61, ENTITY_INSENTIENT),
+ MAGMA_CUBE(62, SLIME),
+ ENDER_DRAGON(63, ENTITY_INSENTIENT),
+ WITHER(64, ENTITY_INSENTIENT),
+ BAT(65, ENTITY_INSENTIENT),
+ WITCH(66, ENTITY_INSENTIENT),
+ ENDERMITE(67, ENTITY_INSENTIENT),
+
+ GUARDIAN(68, ENTITY_INSENTIENT),
+ ELDER_GUARDIAN(4, EntityType.GUARDIAN), // Moved down to avoid illegal forward reference
+
+ IRON_GOLEM(99, ENTITY_INSENTIENT), // moved up to avoid illegal forward references
+ SHULKER(69, EntityType.IRON_GOLEM),
+ PIG(90, ENTITY_AGEABLE),
+ SHEEP(91, ENTITY_AGEABLE),
+ COW(92, ENTITY_AGEABLE),
+ CHICKEN(93, ENTITY_AGEABLE),
+ SQUID(94, ENTITY_INSENTIENT),
+ WOLF(95, ENTITY_TAMEABLE_ANIMAL),
+ MUSHROOM_COW(96, COW),
+ SNOWMAN(97, EntityType.IRON_GOLEM),
+ OCELOT(98, ENTITY_TAMEABLE_ANIMAL),
+
+ ABSTRACT_HORSE(-1, ENTITY_AGEABLE),
+ HORSE(100, ABSTRACT_HORSE),
+ SKELETON_HORSE(28, ABSTRACT_HORSE),
+ ZOMBIE_HORSE(29, ABSTRACT_HORSE),
+
+ CHESTED_HORSE(-1, ABSTRACT_HORSE),
+ DONKEY(31, CHESTED_HORSE),
+ MULE(32, CHESTED_HORSE),
+ LIAMA(103, CHESTED_HORSE),
+
+
+ RABBIT(101, ENTITY_AGEABLE),
+ POLAR_BEAR(102, ENTITY_AGEABLE),
+ VILLAGER(120, ENTITY_AGEABLE),
+ ENDER_CRYSTAL(200, ENTITY),
+ SPLASH_POTION(-1, ENTITY),
+ LINGERING_POTION(-1, SPLASH_POTION),
+ AREA_EFFECT_CLOUD(-1, ENTITY),
+ EGG(-1, ENTITY),
+ FISHING_HOOK(-1, ENTITY),
+ LIGHTNING(-1, ENTITY),
+ WEATHER(-1, ENTITY),
+ PLAYER(-1, ENTITY_HUMAN),
+ COMPLEX_PART(-1, ENTITY),
+ LIAMA_SPIT(-1, ENTITY);
+
+ private final int id;
+ private final EntityType parent;
+
+ EntityType(int id) {
+ this.id = id;
+ this.parent = null;
+ }
+
+ public static Optional findById(int id) {
+ if (id == -1) // Check if this is called
+ return Optional.absent();
+
+ for (EntityType ent : EntityType.values())
+ if (ent.getId() == id)
+ return Optional.of(ent);
+
+ return Optional.absent();
+ }
+
+ public boolean is(EntityType... types) {
+ for (EntityType type : types)
+ if (is(type))
+ return true;
+ return false;
+ }
+
+ public boolean is(EntityType type) {
+ return this == type;
+ }
+
+ public boolean isOrHasParent(EntityType type) {
+ EntityType parent = this;
+
+ do {
+ if (parent.equals(type))
+ return true;
+
+ parent = parent.getParent();
+ } while (parent != null);
+
+ return false;
+ }
+ }
+
+ @AllArgsConstructor
+ @Getter
+ public enum ObjectTypes {
+ BOAT(1, EntityType.BOAT),
+ ITEM(2, EntityType.DROPPED_ITEM),
+ AREA_EFFECT_CLOUD(3, EntityType.AREA_EFFECT_CLOUD),
+ MINECART(10, EntityType.MINECART_ABSTRACT),
+ TNT_PRIMED(50, EntityType.PRIMED_TNT),
+ ENDER_CRYSTAL(51, EntityType.ENDER_CRYSTAL),
+ TIPPED_ARROW(60, EntityType.TIPPED_ARROW),
+ SNOWBALL(61, EntityType.SNOWBALL),
+ EGG(62, EntityType.EGG),
+ FIREBALL(63, EntityType.FIREBALL),
+ SMALL_FIREBALL(64, EntityType.SMALL_FIREBALL),
+ ENDER_PEARL(65, EntityType.ENDER_PEARL),
+ WITHER_SKULL(66, EntityType.WITHER_SKULL),
+ SHULKER_BULLET(67, EntityType.SHULKER_BULLET),
+ LIAMA_SPIT(68, EntityType.LIAMA_SPIT),
+ FALLING_BLOCK(70, EntityType.FALLING_BLOCK),
+ ITEM_FRAME(71, EntityType.ITEM_FRAME),
+ ENDER_SIGNAL(72, EntityType.ENDER_SIGNAL),
+ POTION(73, EntityType.SPLASH_POTION),
+ THROWN_EXP_BOTTLE(75, EntityType.THROWN_EXP_BOTTLE),
+ FIREWORK(76, EntityType.FIREWORK),
+ LEASH(77, EntityType.LEASH_HITCH),
+ ARMOR_STAND(78, EntityType.ARMOR_STAND),
+ EVOCATION_FANGS(39, EntityType.EVOCATION_FANGS),
+ FISHIHNG_HOOK(90, EntityType.FISHING_HOOK),
+ SPECTRAL_ARROW(91, EntityType.SPECTRAL_ARROW),
+ DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL);
+
+ private final int id;
+ private final EntityType type;
+
+ public static Optional findById(int id) {
+ if (id == -1)
+ return Optional.absent();
+
+ for (ObjectTypes ent : ObjectTypes.values())
+ if (ent.getId() == id)
+ return Optional.of(ent);
+
+ return Optional.absent();
+ }
+
+ public static Optional getPCEntity(int id) {
+ Optional output = findById(id);
+
+ if (!output.isPresent())
+ return Optional.absent();
+ return Optional.of(output.get().getType());
+ }
+ }
+}
diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/Environment.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/Environment.java
new file mode 100644
index 000000000..fb098741a
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/Environment.java
@@ -0,0 +1,32 @@
+package us.myles.ViaVersion.api.minecraft;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public enum Environment {
+ NORMAL(0),
+ NETHER(-1),
+ END(1);
+
+ private final int id;
+ private static final Map lookup = new HashMap<>();
+
+ static {
+ for (Environment env : values()) {
+ lookup.put(env.getId(), env);
+ }
+ }
+
+ Environment(int id) {
+ this.id = id;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+
+ public static Environment getEnvironmentById(int id) {
+ return lookup.get(id);
+ }
+}
diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/EulerAngle.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/EulerAngle.java
new file mode 100644
index 000000000..607d41e56
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/EulerAngle.java
@@ -0,0 +1,12 @@
+package us.myles.ViaVersion.api.minecraft;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@Data
+@AllArgsConstructor
+public class EulerAngle {
+ private float x;
+ private float y;
+ private float z;
+}
diff --git a/src/main/java/us/myles/ViaVersion/api/minecraft/Position.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/Position.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/minecraft/Position.java
rename to common/src/main/java/us/myles/ViaVersion/api/minecraft/Position.java
diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/Vector.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/Vector.java
new file mode 100644
index 000000000..78b6b5bdc
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/Vector.java
@@ -0,0 +1,12 @@
+package us.myles.ViaVersion.api.minecraft;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@Data
+@AllArgsConstructor
+public class Vector {
+ private int blockX;
+ private int blockY;
+ private int blockZ;
+}
diff --git a/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/Chunk.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/Chunk.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/minecraft/chunks/Chunk.java
rename to common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/Chunk.java
diff --git a/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java
rename to common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java
diff --git a/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/NibbleArray.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/NibbleArray.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/minecraft/chunks/NibbleArray.java
rename to common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/NibbleArray.java
diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/item/Item.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/item/Item.java
new file mode 100644
index 000000000..9bb8df568
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/item/Item.java
@@ -0,0 +1,16 @@
+package us.myles.ViaVersion.api.minecraft.item;
+
+import lombok.*;
+import org.spacehq.opennbt.tag.builtin.CompoundTag;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString
+public class Item {
+ private short id;
+ private byte amount;
+ private short data;
+ private CompoundTag tag;
+}
diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/metadata/MetaType.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/metadata/MetaType.java
new file mode 100644
index 000000000..31f2c40e8
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/metadata/MetaType.java
@@ -0,0 +1,20 @@
+package us.myles.ViaVersion.api.minecraft.metadata;
+
+import us.myles.ViaVersion.api.type.Type;
+
+public interface MetaType {
+
+ /**
+ * Get the write/read type
+ *
+ * @return Type instance
+ */
+ Type getType();
+
+ /**
+ * Get type id from the specific MetaDataType
+ *
+ * @return Type id as an integer
+ */
+ int getTypeID();
+}
diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/metadata/Metadata.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/metadata/Metadata.java
new file mode 100644
index 000000000..68fdeca43
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/metadata/Metadata.java
@@ -0,0 +1,12 @@
+package us.myles.ViaVersion.api.minecraft.metadata;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@AllArgsConstructor
+@Data
+public class Metadata {
+ private int id;
+ private MetaType metaType;
+ private Object value;
+}
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/metadata/MetadataTypes.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/metadata/types/MetaType1_8.java
similarity index 69%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/metadata/MetadataTypes.java
rename to common/src/main/java/us/myles/ViaVersion/api/minecraft/metadata/types/MetaType1_8.java
index 36060f9bd..7d75b39fe 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/metadata/MetadataTypes.java
+++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/metadata/types/MetaType1_8.java
@@ -1,12 +1,13 @@
-package us.myles.ViaVersion.protocols.protocol1_9to1_8.metadata;
+package us.myles.ViaVersion.api.minecraft.metadata.types;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
+import us.myles.ViaVersion.api.minecraft.metadata.MetaType;
import us.myles.ViaVersion.api.type.Type;
@RequiredArgsConstructor
@Getter
-public enum MetadataTypes {
+public enum MetaType1_8 implements MetaType {
Byte(0, Type.BYTE),
Short(1, Type.SHORT),
Int(2, Type.INT),
@@ -20,7 +21,7 @@ public enum MetadataTypes {
private final int typeID;
private final Type type;
- public static MetadataTypes byId(int id) {
+ public static MetaType1_8 byId(int id) {
return values()[id];
}
}
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/metadata/NewType.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/metadata/types/MetaType1_9.java
similarity index 75%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/metadata/NewType.java
rename to common/src/main/java/us/myles/ViaVersion/api/minecraft/metadata/types/MetaType1_9.java
index 53ae361f2..30be6bef2 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/metadata/NewType.java
+++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/metadata/types/MetaType1_9.java
@@ -1,12 +1,13 @@
-package us.myles.ViaVersion.protocols.protocol1_9to1_8.metadata;
+package us.myles.ViaVersion.api.minecraft.metadata.types;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
+import us.myles.ViaVersion.api.minecraft.metadata.MetaType;
import us.myles.ViaVersion.api.type.Type;
@RequiredArgsConstructor
@Getter
-public enum NewType {
+public enum MetaType1_9 implements MetaType {
Byte(0, Type.BYTE),
VarInt(1, Type.VAR_INT),
Float(2, Type.FLOAT),
@@ -25,7 +26,7 @@ public enum NewType {
private final int typeID;
private final Type type;
- public static NewType byId(int id) {
+ public static MetaType1_9 byId(int id) {
return values()[id];
}
diff --git a/common/src/main/java/us/myles/ViaVersion/api/platform/TaskId.java b/common/src/main/java/us/myles/ViaVersion/api/platform/TaskId.java
new file mode 100644
index 000000000..44993bc2c
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/api/platform/TaskId.java
@@ -0,0 +1,11 @@
+package us.myles.ViaVersion.api.platform;
+
+public interface TaskId {
+ /**
+ * Returns the actual object represented by this TaskId
+ * Null if task cannot be cancelled.
+ *
+ * @return Platform based Object (don't assume)
+ */
+ Object getObject();
+}
diff --git a/common/src/main/java/us/myles/ViaVersion/api/platform/ViaInjector.java b/common/src/main/java/us/myles/ViaVersion/api/platform/ViaInjector.java
new file mode 100644
index 000000000..14f853a2b
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/api/platform/ViaInjector.java
@@ -0,0 +1,39 @@
+package us.myles.ViaVersion.api.platform;
+
+public interface ViaInjector {
+ /**
+ * Inject into the current Platform
+ *
+ * @throws Exception If there is an error with injecting
+ */
+ void inject() throws Exception;
+
+ /**
+ * Uninject into the current Platform
+ *
+ * @throws Exception If there is an error with uninjecting
+ */
+ void uninject() throws Exception;
+
+ /**
+ * Get the server protocol version
+ *
+ * @return The server protocol integer
+ * @throws Exception If there is an error with getting this info, eg. not binded.
+ */
+ int getServerProtocolVersion() throws Exception;
+
+ /**
+ * Get the name of the encoder for then netty pipeline for this platform.
+ *
+ * @return The name
+ */
+ String getEncoderName();
+
+ /**
+ * Get the name of the decoder for then netty pipeline for this platform.
+ *
+ * @return The name
+ */
+ String getDecoderName();
+}
diff --git a/common/src/main/java/us/myles/ViaVersion/api/platform/ViaPlatform.java b/common/src/main/java/us/myles/ViaVersion/api/platform/ViaPlatform.java
new file mode 100644
index 000000000..3a92e7f18
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/api/platform/ViaPlatform.java
@@ -0,0 +1,136 @@
+package us.myles.ViaVersion.api.platform;
+
+import com.google.gson.JsonObject;
+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 java.util.UUID;
+import java.util.logging.Logger;
+
+/**
+ * ViaPlatform represents a platform ViaVersion runs on
+ *
+ * @param - The player type for the platform, used for API related methods
+ */
+public interface ViaPlatform {
+ /**
+ * Get the logger for this platform
+ *
+ * @return Java Logger (may be a wrapper)
+ */
+ Logger getLogger();
+
+ /**
+ * Get the platform name
+ *
+ * @return Platform Name (simply its name)
+ */
+ String getPlatformName();
+
+ /**
+ * Get the plugin version
+ *
+ * @return Plugin version as a semver string
+ */
+ String getPluginVersion();
+
+ /**
+ * Run a task Async
+ *
+ * @param runnable The task to run
+ * @return The Task ID
+ */
+ TaskId runAsync(Runnable runnable);
+
+ /**
+ * Run a task Sync
+ *
+ * @param runnable The task to run
+ * @return The Task ID
+ */
+ TaskId runSync(Runnable runnable);
+
+ /**
+ * Run a task at a repeating interval.
+ * Initial interval is the same as repeat.
+ *
+ * @param runnable The task to run
+ * @param ticks The interval to run it at
+ * @return The Task ID
+ */
+ TaskId runRepeatingSync(Runnable runnable, Long ticks);
+
+ /**
+ * Cancel a task
+ *
+ * @param taskId The task ID to cancel
+ */
+ void cancelTask(TaskId taskId);
+
+ /**
+ * Get the online players
+ *
+ * @return Array of ViaCommandSender
+ */
+ ViaCommandSender[] getOnlinePlayers();
+
+ /**
+ * Send a message to a player
+ *
+ * @param uuid The player's UUID
+ * @param message The message to send
+ */
+ void sendMessage(UUID uuid, String message);
+
+ /**
+ * Kick a player for a reason
+ *
+ * @param uuid The player's UUID
+ * @param message The message to kick them with
+ * @return True if it was successful
+ */
+ boolean kickPlayer(UUID uuid, String message);
+
+ /**
+ * Check if the plugin is enabled.
+ *
+ * @return True if it is enabled
+ */
+ boolean isPluginEnabled();
+
+ /**
+ * Get the API for this platform
+ *
+ * @return The API for the platform
+ */
+ ViaAPI getApi();
+
+ /**
+ * Get the config API for this platform
+ *
+ * @return The config API
+ */
+ ViaVersionConfig getConf();
+
+ /**
+ * Get the backend configuration provider for this platform.
+ * (On some platforms this returns the same as getConf())
+ *
+ * @return The configuration provider
+ */
+ ConfigurationProvider getConfigurationProvider();
+
+ /**
+ * Called when a reload happens
+ */
+ void onReload();
+
+ /**
+ * Get the JSON data required for /viaversion dump
+ *
+ * @return The json data
+ */
+ JsonObject getDump();
+}
diff --git a/common/src/main/java/us/myles/ViaVersion/api/platform/ViaPlatformLoader.java b/common/src/main/java/us/myles/ViaVersion/api/platform/ViaPlatformLoader.java
new file mode 100644
index 000000000..e8c4503bf
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/api/platform/ViaPlatformLoader.java
@@ -0,0 +1,8 @@
+package us.myles.ViaVersion.api.platform;
+
+public interface ViaPlatformLoader {
+ /**
+ * Initialise the loading for a platform, eg. registering listeners / providers / events etc.
+ */
+ void load();
+}
diff --git a/common/src/main/java/us/myles/ViaVersion/api/platform/providers/Provider.java b/common/src/main/java/us/myles/ViaVersion/api/platform/providers/Provider.java
new file mode 100644
index 000000000..f9a6c4d77
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/api/platform/providers/Provider.java
@@ -0,0 +1,4 @@
+package us.myles.ViaVersion.api.platform.providers;
+
+public interface Provider {
+}
diff --git a/common/src/main/java/us/myles/ViaVersion/api/platform/providers/ViaProviders.java b/common/src/main/java/us/myles/ViaVersion/api/platform/providers/ViaProviders.java
new file mode 100644
index 000000000..6911a5217
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/api/platform/providers/ViaProviders.java
@@ -0,0 +1,37 @@
+package us.myles.ViaVersion.api.platform.providers;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ViaProviders {
+ private final Map, Provider> providers = new HashMap<>();
+ private final List> lonelyProviders = new ArrayList<>();
+
+ public void require(Class extends Provider> provider) {
+ lonelyProviders.add(provider);
+ }
+
+ public void register(Class provider, T value) {
+ providers.put(provider, value);
+ }
+
+ public void use(Class provider, T value) {
+ if (lonelyProviders.contains(provider)) {
+ lonelyProviders.remove(provider);
+ }
+ providers.put(provider, value);
+ }
+
+ public T get(Class provider) {
+ if (providers.containsKey(provider)) {
+ return (T) providers.get(provider);
+ } else {
+ if (lonelyProviders.contains(provider)) {
+ throw new IllegalStateException("There was no provider for " + provider + ", one is required!");
+ }
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/us/myles/ViaVersion/api/protocol/Protocol.java b/common/src/main/java/us/myles/ViaVersion/api/protocol/Protocol.java
similarity index 89%
rename from src/main/java/us/myles/ViaVersion/api/protocol/Protocol.java
rename to common/src/main/java/us/myles/ViaVersion/api/protocol/Protocol.java
index 075063c2b..c2c5a8711 100644
--- a/src/main/java/us/myles/ViaVersion/api/protocol/Protocol.java
+++ b/common/src/main/java/us/myles/ViaVersion/api/protocol/Protocol.java
@@ -5,6 +5,7 @@ import lombok.Getter;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.Pair;
import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.api.platform.providers.ViaProviders;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.exception.CancelException;
import us.myles.ViaVersion.packets.Direction;
@@ -15,8 +16,8 @@ import java.util.List;
import java.util.Map;
public abstract class Protocol {
- private Map, ProtocolPacket> incoming = new HashMap<>();
- private Map, ProtocolPacket> outgoing = new HashMap<>();
+ private final Map, ProtocolPacket> incoming = new HashMap<>();
+ private final Map, ProtocolPacket> outgoing = new HashMap<>();
public Protocol() {
registerPackets();
@@ -47,11 +48,23 @@ public abstract class Protocol {
/**
* Register listeners for this protocol
+ *
+ * @deprecated No longer used as listeners are registered in {@link us.myles.ViaVersion.api.platform.ViaPlatformLoader#load}
*/
+ @Deprecated
protected void registerListeners() {
}
+ /**
+ * Handle protocol registration phase, use this to register providers / tasks.
+ *
+ * @param providers The current providers
+ */
+ protected void register(ViaProviders providers) {
+
+ }
+
/**
* Register the packets for this protocol
*/
diff --git a/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolPipeline.java b/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolPipeline.java
similarity index 94%
rename from src/main/java/us/myles/ViaVersion/api/protocol/ProtocolPipeline.java
rename to common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolPipeline.java
index cf0b03385..f8226a775 100644
--- a/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolPipeline.java
+++ b/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolPipeline.java
@@ -1,9 +1,9 @@
package us.myles.ViaVersion.api.protocol;
-import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.PacketWrapper;
-import us.myles.ViaVersion.api.ViaVersion;
+import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.api.platform.ViaPlatform;
import us.myles.ViaVersion.packets.Direction;
import us.myles.ViaVersion.packets.PacketType;
import us.myles.ViaVersion.packets.State;
@@ -74,7 +74,7 @@ public class ProtocolPipeline extends Protocol {
super.transform(direction, state, packetWrapper);
- if (ViaVersion.getInstance().isDebug()) {
+ if (Via.getManager().isDebug()) {
// Debug packet
String packet = "UNKNOWN";
@@ -109,12 +109,12 @@ public class ProtocolPipeline extends Protocol {
}
}
String name = packet + "[" + userConnection.get(ProtocolInfo.class).getProtocolVersion() + "]";
- ViaVersionPlugin plugin = (ViaVersionPlugin) ViaVersion.getInstance();
+ ViaPlatform platform = Via.getPlatform();
String actualUsername = packetWrapper.user().get(ProtocolInfo.class).getUsername();
String username = actualUsername != null ? actualUsername + " " : "";
- plugin.getLogger().log(Level.INFO, "{0}{1}: {2} {3} -> {4} [{5}] Value: {6}",
+ platform.getLogger().log(Level.INFO, "{0}{1}: {2} {3} -> {4} [{5}] Value: {6}",
new Object[]{
username,
direction,
@@ -162,4 +162,9 @@ public class ProtocolPipeline extends Protocol {
public List pipes() {
return protocolList;
}
+
+ public void cleanPipes() {
+ pipes().clear();
+ registerPackets();
+ }
}
diff --git a/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolRegistry.java b/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolRegistry.java
similarity index 88%
rename from src/main/java/us/myles/ViaVersion/api/protocol/ProtocolRegistry.java
rename to common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolRegistry.java
index d8349fc25..51f32af25 100644
--- a/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolRegistry.java
+++ b/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolRegistry.java
@@ -2,8 +2,8 @@ package us.myles.ViaVersion.api.protocol;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
-import org.bukkit.Bukkit;
import us.myles.ViaVersion.api.Pair;
+import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.protocols.base.BaseProtocol;
import us.myles.ViaVersion.protocols.protocol1_10to1_9_3.Protocol1_10To1_9_3_4;
import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.Protocol1_9_1_2TO1_9_3_4;
@@ -20,20 +20,20 @@ public class ProtocolRegistry {
public static final Protocol BASE_PROTOCOL = new BaseProtocol();
public static int SERVER_PROTOCOL = -1;
// Input Version -> Output Version & Protocol (Allows fast lookup)
- private static Map> registryMap = new ConcurrentHashMap<>();
- private static Map, List>> pathCache = new ConcurrentHashMap<>();
- private static List registerList = Lists.newCopyOnWriteArrayList();
- private static Set supportedVersions = Sets.newConcurrentHashSet();
+ private static final Map> registryMap = new ConcurrentHashMap<>();
+ private static final Map, List>> pathCache = new ConcurrentHashMap<>();
+ private static final List registerList = Lists.newCopyOnWriteArrayList();
+ private static final Set supportedVersions = Sets.newConcurrentHashSet();
static {
// Base Protocol
- registerProtocol(BASE_PROTOCOL, Arrays.asList(), -1);
+ registerProtocol(BASE_PROTOCOL, Collections.emptyList(), -1);
// Register built in protocols
registerProtocol(new Protocol1_9TO1_8(), Collections.singletonList(ProtocolVersion.v1_9.getId()), ProtocolVersion.v1_8.getId());
registerProtocol(new Protocol1_9_1TO1_9(), Arrays.asList(ProtocolVersion.v1_9_1.getId(), ProtocolVersion.v1_9_2.getId()), ProtocolVersion.v1_9.getId());
- registerProtocol(new Protocol1_9_3TO1_9_1_2(), Arrays.asList(ProtocolVersion.v1_9_3.getId()), ProtocolVersion.v1_9_2.getId());
+ registerProtocol(new Protocol1_9_3TO1_9_1_2(), Collections.singletonList(ProtocolVersion.v1_9_3.getId()), ProtocolVersion.v1_9_2.getId());
// Only supported for 1.9.4 server to 1.9 (nothing else)
- registerProtocol(new Protocol1_9TO1_9_1(), Arrays.asList(ProtocolVersion.v1_9.getId()), ProtocolVersion.v1_9_2.getId());
+ registerProtocol(new Protocol1_9TO1_9_1(), Collections.singletonList(ProtocolVersion.v1_9.getId()), ProtocolVersion.v1_9_2.getId());
registerProtocol(new Protocol1_9_1_2TO1_9_3_4(), Arrays.asList(ProtocolVersion.v1_9_1.getId(), ProtocolVersion.v1_9_2.getId()), ProtocolVersion.v1_9_3.getId());
registerProtocol(new Protocol1_10To1_9_3_4(), Collections.singletonList(ProtocolVersion.v1_10.getId()), ProtocolVersion.v1_9_3.getId());
@@ -61,8 +61,9 @@ public class ProtocolRegistry {
registryMap.get(version).put(output, protocol);
}
- if (Bukkit.getPluginManager().getPlugin("ViaVersion").isEnabled()) {
+ if (Via.getPlatform().isPluginEnabled()) {
protocol.registerListeners();
+ protocol.register(Via.getManager().getProviders());
refreshVersions();
} else {
registerList.add(protocol);
@@ -106,9 +107,10 @@ public class ProtocolRegistry {
/**
* Called when the server is enabled, to register any non registered listeners.
*/
- public static void registerListeners() {
+ public static void onServerLoaded() {
for (Protocol protocol : registerList) {
protocol.registerListeners();
+ protocol.register(Via.getManager().getProviders());
}
registerList.clear();
}
diff --git a/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolVersion.java b/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolVersion.java
similarity index 81%
rename from src/main/java/us/myles/ViaVersion/api/protocol/ProtocolVersion.java
rename to common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolVersion.java
index 98ec33ab3..735b5814f 100644
--- a/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolVersion.java
+++ b/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolVersion.java
@@ -51,7 +51,8 @@ public class ProtocolVersion {
register(v1_9_2 = new ProtocolVersion(109, "1.9.2"));
register(v1_9_3 = new ProtocolVersion(110, "1.9.3/4"));
register(v1_10 = new ProtocolVersion(210, "1.10"));
- register(vSNAPSHOT = new ProtocolVersion(309, "1.11-SNAPSHOT"));
+ // Snapshot uses colon as dashes are used other places...
+ register(vSNAPSHOT = new ProtocolVersion(309, "1.11:SNAPSHOT"));
register(unknown = new ProtocolVersion(-1, "UNKNOWN"));
}
@@ -80,6 +81,24 @@ public class ProtocolVersion {
return Collections.unmodifiableList(new ArrayList<>(versions.values()));
}
+ public static ProtocolVersion getClosest(String protocol) {
+ for (ProtocolVersion version : versions.values()) {
+ if (version.getName().equals(protocol))
+ return version;
+ if (version.getName().equals(protocol + ".x"))
+ return version;
+ String[] parts = version.getName().split("-");
+ for (String part : parts) {
+ if (part.equalsIgnoreCase(protocol)) {
+ return version;
+ }
+ if (part.equals(protocol + ".x"))
+ return version;
+ }
+ }
+ return null;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
diff --git a/src/main/java/us/myles/ViaVersion/api/remapper/PacketHandler.java b/common/src/main/java/us/myles/ViaVersion/api/remapper/PacketHandler.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/remapper/PacketHandler.java
rename to common/src/main/java/us/myles/ViaVersion/api/remapper/PacketHandler.java
diff --git a/src/main/java/us/myles/ViaVersion/api/remapper/PacketRemapper.java b/common/src/main/java/us/myles/ViaVersion/api/remapper/PacketRemapper.java
similarity index 97%
rename from src/main/java/us/myles/ViaVersion/api/remapper/PacketRemapper.java
rename to common/src/main/java/us/myles/ViaVersion/api/remapper/PacketRemapper.java
index c323e8aea..354f05614 100644
--- a/src/main/java/us/myles/ViaVersion/api/remapper/PacketRemapper.java
+++ b/common/src/main/java/us/myles/ViaVersion/api/remapper/PacketRemapper.java
@@ -9,7 +9,7 @@ import java.util.ArrayList;
import java.util.List;
public abstract class PacketRemapper {
- private List> valueRemappers = new ArrayList<>();
+ private final List> valueRemappers = new ArrayList<>();
public PacketRemapper() {
registerMap();
diff --git a/src/main/java/us/myles/ViaVersion/api/remapper/TypeRemapper.java b/common/src/main/java/us/myles/ViaVersion/api/remapper/TypeRemapper.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/remapper/TypeRemapper.java
rename to common/src/main/java/us/myles/ViaVersion/api/remapper/TypeRemapper.java
diff --git a/src/main/java/us/myles/ViaVersion/api/remapper/ValueCreator.java b/common/src/main/java/us/myles/ViaVersion/api/remapper/ValueCreator.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/remapper/ValueCreator.java
rename to common/src/main/java/us/myles/ViaVersion/api/remapper/ValueCreator.java
diff --git a/src/main/java/us/myles/ViaVersion/api/remapper/ValueReader.java b/common/src/main/java/us/myles/ViaVersion/api/remapper/ValueReader.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/remapper/ValueReader.java
rename to common/src/main/java/us/myles/ViaVersion/api/remapper/ValueReader.java
diff --git a/src/main/java/us/myles/ViaVersion/api/remapper/ValueTransformer.java b/common/src/main/java/us/myles/ViaVersion/api/remapper/ValueTransformer.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/remapper/ValueTransformer.java
rename to common/src/main/java/us/myles/ViaVersion/api/remapper/ValueTransformer.java
diff --git a/src/main/java/us/myles/ViaVersion/api/remapper/ValueWriter.java b/common/src/main/java/us/myles/ViaVersion/api/remapper/ValueWriter.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/remapper/ValueWriter.java
rename to common/src/main/java/us/myles/ViaVersion/api/remapper/ValueWriter.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/ByteBufReader.java b/common/src/main/java/us/myles/ViaVersion/api/type/ByteBufReader.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/ByteBufReader.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/ByteBufReader.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/ByteBufWriter.java b/common/src/main/java/us/myles/ViaVersion/api/type/ByteBufWriter.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/ByteBufWriter.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/ByteBufWriter.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/PartialType.java b/common/src/main/java/us/myles/ViaVersion/api/type/PartialType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/PartialType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/PartialType.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/Type.java b/common/src/main/java/us/myles/ViaVersion/api/type/Type.java
similarity index 97%
rename from src/main/java/us/myles/ViaVersion/api/type/Type.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/Type.java
index 938ed4da9..be9d577ec 100644
--- a/src/main/java/us/myles/ViaVersion/api/type/Type.java
+++ b/common/src/main/java/us/myles/ViaVersion/api/type/Type.java
@@ -2,10 +2,10 @@ package us.myles.ViaVersion.api.type;
import lombok.Getter;
-import org.bukkit.util.EulerAngle;
-import org.bukkit.util.Vector;
import org.spacehq.opennbt.tag.builtin.CompoundTag;
+import us.myles.ViaVersion.api.minecraft.EulerAngle;
import us.myles.ViaVersion.api.minecraft.Position;
+import us.myles.ViaVersion.api.minecraft.Vector;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.type.types.*;
import us.myles.ViaVersion.api.type.types.minecraft.*;
diff --git a/src/main/java/us/myles/ViaVersion/api/type/TypeConverter.java b/common/src/main/java/us/myles/ViaVersion/api/type/TypeConverter.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/TypeConverter.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/TypeConverter.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/ArrayType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/ArrayType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/ArrayType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/ArrayType.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/BooleanType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/BooleanType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/BooleanType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/BooleanType.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/ByteType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/ByteType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/ByteType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/ByteType.java
diff --git a/common/src/main/java/us/myles/ViaVersion/api/type/types/CustomByteType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/CustomByteType.java
new file mode 100644
index 000000000..097209490
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/CustomByteType.java
@@ -0,0 +1,26 @@
+package us.myles.ViaVersion.api.type.types;
+
+import io.netty.buffer.ByteBuf;
+import us.myles.ViaVersion.api.type.PartialType;
+
+public class CustomByteType extends PartialType {
+
+ public CustomByteType(Integer param) {
+ super(param, byte[].class);
+ }
+
+ @Override
+ public byte[] read(ByteBuf byteBuf, Integer integer) throws Exception {
+ if (byteBuf.readableBytes() < integer) throw new RuntimeException("Readable bytes does not match expected!");
+
+ byte[] byteArray = new byte[integer];
+ byteBuf.readBytes(byteArray);
+
+ return byteArray;
+ }
+
+ @Override
+ public void write(ByteBuf byteBuf, Integer integer, byte[] bytes) throws Exception {
+ byteBuf.writeBytes(bytes);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/DoubleType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/DoubleType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/DoubleType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/DoubleType.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/FloatType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/FloatType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/FloatType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/FloatType.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/IntType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/IntType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/IntType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/IntType.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/LongType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/LongType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/LongType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/LongType.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/RemainingBytesType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/RemainingBytesType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/RemainingBytesType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/RemainingBytesType.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/ShortType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/ShortType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/ShortType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/ShortType.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/StringType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/StringType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/StringType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/StringType.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/UUIDType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/UUIDType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/UUIDType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/UUIDType.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/UnsignedByteType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/UnsignedByteType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/UnsignedByteType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/UnsignedByteType.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/UnsignedShortType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/UnsignedShortType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/UnsignedShortType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/UnsignedShortType.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/VarIntType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/VarIntType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/VarIntType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/VarIntType.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/VoidType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/VoidType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/VoidType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/VoidType.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/BaseChunkType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/BaseChunkType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/minecraft/BaseChunkType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/BaseChunkType.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/EulerAngleType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/EulerAngleType.java
similarity index 74%
rename from src/main/java/us/myles/ViaVersion/api/type/types/minecraft/EulerAngleType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/EulerAngleType.java
index 5d324dd62..f4287769a 100644
--- a/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/EulerAngleType.java
+++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/EulerAngleType.java
@@ -1,7 +1,7 @@
package us.myles.ViaVersion.api.type.types.minecraft;
import io.netty.buffer.ByteBuf;
-import org.bukkit.util.EulerAngle;
+import us.myles.ViaVersion.api.minecraft.EulerAngle;
import us.myles.ViaVersion.api.type.Type;
public class EulerAngleType extends Type {
@@ -20,8 +20,8 @@ public class EulerAngleType extends Type {
@Override
public void write(ByteBuf buffer, EulerAngle object) throws Exception {
- Type.FLOAT.write(buffer, (float) object.getX());
- Type.FLOAT.write(buffer, (float) object.getY());
- Type.FLOAT.write(buffer, (float) object.getZ());
+ Type.FLOAT.write(buffer, object.getX());
+ Type.FLOAT.write(buffer, object.getY());
+ Type.FLOAT.write(buffer, object.getZ());
}
}
\ No newline at end of file
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/ItemArrayType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/ItemArrayType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/minecraft/ItemArrayType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/ItemArrayType.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/ItemType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/ItemType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/minecraft/ItemType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/ItemType.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/MetaListTypeTemplate.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/MetaListTypeTemplate.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/minecraft/MetaListTypeTemplate.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/MetaListTypeTemplate.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/MetaTypeTemplate.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/MetaTypeTemplate.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/minecraft/MetaTypeTemplate.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/MetaTypeTemplate.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/NBTType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/NBTType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/minecraft/NBTType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/NBTType.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/OptPositionType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/OptPositionType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/minecraft/OptPositionType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/OptPositionType.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/OptUUIDType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/OptUUIDType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/minecraft/OptUUIDType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/OptUUIDType.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/PositionType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/PositionType.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/minecraft/PositionType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/PositionType.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/VectorType.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/VectorType.java
similarity index 93%
rename from src/main/java/us/myles/ViaVersion/api/type/types/minecraft/VectorType.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/VectorType.java
index 968e4413e..17299241d 100644
--- a/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/VectorType.java
+++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/minecraft/VectorType.java
@@ -1,7 +1,7 @@
package us.myles.ViaVersion.api.type.types.minecraft;
import io.netty.buffer.ByteBuf;
-import org.bukkit.util.Vector;
+import us.myles.ViaVersion.api.minecraft.Vector;
import us.myles.ViaVersion.api.type.Type;
public class VectorType extends Type {
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/version/Metadata1_8Type.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/Metadata1_8Type.java
similarity index 64%
rename from src/main/java/us/myles/ViaVersion/api/type/types/version/Metadata1_8Type.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/version/Metadata1_8Type.java
index cb46b8256..6f3ad63e7 100644
--- a/src/main/java/us/myles/ViaVersion/api/type/types/version/Metadata1_8Type.java
+++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/Metadata1_8Type.java
@@ -3,8 +3,8 @@ package us.myles.ViaVersion.api.type.types.version;
import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
+import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_8;
import us.myles.ViaVersion.api.type.types.minecraft.MetaTypeTemplate;
-import us.myles.ViaVersion.protocols.protocol1_9to1_8.metadata.MetadataTypes;
public class Metadata1_8Type extends MetaTypeTemplate {
@@ -13,15 +13,15 @@ public class Metadata1_8Type extends MetaTypeTemplate {
byte item = buffer.readByte();
if (item == 127) return null; // end of metadata
int typeID = (item & 0xE0) >> 5;
- MetadataTypes type = MetadataTypes.byId(typeID);
+ MetaType1_8 type = MetaType1_8.byId(typeID);
int id = item & 0x1F;
- return new Metadata(id, typeID, type.getType(), type.getType().read(buffer));
+ return new Metadata(id, type, type.getType().read(buffer));
}
@Override
public void write(ByteBuf buffer, Metadata meta) throws Exception {
- byte item = (byte) (meta.getTypeID() << 5 | meta.getId() & 0x1F);
+ byte item = (byte) (meta.getMetaType().getTypeID() << 5 | meta.getId() & 0x1F);
buffer.writeByte(item);
- meta.getType().write(buffer, meta.getValue());
+ meta.getMetaType().getType().write(buffer, meta.getValue());
}
}
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/version/Metadata1_9Type.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/Metadata1_9Type.java
similarity index 66%
rename from src/main/java/us/myles/ViaVersion/api/type/types/version/Metadata1_9Type.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/version/Metadata1_9Type.java
index fb541263c..7d87f7931 100644
--- a/src/main/java/us/myles/ViaVersion/api/type/types/version/Metadata1_9Type.java
+++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/Metadata1_9Type.java
@@ -2,8 +2,8 @@ package us.myles.ViaVersion.api.type.types.version;
import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
+import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_9;
import us.myles.ViaVersion.api.type.types.minecraft.MetaTypeTemplate;
-import us.myles.ViaVersion.protocols.protocol1_9to1_8.metadata.NewType;
public class Metadata1_9Type extends MetaTypeTemplate {
@@ -12,9 +12,9 @@ public class Metadata1_9Type extends MetaTypeTemplate {
short index = buffer.readUnsignedByte();
if (index == 0xff) return null; //End of metadata
- NewType type = NewType.byId(buffer.readByte());
+ MetaType1_9 type = MetaType1_9.byId(buffer.readByte());
- return new Metadata(index, type.getTypeID(), type.getType(), type.getType().read(buffer));
+ return new Metadata(index, type, type.getType().read(buffer));
}
@Override
@@ -23,8 +23,8 @@ public class Metadata1_9Type extends MetaTypeTemplate {
buffer.writeByte(255);
} else {
buffer.writeByte(object.getId());
- buffer.writeByte(object.getTypeID());
- object.getType().write(buffer, object.getValue());
+ buffer.writeByte(object.getMetaType().getTypeID());
+ object.getMetaType().getType().write(buffer, object.getValue());
}
}
}
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/version/MetadataList1_8Type.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/MetadataList1_8Type.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/version/MetadataList1_8Type.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/version/MetadataList1_8Type.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/version/MetadataList1_9Type.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/MetadataList1_9Type.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/version/MetadataList1_9Type.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/version/MetadataList1_9Type.java
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/version/Types1_8.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/Types1_8.java
similarity index 65%
rename from src/main/java/us/myles/ViaVersion/api/type/types/version/Types1_8.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/version/Types1_8.java
index cb0241801..49ca88fae 100644
--- a/src/main/java/us/myles/ViaVersion/api/type/types/version/Types1_8.java
+++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/Types1_8.java
@@ -9,10 +9,10 @@ public class Types1_8 {
/**
* Metadata list type for 1.8
*/
- public static Type> METADATA_LIST = new MetadataList1_8Type();
+ public static final Type> METADATA_LIST = new MetadataList1_8Type();
/**
* Metadata type for 1.8
*/
- public static Type METADATA = new Metadata1_8Type();
+ public static final Type METADATA = new Metadata1_8Type();
}
diff --git a/src/main/java/us/myles/ViaVersion/api/type/types/version/Types1_9.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/Types1_9.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/api/type/types/version/Types1_9.java
rename to common/src/main/java/us/myles/ViaVersion/api/type/types/version/Types1_9.java
diff --git a/src/main/java/us/myles/ViaVersion/boss/ViaBossBar.java b/common/src/main/java/us/myles/ViaVersion/boss/CommonBoss.java
similarity index 76%
rename from src/main/java/us/myles/ViaVersion/boss/ViaBossBar.java
rename to common/src/main/java/us/myles/ViaVersion/boss/CommonBoss.java
index eacbbfa86..7cc89d0c5 100644
--- a/src/main/java/us/myles/ViaVersion/boss/ViaBossBar.java
+++ b/common/src/main/java/us/myles/ViaVersion/boss/CommonBoss.java
@@ -1,13 +1,12 @@
package us.myles.ViaVersion.boss;
+import com.google.common.base.Preconditions;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.Getter;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
-import org.apache.commons.lang.Validate;
-import org.bukkit.entity.Player;
-import us.myles.ViaVersion.api.ViaVersion;
+import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.boss.BossBar;
import us.myles.ViaVersion.api.boss.BossColor;
import us.myles.ViaVersion.api.boss.BossFlag;
@@ -19,7 +18,7 @@ import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
import java.util.*;
@Getter
-public class ViaBossBar implements BossBar {
+public abstract class CommonBoss extends BossBar {
private UUID uuid;
private String title;
private float health;
@@ -29,9 +28,10 @@ public class ViaBossBar implements BossBar {
private boolean visible;
private Set flags;
- public ViaBossBar(String title, float health, BossColor color, BossStyle style) {
- Validate.notNull(title, "Title cannot be null");
- Validate.isTrue((health >= 0 && health <= 1), "Health must be between 0 and 1");
+ public CommonBoss(String title, float health, BossColor color, BossStyle style) {
+ Preconditions.checkNotNull(title, "Title cannot be null");
+ Preconditions.checkArgument((health >= 0 && health <= 1), "Health must be between 0 and 1");
+
this.uuid = UUID.randomUUID();
this.title = title;
this.health = health;
@@ -45,15 +45,15 @@ public class ViaBossBar implements BossBar {
@Override
public BossBar setTitle(@NonNull String title) {
this.title = title;
- sendPacket(UpdateAction.UPDATE_TITLE);
+ sendPacket(CommonBoss.UpdateAction.UPDATE_TITLE);
return this;
}
@Override
public BossBar setHealth(float health) {
- Validate.isTrue((health >= 0 && health <= 1), "Health must be between 0 and 1");
+ Preconditions.checkArgument((health >= 0 && health <= 1), "Health must be between 0 and 1");
this.health = health;
- sendPacket(UpdateAction.UPDATE_HEALTH);
+ sendPacket(CommonBoss.UpdateAction.UPDATE_HEALTH);
return this;
}
@@ -65,53 +65,41 @@ public class ViaBossBar implements BossBar {
@Override
public BossBar setColor(@NonNull BossColor color) {
this.color = color;
- sendPacket(UpdateAction.UPDATE_STYLE);
+ sendPacket(CommonBoss.UpdateAction.UPDATE_STYLE);
return this;
}
@Override
public BossBar setStyle(@NonNull BossStyle style) {
this.style = style;
- sendPacket(UpdateAction.UPDATE_STYLE);
+ sendPacket(CommonBoss.UpdateAction.UPDATE_STYLE);
return this;
}
- @Override
- public BossBar addPlayer(@NonNull Player player) {
- return addPlayer(player.getUniqueId());
- }
-
@Override
public BossBar addPlayer(UUID player) {
if (!players.contains(player)) {
players.add(player);
if (visible)
- sendPacket(player, getPacket(UpdateAction.ADD));
+ sendPacket(player, getPacket(CommonBoss.UpdateAction.ADD));
}
return this;
}
@Override
- public BossBar removePlayer(@NonNull Player player) {
- if (players.contains(player.getUniqueId())) {
- players.remove(player.getUniqueId());
- sendPacket(player.getUniqueId(), getPacket(UpdateAction.REMOVE));
+ public BossBar removePlayer(UUID uuid) {
+ if (players.contains(uuid)) {
+ players.remove(uuid);
+ sendPacket(uuid, getPacket(UpdateAction.REMOVE));
}
return this;
}
- @Override
- public BossBar addPlayers(@NonNull Player... players) {
- for (Player p : players)
- addPlayer(p);
- return this;
- }
-
@Override
public BossBar addFlag(@NonNull BossFlag flag) {
if (!hasFlag(flag))
flags.add(flag);
- sendPacket(UpdateAction.UPDATE_FLAGS);
+ sendPacket(CommonBoss.UpdateAction.UPDATE_FLAGS);
return this;
}
@@ -119,7 +107,7 @@ public class ViaBossBar implements BossBar {
public BossBar removeFlag(@NonNull BossFlag flag) {
if (hasFlag(flag))
flags.remove(flag);
- sendPacket(UpdateAction.UPDATE_FLAGS);
+ sendPacket(CommonBoss.UpdateAction.UPDATE_FLAGS);
return this;
}
@@ -153,7 +141,7 @@ public class ViaBossBar implements BossBar {
private void setVisible(boolean value) {
if (visible != value) {
visible = value;
- sendPacket(value ? UpdateAction.ADD : UpdateAction.REMOVE);
+ sendPacket(value ? CommonBoss.UpdateAction.ADD : CommonBoss.UpdateAction.REMOVE);
}
}
@@ -165,12 +153,12 @@ public class ViaBossBar implements BossBar {
}
private void sendPacket(UUID uuid, ByteBuf buf) {
- if (!ViaVersion.getInstance().isPorted(uuid) || !(ViaVersion.getInstance().getPlayerVersion(uuid) >= ProtocolVersion.v1_9.getId())) {
+ if (!Via.getAPI().isPorted(uuid) || !(Via.getAPI().getPlayerVersion(uuid) >= ProtocolVersion.v1_9.getId())) {
players.remove(uuid);
buf.release();
return;
}
- ViaVersion.getInstance().sendRawPacket(uuid, buf);
+ Via.getAPI().sendRawPacket(uuid, buf);
}
private ByteBuf getPacket(UpdateAction action) {
diff --git a/src/main/java/us/myles/ViaVersion/commands/ViaCommandHandler.java b/common/src/main/java/us/myles/ViaVersion/commands/ViaCommandHandler.java
similarity index 73%
rename from src/main/java/us/myles/ViaVersion/commands/ViaCommandHandler.java
rename to common/src/main/java/us/myles/ViaVersion/commands/ViaCommandHandler.java
index c67230529..00ac8421b 100644
--- a/src/main/java/us/myles/ViaVersion/commands/ViaCommandHandler.java
+++ b/common/src/main/java/us/myles/ViaVersion/commands/ViaCommandHandler.java
@@ -1,21 +1,18 @@
package us.myles.ViaVersion.commands;
+import com.google.common.base.Preconditions;
import lombok.NonNull;
-import org.apache.commons.lang.Validate;
-import org.bukkit.ChatColor;
-import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
-import org.bukkit.command.CommandSender;
-import org.bukkit.command.TabCompleter;
-import us.myles.ViaVersion.api.ViaVersion;
+import net.md_5.bungee.api.ChatColor;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.command.ViaCommandSender;
import us.myles.ViaVersion.api.command.ViaSubCommand;
import us.myles.ViaVersion.api.command.ViaVersionCommand;
import us.myles.ViaVersion.commands.defaultsubs.*;
import java.util.*;
-public class ViaCommandHandler implements ViaVersionCommand, CommandExecutor, TabCompleter {
- private Map commandMap;
+public abstract class ViaCommandHandler implements ViaVersionCommand {
+ private final Map commandMap;
public ViaCommandHandler() {
commandMap = new HashMap<>();
@@ -28,7 +25,7 @@ public class ViaCommandHandler implements ViaVersionCommand, CommandExecutor, Ta
@Override
public void registerSubCommand(@NonNull ViaSubCommand command) throws Exception {
- Validate.isTrue(command.name().matches("^[a-z0-9_-]{3,15}$"), command.name() + " is not a valid subcommand name");
+ Preconditions.checkArgument(command.name().matches("^[a-z0-9_-]{3,15}$"), command.name() + " is not a valid subcommand name");
if (hasSubCommand(command.name()))
throw new Exception("ViaSubCommand " + command.name() + " does already exists!"); //Maybe another exception later.
commandMap.put(command.name().toLowerCase(), command);
@@ -45,21 +42,21 @@ public class ViaCommandHandler implements ViaVersionCommand, CommandExecutor, Ta
}
@Override
- public boolean onCommand(CommandSender sender, Command cmd, String arg, String[] args) {
+ public boolean onCommand(ViaCommandSender sender, String[] args) {
if (args.length == 0) {
showHelp(sender);
return false;
}
if (!hasSubCommand(args[0])) {
- sender.sendMessage(color("&cThis command is not found"));
+ sender.sendMessage(color("&cThis commands is not found"));
showHelp(sender);
return false;
}
ViaSubCommand handler = getSubCommand(args[0]);
if (!hasPermission(sender, handler.permission())) {
- sender.sendMessage(color("&cYou are not allowed to use this command!"));
+ sender.sendMessage(color("&cYou are not allowed to use this commands!"));
return false;
}
@@ -71,7 +68,7 @@ public class ViaCommandHandler implements ViaVersionCommand, CommandExecutor, Ta
}
@Override
- public List onTabComplete(CommandSender sender, Command command, String arg, String[] args) {
+ public List onTabComplete(ViaCommandSender sender, String[] args) {
Set allowed = calculateAllowedCommands(sender);
List output = new ArrayList<>();
@@ -103,20 +100,25 @@ public class ViaCommandHandler implements ViaVersionCommand, CommandExecutor, Ta
return output;
}
- public void showHelp(CommandSender sender) {
+ /**
+ * Shows the ViaVersion help to a sender
+ *
+ * @param sender The sender to send the help to
+ */
+ public void showHelp(ViaCommandSender sender) {
Set allowed = calculateAllowedCommands(sender);
if (allowed.size() == 0) {
- sender.sendMessage(color("&cYou are not allowed to use this command!"));
+ sender.sendMessage(color("&cYou are not allowed to use this commands!"));
return;
}
- sender.sendMessage(color("&aViaVersion &c" + ViaVersion.getInstance().getVersion()));
+ sender.sendMessage(color("&aViaVersion &c" + Via.getPlatform().getPluginVersion()));
sender.sendMessage(color("&6Commands:"));
for (ViaSubCommand cmd : allowed)
sender.sendMessage(color(String.format("&2/viaversion %s &7- &6%s", cmd.usage(), cmd.description())));
allowed.clear();
}
- private Set calculateAllowedCommands(CommandSender sender) {
+ private Set calculateAllowedCommands(ViaCommandSender sender) {
Set cmds = new HashSet<>();
for (ViaSubCommand sub : commandMap.values())
if (hasPermission(sender, sub.permission()))
@@ -124,7 +126,7 @@ public class ViaCommandHandler implements ViaVersionCommand, CommandExecutor, Ta
return cmds;
}
- private boolean hasPermission(CommandSender sender, String permission) {
+ private boolean hasPermission(ViaCommandSender sender, String permission) {
return permission == null || sender.hasPermission(permission);
}
@@ -140,6 +142,12 @@ public class ViaCommandHandler implements ViaVersionCommand, CommandExecutor, Ta
registerSubCommand(new ReloadSubCmd());
}
+ /**
+ * Replaces colour codes in a string
+ *
+ * @param string String to replace
+ * @return The output String
+ */
public static String color(String string) {
try {
string = ChatColor.translateAlternateColorCodes('&', string); //Dont replace all & with $ like we did before.
@@ -148,7 +156,14 @@ public class ViaCommandHandler implements ViaVersionCommand, CommandExecutor, Ta
return string;
}
- public static void sendMessage(@NonNull CommandSender sender, String message, Object... args) {
+ /**
+ * Send a colour coded string with replacements to a user
+ *
+ * @param sender The target to send the message to
+ * @param message The message
+ * @param args The objects to replace
+ */
+ public static void sendMessage(@NonNull ViaCommandSender sender, String message, Object... args) {
sender.sendMessage(color(args == null ? message : String.format(message, args)));
}
}
diff --git a/src/main/java/us/myles/ViaVersion/commands/defaultsubs/AutoTeamSubCmd.java b/common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/AutoTeamSubCmd.java
similarity index 58%
rename from src/main/java/us/myles/ViaVersion/commands/defaultsubs/AutoTeamSubCmd.java
rename to common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/AutoTeamSubCmd.java
index 0217f12d8..eeecc9188 100644
--- a/src/main/java/us/myles/ViaVersion/commands/defaultsubs/AutoTeamSubCmd.java
+++ b/common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/AutoTeamSubCmd.java
@@ -1,9 +1,9 @@
package us.myles.ViaVersion.commands.defaultsubs;
-import org.bukkit.command.CommandSender;
-import us.myles.ViaVersion.ViaVersionPlugin;
-import us.myles.ViaVersion.api.ViaVersion;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.command.ViaCommandSender;
import us.myles.ViaVersion.api.command.ViaSubCommand;
+import us.myles.ViaVersion.api.configuration.ConfigurationProvider;
public class AutoTeamSubCmd extends ViaSubCommand {
@Override
@@ -17,12 +17,12 @@ public class AutoTeamSubCmd extends ViaSubCommand {
}
@Override
- public boolean execute(CommandSender sender, String[] args) {
- ViaVersionPlugin plugin = (ViaVersionPlugin) ViaVersion.getInstance();
+ public boolean execute(ViaCommandSender sender, String[] args) {
+ ConfigurationProvider provider = Via.getPlatform().getConfigurationProvider();
+ boolean newValue = !Via.getConfig().isAutoTeam();
- boolean newValue = !ViaVersion.getConfig().isAutoTeam();
- plugin.getConfig().set("auto-team", newValue);
- plugin.saveConfig();
+ provider.set("auto-team", newValue);
+ provider.saveConfig();
sendMessage(sender, "&6We will %s", (newValue ? "&aautomatically team players" : "&cno longer auto team players"));
sendMessage(sender, "&6All players will need to re-login for the change to take place.");
diff --git a/common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/DebugSubCmd.java b/common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/DebugSubCmd.java
new file mode 100644
index 000000000..47396264c
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/DebugSubCmd.java
@@ -0,0 +1,24 @@
+package us.myles.ViaVersion.commands.defaultsubs;
+
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.command.ViaCommandSender;
+import us.myles.ViaVersion.api.command.ViaSubCommand;
+
+public class DebugSubCmd extends ViaSubCommand {
+ @Override
+ public String name() {
+ return "debug";
+ }
+
+ @Override
+ public String description() {
+ return "Toggle debug mode";
+ }
+
+ @Override
+ public boolean execute(ViaCommandSender sender, String[] args) {
+ Via.getManager().setDebug(!Via.getManager().isDebug());
+ sendMessage(sender, "&6Debug mode is now %s", (Via.getManager().isDebug() ? "&aenabled" : "&cdisabled"));
+ return true;
+ }
+}
diff --git a/src/main/java/us/myles/ViaVersion/commands/defaultsubs/DisplayLeaksSubCmd.java b/common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/DisplayLeaksSubCmd.java
similarity index 87%
rename from src/main/java/us/myles/ViaVersion/commands/defaultsubs/DisplayLeaksSubCmd.java
rename to common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/DisplayLeaksSubCmd.java
index 8701d9f6f..5710105db 100644
--- a/src/main/java/us/myles/ViaVersion/commands/defaultsubs/DisplayLeaksSubCmd.java
+++ b/common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/DisplayLeaksSubCmd.java
@@ -1,7 +1,7 @@
package us.myles.ViaVersion.commands.defaultsubs;
import io.netty.util.ResourceLeakDetector;
-import org.bukkit.command.CommandSender;
+import us.myles.ViaVersion.api.command.ViaCommandSender;
import us.myles.ViaVersion.api.command.ViaSubCommand;
public class DisplayLeaksSubCmd extends ViaSubCommand {
@@ -16,7 +16,7 @@ public class DisplayLeaksSubCmd extends ViaSubCommand {
}
@Override
- public boolean execute(CommandSender sender, String[] args) {
+ public boolean execute(ViaCommandSender sender, String[] args) {
if (ResourceLeakDetector.getLevel() != ResourceLeakDetector.Level.ADVANCED)
ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.ADVANCED);
else
diff --git a/src/main/java/us/myles/ViaVersion/commands/defaultsubs/DontBugMeSubCmd.java b/common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/DontBugMeSubCmd.java
similarity index 50%
rename from src/main/java/us/myles/ViaVersion/commands/defaultsubs/DontBugMeSubCmd.java
rename to common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/DontBugMeSubCmd.java
index f99936c0d..95d92d27d 100644
--- a/src/main/java/us/myles/ViaVersion/commands/defaultsubs/DontBugMeSubCmd.java
+++ b/common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/DontBugMeSubCmd.java
@@ -1,9 +1,9 @@
package us.myles.ViaVersion.commands.defaultsubs;
-import org.bukkit.command.CommandSender;
-import us.myles.ViaVersion.ViaVersionPlugin;
-import us.myles.ViaVersion.api.ViaVersion;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.command.ViaCommandSender;
import us.myles.ViaVersion.api.command.ViaSubCommand;
+import us.myles.ViaVersion.api.configuration.ConfigurationProvider;
public class DontBugMeSubCmd extends ViaSubCommand {
@Override
@@ -17,12 +17,12 @@ public class DontBugMeSubCmd extends ViaSubCommand {
}
@Override
- public boolean execute(CommandSender sender, String[] args) {
- ViaVersionPlugin plugin = (ViaVersionPlugin) ViaVersion.getInstance();
+ public boolean execute(ViaCommandSender sender, String[] args) {
+ ConfigurationProvider provider = Via.getPlatform().getConfigurationProvider();
+ boolean newValue = !Via.getConfig().isCheckForUpdates();
- boolean newValue = !ViaVersion.getConfig().isCheckForUpdates();
- plugin.getConfig().set("checkforupdates", newValue);
- plugin.saveConfig();
+ provider.set("checkforupdates", newValue);
+ provider.saveConfig();
sendMessage(sender, "&6We will %snotify you about updates.", (newValue ? "&a" : "&cnot "));
return true;
diff --git a/src/main/java/us/myles/ViaVersion/commands/defaultsubs/DumpSubCmd.java b/common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/DumpSubCmd.java
similarity index 58%
rename from src/main/java/us/myles/ViaVersion/commands/defaultsubs/DumpSubCmd.java
rename to common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/DumpSubCmd.java
index 03ad3472d..6c99ee559 100644
--- a/src/main/java/us/myles/ViaVersion/commands/defaultsubs/DumpSubCmd.java
+++ b/common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/DumpSubCmd.java
@@ -1,19 +1,14 @@
package us.myles.ViaVersion.commands.defaultsubs;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
-import org.bukkit.Bukkit;
-import org.bukkit.ChatColor;
-import org.bukkit.command.CommandSender;
-import org.bukkit.plugin.Plugin;
-import us.myles.ViaVersion.ViaVersionPlugin;
-import us.myles.ViaVersion.api.ViaVersion;
+import net.md_5.bungee.api.ChatColor;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.command.ViaCommandSender;
import us.myles.ViaVersion.api.command.ViaSubCommand;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
import us.myles.ViaVersion.dump.DumpTemplate;
-import us.myles.ViaVersion.dump.PluginInfo;
import us.myles.ViaVersion.dump.VersionInfo;
+import us.myles.ViaVersion.util.GsonUtil;
import java.io.InputStreamReader;
import java.io.InvalidObjectException;
@@ -21,13 +16,10 @@ import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Map;
import java.util.logging.Level;
public class DumpSubCmd extends ViaSubCommand {
- private final Gson gson = new GsonBuilder().setPrettyPrinting().create();
@Override
public String name() {
@@ -40,24 +32,21 @@ public class DumpSubCmd extends ViaSubCommand {
}
@Override
- public boolean execute(final CommandSender sender, String[] args) {
+ public boolean execute(final ViaCommandSender sender, String[] args) {
VersionInfo version = new VersionInfo(
- Bukkit.getServer().getVersion(),
- Bukkit.getServer().getBukkitVersion(),
System.getProperty("java.version"),
System.getProperty("os.name"),
ProtocolRegistry.SERVER_PROTOCOL,
- ProtocolRegistry.getSupportedVersions());
+ ProtocolRegistry.getSupportedVersions(),
+ Via.getPlatform().getPlatformName(),
+ Via.getPlatform().getPluginVersion()
+ );
- List plugins = new ArrayList<>();
- for (Plugin p : Bukkit.getPluginManager().getPlugins())
- plugins.add(new PluginInfo(p.isEnabled(), p.getDescription().getName(), p.getDescription().getVersion(), p.getDescription().getMain(), p.getDescription().getAuthors()));
+ Map configuration = Via.getPlatform().getConfigurationProvider().getValues();
- Map configuration = ((ViaVersionPlugin) ViaVersion.getInstance()).getConfig().getValues(false);
+ final DumpTemplate template = new DumpTemplate(version, configuration, Via.getPlatform().getDump());
- final DumpTemplate template = new DumpTemplate(version, configuration, plugins);
-
- Bukkit.getScheduler().runTaskAsynchronously((ViaVersionPlugin) ViaVersion.getInstance(), new Runnable() {
+ Via.getPlatform().runAsync(new Runnable() {
@Override
public void run() {
try {
@@ -68,10 +57,10 @@ public class DumpSubCmd extends ViaSubCommand {
con.setDoOutput(true);
OutputStream out = con.getOutputStream();
- out.write(gson.toJson(template).getBytes(Charset.forName("UTF-8")));
+ out.write(GsonUtil.getGsonBuilder().setPrettyPrinting().create().toJson(template).getBytes(Charset.forName("UTF-8")));
out.close();
- JsonObject output = gson.fromJson(new InputStreamReader(con.getInputStream()), JsonObject.class);
+ JsonObject output = GsonUtil.getGson().fromJson(new InputStreamReader(con.getInputStream()), JsonObject.class);
con.getInputStream().close();
if (!output.has("key"))
@@ -80,7 +69,7 @@ public class DumpSubCmd extends ViaSubCommand {
sender.sendMessage(ChatColor.GREEN + "We've made a dump with useful information, report your issue and provide this url: " + getUrl(output.get("key").getAsString()));
} catch (Exception e) {
sender.sendMessage(ChatColor.RED + "Failed to dump, please check the console for more information");
- ((ViaVersionPlugin) ViaVersion.getInstance()).getLogger().log(Level.WARNING, "Could not paste ViaVersion dump to Hastebin", e);
+ Via.getPlatform().getLogger().log(Level.WARNING, "Could not paste ViaVersion dump to Hastebin", e);
}
}
});
diff --git a/common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/HelpSubCmd.java b/common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/HelpSubCmd.java
new file mode 100644
index 000000000..96983349a
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/HelpSubCmd.java
@@ -0,0 +1,23 @@
+package us.myles.ViaVersion.commands.defaultsubs;
+
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.command.ViaCommandSender;
+import us.myles.ViaVersion.api.command.ViaSubCommand;
+
+public class HelpSubCmd extends ViaSubCommand {
+ @Override
+ public String name() {
+ return "help";
+ }
+
+ @Override
+ public String description() {
+ return "You are looking at it right now!";
+ }
+
+ @Override
+ public boolean execute(ViaCommandSender sender, String[] args) {
+ Via.getManager().getCommandHandler().showHelp(sender);
+ return true;
+ }
+}
diff --git a/src/main/java/us/myles/ViaVersion/commands/defaultsubs/ListSubCmd.java b/common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/ListSubCmd.java
similarity index 79%
rename from src/main/java/us/myles/ViaVersion/commands/defaultsubs/ListSubCmd.java
rename to common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/ListSubCmd.java
index 2c85a6de6..c1e8e8458 100644
--- a/src/main/java/us/myles/ViaVersion/commands/defaultsubs/ListSubCmd.java
+++ b/common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/ListSubCmd.java
@@ -1,9 +1,7 @@
package us.myles.ViaVersion.commands.defaultsubs;
-import org.bukkit.Bukkit;
-import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
-import us.myles.ViaVersion.api.ViaVersion;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.command.ViaCommandSender;
import us.myles.ViaVersion.api.command.ViaSubCommand;
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
@@ -26,7 +24,7 @@ public class ListSubCmd extends ViaSubCommand {
}
@Override
- public boolean execute(CommandSender sender, String[] args) {
+ public boolean execute(ViaCommandSender sender, String[] args) {
Map> playerVersions = new TreeMap<>(new Comparator() {
@Override
public int compare(ProtocolVersion o1, ProtocolVersion o2) {
@@ -34,8 +32,8 @@ public class ListSubCmd extends ViaSubCommand {
}
});
- for (Player p : Bukkit.getOnlinePlayers()) {
- int playerVersion = ViaVersion.getInstance().getPlayerVersion(p);
+ for (ViaCommandSender p : Via.getPlatform().getOnlinePlayers()) {
+ int playerVersion = Via.getAPI().getPlayerVersion(p.getUUID());
ProtocolVersion key = ProtocolVersion.getProtocol(playerVersion);
if (!playerVersions.containsKey(key))
playerVersions.put(key, new HashSet());
diff --git a/src/main/java/us/myles/ViaVersion/commands/defaultsubs/PPSSubCmd.java b/common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/PPSSubCmd.java
similarity index 77%
rename from src/main/java/us/myles/ViaVersion/commands/defaultsubs/PPSSubCmd.java
rename to common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/PPSSubCmd.java
index d2e7bc186..69890b3b5 100644
--- a/src/main/java/us/myles/ViaVersion/commands/defaultsubs/PPSSubCmd.java
+++ b/common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/PPSSubCmd.java
@@ -1,10 +1,7 @@
package us.myles.ViaVersion.commands.defaultsubs;
-import org.bukkit.Bukkit;
-import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
-import us.myles.ViaVersion.ViaVersionPlugin;
-import us.myles.ViaVersion.api.ViaVersion;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.command.ViaCommandSender;
import us.myles.ViaVersion.api.command.ViaSubCommand;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
@@ -28,19 +25,17 @@ public class PPSSubCmd extends ViaSubCommand {
}
@Override
- public boolean execute(CommandSender sender, String[] args) {
+ public boolean execute(ViaCommandSender sender, String[] args) {
Map> playerVersions = new HashMap<>();
int totalPackets = 0;
int clients = 0;
long max = 0;
- for (Player p : Bukkit.getOnlinePlayers()) {
- if (!ViaVersion.getInstance().isPorted(p))
- continue;
- int playerVersion = ViaVersion.getInstance().getPlayerVersion(p);
+ for (ViaCommandSender p : Via.getPlatform().getOnlinePlayers()) {
+ int playerVersion = Via.getAPI().getPlayerVersion(p.getUUID());
if (!playerVersions.containsKey(playerVersion))
playerVersions.put(playerVersion, new HashSet());
- UserConnection uc = ((ViaVersionPlugin) ViaVersion.getInstance()).getConnection(p);
+ UserConnection uc = Via.getManager().getConnection(p.getUUID());
if (uc.getPacketsPerSecond() > -1) {
playerVersions.get(playerVersion).add(p.getName() + " (" + uc.getPacketsPerSecond() + " PPS)");
totalPackets += uc.getPacketsPerSecond();
diff --git a/src/main/java/us/myles/ViaVersion/commands/defaultsubs/ReloadSubCmd.java b/common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/ReloadSubCmd.java
similarity index 60%
rename from src/main/java/us/myles/ViaVersion/commands/defaultsubs/ReloadSubCmd.java
rename to common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/ReloadSubCmd.java
index 9a25e6c13..8a1bf109c 100644
--- a/src/main/java/us/myles/ViaVersion/commands/defaultsubs/ReloadSubCmd.java
+++ b/common/src/main/java/us/myles/ViaVersion/commands/defaultsubs/ReloadSubCmd.java
@@ -1,8 +1,7 @@
package us.myles.ViaVersion.commands.defaultsubs;
-import org.bukkit.command.CommandSender;
-import us.myles.ViaVersion.ViaVersionPlugin;
-import us.myles.ViaVersion.api.ViaVersion;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.command.ViaCommandSender;
import us.myles.ViaVersion.api.command.ViaSubCommand;
public class ReloadSubCmd extends ViaSubCommand {
@@ -17,10 +16,8 @@ public class ReloadSubCmd extends ViaSubCommand {
}
@Override
- public boolean execute(CommandSender sender, String[] args) {
- ViaVersionPlugin plugin = (ViaVersionPlugin) ViaVersion.getInstance();
-
- plugin.getConf().generateConfig();
+ public boolean execute(ViaCommandSender sender, String[] args) {
+ Via.getPlatform().getConfigurationProvider().reloadConfig();
sendMessage(sender, "&6Configuration successfully reloaded! Some features may need a restart.");
return true;
}
diff --git a/src/main/java/us/myles/ViaVersion/dump/DumpTemplate.java b/common/src/main/java/us/myles/ViaVersion/dump/DumpTemplate.java
similarity index 77%
rename from src/main/java/us/myles/ViaVersion/dump/DumpTemplate.java
rename to common/src/main/java/us/myles/ViaVersion/dump/DumpTemplate.java
index e6b5451ba..6c35344a6 100644
--- a/src/main/java/us/myles/ViaVersion/dump/DumpTemplate.java
+++ b/common/src/main/java/us/myles/ViaVersion/dump/DumpTemplate.java
@@ -1,9 +1,9 @@
package us.myles.ViaVersion.dump;
+import com.google.gson.JsonObject;
import lombok.AllArgsConstructor;
import lombok.Data;
-import java.util.List;
import java.util.Map;
@Data
@@ -11,5 +11,5 @@ import java.util.Map;
public class DumpTemplate {
private VersionInfo versionInfo;
private Map configuration;
- private List plugins;
+ private JsonObject platformDump;
}
diff --git a/src/main/java/us/myles/ViaVersion/dump/PluginInfo.java b/common/src/main/java/us/myles/ViaVersion/dump/PluginInfo.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/dump/PluginInfo.java
rename to common/src/main/java/us/myles/ViaVersion/dump/PluginInfo.java
diff --git a/src/main/java/us/myles/ViaVersion/dump/VersionInfo.java b/common/src/main/java/us/myles/ViaVersion/dump/VersionInfo.java
similarity index 81%
rename from src/main/java/us/myles/ViaVersion/dump/VersionInfo.java
rename to common/src/main/java/us/myles/ViaVersion/dump/VersionInfo.java
index 75dcef344..9e0da92de 100644
--- a/src/main/java/us/myles/ViaVersion/dump/VersionInfo.java
+++ b/common/src/main/java/us/myles/ViaVersion/dump/VersionInfo.java
@@ -8,11 +8,11 @@ import java.util.Set;
@Data
@AllArgsConstructor
public class VersionInfo {
- private String version;
- private String bukkitVersion;
private String javaVersion;
private String operatingSystem;
private int serverProtocol;
private Set enabledPipelines;
+ private String platformName;
+ private String platformVersion;
}
diff --git a/src/main/java/us/myles/ViaVersion/exception/CancelException.java b/common/src/main/java/us/myles/ViaVersion/exception/CancelException.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/exception/CancelException.java
rename to common/src/main/java/us/myles/ViaVersion/exception/CancelException.java
diff --git a/src/main/java/us/myles/ViaVersion/exception/InformativeException.java b/common/src/main/java/us/myles/ViaVersion/exception/InformativeException.java
similarity index 96%
rename from src/main/java/us/myles/ViaVersion/exception/InformativeException.java
rename to common/src/main/java/us/myles/ViaVersion/exception/InformativeException.java
index 6599eb0a0..3cad1f55a 100644
--- a/src/main/java/us/myles/ViaVersion/exception/InformativeException.java
+++ b/common/src/main/java/us/myles/ViaVersion/exception/InformativeException.java
@@ -4,7 +4,7 @@ import java.util.HashMap;
import java.util.Map;
public class InformativeException extends Exception {
- Map info = new HashMap<>();
+ final Map info = new HashMap<>();
int sources = 0;
public InformativeException(Throwable cause) {
diff --git a/src/main/java/us/myles/ViaVersion/packets/Direction.java b/common/src/main/java/us/myles/ViaVersion/packets/Direction.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/packets/Direction.java
rename to common/src/main/java/us/myles/ViaVersion/packets/Direction.java
diff --git a/src/main/java/us/myles/ViaVersion/packets/PacketType.java b/common/src/main/java/us/myles/ViaVersion/packets/PacketType.java
similarity index 97%
rename from src/main/java/us/myles/ViaVersion/packets/PacketType.java
rename to common/src/main/java/us/myles/ViaVersion/packets/PacketType.java
index 43bb5cf0c..b3077806b 100644
--- a/src/main/java/us/myles/ViaVersion/packets/PacketType.java
+++ b/common/src/main/java/us/myles/ViaVersion/packets/PacketType.java
@@ -1,208 +1,208 @@
-package us.myles.ViaVersion.packets;
-
-import java.util.HashMap;
-
-@Deprecated
-public enum PacketType {
- /* Handshake serverbound */
- HANDSHAKE(State.HANDSHAKE, Direction.INCOMING, 0x00), // Mapped
- /* Login serverbound */
- LOGIN_START(State.LOGIN, Direction.INCOMING, 0x00), // Mapped
- LOGIN_ENCRYPTION_RESPONSE(State.LOGIN, Direction.INCOMING, 0x01), // Mapped
- /* Login clientbound */
- LOGIN_DISCONNECT(State.LOGIN, Direction.OUTGOING, 0x00), // Mapped
- LOGIN_ENCRYPTION_REQUEST(State.LOGIN, Direction.OUTGOING, 0x01), // Mapped
- LOGIN_SUCCESS(State.LOGIN, Direction.OUTGOING, 0x02), // Mapped
- LOGIN_SETCOMPRESSION(State.LOGIN, Direction.OUTGOING, 0x03), // Mapped
-
- /* Status serverbound */
- STATUS_REQUEST(State.STATUS, Direction.INCOMING, 0x00), // Mapped
- STATUS_PING(State.STATUS, Direction.INCOMING, 0x01), // Mapped
- /* Status clientbound */
- STATUS_RESPONSE(State.STATUS, Direction.OUTGOING, 0x00),
- STATUS_PONG(State.STATUS, Direction.OUTGOING, 0x01),
- /* Play serverbound */
- PLAY_TP_CONFIRM(State.PLAY, Direction.INCOMING, -1, 0x00), // Mapped
- PLAY_TAB_COMPLETE_REQUEST(State.PLAY, Direction.INCOMING, 0x14, 0x01), // Mapped
- PLAY_CHAT_MESSAGE_CLIENT(State.PLAY, Direction.INCOMING, 0x01, 0x02), // Mapped
- PLAY_CLIENT_STATUS(State.PLAY, Direction.INCOMING, 0x16, 0x03), // Mapped
- PLAY_CLIENT_SETTINGS(State.PLAY, Direction.INCOMING, 0x15, 0x04), // Mapped
- PLAY_CONFIRM_TRANS(State.PLAY, Direction.INCOMING, 0x0F, 0x05), // Mapped
- PLAY_ENCHANT_ITEM(State.PLAY, Direction.INCOMING, 0x11, 0x06), // Mapped
- PLAY_CLICK_WINDOW(State.PLAY, Direction.INCOMING, 0x0E, 0x07), // Mapped
- PLAY_CLOSE_WINDOW_REQUEST(State.PLAY, Direction.INCOMING, 0x0D, 0x08), // Mapped
- PLAY_PLUGIN_MESSAGE_REQUEST(State.PLAY, Direction.INCOMING, 0x17, 0x09),
- PLAY_USE_ENTITY(State.PLAY, Direction.INCOMING, 0x02, 0x0A), // Mapped
- PLAY_KEEP_ALIVE_REQUEST(State.PLAY, Direction.INCOMING, 0x00, 0x0B), // Mapped
- PLAY_PLAYER_POSITION_REQUEST(State.PLAY, Direction.INCOMING, 0x04, 0x0C), // Mapped
- PLAY_PLAYER_POSITION_LOOK_REQUEST(State.PLAY, Direction.INCOMING, 0x06, 0x0D), // Mapped
- PLAY_PLAYER_LOOK_REQUEST(State.PLAY, Direction.INCOMING, 0x05, 0x0E), // Mapped
- PLAY_PLAYER(State.PLAY, Direction.INCOMING, 0x03, 0x0F), // Mapped
- PLAY_VEHICLE_MOVE_REQUEST(State.PLAY, Direction.INCOMING, -1, 0x10), // Mapped
- PLAY_STEER_BOAT(State.PLAY, Direction.INCOMING, -1, 0x11), // Mapped
- PLAY_PLAYER_ABILITIES_REQUEST(State.PLAY, Direction.INCOMING, 0x13, 0x12), // Mapped
- PLAY_PLAYER_DIGGING(State.PLAY, Direction.INCOMING, 0x07, 0x13), // Mapped
- PLAY_ENTITY_ACTION(State.PLAY, Direction.INCOMING, 0x0B, 0x14), // Mapped
- PLAY_STEER_VEHICLE(State.PLAY, Direction.INCOMING, 0x0C, 0x15), // Mapped
-
- PLAY_RESOURCE_PACK_STATUS(State.PLAY, Direction.INCOMING, 0x19, 0x16), // Mapped
- PLAY_HELD_ITEM_CHANGE_REQUEST(State.PLAY, Direction.INCOMING, 0x09, 0x17), // Mapped
-
- PLAY_CREATIVE_INVENTORY_ACTION(State.PLAY, Direction.INCOMING, 0x10, 0x18), // Mapped
- PLAY_UPDATE_SIGN_REQUEST(State.PLAY, Direction.INCOMING, 0x12, 0x19), // Mapped
- PLAY_ANIMATION_REQUEST(State.PLAY, Direction.INCOMING, 0x0A, 0x1A), // Mapped
- PLAY_SPECTATE(State.PLAY, Direction.INCOMING, 0x18, 0x1B), // Mapped
- PLAY_PLAYER_BLOCK_PLACEMENT(State.PLAY, Direction.INCOMING, 0x08, 0x1C), // Mapped
- PLAY_USE_ITEM(State.PLAY, Direction.INCOMING, -1, 0x1D), // Mapped
- /* Play clientbound */
- PLAY_SPAWN_OBJECT(State.PLAY, Direction.OUTGOING, 0x0E, 0x00), // Mapped
- PLAY_SPAWN_XP_ORB(State.PLAY, Direction.OUTGOING, 0x11, 0x01), // Mapped
- PLAY_SPAWN_GLOBAL_ENTITY(State.PLAY, Direction.OUTGOING, 0x2C, 0x02), // Mapped
- PLAY_SPAWN_MOB(State.PLAY, Direction.OUTGOING, 0x0F, 0x03), // Mapped
- PLAY_SPAWN_PAINTING(State.PLAY, Direction.OUTGOING, 0x10, 0x04), // Mapped
- PLAY_SPAWN_PLAYER(State.PLAY, Direction.OUTGOING, 0x0C, 0x05), // Mapped
-
- PLAY_ANIMATION(State.PLAY, Direction.OUTGOING, 0x0B, 0x06), // Mapped
- PLAY_STATS(State.PLAY, Direction.OUTGOING, 0x37, 0x07), // Mapped
-
- PLAY_BLOCK_BREAK_ANIMATION(State.PLAY, Direction.OUTGOING, 0x25, 0x08), // Mapped
- PLAY_UPDATE_BLOCK_ENTITY(State.PLAY, Direction.OUTGOING, 0x35, 0x09), // Mapped
- PLAY_BLOCK_ACTION(State.PLAY, Direction.OUTGOING, 0x24, 0x0A), // Mapped
- PLAY_BLOCK_CHANGE(State.PLAY, Direction.OUTGOING, 0x23, 0x0B), // Mapped
-
- PLAY_BOSS_BAR(State.PLAY, Direction.OUTGOING, -1, 0x0C),
- PLAY_SERVER_DIFFICULTY(State.PLAY, Direction.OUTGOING, 0x41, 0x0D), // Mapped
- PLAY_TAB_COMPLETE(State.PLAY, Direction.OUTGOING, 0x3A, 0x0E), // Mapped
- PLAY_CHAT_MESSAGE(State.PLAY, Direction.OUTGOING, 0x02, 0x0F), // Mapped
- PLAY_MULTI_BLOCK_CHANGE(State.PLAY, Direction.OUTGOING, 0x22, 0x10), // Mapped
- PLAY_CONFIRM_TRANSACTION(State.PLAY, Direction.OUTGOING, 0x32, 0x11), // Mapped
- PLAY_CLOSE_WINDOW(State.PLAY, Direction.OUTGOING, 0x2E, 0x12), // Mapped
- PLAY_OPEN_WINDOW(State.PLAY, Direction.OUTGOING, 0x2D, 0x13), // Mapped
- PLAY_WINDOW_ITEMS(State.PLAY, Direction.OUTGOING, 0x30, 0x14), // Mapped
- PLAY_WINDOW_PROPERTY(State.PLAY, Direction.OUTGOING, 0x31, 0x15), // Mapped
- PLAY_SET_SLOT(State.PLAY, Direction.OUTGOING, 0x2F, 0x16), // Mapped
- PLAY_SET_COOLDOWN(State.PLAY, Direction.OUTGOING, -1, 0x17),
- PLAY_PLUGIN_MESSAGE(State.PLAY, Direction.OUTGOING, 0x3F, 0x18), // Mapped
- PLAY_NAMED_SOUND_EFFECT(State.PLAY, Direction.OUTGOING, 0x29, 0x19), // Mapped
- PLAY_DISCONNECT(State.PLAY, Direction.OUTGOING, 0x40, 0x1A), // Mapped
- PLAY_ENTITY_STATUS(State.PLAY, Direction.OUTGOING, 0x1A, 0x1B), // Mapped
- PLAY_EXPLOSION(State.PLAY, Direction.OUTGOING, 0x27, 0x1C), // Mapped
- PLAY_UNLOAD_CHUNK(State.PLAY, Direction.OUTGOING, -1, 0x1D),
- PLAY_CHANGE_GAME_STATE(State.PLAY, Direction.OUTGOING, 0x2B, 0x1E),
- PLAY_KEEP_ALIVE(State.PLAY, Direction.OUTGOING, 0x00, 0x1F), // Mapped
- PLAY_CHUNK_DATA(State.PLAY, Direction.OUTGOING, 0x21, 0x20), // Mapped
- PLAY_EFFECT(State.PLAY, Direction.OUTGOING, 0x28, 0x21), // Mapped
- PLAY_PARTICLE(State.PLAY, Direction.OUTGOING, 0x2A, 0x22), // Mapped
- PLAY_JOIN_GAME(State.PLAY, Direction.OUTGOING, 0x01, 0x23), // Mapped
- PLAY_MAP(State.PLAY, Direction.OUTGOING, 0x34, 0x24), // Mapped
- PLAY_ENTITY_RELATIVE_MOVE(State.PLAY, Direction.OUTGOING, 0x15, 0x25), // Mapped
- PLAY_ENTITY_LOOK_MOVE(State.PLAY, Direction.OUTGOING, 0x17, 0x26), // Mapped
- PLAY_ENTITY_LOOK(State.PLAY, Direction.OUTGOING, 0x16, 0x27), // Mapped
- PLAY_ENTITY(State.PLAY, Direction.OUTGOING, 0x14, 0x28), // Mapped
- PLAY_VEHICLE_MOVE(State.PLAY, Direction.OUTGOING, -1, 0x29),
- PLAY_OPEN_SIGN_EDITOR(State.PLAY, Direction.OUTGOING, 0x36, 0x2A), // Mapped
- PLAY_PLAYER_ABILITIES(State.PLAY, Direction.OUTGOING, 0x39, 0x2B), // Mapped
- PLAY_COMBAT_EVENT(State.PLAY, Direction.OUTGOING, 0x42, 0x2C), // Mapped
- PLAY_PLAYER_LIST_ITEM(State.PLAY, Direction.OUTGOING, 0x38, 0x2D), // Mapped
- PLAY_PLAYER_POSITION_LOOK(State.PLAY, Direction.OUTGOING, 0x08, 0x2E), // Mapped
- PLAY_USE_BED(State.PLAY, Direction.OUTGOING, 0x0A, 0x2F), // Mapped
- PLAY_DESTROY_ENTITIES(State.PLAY, Direction.OUTGOING, 0x13, 0x30), // Mapped
- PLAY_REMOVE_ENTITY_EFFECT(State.PLAY, Direction.OUTGOING, 0x1E, 0x31), // Mapped
- PLAY_RESOURCE_PACK_SEND(State.PLAY, Direction.OUTGOING, 0x48, 0x32), // Mapped
- PLAY_RESPAWN(State.PLAY, Direction.OUTGOING, 0x07, 0x33), // Mapped
- PLAY_ENTITY_HEAD_LOOK(State.PLAY, Direction.OUTGOING, 0x19, 0x34), // Mapped
- PLAY_WORLD_BORDER(State.PLAY, Direction.OUTGOING, 0x44, 0x35), // Mapped
- PLAY_CAMERA(State.PLAY, Direction.OUTGOING, 0x43, 0x36), // Mapped
- PLAY_HELD_ITEM_CHANGE(State.PLAY, Direction.OUTGOING, 0x09, 0x37), // Mapped
- PLAY_DISPLAY_SCOREBOARD(State.PLAY, Direction.OUTGOING, 0x3D, 0x38), // Mapped
- PLAY_ENTITY_METADATA(State.PLAY, Direction.OUTGOING, 0x1C, 0x39), // Mapped
- PLAY_ATTACH_ENTITY(State.PLAY, Direction.OUTGOING, 0x1B, 0x3A), // Mapped
- PLAY_ENTITY_VELOCITY(State.PLAY, Direction.OUTGOING, 0x12, 0x3B), // Mapped
- PLAY_ENTITY_EQUIPMENT(State.PLAY, Direction.OUTGOING, 0x04, 0x3C), // Mapped
- PLAY_SET_XP(State.PLAY, Direction.OUTGOING, 0x1F, 0x3D), // Mapped
- PLAY_UPDATE_HEALTH(State.PLAY, Direction.OUTGOING, 0x06, 0x3E), // Mapped
- PLAY_SCOREBOARD_OBJ(State.PLAY, Direction.OUTGOING, 0x3B, 0x3F), // Mapped
- PLAY_SET_PASSENGERS(State.PLAY, Direction.OUTGOING, -1, 0x40),
- PLAY_TEAM(State.PLAY, Direction.OUTGOING, 0x3E, 0x41), // Mapped
- PLAY_UPDATE_SCORE(State.PLAY, Direction.OUTGOING, 0x3C, 0x42), // Mapped
- PLAY_SPAWN_POSITION(State.PLAY, Direction.OUTGOING, 0x05, 0x43), // Mapped
- PLAY_TIME_UPDATE(State.PLAY, Direction.OUTGOING, 0x03, 0x44), // Mapped
- PLAY_TITLE(State.PLAY, Direction.OUTGOING, 0x45, 0x45), // Mapped
- PLAY_UPDATE_SIGN(State.PLAY, Direction.OUTGOING, 0x33, 0x46), // Mapped
- PLAY_SOUND_EFFECT(State.PLAY, Direction.OUTGOING, -1, 0x47),
- PLAY_PLAYER_LIST_HEADER_FOOTER(State.PLAY, Direction.OUTGOING, 0x47, 0x48), // Mapped
- PLAY_COLLECT_ITEM(State.PLAY, Direction.OUTGOING, 0x0D, 0x49), // Mapped
- PLAY_ENTITY_TELEPORT(State.PLAY, Direction.OUTGOING, 0x18, 0x4A), // Mapped
- PLAY_ENTITY_PROPERTIES(State.PLAY, Direction.OUTGOING, 0x20, 0x4B), // Mapped
- PLAY_ENTITY_EFFECT(State.PLAY, Direction.OUTGOING, 0x1D, 0x4C), // Mapped
-
- PLAY_MAP_CHUNK_BULK(State.PLAY, Direction.OUTGOING, 0x26, -1),
- PLAY_SET_COMPRESSION(State.PLAY, Direction.OUTGOING, 0x46, -1),
- PLAY_UPDATE_ENTITY_NBT(State.PLAY, Direction.OUTGOING, 0x49, -1);
-
- private static HashMap oldids = new HashMap<>();
- private static HashMap newids = new HashMap<>();
-
- static {
- for (PacketType pt : PacketType.values()) {
- oldids.put(toShort((short) pt.getPacketID(), (short) pt.getDirection().ordinal(), (short) pt.getState().ordinal()), pt);
- newids.put(toShort((short) pt.getNewPacketID(), (short) pt.getDirection().ordinal(), (short) pt.getState().ordinal()), pt);
- }
- }
-
- private State state;
- private Direction direction;
- private int packetID;
- private int newPacketID = -1;
-
- PacketType(State state, Direction direction, int packetID) {
- this.state = state;
- this.direction = direction;
- this.packetID = packetID;
- this.newPacketID = packetID;
- }
-
- PacketType(State state, Direction direction, int packetID, int newPacketID) {
- this.state = state;
- this.direction = direction;
- this.packetID = packetID;
- this.newPacketID = newPacketID;
- }
-
- public static PacketType findNewPacket(State state, Direction direction, int id) {
- return newids.get(toShort((short) id, (short) direction.ordinal(), (short) state.ordinal()));
- }
-
- public static PacketType findOldPacket(State state, Direction direction, int id) {
- return oldids.get(toShort((short) id, (short) direction.ordinal(), (short) state.ordinal()));
- }
-
- public static PacketType getIncomingPacket(State state, int id) {
- return findNewPacket(state, Direction.INCOMING, id);
- }
-
- public static PacketType getOutgoingPacket(State state, int id) {
- return findOldPacket(state, Direction.OUTGOING, id);
- }
-
- private static short toShort(short id, short direction, short state) {
- return (short) ((id & 0x00FF) | (direction << 8) & 0x0F00 | (state << 12) & 0xF000);
- }
-
- public State getState() {
- return state;
- }
-
- public Direction getDirection() {
- return direction;
- }
-
- public int getPacketID() {
- return packetID;
- }
-
- public int getNewPacketID() {
- return newPacketID;
- }
-
-}
+package us.myles.ViaVersion.packets;
+
+import java.util.HashMap;
+
+@Deprecated
+public enum PacketType {
+ /* Handshake serverbound */
+ HANDSHAKE(State.HANDSHAKE, Direction.INCOMING, 0x00), // Mapped
+ /* Login serverbound */
+ LOGIN_START(State.LOGIN, Direction.INCOMING, 0x00), // Mapped
+ LOGIN_ENCRYPTION_RESPONSE(State.LOGIN, Direction.INCOMING, 0x01), // Mapped
+ /* Login clientbound */
+ LOGIN_DISCONNECT(State.LOGIN, Direction.OUTGOING, 0x00), // Mapped
+ LOGIN_ENCRYPTION_REQUEST(State.LOGIN, Direction.OUTGOING, 0x01), // Mapped
+ LOGIN_SUCCESS(State.LOGIN, Direction.OUTGOING, 0x02), // Mapped
+ LOGIN_SETCOMPRESSION(State.LOGIN, Direction.OUTGOING, 0x03), // Mapped
+
+ /* Status serverbound */
+ STATUS_REQUEST(State.STATUS, Direction.INCOMING, 0x00), // Mapped
+ STATUS_PING(State.STATUS, Direction.INCOMING, 0x01), // Mapped
+ /* Status clientbound */
+ STATUS_RESPONSE(State.STATUS, Direction.OUTGOING, 0x00),
+ STATUS_PONG(State.STATUS, Direction.OUTGOING, 0x01),
+ /* Play serverbound */
+ PLAY_TP_CONFIRM(State.PLAY, Direction.INCOMING, -1, 0x00), // Mapped
+ PLAY_TAB_COMPLETE_REQUEST(State.PLAY, Direction.INCOMING, 0x14, 0x01), // Mapped
+ PLAY_CHAT_MESSAGE_CLIENT(State.PLAY, Direction.INCOMING, 0x01, 0x02), // Mapped
+ PLAY_CLIENT_STATUS(State.PLAY, Direction.INCOMING, 0x16, 0x03), // Mapped
+ PLAY_CLIENT_SETTINGS(State.PLAY, Direction.INCOMING, 0x15, 0x04), // Mapped
+ PLAY_CONFIRM_TRANS(State.PLAY, Direction.INCOMING, 0x0F, 0x05), // Mapped
+ PLAY_ENCHANT_ITEM(State.PLAY, Direction.INCOMING, 0x11, 0x06), // Mapped
+ PLAY_CLICK_WINDOW(State.PLAY, Direction.INCOMING, 0x0E, 0x07), // Mapped
+ PLAY_CLOSE_WINDOW_REQUEST(State.PLAY, Direction.INCOMING, 0x0D, 0x08), // Mapped
+ PLAY_PLUGIN_MESSAGE_REQUEST(State.PLAY, Direction.INCOMING, 0x17, 0x09),
+ PLAY_USE_ENTITY(State.PLAY, Direction.INCOMING, 0x02, 0x0A), // Mapped
+ PLAY_KEEP_ALIVE_REQUEST(State.PLAY, Direction.INCOMING, 0x00, 0x0B), // Mapped
+ PLAY_PLAYER_POSITION_REQUEST(State.PLAY, Direction.INCOMING, 0x04, 0x0C), // Mapped
+ PLAY_PLAYER_POSITION_LOOK_REQUEST(State.PLAY, Direction.INCOMING, 0x06, 0x0D), // Mapped
+ PLAY_PLAYER_LOOK_REQUEST(State.PLAY, Direction.INCOMING, 0x05, 0x0E), // Mapped
+ PLAY_PLAYER(State.PLAY, Direction.INCOMING, 0x03, 0x0F), // Mapped
+ PLAY_VEHICLE_MOVE_REQUEST(State.PLAY, Direction.INCOMING, -1, 0x10), // Mapped
+ PLAY_STEER_BOAT(State.PLAY, Direction.INCOMING, -1, 0x11), // Mapped
+ PLAY_PLAYER_ABILITIES_REQUEST(State.PLAY, Direction.INCOMING, 0x13, 0x12), // Mapped
+ PLAY_PLAYER_DIGGING(State.PLAY, Direction.INCOMING, 0x07, 0x13), // Mapped
+ PLAY_ENTITY_ACTION(State.PLAY, Direction.INCOMING, 0x0B, 0x14), // Mapped
+ PLAY_STEER_VEHICLE(State.PLAY, Direction.INCOMING, 0x0C, 0x15), // Mapped
+
+ PLAY_RESOURCE_PACK_STATUS(State.PLAY, Direction.INCOMING, 0x19, 0x16), // Mapped
+ PLAY_HELD_ITEM_CHANGE_REQUEST(State.PLAY, Direction.INCOMING, 0x09, 0x17), // Mapped
+
+ PLAY_CREATIVE_INVENTORY_ACTION(State.PLAY, Direction.INCOMING, 0x10, 0x18), // Mapped
+ PLAY_UPDATE_SIGN_REQUEST(State.PLAY, Direction.INCOMING, 0x12, 0x19), // Mapped
+ PLAY_ANIMATION_REQUEST(State.PLAY, Direction.INCOMING, 0x0A, 0x1A), // Mapped
+ PLAY_SPECTATE(State.PLAY, Direction.INCOMING, 0x18, 0x1B), // Mapped
+ PLAY_PLAYER_BLOCK_PLACEMENT(State.PLAY, Direction.INCOMING, 0x08, 0x1C), // Mapped
+ PLAY_USE_ITEM(State.PLAY, Direction.INCOMING, -1, 0x1D), // Mapped
+ /* Play clientbound */
+ PLAY_SPAWN_OBJECT(State.PLAY, Direction.OUTGOING, 0x0E, 0x00), // Mapped
+ PLAY_SPAWN_XP_ORB(State.PLAY, Direction.OUTGOING, 0x11, 0x01), // Mapped
+ PLAY_SPAWN_GLOBAL_ENTITY(State.PLAY, Direction.OUTGOING, 0x2C, 0x02), // Mapped
+ PLAY_SPAWN_MOB(State.PLAY, Direction.OUTGOING, 0x0F, 0x03), // Mapped
+ PLAY_SPAWN_PAINTING(State.PLAY, Direction.OUTGOING, 0x10, 0x04), // Mapped
+ PLAY_SPAWN_PLAYER(State.PLAY, Direction.OUTGOING, 0x0C, 0x05), // Mapped
+
+ PLAY_ANIMATION(State.PLAY, Direction.OUTGOING, 0x0B, 0x06), // Mapped
+ PLAY_STATS(State.PLAY, Direction.OUTGOING, 0x37, 0x07), // Mapped
+
+ PLAY_BLOCK_BREAK_ANIMATION(State.PLAY, Direction.OUTGOING, 0x25, 0x08), // Mapped
+ PLAY_UPDATE_BLOCK_ENTITY(State.PLAY, Direction.OUTGOING, 0x35, 0x09), // Mapped
+ PLAY_BLOCK_ACTION(State.PLAY, Direction.OUTGOING, 0x24, 0x0A), // Mapped
+ PLAY_BLOCK_CHANGE(State.PLAY, Direction.OUTGOING, 0x23, 0x0B), // Mapped
+
+ PLAY_BOSS_BAR(State.PLAY, Direction.OUTGOING, -1, 0x0C),
+ PLAY_SERVER_DIFFICULTY(State.PLAY, Direction.OUTGOING, 0x41, 0x0D), // Mapped
+ PLAY_TAB_COMPLETE(State.PLAY, Direction.OUTGOING, 0x3A, 0x0E), // Mapped
+ PLAY_CHAT_MESSAGE(State.PLAY, Direction.OUTGOING, 0x02, 0x0F), // Mapped
+ PLAY_MULTI_BLOCK_CHANGE(State.PLAY, Direction.OUTGOING, 0x22, 0x10), // Mapped
+ PLAY_CONFIRM_TRANSACTION(State.PLAY, Direction.OUTGOING, 0x32, 0x11), // Mapped
+ PLAY_CLOSE_WINDOW(State.PLAY, Direction.OUTGOING, 0x2E, 0x12), // Mapped
+ PLAY_OPEN_WINDOW(State.PLAY, Direction.OUTGOING, 0x2D, 0x13), // Mapped
+ PLAY_WINDOW_ITEMS(State.PLAY, Direction.OUTGOING, 0x30, 0x14), // Mapped
+ PLAY_WINDOW_PROPERTY(State.PLAY, Direction.OUTGOING, 0x31, 0x15), // Mapped
+ PLAY_SET_SLOT(State.PLAY, Direction.OUTGOING, 0x2F, 0x16), // Mapped
+ PLAY_SET_COOLDOWN(State.PLAY, Direction.OUTGOING, -1, 0x17),
+ PLAY_PLUGIN_MESSAGE(State.PLAY, Direction.OUTGOING, 0x3F, 0x18), // Mapped
+ PLAY_NAMED_SOUND_EFFECT(State.PLAY, Direction.OUTGOING, 0x29, 0x19), // Mapped
+ PLAY_DISCONNECT(State.PLAY, Direction.OUTGOING, 0x40, 0x1A), // Mapped
+ PLAY_ENTITY_STATUS(State.PLAY, Direction.OUTGOING, 0x1A, 0x1B), // Mapped
+ PLAY_EXPLOSION(State.PLAY, Direction.OUTGOING, 0x27, 0x1C), // Mapped
+ PLAY_UNLOAD_CHUNK(State.PLAY, Direction.OUTGOING, -1, 0x1D),
+ PLAY_CHANGE_GAME_STATE(State.PLAY, Direction.OUTGOING, 0x2B, 0x1E),
+ PLAY_KEEP_ALIVE(State.PLAY, Direction.OUTGOING, 0x00, 0x1F), // Mapped
+ PLAY_CHUNK_DATA(State.PLAY, Direction.OUTGOING, 0x21, 0x20), // Mapped
+ PLAY_EFFECT(State.PLAY, Direction.OUTGOING, 0x28, 0x21), // Mapped
+ PLAY_PARTICLE(State.PLAY, Direction.OUTGOING, 0x2A, 0x22), // Mapped
+ PLAY_JOIN_GAME(State.PLAY, Direction.OUTGOING, 0x01, 0x23), // Mapped
+ PLAY_MAP(State.PLAY, Direction.OUTGOING, 0x34, 0x24), // Mapped
+ PLAY_ENTITY_RELATIVE_MOVE(State.PLAY, Direction.OUTGOING, 0x15, 0x25), // Mapped
+ PLAY_ENTITY_LOOK_MOVE(State.PLAY, Direction.OUTGOING, 0x17, 0x26), // Mapped
+ PLAY_ENTITY_LOOK(State.PLAY, Direction.OUTGOING, 0x16, 0x27), // Mapped
+ PLAY_ENTITY(State.PLAY, Direction.OUTGOING, 0x14, 0x28), // Mapped
+ PLAY_VEHICLE_MOVE(State.PLAY, Direction.OUTGOING, -1, 0x29),
+ PLAY_OPEN_SIGN_EDITOR(State.PLAY, Direction.OUTGOING, 0x36, 0x2A), // Mapped
+ PLAY_PLAYER_ABILITIES(State.PLAY, Direction.OUTGOING, 0x39, 0x2B), // Mapped
+ PLAY_COMBAT_EVENT(State.PLAY, Direction.OUTGOING, 0x42, 0x2C), // Mapped
+ PLAY_PLAYER_LIST_ITEM(State.PLAY, Direction.OUTGOING, 0x38, 0x2D), // Mapped
+ PLAY_PLAYER_POSITION_LOOK(State.PLAY, Direction.OUTGOING, 0x08, 0x2E), // Mapped
+ PLAY_USE_BED(State.PLAY, Direction.OUTGOING, 0x0A, 0x2F), // Mapped
+ PLAY_DESTROY_ENTITIES(State.PLAY, Direction.OUTGOING, 0x13, 0x30), // Mapped
+ PLAY_REMOVE_ENTITY_EFFECT(State.PLAY, Direction.OUTGOING, 0x1E, 0x31), // Mapped
+ PLAY_RESOURCE_PACK_SEND(State.PLAY, Direction.OUTGOING, 0x48, 0x32), // Mapped
+ PLAY_RESPAWN(State.PLAY, Direction.OUTGOING, 0x07, 0x33), // Mapped
+ PLAY_ENTITY_HEAD_LOOK(State.PLAY, Direction.OUTGOING, 0x19, 0x34), // Mapped
+ PLAY_WORLD_BORDER(State.PLAY, Direction.OUTGOING, 0x44, 0x35), // Mapped
+ PLAY_CAMERA(State.PLAY, Direction.OUTGOING, 0x43, 0x36), // Mapped
+ PLAY_HELD_ITEM_CHANGE(State.PLAY, Direction.OUTGOING, 0x09, 0x37), // Mapped
+ PLAY_DISPLAY_SCOREBOARD(State.PLAY, Direction.OUTGOING, 0x3D, 0x38), // Mapped
+ PLAY_ENTITY_METADATA(State.PLAY, Direction.OUTGOING, 0x1C, 0x39), // Mapped
+ PLAY_ATTACH_ENTITY(State.PLAY, Direction.OUTGOING, 0x1B, 0x3A), // Mapped
+ PLAY_ENTITY_VELOCITY(State.PLAY, Direction.OUTGOING, 0x12, 0x3B), // Mapped
+ PLAY_ENTITY_EQUIPMENT(State.PLAY, Direction.OUTGOING, 0x04, 0x3C), // Mapped
+ PLAY_SET_XP(State.PLAY, Direction.OUTGOING, 0x1F, 0x3D), // Mapped
+ PLAY_UPDATE_HEALTH(State.PLAY, Direction.OUTGOING, 0x06, 0x3E), // Mapped
+ PLAY_SCOREBOARD_OBJ(State.PLAY, Direction.OUTGOING, 0x3B, 0x3F), // Mapped
+ PLAY_SET_PASSENGERS(State.PLAY, Direction.OUTGOING, -1, 0x40),
+ PLAY_TEAM(State.PLAY, Direction.OUTGOING, 0x3E, 0x41), // Mapped
+ PLAY_UPDATE_SCORE(State.PLAY, Direction.OUTGOING, 0x3C, 0x42), // Mapped
+ PLAY_SPAWN_POSITION(State.PLAY, Direction.OUTGOING, 0x05, 0x43), // Mapped
+ PLAY_TIME_UPDATE(State.PLAY, Direction.OUTGOING, 0x03, 0x44), // Mapped
+ PLAY_TITLE(State.PLAY, Direction.OUTGOING, 0x45, 0x45), // Mapped
+ PLAY_UPDATE_SIGN(State.PLAY, Direction.OUTGOING, 0x33, 0x46), // Mapped
+ PLAY_SOUND_EFFECT(State.PLAY, Direction.OUTGOING, -1, 0x47),
+ PLAY_PLAYER_LIST_HEADER_FOOTER(State.PLAY, Direction.OUTGOING, 0x47, 0x48), // Mapped
+ PLAY_COLLECT_ITEM(State.PLAY, Direction.OUTGOING, 0x0D, 0x49), // Mapped
+ PLAY_ENTITY_TELEPORT(State.PLAY, Direction.OUTGOING, 0x18, 0x4A), // Mapped
+ PLAY_ENTITY_PROPERTIES(State.PLAY, Direction.OUTGOING, 0x20, 0x4B), // Mapped
+ PLAY_ENTITY_EFFECT(State.PLAY, Direction.OUTGOING, 0x1D, 0x4C), // Mapped
+
+ PLAY_MAP_CHUNK_BULK(State.PLAY, Direction.OUTGOING, 0x26, -1),
+ PLAY_SET_COMPRESSION(State.PLAY, Direction.OUTGOING, 0x46, -1),
+ PLAY_UPDATE_ENTITY_NBT(State.PLAY, Direction.OUTGOING, 0x49, -1);
+
+ private static final HashMap oldids = new HashMap<>();
+ private static final HashMap newids = new HashMap<>();
+
+ static {
+ for (PacketType pt : PacketType.values()) {
+ oldids.put(toShort((short) pt.getPacketID(), (short) pt.getDirection().ordinal(), (short) pt.getState().ordinal()), pt);
+ newids.put(toShort((short) pt.getNewPacketID(), (short) pt.getDirection().ordinal(), (short) pt.getState().ordinal()), pt);
+ }
+ }
+
+ private State state;
+ private Direction direction;
+ private int packetID;
+ private int newPacketID = -1;
+
+ PacketType(State state, Direction direction, int packetID) {
+ this.state = state;
+ this.direction = direction;
+ this.packetID = packetID;
+ this.newPacketID = packetID;
+ }
+
+ PacketType(State state, Direction direction, int packetID, int newPacketID) {
+ this.state = state;
+ this.direction = direction;
+ this.packetID = packetID;
+ this.newPacketID = newPacketID;
+ }
+
+ public static PacketType findNewPacket(State state, Direction direction, int id) {
+ return newids.get(toShort((short) id, (short) direction.ordinal(), (short) state.ordinal()));
+ }
+
+ public static PacketType findOldPacket(State state, Direction direction, int id) {
+ return oldids.get(toShort((short) id, (short) direction.ordinal(), (short) state.ordinal()));
+ }
+
+ public static PacketType getIncomingPacket(State state, int id) {
+ return findNewPacket(state, Direction.INCOMING, id);
+ }
+
+ public static PacketType getOutgoingPacket(State state, int id) {
+ return findOldPacket(state, Direction.OUTGOING, id);
+ }
+
+ private static short toShort(short id, short direction, short state) {
+ return (short) ((id & 0x00FF) | (direction << 8) & 0x0F00 | (state << 12) & 0xF000);
+ }
+
+ public State getState() {
+ return state;
+ }
+
+ public Direction getDirection() {
+ return direction;
+ }
+
+ public int getPacketID() {
+ return packetID;
+ }
+
+ public int getNewPacketID() {
+ return newPacketID;
+ }
+
+}
diff --git a/src/main/java/us/myles/ViaVersion/packets/State.java b/common/src/main/java/us/myles/ViaVersion/packets/State.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/packets/State.java
rename to common/src/main/java/us/myles/ViaVersion/packets/State.java
diff --git a/src/main/java/us/myles/ViaVersion/protocols/base/BaseProtocol.java b/common/src/main/java/us/myles/ViaVersion/protocols/base/BaseProtocol.java
similarity index 75%
rename from src/main/java/us/myles/ViaVersion/protocols/base/BaseProtocol.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/base/BaseProtocol.java
index 8de79782d..f949d6944 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/base/BaseProtocol.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/base/BaseProtocol.java
@@ -1,22 +1,17 @@
package us.myles.ViaVersion.protocols.base;
+import com.google.common.base.Joiner;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
import io.netty.channel.ChannelFuture;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import net.md_5.bungee.api.ChatColor;
-import org.apache.commons.lang.StringUtils;
-import org.bukkit.Bukkit;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
-import org.bukkit.event.player.PlayerQuitEvent;
-import org.json.simple.JSONObject;
-import org.json.simple.parser.JSONParser;
-import org.json.simple.parser.ParseException;
-import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.Pair;
-import us.myles.ViaVersion.api.ViaVersion;
+import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.api.platform.providers.ViaProviders;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.protocol.ProtocolPipeline;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
@@ -26,6 +21,7 @@ import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.Direction;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
+import us.myles.ViaVersion.util.GsonUtil;
import java.util.List;
import java.util.UUID;
@@ -48,30 +44,34 @@ public class BaseProtocol extends Protocol {
ProtocolInfo info = wrapper.user().get(ProtocolInfo.class);
String originalStatus = wrapper.get(Type.STRING, 0);
try {
- JSONObject json = (JSONObject) new JSONParser().parse(originalStatus);
- JSONObject version = (JSONObject) json.get("version");
- int protocolVersion = ((Long) version.get("protocol")).intValue();
+ JsonObject json = GsonUtil.getGson().fromJson(originalStatus, JsonObject.class);
+ JsonObject version = json.get("version").getAsJsonObject();
+ int protocolVersion = ((Long) version.get("protocol").getAsLong()).intValue();
- if (ViaVersion.getConfig().isSendSupportedVersions()) //Send supported versions
- version.put("supportedVersions", ViaVersion.getInstance().getSupportedVersions());
+ if (Via.getConfig().isSendSupportedVersions()) //Send supported versions
+ version.add("supportedVersions", GsonUtil.getGson().toJsonTree(Via.getAPI().getSupportedVersions()));
if (ProtocolRegistry.SERVER_PROTOCOL == -1) // Set the Server protocol if the detection on startup failed
ProtocolRegistry.SERVER_PROTOCOL = protocolVersion;
- List> protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), ProtocolRegistry.SERVER_PROTOCOL);
+ int protocol = Via.getManager().getProviders().get(VersionProvider.class).getServerProtocol(wrapper.user());
+ List> protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), protocol);
+
if (protocols != null) {
- if (protocolVersion != 9999) //Fix ServerListPlus
- version.put("protocol", info.getProtocolVersion());
+ if (protocolVersion != 9999) {
+ //Fix ServerListPlus
+ version.addProperty("protocol", info.getProtocolVersion());
+ }
} else {
// not compatible :(, *plays very sad violin*
wrapper.user().setActive(false);
}
- if (ViaVersion.getConfig().getBlockedProtocols().contains(info.getProtocolVersion()))
- version.put("protocol", -1); // Show blocked versions as outdated
+ if (Via.getConfig().getBlockedProtocols().contains(info.getProtocolVersion()))
+ version.addProperty("protocol", -1); // Show blocked versions as outdated
- wrapper.set(Type.STRING, 0, json.toJSONString()); // Update value
- } catch (ParseException e) {
+ wrapper.set(Type.STRING, 0, GsonUtil.getGson().toJson(json)); // Update value
+ } catch (JsonParseException e) {
e.printStackTrace();
}
}
@@ -100,18 +100,18 @@ public class BaseProtocol extends Protocol {
info.setUuid(uuid);
info.setUsername(wrapper.get(Type.STRING, 1));
// Add to ported clients
- ((ViaVersionPlugin) ViaVersion.getInstance()).addPortedClient(wrapper.user());
+ Via.getManager().addPortedClient(wrapper.user());
if (info.getPipeline().pipes().size() == 1 && info.getPipeline().pipes().get(0).getClass() == BaseProtocol.class) // Only base protocol
wrapper.user().setActive(false);
- if (ViaVersion.getInstance().isDebug()) {
+ if (Via.getManager().isDebug()) {
// Print out the route to console
- ((ViaVersionPlugin) ViaVersion.getInstance()).getLogger().log(Level.INFO, "{0} logged in with protocol {1}, Route: {2}",
+ Via.getPlatform().getLogger().log(Level.INFO, "{0} logged in with protocol {1}, Route: {2}",
new Object[]{
wrapper.get(Type.STRING, 1),
info.getProtocolVersion(),
- StringUtils.join(info.getPipeline().pipes(), ", ")
+ Joiner.on(", ").join(info.getPipeline().pipes(), ", ")
});
}
}
@@ -140,13 +140,14 @@ public class BaseProtocol extends Protocol {
ProtocolInfo info = wrapper.user().get(ProtocolInfo.class);
info.setProtocolVersion(protVer);
// Choose the pipe
- List> protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), ProtocolRegistry.SERVER_PROTOCOL);
+ int protocol = Via.getManager().getProviders().get(VersionProvider.class).getServerProtocol(wrapper.user());
+ List> protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), protocol);
ProtocolPipeline pipeline = wrapper.user().get(ProtocolInfo.class).getPipeline();
if (protocols != null) {
for (Pair prot : protocols) {
pipeline.add(prot.getValue());
}
- wrapper.set(Type.VAR_INT, 0, ProtocolRegistry.SERVER_PROTOCOL);
+ wrapper.set(Type.VAR_INT, 0, protocol);
}
// Change state
@@ -171,11 +172,11 @@ public class BaseProtocol extends Protocol {
@Override
public void handle(final PacketWrapper wrapper) throws Exception {
int protocol = wrapper.user().get(ProtocolInfo.class).getProtocolVersion();
- if (ViaVersion.getConfig().getBlockedProtocols().contains(protocol)) {
+ if (Via.getConfig().getBlockedProtocols().contains(protocol)) {
if (!wrapper.user().getChannel().isOpen()) return;
PacketWrapper disconnectPacket = new PacketWrapper(0x00, null, wrapper.user()); // Disconnect Packet
- Protocol1_9TO1_8.FIX_JSON.write(disconnectPacket, ChatColor.translateAlternateColorCodes('&', ViaVersion.getConfig().getBlockedDisconnectMsg()));
+ Protocol1_9TO1_8.FIX_JSON.write(disconnectPacket, ChatColor.translateAlternateColorCodes('&', Via.getConfig().getBlockedDisconnectMsg()));
wrapper.cancel(); // cancel current
// Send and close
@@ -200,15 +201,8 @@ public class BaseProtocol extends Protocol {
}
@Override
- protected void registerListeners() {
- final ViaVersionPlugin plugin = (ViaVersionPlugin) Bukkit.getPluginManager().getPlugin("ViaVersion");
-
- Bukkit.getPluginManager().registerEvents(new Listener() {
- @EventHandler
- public void onPlayerQuit(PlayerQuitEvent e) {
- plugin.removePortedClient(e.getPlayer().getUniqueId());
- }
- }, plugin);
+ protected void register(ViaProviders providers) {
+ providers.register(VersionProvider.class, new VersionProvider());
}
@Override
diff --git a/src/main/java/us/myles/ViaVersion/protocols/base/ProtocolInfo.java b/common/src/main/java/us/myles/ViaVersion/protocols/base/ProtocolInfo.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/protocols/base/ProtocolInfo.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/base/ProtocolInfo.java
diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/base/VersionProvider.java b/common/src/main/java/us/myles/ViaVersion/protocols/base/VersionProvider.java
new file mode 100644
index 000000000..ec30cf4b1
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/base/VersionProvider.java
@@ -0,0 +1,12 @@
+package us.myles.ViaVersion.protocols.base;
+
+import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.api.platform.providers.Provider;
+import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
+
+public class VersionProvider implements Provider {
+
+ public int getServerProtocol(UserConnection connection) throws Exception {
+ return ProtocolRegistry.SERVER_PROTOCOL;
+ }
+}
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_10to1_9_3/Protocol1_10To1_9_3_4.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_10to1_9_3/Protocol1_10To1_9_3_4.java
similarity index 95%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_10to1_9_3/Protocol1_10To1_9_3_4.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_10to1_9_3/Protocol1_10To1_9_3_4.java
index 70fbf44df..7d05cadc6 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_10to1_9_3/Protocol1_10To1_9_3_4.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_10to1_9_3/Protocol1_10To1_9_3_4.java
@@ -23,13 +23,13 @@ public class Protocol1_10To1_9_3_4 extends Protocol {
@Deprecated
public static final Type METADATA = new Metadata1_9Type();
- public static ValueTransformer toNewPitch = new ValueTransformer(Type.FLOAT) {
+ public static final ValueTransformer toNewPitch = new ValueTransformer(Type.FLOAT) {
@Override
public Float transform(PacketWrapper wrapper, Short inputValue) throws Exception {
return inputValue / 63.5F;
}
};
- public static ValueTransformer, List> transformMetadata = new ValueTransformer, List>(Types1_9.METADATA_LIST) {
+ public static final ValueTransformer, List> transformMetadata = new ValueTransformer, List>(Types1_9.METADATA_LIST) {
@Override
public List transform(PacketWrapper wrapper, List inputValue) throws Exception {
List metaList = new CopyOnWriteArrayList<>(inputValue);
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_10to1_9_3/storage/ResourcePackTracker.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_10to1_9_3/storage/ResourcePackTracker.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_10to1_9_3/storage/ResourcePackTracker.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_10to1_9_3/storage/ResourcePackTracker.java
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/Protocol1_9_1_2TO1_9_3_4.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/Protocol1_9_1_2TO1_9_3_4.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/Protocol1_9_1_2TO1_9_3_4.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/Protocol1_9_1_2TO1_9_3_4.java
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/BlockEntity.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/BlockEntity.java
similarity index 95%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/BlockEntity.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/BlockEntity.java
index 96ca9f985..bda4b1731 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/BlockEntity.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/BlockEntity.java
@@ -3,7 +3,7 @@ package us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks;
import lombok.Getter;
import org.spacehq.opennbt.tag.builtin.CompoundTag;
import us.myles.ViaVersion.api.PacketWrapper;
-import us.myles.ViaVersion.api.ViaVersion;
+import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.minecraft.Position;
import us.myles.ViaVersion.api.type.Type;
@@ -51,7 +51,7 @@ public class BlockEntity {
updateBlockEntity(pos, (short) newId, tag, connection);
} catch (Exception e) {
- if (ViaVersion.getInstance().isDebug()) {
+ if (Via.getManager().isDebug()) {
System.out.println("Block Entity: " + e.getMessage() + ": " + tag);
}
}
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/Chunk1_9_3_4.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/Chunk1_9_3_4.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/Chunk1_9_3_4.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/Chunk1_9_3_4.java
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/ChunkSection1_9_3_4.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/ChunkSection1_9_3_4.java
similarity index 99%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/ChunkSection1_9_3_4.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/ChunkSection1_9_3_4.java
index 4ea0b0afb..ff3d9a9a0 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/ChunkSection1_9_3_4.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/ChunkSection1_9_3_4.java
@@ -103,7 +103,7 @@ public class ChunkSection1_9_3_4 implements ChunkSection {
*
*
* @param input The buffer to read from.
- * @throws Exception
+ * @throws Exception If it fails to read
*/
public void readBlocks(ByteBuf input) throws Exception {
palette.clear();
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/types/Chunk1_9_3_4Type.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/types/Chunk1_9_3_4Type.java
similarity index 96%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/types/Chunk1_9_3_4Type.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/types/Chunk1_9_3_4Type.java
index 684f1e4a3..c1552692e 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/types/Chunk1_9_3_4Type.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/types/Chunk1_9_3_4Type.java
@@ -2,8 +2,8 @@ package us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.types;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
-import org.bukkit.World;
import org.spacehq.opennbt.tag.builtin.CompoundTag;
+import us.myles.ViaVersion.api.minecraft.Environment;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
import us.myles.ViaVersion.api.type.PartialType;
@@ -48,7 +48,7 @@ public class Chunk1_9_3_4Type extends PartialType {
sections[i] = section;
section.readBlocks(input);
section.readBlockLight(input);
- if (world.getEnvironment() == World.Environment.NORMAL) {
+ if (world.getEnvironment() == Environment.NORMAL) {
section.readSkyLight(input);
}
}
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1to1_9/Protocol1_9_1TO1_9.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1to1_9/Protocol1_9_1TO1_9.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1to1_9/Protocol1_9_1TO1_9.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1to1_9/Protocol1_9_1TO1_9.java
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/Protocol1_9_3TO1_9_1_2.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/Protocol1_9_3TO1_9_1_2.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/Protocol1_9_3TO1_9_1_2.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/Protocol1_9_3TO1_9_1_2.java
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/Chunk1_9_1_2.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/Chunk1_9_1_2.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/Chunk1_9_1_2.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/Chunk1_9_1_2.java
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/ChunkSection1_9_1_2.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/ChunkSection1_9_1_2.java
similarity index 99%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/ChunkSection1_9_1_2.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/ChunkSection1_9_1_2.java
index 17993598f..0e7ed30d9 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/ChunkSection1_9_1_2.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/ChunkSection1_9_1_2.java
@@ -103,7 +103,7 @@ public class ChunkSection1_9_1_2 implements ChunkSection {
*
*
* @param input The buffer to read from.
- * @throws Exception
+ * @throws Exception If it failed to read properly
*/
public void readBlocks(ByteBuf input) throws Exception {
palette.clear();
diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/FakeTileEntity.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/FakeTileEntity.java
new file mode 100644
index 000000000..62250aff1
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/FakeTileEntity.java
@@ -0,0 +1,69 @@
+package us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.chunks;
+
+import org.spacehq.opennbt.tag.builtin.CompoundTag;
+import org.spacehq.opennbt.tag.builtin.IntTag;
+import org.spacehq.opennbt.tag.builtin.StringTag;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Mojang changed the way how tile entities inside chunk packets work in 1.10.1
+ * It requires now to have all tile entity data included in the chunk packet, otherwise it'll crash.
+ */
+public class FakeTileEntity {
+ private static final Map tileEntities = new ConcurrentHashMap<>();
+
+ static {
+ register(Arrays.asList(61, 62), "Furnace");
+ register(Arrays.asList(54, 146), "Chest");
+ register(130, "EnderChest");
+ register(84, "RecordPlayer");
+ register(23, "Trap"); // Dispenser
+ register(158, "Dropper");
+ register(Arrays.asList(63, 68), "Sign");
+ register(52, "MobSpawner");
+ register(25, "Music"); // Note Block
+ register(Arrays.asList(33, 34, 29, 36), "Piston");
+ register(117, "Cauldron"); // Brewing stand
+ register(116, "EnchantTable");
+ register(Arrays.asList(119, 120), "Airportal"); // End portal
+ register(138, "Beacon");
+ register(144, "Skull");
+ register(Arrays.asList(178, 151), "DLDetector");
+ register(154, "Hopper");
+ register(Arrays.asList(149, 150), "Comparator");
+ register(140, "FlowerPot");
+ register(Arrays.asList(176, 177), "Banner");
+ register(209, "EndGateway");
+ register(137, "Control");
+ }
+
+ private static void register(Integer material, String name) {
+ CompoundTag comp = new CompoundTag("");
+ comp.put(new StringTag(name));
+ tileEntities.put(material, comp);
+ }
+
+ private static void register(List materials, String name) {
+ for (int m : materials)
+ register(m, name);
+ }
+
+ public static boolean hasBlock(int block) {
+ return tileEntities.containsKey(block);
+ }
+
+ public static CompoundTag getFromBlock(int x, int y, int z, int block) {
+ if (tileEntities.containsKey(block)) {
+ CompoundTag tag = tileEntities.get(block).clone();
+ tag.put(new IntTag("x", x));
+ tag.put(new IntTag("y", y));
+ tag.put(new IntTag("z", z));
+ return tag;
+ }
+ return null;
+ }
+}
diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/storage/ClientWorld.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/storage/ClientWorld.java
new file mode 100644
index 000000000..9dcca3354
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/storage/ClientWorld.java
@@ -0,0 +1,25 @@
+package us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage;
+
+import lombok.Getter;
+import us.myles.ViaVersion.api.data.StoredObject;
+import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.api.minecraft.Environment;
+
+@Getter
+public class ClientWorld extends StoredObject {
+ private Environment environment;
+
+ public ClientWorld(UserConnection user) {
+ super(user);
+ }
+
+ public void setEnvironment(int environmentId) {
+ this.environment = getEnvFromId(environmentId);
+ }
+
+ private Environment getEnvFromId(int id) {
+ Environment output = Environment.getEnvironmentById(id);
+ if (output == null) return Environment.NETHER;
+ return output;
+ }
+}
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/types/Chunk1_9_1_2Type.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/types/Chunk1_9_1_2Type.java
similarity index 90%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/types/Chunk1_9_1_2Type.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/types/Chunk1_9_1_2Type.java
index cb5d31c10..a1459db83 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/types/Chunk1_9_1_2Type.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/types/Chunk1_9_1_2Type.java
@@ -2,9 +2,9 @@ package us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.types;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
-import org.bukkit.World;
import org.spacehq.opennbt.tag.builtin.CompoundTag;
-import us.myles.ViaVersion.api.ViaVersion;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.minecraft.Environment;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
import us.myles.ViaVersion.api.type.PartialType;
@@ -27,8 +27,8 @@ public class Chunk1_9_1_2Type extends PartialType {
@Override
public Chunk read(ByteBuf input, ClientWorld world) throws Exception {
- boolean replacePistons = world.getUser().get(ProtocolInfo.class).getPipeline().contains(Protocol1_10To1_9_3_4.class) && ViaVersion.getConfig().isReplacePistons();
- int replacementId = ViaVersion.getConfig().getPistonReplacementId();
+ boolean replacePistons = world.getUser().get(ProtocolInfo.class).getPipeline().contains(Protocol1_10To1_9_3_4.class) && Via.getConfig().isReplacePistons();
+ int replacementId = Via.getConfig().getPistonReplacementId();
int chunkX = input.readInt();
int chunkZ = input.readInt();
@@ -53,7 +53,7 @@ public class Chunk1_9_1_2Type extends PartialType {
sections[i] = section;
section.readBlocks(input);
section.readBlockLight(input);
- if (world.getEnvironment() == World.Environment.NORMAL) {
+ if (world.getEnvironment() == Environment.NORMAL) {
section.readSkyLight(input);
}
if (replacePistons) {
@@ -72,9 +72,7 @@ public class Chunk1_9_1_2Type extends PartialType {
}
@Override
- public void write(ByteBuf output, ClientWorld world, Chunk input) throws Exception {
- Chunk chunk = input;
-
+ public void write(ByteBuf output, ClientWorld world, Chunk chunk) throws Exception {
output.writeInt(chunk.getX());
output.writeInt(chunk.getZ());
diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/ArmorType.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/ArmorType.java
new file mode 100644
index 000000000..b4f830521
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/ArmorType.java
@@ -0,0 +1,107 @@
+package us.myles.ViaVersion.protocols.protocol1_9to1_8;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+import java.util.HashMap;
+
+@RequiredArgsConstructor
+@Getter
+public enum ArmorType {
+
+ LEATHER_HELMET(1, 298, "minecraft:leather_helmet"),
+ LEATHER_CHESTPLATE(3, 299, "minecraft:leather_chestplate"),
+ LEATHER_LEGGINGS(2, 300, "minecraft:leather_leggings"),
+ LEATHER_BOOTS(1, 301, "minecraft:leather_boots"),
+ CHAINMAIL_HELMET(2, 302, "minecraft:chainmail_helmet"),
+ CHAINMAIL_CHESTPLATE(5, 303, "minecraft:chainmail_chestplate"),
+ CHAINMAIL_LEGGINGS(4, 304, "minecraft:chainmail_leggings"),
+ CHAINMAIL_BOOTS(1, 305, "minecraft:chainmail_boots"),
+ IRON_HELMET(2, 306, "minecraft:iron_helmet"),
+ IRON_CHESTPLATE(6, 307, "minecraft:iron_chestplate"),
+ IRON_LEGGINGS(5, 308, "minecraft:iron_leggings"),
+ IRON_BOOTS(2, 309, "minecraft:iron_boots"),
+ DIAMOND_HELMET(3, 310, "minecraft:diamond_helmet"),
+ DIAMOND_CHESTPLATE(8, 311, "minecraft:diamond_chestplate"),
+ DIAMOND_LEGGINGS(6, 312, "minecraft:diamond_leggings"),
+ DIAMOND_BOOTS(3, 313, "minecraft:diamond_boots"),
+ GOLD_HELMET(2, 314, "minecraft:gold_helmet"),
+ GOLD_CHESTPLATE(5, 315, "minecraft:gold_chestplate"),
+ GOLD_LEGGINGS(3, 316, "minecraft:gold_leggings"),
+ GOLD_BOOTS(1, 317, "minecraft:gold_boots"),
+ NONE(0, 0, "none");
+
+ private static HashMap armor;
+
+ static {
+ armor = new HashMap<>();
+ for (ArmorType a : ArmorType.values()) {
+ armor.put(a.getId(), a);
+ }
+ }
+
+ private final int armorPoints;
+ private final int id;
+ private final String type;
+
+ /**
+ * Find an armour type by the item id
+ *
+ * @param id ID of the item
+ * @return Return the ArmourType, ArmourType.NONE if not found
+ */
+ public static ArmorType findById(int id) {
+ for (ArmorType a : ArmorType.values())
+ if (a.getId() == id)
+ return a;
+ return ArmorType.NONE;
+ }
+
+ /**
+ * Find an armour type by the item string
+ *
+ * @param type String name for the item
+ * @return Return the ArmourType, ArmourType.NONE if not found
+ */
+ public static ArmorType findByType(String type) {
+ for (ArmorType a : ArmorType.values())
+ if (a.getType().equals(type))
+ return a;
+ return NONE;
+ }
+
+ /**
+ * Check if an item id is armour
+ *
+ * @param id The item ID
+ * @return True if the item is a piece of armour
+ */
+ public static boolean isArmor(int id) {
+ for (ArmorType a : ArmorType.values())
+ if (a.getId() == id)
+ return true;
+ return false;
+ }
+
+ /**
+ * Check if an item id is armour
+ *
+ * @param type The item material name
+ * @return True if the item is a piece of armour
+ */
+ public static boolean isArmor(String type) {
+ for (ArmorType a : ArmorType.values())
+ if (a.getType().equals(type))
+ return true;
+ return false;
+ }
+
+ /**
+ * Get the Minecraft ID for the Armour Type
+ *
+ * @return The ID
+ */
+ public int getId() {
+ return this.id;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/ItemRewriter.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/ItemRewriter.java
similarity index 96%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/ItemRewriter.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/ItemRewriter.java
index 3d3b7b30b..6f663e37f 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/ItemRewriter.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/ItemRewriter.java
@@ -1,6 +1,5 @@
package us.myles.ViaVersion.protocols.protocol1_9to1_8;
-import org.bukkit.Material;
import org.spacehq.opennbt.tag.builtin.CompoundTag;
import org.spacehq.opennbt.tag.builtin.ListTag;
import org.spacehq.opennbt.tag.builtin.StringTag;
@@ -140,7 +139,7 @@ public class ItemRewriter {
public static void toServer(Item item) {
if (item != null) {
- if (item.getId() == Material.MONSTER_EGG.getId() && item.getData() == 0) {
+ if (item.getId() == 383 && item.getData() == 0) { // Monster Egg
CompoundTag tag = item.getTag();
int data = 0;
if (tag != null && tag.get("EntityTag") instanceof CompoundTag) {
@@ -155,7 +154,7 @@ public class ItemRewriter {
item.setTag(tag);
item.setData((short) data);
}
- if (item.getId() == Material.POTION.getId()) {
+ if (item.getId() == 373) { // Potion
CompoundTag tag = item.getTag();
int data = 0;
if (tag != null && tag.get("Potion") instanceof StringTag) {
@@ -169,11 +168,11 @@ public class ItemRewriter {
item.setTag(tag);
item.setData((short) data);
}
- //Splash potion
+ // Splash potion
if (item.getId() == 438) {
CompoundTag tag = item.getTag();
int data = 0;
- item.setId((short) Material.POTION.getId());
+ item.setId((short) 373); // Potion
if (tag != null && tag.get("Potion") instanceof StringTag) {
StringTag potion = tag.get("Potion");
String potionName = potion.getValue().replace("minecraft:", "");
@@ -190,7 +189,7 @@ public class ItemRewriter {
public static void toClient(Item item) {
if (item != null) {
- if (item.getId() == Material.MONSTER_EGG.getId() && item.getData() != 0) {
+ if (item.getId() == 383 && item.getData() != 0) { // Monster Egg
CompoundTag tag = item.getTag();
if (tag == null) {
tag = new CompoundTag("tag");
@@ -204,7 +203,7 @@ public class ItemRewriter {
item.setTag(tag);
item.setData((short) 0);
}
- if (item.getId() == Material.POTION.getId()) {
+ if (item.getId() == 373) { // Potion
CompoundTag tag = item.getTag();
if (tag == null) {
tag = new CompoundTag("tag");
@@ -219,7 +218,7 @@ public class ItemRewriter {
item.setTag(tag);
item.setData((short) 0);
}
- if (item.getId() == Material.WRITTEN_BOOK.getId()) {
+ if (item.getId() == 387) { // WRITTEN_BOOK
CompoundTag tag = item.getTag();
if (tag == null) {
tag = new CompoundTag("tag");
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/PlayerMovementMapper.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/PlayerMovementMapper.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/PlayerMovementMapper.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/PlayerMovementMapper.java
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/Protocol1_9TO1_8.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/Protocol1_9TO1_8.java
similarity index 53%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/Protocol1_9TO1_8.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/Protocol1_9TO1_8.java
index 05cc8bcb8..ed8a0e456 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/Protocol1_9TO1_8.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/Protocol1_9TO1_8.java
@@ -1,43 +1,37 @@
package us.myles.ViaVersion.protocols.protocol1_9to1_8;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
-import org.bukkit.Bukkit;
-import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.PacketWrapper;
-import us.myles.ViaVersion.api.ViaVersion;
+import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
+import us.myles.ViaVersion.api.platform.providers.ViaProviders;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.ValueTransformer;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.version.Metadata1_8Type;
import us.myles.ViaVersion.api.type.types.version.MetadataList1_8Type;
-import us.myles.ViaVersion.protocols.base.ProtocolInfo;
-import us.myles.ViaVersion.protocols.protocol1_9to1_8.listeners.*;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.packets.*;
+import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
+import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.HandItemProvider;
+import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.*;
+import us.myles.ViaVersion.util.GsonUtil;
import java.util.List;
-import java.util.UUID;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
public class Protocol1_9TO1_8 extends Protocol {
- @Deprecated
- public static Type> METADATA_LIST = new MetadataList1_8Type();
- @Deprecated
- public static Type METADATA = new Metadata1_8Type();
-
- private static Gson gson = new GsonBuilder().create();
- public static ValueTransformer FIX_JSON = new ValueTransformer(Type.STRING) {
+ public static final ValueTransformer FIX_JSON = new ValueTransformer(Type.STRING) {
@Override
public String transform(PacketWrapper wrapper, String line) {
return fixJson(line);
}
};
+ @Deprecated
+ public static Type> METADATA_LIST = new MetadataList1_8Type();
+ @Deprecated
+ public static Type METADATA = new Metadata1_8Type();
public static String fixJson(String line) {
if (line == null || line.equalsIgnoreCase("null")) {
@@ -51,9 +45,9 @@ public class Protocol1_9TO1_8 extends Protocol {
}
}
try {
- gson.fromJson(line, JsonObject.class);
+ GsonUtil.getGson().fromJson(line, JsonObject.class);
} catch (Exception e) {
- if (ViaVersion.getConfig().isForceJsonTransform()) {
+ if (Via.getConfig().isForceJsonTransform()) {
return constructJson(line);
} else {
System.out.println("Invalid JSON String: \"" + line + "\" Please report this issue to the ViaVersion Github: " + e.getMessage());
@@ -66,31 +60,21 @@ public class Protocol1_9TO1_8 extends Protocol {
private static String constructJson(String text) {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("text", text);
- return gson.toJson(jsonObject);
+ return GsonUtil.getGson().toJson(jsonObject);
}
public static Item getHandItem(final UserConnection info) {
- if (HandItemCache.CACHE) {
- return HandItemCache.getHandItem(info.get(ProtocolInfo.class).getUuid());
- } else {
- try {
- return Bukkit.getScheduler().callSyncMethod(Bukkit.getPluginManager().getPlugin("ViaVersion"), new Callable- () {
- @Override
- public Item call() throws Exception {
- UUID playerUUID = info.get(ProtocolInfo.class).getUuid();
- if (Bukkit.getPlayer(playerUUID) != null) {
- return Item.getItem(Bukkit.getPlayer(playerUUID).getItemInHand());
- }
- return null;
- }
- }).get(10, TimeUnit.SECONDS);
- } catch (Exception e) {
- System.out.println("Error fetching hand item: " + e.getClass().getName());
- if (ViaVersion.getInstance().isDebug())
- e.printStackTrace();
- return null;
- }
- }
+ return Via.getManager().getProviders().get(HandItemProvider.class).getHandItem(info);
+ }
+
+ public static boolean isSword(int id) {
+ if (id == 267) return true; // Iron
+ if (id == 268) return true; // Wood
+ if (id == 272) return true; // Stone
+ if (id == 276) return true; // Diamond
+ if (id == 283) return true; // Gold
+
+ return false;
}
@Override
@@ -103,29 +87,19 @@ public class Protocol1_9TO1_8 extends Protocol {
}
@Override
- protected void registerListeners() {
- ViaVersionPlugin plugin = (ViaVersionPlugin) Bukkit.getPluginManager().getPlugin("ViaVersion");
-
- new ArmorListener(plugin).register();
- new CommandBlockListener(plugin).register();
- new DeathListener(plugin).register();
- new BlockListener(plugin).register();
-
- if (Bukkit.getVersion().toLowerCase().contains("paper") || Bukkit.getVersion().toLowerCase().contains("taco")) {
- plugin.getLogger().info("Enabling PaperSpigot/TacoSpigot patch: Fixes block placement.");
- new PaperPatch(plugin).register();
- }
- if (plugin.getConf().isStimulatePlayerTick())
- new ViaIdleThread(plugin.getPortedPlayers()).runTaskTimer(plugin, 1L, 1L); // Updates player's idle status
- if (plugin.getConf().isItemCache()) {
- new HandItemCache().runTaskTimerAsynchronously(plugin, 2L, 2L); // Updates player's items :)
- HandItemCache.CACHE = true;
+ protected void register(ViaProviders providers) {
+ providers.register(HandItemProvider.class, new HandItemProvider());
+ providers.register(BulkChunkTranslatorProvider.class, new BulkChunkTranslatorProvider());
+ providers.require(MovementTransmitterProvider.class);
+ if (Via.getConfig().isStimulatePlayerTick()) {
+ Via.getPlatform().runRepeatingSync(new ViaIdleThread(), 1L);
}
}
@Override
public boolean isFiltered(Class packetClass) {
- return packetClass.getName().endsWith("PacketPlayOutMapChunkBulk");
+ return Via.getManager().getProviders().get(BulkChunkTranslatorProvider.class).isFiltered(packetClass);
+
}
@Override
diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/ViaIdleThread.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/ViaIdleThread.java
new file mode 100644
index 000000000..675df3a22
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/ViaIdleThread.java
@@ -0,0 +1,23 @@
+package us.myles.ViaVersion.protocols.protocol1_9to1_8;
+
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.protocols.base.ProtocolInfo;
+import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
+import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.MovementTracker;
+
+public class ViaIdleThread implements Runnable {
+ @Override
+ public void run() {
+ for (UserConnection info : Via.getManager().getPortedPlayers().values()) {
+ if (info.has(ProtocolInfo.class) && info.get(ProtocolInfo.class).getPipeline().contains(Protocol1_9TO1_8.class)) {
+ long nextIdleUpdate = info.get(MovementTracker.class).getNextIdlePacket();
+ if (nextIdleUpdate <= System.currentTimeMillis()) {
+ if (info.getChannel().isOpen()) {
+ Via.getManager().getProviders().get(MovementTransmitterProvider.class).sendPlayer(info);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chat/ChatRewriter.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chat/ChatRewriter.java
similarity index 80%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chat/ChatRewriter.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chat/ChatRewriter.java
index ad757c201..c26b460ef 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chat/ChatRewriter.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chat/ChatRewriter.java
@@ -6,6 +6,12 @@ import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker;
public class ChatRewriter {
+ /**
+ * Rewrite chat being sent to the client so that gamemode issues don't occur.
+ *
+ * @param obj The json object being sent by the server
+ * @param user The player involved. (Required for Gamemode info)
+ */
public static void toClient(JsonObject obj, UserConnection user) {
//Check gamemode change
if (obj.get("translate") != null && obj.get("translate").getAsString().equals("gameMode.changed")) {
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chat/GameMode.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chat/GameMode.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chat/GameMode.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chat/GameMode.java
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/Chunk1_9to1_8.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/Chunk1_9to1_8.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/Chunk1_9to1_8.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/Chunk1_9to1_8.java
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/ChunkSection1_9to1_8.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/ChunkSection1_9to1_8.java
similarity index 99%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/ChunkSection1_9to1_8.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/ChunkSection1_9to1_8.java
index 0953941ed..8d837a37f 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/ChunkSection1_9to1_8.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/ChunkSection1_9to1_8.java
@@ -46,7 +46,7 @@ public class ChunkSection1_9to1_8 implements ChunkSection {
setBlock(index(x, y, z), type, data);
}
- public int getBlockId(int x, int y, int z){
+ public int getBlockId(int x, int y, int z) {
int index = blocks[index(x, y, z)];
return palette.get(index) >> 4;
}
diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/metadata/MetaIndex.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/metadata/MetaIndex.java
new file mode 100644
index 000000000..ffe476089
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/metadata/MetaIndex.java
@@ -0,0 +1,199 @@
+package us.myles.ViaVersion.protocols.protocol1_9to1_8.metadata;
+
+import com.google.common.base.Optional;
+import lombok.Getter;
+import us.myles.ViaVersion.api.Pair;
+import us.myles.ViaVersion.api.entities.Entity1_10Types;
+import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_8;
+import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_9;
+
+import java.util.HashMap;
+
+import static us.myles.ViaVersion.api.entities.Entity1_10Types.EntityType.*;
+
+@Getter
+public enum MetaIndex {
+
+ // entity
+ ENTITY_STATUS(ENTITY, 0, MetaType1_8.Byte, MetaType1_9.Byte),
+ ENTITY_AIR(ENTITY, 1, MetaType1_8.Short, MetaType1_9.VarInt),
+ ENTITY_NAMETAG(ENTITY, 2, MetaType1_8.String, MetaType1_9.String), // in the entity class @ spigot 1.8.8, blame wiki.vg
+ ENTITY_ALWAYS_SHOW_NAMETAG(ENTITY, 3, MetaType1_8.Byte, MetaType1_9.Boolean), // in the entity class @ Spigot 1.8.8, blame wiki.vg
+ ENTITY_SILENT(ENTITY, 4, MetaType1_8.Byte, MetaType1_9.Boolean),
+ // living entity
+ LIVINGENTITY_HEALTH(ENTITY_LIVING, 6, MetaType1_8.Float, MetaType1_9.Float),
+ LIVINGENTITY_POTION_EFFECT_COLOR(ENTITY_LIVING, 7, MetaType1_8.Int, MetaType1_9.VarInt),
+ LIVINGENTITY_IS_POTION_AMBIENT(ENTITY_LIVING, 8, MetaType1_8.Byte, MetaType1_9.Boolean),
+ LIVINGENTITY_NUMBER_OF_ARROWS_IN(ENTITY_LIVING, 9, MetaType1_8.Byte, MetaType1_9.VarInt),
+ LIVINGENTITY_NO_AI(ENTITY_LIVING, 15, MetaType1_8.Byte, 10, MetaType1_9.Byte), // in 1.9 this is combined with Left handed, oh.
+ // ageable
+ AGEABLE_AGE(ENTITY_AGEABLE, 12, MetaType1_8.Byte, 11, MetaType1_9.Boolean),
+ // armour stand
+ STAND_INFO(ARMOR_STAND, 10, MetaType1_8.Byte, MetaType1_9.Byte),
+ STAND_HEAD_POS(ARMOR_STAND, 11, MetaType1_8.Rotation, MetaType1_9.Vector3F),
+ STAND_BODY_POS(ARMOR_STAND, 12, MetaType1_8.Rotation, MetaType1_9.Vector3F),
+ STAND_LA_POS(ARMOR_STAND, 13, MetaType1_8.Rotation, MetaType1_9.Vector3F),
+ STAND_RA_POS(ARMOR_STAND, 14, MetaType1_8.Rotation, MetaType1_9.Vector3F),
+ STAND_LL_POS(ARMOR_STAND, 15, MetaType1_8.Rotation, MetaType1_9.Vector3F),
+ STAND_RL_POS(ARMOR_STAND, 16, MetaType1_8.Rotation, MetaType1_9.Vector3F),
+ // human, discountined?
+ PLAYER_SKIN_FLAGS(ENTITY_HUMAN, 10, MetaType1_8.Byte, 12, MetaType1_9.Byte), // unsigned on 1.8
+ PLAYER_HUMAN_BYTE(ENTITY_HUMAN, 16, MetaType1_8.Byte, MetaType1_9.Discontinued), // unused on 1.8
+ PLAYER_ADDITIONAL_HEARTS(ENTITY_HUMAN, 17, MetaType1_8.Float, 10, MetaType1_9.Float),
+ PLAYER_SCORE(ENTITY_HUMAN, 18, MetaType1_8.Int, 11, MetaType1_9.VarInt),
+ PLAYER_HAND(ENTITY_HUMAN, -1, MetaType1_8.NonExistent, 5, MetaType1_9.Byte), // new in 1.9
+ SOMETHING_ANTICHEAT_PLUGINS_FOR_SOME_REASON_USE(ENTITY_HUMAN, 11, MetaType1_8.Byte, MetaType1_9.Discontinued), //For what we know, This doesn't exists. If you think it exists and knows what it does. Please tell us.
+ // horse
+ HORSE_INFO(HORSE, 16, MetaType1_8.Int, 12, MetaType1_9.Byte),
+ HORSE_TYPE(HORSE, 19, MetaType1_8.Byte, 13, MetaType1_9.VarInt),
+ HORSE_SUBTYPE(HORSE, 20, MetaType1_8.Int, 14, MetaType1_9.VarInt),
+ HORSE_OWNER(HORSE, 21, MetaType1_8.String, 15, MetaType1_9.OptUUID),
+ HORSE_ARMOR(HORSE, 22, MetaType1_8.Int, 16, MetaType1_9.VarInt),
+ // bat
+ BAT_ISHANGING(BAT, 16, MetaType1_8.Byte, 11, MetaType1_9.Byte),
+ // tameable
+ TAMING_INFO(ENTITY_TAMEABLE_ANIMAL, 16, MetaType1_8.Byte, 12, MetaType1_9.Byte),
+ TAMING_OWNER(ENTITY_TAMEABLE_ANIMAL, 17, MetaType1_8.String, 13, MetaType1_9.OptUUID),
+ // ocelot
+ OCELOT_TYPE(OCELOT, 18, MetaType1_8.Byte, 14, MetaType1_9.VarInt),
+ // wolf
+ WOLF_HEALTH(WOLF, 18, MetaType1_8.Float, 14, MetaType1_9.Float),
+ WOLF_BEGGING(WOLF, 19, MetaType1_8.Byte, 15, MetaType1_9.Boolean),
+ WOLF_COLLAR(WOLF, 20, MetaType1_8.Byte, 16, MetaType1_9.VarInt),
+ // pig
+ PIG_SADDLE(PIG, 16, MetaType1_8.Byte, 12, MetaType1_9.Boolean),
+ // rabbit
+ RABBIT_TYPE(RABBIT, 18, MetaType1_8.Byte, 12, MetaType1_9.VarInt),
+ // sheep
+ SHEEP_COLOR(SHEEP, 16, MetaType1_8.Byte, 12, MetaType1_9.Byte),
+ // villager
+ VILLAGER_PROFESSION(VILLAGER, 16, MetaType1_8.Int, 12, MetaType1_9.VarInt),
+ // enderman
+ ENDERMAN_BLOCK(ENDERMAN, 16, MetaType1_8.Short, 11, MetaType1_9.BlockID), // special case
+ ENDERMAN_BLOCKDATA(ENDERMAN, 17, MetaType1_8.Byte, 11, MetaType1_9.BlockID), // special case
+ ENDERMAN_ISSCREAMING(ENDERMAN, 18, MetaType1_8.Byte, 12, MetaType1_9.Boolean),
+ // zombie
+ ZOMBIE_ISCHILD(ZOMBIE, 12, MetaType1_8.Byte, 11, MetaType1_9.Boolean),
+ ZOMBIE_ISVILLAGER(ZOMBIE, 13, MetaType1_8.Byte, 12, MetaType1_9.VarInt),
+ ZOMBIE_ISCONVERTING(ZOMBIE, 14, MetaType1_8.Byte, 13, MetaType1_9.Boolean),
+ // ZOMBIE_RISINGHANDS added in 1.9
+ // blaze
+ BLAZE_ONFIRE(BLAZE, 16, MetaType1_8.Byte, 11, MetaType1_9.Byte),
+ // spider
+ SPIDER_CIMBING(SPIDER, 16, MetaType1_8.Byte, 11, MetaType1_9.Byte),
+ // creeper
+ CREEPER_FUSE(CREEPER, 16, MetaType1_8.Byte, 11, MetaType1_9.VarInt), // -1 idle, 1 is fuse
+ CREEPER_ISPOWERED(CREEPER, 17, MetaType1_8.Byte, 12, MetaType1_9.Boolean),
+ CREEPER_ISIGNITED(CREEPER, 18, MetaType1_8.Byte, 13, MetaType1_9.Boolean),
+ // ghast
+ GHAST_ISATTACKING(GHAST, 16, MetaType1_8.Byte, 11, MetaType1_9.Boolean),
+ // slime
+ SLIME_SIZE(SLIME, 16, MetaType1_8.Byte, 11, MetaType1_9.VarInt),
+ // skeleton
+ SKELETON_TYPE(SKELETON, 13, MetaType1_8.Byte, 11, MetaType1_9.VarInt),
+ // witch
+ WITCH_AGGRO(WITCH, 21, MetaType1_8.Byte, 11, MetaType1_9.Boolean),
+ // iron golem
+ IRON_PLAYERMADE(IRON_GOLEM, 16, MetaType1_8.Byte, 11, MetaType1_9.Byte),
+ // wither
+ WITHER_TARGET1(WITHER, 17, MetaType1_8.Int, 11, MetaType1_9.VarInt),
+ WITHER_TARGET2(WITHER, 18, MetaType1_8.Int, 12, MetaType1_9.VarInt),
+ WITHER_TARGET3(WITHER, 19, MetaType1_8.Int, 13, MetaType1_9.VarInt),
+ WITHER_INVULN_TIME(WITHER, 20, MetaType1_8.Int, 14, MetaType1_9.VarInt),
+ WITHER_PROPERTIES(WITHER, 10, MetaType1_8.Byte, MetaType1_9.Byte),
+ WITHER_UNKNOWN(WITHER, 11, MetaType1_8.Byte, MetaType1_9.Discontinued),
+ // wither skull
+ WITHERSKULL_INVULN(WITHER_SKULL, 10, MetaType1_8.Byte, 5, MetaType1_9.Boolean),
+ // guardian
+ GUARDIAN_INFO(GUARDIAN, 16, MetaType1_8.Int, 11, MetaType1_9.Byte),
+ GUARDIAN_TARGET(GUARDIAN, 17, MetaType1_8.Int, 12, MetaType1_9.VarInt),
+ // boat
+ BOAT_SINCEHIT(BOAT, 17, MetaType1_8.Int, 5, MetaType1_9.VarInt),
+ BOAT_FORWARDDIR(BOAT, 18, MetaType1_8.Int, 6, MetaType1_9.VarInt),
+ BOAT_DMGTAKEN(BOAT, 19, MetaType1_8.Float, 7, MetaType1_9.Float),
+ // BOAT_TYPE in 1.9
+ // minecart
+ MINECART_SHAKINGPOWER(MINECART_ABSTRACT, 17, MetaType1_8.Int, 5, MetaType1_9.VarInt),
+ MINECART_SHAKINGDIRECTION(MINECART_ABSTRACT, 18, MetaType1_8.Int, 6, MetaType1_9.VarInt),
+ MINECART_DAMAGETAKEN(MINECART_ABSTRACT, 19, MetaType1_8.Float, 7, MetaType1_9.Float), // also shaking modifier :P
+ MINECART_BLOCK(MINECART_ABSTRACT, 20, MetaType1_8.Int, 8, MetaType1_9.VarInt),
+ MINECART_BLOCK_Y(MINECART_ABSTRACT, 21, MetaType1_8.Int, 9, MetaType1_9.VarInt),
+ MINECART_SHOWBLOCK(MINECART_ABSTRACT, 22, MetaType1_8.Byte, 10, MetaType1_9.Boolean),
+ // Command minecart (they are still broken)
+ MINECART_COMMANDBLOCK_COMMAND(MINECART_ABSTRACT, 23, MetaType1_8.String, 11, MetaType1_9.String),
+ MINECART_COMMANDBLOCK_OUTPUT(MINECART_ABSTRACT, 24, MetaType1_8.String, 12, MetaType1_9.Chat),
+ // furnace cart
+ FURNACECART_ISPOWERED(MINECART_ABSTRACT, 16, MetaType1_8.Byte, 11, MetaType1_9.Boolean),
+ // item drop
+ ITEM_ITEM(DROPPED_ITEM, 10, MetaType1_8.Slot, 5, MetaType1_9.Slot),
+ // arrow
+ ARROW_ISCRIT(ARROW, 16, MetaType1_8.Byte, 5, MetaType1_9.Byte),
+ // firework
+ FIREWORK_INFO(FIREWORK, 8, MetaType1_8.Slot, 5, MetaType1_9.Slot),
+ // item frame
+ ITEMFRAME_ITEM(ITEM_FRAME, 8, MetaType1_8.Slot, 5, MetaType1_9.Slot),
+ ITEMFRAME_ROTATION(ITEM_FRAME, 9, MetaType1_8.Byte, 6, MetaType1_9.VarInt),
+ // ender crystal
+ ENDERCRYSTAL_HEALTH(ENDER_CRYSTAL, 8, MetaType1_8.Int, MetaType1_9.Discontinued),
+ // Ender dragon boss bar issues
+ ENDERDRAGON_UNKNOWN(ENDER_DRAGON, 5, MetaType1_8.Byte, MetaType1_9.Discontinued),
+ ENDERDRAGON_NAME(ENDER_DRAGON, 10, MetaType1_8.String, MetaType1_9.Discontinued),
+ // Normal Ender dragon
+ ENDERDRAGON_FLAG(ENDER_DRAGON, 15, MetaType1_8.Byte, MetaType1_9.Discontinued),
+ ENDERDRAGON_PHASE(ENDER_DRAGON, 11, MetaType1_8.Byte, MetaType1_9.VarInt);
+
+ private static final HashMap
, MetaIndex> metadataRewrites = new HashMap<>();
+
+ static {
+ for (MetaIndex index : MetaIndex.values())
+ metadataRewrites.put(new Pair<>(index.getClazz(), index.getIndex()), index);
+ }
+
+ private Entity1_10Types.EntityType clazz;
+ private int newIndex;
+ private MetaType1_9 newType;
+ private MetaType1_8 oldType;
+ private int index;
+
+ MetaIndex(Entity1_10Types.EntityType type, int index, MetaType1_8 oldType, MetaType1_9 newType) {
+ this.clazz = type;
+ this.index = index;
+ this.newIndex = index;
+ this.oldType = oldType;
+ this.newType = newType;
+ }
+
+ MetaIndex(Entity1_10Types.EntityType type, int index, MetaType1_8 oldType, int newIndex, MetaType1_9 newType) {
+ this.clazz = type;
+ this.index = index;
+ this.oldType = oldType;
+ this.newIndex = newIndex;
+ this.newType = newType;
+ }
+
+ private static Optional getIndex(Entity1_10Types.EntityType type, int index) {
+ Pair pair = new Pair<>(type, index);
+ if (metadataRewrites.containsKey(pair)) {
+ return Optional.of(metadataRewrites.get(pair));
+ }
+
+ return Optional.absent();
+ }
+
+ public static MetaIndex searchIndex(Entity1_10Types.EntityType type, int index) {
+ Entity1_10Types.EntityType currentType = type;
+ do {
+ Optional optMeta = getIndex(currentType, index);
+
+ if (optMeta.isPresent()) {
+ return optMeta.get();
+ }
+
+ currentType = currentType.getParent();
+ } while (currentType != null);
+
+ return null;
+ }
+
+}
+
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/metadata/MetadataRewriter.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/metadata/MetadataRewriter.java
similarity index 72%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/metadata/MetadataRewriter.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/metadata/MetadataRewriter.java
index 5783a0cc7..1fecbb7d8 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/metadata/MetadataRewriter.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/metadata/MetadataRewriter.java
@@ -1,11 +1,14 @@
package us.myles.ViaVersion.protocols.protocol1_9to1_8.metadata;
-import org.bukkit.entity.EntityType;
-import org.bukkit.util.EulerAngle;
-import org.bukkit.util.Vector;
-import us.myles.ViaVersion.api.ViaVersion;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.entities.Entity1_10Types;
+import us.myles.ViaVersion.api.minecraft.EulerAngle;
+import us.myles.ViaVersion.api.minecraft.Vector;
import us.myles.ViaVersion.api.minecraft.item.Item;
+import us.myles.ViaVersion.api.minecraft.metadata.MetaType;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
+import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_8;
+import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_9;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.ItemRewriter;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
@@ -14,43 +17,41 @@ import java.util.List;
import java.util.UUID;
public class MetadataRewriter {
- public static void transform(EntityType type, List list) {
+ public static void transform(Entity1_10Types.EntityType type, List list) {
short id = -1;
int data = -1;
for (Metadata entry : new ArrayList<>(list)) {
- MetaIndex metaIndex = MetaIndex.getIndex(type, entry.getId());
+ MetaIndex metaIndex = MetaIndex.searchIndex(type, entry.getId());
try {
if (metaIndex != null) {
- 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
+ if (metaIndex.getNewType() != MetaType1_9.Discontinued) {
+ if (metaIndex.getNewType() != MetaType1_9.BlockID || id != -1 && data == -1 || id == -1 && data != -1) { // block ID is only written if we have both parts
entry.setId(metaIndex.getNewIndex());
- entry.setTypeID(metaIndex.getNewType().getTypeID());
+ entry.setMetaType(metaIndex.getNewType());
}
Object value = entry.getValue();
switch (metaIndex.getNewType()) {
case Byte:
- entry.setType(us.myles.ViaVersion.api.type.Type.BYTE);
// convert from int, byte
- if (metaIndex.getOldType() == Type.Byte) {
+ if (metaIndex.getOldType() == MetaType1_8.Byte) {
entry.setValue(value);
}
- if (metaIndex.getOldType() == Type.Int) {
+ if (metaIndex.getOldType() == MetaType1_8.Int) {
entry.setValue(((Integer) value).byteValue());
}
// After writing the last one
- if (metaIndex == MetaIndex.ENTITY_STATUS && type == EntityType.PLAYER) {
+ if (metaIndex == MetaIndex.ENTITY_STATUS && type == Entity1_10Types.EntityType.PLAYER) {
Byte val = 0;
if ((((Byte) value) & 0x10) == 0x10) { // Player eating/aiming/drinking
val = 1;
}
int newIndex = MetaIndex.PLAYER_HAND.getNewIndex();
- int typeID = MetaIndex.PLAYER_HAND.getNewType().getTypeID();
- Metadata metadata = new Metadata(newIndex, typeID, us.myles.ViaVersion.api.type.Type.BYTE, val);
+ MetaType metaType = MetaIndex.PLAYER_HAND.getNewType();
+ Metadata metadata = new Metadata(newIndex, metaType, val);
list.add(metadata);
}
break;
case OptUUID:
- entry.setType(us.myles.ViaVersion.api.type.Type.OPTIONAL_UUID);
String owner = (String) value;
UUID toWrite = null;
if (owner.length() != 0) {
@@ -62,12 +63,11 @@ public class MetadataRewriter {
entry.setValue(toWrite);
break;
case BlockID:
- entry.setType(us.myles.ViaVersion.api.type.Type.VAR_INT);
// if we have both sources :))
- if (metaIndex.getOldType() == Type.Byte) {
+ if (metaIndex.getOldType() == MetaType1_8.Byte) {
data = (Byte) value;
}
- if (metaIndex.getOldType() == Type.Short) {
+ if (metaIndex.getOldType() == MetaType1_8.Short) {
id = (Short) value;
}
if (id != -1 && data != -1) {
@@ -80,50 +80,42 @@ public class MetadataRewriter {
}
break;
case VarInt:
- entry.setType(us.myles.ViaVersion.api.type.Type.VAR_INT);
// convert from int, short, byte
- if (metaIndex.getOldType() == Type.Byte) {
+ if (metaIndex.getOldType() == MetaType1_8.Byte) {
entry.setValue(((Byte) value).intValue());
}
- if (metaIndex.getOldType() == Type.Short) {
+ if (metaIndex.getOldType() == MetaType1_8.Short) {
entry.setValue(((Short) value).intValue());
}
- if (metaIndex.getOldType() == Type.Int) {
+ if (metaIndex.getOldType() == MetaType1_8.Int) {
entry.setValue(value);
}
break;
case Float:
- entry.setType(us.myles.ViaVersion.api.type.Type.FLOAT);
entry.setValue(value);
break;
case String:
- entry.setType(us.myles.ViaVersion.api.type.Type.STRING);
entry.setValue(value);
break;
case Boolean:
- entry.setType(us.myles.ViaVersion.api.type.Type.BOOLEAN);
if (metaIndex == MetaIndex.AGEABLE_AGE)
entry.setValue((Byte) value < 0);
else
entry.setValue((Byte) value != 0);
break;
case Slot:
- entry.setType(us.myles.ViaVersion.api.type.Type.ITEM);
entry.setValue(value);
ItemRewriter.toClient((Item) entry.getValue());
break;
case Position:
- entry.setType(us.myles.ViaVersion.api.type.Type.VECTOR);
Vector vector = (Vector) value;
entry.setValue(vector);
break;
case Vector3F:
- entry.setType(us.myles.ViaVersion.api.type.Type.ROTATION);
EulerAngle angle = (EulerAngle) value;
entry.setValue(angle);
break;
case Chat:
- entry.setType(us.myles.ViaVersion.api.type.Type.STRING);
value = Protocol1_9TO1_8.fixJson((String) value);
entry.setValue(value);
break;
@@ -140,7 +132,7 @@ public class MetadataRewriter {
}
} catch (Exception e) {
list.remove(entry);
- if (!ViaVersion.getConfig().isSuppressMetadataErrors() || ViaVersion.getInstance().isDebug()) {
+ if (!Via.getConfig().isSuppressMetadataErrors() || Via.getManager().isDebug()) {
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.getId());
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/EntityPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/EntityPackets.java
similarity index 94%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/EntityPackets.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/EntityPackets.java
index 45d77585a..e36317a60 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/EntityPackets.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/EntityPackets.java
@@ -1,8 +1,7 @@
package us.myles.ViaVersion.protocols.protocol1_9to1_8.packets;
-import org.bukkit.Material;
import us.myles.ViaVersion.api.PacketWrapper;
-import us.myles.ViaVersion.api.ViaVersion;
+import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.protocol.Protocol;
@@ -21,7 +20,7 @@ import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker;
import java.util.List;
public class EntityPackets {
- public static ValueTransformer toNewShort = new ValueTransformer(Type.SHORT) {
+ public static final ValueTransformer toNewShort = new ValueTransformer(Type.SHORT) {
@Override
public Short transform(PacketWrapper wrapper, Byte inputValue) {
return (short) (inputValue * 128);
@@ -85,11 +84,11 @@ public class EntityPackets {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int entityID = wrapper.get(Type.VAR_INT, 0);
- if (ViaVersion.getConfig().isHologramPatch()) {
+ if (Via.getConfig().isHologramPatch()) {
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
if (tracker.getKnownHolograms().contains(entityID)) {
Double newValue = wrapper.get(Type.DOUBLE, 1);
- newValue += (ViaVersion.getConfig().getHologramYOffset());
+ newValue += (Via.getConfig().getHologramYOffset());
wrapper.set(Type.DOUBLE, 1, newValue);
}
}
@@ -159,11 +158,9 @@ public class EntityPackets {
Item stack = wrapper.get(Type.ITEM, 0);
if (stack != null) {
- if (Material.getMaterial(stack.getId()) != null) {
- if (Material.getMaterial(stack.getId()).name().endsWith("SWORD")) {
- entityTracker.getValidBlocking().add(entityID);
- return;
- }
+ if (Protocol1_9TO1_8.isSword(stack.getId())) {
+ entityTracker.getValidBlocking().add(entityID);
+ return;
}
}
entityTracker.getValidBlocking().remove(entityID);
@@ -231,7 +228,7 @@ public class EntityPackets {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
boolean showParticles = wrapper.read(Type.BOOLEAN); //In 1.8 = true->Show particles : false->Hide particles
- boolean newEffect = ViaVersion.getConfig().isNewEffectIndicator();
+ boolean newEffect = Via.getConfig().isNewEffectIndicator();
//0: hide, 1: shown without indictator, 2: shown with indicator, 3: hide with beacon indicator but we don't use it.
wrapper.write(Type.BYTE, (byte) (showParticles ? newEffect ? 2 : 1 : 0));
}
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/InventoryPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/InventoryPackets.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/InventoryPackets.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/InventoryPackets.java
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/PlayerPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/PlayerPackets.java
similarity index 97%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/PlayerPackets.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/PlayerPackets.java
index 6e14bae8f..aa8559ad0 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/PlayerPackets.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/PlayerPackets.java
@@ -2,11 +2,9 @@ package us.myles.ViaVersion.protocols.protocol1_9to1_8.packets;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
-import org.bukkit.Material;
-import org.bukkit.entity.EntityType;
-import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.PacketWrapper;
-import us.myles.ViaVersion.api.ViaVersion;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.entities.Entity1_10Types;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketHandler;
@@ -124,7 +122,7 @@ public class PlayerPackets {
wrapper.passthrough(Type.STRING); // Name tag visibility
- wrapper.write(Type.STRING, ViaVersion.getConfig().isPreventCollision() ? "never" : "");
+ wrapper.write(Type.STRING, Via.getConfig().isPreventCollision() ? "never" : "");
wrapper.passthrough(Type.BYTE); // Colour
}
@@ -137,12 +135,12 @@ public class PlayerPackets {
if (entityTracker.isAutoTeam() && player.equalsIgnoreCase(myName)) {
if (mode == 4) {
// since removing add to auto team
- ((ViaVersionPlugin) ViaVersion.getInstance()).run(new Runnable() {
+ Via.getPlatform().runSync(new Runnable() {
@Override
public void run() {
entityTracker.sendTeamPacket(true);
}
- }, false);
+ });
} else {
// since adding remove from auto team
entityTracker.sendTeamPacket(false);
@@ -167,7 +165,7 @@ public class PlayerPackets {
public void handle(PacketWrapper wrapper) throws Exception {
int entityID = wrapper.get(Type.INT, 0);
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
- tracker.getClientEntityTypes().put(entityID, EntityType.PLAYER);
+ tracker.getClientEntityTypes().put(entityID, Entity1_10Types.EntityType.PLAYER);
tracker.setEntityID(entityID);
}
});
@@ -477,7 +475,7 @@ public class PlayerPackets {
if (name.equalsIgnoreCase("MC|BSign")) {
Item item = wrapper.passthrough(Type.ITEM);
if (item != null) {
- item.setId((short) Material.WRITTEN_BOOK.getId());
+ item.setId((short) 387); // Written Book
}
}
if (name.equalsIgnoreCase("MC|AutoCmd")) {
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/SpawnPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/SpawnPackets.java
similarity index 95%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/SpawnPackets.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/SpawnPackets.java
index 0ae3c7e70..e868c427a 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/SpawnPackets.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/SpawnPackets.java
@@ -1,10 +1,10 @@
package us.myles.ViaVersion.protocols.protocol1_9to1_8.packets;
-import org.bukkit.Material;
-import org.bukkit.entity.EntityType;
import us.myles.ViaVersion.api.PacketWrapper;
+import us.myles.ViaVersion.api.entities.Entity1_10Types;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
+import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_9;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
@@ -17,15 +17,13 @@ import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.ItemRewriter;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.metadata.MetadataRewriter;
-import us.myles.ViaVersion.protocols.protocol1_9to1_8.metadata.NewType;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker;
-import us.myles.ViaVersion.util.EntityUtil;
import java.util.ArrayList;
import java.util.List;
public class SpawnPackets {
- public static ValueTransformer toNewDouble = new ValueTransformer(Type.DOUBLE) {
+ public static final ValueTransformer toNewDouble = new ValueTransformer(Type.DOUBLE) {
@Override
public Double transform(PacketWrapper wrapper, Integer inputValue) {
return inputValue / 32D;
@@ -56,7 +54,7 @@ public class SpawnPackets {
int entityID = wrapper.get(Type.VAR_INT, 0);
int typeID = wrapper.get(Type.BYTE, 0);
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
- tracker.getClientEntityTypes().put(entityID, EntityUtil.getTypeFromID(typeID, true));
+ tracker.getClientEntityTypes().put(entityID, Entity1_10Types.getTypeFromId(typeID, true));
tracker.sendMetadataBuffer(entityID);
}
});
@@ -97,17 +95,17 @@ public class SpawnPackets {
final int data = wrapper.get(Type.INT, 0); // Data
int typeID = wrapper.get(Type.BYTE, 0);
- if (EntityUtil.getTypeFromID(typeID, true) == EntityType.SPLASH_POTION) {
+ if (Entity1_10Types.getTypeFromId(typeID, true) == Entity1_10Types.EntityType.SPLASH_POTION) {
// Convert this to meta data, woo!
PacketWrapper metaPacket = wrapper.create(0x39, new ValueCreator() {
@Override
public void write(PacketWrapper wrapper) throws Exception {
wrapper.write(Type.VAR_INT, entityID);
List meta = new ArrayList<>();
- Item item = new Item((short) Material.POTION.getId(), (byte) 1, (short) data, null);
+ Item item = new Item((short) 373, (byte) 1, (short) data, null); // Potion
ItemRewriter.toClient(item); // Rewrite so that it gets the right nbt
// TEMP FIX FOR POTIONS UNTIL WE FIGURE OUT HOW TO TRANSFORM SENT PACKETS
- Metadata potion = new Metadata(5, NewType.Slot.getTypeID(), Type.ITEM, item);
+ Metadata potion = new Metadata(5, MetaType1_9.Slot, item);
meta.add(potion);
wrapper.write(Types1_9.METADATA_LIST, meta);
}
@@ -131,7 +129,7 @@ public class SpawnPackets {
public void handle(PacketWrapper wrapper) throws Exception {
int entityID = wrapper.get(Type.VAR_INT, 0);
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
- tracker.getClientEntityTypes().put(entityID, EntityType.EXPERIENCE_ORB);
+ tracker.getClientEntityTypes().put(entityID, Entity1_10Types.EntityType.EXPERIENCE_ORB);
tracker.sendMetadataBuffer(entityID);
}
});
@@ -157,7 +155,7 @@ public class SpawnPackets {
// Currently only lightning uses this
int entityID = wrapper.get(Type.VAR_INT, 0);
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
- tracker.getClientEntityTypes().put(entityID, EntityType.LIGHTNING);
+ tracker.getClientEntityTypes().put(entityID, Entity1_10Types.EntityType.LIGHTNING);
tracker.sendMetadataBuffer(entityID);
}
});
@@ -191,7 +189,7 @@ public class SpawnPackets {
int entityID = wrapper.get(Type.VAR_INT, 0);
int typeID = wrapper.get(Type.UNSIGNED_BYTE, 0);
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
- tracker.getClientEntityTypes().put(entityID, EntityUtil.getTypeFromID(typeID, false));
+ tracker.getClientEntityTypes().put(entityID, Entity1_10Types.getTypeFromId(typeID, false));
tracker.sendMetadataBuffer(entityID);
}
});
@@ -248,7 +246,7 @@ public class SpawnPackets {
public void handle(PacketWrapper wrapper) throws Exception {
int entityID = wrapper.get(Type.VAR_INT, 0);
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
- tracker.getClientEntityTypes().put(entityID, EntityType.PAINTING);
+ tracker.getClientEntityTypes().put(entityID, Entity1_10Types.EntityType.PAINTING);
tracker.sendMetadataBuffer(entityID);
}
});
@@ -282,7 +280,7 @@ public class SpawnPackets {
public void handle(PacketWrapper wrapper) throws Exception {
int entityID = wrapper.get(Type.VAR_INT, 0);
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
- tracker.getClientEntityTypes().put(entityID, EntityType.PLAYER);
+ tracker.getClientEntityTypes().put(entityID, Entity1_10Types.EntityType.PLAYER);
tracker.sendMetadataBuffer(entityID);
}
});
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java
similarity index 86%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java
index a9add7c8d..b4552defd 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/packets/WorldPackets.java
@@ -1,10 +1,11 @@
package us.myles.ViaVersion.protocols.protocol1_9to1_8.packets;
-import org.bukkit.Material;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
import org.spacehq.opennbt.tag.builtin.CompoundTag;
import org.spacehq.opennbt.tag.builtin.StringTag;
import us.myles.ViaVersion.api.PacketWrapper;
-import us.myles.ViaVersion.api.ViaVersion;
+import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.minecraft.Position;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.protocol.Protocol;
@@ -16,6 +17,7 @@ import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.ItemRewriter;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks.Chunk1_9to1_8;
+import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.sounds.Effect;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.sounds.SoundEffect;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks;
@@ -23,6 +25,9 @@ import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.PlaceBlockTracker;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.types.ChunkType;
+import java.io.IOException;
+import java.util.List;
+
public class WorldPackets {
public static void register(Protocol protocol) {
// Sign Update Packet
@@ -126,6 +131,37 @@ public class WorldPackets {
}
});
+ // Bulk Chunk Packet
+ protocol.registerOutgoing(State.PLAY, 0x26, -1, new PacketRemapper() {
+ @Override
+ public void registerMap() {
+ handler(new PacketHandler() {
+ @Override
+ public void handle(PacketWrapper wrapper) throws Exception {
+ wrapper.cancel(); // Cancel the packet from being sent
+ BulkChunkTranslatorProvider provider = Via.getManager().getProviders().get(BulkChunkTranslatorProvider.class);
+
+ // Don't read the packet
+ if (!provider.isPacketLevel())
+ return;
+
+ List list = provider.transformMapChunkBulk(wrapper, wrapper.user().get(ClientChunks.class));
+ for (Object obj : list) {
+ if (!(obj instanceof PacketWrapper))
+ throw new IOException("transformMapChunkBulk returned the wrong object type");
+
+ PacketWrapper output = (PacketWrapper) obj;
+ ByteBuf buffer = Unpooled.buffer();
+ output.setId(-1); // -1 for no writing of id
+ output.writeToBuffer(buffer);
+ PacketWrapper chunkPacket = new PacketWrapper(0x21, buffer, wrapper.user());
+ chunkPacket.send(Protocol1_9TO1_8.class, false);
+ }
+ }
+ });
+ }
+ });
+
// Update Block Entity Packet
protocol.registerOutgoing(State.PLAY, 0x35, 0x09, new PacketRemapper() {
@Override
@@ -168,7 +204,7 @@ public class WorldPackets {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
- if (ViaVersion.getConfig().isAutoTeam()) {
+ if (Via.getConfig().isAutoTeam()) {
EntityTracker entityTracker = wrapper.user().get(EntityTracker.class);
entityTracker.setAutoTeam(true);
entityTracker.sendTeamPacket(true);
@@ -259,19 +295,17 @@ public class WorldPackets {
// Write item in hand
Item item = Protocol1_9TO1_8.getHandItem(wrapper.user());
// Blocking patch
- if (ViaVersion.getConfig().isShieldBlocking()) {
+ if (Via.getConfig().isShieldBlocking()) {
if (item != null) {
- if (Material.getMaterial(item.getId()) != null) {
- if (Material.getMaterial(item.getId()).name().endsWith("SWORD")) {
- if (hand == 0) {
- EntityTracker tracker = wrapper.user().get(EntityTracker.class);
- if (!tracker.isBlocking()) {
- tracker.setBlocking(true);
- Item shield = new Item((short) 442, (byte) 1, (short) 0, null);
- tracker.setSecondHand(shield);
- }
- wrapper.cancel();
+ if (Protocol1_9TO1_8.isSword(item.getId())) {
+ if (hand == 0) {
+ EntityTracker tracker = wrapper.user().get(EntityTracker.class);
+ if (!tracker.isBlocking()) {
+ tracker.setBlocking(true);
+ Item shield = new Item((short) 442, (byte) 1, (short) 0, null);
+ tracker.setSecondHand(shield);
}
+ wrapper.cancel();
}
}
}
diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/providers/BulkChunkTranslatorProvider.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/providers/BulkChunkTranslatorProvider.java
new file mode 100644
index 000000000..3d06352fa
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/providers/BulkChunkTranslatorProvider.java
@@ -0,0 +1,96 @@
+package us.myles.ViaVersion.protocols.protocol1_9to1_8.providers;
+
+import lombok.Data;
+import us.myles.ViaVersion.api.PacketWrapper;
+import us.myles.ViaVersion.api.platform.providers.Provider;
+import us.myles.ViaVersion.api.type.Type;
+import us.myles.ViaVersion.api.type.types.CustomByteType;
+import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BulkChunkTranslatorProvider implements Provider {
+ /**
+ * Transforms a Bulk Chunk packet into Chunk Packets
+ *
+ * @param packet The NMS Packet
+ * @param clientChunks The ClientChunks object for the current player
+ * @return A List of all the output packets
+ */
+ public List transformMapChunkBulk(Object packet, ClientChunks clientChunks) throws Exception {
+ if (!(packet instanceof PacketWrapper))
+ throw new IllegalArgumentException("The default packet has to be a PacketWrapper for transformMapChunkBulk, unexpected " + packet.getClass());
+
+ List packets = new ArrayList<>();
+ PacketWrapper wrapper = (PacketWrapper) packet;
+
+ boolean skyLight = wrapper.read(Type.BOOLEAN);
+ int count = wrapper.read(Type.VAR_INT);
+
+ ChunkBulkSection[] metas = new ChunkBulkSection[count];
+ for (int i = 0; i < count; i++) {
+ metas[i] = ChunkBulkSection.read(wrapper, skyLight);
+ }
+
+ for (ChunkBulkSection meta : metas) {
+ CustomByteType customByteType = new CustomByteType(meta.getLength());
+ meta.setData(wrapper.read(customByteType));
+
+ // Construct chunk packet
+ PacketWrapper chunkPacket = new PacketWrapper(0x21, null, wrapper.user());
+ chunkPacket.write(Type.INT, meta.getX());
+ chunkPacket.write(Type.INT, meta.getZ());
+ chunkPacket.write(Type.BOOLEAN, true); // Always ground-up
+ chunkPacket.write(Type.UNSIGNED_SHORT, meta.getBitMask());
+ chunkPacket.write(Type.VAR_INT, meta.getLength());
+ chunkPacket.write(customByteType, meta.getData());
+
+ clientChunks.getBulkChunks().add(ClientChunks.toLong(meta.getX(), meta.getZ())); // Store for later
+ packets.add(chunkPacket);
+ }
+
+ return packets;
+ }
+
+
+ /**
+ * Check if a packet of a class should be filtered
+ *
+ * @param packet NMS Packet
+ * @return True if it should be filtered into transformmapChunkBulk
+ */
+ public boolean isFiltered(Class> packet) {
+ return false;
+ }
+
+ /**
+ * Check if the packet should be provided as PacketWrapper
+ *
+ * @return True if enabled
+ */
+ public boolean isPacketLevel() {
+ return true;
+ }
+
+ @Data
+ private static class ChunkBulkSection {
+ private int x;
+ private int z;
+ private int bitMask;
+ private int length;
+ private byte[] data;
+
+ public static ChunkBulkSection read(PacketWrapper wrapper, boolean skylight) throws Exception {
+ ChunkBulkSection bulkSection = new ChunkBulkSection();
+ bulkSection.setX(wrapper.read(Type.INT));
+ bulkSection.setZ(wrapper.read(Type.INT));
+ bulkSection.setBitMask(wrapper.read(Type.UNSIGNED_SHORT));
+
+ int bitCount = Integer.bitCount(bulkSection.getBitMask());
+ bulkSection.setLength((bitCount * ((4096 * 2) + 2048)) + (skylight ? bitCount * 2048 : 0) + 256); // Thanks MCProtocolLib
+
+ return bulkSection;
+ }
+ }
+}
diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/providers/HandItemProvider.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/providers/HandItemProvider.java
new file mode 100644
index 000000000..a839dc353
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/providers/HandItemProvider.java
@@ -0,0 +1,11 @@
+package us.myles.ViaVersion.protocols.protocol1_9to1_8.providers;
+
+import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.api.minecraft.item.Item;
+import us.myles.ViaVersion.api.platform.providers.Provider;
+
+public class HandItemProvider implements Provider {
+ public Item getHandItem(final UserConnection info) {
+ return new Item((short) 0, (byte) 0, (short) 0, null);
+ }
+}
diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/providers/MovementTransmitterProvider.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/providers/MovementTransmitterProvider.java
new file mode 100644
index 000000000..311859e90
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/providers/MovementTransmitterProvider.java
@@ -0,0 +1,26 @@
+package us.myles.ViaVersion.protocols.protocol1_9to1_8.providers;
+
+import io.netty.channel.ChannelHandlerContext;
+import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.api.platform.providers.Provider;
+import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.MovementTracker;
+import us.myles.ViaVersion.util.PipelineUtil;
+
+public abstract class MovementTransmitterProvider implements Provider {
+ public abstract Object getFlyingPacket();
+
+ public abstract Object getGroundPacket();
+
+ public void sendPlayer(UserConnection userConnection) {
+ // Old method using packets.
+ ChannelHandlerContext context = PipelineUtil.getContextBefore("decoder", userConnection.getChannel().pipeline());
+ if (context != null) {
+ if (userConnection.get(MovementTracker.class).isGround()) {
+ context.fireChannelRead(getGroundPacket());
+ } else {
+ context.fireChannelRead(getFlyingPacket());
+ }
+ userConnection.get(MovementTracker.class).incrementIdlePacket();
+ }
+ }
+}
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/sounds/Effect.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/sounds/Effect.java
similarity index 95%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/sounds/Effect.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/sounds/Effect.java
index b6a348e57..964ef9611 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/sounds/Effect.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/sounds/Effect.java
@@ -4,7 +4,7 @@ import java.util.HashMap;
public class Effect {
- private static HashMap effects;
+ private final static HashMap effects;
static {
effects = new HashMap<>();
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/sounds/SoundCategory.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/sounds/SoundCategory.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/sounds/SoundCategory.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/sounds/SoundCategory.java
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/sounds/SoundEffect.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/sounds/SoundEffect.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/sounds/SoundEffect.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/sounds/SoundEffect.java
diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/ClientChunks.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/ClientChunks.java
new file mode 100644
index 000000000..e4149ef73
--- /dev/null
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/ClientChunks.java
@@ -0,0 +1,29 @@
+package us.myles.ViaVersion.protocols.protocol1_9to1_8.storage;
+
+import com.google.common.collect.Sets;
+import lombok.Getter;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.data.StoredObject;
+import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
+
+import java.util.List;
+import java.util.Set;
+
+@Getter
+public class ClientChunks extends StoredObject {
+ private final Set loadedChunks = Sets.newConcurrentHashSet();
+ private final Set bulkChunks = Sets.newConcurrentHashSet();
+
+ public ClientChunks(UserConnection user) {
+ super(user);
+ }
+
+ public static long toLong(int msw, int lsw) {
+ return ((long) msw << 32) + lsw - -2147483648L;
+ }
+
+ public List transformMapChunkBulk(Object packet) throws Exception {
+ return Via.getManager().getProviders().get(BulkChunkTranslatorProvider.class).transformMapChunkBulk(packet, this);
+ }
+}
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/EntityTracker.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/EntityTracker.java
similarity index 84%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/EntityTracker.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/EntityTracker.java
index 298da7263..b1521fc18 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/EntityTracker.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/EntityTracker.java
@@ -6,25 +6,24 @@ import com.google.common.collect.Sets;
import io.netty.buffer.ByteBuf;
import lombok.Getter;
import lombok.Setter;
-import org.bukkit.Material;
-import org.bukkit.entity.EntityType;
import us.myles.ViaVersion.api.PacketWrapper;
-import us.myles.ViaVersion.api.ViaVersion;
+import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.boss.BossBar;
import us.myles.ViaVersion.api.boss.BossColor;
import us.myles.ViaVersion.api.boss.BossStyle;
import us.myles.ViaVersion.api.data.StoredObject;
import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.api.entities.Entity1_10Types;
import us.myles.ViaVersion.api.minecraft.Position;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
+import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_9;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.version.Types1_9;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.chat.GameMode;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.metadata.MetadataRewriter;
-import us.myles.ViaVersion.protocols.protocol1_9to1_8.metadata.NewType;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@@ -33,13 +32,13 @@ import java.util.concurrent.TimeUnit;
@Getter
public class EntityTracker extends StoredObject {
private final Map uuidMap = new ConcurrentHashMap<>();
- private final Map clientEntityTypes = new ConcurrentHashMap<>();
+ private final Map clientEntityTypes = new ConcurrentHashMap<>();
private final Map> metadataBuffer = new ConcurrentHashMap<>();
private final Map vehicleMap = new ConcurrentHashMap<>();
private final Map bossBarMap = new ConcurrentHashMap<>();
private final Set validBlocking = Sets.newConcurrentHashSet();
private final Set knownHolograms = Sets.newConcurrentHashSet();
- private final Cache blockInteractions = CacheBuilder.newBuilder().maximumSize(10).expireAfterAccess(250, TimeUnit.MILLISECONDS).build();
+ private final Cache blockInteractions = CacheBuilder.newBuilder().maximumSize(10).expireAfterAccess(250, TimeUnit.MILLISECONDS).build();
@Setter
private boolean blocking = false;
@Setter
@@ -99,9 +98,7 @@ public class EntityTracker extends StoredObject {
public boolean interactedBlockRecently(int x, int y, int z) {
if (blockInteractions.size() == 0)
return false;
- Iterator it = blockInteractions.asMap().keySet().iterator();
- while (it.hasNext()) {
- Position p = it.next();
+ for (Position p : blockInteractions.asMap().keySet()) {
if (p.getX() == x)
if (p.getY() == y)
if (p.getZ() == z)
@@ -111,7 +108,7 @@ public class EntityTracker extends StoredObject {
}
public void addBlockInteraction(Position p) {
- blockInteractions.put(p, Material.AIR);
+ blockInteractions.put(p, 0);
}
public void handleMetadata(int entityID, List metadataList) {
@@ -119,41 +116,41 @@ public class EntityTracker extends StoredObject {
return;
}
- EntityType type = clientEntityTypes.get(entityID);
+ Entity1_10Types.EntityType type = clientEntityTypes.get(entityID);
for (Metadata metadata : new ArrayList<>(metadataList)) {
// Fix: wither (crash fix)
- if (type == EntityType.WITHER) {
+ if (type == Entity1_10Types.EntityType.WITHER) {
if (metadata.getId() == 10) {
metadataList.remove(metadata);
//metadataList.add(new Metadata(10, NewType.Byte.getTypeID(), Type.BYTE, 0));
}
}
// Fix: enderdragon (crash fix)
- if (type == EntityType.ENDER_DRAGON) {
+ if (type == Entity1_10Types.EntityType.ENDER_DRAGON) {
if (metadata.getId() == 11) {
metadataList.remove(metadata);
// metadataList.add(new Metadata(11, NewType.Byte.getTypeID(), Type.VAR_INT, 0));
}
}
- if (type == EntityType.SKELETON) {
+ if (type == Entity1_10Types.EntityType.SKELETON) {
if ((getMetaByIndex(metadataList, 12)) == null) {
- metadataList.add(new Metadata(12, NewType.Boolean.getTypeID(), Type.BOOLEAN, true));
+ metadataList.add(new Metadata(12, MetaType1_9.Boolean, true));
}
}
//ECHOPET Patch
- if (type == EntityType.HORSE) {
+ if (type == Entity1_10Types.EntityType.HORSE) {
// Wrong metadata value from EchoPet, patch since it's discontinued. (https://github.com/DSH105/EchoPet/blob/06947a8b08ce40be9a518c2982af494b3b99d140/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/HorseArmour.java#L22)
if (metadata.getId() == 16 && (int) metadata.getValue() == Integer.MIN_VALUE)
metadata.setValue(0);
}
- if (type == EntityType.PLAYER) {
+ if (type == Entity1_10Types.EntityType.PLAYER) {
if (metadata.getId() == 0) {
// Byte
byte data = (byte) metadata.getValue();
- if (entityID != getEntityID() && ViaVersion.getConfig().isShieldBlocking()) {
+ if (entityID != getEntityID() && Via.getConfig().isShieldBlocking()) {
if ((data & 0x10) == 0x10) {
if (validBlocking.contains(entityID)) {
Item shield = new Item((short) 442, (byte) 1, (short) 0, null);
@@ -165,7 +162,7 @@ public class EntityTracker extends StoredObject {
}
}
}
- if (type == EntityType.ARMOR_STAND && ViaVersion.getConfig().isHologramPatch()) {
+ if (type == Entity1_10Types.EntityType.ARMOR_STAND && Via.getConfig().isHologramPatch()) {
if (metadata.getId() == 0 && getMetaByIndex(metadataList, 10) != null) {
Metadata meta = getMetaByIndex(metadataList, 10); //Only happens if the armorstand is small
byte data = (byte) metadata.getValue();
@@ -180,7 +177,7 @@ public class EntityTracker extends StoredObject {
Type.VAR_INT.write(buf, 0x25); // Relative Move Packet
Type.VAR_INT.write(buf, entityID);
buf.writeShort(0);
- buf.writeShort((short) (128D * (ViaVersion.getConfig().getHologramYOffset() * 32D)));
+ buf.writeShort((short) (128D * (Via.getConfig().getHologramYOffset() * 32D)));
buf.writeShort(0);
buf.writeBoolean(true);
getUser().sendRawPacket(buf, false);
@@ -192,28 +189,28 @@ public class EntityTracker extends StoredObject {
}
UUID uuid = getUser().get(ProtocolInfo.class).getUuid();
// Boss bar
- if (ViaVersion.getConfig().isBossbarPatch()) {
- if (type == EntityType.ENDER_DRAGON || type == EntityType.WITHER) {
+ if (Via.getConfig().isBossbarPatch()) {
+ if (type == Entity1_10Types.EntityType.ENDER_DRAGON || type == Entity1_10Types.EntityType.WITHER) {
if (metadata.getId() == 2) {
BossBar bar = bossBarMap.get(entityID);
String title = (String) metadata.getValue();
- title = title.isEmpty() ? (type == EntityType.ENDER_DRAGON ? "Ender Dragon" : "Wither") : title;
+ title = title.isEmpty() ? (type == Entity1_10Types.EntityType.ENDER_DRAGON ? "Ender Dragon" : "Wither") : title;
if (bar == null) {
- bar = ViaVersion.getInstance().createBossBar(title, BossColor.PINK, BossStyle.SOLID);
+ bar = Via.getAPI().createBossBar(title, BossColor.PINK, BossStyle.SOLID);
bossBarMap.put(entityID, bar);
bar.addPlayer(uuid);
bar.show();
} else {
bar.setTitle(title);
}
- } else if (metadata.getId() == 6 && !ViaVersion.getConfig().isBossbarAntiflicker()) { // If anti flicker is enabled, don't update health
+ } else if (metadata.getId() == 6 && !Via.getConfig().isBossbarAntiflicker()) { // If anti flicker is enabled, don't update health
BossBar bar = bossBarMap.get(entityID);
// Make health range between 0 and 1
- float maxHealth = type == EntityType.ENDER_DRAGON ? 200.0f : 300.0f;
+ float maxHealth = type == Entity1_10Types.EntityType.ENDER_DRAGON ? 200.0f : 300.0f;
float health = Math.max(0.0f, Math.min(((float) metadata.getValue()) / maxHealth, 1.0f));
if (bar == null) {
- String title = type == EntityType.ENDER_DRAGON ? "Ender Dragon" : "Wither";
- bar = ViaVersion.getInstance().createBossBar(title, health, BossColor.PINK, BossStyle.SOLID);
+ String title = type == Entity1_10Types.EntityType.ENDER_DRAGON ? "Ender Dragon" : "Wither";
+ bar = Via.getAPI().createBossBar(title, health, BossColor.PINK, BossStyle.SOLID);
bossBarMap.put(entityID, bar);
bar.addPlayer(uuid);
bar.show();
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/InventoryTracker.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/InventoryTracker.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/InventoryTracker.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/InventoryTracker.java
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/MovementTracker.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/MovementTracker.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/MovementTracker.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/MovementTracker.java
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/PlaceBlockTracker.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/PlaceBlockTracker.java
similarity index 76%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/PlaceBlockTracker.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/PlaceBlockTracker.java
index a8ea3fe73..d3e5d718f 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/PlaceBlockTracker.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/storage/PlaceBlockTracker.java
@@ -16,10 +16,19 @@ public class PlaceBlockTracker extends StoredObject {
super(user);
}
+ /**
+ * Check if a certain amount of time has passed
+ *
+ * @param ms The amount of time in MS
+ * @return True if it has passed
+ */
public boolean isExpired(int ms) {
return System.currentTimeMillis() > (lastPlaceTimestamp + ms);
}
+ /**
+ * Set the last place time to the current time
+ */
public void updateTime() {
lastPlaceTimestamp = System.currentTimeMillis();
}
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/ChunkType.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/ChunkType.java
similarity index 95%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/ChunkType.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/ChunkType.java
index 63c57a9ca..8ac1c6303 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/ChunkType.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/types/ChunkType.java
@@ -2,8 +2,7 @@ package us.myles.ViaVersion.protocols.protocol1_9to1_8.types;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
-import org.bukkit.Bukkit;
-import us.myles.ViaVersion.api.ViaVersion;
+import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
import us.myles.ViaVersion.api.type.PartialType;
import us.myles.ViaVersion.api.type.Type;
@@ -49,8 +48,8 @@ public class ChunkType extends PartialType {
@Override
public Chunk read(ByteBuf input, ClientChunks param) throws Exception {
- boolean replacePistons = param.getUser().get(ProtocolInfo.class).getPipeline().contains(Protocol1_10To1_9_3_4.class) && ViaVersion.getConfig().isReplacePistons();
- int replacementId = ViaVersion.getConfig().getPistonReplacementId();
+ boolean replacePistons = param.getUser().get(ProtocolInfo.class).getPipeline().contains(Protocol1_10To1_9_3_4.class) && Via.getConfig().isReplacePistons();
+ int replacementId = Via.getConfig().getPistonReplacementId();
int chunkX = input.readInt();
int chunkZ = input.readInt();
@@ -134,7 +133,7 @@ public class ChunkType extends PartialType {
// Check remaining bytes
if (bytesLeft > 0) {
- Bukkit.getLogger().log(Level.WARNING, bytesLeft + " Bytes left after reading chunks! (" + groundUp + ")");
+ Via.getPlatform().getLogger().log(Level.WARNING, bytesLeft + " Bytes left after reading chunks! (" + groundUp + ")");
}
// Return chunks
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_9_1/Protocol1_9TO1_9_1.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_9_1/Protocol1_9TO1_9_1.java
similarity index 100%
rename from src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_9_1/Protocol1_9TO1_9_1.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_9_1/Protocol1_9TO1_9_1.java
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_10/ItemRewriter.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_10/ItemRewriter.java
similarity index 93%
rename from src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_10/ItemRewriter.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_10/ItemRewriter.java
index b684a7f37..ada23508d 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_10/ItemRewriter.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_10/ItemRewriter.java
@@ -1,6 +1,5 @@
package us.myles.ViaVersion.protocols.protocolsnapshotto1_10;
-import org.bukkit.Material;
import org.spacehq.opennbt.tag.builtin.CompoundTag;
import org.spacehq.opennbt.tag.builtin.StringTag;
import us.myles.ViaVersion.api.minecraft.item.Item;
@@ -31,7 +30,7 @@ public class ItemRewriter {
}
private static boolean hasEntityTag(Item item) {
- if (item != null && item.getId() == Material.MONSTER_EGG.getId()) {
+ if (item != null && item.getId() == 383) { // Monster Egg
CompoundTag tag = item.getTag();
if (tag != null && tag.contains("EntityTag") && tag.get("EntityTag") instanceof CompoundTag) {
if (((CompoundTag) tag.get("EntityTag")).get("id") instanceof StringTag) {
diff --git a/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_10/MetadataRewriter.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_10/MetadataRewriter.java
similarity index 50%
rename from src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_10/MetadataRewriter.java
rename to common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_10/MetadataRewriter.java
index 16d3c6114..e4aa98f6f 100644
--- a/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_10/MetadataRewriter.java
+++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocolsnapshotto1_10/MetadataRewriter.java
@@ -1,55 +1,67 @@
package us.myles.ViaVersion.protocols.protocolsnapshotto1_10;
import com.google.common.base.Optional;
-import us.myles.ViaVersion.api.ViaVersion;
+import us.myles.ViaVersion.api.PacketWrapper;
+import us.myles.ViaVersion.api.Via;
+import us.myles.ViaVersion.api.data.UserConnection;
+import us.myles.ViaVersion.api.entities.Entity1_11Types.EntityType;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
+import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_9;
import us.myles.ViaVersion.api.type.Type;
-import us.myles.ViaVersion.protocols.protocol1_9to1_8.metadata.NewType;
+import us.myles.ViaVersion.protocols.protocolsnapshotto1_10.storage.EntityTracker;
import java.util.ArrayList;
import java.util.List;
public class MetadataRewriter {
- public static int rewriteEntityType(int currentType, List metadata) {
+ public static EntityType rewriteEntityType(int numType, List metadata) {
+ Optional optType = EntityType.findById(numType);
+ if (!optType.isPresent()) {
+ Via.getManager().getPlatform().getLogger().severe("Error: could not find Entity type " + numType + " with metadata: " + metadata);
+ return null;
+ }
+
+ EntityType type = optType.get();
+
try {
- if (currentType == 68) {
+ if (type.is(EntityType.GUARDIAN)) {
// ElderGuardian - 4
Optional options = getById(metadata, 12);
if (options.isPresent()) {
if ((((byte) options.get().getValue()) & 0x04) == 0x04) {
- return 4;
+ return EntityType.ELDER_GUARDIAN;
}
}
}
- if (currentType == 51) {
+ if (type.is(EntityType.SKELETON)) {
// WitherSkeleton - 5
// Stray - 6
Optional options = getById(metadata, 12);
if (options.isPresent()) {
if (((int) options.get().getValue()) == 1) {
- return 5;
+ return EntityType.WITHER_SKELETON;
}
if (((int) options.get().getValue()) == 2) {
- return 6;
+ return EntityType.STRAY;
}
}
}
- if (currentType == 54) {
+ if (type.is(EntityType.ZOMBIE)) {
// ZombieVillager - 27
// Husk - 23
Optional options = getById(metadata, 13);
if (options.isPresent()) {
int value = (int) options.get().getValue();
if (value > 0 && value < 6) {
- metadata.add(new Metadata(16, NewType.VarInt.getTypeID(), Type.VAR_INT, value - 1)); // Add profession type to new metadata
- return 27;
+ metadata.add(new Metadata(16, MetaType1_9.VarInt, value - 1)); // Add profession type to new metadata
+ return EntityType.ZOMBIE_VILLAGER;
}
if (value == 6) {
- return 23;
+ return EntityType.HUSK;
}
}
}
- if (currentType == 100) {
+ if (type.is(EntityType.HORSE)) {
// SkeletonHorse - 28
// ZombieHorse - 29
// Donkey - 31
@@ -57,47 +69,45 @@ public class MetadataRewriter {
Optional options = getById(metadata, 14);
if (options.isPresent()) {
if (((int) options.get().getValue()) == 0) {
- return currentType;
+ return EntityType.HORSE;
}
if (((int) options.get().getValue()) == 1) {
- return 31;
+ return EntityType.DONKEY;
}
if (((int) options.get().getValue()) == 2) {
- return 32;
+ return EntityType.MULE;
}
if (((int) options.get().getValue()) == 3) {
- return 29;
+ return EntityType.ZOMBIE_HORSE;
}
if (((int) options.get().getValue()) == 4) {
- return 28;
+ return EntityType.SKELETON_HORSE;
}
}
}
- return currentType;
} catch (Exception e) {
- ;
- if (!ViaVersion.getConfig().isSuppressMetadataErrors() || ViaVersion.getInstance().isDebug()) {
+ if (!Via.getConfig().isSuppressMetadataErrors() || Via.getManager().isDebug()) {
System.out.println("An error occurred with entity type rewriter");
System.out.println("Metadata: " + metadata);
e.printStackTrace();
}
}
- return currentType;
+
+ return type;
}
- public static void handleMetadata(int type, List metadatas) {
+ public static void handleMetadata(int entityId, EntityType type, List metadatas, UserConnection connection) {
for (Metadata metadata : new ArrayList<>(metadatas)) {
try {
- if (type == 4 || type == 68) { // Guardians
+ if (type.is(EntityType.ELDER_GUARDIAN) || type.is(EntityType.GUARDIAN)) { // Guardians
int oldid = metadata.getId();
if (oldid == 12) {
- metadata.setType(Type.BOOLEAN);
- metadata.setTypeID(NewType.Boolean.getTypeID());
+ metadata.setMetaType(MetaType1_9.Boolean);
boolean val = (((byte) metadata.getValue()) & 0x02) == 0x02;
metadata.setValue(val);
}
}
- if (type == 51 || type == 5 || type == 6) { // Skeletons
+ if (type.isOrHasParent(EntityType.ABSTRACT_SKELETON)) { // Skeletons
int oldid = metadata.getId();
if (oldid == 12) {
metadatas.remove(metadata);
@@ -106,8 +116,8 @@ public class MetadataRewriter {
metadata.setId(12);
}
}
- if (type == 54 || type == 27) { // Zombie | Zombie Villager
- if (type == 54 && metadata.getId() == 14) {
+ if (type.isOrHasParent(EntityType.ZOMBIE)) { // Zombie | Zombie Villager | Husk
+ if (type.is(EntityType.ZOMBIE, EntityType.HUSK) && metadata.getId() == 14) {
metadatas.remove(metadata);
} else {
if (metadata.getId() == 15) {
@@ -119,7 +129,7 @@ public class MetadataRewriter {
}
}
}
- if (type == 100 || type == 31 || type == 32 || type == 29 || type == 28) { // Horses
+ if (type.isOrHasParent(EntityType.ABSTRACT_HORSE)) { // Horses
// Remap metadata id
int oldid = metadata.getId();
if (oldid == 14) { // Type
@@ -133,7 +143,7 @@ public class MetadataRewriter {
}
// Process per type
- if (type == 100) {
+ if (type.is(EntityType.HORSE)) {
// Normal Horse
} else {
// Remove 15, 16
@@ -141,26 +151,57 @@ public class MetadataRewriter {
metadatas.remove(metadata);
}
}
- if (type == 31 || type == 32) {
+ if (type.is(EntityType.DONKEY, EntityType.MULE)) {
// Chested Horse
if (metadata.getId() == 13) {
if ((((byte) metadata.getValue()) & 0x08) == 0x08) {
- metadatas.add(new Metadata(15, NewType.Boolean.getTypeID(), Type.BOOLEAN, true));
+ metadatas.add(new Metadata(15, MetaType1_9.Boolean, true));
} else {
- metadatas.add(new Metadata(15, NewType.Boolean.getTypeID(), Type.BOOLEAN, false));
+ metadatas.add(new Metadata(15, MetaType1_9.Boolean, false));
+ }
+ }
+ }
+ }
+ if (type.is(EntityType.ARMOR_STAND) && Via.getConfig().isHologramPatch()) {
+ Optional flags = getById(metadatas, 11);
+ Optional customName = getById(metadatas, 2);
+ Optional customNameVisible = getById(metadatas, 3);
+ if (metadata.getId() == 0 && flags.isPresent() && customName.isPresent() && customNameVisible.isPresent()) {
+ Metadata meta = flags.get();
+ byte data = (byte) metadata.getValue();
+ // Check invisible | Check small | Check if custom name is empty | Check if custom name visible is true
+ if ((data & 0x20) == 0x20 && ((byte) meta.getValue() & 0x01) == 0x01
+ && ((String) customName.get().getValue()).length() != 0 && (boolean) customNameVisible.get().getValue()) {
+ EntityTracker tracker = connection.get(EntityTracker.class);
+ if (!tracker.isHologram(entityId)) {
+ tracker.addHologram(entityId);
+ try {
+ // Send movement
+ PacketWrapper wrapper = new PacketWrapper(0x25, null, connection);
+ wrapper.write(Type.VAR_INT, entityId);
+ wrapper.write(Type.SHORT, (short) 0);
+ wrapper.write(Type.SHORT, (short) (128D * (-Via.getConfig().getHologramYOffset() * 32D)));
+ wrapper.write(Type.SHORT, (short) 0);
+ wrapper.write(Type.BOOLEAN, true);
+
+ wrapper.send(ProtocolSnapshotTo1_10.class);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
}
}
}
} catch (Exception e) {
metadatas.remove(metadata);
- if (!ViaVersion.getConfig().isSuppressMetadataErrors() || ViaVersion.getInstance().isDebug()) {
+ if (!Via.getConfig().isSuppressMetadataErrors() || Via.getManager().isDebug()) {
System.out.println("An error occurred with entity metadata handler");
System.out.println("Metadata: " + metadata);
e.printStackTrace();
}
}
}
+
}
public static Optional getById(List