Skip to content

Commit

Permalink
bungee: Stupid hacks to workaround Travertine issues with <=1.8 clients
Browse files Browse the repository at this point in the history
  • Loading branch information
jpenilla committed Mar 28, 2021
1 parent b44070b commit 71f6531
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,23 @@
*/
package xyz.jpenilla.minimotd.bungee;

import com.google.gson.Gson;
import net.kyori.adventure.platform.bungeecord.BungeeAudiences;
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
import net.md_5.bungee.api.Favicon;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.plugin.Plugin;
import org.bstats.bungeecord.Metrics;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import xyz.jpenilla.minimotd.common.MiniMOTD;
import xyz.jpenilla.minimotd.common.MiniMOTDPlatform;
import xyz.jpenilla.minimotd.common.UpdateChecker;

import java.awt.image.BufferedImage;
import java.lang.reflect.Field;
import java.nio.file.Path;

public class MiniMOTDPlugin extends Plugin implements MiniMOTDPlatform<Favicon> {
Expand All @@ -52,13 +57,14 @@ public void onEnable() {
this.miniMOTD = new MiniMOTD<>(this);
this.miniMOTD.configManager().loadExtraConfigs();
this.audiences = BungeeAudiences.create(this);
this.injectTravertineGson();
this.getProxy().getPluginManager().registerListener(this, new PingListener(this.miniMOTD));
this.getProxy().getPluginManager().registerCommand(this, new BungeeCommand(this));
final Metrics metrics = new Metrics(this, 8137);

if (this.miniMOTD.configManager().pluginSettings().updateChecker()) {
this.getProxy().getScheduler().runAsync(this, () ->
new UpdateChecker().checkVersion().forEach(getLogger()::info));
new UpdateChecker().checkVersion().forEach(this.logger::info));
}
}

Expand All @@ -85,4 +91,23 @@ public void onEnable() {
public void onReload() {
this.miniMOTD.configManager().loadExtraConfigs();
}

private void injectTravertineGson() {
final Field gsonLegacyField = findDeclaredField(ProxyServer.getInstance().getClass(), "gsonLegacy");
if (gsonLegacyField != null) {
try {
BungeeComponentSerializer.inject((Gson) gsonLegacyField.get(ProxyServer.getInstance()));
} catch (final IllegalAccessException ex) {
this.miniMOTD.logger().warn("Failed to inject into Travertine's gsonLegacy gson instance. There will likely be issues with 1.7.x clients.", ex);
}
}
}

private static @Nullable Field findDeclaredField(final @NonNull Class<?> holder, final @NonNull String name) {
try {
return holder.getDeclaredField(name);
} catch (final NoSuchFieldException ex) {
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,12 @@
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
import net.md_5.bungee.api.Favicon;
import net.md_5.bungee.api.ServerPing;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.event.ProxyPingEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.event.EventHandler;
import net.md_5.bungee.event.EventPriority;
import org.checkerframework.checker.nullness.qual.NonNull;
import xyz.jpenilla.minimotd.common.ComponentColorDownsampler;
import xyz.jpenilla.minimotd.common.Constants;
import xyz.jpenilla.minimotd.common.MOTDIconPair;
import xyz.jpenilla.minimotd.common.MiniMOTD;
Expand All @@ -48,7 +47,7 @@ public PingListener(final @NonNull MiniMOTD<Favicon> miniMOTD) {
this.miniMOTD = miniMOTD;
}

@EventHandler(priority = EventPriority.LOWEST)
@EventHandler
public void onPing(final @NonNull ProxyPingEvent e) {
final ServerPing response = e.getResponse();
if (response == null) {
Expand Down Expand Up @@ -77,12 +76,19 @@ public void onPing(final @NonNull ProxyPingEvent e) {

final MOTDIconPair<Favicon> pair = this.miniMOTD.createMOTD(cfg, onlinePlayers, maxPlayers);

Component motdComponent = pair.motd();
final Component motdComponent = pair.motd();
if (motdComponent != null) {
final BaseComponent[] bungee;
if (e.getConnection().getVersion() < Constants.MINECRAFT_1_16_PROTOCOL_VERSION) {
motdComponent = ComponentColorDownsampler.downsampler().downsample(motdComponent);
bungee = BungeeComponentSerializer.legacy().serialize(motdComponent);
} else {
bungee = BungeeComponentSerializer.get().serialize(motdComponent);
}
if (BungeeComponentSerializer.isNative()) {
response.setDescriptionComponent(bungee[0]);
} else {
response.setDescriptionComponent(new TextComponent(bungee));
}
response.setDescriptionComponent(new TextComponent(BungeeComponentSerializer.get().serialize(motdComponent)));
}

final Favicon favicon = pair.icon();
Expand Down
6 changes: 6 additions & 0 deletions common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ plugins {
id("net.kyori.blossom")
}

tasks.jar {
from(rootProject.file("license.txt")) {
rename { "license_${rootProject.name.toLowerCase()}.txt" }
}
}

dependencies {
api("org.slf4j", "slf4j-api", "1.7.30")
api("org.spongepowered", "configurate-hocon", "4.1.0-SNAPSHOT")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -111,7 +112,7 @@ private void createDefaultExtraConfigs(final @NonNull Path extraConfigsDir) thro
MiniMOTDConfig.class,
pair.left()
);
loader.save(new MiniMOTDConfig(ImmutableList.of(pair.right())));
loader.save(new MiniMOTDConfig(Collections.singletonList(pair.right())));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import net.fabricmc.loader.api.FabricLoader;
import net.kyori.adventure.platform.fabric.FabricServerAudiences;
import net.minecraft.commands.CommandSourceStack;
import org.apache.commons.lang3.Validate;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -130,8 +129,6 @@ public int run(final @NonNull CommandContext<CommandSourceStack> context) {

@Override
public @NonNull String loadIcon(final @NonNull BufferedImage bufferedImage) throws Exception {
Validate.validState(bufferedImage.getWidth() == 64, "Must be 64 pixels wide");
Validate.validState(bufferedImage.getHeight() == 64, "Must be 64 pixels high");
final ByteBuf byteBuf = Unpooled.buffer();
final String icon;
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.CachedServerIcon;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import xyz.jpenilla.minimotd.common.MiniMOTD;
Expand All @@ -40,51 +41,45 @@
import java.nio.file.Path;

public final class MiniMOTDPlugin extends JavaPlugin implements MiniMOTDPlatform<CachedServerIcon> {
private static final boolean PAPER_PING_EVENT_EXISTS = findClass("com.destroystokyo.paper.event.server.PaperServerListPingEvent") != null;

private Logger logger;
private MiniMOTD<CachedServerIcon> miniMOTD;
private boolean isPaperServer;
private BukkitAudiences audiences;
private String serverPackageName;
private String serverApiVersion;
private int majorMinecraftVersion;
private BukkitAudiences audiences;
private Logger logger;

@Override
public void onEnable() {
this.logger = LoggerFactory.getLogger(this.getName());
this.miniMOTD = new MiniMOTD<>(this);
this.audiences = BukkitAudiences.create(this);
this.serverPackageName = this.getServer().getClass().getPackage().getName();
this.serverApiVersion = this.serverPackageName.substring(this.serverPackageName.lastIndexOf('.') + 1);
this.majorMinecraftVersion = Integer.parseInt(this.serverApiVersion.split("_")[1]);

try {
Class.forName("com.destroystokyo.paper.event.server.PaperServerListPingEvent");
this.isPaperServer = true;
} catch (final ClassNotFoundException e) {
this.isPaperServer = false;
}
if (this.isPaperServer) {
getServer().getPluginManager().registerEvents(new PaperPingListener(this, this.miniMOTD), this);
if (PAPER_PING_EVENT_EXISTS) {
Bukkit.getPluginManager().registerEvents(new PaperPingListener(this, this.miniMOTD), this);
} else {
getServer().getPluginManager().registerEvents(new PingListener(this, this.miniMOTD), this);
if (this.majorMinecraftVersion > 11) {
getLogger().info("#");
getLogger().info("# This server is not using Paper, and therefore some features may be limited or disabled.");
getLogger().info("# Get Paper from https://papermc.io/downloads");
getLogger().info("#");
Bukkit.getPluginManager().registerEvents(new PingListener(this, this.miniMOTD), this);
if (this.majorMinecraftVersion >= 12) { // PaperServerListPingEvent was added in 1.12
this.suggestPaper();
}
}
this.audiences = BukkitAudiences.create(this);
final PluginCommand command = getCommand("minimotd");

final PluginCommand command = this.getCommand("minimotd");
if (command != null) {
command.setExecutor(new SpigotCommand(this));
command.setTabCompleter(new SpigotCommand(this));
final SpigotCommand spigotCommand = new SpigotCommand(this);
command.setExecutor(spigotCommand);
command.setTabCompleter(spigotCommand);
}

final Metrics metrics = new Metrics(this, 8132);

if (this.miniMOTD.configManager().pluginSettings().updateChecker()) {
Bukkit.getScheduler().runTaskAsynchronously(this, () ->
new UpdateChecker().checkVersion().forEach(getLogger()::info));
new UpdateChecker().checkVersion().forEach(this.logger::info));
}
}

Expand Down Expand Up @@ -114,4 +109,26 @@ public int majorMinecraftVersion() {
public @NonNull BukkitAudiences audiences() {
return this.audiences;
}

private void suggestPaper() {
this.logger.warn("======================================================");
this.logger.warn(" MiniMOTD works better if you use Paper as your server");
this.logger.warn(" software.");
this.logger.warn(" ");
this.logger.warn(" Spigot does not include the necessary APIs for all");
this.logger.warn(" of MiniMOTD's features to operate. MiniMOTD was");
this.logger.warn(" designed to work with Paper and it's expanded API");
this.logger.warn(" for full compatibility.");
this.logger.warn(" ");
this.logger.warn(" Get Paper from https://papermc.io/downloads");
this.logger.warn("======================================================");
}

private static @Nullable Class<?> findClass(final @NonNull String className) {
try {
return Class.forName(className);
} catch (final ClassNotFoundException ex) {
return null;
}
}
}
3 changes: 1 addition & 2 deletions sponge8/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,10 @@ tasks {
relocate("io.leangen.geantyref", "xyz.jpenilla.minimotd.lib.io.leangen.geantyref")
relocate("com.typesafe.config", "xyz.jpenilla.minimotd.lib.typesafe.config")
relocate("net.kyori.adventure.text.minimessage", "xyz.jpenilla.minimotd.lib.kyori_native.minimessage")
relocate("net.kyori.adventure.text.serializer.legacy", "xyz.jpenilla.minimotd.lib.kyori_native.legacy.text.serializer")
relocate("org.checkerframework", "xyz.jpenilla.minimotd.lib.checkerframework")
relocate("xyz.jpenilla.minimotd.common", "xyz.jpenilla.minimotd.lib.sponge8.minimotd.common")
dependencies {
exclude { dep -> dep.moduleGroup == "net.kyori" && !dep.name.contains("minimessage") && !dep.name.contains("text-serializer-legacy") }
exclude { dep -> dep.moduleGroup == "net.kyori" && !dep.name.contains("minimessage") }
}
}
runServer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,11 @@
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import com.velocitypowered.api.event.proxy.ProxyPingEvent;
import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.plugin.PluginContainer;
import com.velocitypowered.api.plugin.PluginDescription;
import com.velocitypowered.api.plugin.annotation.DataDirectory;
import com.velocitypowered.api.proxy.ProxyServer;
import com.velocitypowered.api.proxy.server.ServerPing;
import com.velocitypowered.api.util.Favicon;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bstats.velocity.Metrics;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.slf4j.Logger;
Expand Down Expand Up @@ -69,8 +66,6 @@ public final class MiniMOTDPlugin implements MiniMOTDPlatform<Favicon> {
private final MiniMOTD<Favicon> miniMOTD;
private final ProxyServer server;
private final Logger logger;
private final MiniMessage miniMessage = MiniMessage.get();
private final PluginContainer pluginContainer;
private final CommandManager commandManager;
private final Path dataDirectory;
private final Metrics.Factory metricsFactory;
Expand All @@ -80,14 +75,12 @@ public MiniMOTDPlugin(
final @NonNull ProxyServer server,
final @NonNull Logger logger,
final @NonNull CommandManager commandManager,
final @NonNull PluginContainer pluginContainer,
@DataDirectory final @NonNull Path dataDirectory,
final Metrics.@NonNull Factory metricsFactory
) {
this.server = server;
this.logger = logger;
this.commandManager = commandManager;
this.pluginContainer = pluginContainer;
this.dataDirectory = dataDirectory;
this.metricsFactory = metricsFactory;
this.miniMOTD = new MiniMOTD<>(this);
Expand Down Expand Up @@ -132,15 +125,15 @@ public int run(final @NonNull CommandContext<CommandSource> context) {
}

@Subscribe
public void onServerListPing(final @NonNull ProxyPingEvent ping) {
public void onServerListPing(final @NonNull ProxyPingEvent event) {
final String configString = this.miniMOTD.configManager().pluginSettings().configStringForHost(
ping.getConnection().getVirtualHost()
event.getConnection().getVirtualHost()
.map(inetSocketAddress -> String.format("%s:%s", inetSocketAddress.getHostName(), inetSocketAddress.getPort()))
.orElse("default")
).orElse("default");
final MiniMOTDConfig config = this.miniMOTD.configManager().resolveConfig(configString);

final ServerPing.Builder pong = ping.getPing().asBuilder();
final ServerPing.Builder pong = event.getPing().asBuilder();

final int onlinePlayers = this.miniMOTD.calculateOnlinePlayers(config, pong.getOnlinePlayers());
pong.onlinePlayers(onlinePlayers);
Expand Down Expand Up @@ -170,11 +163,7 @@ public void onServerListPing(final @NonNull ProxyPingEvent ping) {
pong.nullPlayers();
}

ping.setPing(pong.build());
}

public @NonNull MiniMOTD<Favicon> miniMOTD() {
return this.miniMOTD;
event.setPing(pong.build());
}

@Override
Expand All @@ -192,14 +181,6 @@ public void onServerListPing(final @NonNull ProxyPingEvent ping) {
return Favicon.create(image);
}

public @NonNull MiniMessage miniMessage() {
return this.miniMessage;
}

public @NonNull PluginDescription pluginDescription() {
return this.pluginContainer.getDescription();
}

@Override
public void onReload() {
this.miniMOTD.configManager().loadExtraConfigs();
Expand Down

0 comments on commit 71f6531

Please sign in to comment.