mirror of https://github.com/GeyserMC/Geyser.git
init: send correct structure size/offset/rotation to java, not fully working yet
This commit is contained in:
parent
d1e4b31bce
commit
a30d49acba
|
@ -90,6 +90,7 @@ import org.cloudburstmc.protocol.bedrock.data.command.CommandPermission;
|
|||
import org.cloudburstmc.protocol.bedrock.data.command.SoftEnumUpdateType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.structure.StructureSettings;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.*;
|
||||
import org.cloudburstmc.protocol.common.DefinitionRegistry;
|
||||
import org.cloudburstmc.protocol.common.util.OptionalBoolean;
|
||||
|
@ -608,6 +609,13 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||
@Setter @Getter
|
||||
private @Nullable Vector3i currentStructureBlock;
|
||||
|
||||
/**
|
||||
* Stores current structure block settings so we know what rotation to undo
|
||||
* if Bedrock decides to change the rotation
|
||||
*/
|
||||
@Setter @Getter
|
||||
private @Nullable StructureSettings structureSettings;
|
||||
|
||||
private final GeyserCameraData cameraData;
|
||||
|
||||
private final GeyserEntityData entityData;
|
||||
|
|
|
@ -27,18 +27,15 @@ package org.geysermc.geyser.translator.level.block.entity;
|
|||
|
||||
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtUtils;
|
||||
import org.cloudburstmc.protocol.bedrock.data.structure.StructureMirror;
|
||||
import org.cloudburstmc.protocol.bedrock.data.structure.StructureRotation;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.util.StructureBlockUtils;
|
||||
|
||||
@BlockEntity(type = BlockEntityType.STRUCTURE_BLOCK)
|
||||
public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator {
|
||||
|
||||
@Override
|
||||
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {
|
||||
GeyserImpl.getInstance().getLogger().info(NbtUtils.toString(tag));
|
||||
if (tag.size() < 5) {
|
||||
return; // These values aren't here
|
||||
}
|
||||
|
@ -81,13 +78,20 @@ public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator {
|
|||
|
||||
int xStructureSize = getOrDefault(tag.get("sizeX"), 0);
|
||||
int zStructureSize = getOrDefault(tag.get("sizeZ"), 0);
|
||||
int newXStructureSize = xStructureSize;
|
||||
int newZStructureSize = zStructureSize;
|
||||
|
||||
// The "positions" are also offsets on Java
|
||||
int posX = getOrDefault(tag.get("posX"), 0);
|
||||
int posZ = getOrDefault(tag.get("posZ"), 0);
|
||||
|
||||
Vector3i[] sizeAndOffset = StructureBlockUtils.addOffsets(bedrockRotation, bedrockMirror,
|
||||
xStructureSize, getOrDefault(tag.get("sizeY"), 0), zStructureSize,
|
||||
posX, getOrDefault(tag.get("posY"), 0), posZ);
|
||||
|
||||
/*
|
||||
|
||||
int newXStructureSize = xStructureSize;
|
||||
int newZStructureSize = zStructureSize;
|
||||
|
||||
// Modify positions if mirrored - Bedrock doesn't have this
|
||||
if (bedrockMirror == (byte) StructureMirror.Z.ordinal()) {
|
||||
posX = posX + xStructureSize;
|
||||
|
@ -138,17 +142,20 @@ public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator {
|
|||
}
|
||||
}
|
||||
|
||||
builder.putInt("xStructureSize", newXStructureSize);
|
||||
builder.putInt("yStructureSize", getOrDefault(tag.get("sizeY"), 0));
|
||||
builder.putInt("zStructureSize", newZStructureSize);
|
||||
*/
|
||||
|
||||
builder.putInt("xStructureOffset", posX);
|
||||
builder.putInt("yStructureOffset", getOrDefault(tag.get("posY"), 0));
|
||||
builder.putInt("zStructureOffset", posZ);
|
||||
Vector3i size = sizeAndOffset[1];
|
||||
builder.putInt("xStructureSize", size.getX());
|
||||
builder.putInt("yStructureSize", size.getY());
|
||||
builder.putInt("zStructureSize", size.getZ());
|
||||
|
||||
Vector3i offset = sizeAndOffset[0];
|
||||
builder.putInt("xStructureOffset", offset.getX());
|
||||
builder.putInt("yStructureOffset", offset.getY());
|
||||
builder.putInt("zStructureOffset", offset.getZ());
|
||||
|
||||
builder.putFloat("integrity", getOrDefault(tag.get("integrity"), 0f)); // Is 1.0f by default on Java but 100.0f on Bedrock
|
||||
|
||||
// Java's "showair" is unrepresented
|
||||
GeyserImpl.getInstance().getLogger().error(builder.toString());
|
||||
}
|
||||
}
|
|
@ -30,19 +30,23 @@ import com.github.steveice10.mc.protocol.data.game.inventory.UpdateStructureBloc
|
|||
import com.github.steveice10.mc.protocol.data.game.level.block.StructureMirror;
|
||||
import com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetStructureBlockPacket;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.protocol.bedrock.data.structure.StructureBlockType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.structure.StructureEditorData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.structure.StructureSettings;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.StructureBlockUpdatePacket;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
import org.geysermc.geyser.util.StructureBlockUtils;
|
||||
|
||||
@Translator(packet = StructureBlockUpdatePacket.class)
|
||||
public class BedrockStructureBlockUpdateTranslator extends PacketTranslator<StructureBlockUpdatePacket> {
|
||||
|
||||
@Override
|
||||
public void translate(GeyserSession session, StructureBlockUpdatePacket packet) {
|
||||
GeyserImpl.getInstance().getLogger().info(packet.toString());
|
||||
StructureEditorData data = packet.getEditorData();
|
||||
StructureSettings settings = data.getSettings();
|
||||
|
||||
|
@ -63,7 +67,11 @@ public class BedrockStructureBlockUpdateTranslator extends PacketTranslator<Stru
|
|||
};
|
||||
|
||||
// Ignore mirror - Java appears to mirror on an axis, while Bedrock mirrors in place
|
||||
StructureMirror mirror = StructureMirror.NONE;
|
||||
StructureMirror mirror = switch (data.getSettings().getMirror()) {
|
||||
case X -> StructureMirror.FRONT_BACK;
|
||||
case XZ -> StructureMirror.LEFT_RIGHT;
|
||||
default -> StructureMirror.NONE;
|
||||
};
|
||||
|
||||
com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation rotation = switch (settings.getRotation()) {
|
||||
case ROTATE_90 -> StructureRotation.CLOCKWISE_90;
|
||||
|
@ -72,13 +80,15 @@ public class BedrockStructureBlockUpdateTranslator extends PacketTranslator<Stru
|
|||
default -> StructureRotation.NONE;
|
||||
};
|
||||
|
||||
Vector3i[] offsetAndSize = StructureBlockUtils.getStructureOffsetAndRotation(session, settings);
|
||||
|
||||
ServerboundSetStructureBlockPacket structureBlockPacket = new ServerboundSetStructureBlockPacket(
|
||||
packet.getBlockPosition(),
|
||||
action,
|
||||
mode,
|
||||
data.getName(),
|
||||
settings.getOffset(),
|
||||
settings.getSize(),
|
||||
offsetAndSize[0],
|
||||
offsetAndSize[1],
|
||||
mirror,
|
||||
rotation,
|
||||
"",
|
||||
|
@ -89,6 +99,7 @@ public class BedrockStructureBlockUpdateTranslator extends PacketTranslator<Stru
|
|||
data.isBoundingBoxVisible()
|
||||
);
|
||||
|
||||
session.setStructureSettings(null);
|
||||
session.sendDownstreamPacket(structureBlockPacket);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,18 +31,13 @@ import com.github.steveice10.mc.protocol.data.game.level.block.StructureMirror;
|
|||
import com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.ServerboundSetStructureBlockPacket;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.nbt.NbtList;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.structure.StructureTemplateRequestOperation;
|
||||
import org.cloudburstmc.protocol.bedrock.data.structure.StructureTemplateResponseType;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.StructureTemplateDataRequestPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.StructureTemplateDataResponsePacket;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
import org.geysermc.geyser.util.StructureBlockUtils;
|
||||
|
||||
/**
|
||||
* Packet used in Bedrock to load structure size into the structure block GUI.
|
||||
|
@ -52,33 +47,25 @@ import org.geysermc.geyser.translator.protocol.Translator;
|
|||
@Translator(packet = StructureTemplateDataRequestPacket.class)
|
||||
public class BedrockStructureTemplateDataRequestTranslator extends PacketTranslator<StructureTemplateDataRequestPacket> {
|
||||
|
||||
private static final NbtMap EMPTY_STRUCTURE_DATA;
|
||||
|
||||
static {
|
||||
NbtMapBuilder builder = NbtMap.builder();
|
||||
builder.putInt("format_version", 1);
|
||||
builder.putCompound("structure", NbtMap.builder()
|
||||
.putList("block_indices", NbtType.LIST, NbtList.EMPTY, NbtList.EMPTY)
|
||||
.putList("entities", NbtType.COMPOUND)
|
||||
.putCompound("palette", NbtMap.EMPTY)
|
||||
.build());
|
||||
builder.putList("structure_world_origin", NbtType.INT, 0, 0, 0);
|
||||
EMPTY_STRUCTURE_DATA = builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GeyserSession session, StructureTemplateDataRequestPacket packet) {
|
||||
// This packet is actually rather neat. Each time Bedrock players open the structure block,
|
||||
// it is sent. Which allows us to cache what rotation operation we might need to (un)do :p
|
||||
GeyserImpl.getInstance().getLogger().info(packet.toString());
|
||||
if (packet.getOperation().equals(StructureTemplateRequestOperation.QUERY_SAVED_STRUCTURE)) {
|
||||
// If we send a load packet to the Java server when the structure size is known, we place the structure.
|
||||
if (!packet.getSettings().getSize().equals(Vector3i.ZERO)) {
|
||||
if (session.getStructureSettings() == null) {
|
||||
// This ensures we don't add more rotation offsetting than needed
|
||||
session.setStructureSettings(packet.getSettings());
|
||||
}
|
||||
// Otherwise, the Bedrock client can't load the structure in
|
||||
sendEmptyStructureData(session, packet);
|
||||
StructureBlockUtils.sendEmptyStructureData(session, packet);
|
||||
return;
|
||||
}
|
||||
session.setCurrentStructureBlock(packet.getPosition());
|
||||
|
||||
// Request a "load" from Java server so it sends us the structures size :p
|
||||
// Request a "load" from Java server, so it sends us the structure's size :p
|
||||
var settings = packet.getSettings();
|
||||
com.github.steveice10.mc.protocol.data.game.level.block.StructureRotation rotation = switch (settings.getRotation()) {
|
||||
case ROTATE_90 -> StructureRotation.CLOCKWISE_90;
|
||||
|
@ -105,19 +92,7 @@ public class BedrockStructureTemplateDataRequestTranslator extends PacketTransla
|
|||
);
|
||||
session.sendDownstreamPacket(structureBlockPacket);
|
||||
} else {
|
||||
sendEmptyStructureData(session, packet);
|
||||
StructureBlockUtils.sendEmptyStructureData(session, packet);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendEmptyStructureData(GeyserSession session, StructureTemplateDataRequestPacket packet) {
|
||||
StructureTemplateDataResponsePacket responsePacket = new StructureTemplateDataResponsePacket();
|
||||
responsePacket.setName(packet.getName());
|
||||
responsePacket.setSave(true);
|
||||
responsePacket.setTag(EMPTY_STRUCTURE_DATA.toBuilder()
|
||||
.putList("size", NbtType.INT, packet.getSettings().getSize().getX(),
|
||||
packet.getSettings().getSize().getY(), packet.getSettings().getSize().getZ())
|
||||
.build());
|
||||
responsePacket.setType(StructureTemplateResponseType.QUERY);
|
||||
session.sendUpstreamPacket(responsePacket);
|
||||
}
|
||||
}
|
|
@ -30,18 +30,16 @@ import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
|
|||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundBlockEntityDataPacket;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.nbt.NbtList;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.structure.StructureTemplateResponseType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.structure.StructureAnimationMode;
|
||||
import org.cloudburstmc.protocol.bedrock.data.structure.StructureMirror;
|
||||
import org.cloudburstmc.protocol.bedrock.data.structure.StructureRotation;
|
||||
import org.cloudburstmc.protocol.bedrock.data.structure.StructureSettings;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.ContainerOpenPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.StructureTemplateDataResponsePacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator;
|
||||
|
@ -50,24 +48,11 @@ import org.geysermc.geyser.translator.level.block.entity.SkullBlockEntityTransla
|
|||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
import org.geysermc.geyser.util.BlockEntityUtils;
|
||||
import org.geysermc.geyser.util.StructureBlockUtils;
|
||||
|
||||
@Translator(packet = ClientboundBlockEntityDataPacket.class)
|
||||
public class JavaBlockEntityDataTranslator extends PacketTranslator<ClientboundBlockEntityDataPacket> {
|
||||
|
||||
private static final NbtMap EMPTY_STRUCTURE_DATA;
|
||||
|
||||
static {
|
||||
NbtMapBuilder builder = NbtMap.builder();
|
||||
builder.putInt("format_version", 1);
|
||||
builder.putCompound("structure", NbtMap.builder()
|
||||
.putList("block_indices", NbtType.LIST, NbtList.EMPTY, NbtList.EMPTY)
|
||||
.putList("entities", NbtType.COMPOUND)
|
||||
.putCompound("palette", NbtMap.EMPTY)
|
||||
.build());
|
||||
builder.putList("structure_world_origin", NbtType.INT, 0, 0, 0);
|
||||
EMPTY_STRUCTURE_DATA = builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(GeyserSession session, ClientboundBlockEntityDataPacket packet) {
|
||||
final BlockEntityType type = packet.getType();
|
||||
|
@ -130,20 +115,46 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator<ClientboundB
|
|||
return;
|
||||
}
|
||||
|
||||
int x = getOrDefault(map.get("sizeX"), 0);
|
||||
int y = getOrDefault(map.get("sizeY"), 0);
|
||||
int z = getOrDefault(map.get("sizeZ"), 0);
|
||||
String mirror = getOrDefault(map.get("mirror"), "");
|
||||
byte bedrockMirror = switch (mirror) {
|
||||
case "LEFT_RIGHT" -> 1;
|
||||
case "FRONT_BACK" -> 2;
|
||||
default -> 0; // Or NONE
|
||||
};
|
||||
|
||||
StructureTemplateDataResponsePacket responsePacket = new StructureTemplateDataResponsePacket();
|
||||
responsePacket.setName(getOrDefault(map.get("name"), " "));
|
||||
responsePacket.setSave(true);
|
||||
responsePacket.setTag(EMPTY_STRUCTURE_DATA.toBuilder()
|
||||
.putList("size", NbtType.INT, x, y, z)
|
||||
.build());
|
||||
responsePacket.setType(StructureTemplateResponseType.QUERY);
|
||||
GeyserImpl.getInstance().getLogger().info(responsePacket.toString());
|
||||
session.sendUpstreamPacket(responsePacket);
|
||||
String rotation = getOrDefault(map.get("rotation"), "");
|
||||
byte bedrockRotation = switch (rotation) {
|
||||
case "CLOCKWISE_90" -> 1;
|
||||
case "CLOCKWISE_180" -> 2;
|
||||
case "COUNTERCLOCKWISE_90" -> 3;
|
||||
default -> 0; // Or NONE keep it as 0
|
||||
};
|
||||
|
||||
// The "positions" are also offsets on Java
|
||||
int posX = getOrDefault(map.get("posX"), 0);
|
||||
int posZ = getOrDefault(map.get("posZ"), 0);
|
||||
|
||||
Vector3i[] sizeAndOffset = StructureBlockUtils.addOffsets(bedrockRotation, bedrockMirror,
|
||||
getOrDefault(map.get("sizeX"), 0), getOrDefault(map.get("sizeY"), 0),
|
||||
getOrDefault(map.get("sizeZ"), 0), posX, getOrDefault(map.get("posY"), 0), posZ);
|
||||
|
||||
String name = getOrDefault(map.get("name"), "");
|
||||
|
||||
Vector3i size = sizeAndOffset[1];
|
||||
StructureBlockUtils.sendStructureData(session, size.getX(), size.getY(), size.getZ(), name);
|
||||
|
||||
StructureSettings settings = new StructureSettings("",
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
size,
|
||||
sizeAndOffset[1],
|
||||
-1,
|
||||
StructureRotation.from(bedrockRotation),
|
||||
StructureMirror.from(bedrockMirror),
|
||||
StructureAnimationMode.NONE,
|
||||
0, 0, 0, Vector3f.ZERO);
|
||||
session.setStructureSettings(settings);
|
||||
session.setCurrentStructureBlock(null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2024 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.geyser.util;
|
||||
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.nbt.NbtList;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.structure.StructureMirror;
|
||||
import org.cloudburstmc.protocol.bedrock.data.structure.StructureRotation;
|
||||
import org.cloudburstmc.protocol.bedrock.data.structure.StructureSettings;
|
||||
import org.cloudburstmc.protocol.bedrock.data.structure.StructureTemplateResponseType;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.StructureTemplateDataRequestPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.StructureTemplateDataResponsePacket;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
||||
public class StructureBlockUtils {
|
||||
|
||||
private static final NbtMap EMPTY_STRUCTURE_DATA;
|
||||
|
||||
static {
|
||||
NbtMapBuilder builder = NbtMap.builder();
|
||||
builder.putInt("format_version", 1);
|
||||
builder.putCompound("structure", NbtMap.builder()
|
||||
.putList("block_indices", NbtType.LIST, NbtList.EMPTY, NbtList.EMPTY)
|
||||
.putList("entities", NbtType.COMPOUND)
|
||||
.putCompound("palette", NbtMap.EMPTY)
|
||||
.build());
|
||||
builder.putList("structure_world_origin", NbtType.INT, 0, 0, 0);
|
||||
EMPTY_STRUCTURE_DATA = builder.build();
|
||||
}
|
||||
|
||||
public static void sendEmptyStructureData(GeyserSession session, StructureTemplateDataRequestPacket packet) {
|
||||
sendStructureData(session, packet.getSettings().getSize().getX(),
|
||||
packet.getSettings().getSize().getY(),
|
||||
packet.getSettings().getSize().getZ(),
|
||||
packet.getName());
|
||||
}
|
||||
|
||||
public static void sendStructureData(GeyserSession session, int x, int y, int z, String name) {
|
||||
StructureTemplateDataResponsePacket responsePacket = new StructureTemplateDataResponsePacket();
|
||||
responsePacket.setName(name);
|
||||
responsePacket.setSave(true);
|
||||
responsePacket.setTag(EMPTY_STRUCTURE_DATA.toBuilder()
|
||||
.putList("size", NbtType.INT, x, y, z)
|
||||
.build());
|
||||
responsePacket.setType(StructureTemplateResponseType.QUERY);
|
||||
session.sendUpstreamPacket(responsePacket);
|
||||
}
|
||||
|
||||
public static Vector3i[] getStructureOffsetAndRotation(GeyserSession session, StructureSettings newSettings) {
|
||||
StructureSettings old = session.getStructureSettings();
|
||||
|
||||
if (old == null) {
|
||||
return new Vector3i[] {newSettings.getOffset(), newSettings.getSize()};
|
||||
}
|
||||
|
||||
// Remove offsets for old
|
||||
return removeOffset(old.getRotation(), old.getMirror(), old.getOffset(), old.getSize());
|
||||
|
||||
// Remove offsets for new
|
||||
//return removeOffset(newSettings.getRotation(), newSettings.getMirror(), temp[0], temp[1]);
|
||||
|
||||
}
|
||||
|
||||
private static Vector3i[] removeOffset(StructureRotation rotation, StructureMirror mirror,
|
||||
Vector3i offset, Vector3i size) {
|
||||
int sizeX = size.getX();
|
||||
int sizeY = size.getY();
|
||||
int sizeZ = size.getZ();
|
||||
|
||||
int offsetX = offset.getX();
|
||||
int offsetY = offset.getY();
|
||||
int offsetZ = offset.getZ();
|
||||
|
||||
// Undo mirror/rotation changes
|
||||
switch (rotation) {
|
||||
case NONE:
|
||||
break;
|
||||
case ROTATE_90:
|
||||
int tempX = offsetX;
|
||||
offsetX = offsetZ;
|
||||
offsetZ = sizeX - 1 - tempX;
|
||||
int tempSizeX = sizeX;
|
||||
sizeX = sizeZ;
|
||||
sizeZ = tempSizeX;
|
||||
break;
|
||||
case ROTATE_180:
|
||||
offsetX = sizeX - 1 - offsetX;
|
||||
offsetZ = sizeZ - 1 - offsetZ;
|
||||
break;
|
||||
case ROTATE_270:
|
||||
int tempY = offsetY;
|
||||
offsetY = offsetZ;
|
||||
offsetZ = sizeZ - 1 - tempY;
|
||||
int tempSizeZ = sizeZ;
|
||||
sizeZ = sizeX;
|
||||
sizeX = tempSizeZ;
|
||||
break;
|
||||
}
|
||||
|
||||
if (mirror == StructureMirror.Z) {
|
||||
offsetX = sizeX - 1 - offsetX;
|
||||
} else if (mirror == StructureMirror.X) {
|
||||
offsetZ = sizeZ - 1 - offsetZ;
|
||||
}
|
||||
|
||||
return new Vector3i[]{Vector3i.from(offsetX, offsetY, offsetZ), Vector3i.from(sizeX, sizeY, sizeZ)};
|
||||
}
|
||||
|
||||
public static Vector3i[] addOffsets(byte bedrockRotation, byte bedrockMirror,
|
||||
int sizeX, int sizeY, int sizeZ, int offsetX, int offsetY, int offsetZ) {
|
||||
int newXStructureSize = sizeX;
|
||||
int newZStructureSize = sizeZ;
|
||||
|
||||
// Modify positions if mirrored - Bedrock doesn't have this
|
||||
if (bedrockMirror == (byte) StructureMirror.Z.ordinal()) {
|
||||
offsetX = offsetX + sizeX;
|
||||
newXStructureSize = sizeX * -1;
|
||||
} else if (bedrockMirror == (byte) StructureMirror.X.ordinal()) {
|
||||
offsetZ = offsetZ + sizeZ;
|
||||
newZStructureSize = sizeZ * -1;
|
||||
}
|
||||
|
||||
// Bedrock rotates with the same origin; Java does not
|
||||
StructureRotation structureRotation = StructureRotation.values()[bedrockRotation];
|
||||
switch (structureRotation) {
|
||||
case ROTATE_90 -> {
|
||||
if (sizeX >= 0) {
|
||||
offsetX += 1;
|
||||
}
|
||||
if (sizeZ < 0) {
|
||||
offsetZ += 1;
|
||||
}
|
||||
offsetX -= sizeZ;
|
||||
}
|
||||
case ROTATE_180 -> {
|
||||
if (sizeX >= 0) {
|
||||
offsetX += 1;
|
||||
}
|
||||
if (sizeZ >= 0) {
|
||||
offsetZ += 1;
|
||||
}
|
||||
offsetX -= sizeX;
|
||||
offsetZ -= sizeZ;
|
||||
}
|
||||
case ROTATE_270 -> {
|
||||
if (sizeX < 0) {
|
||||
offsetX += 1;
|
||||
}
|
||||
if (sizeZ >= 0) {
|
||||
offsetZ += 1;
|
||||
}
|
||||
offsetZ -= sizeX;
|
||||
}
|
||||
default -> {
|
||||
if (sizeX < 0) {
|
||||
offsetX += 1;
|
||||
}
|
||||
if (sizeZ < 0) {
|
||||
offsetZ += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new Vector3i[]{Vector3i.from(offsetX, offsetY, offsetZ), Vector3i.from(newXStructureSize, sizeY, newZStructureSize)};
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue