mirror of https://github.com/GeyserMC/Geyser.git
restore offsets so we are sending correct values to the java server regarding where we want the structure to be placed
This commit is contained in:
parent
a30d49acba
commit
2aa6dce227
|
@ -610,8 +610,8 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||
private @Nullable Vector3i currentStructureBlock;
|
||||
|
||||
/**
|
||||
* Stores current structure block settings so we know what rotation to undo
|
||||
* if Bedrock decides to change the rotation
|
||||
* Is stored so we know which rotation/mirror offsetting to undo when sending
|
||||
* the structure load request to the Java server.
|
||||
*/
|
||||
@Setter @Getter
|
||||
private @Nullable StructureSettings structureSettings;
|
||||
|
|
|
@ -87,73 +87,16 @@ public class StructureBlockBlockEntityTranslator extends BlockEntityTranslator {
|
|||
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;
|
||||
newXStructureSize = xStructureSize * -1;
|
||||
} else if (bedrockMirror == (byte) StructureMirror.X.ordinal()) {
|
||||
posZ = posZ + zStructureSize;
|
||||
newZStructureSize = zStructureSize * -1;
|
||||
}
|
||||
|
||||
// Bedrock rotates with the same origin; Java does not
|
||||
StructureRotation structureRotation = StructureRotation.values()[bedrockRotation];
|
||||
switch (structureRotation) {
|
||||
case ROTATE_90 -> {
|
||||
if (xStructureSize >= 0) {
|
||||
posX += 1;
|
||||
}
|
||||
if (zStructureSize < 0) {
|
||||
posZ += 1;
|
||||
}
|
||||
posX -= zStructureSize;
|
||||
}
|
||||
case ROTATE_180 -> {
|
||||
if (xStructureSize >= 0) {
|
||||
posX += 1;
|
||||
}
|
||||
if (zStructureSize >= 0) {
|
||||
posZ += 1;
|
||||
}
|
||||
posX -= xStructureSize;
|
||||
posZ -= zStructureSize;
|
||||
}
|
||||
case ROTATE_270 -> {
|
||||
if (xStructureSize < 0) {
|
||||
posX += 1;
|
||||
}
|
||||
if (zStructureSize >= 0) {
|
||||
posZ += 1;
|
||||
}
|
||||
posZ -= xStructureSize;
|
||||
}
|
||||
default -> {
|
||||
if (xStructureSize < 0) {
|
||||
posX += 1;
|
||||
}
|
||||
if (zStructureSize < 0) {
|
||||
posZ += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
Vector3i offset = sizeAndOffset[0];
|
||||
builder.putInt("xStructureOffset", offset.getX());
|
||||
builder.putInt("yStructureOffset", offset.getY());
|
||||
builder.putInt("zStructureOffset", offset.getZ());
|
||||
|
||||
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
|
||||
|
|
|
@ -35,7 +35,6 @@ 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;
|
||||
|
@ -46,7 +45,6 @@ public class BedrockStructureBlockUpdateTranslator extends PacketTranslator<Stru
|
|||
|
||||
@Override
|
||||
public void translate(GeyserSession session, StructureBlockUpdatePacket packet) {
|
||||
GeyserImpl.getInstance().getLogger().info(packet.toString());
|
||||
StructureEditorData data = packet.getEditorData();
|
||||
StructureSettings settings = data.getSettings();
|
||||
|
||||
|
@ -66,10 +64,9 @@ public class BedrockStructureBlockUpdateTranslator extends PacketTranslator<Stru
|
|||
default -> UpdateStructureBlockMode.SAVE;
|
||||
};
|
||||
|
||||
// Ignore mirror - Java appears to mirror on an axis, while Bedrock mirrors in place
|
||||
StructureMirror mirror = switch (data.getSettings().getMirror()) {
|
||||
case X -> StructureMirror.FRONT_BACK;
|
||||
case XZ -> StructureMirror.LEFT_RIGHT;
|
||||
case Z -> StructureMirror.LEFT_RIGHT;
|
||||
default -> StructureMirror.NONE;
|
||||
};
|
||||
|
||||
|
|
|
@ -33,14 +33,14 @@ import com.github.steveice10.mc.protocol.packet.ingame.serverbound.inventory.Ser
|
|||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.protocol.bedrock.data.structure.StructureTemplateRequestOperation;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.StructureTemplateDataRequestPacket;
|
||||
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.
|
||||
* Packet used in Bedrock to load structure size into the structure block GUI. It is sent every time the GUI is opened.
|
||||
* Or, if the player updates the structure name. Which we can use to request the structure size from the Java server!
|
||||
* <p>
|
||||
* Java does not have this preview, instead, Java clients are forced out of the GUI to look at the area.
|
||||
*/
|
||||
|
@ -49,14 +49,10 @@ public class BedrockStructureTemplateDataRequestTranslator extends PacketTransla
|
|||
|
||||
@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
|
||||
|
|
|
@ -104,8 +104,8 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator<ClientboundB
|
|||
session.sendUpstreamPacket(openPacket);
|
||||
}
|
||||
|
||||
// On Java edition, if we are trying to load a structure, we expect the server to send us the size of the structure.
|
||||
// On 1.20.4, the server does here - we can pass that through to Bedrock so we're properly selecting the area selection
|
||||
// When a Java client is trying to load a structure, it expects the server to send it the size of the structure.
|
||||
// On 1.20.4, the server does so here - we can pass that through to Bedrock, so we're properly selecting the area.
|
||||
if (type == BlockEntityType.STRUCTURE_BLOCK && session.getGameMode() == GameMode.CREATIVE &&
|
||||
packet.getPosition().equals(session.getCurrentStructureBlock()) && packet.getNbt() != null && packet.getNbt().size() > 5) {
|
||||
CompoundTag map = packet.getNbt();
|
||||
|
@ -143,12 +143,13 @@ public class JavaBlockEntityDataTranslator extends PacketTranslator<ClientboundB
|
|||
Vector3i size = sizeAndOffset[1];
|
||||
StructureBlockUtils.sendStructureData(session, size.getX(), size.getY(), size.getZ(), name);
|
||||
|
||||
// Create dummy structure settings that store size, offset, mirror and rotation.
|
||||
StructureSettings settings = new StructureSettings("",
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
size,
|
||||
sizeAndOffset[1],
|
||||
sizeAndOffset[0],
|
||||
-1,
|
||||
StructureRotation.from(bedrockRotation),
|
||||
StructureMirror.from(bedrockMirror),
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.cloudburstmc.protocol.bedrock.data.structure.StructureTemplateRespons
|
|||
import org.cloudburstmc.protocol.bedrock.packet.StructureTemplateDataRequestPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.StructureTemplateDataResponsePacket;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.text.ChatColor;
|
||||
|
||||
public class StructureBlockUtils {
|
||||
|
||||
|
@ -79,57 +80,73 @@ public class StructureBlockUtils {
|
|||
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();
|
||||
Vector3i offset = old.getOffset();
|
||||
Vector3i size = old.getSize();
|
||||
|
||||
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;
|
||||
// First: Let's get the original size. It's not modified when rotating, just with mirroring
|
||||
int originalSizeX = size.getX();
|
||||
int originalSizeZ = size.getZ();
|
||||
|
||||
switch (old.getMirror()) {
|
||||
case X -> {
|
||||
originalSizeX *= -1;
|
||||
offsetX = offsetX - originalSizeX;
|
||||
}
|
||||
case Z -> {
|
||||
originalSizeZ *= -1;
|
||||
offsetZ = offsetZ - originalSizeZ;
|
||||
}
|
||||
case XZ -> session.sendMessage(ChatColor.RED + "Mirroring on both axis is not possible on Java. Not mirroring!");
|
||||
}
|
||||
|
||||
if (mirror == StructureMirror.Z) {
|
||||
offsetX = sizeX - 1 - offsetX;
|
||||
} else if (mirror == StructureMirror.X) {
|
||||
offsetZ = sizeZ - 1 - offsetZ;
|
||||
switch (old.getRotation()) {
|
||||
case ROTATE_90 -> {
|
||||
if (originalSizeX >= 0) {
|
||||
offsetX -= 1;
|
||||
}
|
||||
if (originalSizeZ < 0) {
|
||||
offsetZ -= 1;
|
||||
}
|
||||
offsetX += originalSizeZ;
|
||||
}
|
||||
case ROTATE_180 -> {
|
||||
if (originalSizeX >= 0) {
|
||||
offsetX -= 1;
|
||||
}
|
||||
if (originalSizeZ >= 0) {
|
||||
offsetZ -= 1;
|
||||
}
|
||||
offsetX += originalSizeX;
|
||||
offsetZ += originalSizeZ;
|
||||
}
|
||||
case ROTATE_270 -> {
|
||||
if (originalSizeX < 0) {
|
||||
offsetX -= 1;
|
||||
}
|
||||
if (originalSizeZ >= 0) {
|
||||
offsetZ -= 1;
|
||||
}
|
||||
offsetZ += originalSizeX;
|
||||
}
|
||||
default -> {
|
||||
if (originalSizeX < 0) {
|
||||
offsetX -= 1;
|
||||
}
|
||||
if (originalSizeZ < 0) {
|
||||
offsetZ -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new Vector3i[]{Vector3i.from(offsetX, offsetY, offsetZ), Vector3i.from(sizeX, sizeY, sizeZ)};
|
||||
Vector3i originalOffset = Vector3i.from(offsetX, offset.getY(), offsetZ);
|
||||
Vector3i originalSize = Vector3i.from(originalSizeX, size.getY(), originalSizeZ);
|
||||
|
||||
return new Vector3i[]{originalOffset, originalSize};
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static Vector3i[] addOffsets(byte bedrockRotation, byte bedrockMirror,
|
||||
|
@ -187,6 +204,9 @@ public class StructureBlockUtils {
|
|||
}
|
||||
}
|
||||
|
||||
return new Vector3i[]{Vector3i.from(offsetX, offsetY, offsetZ), Vector3i.from(newXStructureSize, sizeY, newZStructureSize)};
|
||||
Vector3i offset = Vector3i.from(offsetX, offsetY, offsetZ);
|
||||
Vector3i size = Vector3i.from(newXStructureSize, sizeY, newZStructureSize);
|
||||
|
||||
return new Vector3i[]{offset, size};
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue