From 49288f7f95915092fd514d7dcb0f6e7e7c3ea36d Mon Sep 17 00:00:00 2001 From: CraftBukkit/Spigot Date: Sat, 13 Dec 2014 03:06:05 +0100 Subject: [PATCH] BungeeCord Chat API By: md_5 --- .../ClientboundSystemChatPacket.java.patch | 13 +++ .../org/bukkit/craftbukkit/CraftServer.java | 16 ++++ .../command/ServerCommandSender.java | 23 +++++ .../craftbukkit/entity/CraftEntity.java | 22 +++++ .../craftbukkit/entity/CraftPlayer.java | 44 ++++++++++ .../craftbukkit/inventory/CraftMetaBook.java | 86 +++++++++++++++++++ .../inventory/CraftMetaBookSigned.java | 83 ++++++++++++++++++ 7 files changed, 287 insertions(+) diff --git a/paper-server/patches/sources/net/minecraft/network/protocol/game/ClientboundSystemChatPacket.java.patch b/paper-server/patches/sources/net/minecraft/network/protocol/game/ClientboundSystemChatPacket.java.patch index 362eebf617..048868c319 100644 --- a/paper-server/patches/sources/net/minecraft/network/protocol/game/ClientboundSystemChatPacket.java.patch +++ b/paper-server/patches/sources/net/minecraft/network/protocol/game/ClientboundSystemChatPacket.java.patch @@ -5,3 +5,16 @@ package net.minecraft.network.protocol.game; import net.minecraft.network.RegistryFriendlyByteBuf; +@@ -12,6 +13,12 @@ + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite(ComponentSerialization.TRUSTED_STREAM_CODEC, ClientboundSystemChatPacket::content, ByteBufCodecs.BOOL, ClientboundSystemChatPacket::overlay, ClientboundSystemChatPacket::new); + ++ // Spigot start ++ public ClientboundSystemChatPacket(net.md_5.bungee.api.chat.BaseComponent[] content, boolean overlay) { ++ this(org.bukkit.craftbukkit.util.CraftChatMessage.fromJSON(net.md_5.bungee.chat.ComponentSerializer.toString(content)), overlay); ++ } ++ // Spigot end ++ + @Override + public PacketType type() { + return GamePacketTypes.CLIENTBOUND_SYSTEM_CHAT; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java index e6d4e4e532..46b067fdfb 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -268,6 +268,8 @@ import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.SafeConstructor; import org.yaml.snakeyaml.error.MarkedYAMLException; +import net.md_5.bungee.api.chat.BaseComponent; // Spigot + public final class CraftServer implements Server { private final String serverName = "CraftBukkit"; private final String serverVersion; @@ -2603,6 +2605,20 @@ public final class CraftServer implements Server { public void restart() { org.spigotmc.RestartCommand.restart(); } + + @Override + public void broadcast(BaseComponent component) { + for (Player player : CraftServer.this.getOnlinePlayers()) { + player.spigot().sendMessage(component); + } + } + + @Override + public void broadcast(BaseComponent... components) { + for (Player player : CraftServer.this.getOnlinePlayers()) { + player.spigot().sendMessage(components); + } + } }; public org.bukkit.Server.Spigot spigot() diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java b/paper-server/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java index ed9f153ea1..1e82312c24 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java @@ -99,6 +99,29 @@ public abstract class ServerCommandSender implements CommandSender { // Spigot start private final org.bukkit.command.CommandSender.Spigot spigot = new org.bukkit.command.CommandSender.Spigot() { + @Override + public void sendMessage(net.md_5.bungee.api.chat.BaseComponent component) + { + ServerCommandSender.this.sendMessage(net.md_5.bungee.api.chat.TextComponent.toLegacyText(component)); + } + + @Override + public void sendMessage(net.md_5.bungee.api.chat.BaseComponent... components) + { + ServerCommandSender.this.sendMessage(net.md_5.bungee.api.chat.TextComponent.toLegacyText(components)); + } + + @Override + public void sendMessage(UUID sender, net.md_5.bungee.api.chat.BaseComponent... components) + { + this.sendMessage(components); + } + + @Override + public void sendMessage(UUID sender, net.md_5.bungee.api.chat.BaseComponent component) + { + this.sendMessage(component); + } }; @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index daa49fdcb7..8b53a3c4f4 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -59,6 +59,8 @@ import org.bukkit.util.BoundingBox; import org.bukkit.util.NumberConversions; import org.bukkit.util.Vector; +import net.md_5.bungee.api.chat.BaseComponent; // Spigot + public abstract class CraftEntity implements org.bukkit.entity.Entity { private static PermissibleBase perm; private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry(); @@ -897,6 +899,26 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { // Spigot start private final org.bukkit.entity.Entity.Spigot spigot = new org.bukkit.entity.Entity.Spigot() { + + @Override + public void sendMessage(net.md_5.bungee.api.chat.BaseComponent component) + { + } + + @Override + public void sendMessage(net.md_5.bungee.api.chat.BaseComponent... components) + { + } + + @Override + public void sendMessage(UUID sender, BaseComponent... components) + { + } + + @Override + public void sendMessage(UUID sender, BaseComponent component) + { + } }; public org.bukkit.entity.Entity.Spigot spigot() diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index 8da16ea0fe..9f6e15c138 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -196,6 +196,8 @@ import org.bukkit.profile.PlayerProfile; import org.bukkit.scoreboard.Scoreboard; import org.jetbrains.annotations.NotNull; +import net.md_5.bungee.api.chat.BaseComponent; // Spigot + @DelegateDeserialization(CraftOfflinePlayer.class) public class CraftPlayer extends CraftHumanEntity implements Player { private long firstPlayed = 0; @@ -2381,6 +2383,48 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return java.util.Collections.unmodifiableSet( ret ); } + + @Override + public void sendMessage(BaseComponent component) { + this.sendMessage( new BaseComponent[] { component } ); + } + + @Override + public void sendMessage(BaseComponent... components) { + this.sendMessage(net.md_5.bungee.api.ChatMessageType.SYSTEM, components); + } + + @Override + public void sendMessage(UUID sender, BaseComponent component) { + this.sendMessage(net.md_5.bungee.api.ChatMessageType.CHAT, sender, component); + } + + @Override + public void sendMessage(UUID sender, BaseComponent... components) { + this.sendMessage(net.md_5.bungee.api.ChatMessageType.CHAT, sender, components); + } + + @Override + public void sendMessage(net.md_5.bungee.api.ChatMessageType position, BaseComponent component) { + this.sendMessage( position, new BaseComponent[] { component } ); + } + + @Override + public void sendMessage(net.md_5.bungee.api.ChatMessageType position, BaseComponent... components) { + this.sendMessage(position, null, components); + } + + @Override + public void sendMessage(net.md_5.bungee.api.ChatMessageType position, UUID sender, BaseComponent component) { + this.sendMessage( position, sender, new BaseComponent[] { component } ); + } + + @Override + public void sendMessage(net.md_5.bungee.api.ChatMessageType position, UUID sender, BaseComponent... components) { + if ( CraftPlayer.this.getHandle().connection == null ) return; + + CraftPlayer.this.getHandle().connection.send(new net.minecraft.network.protocol.game.ClientboundSystemChatPacket(components, position == net.md_5.bungee.api.ChatMessageType.ACTION_BAR)); + } }; public Player.Spigot spigot() diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java index 3f03e3b029..3ab6b21200 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java @@ -11,6 +11,7 @@ import java.util.Map; import java.util.Objects; import net.minecraft.core.component.DataComponentPatch; import net.minecraft.core.component.DataComponents; +import net.minecraft.network.chat.Component; import net.minecraft.server.network.Filterable; import net.minecraft.server.network.FilteredText; import net.minecraft.world.item.component.WritableBookContent; @@ -20,6 +21,13 @@ import org.bukkit.craftbukkit.util.CraftChatMessage; import org.bukkit.inventory.meta.BookMeta; import org.bukkit.inventory.meta.WritableBookMeta; +// Spigot start +import java.util.AbstractList; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.chat.ComponentSerializer; +import org.bukkit.craftbukkit.util.CraftChatMessage; +// Spigot end + @DelegateDeserialization(SerializableMeta.class) public class CraftMetaBook extends CraftMetaItem implements BookMeta, WritableBookMeta { @ItemMetaKey.Specific(ItemMetaKey.Specific.To.NBT) @@ -291,6 +299,84 @@ public class CraftMetaBook extends CraftMetaItem implements BookMeta, WritableBo // Spigot start private BookMeta.Spigot spigot = new SpigotMeta(); private class SpigotMeta extends BookMeta.Spigot { + + private String pageToJSON(String page) { + // Convert from plain String to JSON (similar to conversion between writable books and written books): + Component component = CraftChatMessage.fromString(page, true, true)[0]; + return CraftChatMessage.toJSON(component); + } + + private String componentsToPage(BaseComponent[] components) { + // Convert component to plain String: + Component component = CraftChatMessage.fromJSONOrNull(ComponentSerializer.toString(components)); + return CraftChatMessage.fromComponent(component); + } + + @Override + public BaseComponent[] getPage(final int page) { + Preconditions.checkArgument(CraftMetaBook.this.isValidPage(page), "Invalid page number"); + return ComponentSerializer.parse(this.pageToJSON(CraftMetaBook.this.pages.get(page - 1))); + } + + @Override + public void setPage(final int page, final BaseComponent... text) { + if (!CraftMetaBook.this.isValidPage(page)) { + throw new IllegalArgumentException("Invalid page number " + page + "/" + CraftMetaBook.this.getPageCount()); + } + + BaseComponent[] newText = text == null ? new BaseComponent[0] : text; + CraftMetaBook.this.pages.set(page - 1, this.componentsToPage(newText)); + } + + @Override + public void setPages(final BaseComponent[]... pages) { + this.setPages(Arrays.asList(pages)); + } + + @Override + public void addPage(final BaseComponent[]... pages) { + for (BaseComponent[] page : pages) { + if (page == null) { + page = new BaseComponent[0]; + } + + CraftMetaBook.this.internalAddPage(this.componentsToPage(page)); + } + } + + @Override + public List getPages() { + if (CraftMetaBook.this.pages == null) return ImmutableList.of(); + final List copy = ImmutableList.copyOf(CraftMetaBook.this.pages); + return new AbstractList() { + + @Override + public BaseComponent[] get(int index) { + return ComponentSerializer.parse(SpigotMeta.this.pageToJSON(copy.get(index))); + } + + @Override + public int size() { + return copy.size(); + } + }; + } + + @Override + public void setPages(List pages) { + if (pages.isEmpty()) { + CraftMetaBook.this.pages = null; + return; + } + + if (CraftMetaBook.this.pages != null) { + CraftMetaBook.this.pages.clear(); + } + + for (BaseComponent[] page : pages) { + this.addPage(page); + } + } }; @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java index 8f8a69eea7..c71a4971f1 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java @@ -21,6 +21,12 @@ import org.bukkit.configuration.serialization.DelegateDeserialization; import org.bukkit.craftbukkit.util.CraftChatMessage; import org.bukkit.inventory.meta.BookMeta; +// Spigot start +import java.util.AbstractList; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.chat.ComponentSerializer; +// Spigot end + @DelegateDeserialization(SerializableMeta.class) public class CraftMetaBookSigned extends CraftMetaItem implements BookMeta { @ItemMetaKey.Specific(ItemMetaKey.Specific.To.NBT) @@ -369,6 +375,83 @@ public class CraftMetaBookSigned extends CraftMetaItem implements BookMeta { // Spigot start private BookMeta.Spigot spigot = new SpigotMeta(); private class SpigotMeta extends BookMeta.Spigot { + + private String pageToJSON(Component page) { + // Page data is already in JSON format: + return CraftChatMessage.toJSON(page); + } + + private Component componentsToPage(BaseComponent[] components) { + // asserted: components != null + // Pages are in JSON format: + return CraftChatMessage.fromJSON(ComponentSerializer.toString(components)); + } + + @Override + public BaseComponent[] getPage(final int page) { + Preconditions.checkArgument(CraftMetaBookSigned.this.isValidPage(page), "Invalid page number"); + return ComponentSerializer.parse(this.pageToJSON(CraftMetaBookSigned.this.pages.get(page - 1))); + } + + @Override + public void setPage(final int page, final BaseComponent... text) { + if (!CraftMetaBookSigned.this.isValidPage(page)) { + throw new IllegalArgumentException("Invalid page number " + page + "/" + CraftMetaBookSigned.this.getPageCount()); + } + + BaseComponent[] newText = text == null ? new BaseComponent[0] : text; + CraftMetaBookSigned.this.pages.set(page - 1, this.componentsToPage(newText)); + } + + @Override + public void setPages(final BaseComponent[]... pages) { + this.setPages(Arrays.asList(pages)); + } + + @Override + public void addPage(final BaseComponent[]... pages) { + for (BaseComponent[] page : pages) { + if (page == null) { + page = new BaseComponent[0]; + } + + CraftMetaBookSigned.this.internalAddPage(this.componentsToPage(page)); + } + } + + @Override + public List getPages() { + if (CraftMetaBookSigned.this.pages == null) return ImmutableList.of(); + final List copy = ImmutableList.copyOf(CraftMetaBookSigned.this.pages); + return new AbstractList() { + + @Override + public BaseComponent[] get(int index) { + return ComponentSerializer.parse(SpigotMeta.this.pageToJSON(copy.get(index))); + } + + @Override + public int size() { + return copy.size(); + } + }; + } + + @Override + public void setPages(List pages) { + if (pages.isEmpty()) { + CraftMetaBookSigned.this.pages = null; + return; + } + + if (CraftMetaBookSigned.this.pages != null) { + CraftMetaBookSigned.this.pages.clear(); + } + + for (BaseComponent[] page : pages) { + this.addPage(page); + } + } }; @Override