From 10bd24319bd2bbe2a41b4bea23275c9c353ece44 Mon Sep 17 00:00:00 2001 From: Jedediah Smith Date: Thu, 19 Jan 2017 23:39:56 -0500 Subject: [PATCH] Custom text rendering API --- .../tc/oc/minecraft/api/command/Console.java | 4 ++ .../api/command/ConsoleCommandSender.java | 4 -- .../oc/minecraft/api/server/LocalServer.java | 4 +- .../minecraft/api/text/TextRenderContext.java | 19 ++++++++ .../oc/minecraft/api/text/TextRenderer.java | 44 +++++++++++++++++++ .../api/text/TextRendererBinder.java | 22 ++++++++++ 6 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 src/main/java/tc/oc/minecraft/api/command/Console.java delete mode 100644 src/main/java/tc/oc/minecraft/api/command/ConsoleCommandSender.java create mode 100644 src/main/java/tc/oc/minecraft/api/text/TextRenderContext.java create mode 100644 src/main/java/tc/oc/minecraft/api/text/TextRenderer.java create mode 100644 src/main/java/tc/oc/minecraft/api/text/TextRendererBinder.java diff --git a/src/main/java/tc/oc/minecraft/api/command/Console.java b/src/main/java/tc/oc/minecraft/api/command/Console.java new file mode 100644 index 0000000..7497849 --- /dev/null +++ b/src/main/java/tc/oc/minecraft/api/command/Console.java @@ -0,0 +1,4 @@ +package tc.oc.minecraft.api.command; + +public interface Console extends CommandSender { +} diff --git a/src/main/java/tc/oc/minecraft/api/command/ConsoleCommandSender.java b/src/main/java/tc/oc/minecraft/api/command/ConsoleCommandSender.java deleted file mode 100644 index 3e4a388..0000000 --- a/src/main/java/tc/oc/minecraft/api/command/ConsoleCommandSender.java +++ /dev/null @@ -1,4 +0,0 @@ -package tc.oc.minecraft.api.command; - -public interface ConsoleCommandSender extends CommandSender { -} diff --git a/src/main/java/tc/oc/minecraft/api/server/LocalServer.java b/src/main/java/tc/oc/minecraft/api/server/LocalServer.java index 8273d07..6d75f78 100644 --- a/src/main/java/tc/oc/minecraft/api/server/LocalServer.java +++ b/src/main/java/tc/oc/minecraft/api/server/LocalServer.java @@ -2,7 +2,7 @@ import java.util.Set; -import tc.oc.minecraft.api.command.ConsoleCommandSender; +import tc.oc.minecraft.api.command.Console; import tc.oc.minecraft.api.logging.Loggable; import tc.oc.minecraft.api.plugin.PluginFinder; @@ -13,7 +13,7 @@ public interface LocalServer extends Loggable, Server { PluginFinder getPluginFinder(); - ConsoleCommandSender getConsoleSender(); + Console getConsoleSender(); /** * All Minecraft protocol versions supported by this server diff --git a/src/main/java/tc/oc/minecraft/api/text/TextRenderContext.java b/src/main/java/tc/oc/minecraft/api/text/TextRenderContext.java new file mode 100644 index 0000000..d0203bf --- /dev/null +++ b/src/main/java/tc/oc/minecraft/api/text/TextRenderContext.java @@ -0,0 +1,19 @@ +package tc.oc.minecraft.api.text; + +import net.md_5.bungee.api.chat.BaseComponent; +import tc.oc.minecraft.api.command.CommandSender; + +/** + * A service that "renders" {@link BaseComponent}s for display to a specific {@link CommandSender}. + * + * This may involve translation of {@link net.md_5.bungee.api.chat.TranslatableComponent}s, + * or other operations implemented by plugins. It also may do nothing at all, in which case + * the {@link #render(BaseComponent, CommandSender)} method is likely to return the same + * {@link BaseComponent} that was passed to it. + * + * @see TextRenderer + */ +public interface TextRenderContext { + + BaseComponent render(BaseComponent text, CommandSender viewer); +} diff --git a/src/main/java/tc/oc/minecraft/api/text/TextRenderer.java b/src/main/java/tc/oc/minecraft/api/text/TextRenderer.java new file mode 100644 index 0000000..98bd6f4 --- /dev/null +++ b/src/main/java/tc/oc/minecraft/api/text/TextRenderer.java @@ -0,0 +1,44 @@ +package tc.oc.minecraft.api.text; + +import net.md_5.bungee.api.chat.BaseComponent; +import tc.oc.minecraft.api.command.CommandSender; +import tc.oc.minecraft.api.command.Console; +import tc.oc.minecraft.api.entity.Player; + +/** + * A plugin can register one of these with a {@link TextRendererBinder} in order to process + * {@link BaseComponent}s before they are sent to individual {@link CommandSender}s. + * + * The server will pass most text through all registered {@link TextRenderer}s, in unspecified order. + * Rendering happens on the main thread, just before the text is displayed or transmitted. + * + * Implementors must NOT modify the text passed to the render method. The original text can be + * returned unmodified, or a new object can be returned. Returned objects are not modified + * by the server, so they can be reused for other renderings. + * + * Implementors should try to be fast and minimize object creation, as rendering is called once + * per player, per piece of text displayed, even for broadcasted messages. + * + * @see TextRenderContext + * @see TextRendererBinder + */ +public interface TextRenderer { + + default BaseComponent render(TextRenderContext context, BaseComponent text, CommandSender viewer) { + if(viewer instanceof Player) { + return render(context, text, (Player) viewer); + } else if(viewer instanceof Console) { + return render(context, text, (Console) viewer); + } else { + return text; + } + } + + default BaseComponent render(TextRenderContext context, BaseComponent text, Player viewer) { + return text; + } + + default BaseComponent render(TextRenderContext context, BaseComponent text, Console viewer) { + return text; + } +} diff --git a/src/main/java/tc/oc/minecraft/api/text/TextRendererBinder.java b/src/main/java/tc/oc/minecraft/api/text/TextRendererBinder.java new file mode 100644 index 0000000..d564508 --- /dev/null +++ b/src/main/java/tc/oc/minecraft/api/text/TextRendererBinder.java @@ -0,0 +1,22 @@ +package tc.oc.minecraft.api.text; + +import com.google.inject.Binder; +import com.google.inject.binder.LinkedBindingBuilder; +import com.google.inject.multibindings.Multibinder; + +/** + * Register {@link TextRenderer}s to process all outgoing text from the server, + * for as long as the owning plugin is enabled. + */ +public class TextRendererBinder { + + private final Multibinder renderers; + + public TextRendererBinder(Binder binder) { + this.renderers = Multibinder.newSetBinder(binder, TextRenderer.class); + } + + public LinkedBindingBuilder bindRenderer() { + return renderers.addBinding(); + } +}