[Signs] Add a formatted text getter and setter api

Signed-off-by: Irmo van den Berge <irmo.vandenberge@ziggo.nl>
This commit is contained in:
Irmo van den Berge committed 2024-02-01 17:45:36 +01:00
1 parent 16c3780e29
commit 07dcf7b26e
5 files changed
+149 -4

No files matched your search

@@ -1,6 +1,7 @@
package com.bergerkiller.generated.net.minecraft.world.level.block.entity;
import com.bergerkiller.mountiplex.reflection.declarations.Template;
import com.bergerkiller.bukkit.common.wrappers.ChatText;
/**
* Instance wrapper handle for type <b>net.minecraft.world.level.block.entity.TileEntitySign</b>.
@@ -21,6 +22,15 @@ public abstract class TileEntitySignHandle extends TileEntityHandle {
public abstract Object[] getRawFrontLines();
public abstract Object[] getRawBackLines();
public abstract void setFormattedFrontLine(int index, ChatText text);
public abstract void setFormattedBackLine(int index, ChatText text);
public static final Object[] ALL_EMPTY_RAW_LINES;
static {
Object raw_empty = ChatText.empty().getRawHandle();
ALL_EMPTY_RAW_LINES = new Object[] {raw_empty, raw_empty, raw_empty, raw_empty};
}
@Override
public org.bukkit.block.Sign toBukkit() {
@@ -37,6 +47,8 @@ public abstract class TileEntitySignHandle extends TileEntityHandle {
public static final class TileEntitySignClass extends Template.Class<TileEntitySignHandle> {
public final Template.Method<Object[]> getRawFrontLines = new Template.Method<Object[]>();
public final Template.Method<Object[]> getRawBackLines = new Template.Method<Object[]>();
public final Template.Method.Converted<Void> setFormattedFrontLine = new Template.Method.Converted<Void>();
public final Template.Method.Converted<Void> setFormattedBackLine = new Template.Method.Converted<Void>();
}
@@ -50,7 +50,8 @@ public class Common {
"Common:Sound:CloudParser",
"Common:Event:PlayerAdvancementProgressEvent",
"Common:Yaml:ChildWithLiteralName",
"Common:ChunkUtil:getChunkViewers"
"Common:ChunkUtil:getChunkViewers",
"Common:SignChangeTracker:FormattedText"
).collect(Collectors.toSet());
/**
@@ -5,6 +5,8 @@ import java.util.function.Function;
import java.util.logging.Level;
import com.bergerkiller.bukkit.common.internal.CommonCapabilities;
import com.bergerkiller.bukkit.common.utils.LogicUtil;
import com.bergerkiller.bukkit.common.wrappers.ChatText;
import com.bergerkiller.generated.org.bukkit.block.SignHandle;
import org.bukkit.World;
import org.bukkit.block.Block;
@@ -198,6 +200,43 @@ public class SignChangeTracker implements Cloneable {
return stateHandle.getFrontLines();
}
/**
* Gets a line as a formatted component of the front of the sign.
*
* @param index Line index
* @return Line at this index at the front of the sign
*/
public ChatText getFormattedFrontLine(int index) {
checkRemoved();
return ChatText.fromComponent(tileEntity.getRawFrontLines()[index]);
}
/**
* Sets a line as a formatted component of the front of the sign, updating the sign in the world.
* After calling {@link #update()} this change will be detected.
*
* @param index Line index
* @param text New text to put at this index at the front of the sign
*/
public void setFormattedFrontLine(int index, ChatText text) {
checkRemoved();
this.tileEntity.setFormattedFrontLine(index, text);
// Must recreate sign state, as that one caches the sign lines which are now outdated
this.state = this.tileEntity.toBukkit();
this.stateHandle = SignHandle.createHandle(this.state);
}
/**
* Gets all the lines put at the front of the sign as formatted components. 4 lines.
*
* @return Sign front lines
*/
public ChatText[] getFormattedFrontLines() {
checkRemoved();
return LogicUtil.mapArray(tileEntity.getRawFrontLines(), ChatText.class, ChatText::fromComponent);
}
/**
* Gets a line of the back of the sign.
* Always returns an empty String on Minecraft versions below 1.20.
@@ -227,7 +266,7 @@ public class SignChangeTracker implements Cloneable {
}
/**
* Gets all the lines put at the front of the sign. 4 lines.
* Gets all the lines put at the back of the sign. 4 lines.
* Always returns an array of empty Strings on Minecraft versions below 1.20.
*
* @return Sign front lines
@@ -237,6 +276,48 @@ public class SignChangeTracker implements Cloneable {
return stateHandle.getBackLines();
}
/**
* Gets a line as a formatted component of the back of the sign.
* Always returns an empty String on Minecraft versions below 1.20.
*
* @param index Line index
* @return Line at this index at the back of the sign
*/
public ChatText getFormattedBackLine(int index) {
checkRemoved();
return ChatText.fromComponent(tileEntity.getRawBackLines()[index]);
}
/**
* Sets a line as a formatted component of the back of the sign, updating the sign in the world.
* After calling {@link #update()} this change will be detected.
* Does nothing on Minecraft versions below 1.20.
*
* @param index Line index
* @param text New text to put at this index at the back of the sign
*/
public void setFormattedBackLine(int index, ChatText text) {
checkRemoved();
if (CommonCapabilities.HAS_SIGN_BACK_TEXT) {
this.tileEntity.setFormattedBackLine(index, text);
// Must recreate sign state, as that one caches the sign lines which are now outdated
this.state = this.tileEntity.toBukkit();
this.stateHandle = SignHandle.createHandle(this.state);
}
}
/**
* Gets all the lines put at the back of the sign as formatted components. 4 lines.
* Always returns an array of empty Strings on Minecraft versions below 1.20.
*
* @return Sign front lines
*/
public ChatText[] getFormattedBackLines() {
checkRemoved();
return LogicUtil.mapArray(tileEntity.getRawBackLines(), ChatText.class, ChatText::fromComponent);
}
/**
* Gets the BlockFace the Sign is attached to
*
@@ -383,7 +464,7 @@ public class SignChangeTracker implements Cloneable {
Object[] newRawFrontLines = tileEntity.getRawFrontLines();
Object[] oldRawBackLines = this.lastRawBackLines;
Object[] newRawBackLines = tileEntity.getRawBackLines(); // Null on < 1.20
Object[] newRawBackLines = tileEntity.getRawBackLines();
if (oldRawFrontLines.length != newRawFrontLines.length ||
(CommonCapabilities.HAS_SIGN_BACK_TEXT && oldRawBackLines.length != newRawBackLines.length)
@@ -347,6 +347,25 @@ public class LogicUtil {
return (array == null) ? null : array.clone();
}
/**
* Maps all the elements of an input array and writes the result as a new array
*
* @param inputArray Input array to map
* @param outputType Output type of the array to map into
* @param mapper Mapper function. All values in the input array are mapped.
* @return Mapped array
* @param <I> Input array element type
* @param <O> Output array element type
*/
public static <I, O> O[] mapArray(I[] inputArray, Class<O> outputType, Function<I, O> mapper) {
int len = inputArray.length;
O[] outputArray = createArray(outputType, len);
for (int i = 0; i < len; i++) {
outputArray[i] = mapper.apply(inputArray[i]);
}
return outputArray;
}
/**
* Registers a custom value cloning function for the type specified, overriding any automatically
* or previously decided cloning technique. This will be used by clone operations of this class.
@@ -1,6 +1,7 @@
package net.minecraft.world.level.block.entity;
import net.minecraft.core.BlockPosition;
import net.minecraft.network.chat.IChatBaseComponent;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.PacketPlayOutTileEntityData
import net.minecraft.nbt.NBTTagCompound;
@@ -14,10 +15,12 @@ import com.bergerkiller.bukkit.common.bases.IntVector3;
import com.bergerkiller.bukkit.common.nbt.CommonTagCompound;
import com.bergerkiller.bukkit.common.protocol.CommonPacket;
import com.bergerkiller.bukkit.common.wrappers.BlockData;
import com.bergerkiller.bukkit.common.wrappers.ChatText;
import com.bergerkiller.generated.net.minecraft.core.BlockPositionHandle;
import com.bergerkiller.generated.net.minecraft.world.item.ItemStackHandle;
import com.bergerkiller.generated.net.minecraft.world.level.WorldHandle;
import com.bergerkiller.generated.net.minecraft.world.level.block.entity.TileEntitySignHandle;
class TileEntity {
#if version >= 1.17
@@ -238,11 +241,40 @@ class TileEntitySign extends TileEntity {
#endif
}
<code>
public static final Object[] ALL_EMPTY_RAW_LINES;
static {
Object raw_empty = ChatText.empty().getRawHandle();
ALL_EMPTY_RAW_LINES = new Object[] {raw_empty, raw_empty, raw_empty, raw_empty};
}
</code>
public Object[] getRawBackLines() {
#if version >= 1.20
return instance.getBackText().getMessages(false);
#else
return null;
return TileEntitySignHandle.ALL_EMPTY_RAW_LINES;
#endif
}
public void setFormattedFrontLine(int index, (ChatText) IChatBaseComponent text) {
#if version >= 1.20
instance.setText(instance.getFrontText().setMessage(index, text), true);
#elseif version >= 1.18
instance.setMessage(index, text);
instance.setChanged();
#elseif version >= 1.17
instance.a(index, text);
instance.update();
#else
instance.lines[index] = text;
instance.update();
#endif
}
public void setFormattedBackLine(int index, (ChatText) IChatBaseComponent text) {
#if version >= 1.20
instance.setText(instance.getBackText().setMessage(index, text), false);
#endif
}