mirror of
https://github.com/PaperMC/Paper.git
synced 2025-07-31 20:22:05 -07:00
net.minecraft.network.chat
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
--- a/net/minecraft/network/chat/ChatDecorator.java
|
||||
+++ b/net/minecraft/network/chat/ChatDecorator.java
|
||||
@@ -5,7 +_,14 @@
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ChatDecorator {
|
||||
- ChatDecorator PLAIN = (player, message) -> message;
|
||||
-
|
||||
- Component decorate(@Nullable ServerPlayer player, Component message);
|
||||
+ ChatDecorator PLAIN = (sender, message) -> java.util.concurrent.CompletableFuture.completedFuture(message); // Paper - adventure; support async chat decoration events
|
||||
+
|
||||
+ @io.papermc.paper.annotation.DoNotUse @Deprecated // Paper - adventure; support chat decoration events (callers should use the overload with CommandSourceStack)
|
||||
+ java.util.concurrent.CompletableFuture<Component> decorate(@Nullable ServerPlayer sender, Component message); // Paper - adventure; support async chat decoration events
|
||||
+
|
||||
+ // Paper start - adventure; support async chat decoration events
|
||||
+ default java.util.concurrent.CompletableFuture<Component> decorate(@Nullable ServerPlayer sender, @Nullable net.minecraft.commands.CommandSourceStack commandSourceStack, Component message) {
|
||||
+ throw new UnsupportedOperationException("Must override this implementation");
|
||||
+ }
|
||||
+ // Paper end - adventure; support async chat decoration events
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
--- a/net/minecraft/network/chat/Component.java
|
||||
+++ b/net/minecraft/network/chat/Component.java
|
||||
@@ -37,7 +_,19 @@
|
||||
import net.minecraft.util.FormattedCharSequence;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
|
||||
-public interface Component extends Message, FormattedText {
|
||||
+public interface Component extends Message, FormattedText, Iterable<Component> { // CraftBukkit
|
||||
+
|
||||
+ // CraftBukkit start
|
||||
+ default java.util.stream.Stream<Component> stream() {
|
||||
+ return com.google.common.collect.Streams.concat(new java.util.stream.Stream[]{java.util.stream.Stream.of(this), this.getSiblings().stream().flatMap(Component::stream)});
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default java.util.Iterator<Component> iterator() {
|
||||
+ return this.stream().iterator();
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
Style getStyle();
|
||||
|
||||
ComponentContents getContents();
|
@@ -0,0 +1,97 @@
|
||||
--- a/net/minecraft/network/chat/ComponentSerialization.java
|
||||
+++ b/net/minecraft/network/chat/ComponentSerialization.java
|
||||
@@ -37,9 +_,31 @@
|
||||
|
||||
public class ComponentSerialization {
|
||||
public static final Codec<Component> CODEC = Codec.recursive("Component", ComponentSerialization::createCodec);
|
||||
- public static final StreamCodec<RegistryFriendlyByteBuf, Component> STREAM_CODEC = ByteBufCodecs.fromCodecWithRegistries(CODEC);
|
||||
+ public static final StreamCodec<RegistryFriendlyByteBuf, Component> STREAM_CODEC = createTranslationAware(() -> net.minecraft.nbt.NbtAccounter.create(net.minecraft.network.FriendlyByteBuf.DEFAULT_NBT_QUOTA)); // Paper - adventure
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, Optional<Component>> OPTIONAL_STREAM_CODEC = STREAM_CODEC.apply(ByteBufCodecs::optional);
|
||||
- public static final StreamCodec<RegistryFriendlyByteBuf, Component> TRUSTED_STREAM_CODEC = ByteBufCodecs.fromCodecWithRegistriesTrusted(CODEC);
|
||||
+ // Paper start - adventure; use locale from bytebuf for translation
|
||||
+ public static final ThreadLocal<Boolean> DONT_RENDER_TRANSLATABLES = ThreadLocal.withInitial(() -> false);
|
||||
+ public static final StreamCodec<RegistryFriendlyByteBuf, Component> TRUSTED_STREAM_CODEC = createTranslationAware(net.minecraft.nbt.NbtAccounter::unlimitedHeap);
|
||||
+ private static StreamCodec<RegistryFriendlyByteBuf, Component> createTranslationAware(final Supplier<net.minecraft.nbt.NbtAccounter> sizeTracker) {
|
||||
+ return new StreamCodec<>() {
|
||||
+ final StreamCodec<ByteBuf, net.minecraft.nbt.Tag> streamCodec = ByteBufCodecs.tagCodec(sizeTracker);
|
||||
+ @Override
|
||||
+ public Component decode(RegistryFriendlyByteBuf registryFriendlyByteBuf) {
|
||||
+ net.minecraft.nbt.Tag tag = this.streamCodec.decode(registryFriendlyByteBuf);
|
||||
+ RegistryOps<net.minecraft.nbt.Tag> registryOps = registryFriendlyByteBuf.registryAccess().createSerializationContext(net.minecraft.nbt.NbtOps.INSTANCE);
|
||||
+ return CODEC.parse(registryOps, tag).getOrThrow(error -> new io.netty.handler.codec.DecoderException("Failed to decode: " + error + " " + tag));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void encode(RegistryFriendlyByteBuf registryFriendlyByteBuf, Component object) {
|
||||
+ RegistryOps<net.minecraft.nbt.Tag> registryOps = registryFriendlyByteBuf.registryAccess().createSerializationContext(net.minecraft.nbt.NbtOps.INSTANCE);
|
||||
+ net.minecraft.nbt.Tag tag = (DONT_RENDER_TRANSLATABLES.get() ? CODEC : ComponentSerialization.localizedCodec(registryFriendlyByteBuf.adventure$locale))
|
||||
+ .encodeStart(registryOps, object).getOrThrow(error -> new io.netty.handler.codec.EncoderException("Failed to encode: " + error + " " + object));
|
||||
+ this.streamCodec.encode(registryFriendlyByteBuf, tag);
|
||||
+ }
|
||||
+ };
|
||||
+ }
|
||||
+ // Paper end - adventure; use locale from bytebuf for translation
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, Optional<Component>> TRUSTED_OPTIONAL_STREAM_CODEC = TRUSTED_STREAM_CODEC.apply(
|
||||
ByteBufCodecs::optional
|
||||
);
|
||||
@@ -102,7 +_,25 @@
|
||||
return ExtraCodecs.orCompressed(mapCodec2, mapCodec1);
|
||||
}
|
||||
|
||||
+ // Paper start - adventure; create separate codec for each locale
|
||||
+ private static final java.util.Map<java.util.Locale, Codec<Component>> LOCALIZED_CODECS = new java.util.concurrent.ConcurrentHashMap<>();
|
||||
+
|
||||
+ public static Codec<Component> localizedCodec(final java.util.@org.checkerframework.checker.nullness.qual.Nullable Locale locale) {
|
||||
+ if (locale == null) {
|
||||
+ return CODEC;
|
||||
+ }
|
||||
+ return LOCALIZED_CODECS.computeIfAbsent(locale,
|
||||
+ loc -> Codec.recursive("Component", selfCodec -> createCodec(selfCodec, loc)));
|
||||
+ }
|
||||
+ // Paper end - adventure; create separate codec for each locale
|
||||
+
|
||||
private static Codec<Component> createCodec(Codec<Component> codec) {
|
||||
+ // Paper start - adventure; create separate codec for each locale
|
||||
+ return createCodec(codec, null);
|
||||
+ }
|
||||
+
|
||||
+ private static Codec<Component> createCodec(Codec<Component> codec, @javax.annotation.Nullable java.util.Locale locale) {
|
||||
+ // Paper end - adventure; create separate codec for each locale
|
||||
ComponentContents.Type<?>[] types = new ComponentContents.Type[]{
|
||||
PlainTextContents.TYPE, TranslatableContents.TYPE, KeybindContents.TYPE, ScoreContents.TYPE, SelectorContents.TYPE, NbtContents.TYPE
|
||||
};
|
||||
@@ -115,6 +_,34 @@
|
||||
)
|
||||
.apply(instance, MutableComponent::new)
|
||||
);
|
||||
+ // Paper start - adventure; create separate codec for each locale
|
||||
+ final Codec<Component> origCodec = codec;
|
||||
+ codec = new Codec<>() {
|
||||
+ @Override
|
||||
+ public <T> DataResult<com.mojang.datafixers.util.Pair<Component, T>> decode(final DynamicOps<T> ops, final T input) {
|
||||
+ return origCodec.decode(ops, input);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public <T> DataResult<T> encode(final Component input, final DynamicOps<T> ops, final T prefix) {
|
||||
+ final net.kyori.adventure.text.Component adventureComponent;
|
||||
+ if (input instanceof io.papermc.paper.adventure.AdventureComponent adv) {
|
||||
+ adventureComponent = adv.adventure$component();
|
||||
+ } else if (locale != null && input.getContents() instanceof TranslatableContents && io.papermc.paper.adventure.PaperAdventure.hasAnyTranslations()) {
|
||||
+ adventureComponent = io.papermc.paper.adventure.PaperAdventure.asAdventure(input);
|
||||
+ } else {
|
||||
+ return origCodec.encode(input, ops, prefix);
|
||||
+ }
|
||||
+ return io.papermc.paper.adventure.PaperAdventure.localizedCodec(locale)
|
||||
+ .encode(adventureComponent, ops, prefix);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String toString() {
|
||||
+ return origCodec.toString() + "[AdventureComponentAware]";
|
||||
+ }
|
||||
+ };
|
||||
+ // Paper end - adventure; create separate codec for each locale
|
||||
return Codec.either(Codec.either(Codec.STRING, ExtraCodecs.nonEmptyList(codec.listOf())), codec1)
|
||||
.xmap(
|
||||
either -> either.map(either1 -> either1.map(Component::literal, ComponentSerialization::createFromList), component -> (Component)component),
|
@@ -0,0 +1,51 @@
|
||||
--- a/net/minecraft/network/chat/ComponentUtils.java
|
||||
+++ b/net/minecraft/network/chat/ComponentUtils.java
|
||||
@@ -33,6 +_,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ @io.papermc.paper.annotation.DoNotUse // Paper - validate separators - right now this method is only used for separator evaluation. Error on build if this changes to re-evaluate.
|
||||
public static Optional<MutableComponent> updateForEntity(
|
||||
@Nullable CommandSourceStack commandSourceStack, Optional<Component> optionalComponent, @Nullable Entity entity, int recursionDepth
|
||||
) throws CommandSyntaxException {
|
||||
@@ -41,12 +_,40 @@
|
||||
: Optional.empty();
|
||||
}
|
||||
|
||||
+ // Paper start - validate separator
|
||||
+ public static Optional<MutableComponent> updateSeparatorForEntity(@Nullable CommandSourceStack source, Optional<Component> text, @Nullable Entity sender, int depth) throws CommandSyntaxException {
|
||||
+ if (text.isEmpty() || !isValidSelector(text.get())) return Optional.empty();
|
||||
+ return Optional.of(updateForEntity(source, text.get(), sender, depth));
|
||||
+ }
|
||||
+
|
||||
+ public static boolean isValidSelector(final Component component) {
|
||||
+ final ComponentContents contents = component.getContents();
|
||||
+
|
||||
+ if (contents instanceof net.minecraft.network.chat.contents.NbtContents || contents instanceof net.minecraft.network.chat.contents.SelectorContents)
|
||||
+ return false;
|
||||
+ if (contents instanceof final net.minecraft.network.chat.contents.TranslatableContents translatableContents) {
|
||||
+ for (final Object arg : translatableContents.getArgs()) {
|
||||
+ if (arg instanceof final Component argumentAsComponent && !isValidSelector(argumentAsComponent))
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end - validate separator
|
||||
+
|
||||
public static MutableComponent updateForEntity(
|
||||
@Nullable CommandSourceStack commandSourceStack, Component component, @Nullable Entity entity, int recursionDepth
|
||||
) throws CommandSyntaxException {
|
||||
if (recursionDepth > 100) {
|
||||
return component.copy();
|
||||
} else {
|
||||
+ // Paper start - adventure; pass actual vanilla component
|
||||
+ if (component instanceof io.papermc.paper.adventure.AdventureComponent adventureComponent) {
|
||||
+ component = adventureComponent.deepConverted();
|
||||
+ }
|
||||
+ // Paper end - adventure; pass actual vanilla component
|
||||
+
|
||||
MutableComponent mutableComponent = component.getContents().resolve(commandSourceStack, entity, recursionDepth + 1);
|
||||
|
||||
for (Component component1 : component.getSiblings()) {
|
@@ -0,0 +1,10 @@
|
||||
--- a/net/minecraft/network/chat/MessageSignature.java
|
||||
+++ b/net/minecraft/network/chat/MessageSignature.java
|
||||
@@ -13,6 +_,7 @@
|
||||
import net.minecraft.util.SignatureValidator;
|
||||
|
||||
public record MessageSignature(byte[] bytes) {
|
||||
+ public net.kyori.adventure.chat.SignedMessage.Signature adventure() { return () -> this.bytes; } // Paper - adventure; support signed messages
|
||||
public static final Codec<MessageSignature> CODEC = ExtraCodecs.BASE64_STRING.xmap(MessageSignature::new, MessageSignature::bytes);
|
||||
public static final int BYTES = 256;
|
||||
|
@@ -0,0 +1,14 @@
|
||||
--- a/net/minecraft/network/chat/MutableComponent.java
|
||||
+++ b/net/minecraft/network/chat/MutableComponent.java
|
||||
@@ -94,6 +_,11 @@
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
+ // Paper start - make AdventureComponent equivalent
|
||||
+ if (other instanceof io.papermc.paper.adventure.AdventureComponent adventureComponent) {
|
||||
+ other = adventureComponent.deepConverted();
|
||||
+ }
|
||||
+ // Paper end - make AdventureComponent equivalent
|
||||
return this == other
|
||||
|| other instanceof MutableComponent mutableComponent
|
||||
&& this.contents.equals(mutableComponent.contents)
|
@@ -0,0 +1,43 @@
|
||||
--- a/net/minecraft/network/chat/OutgoingChatMessage.java
|
||||
+++ b/net/minecraft/network/chat/OutgoingChatMessage.java
|
||||
@@ -7,6 +_,12 @@
|
||||
|
||||
void sendToPlayer(ServerPlayer player, boolean filtered, ChatType.Bound boundType);
|
||||
|
||||
+ // Paper start
|
||||
+ default void sendToPlayer(ServerPlayer sender, boolean filterMaskEnabled, ChatType.Bound params, @javax.annotation.Nullable Component unsigned) {
|
||||
+ this.sendToPlayer(sender, filterMaskEnabled, params);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
static OutgoingChatMessage create(PlayerChatMessage message) {
|
||||
return (OutgoingChatMessage)(message.isSystem()
|
||||
? new OutgoingChatMessage.Disguised(message.decoratedContent())
|
||||
@@ -16,7 +_,12 @@
|
||||
public record Disguised(@Override Component content) implements OutgoingChatMessage {
|
||||
@Override
|
||||
public void sendToPlayer(ServerPlayer player, boolean filtered, ChatType.Bound boundType) {
|
||||
- player.connection.sendDisguisedChatMessage(this.content, boundType);
|
||||
+ // Paper start
|
||||
+ this.sendToPlayer(player, filtered, boundType, null);
|
||||
+ }
|
||||
+ public void sendToPlayer(ServerPlayer player, boolean filtered, ChatType.Bound boundType, @javax.annotation.Nullable Component unsigned) {
|
||||
+ player.connection.sendDisguisedChatMessage(unsigned != null ? unsigned : this.content, boundType);
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +_,13 @@
|
||||
|
||||
@Override
|
||||
public void sendToPlayer(ServerPlayer player, boolean filtered, ChatType.Bound boundType) {
|
||||
+ // Paper start
|
||||
+ this.sendToPlayer(player, filtered, boundType, null);
|
||||
+ }
|
||||
+ public void sendToPlayer(ServerPlayer player, boolean filtered, ChatType.Bound boundType, @javax.annotation.Nullable Component unsigned) {
|
||||
+ // Paper end
|
||||
PlayerChatMessage playerChatMessage = this.message.filter(filtered);
|
||||
+ playerChatMessage = unsigned != null ? playerChatMessage.withUnsignedContent(unsigned) : playerChatMessage; // Paper
|
||||
if (!playerChatMessage.isFullyFiltered()) {
|
||||
player.connection.sendPlayerChatMessage(playerChatMessage, boundType);
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
--- a/net/minecraft/network/chat/PlayerChatMessage.java
|
||||
+++ b/net/minecraft/network/chat/PlayerChatMessage.java
|
||||
@@ -17,6 +_,43 @@
|
||||
public record PlayerChatMessage(
|
||||
SignedMessageLink link, @Nullable MessageSignature signature, SignedMessageBody signedBody, @Nullable Component unsignedContent, FilterMask filterMask
|
||||
) {
|
||||
+ // Paper start - adventure; support signed messages
|
||||
+ public final class AdventureView implements net.kyori.adventure.chat.SignedMessage {
|
||||
+ private AdventureView() {
|
||||
+ }
|
||||
+ @Override
|
||||
+ public @org.jetbrains.annotations.NotNull Instant timestamp() {
|
||||
+ return PlayerChatMessage.this.timeStamp();
|
||||
+ }
|
||||
+ @Override
|
||||
+ public long salt() {
|
||||
+ return PlayerChatMessage.this.salt();
|
||||
+ }
|
||||
+ @Override
|
||||
+ public @org.jetbrains.annotations.Nullable Signature signature() {
|
||||
+ return PlayerChatMessage.this.signature == null ? null : PlayerChatMessage.this.signature.adventure();
|
||||
+ }
|
||||
+ @Override
|
||||
+ public net.kyori.adventure.text.@org.jetbrains.annotations.Nullable Component unsignedContent() {
|
||||
+ return PlayerChatMessage.this.unsignedContent() == null ? null : io.papermc.paper.adventure.PaperAdventure.asAdventure(PlayerChatMessage.this.unsignedContent());
|
||||
+ }
|
||||
+ @Override
|
||||
+ public @org.jetbrains.annotations.NotNull String message() {
|
||||
+ return PlayerChatMessage.this.signedContent();
|
||||
+ }
|
||||
+ @Override
|
||||
+ public @org.jetbrains.annotations.NotNull net.kyori.adventure.identity.Identity identity() {
|
||||
+ return net.kyori.adventure.identity.Identity.identity(PlayerChatMessage.this.sender());
|
||||
+ }
|
||||
+ public PlayerChatMessage playerChatMessage() {
|
||||
+ return PlayerChatMessage.this;
|
||||
+ }
|
||||
+ }
|
||||
+ public AdventureView adventureView() {
|
||||
+ return new AdventureView();
|
||||
+ }
|
||||
+ // Paper end - adventure; support signed messages
|
||||
+
|
||||
public static final MapCodec<PlayerChatMessage> MAP_CODEC = RecordCodecBuilder.mapCodec(
|
||||
instance -> instance.group(
|
||||
SignedMessageLink.CODEC.fieldOf("link").forGetter(PlayerChatMessage::link),
|
||||
@@ -47,7 +_,14 @@
|
||||
}
|
||||
|
||||
public PlayerChatMessage withUnsignedContent(Component message) {
|
||||
- Component component = !message.equals(Component.literal(this.signedContent())) ? message : null;
|
||||
+ // Paper start - adventure
|
||||
+ final Component component;
|
||||
+ if (unsignedContent instanceof io.papermc.paper.adventure.AdventureComponent advComponent) {
|
||||
+ component = this.signedContent().equals(io.papermc.paper.adventure.AdventureCodecs.tryCollapseToString(advComponent.adventure$component())) ? null : unsignedContent;
|
||||
+ } else {
|
||||
+ component = !unsignedContent.equals(Component.literal(this.signedContent())) ? unsignedContent : null;
|
||||
+ }
|
||||
+ // Paper end - adventure
|
||||
return new PlayerChatMessage(this.link, this.signature, this.signedBody, component, this.filterMask);
|
||||
}
|
||||
|
@@ -0,0 +1,37 @@
|
||||
--- a/net/minecraft/network/chat/SignedMessageChain.java
|
||||
+++ b/net/minecraft/network/chat/SignedMessageChain.java
|
||||
@@ -40,14 +_,14 @@
|
||||
if (signature == null) {
|
||||
throw new SignedMessageChain.DecodeException(SignedMessageChain.DecodeException.MISSING_PROFILE_KEY);
|
||||
} else if (publicKey.data().hasExpired()) {
|
||||
- throw new SignedMessageChain.DecodeException(SignedMessageChain.DecodeException.EXPIRED_PROFILE_KEY);
|
||||
+ throw new SignedMessageChain.DecodeException(SignedMessageChain.DecodeException.EXPIRED_PROFILE_KEY, org.bukkit.event.player.PlayerKickEvent.Cause.EXPIRED_PROFILE_PUBLIC_KEY); // Paper - kick event causes
|
||||
} else {
|
||||
SignedMessageLink signedMessageLink = SignedMessageChain.this.nextLink;
|
||||
if (signedMessageLink == null) {
|
||||
throw new SignedMessageChain.DecodeException(SignedMessageChain.DecodeException.CHAIN_BROKEN);
|
||||
} else if (body.timeStamp().isBefore(SignedMessageChain.this.lastTimeStamp)) {
|
||||
this.setChainBroken();
|
||||
- throw new SignedMessageChain.DecodeException(SignedMessageChain.DecodeException.OUT_OF_ORDER_CHAT);
|
||||
+ throw new SignedMessageChain.DecodeException(SignedMessageChain.DecodeException.OUT_OF_ORDER_CHAT, org.bukkit.event.player.PlayerKickEvent.Cause.OUT_OF_ORDER_CHAT); // Paper - kick event causes
|
||||
} else {
|
||||
SignedMessageChain.this.lastTimeStamp = body.timeStamp();
|
||||
PlayerChatMessage playerChatMessage = new PlayerChatMessage(signedMessageLink, signature, body, null, FilterMask.PASS_THROUGH);
|
||||
@@ -80,8 +_,15 @@
|
||||
static final Component INVALID_SIGNATURE = Component.translatable("chat.disabled.invalid_signature");
|
||||
static final Component OUT_OF_ORDER_CHAT = Component.translatable("chat.disabled.out_of_order_chat");
|
||||
|
||||
- public DecodeException(Component component) {
|
||||
- super(component);
|
||||
+ // Paper start
|
||||
+ public final org.bukkit.event.player.PlayerKickEvent.Cause kickCause;
|
||||
+ public DecodeException(Component message, org.bukkit.event.player.PlayerKickEvent.Cause event) {
|
||||
+ super(message);
|
||||
+ this.kickCause = event;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+ public DecodeException(Component message) {
|
||||
+ this(message, org.bukkit.event.player.PlayerKickEvent.Cause.UNKNOWN); // Paper
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,34 @@
|
||||
--- a/net/minecraft/network/chat/TextColor.java
|
||||
+++ b/net/minecraft/network/chat/TextColor.java
|
||||
@@ -17,23 +_,29 @@
|
||||
public static final Codec<TextColor> CODEC = Codec.STRING.comapFlatMap(TextColor::parseColor, TextColor::serialize);
|
||||
private static final Map<ChatFormatting, TextColor> LEGACY_FORMAT_TO_COLOR = Stream.of(ChatFormatting.values())
|
||||
.filter(ChatFormatting::isColor)
|
||||
- .collect(ImmutableMap.toImmutableMap(Function.identity(), formatting -> new TextColor(formatting.getColor(), formatting.getName())));
|
||||
+ .collect(ImmutableMap.toImmutableMap(Function.identity(), formatting -> new TextColor(formatting.getColor(), formatting.getName(), formatting))); // CraftBukkit
|
||||
private static final Map<String, TextColor> NAMED_COLORS = LEGACY_FORMAT_TO_COLOR.values()
|
||||
.stream()
|
||||
.collect(ImmutableMap.toImmutableMap(textColor -> textColor.name, Function.identity()));
|
||||
private final int value;
|
||||
@Nullable
|
||||
public final String name;
|
||||
+ // CraftBukkit start
|
||||
+ @Nullable
|
||||
+ public final ChatFormatting format;
|
||||
|
||||
- private TextColor(int value, String name) {
|
||||
+ private TextColor(int value, String name, ChatFormatting format) {
|
||||
this.value = value & 16777215;
|
||||
this.name = name;
|
||||
+ this.format = format;
|
||||
}
|
||||
|
||||
private TextColor(int value) {
|
||||
this.value = value & 16777215;
|
||||
this.name = null;
|
||||
+ this.format = null;
|
||||
}
|
||||
+ // CraftBukkit end
|
||||
|
||||
public int getValue() {
|
||||
return this.value;
|
Reference in New Issue
Block a user