<1.1.4> Add HAProxy and 1.9-1.12 support to EaglerXVelocity
This commit is contained in:
parent
b80d5f6772
commit
4d66ca140a
|
@ -46,7 +46,7 @@ The settings.yml file is primarily used for configuring the built-in skin and ca
|
||||||
- **`disable_fnaw_skins_everywhere:`** Boolean, default value is `false`, can be used to globally disable FNAW skins if your players bitch about them a lot and are too lazy to just disable the FNAW skins locally on their clients.
|
- **`disable_fnaw_skins_everywhere:`** Boolean, default value is `false`, can be used to globally disable FNAW skins if your players bitch about them a lot and are too lazy to just disable the FNAW skins locally on their clients.
|
||||||
- **`disable_fnaw_skins_on_servers:`** List of strings, default value is nothing (`[]`), contains a list of names of registered servers on your Velocity proxy that the FNAW skins should be disabled on. Good for explicitly disabling them for PVP but allowing them everywhere else.
|
- **`disable_fnaw_skins_on_servers:`** List of strings, default value is nothing (`[]`), contains a list of names of registered servers on your Velocity proxy that the FNAW skins should be disabled on. Good for explicitly disabling them for PVP but allowing them everywhere else.
|
||||||
- **`enable_backend_rpc_api:`** Boolean, default value is `false`, if support for servers running the EaglerXBukkitAPI plugin should be enabled or not.
|
- **`enable_backend_rpc_api:`** Boolean, default value is `false`, if support for servers running the EaglerXBukkitAPI plugin should be enabled or not.
|
||||||
- **use_modernized_channel_names:`** Boolean, default value is `false`, if "modernized" plugin channel names compatible with Minecraft 1.13+ should be used for EaglerXBukkitAPI plugin message packets
|
- **`use_modernized_channel_names:`** Boolean, default value is `false`, if "modernized" plugin channel names compatible with Minecraft 1.13+ should be used for EaglerXBukkitAPI plugin message packets
|
||||||
|
|
||||||
### `listeners.yml`
|
### `listeners.yml`
|
||||||
|
|
||||||
|
@ -62,9 +62,12 @@ Defines one or more "listeners" (open ports) for EaglercraftX players to use to
|
||||||
- **`server_motd:`** List of up to 2 strings, default value is `'&6An EaglercraftX server'`, sets the contents of the listener's MOTD, which is the text displayed along with the `server_icon` when players add this server's listener address to their client's Multiplayer menu server list.
|
- **`server_motd:`** List of up to 2 strings, default value is `'&6An EaglercraftX server'`, sets the contents of the listener's MOTD, which is the text displayed along with the `server_icon` when players add this server's listener address to their client's Multiplayer menu server list.
|
||||||
- **`allow_motd:`** Boolean, default value is `true`, if this listener should respond to MOTD queries or not.
|
- **`allow_motd:`** Boolean, default value is `true`, if this listener should respond to MOTD queries or not.
|
||||||
- **`allow_query:`** Boolean, default value is `true`, if this listener should respond to all other types of queries or not.
|
- **`allow_query:`** Boolean, default value is `true`, if this listener should respond to all other types of queries or not.
|
||||||
|
- **`min_minecraft_protocol:`** Integer, default value is `47`, sets the minimum Minecraft [protocol version](https://wiki.vg/Protocol_version_numbers) that EaglercraftX-based clients are allowed to connect with (`47` = 1.8)
|
||||||
|
- **`max_minecraft_protocol:`** Integer, default value is `340`, sets the maximum Minecraft protocol version that EaglercraftX-based clients are allowed to connect with (`340` = 1.12.2)
|
||||||
- **`allow_protocol_v3:`** Boolean, default value is `true`, if this listener should allow clients using the v1/v2/v3 protocols to join (pre-u37 clients).
|
- **`allow_protocol_v3:`** Boolean, default value is `true`, if this listener should allow clients using the v1/v2/v3 protocols to join (pre-u37 clients).
|
||||||
- **`allow_protocol_v4:`** Boolean, default value is `true`, if this listener should allow clients using the v4 protocol to join (post-u37 clients).
|
- **`allow_protocol_v4:`** Boolean, default value is `true`, if this listener should allow clients using the v4 protocol to join (post-u37 clients).
|
||||||
- **`protocol_v4_defrag_send_delay:`** Integer, default value is `10`, the number of milliseconds to wait before flushing all pending EaglercraftX plugin message packets, saves bandwidth by combining multiple messages into a single plugin message packet. Setting this to `0` has the same effect on clientbound packets as setting `eaglerNoDelay` to `true` does on a post-u37 client for all serverbound packets.
|
- **`protocol_v4_defrag_send_delay:`** Integer, default value is `10`, the number of milliseconds to wait before flushing all pending EaglercraftX plugin message packets, saves bandwidth by combining multiple messages into a single plugin message packet. Setting this to `0` has the same effect on clientbound packets as setting `eaglerNoDelay` to `true` does on a post-u37 client for all serverbound packets.
|
||||||
|
- **`use_haproxy_protocol:`** Boolean, default value is `false`, can be used to enable support for the HAProxy proxy protocol. Make sure to also add the `check`, `check-send-proxy`, and `send-proxy-v2` parameters to your `server` directives in the HAProxy config file.
|
||||||
- **`allow_cookie_revoke_query:`** Boolean, default value is `true`, If this listener should accept queries from post-u37 clients to revoke session tokens, you need to create your own Velocity plugin to go with EaglerXVelocity that handles the `EaglercraftRevokeSessionQueryEvent` event it fires in order for this feature to work correctly.
|
- **`allow_cookie_revoke_query:`** Boolean, default value is `true`, If this listener should accept queries from post-u37 clients to revoke session tokens, you need to create your own Velocity plugin to go with EaglerXVelocity that handles the `EaglercraftRevokeSessionQueryEvent` event it fires in order for this feature to work correctly.
|
||||||
- **`request_motd_cache:`** Section that defines caching hints for server lists that cache the MOTD via the `MOTD.cache` query. As far as we know, not even the official Eaglercraft Server List on eaglercraft.com currently pays attention to these hints or attempts to cache MOTDs, so they can be ignored for now.
|
- **`request_motd_cache:`** Section that defines caching hints for server lists that cache the MOTD via the `MOTD.cache` query. As far as we know, not even the official Eaglercraft Server List on eaglercraft.com currently pays attention to these hints or attempts to cache MOTDs, so they can be ignored for now.
|
||||||
- **`cache_ttl:`** Integer, default value is `7200`, sets how many seconds for the server list to store the MOTD in cache.
|
- **`cache_ttl:`** Integer, default value is `7200`, sets how many seconds for the server list to store the MOTD in cache.
|
||||||
|
|
Binary file not shown.
|
@ -17,13 +17,13 @@ package net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity;
|
||||||
*/
|
*/
|
||||||
public class EaglerXVelocityVersion {
|
public class EaglerXVelocityVersion {
|
||||||
|
|
||||||
public static final String NATIVE_VELOCITY_BUILD = "3.4.0-SNAPSHOT:99aaf3ce:b439";
|
public static final String NATIVE_VELOCITY_BUILD = "3.4.0-SNAPSHOT:cefa3b27:b450";
|
||||||
|
|
||||||
public static final String ID = "EaglerXVelocity";
|
public static final String ID = "EaglerXVelocity";
|
||||||
public static final String PLUGIN_ID = "eaglerxvelocity";
|
public static final String PLUGIN_ID = "eaglerxvelocity";
|
||||||
public static final String NAME = "EaglercraftXVelocity";
|
public static final String NAME = "EaglercraftXVelocity";
|
||||||
public static final String DESCRIPTION = "Plugin to allow EaglercraftX 1.8 players to join your network, or allow EaglercraftX 1.8 players to use your network as a proxy to join other networks";
|
public static final String DESCRIPTION = "Plugin to allow EaglercraftX 1.8 players to join your network, or allow EaglercraftX 1.8 players to use your network as a proxy to join other networks";
|
||||||
public static final String VERSION = "1.1.3";
|
public static final String VERSION = "1.1.4";
|
||||||
public static final String[] AUTHORS = new String[] { "lax1dude", "ayunami2000" };
|
public static final String[] AUTHORS = new String[] { "lax1dude", "ayunami2000" };
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.api;
|
package net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.api;
|
||||||
|
|
||||||
import com.velocitypowered.proxy.protocol.util.VelocityLegacyHoverEventSerializer;
|
|
||||||
|
|
||||||
import net.kyori.adventure.text.serializer.json.JSONComponentSerializer;
|
import net.kyori.adventure.text.serializer.json.JSONComponentSerializer;
|
||||||
|
import net.kyori.adventure.text.serializer.json.LegacyHoverEventSerializer;
|
||||||
|
import net.kyori.adventure.text.serializer.json.legacyimpl.NBTLegacyHoverEventSerializer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||||
|
@ -21,7 +21,21 @@ import net.kyori.adventure.text.serializer.json.JSONComponentSerializer;
|
||||||
*/
|
*/
|
||||||
public class JSONLegacySerializer {
|
public class JSONLegacySerializer {
|
||||||
|
|
||||||
public static final JSONComponentSerializer instance = JSONComponentSerializer.builder()
|
static {
|
||||||
.legacyHoverEventSerializer(VelocityLegacyHoverEventSerializer.INSTANCE).build();
|
JSONComponentSerializer.Builder builder = JSONComponentSerializer.builder();
|
||||||
|
try {
|
||||||
|
builder.legacyHoverEventSerializer(NBTLegacyHoverEventSerializer.get());
|
||||||
|
}catch(Throwable t) {
|
||||||
|
try {
|
||||||
|
Class c = Class.forName("com.velocitypowered.proxy.protocol.util.VelocityLegacyHoverEventSerializer");
|
||||||
|
builder.legacyHoverEventSerializer((LegacyHoverEventSerializer)c.getDeclaredField("INSTANCE").get(null));
|
||||||
|
}catch(Throwable tt) {
|
||||||
|
throw new RuntimeException("Legacy hover event serializer is unavailable! (downgrade velocity)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
instance = builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final JSONComponentSerializer instance;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,12 +71,15 @@ public class EaglerListenerConfig {
|
||||||
}
|
}
|
||||||
boolean allowMOTD = config.getBoolean("allow_motd", true);
|
boolean allowMOTD = config.getBoolean("allow_motd", true);
|
||||||
boolean allowQuery = config.getBoolean("allow_query", true);
|
boolean allowQuery = config.getBoolean("allow_query", true);
|
||||||
|
int minMCProtocol = config.getInt("min_minecraft_protocol", 47);
|
||||||
|
int maxMCProtocol = config.getInt("max_minecraft_protocol", 340);
|
||||||
boolean allowV3 = config.getBoolean("allow_protocol_v3", true);
|
boolean allowV3 = config.getBoolean("allow_protocol_v3", true);
|
||||||
boolean allowV4 = config.getBoolean("allow_protocol_v4", true);
|
boolean allowV4 = config.getBoolean("allow_protocol_v4", true);
|
||||||
if(!allowV3 && !allowV4) {
|
if(!allowV3 && !allowV4) {
|
||||||
throw new IllegalArgumentException("Both v3 and v4 protocol are disabled!");
|
throw new IllegalArgumentException("Both v3 and v4 protocol are disabled!");
|
||||||
}
|
}
|
||||||
int defragSendDelay = config.getInt("protocol_v4_defrag_send_delay", 10);
|
int defragSendDelay = config.getInt("protocol_v4_defrag_send_delay", 10);
|
||||||
|
boolean haproxyProtocol = config.getBoolean("use_haproxy_protocol", false);
|
||||||
|
|
||||||
int cacheTTL = 7200;
|
int cacheTTL = 7200;
|
||||||
boolean cacheAnimation = false;
|
boolean cacheAnimation = false;
|
||||||
|
@ -152,8 +155,8 @@ public class EaglerListenerConfig {
|
||||||
cacheTrending, cachePortfolios);
|
cacheTrending, cachePortfolios);
|
||||||
return new EaglerListenerConfig(hostv4, hostv6, maxPlayer,
|
return new EaglerListenerConfig(hostv4, hostv6, maxPlayer,
|
||||||
forwardIp, forwardIpHeader, redirectLegacyClientsTo, serverIcon, serverMOTD, allowMOTD, allowQuery,
|
forwardIp, forwardIpHeader, redirectLegacyClientsTo, serverIcon, serverMOTD, allowMOTD, allowQuery,
|
||||||
allowV3, allowV4, defragSendDelay, cacheConfig, httpServer, enableVoiceChat, ratelimitIp,
|
minMCProtocol, maxMCProtocol, allowV3, allowV4, defragSendDelay, haproxyProtocol, cacheConfig,
|
||||||
ratelimitLogin, ratelimitMOTD, ratelimitQuery);
|
httpServer, enableVoiceChat, ratelimitIp, ratelimitLogin, ratelimitMOTD, ratelimitQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final InetSocketAddress address;
|
private final InetSocketAddress address;
|
||||||
|
@ -166,9 +169,12 @@ public class EaglerListenerConfig {
|
||||||
private final List<String> serverMOTD;
|
private final List<String> serverMOTD;
|
||||||
private final boolean allowMOTD;
|
private final boolean allowMOTD;
|
||||||
private final boolean allowQuery;
|
private final boolean allowQuery;
|
||||||
|
private final int minMCProtocol;
|
||||||
|
private final int maxMCProtocol;
|
||||||
private final boolean allowV3;
|
private final boolean allowV3;
|
||||||
private final boolean allowV4;
|
private final boolean allowV4;
|
||||||
private final int defragSendDelay;
|
private final int defragSendDelay;
|
||||||
|
private final boolean haproxyProtocol;
|
||||||
private final MOTDCacheConfiguration motdCacheConfig;
|
private final MOTDCacheConfiguration motdCacheConfig;
|
||||||
private final HttpWebServer webServer;
|
private final HttpWebServer webServer;
|
||||||
private boolean serverIconSet = false;
|
private boolean serverIconSet = false;
|
||||||
|
@ -181,10 +187,11 @@ public class EaglerListenerConfig {
|
||||||
|
|
||||||
public EaglerListenerConfig(InetSocketAddress address, InetSocketAddress addressV6, int maxPlayer,
|
public EaglerListenerConfig(InetSocketAddress address, InetSocketAddress addressV6, int maxPlayer,
|
||||||
boolean forwardIp, String forwardIpHeader, String redirectLegacyClientsTo, String serverIcon,
|
boolean forwardIp, String forwardIpHeader, String redirectLegacyClientsTo, String serverIcon,
|
||||||
List<String> serverMOTD, boolean allowMOTD, boolean allowQuery, boolean allowV3, boolean allowV4,
|
List<String> serverMOTD, boolean allowMOTD, boolean allowQuery, int minMCProtocol, int maxMCProtocol,
|
||||||
int defragSendDelay, MOTDCacheConfiguration motdCacheConfig, HttpWebServer webServer,
|
boolean allowV3, boolean allowV4, int defragSendDelay, boolean haproxyProtocol,
|
||||||
boolean enableVoiceChat, EaglerRateLimiter ratelimitIp, EaglerRateLimiter ratelimitLogin,
|
MOTDCacheConfiguration motdCacheConfig, HttpWebServer webServer, boolean enableVoiceChat,
|
||||||
EaglerRateLimiter ratelimitMOTD, EaglerRateLimiter ratelimitQuery) {
|
EaglerRateLimiter ratelimitIp, EaglerRateLimiter ratelimitLogin, EaglerRateLimiter ratelimitMOTD,
|
||||||
|
EaglerRateLimiter ratelimitQuery) {
|
||||||
this.address = address;
|
this.address = address;
|
||||||
this.addressV6 = addressV6;
|
this.addressV6 = addressV6;
|
||||||
this.maxPlayer = maxPlayer;
|
this.maxPlayer = maxPlayer;
|
||||||
|
@ -195,9 +202,12 @@ public class EaglerListenerConfig {
|
||||||
this.serverMOTD = serverMOTD;
|
this.serverMOTD = serverMOTD;
|
||||||
this.allowMOTD = allowMOTD;
|
this.allowMOTD = allowMOTD;
|
||||||
this.allowQuery = allowQuery;
|
this.allowQuery = allowQuery;
|
||||||
|
this.minMCProtocol = minMCProtocol;
|
||||||
|
this.maxMCProtocol = maxMCProtocol;
|
||||||
this.allowV3 = allowV3;
|
this.allowV3 = allowV3;
|
||||||
this.allowV4 = allowV4;
|
this.allowV4 = allowV4;
|
||||||
this.defragSendDelay = defragSendDelay;
|
this.defragSendDelay = defragSendDelay;
|
||||||
|
this.haproxyProtocol = haproxyProtocol;
|
||||||
this.motdCacheConfig = motdCacheConfig;
|
this.motdCacheConfig = motdCacheConfig;
|
||||||
this.webServer = webServer;
|
this.webServer = webServer;
|
||||||
this.enableVoiceChat = enableVoiceChat;
|
this.enableVoiceChat = enableVoiceChat;
|
||||||
|
@ -261,6 +271,14 @@ public class EaglerListenerConfig {
|
||||||
return allowQuery;
|
return allowQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getMinMCProtocol() {
|
||||||
|
return minMCProtocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxMCProtocol() {
|
||||||
|
return maxMCProtocol;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isAllowV3() {
|
public boolean isAllowV3() {
|
||||||
return allowV3;
|
return allowV3;
|
||||||
}
|
}
|
||||||
|
@ -273,6 +291,10 @@ public class EaglerListenerConfig {
|
||||||
return defragSendDelay;
|
return defragSendDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isHAProxyProtocol() {
|
||||||
|
return haproxyProtocol;
|
||||||
|
}
|
||||||
|
|
||||||
public HttpWebServer getWebServer() {
|
public HttpWebServer getWebServer() {
|
||||||
return webServer;
|
return webServer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,15 @@ import com.velocitypowered.api.proxy.Player;
|
||||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||||
import com.velocitypowered.proxy.scheduler.VelocityScheduler;
|
import com.velocitypowered.proxy.scheduler.VelocityScheduler;
|
||||||
|
|
||||||
|
import io.netty.buffer.PooledByteBufAllocator;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
|
import io.netty.channel.ChannelException;
|
||||||
import io.netty.channel.ChannelInitializer;
|
import io.netty.channel.ChannelInitializer;
|
||||||
|
import io.netty.channel.ChannelOption;
|
||||||
import io.netty.channel.ChannelPipeline;
|
import io.netty.channel.ChannelPipeline;
|
||||||
import io.netty.channel.WriteBufferWaterMark;
|
import io.netty.channel.WriteBufferWaterMark;
|
||||||
import io.netty.handler.codec.compression.ZlibCodecFactory;
|
import io.netty.handler.codec.compression.ZlibCodecFactory;
|
||||||
|
import io.netty.handler.codec.haproxy.HAProxyMessageDecoder;
|
||||||
import io.netty.handler.codec.http.HttpObjectAggregator;
|
import io.netty.handler.codec.http.HttpObjectAggregator;
|
||||||
import io.netty.handler.codec.http.HttpServerCodec;
|
import io.netty.handler.codec.http.HttpServerCodec;
|
||||||
import io.netty.handler.codec.http.websocketx.PingWebSocketFrame;
|
import io.netty.handler.codec.http.websocketx.PingWebSocketFrame;
|
||||||
|
@ -211,7 +215,16 @@ public class EaglerPipeline {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initChannel(Channel channel) throws Exception {
|
protected void initChannel(Channel channel) throws Exception {
|
||||||
|
channel.config().setAllocator(PooledByteBufAllocator.DEFAULT).setWriteBufferWaterMark(SERVER_WRITE_MARK);
|
||||||
|
try {
|
||||||
|
channel.config().setOption(ChannelOption.IP_TOS, 24);
|
||||||
|
} catch (ChannelException var3) {
|
||||||
|
}
|
||||||
|
EaglerListenerConfig listener = channel.attr(LISTENER).get();
|
||||||
ChannelPipeline pipeline = channel.pipeline();
|
ChannelPipeline pipeline = channel.pipeline();
|
||||||
|
if(listener.isHAProxyProtocol()) {
|
||||||
|
pipeline.addLast("HAProxyMessageDecoder", new HAProxyMessageDecoder());
|
||||||
|
}
|
||||||
pipeline.addLast("HttpServerCodec", new HttpServerCodec());
|
pipeline.addLast("HttpServerCodec", new HttpServerCodec());
|
||||||
pipeline.addLast("HttpObjectAggregator", new HttpObjectAggregator(65535));
|
pipeline.addLast("HttpObjectAggregator", new HttpObjectAggregator(65535));
|
||||||
int compressionLevel = EaglerXVelocity.getEagler().getConfig().getHttpWebsocketCompressionLevel();
|
int compressionLevel = EaglerXVelocity.getEagler().getConfig().getHttpWebsocketCompressionLevel();
|
||||||
|
@ -227,7 +240,7 @@ public class EaglerPipeline {
|
||||||
pipeline.addLast("HttpCompressionHandler", new WebSocketServerExtensionHandler(deflateExtensionHandshaker,
|
pipeline.addLast("HttpCompressionHandler", new WebSocketServerExtensionHandler(deflateExtensionHandshaker,
|
||||||
perMessageDeflateExtensionHandshaker));
|
perMessageDeflateExtensionHandshaker));
|
||||||
}
|
}
|
||||||
pipeline.addLast("HttpHandshakeHandler", new HttpHandshakeHandler(channel.attr(LISTENER).get()));
|
pipeline.addLast("HttpHandshakeHandler", new HttpHandshakeHandler(listener));
|
||||||
channel.attr(CONNECTION_INSTANCE).set(new EaglerConnectionInstance(channel));
|
channel.attr(CONNECTION_INSTANCE).set(new EaglerConnectionInstance(channel));
|
||||||
synchronized(openChannels) {
|
synchronized(openChannels) {
|
||||||
openChannels.add(channel);
|
openChannels.add(channel);
|
||||||
|
|
|
@ -10,6 +10,7 @@ import io.netty.channel.ChannelFuture;
|
||||||
import io.netty.channel.ChannelFutureListener;
|
import io.netty.channel.ChannelFutureListener;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
|
import io.netty.handler.codec.haproxy.HAProxyMessage;
|
||||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||||
import io.netty.handler.codec.http.HttpHeaders;
|
import io.netty.handler.codec.http.HttpHeaders;
|
||||||
|
@ -48,6 +49,9 @@ public class HttpHandshakeHandler extends ChannelInboundHandlerAdapter {
|
||||||
private static final byte[] error429Bytes = "<h3>429 Too Many Requests<br /><small>(Try again later)</small></h3>".getBytes(StandardCharsets.UTF_8);
|
private static final byte[] error429Bytes = "<h3>429 Too Many Requests<br /><small>(Try again later)</small></h3>".getBytes(StandardCharsets.UTF_8);
|
||||||
|
|
||||||
private final EaglerListenerConfig conf;
|
private final EaglerListenerConfig conf;
|
||||||
|
private boolean logExceptions;
|
||||||
|
private boolean healthCheck;
|
||||||
|
private InetSocketAddress haproxyRemoteAddr;
|
||||||
|
|
||||||
public HttpHandshakeHandler(EaglerListenerConfig conf) {
|
public HttpHandshakeHandler(EaglerListenerConfig conf) {
|
||||||
this.conf = conf;
|
this.conf = conf;
|
||||||
|
@ -56,18 +60,31 @@ public class HttpHandshakeHandler extends ChannelInboundHandlerAdapter {
|
||||||
public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
|
public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||||
try {
|
try {
|
||||||
if (msg instanceof HttpRequest) {
|
if (msg instanceof HttpRequest) {
|
||||||
|
logExceptions = true;
|
||||||
EaglerConnectionInstance pingTracker = ctx.channel().attr(EaglerPipeline.CONNECTION_INSTANCE).get();
|
EaglerConnectionInstance pingTracker = ctx.channel().attr(EaglerPipeline.CONNECTION_INSTANCE).get();
|
||||||
HttpRequest req = (HttpRequest) msg;
|
HttpRequest req = (HttpRequest) msg;
|
||||||
HttpHeaders headers = req.headers();
|
HttpHeaders headers = req.headers();
|
||||||
|
|
||||||
String rateLimitHost = null;
|
String rateLimitHost = null;
|
||||||
|
|
||||||
|
SocketAddress addr;
|
||||||
if (conf.isForwardIp()) {
|
if (conf.isForwardIp()) {
|
||||||
String str = headers.get(conf.getForwardIpHeader());
|
String str = headers.get(conf.getForwardIpHeader());
|
||||||
if (str != null) {
|
if (str != null) {
|
||||||
rateLimitHost = str.split(",", 2)[0];
|
rateLimitHost = str.split(",", 2)[0];
|
||||||
try {
|
try {
|
||||||
ctx.channel().attr(EaglerPipeline.REAL_ADDRESS).set(InetAddress.getByName(rateLimitHost));
|
InetAddress inetAddr = InetAddress.getByName(rateLimitHost);
|
||||||
|
if(haproxyRemoteAddr != null) {
|
||||||
|
addr = new InetSocketAddress(inetAddr, haproxyRemoteAddr.getPort());
|
||||||
|
}else {
|
||||||
|
addr = ctx.channel().remoteAddress();
|
||||||
|
if(addr instanceof InetSocketAddress) {
|
||||||
|
addr = new InetSocketAddress(inetAddr, ((InetSocketAddress)addr).getPort());
|
||||||
|
}else {
|
||||||
|
addr = new InetSocketAddress(inetAddr, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.channel().attr(EaglerPipeline.REAL_ADDRESS).set(inetAddr);
|
||||||
} catch (UnknownHostException ex) {
|
} catch (UnknownHostException ex) {
|
||||||
EaglerXVelocity.logger().warn("[{}]: Connected with an invalid '{}' header, disconnecting...", ctx.channel().remoteAddress(), conf.getForwardIpHeader());
|
EaglerXVelocity.logger().warn("[{}]: Connected with an invalid '{}' header, disconnecting...", ctx.channel().remoteAddress(), conf.getForwardIpHeader());
|
||||||
ctx.close();
|
ctx.close();
|
||||||
|
@ -78,8 +95,11 @@ public class HttpHandshakeHandler extends ChannelInboundHandlerAdapter {
|
||||||
ctx.close();
|
ctx.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else if(haproxyRemoteAddr != null) {
|
||||||
|
addr = haproxyRemoteAddr;
|
||||||
|
ctx.channel().attr(EaglerPipeline.REAL_ADDRESS).set(haproxyRemoteAddr.getAddress());
|
||||||
} else {
|
} else {
|
||||||
SocketAddress addr = ctx.channel().remoteAddress();
|
addr = ctx.channel().remoteAddress();
|
||||||
if (addr instanceof InetSocketAddress) {
|
if (addr instanceof InetSocketAddress) {
|
||||||
rateLimitHost = ((InetSocketAddress) addr).getAddress().getHostAddress();
|
rateLimitHost = ((InetSocketAddress) addr).getAddress().getHostAddress();
|
||||||
}
|
}
|
||||||
|
@ -176,6 +196,19 @@ public class HttpHandshakeHandler extends ChannelInboundHandlerAdapter {
|
||||||
.addListener(ChannelFutureListener.CLOSE);
|
.addListener(ChannelFutureListener.CLOSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (msg instanceof HAProxyMessage) {
|
||||||
|
logExceptions = true;
|
||||||
|
HAProxyMessage proxy = (HAProxyMessage) msg;
|
||||||
|
if(proxy.sourceAddress() != null) {
|
||||||
|
if(!conf.isForwardIp()) {
|
||||||
|
try {
|
||||||
|
haproxyRemoteAddr = new InetSocketAddress(proxy.sourceAddress(), proxy.sourcePort());
|
||||||
|
}catch(IllegalArgumentException t) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
healthCheck = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ctx.close();
|
ctx.close();
|
||||||
}
|
}
|
||||||
|
@ -186,15 +219,13 @@ public class HttpHandshakeHandler extends ChannelInboundHandlerAdapter {
|
||||||
|
|
||||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||||
if (ctx.channel().isActive()) {
|
if (ctx.channel().isActive()) {
|
||||||
|
if(logExceptions && !healthCheck) {
|
||||||
EaglerXVelocity.logger().warn("[Pre][{}]: Exception Caught: {}", ctx.channel().remoteAddress(), cause.toString(), cause);
|
EaglerXVelocity.logger().warn("[Pre][{}]: Exception Caught: {}", ctx.channel().remoteAddress(), cause.toString(), cause);
|
||||||
|
}
|
||||||
ctx.close();
|
ctx.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String formatAddressFor404(String str) {
|
|
||||||
return "<span style=\"font-family:monospace;font-weight:bold;background-color:#EEEEEE;padding:3px 4px;\">" + str.replace("<", "<").replace(">", ">") + "</span>";
|
|
||||||
}
|
|
||||||
|
|
||||||
public void channelInactive(ChannelHandlerContext ctx) {
|
public void channelInactive(ChannelHandlerContext ctx) {
|
||||||
EaglerPipeline.closeChannel(ctx.channel());
|
EaglerPipeline.closeChannel(ctx.channel());
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.ChannelFutureListener;
|
import io.netty.channel.ChannelFutureListener;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
|
import io.netty.handler.codec.haproxy.HAProxyMessage;
|
||||||
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
|
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
|
||||||
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
|
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
|
||||||
import io.netty.handler.codec.http.websocketx.PingWebSocketFrame;
|
import io.netty.handler.codec.http.websocketx.PingWebSocketFrame;
|
||||||
|
@ -136,7 +137,9 @@ public abstract class HttpServerQueryHandler extends ChannelInboundHandlerAdapte
|
||||||
} else if (msg instanceof CloseWebSocketFrame) {
|
} else if (msg instanceof CloseWebSocketFrame) {
|
||||||
ctx.close();
|
ctx.close();
|
||||||
}
|
}
|
||||||
} else {
|
}else if(msg instanceof HAProxyMessage) {
|
||||||
|
EaglerXVelocity.logger().warn("[{}]: Ignoring HAProxyMessage because the WebSocket connection has already been established", ctx.channel().remoteAddress());
|
||||||
|
}else {
|
||||||
EaglerXVelocity.logger().error("Unexpected Packet: {}", msg.getClass().getSimpleName());
|
EaglerXVelocity.logger().error("Unexpected Packet: {}", msg.getClass().getSimpleName());
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -36,7 +36,6 @@ import com.velocitypowered.api.util.GameProfile;
|
||||||
import com.velocitypowered.api.util.GameProfile.Property;
|
import com.velocitypowered.api.util.GameProfile.Property;
|
||||||
import com.velocitypowered.proxy.VelocityServer;
|
import com.velocitypowered.proxy.VelocityServer;
|
||||||
import com.velocitypowered.proxy.config.PlayerInfoForwarding;
|
import com.velocitypowered.proxy.config.PlayerInfoForwarding;
|
||||||
import com.velocitypowered.proxy.connection.ConnectionType;
|
|
||||||
import com.velocitypowered.proxy.connection.ConnectionTypes;
|
import com.velocitypowered.proxy.connection.ConnectionTypes;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||||
import com.velocitypowered.proxy.connection.client.*;
|
import com.velocitypowered.proxy.connection.client.*;
|
||||||
|
@ -53,6 +52,7 @@ import io.netty.channel.ChannelFutureListener;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
import io.netty.channel.ChannelPipeline;
|
import io.netty.channel.ChannelPipeline;
|
||||||
|
import io.netty.handler.codec.haproxy.HAProxyMessage;
|
||||||
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
|
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
|
||||||
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
|
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
|
||||||
import io.netty.handler.codec.http.websocketx.PingWebSocketFrame;
|
import io.netty.handler.codec.http.websocketx.PingWebSocketFrame;
|
||||||
|
@ -203,7 +203,9 @@ public class HttpWebSocketHandler extends ChannelInboundHandlerAdapter {
|
||||||
} else if (msg instanceof CloseWebSocketFrame) {
|
} else if (msg instanceof CloseWebSocketFrame) {
|
||||||
ctx.close();
|
ctx.close();
|
||||||
}
|
}
|
||||||
} else {
|
}else if(msg instanceof HAProxyMessage) {
|
||||||
|
EaglerXVelocity.logger().warn("[{}]: Ignoring HAProxyMessage because the WebSocket connection has already been established", ctx.channel().remoteAddress());
|
||||||
|
}else {
|
||||||
EaglerXVelocity.logger().error("Unexpected Packet: {}", msg.getClass().getSimpleName());
|
EaglerXVelocity.logger().error("Unexpected Packet: {}", msg.getClass().getSimpleName());
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -312,8 +314,6 @@ public class HttpWebSocketHandler extends ChannelInboundHandlerAdapter {
|
||||||
EaglerXVelocity eaglerXBungee = EaglerXVelocity.getEagler();
|
EaglerXVelocity eaglerXBungee = EaglerXVelocity.getEagler();
|
||||||
EaglerAuthConfig authConfig = eaglerXBungee.getConfig().getAuthConfig();
|
EaglerAuthConfig authConfig = eaglerXBungee.getConfig().getAuthConfig();
|
||||||
|
|
||||||
final int minecraftProtocolVersion = 47;
|
|
||||||
|
|
||||||
int eaglerLegacyProtocolVersion = buffer.readUnsignedByte();
|
int eaglerLegacyProtocolVersion = buffer.readUnsignedByte();
|
||||||
|
|
||||||
if(eaglerLegacyProtocolVersion == 1) {
|
if(eaglerLegacyProtocolVersion == 1) {
|
||||||
|
@ -321,7 +321,8 @@ public class HttpWebSocketHandler extends ChannelInboundHandlerAdapter {
|
||||||
sendErrorCode(ctx, HandshakePacketTypes.SERVER_ERROR_CUSTOM_MESSAGE, "Please update your client to register on this server!")
|
sendErrorCode(ctx, HandshakePacketTypes.SERVER_ERROR_CUSTOM_MESSAGE, "Please update your client to register on this server!")
|
||||||
.addListener(ChannelFutureListener.CLOSE);
|
.addListener(ChannelFutureListener.CLOSE);
|
||||||
return;
|
return;
|
||||||
}else if(buffer.readUnsignedByte() != minecraftProtocolVersion || !conf.isAllowV3()) {
|
} else if (buffer.readUnsignedByte() != 47 || 47 < conf.getMinMCProtocol()
|
||||||
|
|| 47 > conf.getMaxMCProtocol() || !conf.isAllowV3()) {
|
||||||
clientLoginState = HandshakePacketTypes.STATE_CLIENT_COMPLETE;
|
clientLoginState = HandshakePacketTypes.STATE_CLIENT_COMPLETE;
|
||||||
connectionClosed = true;
|
connectionClosed = true;
|
||||||
ByteBuf buf = ctx.alloc().buffer();
|
ByteBuf buf = ctx.alloc().buffer();
|
||||||
|
@ -341,8 +342,7 @@ public class HttpWebSocketHandler extends ChannelInboundHandlerAdapter {
|
||||||
int maxServerSupported = conf.isAllowV4() ? 4 : 3;
|
int maxServerSupported = conf.isAllowV4() ? 4 : 3;
|
||||||
int minAvailableProtVers = Integer.MAX_VALUE;
|
int minAvailableProtVers = Integer.MAX_VALUE;
|
||||||
int maxAvailableProtVers = Integer.MIN_VALUE;
|
int maxAvailableProtVers = Integer.MIN_VALUE;
|
||||||
int minSupportedProtVers = Integer.MAX_VALUE;
|
int protVers = -1;
|
||||||
int maxSupportedProtVers = Integer.MIN_VALUE;
|
|
||||||
|
|
||||||
int cnt = buffer.readUnsignedShort();
|
int cnt = buffer.readUnsignedShort();
|
||||||
for(int i = 0; i < cnt; ++i) {
|
for(int i = 0; i < cnt; ++i) {
|
||||||
|
@ -353,53 +353,52 @@ public class HttpWebSocketHandler extends ChannelInboundHandlerAdapter {
|
||||||
if(j < minAvailableProtVers) {
|
if(j < minAvailableProtVers) {
|
||||||
minAvailableProtVers = j;
|
minAvailableProtVers = j;
|
||||||
}
|
}
|
||||||
if(j >= minServerSupported && j <= maxServerSupported) {
|
if(j >= minServerSupported && j <= maxServerSupported && j > protVers) {
|
||||||
if(j > maxSupportedProtVers) {
|
protVers = j;
|
||||||
maxSupportedProtVers = j;
|
|
||||||
}
|
|
||||||
if(j < minSupportedProtVers) {
|
|
||||||
minSupportedProtVers = j;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int minGameVers = Integer.MAX_VALUE;
|
int minGameVers = conf.getMinMCProtocol();
|
||||||
int maxGameVers = -1;
|
int maxGameVers = conf.getMaxMCProtocol();
|
||||||
boolean has47InList = false;
|
int minAvailableGameVers = Integer.MAX_VALUE;
|
||||||
|
int maxAvailableGameVers = Integer.MIN_VALUE;
|
||||||
|
int gameVers = -1;
|
||||||
|
|
||||||
cnt = buffer.readUnsignedShort();
|
cnt = buffer.readUnsignedShort();
|
||||||
for(int i = 0; i < cnt; ++i) {
|
for(int i = 0; i < cnt; ++i) {
|
||||||
int j = buffer.readUnsignedShort();
|
int j = buffer.readUnsignedShort();
|
||||||
if(j == minecraftProtocolVersion) {
|
if(j > maxAvailableGameVers) {
|
||||||
has47InList = true;
|
maxAvailableGameVers = j;
|
||||||
}
|
}
|
||||||
if(j > maxGameVers) {
|
if(j < minAvailableGameVers) {
|
||||||
maxGameVers = j;
|
minAvailableGameVers = j;
|
||||||
}
|
}
|
||||||
if(j < minGameVers) {
|
if(j >= minGameVers && j <= maxGameVers && j > gameVers) {
|
||||||
minGameVers = j;
|
gameVers = j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(maxAvailableProtVers == Integer.MIN_VALUE || maxGameVers == Integer.MIN_VALUE) {
|
if(maxAvailableProtVers == Integer.MIN_VALUE || maxAvailableGameVers == Integer.MIN_VALUE) {
|
||||||
throw new IOException();
|
throw new IOException();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean versMisMatch = false;
|
boolean versMisMatch = false;
|
||||||
boolean isServerProbablyOutdated = false;
|
boolean isServerProbablyOutdated = false;
|
||||||
boolean isClientProbablyOutdated = false;
|
boolean isClientProbablyOutdated = false;
|
||||||
if(maxSupportedProtVers == Integer.MIN_VALUE) {
|
if(protVers == -1) {
|
||||||
clientProtocolVersion = maxAvailableProtVers < 3 ? 2 : 3;
|
clientProtocolVersion = maxAvailableProtVers < 3 ? 2 : 3;
|
||||||
versMisMatch = true;
|
versMisMatch = true;
|
||||||
isServerProbablyOutdated = minAvailableProtVers > maxServerSupported && maxAvailableProtVers > maxServerSupported;
|
isServerProbablyOutdated = minAvailableProtVers > maxServerSupported && maxAvailableProtVers > maxServerSupported;
|
||||||
isClientProbablyOutdated = minAvailableProtVers < minServerSupported && maxAvailableProtVers < minServerSupported;
|
isClientProbablyOutdated = minAvailableProtVers < minServerSupported && maxAvailableProtVers < minServerSupported;
|
||||||
}else if(!has47InList) {
|
|
||||||
clientProtocolVersion = 3;
|
|
||||||
versMisMatch = true;
|
|
||||||
isServerProbablyOutdated = minGameVers > minecraftProtocolVersion && maxGameVers > minecraftProtocolVersion;
|
|
||||||
isClientProbablyOutdated = minGameVers < minecraftProtocolVersion && maxGameVers < minecraftProtocolVersion;
|
|
||||||
}else {
|
}else {
|
||||||
clientProtocolVersion = maxSupportedProtVers;
|
clientProtocolVersion = protVers;
|
||||||
|
if(gameVers == -1) {
|
||||||
|
versMisMatch = true;
|
||||||
|
isServerProbablyOutdated = minAvailableGameVers > maxGameVers && maxAvailableGameVers > maxGameVers;
|
||||||
|
isClientProbablyOutdated = minAvailableGameVers < minGameVers && maxAvailableGameVers < minGameVers;
|
||||||
|
}else {
|
||||||
|
gameProtocolVersion = gameVers;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(versMisMatch) {
|
if(versMisMatch) {
|
||||||
|
@ -417,8 +416,9 @@ public class HttpWebSocketHandler extends ChannelInboundHandlerAdapter {
|
||||||
buf.writeShort(4);
|
buf.writeShort(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
buf.writeShort(1);
|
buf.writeShort(2);
|
||||||
buf.writeShort(minecraftProtocolVersion); // want game version 47
|
buf.writeShort(minGameVers);
|
||||||
|
buf.writeShort(maxGameVers);
|
||||||
|
|
||||||
String str = isClientProbablyOutdated ? "Outdated Client" : (isServerProbablyOutdated ? "Outdated Server" : "Unsupported Client Version");
|
String str = isClientProbablyOutdated ? "Outdated Client" : (isServerProbablyOutdated ? "Outdated Server" : "Unsupported Client Version");
|
||||||
buf.writeByte(str.length());
|
buf.writeByte(str.length());
|
||||||
|
@ -450,6 +450,7 @@ public class HttpWebSocketHandler extends ChannelInboundHandlerAdapter {
|
||||||
boolean useSnapshotFallbackProtocol = false;
|
boolean useSnapshotFallbackProtocol = false;
|
||||||
if(eaglerLegacyProtocolVersion == 1 && !authConfig.isEnableAuthentication()) {
|
if(eaglerLegacyProtocolVersion == 1 && !authConfig.isEnableAuthentication()) {
|
||||||
clientProtocolVersion = 2;
|
clientProtocolVersion = 2;
|
||||||
|
gameProtocolVersion = 47;
|
||||||
useSnapshotFallbackProtocol = true;
|
useSnapshotFallbackProtocol = true;
|
||||||
clientAuth = false;
|
clientAuth = false;
|
||||||
clientAuthUsername = null;
|
clientAuthUsername = null;
|
||||||
|
@ -481,7 +482,6 @@ public class HttpWebSocketHandler extends ChannelInboundHandlerAdapter {
|
||||||
final boolean final_useSnapshotFallbackProtocol = useSnapshotFallbackProtocol;
|
final boolean final_useSnapshotFallbackProtocol = useSnapshotFallbackProtocol;
|
||||||
Runnable continueThread = () -> {
|
Runnable continueThread = () -> {
|
||||||
clientLoginState = HandshakePacketTypes.STATE_CLIENT_VERSION;
|
clientLoginState = HandshakePacketTypes.STATE_CLIENT_VERSION;
|
||||||
gameProtocolVersion = 47;
|
|
||||||
clientBrandString = eaglerBrand;
|
clientBrandString = eaglerBrand;
|
||||||
clientVersionString = eaglerVersionString;
|
clientVersionString = eaglerVersionString;
|
||||||
|
|
||||||
|
@ -492,7 +492,7 @@ public class HttpWebSocketHandler extends ChannelInboundHandlerAdapter {
|
||||||
buf.writeByte(1);
|
buf.writeByte(1);
|
||||||
}else {
|
}else {
|
||||||
buf.writeShort(clientProtocolVersion);
|
buf.writeShort(clientProtocolVersion);
|
||||||
buf.writeShort(minecraftProtocolVersion);
|
buf.writeShort(gameProtocolVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
String brandStr = EaglerXVelocityVersion.NAME;
|
String brandStr = EaglerXVelocityVersion.NAME;
|
||||||
|
|
|
@ -27,7 +27,6 @@ import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.server.SPac
|
||||||
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.server.SPacketRPCEventWebViewOpenClose;
|
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.server.SPacketRPCEventWebViewOpenClose;
|
||||||
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.EaglerXVelocity;
|
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.EaglerXVelocity;
|
||||||
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.api.EnumVoiceState;
|
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.api.EnumVoiceState;
|
||||||
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.api.event.EaglercraftVoiceStatusChangeEvent;
|
|
||||||
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.server.EaglerPlayerData;
|
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.server.EaglerPlayerData;
|
||||||
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.voice.VoiceService;
|
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.voice.VoiceService;
|
||||||
import net.lax1dude.eaglercraft.v1_8.socket.protocol.util.ReusableByteArrayInputStream;
|
import net.lax1dude.eaglercraft.v1_8.socket.protocol.util.ReusableByteArrayInputStream;
|
||||||
|
|
|
@ -5,9 +5,10 @@ import com.google.gson.JsonObject;
|
||||||
|
|
||||||
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.EaglerXVelocity;
|
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.EaglerXVelocity;
|
||||||
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.api.query.EaglerQuerySimpleHandler;
|
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.api.query.EaglerQuerySimpleHandler;
|
||||||
|
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.config.EaglerListenerConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2022-2023 lax1dude. All Rights Reserved.
|
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
@ -27,20 +28,19 @@ public class VersionQueryHandler extends EaglerQuerySimpleHandler {
|
||||||
protected void begin(String queryType) {
|
protected void begin(String queryType) {
|
||||||
JsonObject responseObj = new JsonObject();
|
JsonObject responseObj = new JsonObject();
|
||||||
JsonArray handshakeVersions = new JsonArray();
|
JsonArray handshakeVersions = new JsonArray();
|
||||||
if(this.getListener().isAllowV3()) {
|
EaglerListenerConfig cfg = this.getListener();
|
||||||
|
if(cfg.isAllowV3()) {
|
||||||
handshakeVersions.add(2);
|
handshakeVersions.add(2);
|
||||||
handshakeVersions.add(3);
|
handshakeVersions.add(3);
|
||||||
}
|
}
|
||||||
if(this.getListener().isAllowV4()) {
|
if(cfg.isAllowV4()) {
|
||||||
handshakeVersions.add(4);
|
handshakeVersions.add(4);
|
||||||
}
|
}
|
||||||
responseObj.add("handshakeVersions", handshakeVersions);
|
responseObj.add("handshakeVersions", handshakeVersions);
|
||||||
JsonArray protocolVersions = new JsonArray();
|
JsonObject protocolVersions = new JsonObject();
|
||||||
protocolVersions.add(47);
|
protocolVersions.addProperty("min", cfg.getMinMCProtocol());
|
||||||
|
protocolVersions.addProperty("max", cfg.getMaxMCProtocol());
|
||||||
responseObj.add("protocolVersions", protocolVersions);
|
responseObj.add("protocolVersions", protocolVersions);
|
||||||
JsonArray gameVersions = new JsonArray();
|
|
||||||
gameVersions.add("1.8");
|
|
||||||
responseObj.add("gameVersions", gameVersions);
|
|
||||||
JsonObject proxyInfo = new JsonObject();
|
JsonObject proxyInfo = new JsonObject();
|
||||||
proxyInfo.addProperty("brand", EaglerXVelocity.proxy().getVersion().getName());
|
proxyInfo.addProperty("brand", EaglerXVelocity.proxy().getVersion().getName());
|
||||||
proxyInfo.addProperty("vers", EaglerXVelocity.proxy().getVersion().getVersion());
|
proxyInfo.addProperty("vers", EaglerXVelocity.proxy().getVersion().getVersion());
|
||||||
|
|
|
@ -10,9 +10,12 @@ listener_01:
|
||||||
- '&6An EaglercraftX server'
|
- '&6An EaglercraftX server'
|
||||||
allow_motd: true
|
allow_motd: true
|
||||||
allow_query: true
|
allow_query: true
|
||||||
|
min_minecraft_protocol: 47
|
||||||
|
max_minecraft_protocol: 340
|
||||||
allow_protocol_v3: true
|
allow_protocol_v3: true
|
||||||
allow_protocol_v4: true
|
allow_protocol_v4: true
|
||||||
protocol_v4_defrag_send_delay: 10
|
protocol_v4_defrag_send_delay: 10
|
||||||
|
use_haproxy_protocol: false
|
||||||
allow_cookie_revoke_query: true
|
allow_cookie_revoke_query: true
|
||||||
request_motd_cache:
|
request_motd_cache:
|
||||||
cache_ttl: 7200
|
cache_ttl: 7200
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"id":"eaglerxvelocity","name":"EaglercraftXVelocity","version":"1.1.3","description":"Plugin to allow EaglercraftX 1.8 players to join your network, or allow EaglercraftX 1.8 players to use your network as a proxy to join other networks","authors":["lax1dude", "ayunami2000"],"dependencies":[],"main":"net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.EaglerXVelocity"}
|
{"id":"eaglerxvelocity","name":"EaglercraftXVelocity","version":"1.1.4","description":"Plugin to allow EaglercraftX 1.8 players to join your network, or allow EaglercraftX 1.8 players to use your network as a proxy to join other networks","authors":["lax1dude", "ayunami2000"],"dependencies":[],"main":"net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.EaglerXVelocity"}
|
|
@ -1 +1 @@
|
||||||
1.1.3
|
1.1.4
|
Loading…
Reference in New Issue
Block a user