use of com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundSignUpdatePacket in project Geyser by GeyserMC.
the class BedrockBlockEntityDataTranslator method translate.
@Override
public void translate(GeyserSession session, BlockEntityDataPacket packet) {
NbtMap tag = packet.getData();
String id = tag.getString("id");
if (id.equals("Sign")) {
String text = tag.getString("Text");
// So if the latest update does not match the last cached update then it's still being edited
if (!text.equals(session.getLastSignMessage())) {
session.setLastSignMessage(text);
return;
}
// Otherwise the two messages are identical and we can get to work deconstructing
StringBuilder newMessage = new StringBuilder();
// While Bedrock's sign lines are one string, Java's is an array of each line
// (Initialized all with empty strings because it complains about null)
String[] lines = new String[] { "", "", "", "" };
int iterator = 0;
// Keep track of the width of each character
// If it goes over the maximum, we need to start a new line to match Java
int widthCount = 0;
// This converts the message into the array'd message Java wants
for (char character : text.toCharArray()) {
widthCount += SignUtils.getCharacterWidth(character);
// If we get a return in Bedrock, or go over the character width max, that signals to use the next line.
if (character == '\n' || widthCount > SignUtils.JAVA_CHARACTER_WIDTH_MAX) {
// We need to apply some more logic if we went over the character width max
boolean wentOverMax = widthCount > SignUtils.JAVA_CHARACTER_WIDTH_MAX && character != '\n';
widthCount = 0;
// Saves if we're moving a word to the next line
String word = null;
if (wentOverMax && iterator < lines.length - 1) {
// If we went over the max, we want to try to wrap properly like Bedrock does.
// So we look for a space in the Bedrock user's text to imply a word.
int index = newMessage.lastIndexOf(" ");
if (index != -1) {
// There is indeed a space in this line; let's get it
word = newMessage.substring(index + 1);
// 'Delete' that word from the string builder
newMessage.delete(index, newMessage.length());
}
}
lines[iterator] = newMessage.toString();
iterator++;
// We don't care about that so we discard that
if (iterator > lines.length - 1) {
break;
}
newMessage = new StringBuilder();
if (wentOverMax) {
// Apply the wrapped word to the new line
if (word != null) {
newMessage.append(word);
// And apply the width count
for (char wordCharacter : word.toCharArray()) {
widthCount += SignUtils.getCharacterWidth(wordCharacter);
}
}
// If we went over the max, we want to append the character to the new line.
newMessage.append(character);
widthCount += SignUtils.getCharacterWidth(character);
}
} else
newMessage.append(character);
}
// Put the final line on since it isn't done in the for loop
if (iterator < lines.length)
lines[iterator] = newMessage.toString();
Position pos = new Position(tag.getInt("x"), tag.getInt("y"), tag.getInt("z"));
ServerboundSignUpdatePacket signUpdatePacket = new ServerboundSignUpdatePacket(pos, lines);
session.sendDownstreamPacket(signUpdatePacket);
// We set the sign text cached in the session to null to indicate there is no work-in-progress sign
session.setLastSignMessage(null);
} else if (id.equals("JigsawBlock")) {
// Client has just sent a jigsaw block update
Position pos = new Position(tag.getInt("x"), tag.getInt("y"), tag.getInt("z"));
String name = tag.getString("name");
String target = tag.getString("target");
String pool = tag.getString("target_pool");
String finalState = tag.getString("final_state");
String joint = tag.getString("joint");
ServerboundSetJigsawBlockPacket jigsawPacket = new ServerboundSetJigsawBlockPacket(pos, name, target, pool, finalState, joint);
session.sendDownstreamPacket(jigsawPacket);
}
}
Aggregations