From 001d20c7757db013331a9b0c1e359da825699208 Mon Sep 17 00:00:00 2001 From: Dawid Sawicki <44551064+dasavick@users.noreply.github.com> Date: Fri, 5 Jul 2024 02:22:39 +0200 Subject: [PATCH] Allow to customize ping events priority via handle-motd-order (#108) Currently, the bungee implementation is using NORMAL priority for the ping event handler, while the velocity implementation is using LAST. Regardless of which choice may be the better one, this is an inconsistency that this patch addresses by using NORMAL as the default for both platforms. Additionally to addressing the inconsistency, this patch adds a new config option `handle-motd-order` which uses velocity's event priority nomenclature to allow configuring the behavior of the MOTD handling on both platforms. In cases where there is a MOTD plugin that incorrectly overrides a player count using the local player count, one may choose to use order LAST to override the value back to the global player count. In cases where there is a MOTD plugin that relies on a player count value from the ping response, one may choose to use order FIRST to make sure the response will have the correct global player count. Fixes https://github.com/ProxioDev/ValioBungee/issues/107 --- .../api/config/HandleMotdOrder.java | 17 +++++++++++ .../api/config/RedisBungeeConfiguration.java | 8 ++++- .../api/config/loaders/ConfigLoader.java | 14 ++++++++- api/src/main/resources/config.yml | 7 +++++ .../redisbungee/RedisBungeeListener.java | 30 +++++++++++++++++-- .../redisbungee/RedisBungeeListener.java | 28 +++++++++++++++-- 6 files changed, 97 insertions(+), 7 deletions(-) create mode 100644 api/src/main/java/com/imaginarycode/minecraft/redisbungee/api/config/HandleMotdOrder.java diff --git a/api/src/main/java/com/imaginarycode/minecraft/redisbungee/api/config/HandleMotdOrder.java b/api/src/main/java/com/imaginarycode/minecraft/redisbungee/api/config/HandleMotdOrder.java new file mode 100644 index 0000000..07b7f21 --- /dev/null +++ b/api/src/main/java/com/imaginarycode/minecraft/redisbungee/api/config/HandleMotdOrder.java @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2013-present RedisBungee contributors + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * + * http://www.eclipse.org/legal/epl-v10.html + */ + +package com.imaginarycode.minecraft.redisbungee.api.config; + +public enum HandleMotdOrder { + FIRST, + NORMAL, + LAST +} diff --git a/api/src/main/java/com/imaginarycode/minecraft/redisbungee/api/config/RedisBungeeConfiguration.java b/api/src/main/java/com/imaginarycode/minecraft/redisbungee/api/config/RedisBungeeConfiguration.java index f76fb39..4a27b40 100644 --- a/api/src/main/java/com/imaginarycode/minecraft/redisbungee/api/config/RedisBungeeConfiguration.java +++ b/api/src/main/java/com/imaginarycode/minecraft/redisbungee/api/config/RedisBungeeConfiguration.java @@ -25,12 +25,13 @@ public class RedisBungeeConfiguration { private final boolean handleReconnectToLastServer; private final boolean handleMotd; + private final HandleMotdOrder handleMotdOrder; private final CommandsConfiguration commandsConfiguration; private final String networkId; - public RedisBungeeConfiguration(String networkId, String proxyId, List exemptAddresses, boolean kickWhenOnline, boolean handleReconnectToLastServer, boolean handleMotd, CommandsConfiguration commandsConfiguration) { + public RedisBungeeConfiguration(String networkId, String proxyId, List exemptAddresses, boolean kickWhenOnline, boolean handleReconnectToLastServer, boolean handleMotd, HandleMotdOrder handleMotdOrder, CommandsConfiguration commandsConfiguration) { this.proxyId = proxyId; ImmutableList.Builder addressBuilder = ImmutableList.builder(); for (String s : exemptAddresses) { @@ -40,6 +41,7 @@ public class RedisBungeeConfiguration { this.kickWhenOnline = kickWhenOnline; this.handleReconnectToLastServer = handleReconnectToLastServer; this.handleMotd = handleMotd; + this.handleMotdOrder = handleMotdOrder; this.commandsConfiguration = commandsConfiguration; this.networkId = networkId; } @@ -60,6 +62,10 @@ public class RedisBungeeConfiguration { return this.handleMotd; } + public HandleMotdOrder handleMotdOrder() { + return handleMotdOrder; + } + public boolean handleReconnectToLastServer() { return this.handleReconnectToLastServer; } diff --git a/api/src/main/java/com/imaginarycode/minecraft/redisbungee/api/config/loaders/ConfigLoader.java b/api/src/main/java/com/imaginarycode/minecraft/redisbungee/api/config/loaders/ConfigLoader.java index a73b6ef..415b43a 100644 --- a/api/src/main/java/com/imaginarycode/minecraft/redisbungee/api/config/loaders/ConfigLoader.java +++ b/api/src/main/java/com/imaginarycode/minecraft/redisbungee/api/config/loaders/ConfigLoader.java @@ -14,6 +14,7 @@ package com.imaginarycode.minecraft.redisbungee.api.config.loaders; import com.google.common.reflect.TypeToken; import com.imaginarycode.minecraft.redisbungee.api.RedisBungeeMode; import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin; +import com.imaginarycode.minecraft.redisbungee.api.config.HandleMotdOrder; import com.imaginarycode.minecraft.redisbungee.api.config.RedisBungeeConfiguration; import com.imaginarycode.minecraft.redisbungee.api.summoners.JedisClusterSummoner; import com.imaginarycode.minecraft.redisbungee.api.summoners.JedisPooledSummoner; @@ -104,6 +105,16 @@ public interface ConfigLoader extends GenericConfigLoader { plugin.logInfo("handle reconnect to last server: {}", reconnectToLastServer); plugin.logInfo("handle motd: {}", handleMotd); + HandleMotdOrder handleMotdOrder = HandleMotdOrder.NORMAL; + String handleMotdOrderName = node.getNode("handle-motd-priority").getString(); + if (handleMotdOrderName != null) { + try { + handleMotdOrder = HandleMotdOrder.valueOf(handleMotdOrderName.toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException e) { + plugin.logWarn("handle motd order value '{}' is unsupported (allowed: {})", handleMotdOrderName, HandleMotdOrder.values()); + } + } + plugin.logInfo("handle motd order: {}", handleMotdOrder); // commands boolean redisBungeeEnabled = node.getNode("commands", "redisbungee", "enabled").getBoolean(true); @@ -130,7 +141,8 @@ public interface ConfigLoader extends GenericConfigLoader { boolean installPlist = node.getNode("commands", "redisbungee-legacy", "subcommands", "plist", "install").getBoolean(false); - RedisBungeeConfiguration configuration = new RedisBungeeConfiguration(networkId, proxyId, exemptAddresses, kickWhenOnline, reconnectToLastServer, handleMotd, new RedisBungeeConfiguration.CommandsConfiguration( + RedisBungeeConfiguration configuration = new RedisBungeeConfiguration(networkId, proxyId, exemptAddresses, kickWhenOnline, reconnectToLastServer, handleMotd, handleMotdOrder, + new RedisBungeeConfiguration.CommandsConfiguration( redisBungeeEnabled, redisBungeeLegacyEnabled, new RedisBungeeConfiguration.LegacySubCommandsConfiguration( findEnabled, glistEnabled, ipEnabled, diff --git a/api/src/main/resources/config.yml b/api/src/main/resources/config.yml index 786efd9..b69b5ee 100644 --- a/api/src/main/resources/config.yml +++ b/api/src/main/resources/config.yml @@ -77,6 +77,13 @@ kick-when-online: true # you can disable this when you want to handle motd yourself, use RedisBungee api to get total players when needed :) handle-motd: true +# MOTD plugins compatibility setting +# Allowed values: FIRST, NORMAL, LAST +# This option enables RedisBungee to manage various interactions between other plugins and the online player count, +# which is dynamically updated to a global player count in ping responses if the handle-motd option is enabled. +# If you encounter issues with other plugins accessing or modifying the player count, try using a value of FIRST or LAST. +handle-motd-order: NORMAL + # A list of IP addresses for which RedisBungee will not modify the response for, useful for automatic # restart scripts. # Automatically disabled if handle-motd is disabled. diff --git a/proxies/bungeecord/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeListener.java b/proxies/bungeecord/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeListener.java index b5c401f..39d8083 100644 --- a/proxies/bungeecord/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeListener.java +++ b/proxies/bungeecord/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeListener.java @@ -17,7 +17,7 @@ import com.google.common.io.ByteArrayDataInput; import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin; -import net.kyori.adventure.text.Component; +import com.imaginarycode.minecraft.redisbungee.api.config.HandleMotdOrder; import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer; import net.md_5.bungee.api.AbstractReconnectHandler; import net.md_5.bungee.api.ProxyServer; @@ -29,6 +29,7 @@ import net.md_5.bungee.api.event.ProxyPingEvent; import net.md_5.bungee.api.event.ServerConnectEvent; import net.md_5.bungee.api.plugin.Listener; import net.md_5.bungee.event.EventHandler; +import net.md_5.bungee.event.EventPriority; import java.util.*; @@ -42,8 +43,31 @@ public class RedisBungeeListener implements Listener { this.plugin = plugin; } - @EventHandler - public void onPing(ProxyPingEvent event) { + @EventHandler(priority = EventPriority.LOWEST) + private void onPingFirst(ProxyPingEvent event) { + if (plugin.configuration().handleMotdOrder() != HandleMotdOrder.FIRST) { + return; + } + onPing0(event); + } + + @EventHandler(priority = EventPriority.NORMAL) + private void onPingNormal(ProxyPingEvent event) { + if (plugin.configuration().handleMotdOrder() != HandleMotdOrder.NORMAL) { + return; + } + onPing0(event); + } + + @EventHandler(priority = EventPriority.HIGHEST) + private void onPingLast(ProxyPingEvent event) { + if (plugin.configuration().handleMotdOrder() != HandleMotdOrder.LAST) { + return; + } + onPing0(event); + } + + private void onPing0(ProxyPingEvent event) { if (!plugin.configuration().handleMotd()) return; if (plugin.configuration().getExemptAddresses().contains(event.getConnection().getAddress().getAddress())) return; ServerInfo forced = AbstractReconnectHandler.getForcedHost(event.getConnection()); diff --git a/proxies/velocity/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeListener.java b/proxies/velocity/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeListener.java index b0ac059..c94e0c2 100644 --- a/proxies/velocity/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeListener.java +++ b/proxies/velocity/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeListener.java @@ -17,6 +17,7 @@ import com.google.common.io.ByteArrayDataInput; import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin; +import com.imaginarycode.minecraft.redisbungee.api.config.HandleMotdOrder; import com.velocitypowered.api.event.PostOrder; import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.connection.PluginMessageEvent; @@ -41,8 +42,31 @@ public class RedisBungeeListener { this.plugin = plugin; } - @Subscribe(order = PostOrder.LAST) // some plugins changes it online players so we need to be executed as last - public void onPing(ProxyPingEvent event) { + @Subscribe(order = PostOrder.FIRST) + public void onPingFirst(ProxyPingEvent event) { + if (plugin.configuration().handleMotdOrder() != HandleMotdOrder.FIRST) { + return; + } + onPing0(event); + } + + @Subscribe(order = PostOrder.NORMAL) + public void onPingNormal(ProxyPingEvent event) { + if (plugin.configuration().handleMotdOrder() != HandleMotdOrder.NORMAL) { + return; + } + onPing0(event); + } + + @Subscribe(order = PostOrder.LAST) + public void onPingLast(ProxyPingEvent event) { + if (plugin.configuration().handleMotdOrder() != HandleMotdOrder.LAST) { + return; + } + onPing0(event); + } + + private void onPing0(ProxyPingEvent event) { if (!plugin.configuration().handleMotd()) return; if (plugin.configuration().getExemptAddresses().contains(event.getConnection().getRemoteAddress().getAddress())) return;