Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-12-26 00:00:28 +01:00
Merge branch 'pr/1045'
Dieser Commit ist enthalten in:
Commit
73dccbaf24
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>viaversion-parent</artifactId>
|
<artifactId>viaversion-parent</artifactId>
|
||||||
<groupId>us.myles</groupId>
|
<groupId>us.myles</groupId>
|
||||||
<version>1.6.1-SNAPSHOT</version>
|
<version>2.0.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform {
|
|||||||
private boolean lateBind = false;
|
private boolean lateBind = false;
|
||||||
private boolean protocolSupport = false;
|
private boolean protocolSupport = false;
|
||||||
@Getter
|
@Getter
|
||||||
private BukkitConfigAPI conf;
|
private BukkitViaConfig conf;
|
||||||
@Getter
|
@Getter
|
||||||
private ViaAPI<Player> api = new BukkitViaAPI(this);
|
private ViaAPI<Player> api = new BukkitViaAPI(this);
|
||||||
private List<Runnable> queuedTasks = new ArrayList<>();
|
private List<Runnable> queuedTasks = new ArrayList<>();
|
||||||
@ -51,7 +51,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform {
|
|||||||
.loader(new BukkitViaLoader(this))
|
.loader(new BukkitViaLoader(this))
|
||||||
.build());
|
.build());
|
||||||
// Config magic
|
// Config magic
|
||||||
conf = new BukkitConfigAPI();
|
conf = new BukkitViaConfig();
|
||||||
// For compatibility
|
// For compatibility
|
||||||
ViaVersion.setInstance(this);
|
ViaVersion.setInstance(this);
|
||||||
|
|
||||||
|
@ -11,10 +11,10 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class BukkitConfigAPI extends Config implements ViaVersionConfig {
|
public class BukkitViaConfig extends Config implements ViaVersionConfig {
|
||||||
private static List<String> UNSUPPORTED = Arrays.asList("bungee-ping-interval", "bungee-ping-save", "bungee-servers");
|
private static List<String> 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"));
|
super(new File(((ViaVersionPlugin) Via.getPlatform()).getDataFolder(), "config.yml"));
|
||||||
// Load config
|
// Load config
|
||||||
reloadConfig();
|
reloadConfig();
|
||||||
@ -192,7 +192,7 @@ public class BukkitConfigAPI extends Config implements ViaVersionConfig {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public URL getDefaultConfigURL() {
|
public URL getDefaultConfigURL() {
|
||||||
return BukkitConfigAPI.class.getClassLoader().getResource("assets/viaversion/config.yml");
|
return BukkitViaConfig.class.getClassLoader().getResource("assets/viaversion/config.yml");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>viaversion-parent</artifactId>
|
<artifactId>viaversion-parent</artifactId>
|
||||||
<groupId>us.myles</groupId>
|
<groupId>us.myles</groupId>
|
||||||
<version>1.6.1-SNAPSHOT</version>
|
<version>2.0.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
@ -31,13 +31,13 @@ import java.util.concurrent.TimeUnit;
|
|||||||
|
|
||||||
public class BungeePlugin extends Plugin implements ViaPlatform, Listener {
|
public class BungeePlugin extends Plugin implements ViaPlatform, Listener {
|
||||||
private BungeeViaAPI api;
|
private BungeeViaAPI api;
|
||||||
private BungeeConfigAPI config;
|
private BungeeViaConfig config;
|
||||||
private BungeeCommandHandler commandHandler;
|
private BungeeCommandHandler commandHandler;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
api = new BungeeViaAPI();
|
api = new BungeeViaAPI();
|
||||||
config = new BungeeConfigAPI(getDataFolder());
|
config = new BungeeViaConfig(getDataFolder());
|
||||||
commandHandler = new BungeeCommandHandler();
|
commandHandler = new BungeeCommandHandler();
|
||||||
ProxyServer.getInstance().getPluginManager().registerCommand(this, new BungeeCommand(commandHandler));
|
ProxyServer.getInstance().getPluginManager().registerCommand(this, new BungeeCommand(commandHandler));
|
||||||
// Init platform
|
// Init platform
|
||||||
@ -134,7 +134,7 @@ public class BungeePlugin extends Plugin implements ViaPlatform, Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BungeeConfigAPI getConf() {
|
public BungeeViaConfig getConf() {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ package us.myles.ViaVersion.bungee.commands.subs;
|
|||||||
import us.myles.ViaVersion.api.Via;
|
import us.myles.ViaVersion.api.Via;
|
||||||
import us.myles.ViaVersion.api.command.ViaCommandSender;
|
import us.myles.ViaVersion.api.command.ViaCommandSender;
|
||||||
import us.myles.ViaVersion.api.command.ViaSubCommand;
|
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;
|
import us.myles.ViaVersion.bungee.service.ProtocolDetectorService;
|
||||||
|
|
||||||
public class ProbeSubCmd extends ViaSubCommand {
|
public class ProbeSubCmd extends ViaSubCommand {
|
||||||
@ -15,7 +15,7 @@ public class ProbeSubCmd extends ViaSubCommand {
|
|||||||
@Override
|
@Override
|
||||||
public String description() {
|
public String description() {
|
||||||
return "Forces ViaVersion to scan server protocol versions " +
|
return "Forces ViaVersion to scan server protocol versions " +
|
||||||
(((BungeeConfigAPI) Via.getConfig()).getBungeePingInterval() == -1 ?
|
(((BungeeViaConfig) Via.getConfig()).getBungeePingInterval() == -1 ?
|
||||||
"" : "(Also happens at an interval)");
|
"" : "(Also happens at an interval)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,10 +9,10 @@ import java.io.File;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class BungeeConfigAPI extends Config implements ViaVersionConfig {
|
public class BungeeViaConfig extends Config implements ViaVersionConfig {
|
||||||
private static List<String> UNSUPPORTED = Arrays.asList("nms-player-ticking", "item-cache", "anti-xray-patch", "quick-move-action-fix");
|
private static List<String> 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"));
|
super(new File(configFile, "config.yml"));
|
||||||
// Load config
|
// Load config
|
||||||
reloadConfig();
|
reloadConfig();
|
||||||
@ -20,7 +20,7 @@ public class BungeeConfigAPI extends Config implements ViaVersionConfig {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public URL getDefaultConfigURL() {
|
public URL getDefaultConfigURL() {
|
||||||
return BungeeConfigAPI.class.getClassLoader().getResource("assets/viaversion/config.yml");
|
return BungeeViaConfig.class.getClassLoader().getResource("assets/viaversion/config.yml");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@ -6,7 +6,7 @@ import net.md_5.bungee.api.ServerPing;
|
|||||||
import net.md_5.bungee.api.config.ServerInfo;
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
import us.myles.ViaVersion.BungeePlugin;
|
import us.myles.ViaVersion.BungeePlugin;
|
||||||
import us.myles.ViaVersion.api.Via;
|
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 us.myles.ViaVersion.bungee.providers.BungeeVersionProvider;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -26,7 +26,7 @@ public class ProtocolDetectorService implements Runnable {
|
|||||||
|
|
||||||
public static Integer getProtocolId(String serverName) {
|
public static Integer getProtocolId(String serverName) {
|
||||||
// Step 1. Check Config
|
// Step 1. Check Config
|
||||||
Map<String, Integer> servers = ((BungeeConfigAPI) Via.getConfig()).getBungeeServerProtocols();
|
Map<String, Integer> servers = ((BungeeViaConfig) Via.getConfig()).getBungeeServerProtocols();
|
||||||
Integer protocol = servers.get(serverName);
|
Integer protocol = servers.get(serverName);
|
||||||
if (protocol != null) {
|
if (protocol != null) {
|
||||||
return protocol;
|
return protocol;
|
||||||
@ -61,8 +61,8 @@ public class ProtocolDetectorService implements Runnable {
|
|||||||
// Ensure protocol is positive, some services will return -1
|
// Ensure protocol is positive, some services will return -1
|
||||||
if (serverPing.getVersion().getProtocol() > 0) {
|
if (serverPing.getVersion().getProtocol() > 0) {
|
||||||
detectedProtocolIds.put(key, serverPing.getVersion().getProtocol());
|
detectedProtocolIds.put(key, serverPing.getVersion().getProtocol());
|
||||||
if (((BungeeConfigAPI) Via.getConfig()).isBungeePingSave()) {
|
if (((BungeeViaConfig) Via.getConfig()).isBungeePingSave()) {
|
||||||
Map<String, Integer> servers = ((BungeeConfigAPI) Via.getConfig()).getBungeeServerProtocols();
|
Map<String, Integer> servers = ((BungeeViaConfig) Via.getConfig()).getBungeeServerProtocols();
|
||||||
Integer protocol = servers.get(key);
|
Integer protocol = servers.get(key);
|
||||||
if (protocol != null && protocol == serverPing.getVersion().getProtocol()) {
|
if (protocol != null && protocol == serverPing.getVersion().getProtocol()) {
|
||||||
return;
|
return;
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>viaversion-parent</artifactId>
|
<artifactId>viaversion-parent</artifactId>
|
||||||
<groupId>us.myles</groupId>
|
<groupId>us.myles</groupId>
|
||||||
<version>1.6.1-SNAPSHOT</version>
|
<version>2.0.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
@ -17,7 +17,7 @@
|
|||||||
<groupId>org.yaml</groupId>
|
<groupId>org.yaml</groupId>
|
||||||
<artifactId>snakeyaml</artifactId>
|
<artifactId>snakeyaml</artifactId>
|
||||||
<version>1.18</version>
|
<version>1.18</version>
|
||||||
<scope>provided</scope>
|
<scope>compile</scope> <!-- Velocity doesn't have snakeyaml -->
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
@ -18,6 +18,8 @@ import us.myles.ViaVersion.util.PipelineUtil;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.locks.ReadWriteLock;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class UserConnection {
|
public class UserConnection {
|
||||||
@ -36,7 +38,7 @@ public class UserConnection {
|
|||||||
// Used for handling warnings (over time)
|
// Used for handling warnings (over time)
|
||||||
private int secondsObserved = 0;
|
private int secondsObserved = 0;
|
||||||
private int warnings = 0;
|
private int warnings = 0;
|
||||||
|
private ReadWriteLock velocityLock = new ReentrantReadWriteLock();
|
||||||
|
|
||||||
public UserConnection(Channel channel) {
|
public UserConnection(Channel channel) {
|
||||||
this.channel = channel;
|
this.channel = channel;
|
||||||
@ -108,7 +110,8 @@ public class UserConnection {
|
|||||||
*/
|
*/
|
||||||
public ChannelFuture sendRawPacketFuture(final ByteBuf packet) {
|
public ChannelFuture sendRawPacketFuture(final ByteBuf packet) {
|
||||||
final ChannelHandler handler = channel.pipeline().get(Via.getManager().getInjector().getEncoderName());
|
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);
|
buf.writeBytes(packet);
|
||||||
packet.release();
|
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 (currentThread) {
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
context.fireChannelRead(buf);
|
context.fireChannelRead(buf);
|
||||||
|
@ -74,7 +74,7 @@ public abstract class ViaCommandHandler implements ViaVersionCommand {
|
|||||||
|
|
||||||
//SubCommands tabcomplete
|
//SubCommands tabcomplete
|
||||||
if (args.length == 1) {
|
if (args.length == 1) {
|
||||||
if (!args[0].equals("")) {
|
if (!args[0].isEmpty()) {
|
||||||
for (ViaSubCommand sub : allowed)
|
for (ViaSubCommand sub : allowed)
|
||||||
if (sub.name().toLowerCase().startsWith(args[0].toLowerCase()))
|
if (sub.name().toLowerCase().startsWith(args[0].toLowerCase()))
|
||||||
output.add(sub.name());
|
output.add(sub.name());
|
||||||
|
@ -5,6 +5,8 @@ import io.netty.channel.ChannelHandlerContext;
|
|||||||
import io.netty.channel.ChannelPipeline;
|
import io.netty.channel.ChannelPipeline;
|
||||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||||
import io.netty.handler.codec.MessageToByteEncoder;
|
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.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
@ -14,6 +16,7 @@ import java.util.List;
|
|||||||
public class PipelineUtil {
|
public class PipelineUtil {
|
||||||
private static Method DECODE_METHOD;
|
private static Method DECODE_METHOD;
|
||||||
private static Method ENCODE_METHOD;
|
private static Method ENCODE_METHOD;
|
||||||
|
private static Method MTM_DECODE;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
@ -28,6 +31,12 @@ public class PipelineUtil {
|
|||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
e.printStackTrace();
|
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<Object> callDecode(MessageToMessageDecoder decoder, ChannelHandlerContext ctx, Object msg) throws InvocationTargetException {
|
||||||
|
List<Object> 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
|
* Check if a stack trace contains a certain exception
|
||||||
*
|
*
|
||||||
|
@ -46,6 +46,28 @@ bungee-ping-save: true
|
|||||||
bungee-servers: {}
|
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 #
|
# GLOBAL PACKET LIMITER #
|
||||||
#----------------------------------------------------------#
|
#----------------------------------------------------------#
|
||||||
#
|
#
|
||||||
|
11
jar/pom.xml
11
jar/pom.xml
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>viaversion-parent</artifactId>
|
<artifactId>viaversion-parent</artifactId>
|
||||||
<groupId>us.myles</groupId>
|
<groupId>us.myles</groupId>
|
||||||
<version>1.6.1-SNAPSHOT</version>
|
<version>2.0.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<name>viaversion-jar</name>
|
<name>viaversion-jar</name>
|
||||||
@ -57,6 +57,10 @@
|
|||||||
<pattern>org.javassist</pattern>
|
<pattern>org.javassist</pattern>
|
||||||
<shadedPattern>us.myles.viaversion.libs.javassist</shadedPattern>
|
<shadedPattern>us.myles.viaversion.libs.javassist</shadedPattern>
|
||||||
</relocation>
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>org.yaml.snakeyaml</pattern>
|
||||||
|
<shadedPattern>us.myles.viaversion.libs.snakeyaml</shadedPattern>
|
||||||
|
</relocation>
|
||||||
</relocations>
|
</relocations>
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
@ -92,6 +96,11 @@
|
|||||||
<artifactId>viaversion-sponge</artifactId>
|
<artifactId>viaversion-sponge</artifactId>
|
||||||
<version>${project.parent.version}</version>
|
<version>${project.parent.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>us.myles</groupId>
|
||||||
|
<artifactId>viaversion-velocity</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
3
pom.xml
3
pom.xml
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<groupId>us.myles</groupId>
|
<groupId>us.myles</groupId>
|
||||||
<artifactId>viaversion-parent</artifactId>
|
<artifactId>viaversion-parent</artifactId>
|
||||||
<version>1.6.1-SNAPSHOT</version>
|
<version>2.0.0-SNAPSHOT</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<name>viaversion-parent</name>
|
<name>viaversion-parent</name>
|
||||||
@ -21,6 +21,7 @@
|
|||||||
<module>bungee</module>
|
<module>bungee</module>
|
||||||
<module>sponge</module>
|
<module>sponge</module>
|
||||||
<module>sponge-legacy</module>
|
<module>sponge-legacy</module>
|
||||||
|
<module>velocity</module>
|
||||||
<module>jar</module>
|
<module>jar</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>viaversion-parent</artifactId>
|
<artifactId>viaversion-parent</artifactId>
|
||||||
<groupId>us.myles</groupId>
|
<groupId>us.myles</groupId>
|
||||||
<version>1.6.1-SNAPSHOT</version>
|
<version>2.0.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>viaversion-parent</artifactId>
|
<artifactId>viaversion-parent</artifactId>
|
||||||
<groupId>us.myles</groupId>
|
<groupId>us.myles</groupId>
|
||||||
<version>1.6.1-SNAPSHOT</version>
|
<version>2.0.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@ import org.spongepowered.api.plugin.PluginContainer;
|
|||||||
import org.spongepowered.api.scheduler.Task;
|
import org.spongepowered.api.scheduler.Task;
|
||||||
import org.spongepowered.api.text.serializer.TextSerializers;
|
import org.spongepowered.api.text.serializer.TextSerializers;
|
||||||
import us.myles.ViaVersion.api.Via;
|
import us.myles.ViaVersion.api.Via;
|
||||||
import us.myles.ViaVersion.api.ViaAPI;
|
|
||||||
import us.myles.ViaVersion.api.command.ViaCommandSender;
|
import us.myles.ViaVersion.api.command.ViaCommandSender;
|
||||||
import us.myles.ViaVersion.api.configuration.ConfigurationProvider;
|
import us.myles.ViaVersion.api.configuration.ConfigurationProvider;
|
||||||
import us.myles.ViaVersion.api.platform.TaskId;
|
import us.myles.ViaVersion.api.platform.TaskId;
|
||||||
@ -32,10 +31,8 @@ import us.myles.ViaVersion.util.GsonUtil;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@Plugin(id = "viaversion",
|
@Plugin(id = "viaversion",
|
||||||
@ -58,7 +55,7 @@ public class SpongePlugin implements ViaPlatform {
|
|||||||
@Getter
|
@Getter
|
||||||
private SpongeViaAPI api = new SpongeViaAPI();
|
private SpongeViaAPI api = new SpongeViaAPI();
|
||||||
@Getter
|
@Getter
|
||||||
private SpongeConfigAPI conf;
|
private SpongeViaConfig conf;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private Logger logger;
|
private Logger logger;
|
||||||
@ -68,7 +65,7 @@ public class SpongePlugin implements ViaPlatform {
|
|||||||
// Setup Logger
|
// Setup Logger
|
||||||
logger = new LoggerWrapper(container.getLogger());
|
logger = new LoggerWrapper(container.getLogger());
|
||||||
// Setup Plugin
|
// Setup Plugin
|
||||||
conf = new SpongeConfigAPI(container, defaultConfig.getParentFile());
|
conf = new SpongeViaConfig(container, defaultConfig.getParentFile());
|
||||||
SpongeCommandHandler commandHandler = new SpongeCommandHandler();
|
SpongeCommandHandler commandHandler = new SpongeCommandHandler();
|
||||||
game.getCommandManager().register(this, commandHandler, "viaversion", "viaver", "vvsponge");
|
game.getCommandManager().register(this, commandHandler, "viaversion", "viaver", "vvsponge");
|
||||||
getLogger().info("ViaVersion " + getPluginVersion() + " is now loaded!");
|
getLogger().info("ViaVersion " + getPluginVersion() + " is now loaded!");
|
||||||
|
@ -12,11 +12,11 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class SpongeConfigAPI extends Config implements ViaVersionConfig {
|
public class SpongeViaConfig extends Config implements ViaVersionConfig {
|
||||||
private static List<String> UNSUPPORTED = Arrays.asList("anti-xray-patch", "bungee-ping-interval", "bungee-ping-save", "bungee-servers", "quick-move-action-fix");
|
private static List<String> 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;
|
private final PluginContainer pluginContainer;
|
||||||
|
|
||||||
public SpongeConfigAPI(PluginContainer pluginContainer, File configFile) {
|
public SpongeViaConfig(PluginContainer pluginContainer, File configFile) {
|
||||||
super(new File(configFile, "config.yml"));
|
super(new File(configFile, "config.yml"));
|
||||||
this.pluginContainer = pluginContainer;
|
this.pluginContainer = pluginContainer;
|
||||||
// Load config
|
// Load config
|
62
velocity/pom.xml
Normale Datei
62
velocity/pom.xml
Normale Datei
@ -0,0 +1,62 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>viaversion-parent</artifactId>
|
||||||
|
<groupId>us.myles</groupId>
|
||||||
|
<version>2.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>viaversion-velocity</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>velocity</id>
|
||||||
|
<url>https://repo.velocitypowered.com/snapshots</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>templating-maven-plugin</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>filter-src</id>
|
||||||
|
<goals>
|
||||||
|
<goal>filter-sources</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- Common Module -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>us.myles</groupId>
|
||||||
|
<artifactId>viaversion-common</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Velocity API 1.0 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.velocitypowered</groupId>
|
||||||
|
<artifactId>velocity-api</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,5 @@
|
|||||||
|
package us.myles.ViaVersion.velocity;
|
||||||
|
|
||||||
|
public class VersionInfo {
|
||||||
|
public static final String VERSION = "${project.version}";
|
||||||
|
}
|
206
velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java
Normale Datei
206
velocity/src/main/java/us/myles/ViaVersion/VelocityPlugin.java
Normale Datei
@ -0,0 +1,206 @@
|
|||||||
|
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<Player> {
|
||||||
|
@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;
|
||||||
|
private VelocityViaConfig conf;
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onProxyInit(ProxyInitializeEvent e) {
|
||||||
|
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()
|
||||||
|
.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() {
|
||||||
|
String proxyImpl = ProxyServer.class.getPackage().getImplementationTitle();
|
||||||
|
return (proxyImpl != null) ? proxyImpl : "Velocity";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPlatformVersion() {
|
||||||
|
String version = ProxyServer.class.getPackage().getImplementationVersion();
|
||||||
|
return (version != null) ? version : "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
@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<PluginInfo> 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;
|
||||||
|
}
|
||||||
|
}
|
@ -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<String> suggest(@NonNull CommandSource source, String[] currentArgs) {
|
||||||
|
return onTabComplete(new VelocityCommandSender(source), currentArgs);
|
||||||
|
}
|
||||||
|
}
|
@ -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 "?"; // :(
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
@ -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<ByteBuf> {
|
||||||
|
private final UserConnection info;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void decode(ChannelHandlerContext ctx, ByteBuf bytebuf, List<Object> 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);
|
||||||
|
}
|
||||||
|
}
|
@ -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<ByteBuf> {
|
||||||
|
@NonNull
|
||||||
|
private final UserConnection info;
|
||||||
|
private boolean handledCompression = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void encode(final ChannelHandlerContext ctx, ByteBuf bytebuf, List<Object> 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);
|
||||||
|
}
|
||||||
|
}
|
@ -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<Pair<Integer, Protocol>> 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<Pair<Integer, Protocol>> 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<Integer, Protocol> 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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<Player> {
|
||||||
|
public VelocityBossBar(String title, float health, BossColor color, BossStyle style) {
|
||||||
|
super(title, health, color, style);
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
@ -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<Player> {
|
||||||
|
@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<Integer> getSupportedVersions() {
|
||||||
|
SortedSet<Integer> outputSet = new TreeSet<>(ProtocolRegistry.getSupportedVersions());
|
||||||
|
outputSet.removeAll(Via.getPlatform().getConf().getBlockedProtocols());
|
||||||
|
|
||||||
|
return outputSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<UUID, UserConnection> getPortedPlayers() {
|
||||||
|
return Via.getManager().getPortedPlayers();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,280 @@
|
|||||||
|
package us.myles.ViaVersion.velocity.platform;
|
||||||
|
|
||||||
|
import us.myles.ViaVersion.api.ViaVersionConfig;
|
||||||
|
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<String> 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<String, Object> config) {
|
||||||
|
// Parse servers
|
||||||
|
Map<String, Object> 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<String, Object> 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")) {
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> 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<Integer> 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<String, Integer> 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);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
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 getLowestSupportedProtocolVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getLowestSupportedProtocolVersion() 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";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
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());
|
||||||
|
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
|
||||||
|
public void unload() {
|
||||||
|
// Probably not useful, there's no ProxyReloadEvent
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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<Integer> sorted = new ArrayList<Integer>((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<Integer> 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;
|
||||||
|
}
|
||||||
|
}
|
@ -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<String, Integer> detectedProtocolIds = new ConcurrentHashMap<>();
|
||||||
|
@Getter
|
||||||
|
private static ProtocolDetectorService instance;
|
||||||
|
|
||||||
|
public ProtocolDetectorService() {
|
||||||
|
instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Integer getProtocolId(String serverName) {
|
||||||
|
// Step 1. Check Config
|
||||||
|
Map<String, Integer> 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<String, Integer> 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<String, Integer> getDetectedIds() {
|
||||||
|
return new HashMap<>(detectedProtocolIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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<UUID> 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<UUID>) ReflectionUtil.invoke(sessionHandler, "getServerBossBars");
|
||||||
|
// TODO make this work
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren