From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Tue, 3 Nov 2020 01:25:06 -0600 Subject: [PATCH] Allow color codes in books diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java index 0ffad0fee921ac302f31894766594921751fbff9..62fdb1e8b84facec3ce69d5001e7d626d74a37ce 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1214,10 +1214,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl Objects.requireNonNull(list); optional.ifPresent(list::add); list.addAll(packet.pages()); + // Purpur start + boolean hasEditPerm = getCraftPlayer().hasPermission("purpur.book.color.edit"); + boolean hasSignPerm = hasEditPerm || getCraftPlayer().hasPermission("purpur.book.color.sign"); + // Purpur end Consumer> consumer = optional.isPresent() ? (list1) -> { - this.signBook((FilteredText) list1.get(0), list1.subList(1, list1.size()), i); + this.signBook((FilteredText) list1.get(0), list1.subList(1, list1.size()), i, hasSignPerm); // Purpur } : (list1) -> { - this.updateBookContents(list1, i); + this.updateBookContents(list1, i, hasEditPerm); // Purpur }; this.filterTextPacket((List) list).thenAcceptAsync(consumer, this.server); @@ -1225,13 +1229,18 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } private void updateBookContents(List pages, int slotId) { + // Purpur start + updateBookContents(pages, slotId, false); + } + private void updateBookContents(List pages, int slotId, boolean hasPerm) { + // Purpur end // CraftBukkit start ItemStack handItem = this.player.getInventory().getItem(slotId); ItemStack itemstack = handItem.copy(); // CraftBukkit end if (itemstack.has(DataComponents.WRITABLE_BOOK_CONTENT)) { - List> list1 = pages.stream().map(this::filterableFromOutgoing).toList(); + List> list1 = pages.stream().map(filteredText -> filterableFromOutgoing(filteredText).map(s -> color(s, hasPerm))).toList(); // Purpur itemstack.set(DataComponents.WRITABLE_BOOK_CONTENT, new WritableBookContent(list1)); this.player.getInventory().setItem(slotId, CraftEventFactory.handleEditBookEvent(this.player, slotId, handItem, itemstack)); // CraftBukkit // Paper - Don't ignore result (see other callsite for handleEditBookEvent) @@ -1239,6 +1248,11 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } private void signBook(FilteredText title, List pages, int slotId) { + // Purpur start + signBook(title, pages, slotId, false); + } + private void signBook(FilteredText title, List pages, int slotId, boolean hasPerm) { + // Purpur end ItemStack itemstack = this.player.getInventory().getItem(slotId); if (itemstack.has(DataComponents.WRITABLE_BOOK_CONTENT)) { @@ -1246,10 +1260,10 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl itemstack1.remove(DataComponents.WRITABLE_BOOK_CONTENT); List> list1 = (List>) (List) pages.stream().map((filteredtext1) -> { // CraftBukkit - decompile error - return this.filterableFromOutgoing(filteredtext1).map(Component::literal); + return this.filterableFromOutgoing(filteredtext1).map(s -> hexColor(s, hasPerm)); // Purpur }).toList(); - itemstack1.set(DataComponents.WRITTEN_BOOK_CONTENT, new WrittenBookContent(this.filterableFromOutgoing(title), this.player.getName().getString(), 0, list1, true)); + itemstack1.set(DataComponents.WRITTEN_BOOK_CONTENT, new WrittenBookContent(this.filterableFromOutgoing(title).map(s -> color(s, hasPerm)), this.player.getName().getString(), 0, list1, true)); // Purpur CraftEventFactory.handleEditBookEvent(this.player, slotId, itemstack, itemstack1); // CraftBukkit this.player.getInventory().setItem(slotId, itemstack); // CraftBukkit - event factory updates the hand book } @@ -1259,6 +1273,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl return this.player.isTextFilteringEnabled() ? Filterable.passThrough(message.filteredOrEmpty()) : Filterable.from(message); } + // Purpur start + private Component hexColor(String str, boolean hasPerm) { + return hasPerm ? PaperAdventure.asVanilla(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacyAmpersand().deserialize(str)) : Component.literal(str); + } + + private String color(String str, boolean hasPerm) { + return hasPerm ? org.bukkit.ChatColor.color(str, false) : str; + } + // Purpur end + @Override public void handleEntityTagQuery(ServerboundEntityTagQueryPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());