use of com.nukkitx.nbt.NbtMap in project ProxyPass by CloudburstMC.
the class BlockPaletteUtils method convertToJson.
public static void convertToJson(ProxyPass proxy, List<NbtMap> tags) {
List<NbtMap> palette = new ArrayList<>(tags);
palette.sort((o1, o2) -> {
int compare = Integer.compare(o1.getShort("id"), o2.getShort("id"));
if (compare == 0) {
NbtMap states1 = o1.getCompound("block").getCompound("states");
NbtMap states2 = o2.getCompound("block").getCompound("states");
for (Map.Entry<String, Object> entry : states1.entrySet()) {
Object bs2 = states2.get(entry.getKey());
compare = ((Comparable) entry.getValue()).compareTo(bs2);
if (compare != 0) {
break;
}
}
}
return compare;
});
proxy.saveMojangson("runtime_block_states.mojangson", NbtMap.builder().putList("palette", NbtType.COMPOUND, palette).build());
// Get all block states
Map<String, Set<Object>> blockTraits = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
for (NbtMap tag : tags) {
NbtMap map = tag.getCompound("block").getCompound("states");
map.forEach((trait, value) -> {
blockTraits.computeIfAbsent(trait, s -> new HashSet<>()).add(value);
});
}
proxy.saveJson("block_traits.json", blockTraits);
}
use of com.nukkitx.nbt.NbtMap 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);
}
}
use of com.nukkitx.nbt.NbtMap in project Geyser by GeyserMC.
the class FlowerPotBlockEntityTranslator method updateBlock.
@Override
public void updateBlock(GeyserSession session, int blockState, Vector3i position) {
NbtMap tag = getTag(session, blockState, position);
BlockEntityUtils.updateBlockEntity(session, tag, position);
UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
updateBlockPacket.setDataLayer(0);
updateBlockPacket.setRuntimeId(session.getBlockMappings().getBedrockBlockId(blockState));
updateBlockPacket.setBlockPosition(position);
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS);
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK);
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.PRIORITY);
session.sendUpstreamPacket(updateBlockPacket);
BlockEntityUtils.updateBlockEntity(session, tag, position);
}
use of com.nukkitx.nbt.NbtMap in project Geyser by GeyserMC.
the class LecternInventoryTranslator method updateBook.
/**
* Translate the data of the book in the lectern into a block entity tag.
*/
private void updateBook(GeyserSession session, Inventory inventory, GeyserItemStack book) {
LecternContainer lecternContainer = (LecternContainer) inventory;
if (session.isDroppingLecternBook()) {
// We have to enter the inventory GUI to eject the book
ServerboundContainerButtonClickPacket packet = new ServerboundContainerButtonClickPacket(inventory.getId(), 3);
session.sendDownstreamPacket(packet);
session.setDroppingLecternBook(false);
InventoryUtils.closeInventory(session, inventory.getId(), false);
} else if (lecternContainer.getBlockEntityTag() == null) {
CompoundTag tag = book.getNbt();
// Position has to be the last interacted position... right?
Vector3i position = session.getLastInteractionBlockPosition();
// If shouldExpectLecternHandled returns true, this is already handled for us
// shouldRefresh means that we should boot out the client on our side because their lectern GUI isn't updated yet
boolean shouldRefresh = !session.getGeyser().getWorldManager().shouldExpectLecternHandled() && !session.getLecternCache().contains(position);
NbtMap blockEntityTag;
if (tag != null) {
int pagesSize = ((ListTag) tag.get("pages")).size();
ItemData itemData = book.getItemData(session);
NbtMapBuilder lecternTag = getBaseLecternTag(position.getX(), position.getY(), position.getZ(), pagesSize);
lecternTag.putCompound("book", NbtMap.builder().putByte("Count", (byte) itemData.getCount()).putShort("Damage", (short) 0).putString("Name", "minecraft:written_book").putCompound("tag", itemData.getTag()).build());
lecternTag.putInt("page", lecternContainer.getCurrentBedrockPage());
blockEntityTag = lecternTag.build();
} else {
// There is *a* book here, but... no NBT.
NbtMapBuilder lecternTag = getBaseLecternTag(position.getX(), position.getY(), position.getZ(), 1);
NbtMapBuilder bookTag = NbtMap.builder().putByte("Count", (byte) 1).putShort("Damage", (short) 0).putString("Name", "minecraft:writable_book").putCompound("tag", NbtMap.builder().putList("pages", NbtType.COMPOUND, Collections.singletonList(NbtMap.builder().putString("photoname", "").putString("text", "").build())).build());
blockEntityTag = lecternTag.putCompound("book", bookTag.build()).build();
}
// Even with serverside access to lecterns, we don't easily know which lectern this is, so we need to rebuild
// the block entity tag
lecternContainer.setBlockEntityTag(blockEntityTag);
lecternContainer.setPosition(position);
if (shouldRefresh) {
// Update the lectern because it's not updated client-side
BlockEntityUtils.updateBlockEntity(session, blockEntityTag, position);
session.getLecternCache().add(position);
// Close the window - we will reopen it once the client has this data synced
ServerboundContainerClosePacket closeWindowPacket = new ServerboundContainerClosePacket(lecternContainer.getId());
session.sendDownstreamPacket(closeWindowPacket);
InventoryUtils.closeInventory(session, inventory.getId(), false);
}
}
}
use of com.nukkitx.nbt.NbtMap in project Geyser by GeyserMC.
the class DoubleChestInventoryTranslator method prepareInventory.
@Override
public void prepareInventory(GeyserSession session, Inventory inventory) {
// See BlockInventoryHolder - same concept there except we're also dealing with a specific block state
if (session.getLastInteractionPlayerPosition().equals(session.getPlayerEntity().getPosition())) {
int javaBlockId = session.getGeyser().getWorldManager().getBlockAt(session, session.getLastInteractionBlockPosition());
String[] javaBlockString = BlockRegistries.JAVA_IDENTIFIERS.get().getOrDefault(javaBlockId, "minecraft:air").split("\\[");
if (javaBlockString.length > 1 && (javaBlockString[0].equals("minecraft:chest") || javaBlockString[0].equals("minecraft:trapped_chest")) && !javaBlockString[1].contains("type=single")) {
inventory.setHolderPosition(session.getLastInteractionBlockPosition());
((Container) inventory).setUsingRealBlock(true, javaBlockString[0]);
NbtMapBuilder tag = NbtMap.builder().putString("id", "Chest").putInt("x", session.getLastInteractionBlockPosition().getX()).putInt("y", session.getLastInteractionBlockPosition().getY()).putInt("z", session.getLastInteractionBlockPosition().getZ()).putString("CustomName", inventory.getTitle()).putString("id", "Chest");
DoubleChestValue chestValue = BlockStateValues.getDoubleChestValues().get(javaBlockId);
DoubleChestBlockEntityTranslator.translateChestValue(tag, chestValue, session.getLastInteractionBlockPosition().getX(), session.getLastInteractionBlockPosition().getZ());
BlockEntityDataPacket dataPacket = new BlockEntityDataPacket();
dataPacket.setData(tag.build());
dataPacket.setBlockPosition(session.getLastInteractionBlockPosition());
session.sendUpstreamPacket(dataPacket);
return;
}
}
Vector3i position = session.getPlayerEntity().getPosition().toInt().add(Vector3i.UP);
Vector3i pairPosition = position.add(Vector3i.UNIT_X);
int bedrockBlockId = session.getBlockMappings().getBedrockBlockId(defaultJavaBlockState);
UpdateBlockPacket blockPacket = new UpdateBlockPacket();
blockPacket.setDataLayer(0);
blockPacket.setBlockPosition(position);
blockPacket.setRuntimeId(bedrockBlockId);
blockPacket.getFlags().addAll(UpdateBlockPacket.FLAG_ALL_PRIORITY);
session.sendUpstreamPacket(blockPacket);
NbtMap tag = NbtMap.builder().putString("id", "Chest").putInt("x", position.getX()).putInt("y", position.getY()).putInt("z", position.getZ()).putInt("pairx", pairPosition.getX()).putInt("pairz", pairPosition.getZ()).putString("CustomName", inventory.getTitle()).build();
BlockEntityDataPacket dataPacket = new BlockEntityDataPacket();
dataPacket.setData(tag);
dataPacket.setBlockPosition(position);
session.sendUpstreamPacket(dataPacket);
blockPacket = new UpdateBlockPacket();
blockPacket.setDataLayer(0);
blockPacket.setBlockPosition(pairPosition);
blockPacket.setRuntimeId(bedrockBlockId);
blockPacket.getFlags().addAll(UpdateBlockPacket.FLAG_ALL_PRIORITY);
session.sendUpstreamPacket(blockPacket);
tag = NbtMap.builder().putString("id", "Chest").putInt("x", pairPosition.getX()).putInt("y", pairPosition.getY()).putInt("z", pairPosition.getZ()).putInt("pairx", position.getX()).putInt("pairz", position.getZ()).putString("CustomName", inventory.getTitle()).build();
dataPacket = new BlockEntityDataPacket();
dataPacket.setData(tag);
dataPacket.setBlockPosition(pairPosition);
session.sendUpstreamPacket(dataPacket);
inventory.setHolderPosition(position);
}
Aggregations