From 4c07b6d28d9ee5d0584713a8100c307d03873478 Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Sun, 30 Sep 2018 10:30:34 -0300 Subject: [PATCH 1/5] Squash Velocity platform commits incomplete velocity code untested velocity version detector update velocity module version Injecting, but not working facepalm Fix handler type Should work now will it work now? it works!!! fix npe in command tab completion Do not forward command to server implement server changing with different versions thanks @Leymooo Fix memory leaks maybe cleaner code? trying to port mainhandpatch, added todo fix version Use separated protocol version, add todo Trying to mitigate UserConnection#toServer concurrent issue port elytrapatch it works but horribly and needs a modification in velocity replace with a semaphore and EventLoop#submit Lock for incoming packets fix version remove some TODOs Listen to DisconnectEvent Relocate snakeyaml --- .../bukkit/platform/BukkitConfigAPI.java | 2 +- .../bungee/platform/BungeeConfigAPI.java | 2 +- common/pom.xml | 2 +- .../ViaVersion/api/data/UserConnection.java | 10 +- .../commands/ViaCommandHandler.java | 2 +- .../myles/ViaVersion/util/PipelineUtil.java | 19 ++ .../resources/assets/viaversion/config.yml | 22 ++ jar/pom.xml | 9 + pom.xml | 1 + .../sponge/platform/SpongeConfigAPI.java | 2 +- velocity/pom.xml | 62 ++++ .../ViaVersion/velocity/VersionInfo.java | 5 + .../us/myles/ViaVersion/VelocityPlugin.java | 203 +++++++++++++ .../command/VelocityCommandHandler.java | 29 ++ .../command/VelocityCommandSender.java | 46 +++ .../velocity/command/subs/ProbeSubCmd.java | 28 ++ .../handlers/VelocityChannelInitializer.java | 38 +++ .../handlers/VelocityDecodeHandler.java | 78 +++++ .../handlers/VelocityEncodeHandler.java | 90 ++++++ .../handlers/VelocityServerHandler.java | 138 +++++++++ .../velocity/listeners/ElytraPatch.java | 44 +++ .../velocity/listeners/MainHandPatch.java | 49 ++++ .../velocity/listeners/UpdateListener.java | 16 + .../velocity/platform/VelocityBossBar.java | 13 + .../velocity/platform/VelocityTaskId.java | 12 + .../velocity/platform/VelocityViaAPI.java | 78 +++++ .../velocity/platform/VelocityViaConfig.java | 275 ++++++++++++++++++ .../platform/VelocityViaInjector.java | 41 +++ .../velocity/platform/VelocityViaLoader.java | 45 +++ .../providers/VelocityBossBarProvider.java | 30 ++ .../VelocityMovementTransmitter.java | 35 +++ .../providers/VelocityVersionProvider.java | 73 +++++ .../service/ProtocolDetectorService.java | 82 ++++++ .../velocity/storage/VelocityStorage.java | 38 +++ .../velocity/util/LoggerWrapper.java | 69 +++++ 35 files changed, 1680 insertions(+), 8 deletions(-) create mode 100644 velocity/pom.xml create mode 100644 velocity/src/main/java-templates/us/myles/ViaVersion/velocity/VersionInfo.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/command/VelocityCommandHandler.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/command/VelocityCommandSender.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/command/subs/ProbeSubCmd.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityChannelInitializer.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityDecodeHandler.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityEncodeHandler.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityServerHandler.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/ElytraPatch.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/MainHandPatch.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/UpdateListener.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityBossBar.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityTaskId.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaAPI.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaInjector.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaLoader.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityBossBarProvider.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityMovementTransmitter.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityVersionProvider.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/service/ProtocolDetectorService.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/storage/VelocityStorage.java create mode 100644 velocity/src/main/java/us/myles/ViaVersion/velocity/util/LoggerWrapper.java 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 index b033cdb79..74db3b715 100644 --- a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java +++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java @@ -12,7 +12,7 @@ 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"); + private static List UNSUPPORTED = Arrays.asList("bungee-ping-interval", "bungee-ping-save", "bungee-servers", "velocity-ping-interval", "velocity-ping-save", "velocity-servers"); public BukkitConfigAPI() { super(new File(((ViaVersionPlugin) Via.getPlatform()).getDataFolder(), "config.yml")); 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 index 1c013f3f2..4f9112099 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java +++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java @@ -10,7 +10,7 @@ import java.net.URL; import java.util.*; public class BungeeConfigAPI extends Config implements ViaVersionConfig { - private static List UNSUPPORTED = Arrays.asList("nms-player-ticking", "item-cache", "anti-xray-patch", "quick-move-action-fix"); + private static List UNSUPPORTED = Arrays.asList("nms-player-ticking", "item-cache", "anti-xray-patch", "quick-move-action-fix", "velocity-ping-interval", "velocity-ping-save", "velocity-servers"); public BungeeConfigAPI(File configFile) { super(new File(configFile, "config.yml")); diff --git a/common/pom.xml b/common/pom.xml index d1cad3b92..351079c5d 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -17,7 +17,7 @@ org.yaml snakeyaml 1.18 - provided + compile \ No newline at end of file diff --git a/common/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java b/common/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java index aa9019262..a620c3798 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java +++ b/common/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java @@ -18,6 +18,8 @@ import us.myles.ViaVersion.util.PipelineUtil; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; @Data public class UserConnection { @@ -36,7 +38,7 @@ public class UserConnection { // Used for handling warnings (over time) private int secondsObserved = 0; private int warnings = 0; - + private ReadWriteLock velocityLock = new ReentrantReadWriteLock(); public UserConnection(Channel channel) { this.channel = channel; @@ -108,7 +110,8 @@ public class UserConnection { */ public ChannelFuture sendRawPacketFuture(final ByteBuf packet) { final ChannelHandler handler = channel.pipeline().get(Via.getManager().getInjector().getEncoderName()); - return channel.pipeline().context(handler).writeAndFlush(packet); + ChannelFuture future = channel.pipeline().context(handler).writeAndFlush(packet); + return future; } /** @@ -218,7 +221,8 @@ public class UserConnection { } buf.writeBytes(packet); packet.release(); - final ChannelHandlerContext context = PipelineUtil.getPreviousContext(Via.getManager().getInjector().getDecoderName(), getChannel().pipeline()); + final ChannelHandlerContext context = PipelineUtil + .getPreviousContext(Via.getManager().getInjector().getDecoderName(), getChannel().pipeline()); if (currentThread) { if (context != null) { context.fireChannelRead(buf); diff --git a/common/src/main/java/us/myles/ViaVersion/commands/ViaCommandHandler.java b/common/src/main/java/us/myles/ViaVersion/commands/ViaCommandHandler.java index c6afc0b6e..5610e2a50 100644 --- a/common/src/main/java/us/myles/ViaVersion/commands/ViaCommandHandler.java +++ b/common/src/main/java/us/myles/ViaVersion/commands/ViaCommandHandler.java @@ -74,7 +74,7 @@ public abstract class ViaCommandHandler implements ViaVersionCommand { //SubCommands tabcomplete if (args.length == 1) { - if (!args[0].equals("")) { + if (!args[0].isEmpty()) { for (ViaSubCommand sub : allowed) if (sub.name().toLowerCase().startsWith(args[0].toLowerCase())) output.add(sub.name()); diff --git a/common/src/main/java/us/myles/ViaVersion/util/PipelineUtil.java b/common/src/main/java/us/myles/ViaVersion/util/PipelineUtil.java index f5bdd51f9..6be8ac0b8 100644 --- a/common/src/main/java/us/myles/ViaVersion/util/PipelineUtil.java +++ b/common/src/main/java/us/myles/ViaVersion/util/PipelineUtil.java @@ -5,6 +5,8 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPipeline; import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.MessageToByteEncoder; +import io.netty.handler.codec.MessageToMessageDecoder; +import io.netty.handler.codec.MessageToMessageEncoder; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -14,6 +16,7 @@ import java.util.List; public class PipelineUtil { private static Method DECODE_METHOD; private static Method ENCODE_METHOD; + private static Method MTM_DECODE; static { try { @@ -28,6 +31,12 @@ public class PipelineUtil { } catch (NoSuchMethodException e) { e.printStackTrace(); } + try { + MTM_DECODE = MessageToMessageDecoder.class.getDeclaredMethod("decode", ChannelHandlerContext.class, Object.class, List.class); + MTM_DECODE.setAccessible(true); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } } /** @@ -66,6 +75,16 @@ public class PipelineUtil { } } + public static List callDecode(MessageToMessageDecoder decoder, ChannelHandlerContext ctx, Object msg) throws InvocationTargetException { + List output = new ArrayList<>(); + try { + MTM_DECODE.invoke(decoder, ctx, msg, output); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return output; + } + /** * Check if a stack trace contains a certain exception * diff --git a/common/src/main/resources/assets/viaversion/config.yml b/common/src/main/resources/assets/viaversion/config.yml index 0252d7ffa..7675a477f 100644 --- a/common/src/main/resources/assets/viaversion/config.yml +++ b/common/src/main/resources/assets/viaversion/config.yml @@ -46,6 +46,28 @@ bungee-ping-save: true bungee-servers: {} # #----------------------------------------------------------# +# VELOCITY OPTIONS # +#----------------------------------------------------------# +# +# Velocity allows you to have different server versions inside. +# Instead of you entering all the versions of these servers, we can ping them. +# +# What interval would you like us to ping at? (in seconds) +# Use -1 to disable. +velocity-ping-interval: 60 +# If the above is enabled, should we save the info to the config (in the section below) +velocity-ping-save: true +# To get a servers protocol, ViaVersion will do the following: +# Look for the server in the following section, then look for the last ping if velocity-ping is enabled +# otherwise use default. +# +# The format for the following is: +# servername: protocolversion +# You can find protocol ids on http://wiki.vg/Protocol_version_numbers +# It will fallback to the default option if none found. +velocity-servers: {} +# +#----------------------------------------------------------# # GLOBAL PACKET LIMITER # #----------------------------------------------------------# # diff --git a/jar/pom.xml b/jar/pom.xml index a9399516f..95b282a0a 100644 --- a/jar/pom.xml +++ b/jar/pom.xml @@ -57,6 +57,10 @@ org.javassist us.myles.viaversion.libs.javassist + + org.yaml.snakeyaml + us.myles.viaversion.libs.snakeyaml + @@ -92,6 +96,11 @@ viaversion-sponge ${project.parent.version} + + us.myles + viaversion-velocity + ${project.parent.version} + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 00c615f8a..137071b6e 100644 --- a/pom.xml +++ b/pom.xml @@ -21,6 +21,7 @@ bungee sponge sponge-legacy + velocity jar diff --git a/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeConfigAPI.java b/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeConfigAPI.java index 86a98cef7..a216b0017 100644 --- a/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeConfigAPI.java +++ b/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeConfigAPI.java @@ -13,7 +13,7 @@ import java.util.Map; import java.util.Optional; public class SpongeConfigAPI extends Config implements ViaVersionConfig { - private static List UNSUPPORTED = Arrays.asList("anti-xray-patch", "bungee-ping-interval", "bungee-ping-save", "bungee-servers", "quick-move-action-fix"); + private static List UNSUPPORTED = Arrays.asList("anti-xray-patch", "bungee-ping-interval", "bungee-ping-save", "bungee-servers", "velocity-ping-interval", "velocity-ping-save", "velocity-servers", "quick-move-action-fix"); private final PluginContainer pluginContainer; public SpongeConfigAPI(PluginContainer pluginContainer, File configFile) { diff --git a/velocity/pom.xml b/velocity/pom.xml new file mode 100644 index 000000000..232fc97a4 --- /dev/null +++ b/velocity/pom.xml @@ -0,0 +1,62 @@ + + + + viaversion-parent + us.myles + 1.6.1-18w43c + + 4.0.0 + + viaversion-velocity + + + 1.8 + 1.8 + + + + + velocity + https://repo.velocitypowered.com/snapshots + + + + + + + org.codehaus.mojo + templating-maven-plugin + 1.0.0 + + + filter-src + + filter-sources + + + + + + + + + + + us.myles + viaversion-common + ${project.parent.version} + provided + + + + + com.velocitypowered + velocity-api + 1.0-SNAPSHOT + provided + + + + \ No newline at end of file diff --git a/velocity/src/main/java-templates/us/myles/ViaVersion/velocity/VersionInfo.java b/velocity/src/main/java-templates/us/myles/ViaVersion/velocity/VersionInfo.java new file mode 100644 index 000000000..4b189c863 --- /dev/null +++ b/velocity/src/main/java-templates/us/myles/ViaVersion/velocity/VersionInfo.java @@ -0,0 +1,5 @@ +package us.myles.ViaVersion.velocity; + +public class VersionInfo { + public static final String VERSION = "${project.version}"; +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java b/velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java new file mode 100644 index 000000000..d01d0e6c5 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java @@ -0,0 +1,203 @@ +package us.myles.ViaVersion; + +import com.google.gson.JsonObject; +import com.google.inject.Inject; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.connection.DisconnectEvent; +import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; +import com.velocitypowered.api.plugin.Plugin; +import com.velocitypowered.api.plugin.PluginContainer; +import com.velocitypowered.api.plugin.annotation.DataDirectory; +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.ProxyServer; +import lombok.Getter; +import net.kyori.text.serializer.ComponentSerializers; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.chat.ComponentSerializer; +import org.slf4j.Logger; +import us.myles.ViaVersion.api.Via; +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.dump.PluginInfo; +import us.myles.ViaVersion.util.GsonUtil; +import us.myles.ViaVersion.velocity.VersionInfo; +import us.myles.ViaVersion.velocity.command.VelocityCommandHandler; +import us.myles.ViaVersion.velocity.command.VelocityCommandSender; +import us.myles.ViaVersion.velocity.platform.*; +import us.myles.ViaVersion.velocity.service.ProtocolDetectorService; +import us.myles.ViaVersion.velocity.util.LoggerWrapper; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +@Plugin( + id = "viaversion", + name = "ViaVersion", + version = VersionInfo.VERSION, + authors = {"_MylesC", "Matsv"}, + description = "Allow newer Minecraft versions to connect to an older server version.", + url = "https://viaversion.com" +) +@Getter +public class VelocityPlugin implements ViaPlatform { + @Inject + private ProxyServer proxy; + @Inject + public static ProxyServer PROXY; + @Inject + private Logger loggerslf4j; + private java.util.logging.Logger logger; + @Inject + @DataDirectory + private Path configDir; + private VelocityViaAPI api = new VelocityViaAPI(); + private VelocityViaConfig conf; + + @Subscribe + public void onProxyInit(ProxyInitializeEvent e) { + PROXY = proxy; + VelocityCommandHandler commandHandler = new VelocityCommandHandler(); + PROXY.getCommandManager().register(commandHandler, "viaver", "vvvelocity", "viaversion"); + conf = new VelocityViaConfig(configDir.toFile()); + logger = new LoggerWrapper(loggerslf4j); + Via.init(ViaManager.builder() + .platform(this) + .commandHandler(commandHandler) + .loader(new VelocityViaLoader()) + .injector(new VelocityViaInjector()).build()); + Via.getManager().init(); + } + + @Subscribe + public void onQuit(DisconnectEvent e) { + UserConnection userConnection = Via.getManager().getPortedPlayers().get(e.getPlayer().getUniqueId()); + if (userConnection != null) { + // Only remove if the connection is disconnected (eg. relogin) + if (userConnection.getChannel() == null || !userConnection.getChannel().isOpen()) { + Via.getManager().removePortedClient(e.getPlayer().getUniqueId()); + } + } + } + + @Override + public String getPlatformName() { + return "Velocity"; + } + + @Override + public String getPlatformVersion() { + return ProxyServer.class.getPackage().getImplementationVersion(); + } + + @Override + public String getPluginVersion() { + return VersionInfo.VERSION; + } + + @Override + public TaskId runAsync(Runnable runnable) { + return runSync(runnable); + } + + @Override + public TaskId runSync(Runnable runnable) { + return runSync(runnable, 0L); + } + + @Override + public TaskId runSync(Runnable runnable, Long ticks) { + return new VelocityTaskId( + PROXY.getScheduler() + .buildTask(this, runnable) + .delay(ticks * 50, TimeUnit.MILLISECONDS).schedule() + ); + } + + @Override + public TaskId runRepeatingSync(Runnable runnable, Long ticks) { + return new VelocityTaskId( + PROXY.getScheduler() + .buildTask(this, runnable) + .repeat(ticks * 50, TimeUnit.MILLISECONDS).schedule() + ); + } + + @Override + public void cancelTask(TaskId taskId) { + if (taskId instanceof VelocityTaskId) { + ((VelocityTaskId) taskId).getObject().cancel(); + } + } + + @Override + public ViaCommandSender[] getOnlinePlayers() { + return PROXY.getAllPlayers().stream() + .map(VelocityCommandSender::new) + .toArray(ViaCommandSender[]::new); + } + + @Override + public void sendMessage(UUID uuid, String message) { + PROXY.getPlayer(uuid).ifPresent(it -> it.sendMessage( + ComponentSerializers.JSON.deserialize( + ComponentSerializer.toString(TextComponent.fromLegacyText(message)) // Fixes links + ) + )); + } + + @Override + public boolean kickPlayer(UUID uuid, String message) { + return PROXY.getPlayer(uuid).map(it -> { + it.disconnect( + ComponentSerializers.JSON.deserialize( + ComponentSerializer.toString(TextComponent.fromLegacyText(message)) // ComponentSerializers.LEGACY is deprecated + ) + ); + return true; + }).orElse(false); + } + + @Override + public boolean isPluginEnabled() { + return true; + } + + @Override + public ConfigurationProvider getConfigurationProvider() { + return conf; + } + + @Override + public void onReload() { + + } + + @Override + public JsonObject getDump() { + JsonObject extra = new JsonObject(); + List plugins = new ArrayList<>(); + for (PluginContainer p : PROXY.getPluginManager().getPlugins()) { + plugins.add(new PluginInfo( + true, + p.getDescription().getName().orElse(p.getDescription().getId()), + p.getDescription().getVersion().orElse("Unknown Version"), + p.getInstance().isPresent() ? p.getInstance().get().getClass().getCanonicalName() : "Unknown", + p.getDescription().getAuthors() + )); + } + extra.add("plugins", GsonUtil.getGson().toJsonTree(plugins)); + extra.add("servers", GsonUtil.getGson().toJsonTree(ProtocolDetectorService.getDetectedIds())); + return extra; + } + + @Override + public boolean isOldClientsAllowed() { + return true; + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/command/VelocityCommandHandler.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/command/VelocityCommandHandler.java new file mode 100644 index 000000000..9c23a01e5 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/command/VelocityCommandHandler.java @@ -0,0 +1,29 @@ +package us.myles.ViaVersion.velocity.command; + +import com.velocitypowered.api.command.Command; +import com.velocitypowered.api.command.CommandSource; +import org.checkerframework.checker.nullness.qual.NonNull; +import us.myles.ViaVersion.commands.ViaCommandHandler; +import us.myles.ViaVersion.velocity.command.subs.ProbeSubCmd; + +import java.util.List; + +public class VelocityCommandHandler extends ViaCommandHandler implements Command { + public VelocityCommandHandler() { + try { + registerSubCommand(new ProbeSubCmd()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void execute(@NonNull CommandSource source, String[] args) { + onCommand(new VelocityCommandSender(source), args); + } + + @Override + public List suggest(@NonNull CommandSource source, String[] currentArgs) { + return onTabComplete(new VelocityCommandSender(source), currentArgs); + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/command/VelocityCommandSender.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/command/VelocityCommandSender.java new file mode 100644 index 000000000..1a61f8b5c --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/command/VelocityCommandSender.java @@ -0,0 +1,46 @@ +package us.myles.ViaVersion.velocity.command; + +import com.velocitypowered.api.command.CommandSource; +import com.velocitypowered.api.proxy.Player; +import lombok.AllArgsConstructor; +import net.kyori.text.serializer.ComponentSerializers; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.chat.ComponentSerializer; +import us.myles.ViaVersion.api.command.ViaCommandSender; + +import java.util.UUID; + +@AllArgsConstructor +public class VelocityCommandSender implements ViaCommandSender { + private CommandSource source; + + @Override + public boolean hasPermission(String permission) { + return source.hasPermission(permission); + } + + @Override + public void sendMessage(String msg) { + source.sendMessage( + ComponentSerializers.JSON.deserialize( + ComponentSerializer.toString(TextComponent.fromLegacyText(msg)) // Fixes links + ) + ); + } + + @Override + public UUID getUUID() { + if (source instanceof Player) { + return ((Player) source).getUniqueId(); + } + return UUID.fromString(getName()); + } + + @Override + public String getName() { + if (source instanceof Player) { + return ((Player) source).getUsername(); + } + return "?"; // :( + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/command/subs/ProbeSubCmd.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/command/subs/ProbeSubCmd.java new file mode 100644 index 000000000..1470f49f1 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/command/subs/ProbeSubCmd.java @@ -0,0 +1,28 @@ +package us.myles.ViaVersion.velocity.command.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.velocity.platform.VelocityViaConfig; +import us.myles.ViaVersion.velocity.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 " + + (((VelocityViaConfig) Via.getConfig()).getVelocityPingInterval() == -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/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityChannelInitializer.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityChannelInitializer.java new file mode 100644 index 000000000..306bcf667 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityChannelInitializer.java @@ -0,0 +1,38 @@ +package us.myles.ViaVersion.velocity.handlers; + +import io.netty.channel.Channel; +import io.netty.channel.ChannelInitializer; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.protocol.ProtocolPipeline; + +import java.lang.reflect.Method; + +@RequiredArgsConstructor +public class VelocityChannelInitializer extends ChannelInitializer { + @NonNull + private ChannelInitializer original; + private Method initChannel; + + { + try { + initChannel = ChannelInitializer.class.getDeclaredMethod("initChannel", Channel.class); + initChannel.setAccessible(true); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + } + + @Override + protected void initChannel(Channel channel) throws Exception { + initChannel.invoke(original, channel); + + UserConnection user = new UserConnection(channel); + new ProtocolPipeline(user); + + // We need to add a separated handler because Velocity uses pipeline().get(MINECRAFT_DECODER) + channel.pipeline().addBefore("minecraft-encoder", "via-encoder", new VelocityEncodeHandler(user)); + channel.pipeline().addBefore("minecraft-decoder", "via-decoder", new VelocityDecodeHandler(user)); + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityDecodeHandler.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityDecodeHandler.java new file mode 100644 index 000000000..23dbd77fd --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityDecodeHandler.java @@ -0,0 +1,78 @@ +package us.myles.ViaVersion.velocity.handlers; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToMessageDecoder; +import lombok.AllArgsConstructor; +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 +@AllArgsConstructor +public class VelocityDecodeHandler extends MessageToMessageDecoder { + private final UserConnection info; + + @Override + protected void decode(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; + } + info.getVelocityLock().readLock().lock(); + 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(); + info.getVelocityLock().readLock().unlock(); + throw e; + } + } else { + bytebuf.retain(); + } + info.getVelocityLock().readLock().unlock(); + + 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/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityEncodeHandler.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityEncodeHandler.java new file mode 100644 index 000000000..1a929c2e8 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityEncodeHandler.java @@ -0,0 +1,90 @@ +package us.myles.ViaVersion.velocity.handlers; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; +import io.netty.handler.codec.MessageToMessageDecoder; +import io.netty.handler.codec.MessageToMessageEncoder; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +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 +@RequiredArgsConstructor +public class VelocityEncodeHandler extends MessageToMessageEncoder { + @NonNull + private final UserConnection info; + private boolean handledCompression = false; + + @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 + && ctx.pipeline().names().indexOf("compression-encoder") > ctx.pipeline().names().indexOf("via-encoder")) { + // Need to decompress this packet due to bad order + bytebuf = (ByteBuf) PipelineUtil.callDecode((MessageToMessageDecoder) ctx.pipeline().get("compression-decoder"), ctx, bytebuf).get(0); + ChannelHandler encoder = ctx.pipeline().get("via-encoder"); + ChannelHandler decoder = ctx.pipeline().get("via-decoder"); + ctx.pipeline().remove(encoder); + ctx.pipeline().remove(decoder); + ctx.pipeline().addAfter("compression-encoder", "via-encoder", encoder); + ctx.pipeline().addAfter("compression-decoder", "via-decoder", decoder); + needsCompress = true; + handledCompression = true; + } else { + bytebuf.retain(); + } + // Increment sent + info.incrementSent(); + + + if (info.isActive()) { + // Handle ID + int id = Type.VAR_INT.read(bytebuf); + // Transform + ByteBuf newPacket = bytebuf.alloc().buffer(); + try { + PacketWrapper wrapper = new PacketWrapper(id, bytebuf, info); + ProtocolInfo protInfo = info.get(ProtocolInfo.class); + protInfo.getPipeline().transform(Direction.OUTGOING, protInfo.getState(), wrapper); + + wrapper.writeToBuffer(newPacket); + + bytebuf.clear(); + bytebuf.release(); + bytebuf = newPacket; + } catch (Exception e) { + bytebuf.clear(); + bytebuf.release(); + newPacket.release(); + throw e; + } + } + + if (needsCompress) { + ByteBuf old = bytebuf; + bytebuf = ctx.alloc().buffer(); + PipelineUtil.callEncode((MessageToByteEncoder) ctx.pipeline().get("compression-encoder"), ctx, old, bytebuf); + old.release(); + } + 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/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityServerHandler.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityServerHandler.java new file mode 100644 index 000000000..51bb600d1 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/handlers/VelocityServerHandler.java @@ -0,0 +1,138 @@ +package us.myles.ViaVersion.velocity.handlers; + +import com.velocitypowered.api.event.PostOrder; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.player.ServerConnectedEvent; +import com.velocitypowered.api.event.player.ServerPreConnectEvent; +import us.myles.ViaVersion.api.Pair; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.boss.BossBar; +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.protocols.base.ProtocolInfo; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker; +import us.myles.ViaVersion.util.ReflectionUtil; +import us.myles.ViaVersion.velocity.service.ProtocolDetectorService; +import us.myles.ViaVersion.velocity.storage.VelocityStorage; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.List; +import java.util.concurrent.Semaphore; + +public class VelocityServerHandler { + private static Method setProtocolVersion; + private static Method setNextProtocolVersion; + + static { + try { + setProtocolVersion = Class.forName("com.velocitypowered.proxy.connection.MinecraftConnection").getDeclaredMethod("setProtocolVersion", int.class); + setNextProtocolVersion = Class.forName("com.velocitypowered.proxy.connection.MinecraftConnection").getDeclaredMethod("setNextProtocolVersion", int.class); + } catch (NoSuchMethodException | ClassNotFoundException e) { + e.printStackTrace(); + } + } + + @Subscribe + public void preServerConnect(ServerPreConnectEvent e) { + try { + UserConnection user = Via.getManager().getConnection(e.getPlayer().getUniqueId()); + if (user == null) return; + if (!user.has(VelocityStorage.class)) { + user.put(new VelocityStorage(user, e.getPlayer())); + } + + int protocolId = ProtocolDetectorService.getProtocolId(e.getOriginalServer().getServerInfo().getName()); + List> protocols = ProtocolRegistry.getProtocolPath(user.get(ProtocolInfo.class).getProtocolVersion(), protocolId); + + // Check if ViaVersion can support that version + Object connection = ReflectionUtil.invoke(e.getPlayer(), "getConnection"); + setNextProtocolVersion.invoke(connection, protocols == null ? user.get(ProtocolInfo.class).getProtocolVersion() : protocolId); + + } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e1) { + e1.printStackTrace(); + } + } + + @Subscribe(order = PostOrder.LATE) + public void connectedEvent(ServerConnectedEvent e) { + UserConnection user = Via.getManager().getConnection(e.getPlayer().getUniqueId()); + try { + checkServerChange(e, Via.getManager().getConnection(e.getPlayer().getUniqueId())); + } catch (Exception e1) { + e1.printStackTrace(); + } + } + + public void checkServerChange(ServerConnectedEvent e, UserConnection user) throws Exception { + if (user == null) return; + // Manually hide ViaVersion-created BossBars if the childserver was version 1.8.x (#666) + if (user.has(EntityTracker.class)) { + EntityTracker tracker = user.get(EntityTracker.class); + + if (tracker.getBossBarMap() != null) + for (BossBar bar : tracker.getBossBarMap().values()) + bar.hide(); + } + // Handle server/version change + if (user.has(VelocityStorage.class)) { + // Wait all the scheduled packets be sent + Semaphore semaphore = new Semaphore(1); + semaphore.acquireUninterruptibly(); + user.getChannel().eventLoop().submit((Runnable) semaphore::release); + semaphore.acquireUninterruptibly(); + semaphore.release(); + + user.getVelocityLock().writeLock().lock(); + + VelocityStorage storage = user.get(VelocityStorage.class); + + if (e.getServer() != null) { + if (!e.getServer().getServerInfo().getName().equals(storage.getCurrentServer())) { + String serverName = e.getServer().getServerInfo().getName(); + + storage.setCurrentServer(serverName); + + int protocolId = ProtocolDetectorService.getProtocolId(serverName); + + ProtocolInfo info = user.get(ProtocolInfo.class); + + // Refresh the pipes + List> protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), protocolId); + ProtocolPipeline pipeline = user.get(ProtocolInfo.class).getPipeline(); + user.clearStoredObjects(); + pipeline.cleanPipes(); + if (protocols == null) { + // TODO Check Bungee Supported Protocols? *shrugs* + protocolId = info.getProtocolVersion(); + } else { + for (Pair prot : protocols) { + pipeline.add(prot.getValue()); + } + } + + info.setServerProtocolVersion(protocolId); + // Add version-specific base Protocol + pipeline.add(ProtocolRegistry.getBaseProtocol(protocolId)); + + user.put(info); + user.put(storage); + + user.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(user); + } + + Object connection = ReflectionUtil.invoke(e.getPlayer(), "getConnection"); + int version = (int) ReflectionUtil.invoke(connection,"getNextProtocolVersion"); + setProtocolVersion.invoke(ReflectionUtil.invoke(e.getPlayer(), "getConnection"), version); + } + } + user.getVelocityLock().writeLock().unlock(); + } + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/ElytraPatch.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/ElytraPatch.java new file mode 100644 index 000000000..9e9a93ba0 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/ElytraPatch.java @@ -0,0 +1,44 @@ +package us.myles.ViaVersion.velocity.listeners; + +import com.velocitypowered.api.event.PostOrder; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.player.ServerConnectedEvent; +import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.data.UserConnection; +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.storage.EntityTracker; + +import java.util.Collections; + +/* + * This patches https://github.com/MylesIsCool/ViaVersion/issues/555 + */ +public class ElytraPatch { + + @Subscribe(order = PostOrder.LAST) + public void onServerConnected(ServerConnectedEvent event) { + UserConnection user = Via.getManager().getConnection(event.getPlayer().getUniqueId()); + if (user == null) return; + + try { + if (user.get(ProtocolInfo.class).getPipeline().contains(Protocol1_9TO1_8.class)) { + int entityId = user.get(EntityTracker.class).getProvidedEntityId(); + + PacketWrapper wrapper = new PacketWrapper(0x39, null, user); + + wrapper.write(Type.VAR_INT, entityId); + wrapper.write(Types1_9.METADATA_LIST, Collections.singletonList(new Metadata(0, MetaType1_9.Byte, (byte) 0))); + + wrapper.send(Protocol1_9TO1_8.class); + } + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/MainHandPatch.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/MainHandPatch.java new file mode 100644 index 000000000..eae7f08c3 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/MainHandPatch.java @@ -0,0 +1,49 @@ +package us.myles.ViaVersion.velocity.listeners; + +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.player.ServerConnectedEvent; +import com.velocitypowered.api.proxy.player.PlayerSettings; +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.Protocol1_9TO1_8; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker; +import us.myles.ViaVersion.util.ReflectionUtil; + +import java.lang.reflect.Method; + +/* + This solves the wrong mainhand issue when you join with BungeeCord on a 1.8 server, and switch to a 1.9 or higher. + */ +public class MainHandPatch { + private static Method setSettings; + + static { + try { + Class clientSettings = Class.forName("com.velocitypowered.proxy.protocol.packet.ClientSettings"); + setSettings = Class.forName("com.velocitypowered.proxy.connection.client.ConnectedPlayer").getDeclaredMethod("setPlayerSettings", clientSettings); + setSettings.setAccessible(true); + } catch (ClassNotFoundException | NoSuchMethodException e) { + e.printStackTrace(); + } + } + + @Subscribe + public void onServerConnect(ServerConnectedEvent event) { + UserConnection user = Via.getManager().getConnection(event.getPlayer().getUniqueId()); + if (user == null || setSettings == null) return; + + try { + if (user.get(ProtocolInfo.class).getPipeline().contains(Protocol1_9TO1_8.class)) { + PlayerSettings settings = event.getPlayer().getPlayerSettings(); + if (user.has(EntityTracker.class)) { + Object clientSettings = ReflectionUtil.get(settings, "settings", Object.class); + ReflectionUtil.set(clientSettings, "mainHand", user.get(EntityTracker.class).getMainHand()); + setSettings.invoke(event.getPlayer(), clientSettings); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/UpdateListener.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/UpdateListener.java new file mode 100644 index 000000000..d12069810 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/listeners/UpdateListener.java @@ -0,0 +1,16 @@ +package us.myles.ViaVersion.velocity.listeners; + +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.connection.PostLoginEvent; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.update.UpdateUtil; + +public class UpdateListener { + @Subscribe + public void onJoin(PostLoginEvent e) { + if (e.getPlayer().hasPermission("viaversion.update") + && Via.getConfig().isCheckForUpdates()) { + UpdateUtil.sendUpdateMessage(e.getPlayer().getUniqueId()); + } + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityBossBar.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityBossBar.java new file mode 100644 index 000000000..46a767c6a --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityBossBar.java @@ -0,0 +1,13 @@ +package us.myles.ViaVersion.velocity.platform; + +import com.velocitypowered.api.proxy.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.boss.CommonBoss; + +public class VelocityBossBar extends CommonBoss { + public VelocityBossBar(String title, float health, BossColor color, BossStyle style) { + super(title, health, color, style); + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityTaskId.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityTaskId.java new file mode 100644 index 000000000..9d7edbb56 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityTaskId.java @@ -0,0 +1,12 @@ +package us.myles.ViaVersion.velocity.platform; + +import com.velocitypowered.api.scheduler.ScheduledTask; +import lombok.AllArgsConstructor; +import lombok.Getter; +import us.myles.ViaVersion.api.platform.TaskId; + +@Getter +@AllArgsConstructor +public class VelocityTaskId implements TaskId { + private ScheduledTask object; +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaAPI.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaAPI.java new file mode 100644 index 000000000..aca7fe39a --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaAPI.java @@ -0,0 +1,78 @@ +package us.myles.ViaVersion.velocity.platform; + +import com.velocitypowered.api.proxy.Player; +import io.netty.buffer.ByteBuf; +import lombok.NonNull; +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 VelocityViaAPI implements ViaAPI { + @Override + public int getPlayerVersion(@NonNull Player 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(Player player, ByteBuf packet) throws IllegalArgumentException { + sendRawPacket(player.getUniqueId(), packet); + } + + @Override + public BossBar createBossBar(String title, BossColor color, BossStyle style) { + return new VelocityBossBar(title, 1F, color, style); + } + + @Override + public BossBar createBossBar(String title, float health, BossColor color, BossStyle style) { + return new VelocityBossBar(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/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java new file mode 100644 index 000000000..373bd5c61 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java @@ -0,0 +1,275 @@ +package us.myles.ViaVersion.velocity.platform; + +import us.myles.ViaVersion.api.ViaVersionConfig; +import us.myles.ViaVersion.api.protocol.ProtocolRegistry; +import us.myles.ViaVersion.api.protocol.ProtocolVersion; +import us.myles.ViaVersion.util.Config; + +import java.io.File; +import java.net.URL; +import java.util.*; + +public class VelocityViaConfig extends Config implements ViaVersionConfig { + private static List UNSUPPORTED = Arrays.asList("nms-player-ticking", "item-cache", "anti-xray-patch", "quick-move-action-fix", "bungee-ping-interval", "bungee-ping-save", "bungee-servers"); + + public VelocityViaConfig(File configFile) { + super(new File(configFile, "config.yml")); + // Load config + reloadConfig(); + } + + @Override + public URL getDefaultConfigURL() { + return getClass().getClassLoader().getResource("assets/viaversion/config.yml"); + } + + @Override + protected void handleConfig(Map config) { + // Parse servers + Map servers; + if (!(config.get("velocity-servers") instanceof Map)) { + servers = new HashMap<>(); + } else { + servers = (Map) config.get("velocity-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", ProtocolRegistry.SERVER_PROTOCOL); + } + // Put back + config.put("velocity-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 isPistonAnimationPatch() { + return getBoolean("piston-animation-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 boolean is1_12NBTArrayFix() { + return getBoolean("chat-nbt-fix", true); + } + + @Override + public boolean is1_12QuickMoveActionFix() { + return 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 + public boolean isMinimizeCooldown() { + return getBoolean("minimize-cooldown", true); + } + + /** + * What is the interval for checking servers via ping + * -1 for disabled + * + * @return Ping interval in seconds + */ + public int getVelocityPingInterval() { + return getInt("velocity-ping-interval", 60); + } + + /** + * Should the velocity ping be saved to the config on change. + * + * @return True if it should save + */ + public boolean isVelocityPingSave() { + return getBoolean("velocity-ping-save", true); + } + + /** + * Get the listed server protocols in the config. + * default will be listed as default. + * + * @return Map of String, Integer + */ + public Map getVelocityServerProtocols() { + return get("velocity-servers", Map.class, new HashMap<>()); + } + + @Override + public boolean is1_13TeamColourFix() { + return getBoolean("team-colour-fix", true); + } + + @Override + public boolean isSuppress1_13ConversionErrors() { + return getBoolean("suppress-1_13-conversion-errors", false); + } + + @Override + public boolean isDisable1_13AutoComplete() { + return getBoolean("disable-1_13-auto-complete", false); + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaInjector.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaInjector.java new file mode 100644 index 000000000..78e5a532b --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaInjector.java @@ -0,0 +1,41 @@ +package us.myles.ViaVersion.velocity.platform; + +import io.netty.channel.ChannelInitializer; +import us.myles.ViaVersion.VelocityPlugin; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.platform.ViaInjector; +import us.myles.ViaVersion.util.ReflectionUtil; +import us.myles.ViaVersion.velocity.handlers.VelocityChannelInitializer; + + +public class VelocityViaInjector implements ViaInjector { + @Override + public void inject() throws Exception { + Object connectionManager = ReflectionUtil.get(VelocityPlugin.PROXY, "cm", Object.class); + Object channelInitializerHolder = ReflectionUtil.invoke(connectionManager, "getServerChannelInitializer"); + ChannelInitializer originalIntializer = (ChannelInitializer) ReflectionUtil.invoke(channelInitializerHolder, "get"); + channelInitializerHolder.getClass().getMethod("set", ChannelInitializer.class) + .invoke(channelInitializerHolder, new VelocityChannelInitializer(originalIntializer)); + } + + @Override + public void uninject() { + Via.getPlatform().getLogger().severe("ViaVersion cannot remove itself from Velocity without a reboot!"); + } + + + @Override + public int getServerProtocolVersion() throws Exception { + return ReflectionUtil.getStatic(Class.forName("com.velocitypowered.proxy.protocol.ProtocolConstants"), "MINIMUM_GENERIC_VERSION", int.class); + } + + @Override + public String getEncoderName() { + return "via-encoder"; + } + + @Override + public String getDecoderName() { + return "via-decoder"; + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaLoader.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaLoader.java new file mode 100644 index 000000000..ff2ff10f1 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaLoader.java @@ -0,0 +1,45 @@ +package us.myles.ViaVersion.velocity.platform; + +import com.velocitypowered.api.plugin.PluginContainer; +import us.myles.ViaVersion.VelocityPlugin; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.platform.ViaPlatformLoader; +import us.myles.ViaVersion.protocols.base.VersionProvider; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BossBarProvider; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider; +import us.myles.ViaVersion.velocity.handlers.VelocityServerHandler; +import us.myles.ViaVersion.velocity.listeners.ElytraPatch; +import us.myles.ViaVersion.velocity.listeners.MainHandPatch; +import us.myles.ViaVersion.velocity.listeners.UpdateListener; +import us.myles.ViaVersion.velocity.providers.VelocityBossBarProvider; +import us.myles.ViaVersion.velocity.providers.VelocityMovementTransmitter; +import us.myles.ViaVersion.velocity.providers.VelocityVersionProvider; +import us.myles.ViaVersion.velocity.service.ProtocolDetectorService; + +public class VelocityViaLoader implements ViaPlatformLoader { + @Override + public void load() { + Object plugin = VelocityPlugin.PROXY.getPluginManager() + .getPlugin("viaversion").flatMap(PluginContainer::getInstance).get(); + + Via.getManager().getProviders().use(MovementTransmitterProvider.class, new VelocityMovementTransmitter()); + Via.getManager().getProviders().use(BossBarProvider.class, new VelocityBossBarProvider()); + Via.getManager().getProviders().use(VersionProvider.class, new VelocityVersionProvider()); + // We probably don't need a EntityIdProvider because velocity sends a Join packet on server change + + VelocityPlugin.PROXY.getEventManager().register( + plugin, + new UpdateListener()); + Via.getPlatform().runRepeatingSync( + new ProtocolDetectorService(), + ((VelocityViaConfig) Via.getPlatform().getConf()).getVelocityPingInterval() * 50L); + VelocityPlugin.PROXY.getEventManager().register(plugin, new VelocityServerHandler()); + VelocityPlugin.PROXY.getEventManager().register(plugin, new MainHandPatch()); + VelocityPlugin.PROXY.getEventManager().register(plugin, new ElytraPatch()); + } + + @Override + public void unload() { + // Probably not useful, there's no ProxyReloadEvent + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityBossBarProvider.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityBossBarProvider.java new file mode 100644 index 000000000..276d4b931 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityBossBarProvider.java @@ -0,0 +1,30 @@ +package us.myles.ViaVersion.velocity.providers; + +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BossBarProvider; +import us.myles.ViaVersion.velocity.storage.VelocityStorage; + +import java.util.UUID; + +public class VelocityBossBarProvider extends BossBarProvider { + @Override + public void handleAdd(UserConnection user, UUID barUUID) { + if (user.has(VelocityStorage.class)) { + VelocityStorage storage = user.get(VelocityStorage.class); + // Check if bossbars are supported by bungee, static maybe + if (storage.getBossbar() != null) { + storage.getBossbar().add(barUUID); + } + } + } + + @Override + public void handleRemove(UserConnection user, UUID barUUID) { + if (user.has(VelocityStorage.class)) { + VelocityStorage storage = user.get(VelocityStorage.class); + if (storage.getBossbar() != null) { + storage.getBossbar().remove(barUUID); + } + } + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityMovementTransmitter.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityMovementTransmitter.java new file mode 100644 index 000000000..473633790 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityMovementTransmitter.java @@ -0,0 +1,35 @@ +package us.myles.ViaVersion.velocity.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.Protocol1_9TO1_8; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.MovementTracker; + +public class VelocityMovementTransmitter 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(Protocol1_9TO1_8.class); + } catch (Exception e) { + e.printStackTrace(); + } + // PlayerPackets will increment idle + } + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityVersionProvider.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityVersionProvider.java new file mode 100644 index 000000000..30fd4add9 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/providers/VelocityVersionProvider.java @@ -0,0 +1,73 @@ +package us.myles.ViaVersion.velocity.providers; + +import com.google.common.collect.Lists; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.protocol.ProtocolVersion; +import us.myles.ViaVersion.protocols.base.ProtocolInfo; +import us.myles.ViaVersion.protocols.base.VersionProvider; +import us.myles.ViaVersion.util.ReflectionUtil; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class VelocityVersionProvider extends VersionProvider { + private static Class ref ; + + static { + try { + ref = Class.forName("com.velocitypowered.proxy.protocol.ProtocolConstants"); + } catch (Exception e) { + Via.getPlatform().getLogger().severe("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) + Object list = ReflectionUtil.getStatic(ref, "SUPPORTED_VERSIONS", Object.class); + List sorted = new ArrayList((List) ReflectionUtil.invoke(list, "asList")); + Collections.sort(sorted); + + ProtocolInfo info = user.get(ProtocolInfo.class); + + // Bungee supports it + if (sorted.contains(info.getProtocolVersion())) + return info.getProtocolVersion(); + + // Older than bungee supports, get the lowest version + if (info.getProtocolVersion() < sorted.get(0)) { + return getLowestSupportedVersion(); + } + + // Loop through all protocols to get the closest protocol id that bungee supports (and that viaversion does too) + + // TODO: This needs a better fix, i.e checking ProtocolRegistry to see if it would work. + // This is more of a workaround for snapshot support by bungee. + for (Integer protocol : Lists.reverse(sorted)) { + if (info.getProtocolVersion() > protocol && ProtocolVersion.isRegistered(protocol)) + return protocol; + } + + Via.getPlatform().getLogger().severe("Panic, no protocol id found for " + info.getProtocolVersion()); + return info.getProtocolVersion(); + } + + public static int getLowestSupportedVersion() { + List list; + try { + return ReflectionUtil.getStatic( + Class.forName("com.velocitypowered.proxy.protocol.ProtocolConstants"), + "MINIMUM_GENERIC_VERSION", + int.class); + } catch (NoSuchFieldException | IllegalAccessException | ClassNotFoundException e) { + e.printStackTrace(); + } + // Fallback + return -1; + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/service/ProtocolDetectorService.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/service/ProtocolDetectorService.java new file mode 100644 index 000000000..8abe51927 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/service/ProtocolDetectorService.java @@ -0,0 +1,82 @@ +package us.myles.ViaVersion.velocity.service; + +import com.velocitypowered.api.proxy.server.RegisteredServer; +import lombok.Getter; +import us.myles.ViaVersion.VelocityPlugin; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.protocol.ProtocolVersion; +import us.myles.ViaVersion.velocity.platform.VelocityViaConfig; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class ProtocolDetectorService implements Runnable { + private static final Map detectedProtocolIds = new ConcurrentHashMap<>(); + @Getter + private static ProtocolDetectorService instance; + + public ProtocolDetectorService() { + instance = this; + } + + public static Integer getProtocolId(String serverName) { + // Step 1. Check Config + Map servers = ((VelocityViaConfig) Via.getConfig()).getVelocityServerProtocols(); + Integer protocol = servers.get(serverName); + if (protocol != null) { + return protocol; + } + // Step 2. Check Detected + Integer detectedProtocol = detectedProtocolIds.get(serverName); + if (detectedProtocol != null) { + return detectedProtocol; + } + // Step 3. Use Default + Integer defaultProtocol = servers.get("default"); + if (defaultProtocol != null) { + return defaultProtocol; + } + // Step 4: Use bungee lowest supported... *cries* + try { + return Via.getManager().getInjector().getServerProtocolVersion(); + } catch (Exception e) { + e.printStackTrace(); + return ProtocolVersion.v1_8.getId(); + } + } + + @Override + public void run() { + for (final RegisteredServer serv : VelocityPlugin.PROXY.getAllServers()) { + probeServer(serv); + } + } + + public static void probeServer(final RegisteredServer serverInfo) { + final String key = serverInfo.getServerInfo().getName(); + serverInfo.ping().thenAccept((serverPing) -> { + if (serverPing != null && serverPing.getVersion() != null) { + detectedProtocolIds.put(key, serverPing.getVersion().getProtocol()); + if (((VelocityViaConfig) Via.getConfig()).isVelocityPingSave()) { + Map servers = ((VelocityViaConfig) Via.getConfig()).getVelocityServerProtocols(); + Integer protocol = servers.get(key); + if (protocol != null && protocol == serverPing.getVersion().getProtocol()) { + return; + } + // Ensure we're the only ones writing to the config + synchronized (Via.getPlatform().getConfigurationProvider()) { + servers.put(key, serverPing.getVersion().getProtocol()); + } + // Save + Via.getPlatform().getConfigurationProvider().saveConfig(); + } + } + }); + } + + public static Map getDetectedIds() { + return new HashMap<>(detectedProtocolIds); + } + +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/storage/VelocityStorage.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/storage/VelocityStorage.java new file mode 100644 index 000000000..353430070 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/storage/VelocityStorage.java @@ -0,0 +1,38 @@ +package us.myles.ViaVersion.velocity.storage; + +import com.velocitypowered.api.proxy.Player; +import lombok.Data; +import lombok.EqualsAndHashCode; +import us.myles.ViaVersion.api.data.StoredObject; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.util.ReflectionUtil; + +import java.lang.reflect.InvocationTargetException; +import java.util.Set; +import java.util.UUID; + +@Data +@EqualsAndHashCode(callSuper = true) +public class VelocityStorage extends StoredObject { + private Player player; + private String currentServer; + private Set bossbar; + + public VelocityStorage(UserConnection user, Player player) { + super(user); + this.player = player; + this.currentServer = ""; + + // Get bossbar list if it's supported + try { + Object connection = ReflectionUtil.invoke(player, "getConnection"); + Object sessionHandler = ReflectionUtil.invoke(connection, "getSessionHandler"); + if (sessionHandler.getClass().getSimpleName().contains("Play")) { + bossbar = (Set) ReflectionUtil.invoke(sessionHandler, "getServerBossBars"); + // TODO make this work + } + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { + e.printStackTrace(); + } + } +} diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/util/LoggerWrapper.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/util/LoggerWrapper.java new file mode 100644 index 000000000..60300e8c7 --- /dev/null +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/util/LoggerWrapper.java @@ -0,0 +1,69 @@ +package us.myles.ViaVersion.velocity.util; + +import org.slf4j.Logger; + +import java.text.MessageFormat; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +public class LoggerWrapper extends java.util.logging.Logger { + private final Logger base; + + public LoggerWrapper(Logger logger) { + super("logger", null); + this.base = logger; + } + + @Override + public void log(LogRecord record) { + log(record.getLevel(), record.getMessage()); + } + + @Override + public void log(Level level, String msg) { + if (level == Level.FINE) + base.debug(msg); + else if (level == Level.WARNING) + base.warn(msg); + else if (level == Level.SEVERE) + base.error(msg); + else if (level == Level.INFO) + base.info(msg); + else + base.trace(msg); + } + + @Override + public void log(Level level, String msg, Object param1) { + if (level == Level.FINE) + base.debug(msg, param1); + else if (level == Level.WARNING) + base.warn(msg, param1); + else if (level == Level.SEVERE) + base.error(msg, param1); + else if (level == Level.INFO) + base.info(msg, param1); + else + base.trace(msg, param1); + } + + @Override + public void log(Level level, String msg, Object[] params) { + log(level, MessageFormat.format(msg, params)); // workaround not formatting correctly + } + + @Override + public void log(Level level, String msg, Throwable params) { + if (level == Level.FINE) + base.debug(msg, params); + else if (level == Level.WARNING) + base.warn(msg, params); + else if (level == Level.SEVERE) + base.error(msg, params); + else if (level == Level.INFO) + base.info(msg, params); + else + base.trace(msg, params); + } + +} From 3ef1ac06df52a9c19e081fab5ffdbe898d6657bf Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Mon, 12 Nov 2018 14:21:48 -0200 Subject: [PATCH 2/5] fix version, detect velocity implementation, fix npe, fix detectorservice --- velocity/pom.xml | 2 +- .../java/us/myles/ViaVersion/VelocityPlugin.java | 6 ++++-- .../velocity/platform/VelocityViaLoader.java | 14 ++++++++------ 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/velocity/pom.xml b/velocity/pom.xml index 232fc97a4..50d9a28d5 100644 --- a/velocity/pom.xml +++ b/velocity/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 1.6.1-18w43c + 1.6.1-SNAPSHOT 4.0.0 diff --git a/velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java b/velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java index d01d0e6c5..f16cad720 100644 --- a/velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java +++ b/velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java @@ -87,12 +87,14 @@ public class VelocityPlugin implements ViaPlatform { @Override public String getPlatformName() { - return "Velocity"; + String proxyImpl = ProxyServer.class.getPackage().getImplementationTitle(); + return (proxyImpl != null) ? proxyImpl : "Velocity"; } @Override public String getPlatformVersion() { - return ProxyServer.class.getPackage().getImplementationVersion(); + String version = ProxyServer.class.getPackage().getImplementationVersion(); + return (version != null) ? version : "Unknown"; } @Override diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaLoader.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaLoader.java index ff2ff10f1..f81447437 100644 --- a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaLoader.java +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaLoader.java @@ -27,15 +27,17 @@ public class VelocityViaLoader implements ViaPlatformLoader { Via.getManager().getProviders().use(VersionProvider.class, new VelocityVersionProvider()); // We probably don't need a EntityIdProvider because velocity sends a Join packet on server change - VelocityPlugin.PROXY.getEventManager().register( - plugin, - new UpdateListener()); - Via.getPlatform().runRepeatingSync( - new ProtocolDetectorService(), - ((VelocityViaConfig) Via.getPlatform().getConf()).getVelocityPingInterval() * 50L); + VelocityPlugin.PROXY.getEventManager().register(plugin, new UpdateListener()); VelocityPlugin.PROXY.getEventManager().register(plugin, new VelocityServerHandler()); VelocityPlugin.PROXY.getEventManager().register(plugin, new MainHandPatch()); VelocityPlugin.PROXY.getEventManager().register(plugin, new ElytraPatch()); + + int pingInterval = ((VelocityViaConfig) Via.getPlatform().getConf()).getVelocityPingInterval(); + if (pingInterval > 0) { + Via.getPlatform().runRepeatingSync( + new ProtocolDetectorService(), + pingInterval * 20L); + } } @Override From d0300de136e747520dccf6f3485448b34bdd21cf Mon Sep 17 00:00:00 2001 From: Myles Date: Sat, 17 Nov 2018 13:08:51 +0000 Subject: [PATCH 3/5] Prevent initialization error --- .../main/java/us/myles/ViaVersion/VelocityPlugin.java | 3 ++- .../ViaVersion/velocity/platform/VelocityViaConfig.java | 9 +++++++-- .../velocity/platform/VelocityViaInjector.java | 4 ++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java b/velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java index f16cad720..94b131740 100644 --- a/velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java +++ b/velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java @@ -56,7 +56,7 @@ public class VelocityPlugin implements ViaPlatform { @Inject @DataDirectory private Path configDir; - private VelocityViaAPI api = new VelocityViaAPI(); + private VelocityViaAPI api; private VelocityViaConfig conf; @Subscribe @@ -64,6 +64,7 @@ public class VelocityPlugin implements ViaPlatform { PROXY = proxy; VelocityCommandHandler commandHandler = new VelocityCommandHandler(); PROXY.getCommandManager().register(commandHandler, "viaver", "vvvelocity", "viaversion"); + api = new VelocityViaAPI(); conf = new VelocityViaConfig(configDir.toFile()); logger = new LoggerWrapper(loggerslf4j); Via.init(ViaManager.builder() diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java index 373bd5c61..9d8da33f0 100644 --- a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java @@ -1,7 +1,6 @@ package us.myles.ViaVersion.velocity.platform; import us.myles.ViaVersion.api.ViaVersionConfig; -import us.myles.ViaVersion.api.protocol.ProtocolRegistry; import us.myles.ViaVersion.api.protocol.ProtocolVersion; import us.myles.ViaVersion.util.Config; @@ -49,7 +48,13 @@ public class VelocityViaConfig extends Config implements ViaVersionConfig { } // Ensure default exists if (!servers.containsKey("default")) { - servers.put("default", ProtocolRegistry.SERVER_PROTOCOL); + // Side note: This doesn't use ProtocolRegistry as it doesn't know the protocol version at boot. + try { + servers.put("default", VelocityViaInjector.getLowestSupportedProtocolVersion()); + } catch (Exception e) { + // Something went very wrong + e.printStackTrace(); + } } // Put back config.put("velocity-servers", servers); diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaInjector.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaInjector.java index 78e5a532b..4673d23c4 100644 --- a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaInjector.java +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaInjector.java @@ -26,6 +26,10 @@ public class VelocityViaInjector implements ViaInjector { @Override public int getServerProtocolVersion() throws Exception { + return getLowestSupportedProtocolVersion(); + } + + public static int getLowestSupportedProtocolVersion() throws Exception { return ReflectionUtil.getStatic(Class.forName("com.velocitypowered.proxy.protocol.ProtocolConstants"), "MINIMUM_GENERIC_VERSION", int.class); } From 8549c2256789af44ae2cfd7edc28d6b1b26da21a Mon Sep 17 00:00:00 2001 From: Myles Date: Sat, 17 Nov 2018 13:12:19 +0000 Subject: [PATCH 4/5] Change the name of the config class to be more consistent --- .../main/java/us/myles/ViaVersion/ViaVersionPlugin.java | 4 ++-- .../{BukkitConfigAPI.java => BukkitViaConfig.java} | 6 +++--- .../src/main/java/us/myles/ViaVersion/BungeePlugin.java | 6 +++--- .../ViaVersion/bungee/commands/subs/ProbeSubCmd.java | 4 ++-- .../{BungeeConfigAPI.java => BungeeViaConfig.java} | 6 +++--- .../bungee/service/ProtocolDetectorService.java | 8 ++++---- .../src/main/java/us/myles/ViaVersion/SpongePlugin.java | 7 ++----- .../{SpongeConfigAPI.java => SpongeViaConfig.java} | 4 ++-- 8 files changed, 21 insertions(+), 24 deletions(-) rename bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/{BukkitConfigAPI.java => BukkitViaConfig.java} (97%) rename bungee/src/main/java/us/myles/ViaVersion/bungee/platform/{BungeeConfigAPI.java => BungeeViaConfig.java} (97%) rename sponge/src/main/java/us/myles/ViaVersion/sponge/platform/{SpongeConfigAPI.java => SpongeViaConfig.java} (97%) diff --git a/bukkit/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java b/bukkit/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java index d4c326384..f597c65c1 100644 --- a/bukkit/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java +++ b/bukkit/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java @@ -34,7 +34,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform { private boolean lateBind = false; private boolean protocolSupport = false; @Getter - private BukkitConfigAPI conf; + private BukkitViaConfig conf; @Getter private ViaAPI api = new BukkitViaAPI(this); private List queuedTasks = new ArrayList<>(); @@ -51,7 +51,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform { .loader(new BukkitViaLoader(this)) .build()); // Config magic - conf = new BukkitConfigAPI(); + conf = new BukkitViaConfig(); // For compatibility ViaVersion.setInstance(this); diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaConfig.java similarity index 97% rename from bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java rename to bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaConfig.java index 74db3b715..014e567e5 100644 --- a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java +++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaConfig.java @@ -11,10 +11,10 @@ import java.util.Arrays; import java.util.List; import java.util.Map; -public class BukkitConfigAPI extends Config implements ViaVersionConfig { +public class BukkitViaConfig extends Config implements ViaVersionConfig { private static List UNSUPPORTED = Arrays.asList("bungee-ping-interval", "bungee-ping-save", "bungee-servers", "velocity-ping-interval", "velocity-ping-save", "velocity-servers"); - public BukkitConfigAPI() { + public BukkitViaConfig() { super(new File(((ViaVersionPlugin) Via.getPlatform()).getDataFolder(), "config.yml")); // Load config reloadConfig(); @@ -192,7 +192,7 @@ public class BukkitConfigAPI extends Config implements ViaVersionConfig { @Override public URL getDefaultConfigURL() { - return BukkitConfigAPI.class.getClassLoader().getResource("assets/viaversion/config.yml"); + return BukkitViaConfig.class.getClassLoader().getResource("assets/viaversion/config.yml"); } @Override diff --git a/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java b/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java index 97e3a9c75..72142e311 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java +++ b/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java @@ -31,13 +31,13 @@ import java.util.concurrent.TimeUnit; public class BungeePlugin extends Plugin implements ViaPlatform, Listener { private BungeeViaAPI api; - private BungeeConfigAPI config; + private BungeeViaConfig config; private BungeeCommandHandler commandHandler; @Override public void onLoad() { api = new BungeeViaAPI(); - config = new BungeeConfigAPI(getDataFolder()); + config = new BungeeViaConfig(getDataFolder()); commandHandler = new BungeeCommandHandler(); ProxyServer.getInstance().getPluginManager().registerCommand(this, new BungeeCommand(commandHandler)); // Init platform @@ -134,7 +134,7 @@ public class BungeePlugin extends Plugin implements ViaPlatform, Listener { } @Override - public BungeeConfigAPI getConf() { + public BungeeViaConfig getConf() { return config; } 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 index fda215417..a6184efa6 100644 --- 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 @@ -3,7 +3,7 @@ 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.platform.BungeeViaConfig; import us.myles.ViaVersion.bungee.service.ProtocolDetectorService; public class ProbeSubCmd extends ViaSubCommand { @@ -15,7 +15,7 @@ public class ProbeSubCmd extends ViaSubCommand { @Override public String description() { return "Forces ViaVersion to scan server protocol versions " + - (((BungeeConfigAPI) Via.getConfig()).getBungeePingInterval() == -1 ? + (((BungeeViaConfig) Via.getConfig()).getBungeePingInterval() == -1 ? "" : "(Also happens at an interval)"); } diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaConfig.java similarity index 97% rename from bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java rename to bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaConfig.java index 4f9112099..cdb1ca4c7 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java +++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaConfig.java @@ -9,10 +9,10 @@ import java.io.File; import java.net.URL; import java.util.*; -public class BungeeConfigAPI extends Config implements ViaVersionConfig { +public class BungeeViaConfig extends Config implements ViaVersionConfig { private static List UNSUPPORTED = Arrays.asList("nms-player-ticking", "item-cache", "anti-xray-patch", "quick-move-action-fix", "velocity-ping-interval", "velocity-ping-save", "velocity-servers"); - public BungeeConfigAPI(File configFile) { + public BungeeViaConfig(File configFile) { super(new File(configFile, "config.yml")); // Load config reloadConfig(); @@ -20,7 +20,7 @@ public class BungeeConfigAPI extends Config implements ViaVersionConfig { @Override public URL getDefaultConfigURL() { - return BungeeConfigAPI.class.getClassLoader().getResource("assets/viaversion/config.yml"); + return BungeeViaConfig.class.getClassLoader().getResource("assets/viaversion/config.yml"); } @Override 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 index 252959224..6f5f6a909 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/bungee/service/ProtocolDetectorService.java +++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/service/ProtocolDetectorService.java @@ -6,7 +6,7 @@ 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.platform.BungeeViaConfig; import us.myles.ViaVersion.bungee.providers.BungeeVersionProvider; import java.util.HashMap; @@ -26,7 +26,7 @@ public class ProtocolDetectorService implements Runnable { public static Integer getProtocolId(String serverName) { // Step 1. Check Config - Map servers = ((BungeeConfigAPI) Via.getConfig()).getBungeeServerProtocols(); + Map servers = ((BungeeViaConfig) Via.getConfig()).getBungeeServerProtocols(); Integer protocol = servers.get(serverName); if (protocol != null) { return protocol; @@ -61,8 +61,8 @@ public class ProtocolDetectorService implements Runnable { // Ensure protocol is positive, some services will return -1 if (serverPing.getVersion().getProtocol() > 0) { detectedProtocolIds.put(key, serverPing.getVersion().getProtocol()); - if (((BungeeConfigAPI) Via.getConfig()).isBungeePingSave()) { - Map servers = ((BungeeConfigAPI) Via.getConfig()).getBungeeServerProtocols(); + if (((BungeeViaConfig) Via.getConfig()).isBungeePingSave()) { + Map servers = ((BungeeViaConfig) Via.getConfig()).getBungeeServerProtocols(); Integer protocol = servers.get(key); if (protocol != null && protocol == serverPing.getVersion().getProtocol()) { return; diff --git a/sponge/src/main/java/us/myles/ViaVersion/SpongePlugin.java b/sponge/src/main/java/us/myles/ViaVersion/SpongePlugin.java index 7ca0ac3f6..670dd56ae 100644 --- a/sponge/src/main/java/us/myles/ViaVersion/SpongePlugin.java +++ b/sponge/src/main/java/us/myles/ViaVersion/SpongePlugin.java @@ -17,7 +17,6 @@ import org.spongepowered.api.plugin.PluginContainer; import org.spongepowered.api.scheduler.Task; import org.spongepowered.api.text.serializer.TextSerializers; 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.platform.TaskId; @@ -32,10 +31,8 @@ import us.myles.ViaVersion.util.GsonUtil; import java.io.File; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.UUID; -import java.util.concurrent.TimeUnit; import java.util.logging.Logger; @Plugin(id = "viaversion", @@ -58,7 +55,7 @@ public class SpongePlugin implements ViaPlatform { @Getter private SpongeViaAPI api = new SpongeViaAPI(); @Getter - private SpongeConfigAPI conf; + private SpongeViaConfig conf; @Getter private Logger logger; @@ -68,7 +65,7 @@ public class SpongePlugin implements ViaPlatform { // Setup Logger logger = new LoggerWrapper(container.getLogger()); // Setup Plugin - conf = new SpongeConfigAPI(container, defaultConfig.getParentFile()); + conf = new SpongeViaConfig(container, defaultConfig.getParentFile()); SpongeCommandHandler commandHandler = new SpongeCommandHandler(); game.getCommandManager().register(this, commandHandler, "viaversion", "viaver", "vvsponge"); getLogger().info("ViaVersion " + getPluginVersion() + " is now loaded!"); diff --git a/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeConfigAPI.java b/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeViaConfig.java similarity index 97% rename from sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeConfigAPI.java rename to sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeViaConfig.java index a216b0017..ca8ce5dd6 100644 --- a/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeConfigAPI.java +++ b/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeViaConfig.java @@ -12,11 +12,11 @@ import java.util.List; import java.util.Map; import java.util.Optional; -public class SpongeConfigAPI extends Config implements ViaVersionConfig { +public class SpongeViaConfig extends Config implements ViaVersionConfig { private static List UNSUPPORTED = Arrays.asList("anti-xray-patch", "bungee-ping-interval", "bungee-ping-save", "bungee-servers", "velocity-ping-interval", "velocity-ping-save", "velocity-servers", "quick-move-action-fix"); private final PluginContainer pluginContainer; - public SpongeConfigAPI(PluginContainer pluginContainer, File configFile) { + public SpongeViaConfig(PluginContainer pluginContainer, File configFile) { super(new File(configFile, "config.yml")); this.pluginContainer = pluginContainer; // Load config From ab1c44c4fb05dca408fcff267aa8118e6c30b73c Mon Sep 17 00:00:00 2001 From: Myles Date: Sat, 17 Nov 2018 13:13:55 +0000 Subject: [PATCH 5/5] Propose 2.0.0 snapshot as this version contains several API breaking changes --- bukkit/pom.xml | 2 +- bungee/pom.xml | 2 +- common/pom.xml | 2 +- jar/pom.xml | 2 +- pom.xml | 2 +- sponge-legacy/pom.xml | 2 +- sponge/pom.xml | 2 +- velocity/pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bukkit/pom.xml b/bukkit/pom.xml index 8dda19ea8..3270ff38b 100644 --- a/bukkit/pom.xml +++ b/bukkit/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT 4.0.0 diff --git a/bungee/pom.xml b/bungee/pom.xml index d09b21455..384d30083 100644 --- a/bungee/pom.xml +++ b/bungee/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT 4.0.0 diff --git a/common/pom.xml b/common/pom.xml index 351079c5d..8c4605b9c 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT 4.0.0 diff --git a/jar/pom.xml b/jar/pom.xml index 95b282a0a..c37896688 100644 --- a/jar/pom.xml +++ b/jar/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT 4.0.0 viaversion-jar diff --git a/pom.xml b/pom.xml index 137071b6e..a9b791357 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ us.myles viaversion-parent - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT pom viaversion-parent diff --git a/sponge-legacy/pom.xml b/sponge-legacy/pom.xml index ac481ad6b..ff4f85e09 100644 --- a/sponge-legacy/pom.xml +++ b/sponge-legacy/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT 4.0.0 diff --git a/sponge/pom.xml b/sponge/pom.xml index d9367e0e1..6c651d51d 100644 --- a/sponge/pom.xml +++ b/sponge/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT 4.0.0 diff --git a/velocity/pom.xml b/velocity/pom.xml index 50d9a28d5..aa5b4f579 100644 --- a/velocity/pom.xml +++ b/velocity/pom.xml @@ -5,7 +5,7 @@ viaversion-parent us.myles - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT 4.0.0