diff --git a/src/main/java/minescript/block/entity/TurtleBlockEntity.java b/src/main/java/minescript/block/entity/TurtleBlockEntity.java index d6888cc..0e466f2 100644 --- a/src/main/java/minescript/block/entity/TurtleBlockEntity.java +++ b/src/main/java/minescript/block/entity/TurtleBlockEntity.java @@ -31,6 +31,10 @@ public void setTurtleInput(String input) { this.markDirty(); } + public String getTurtleInput () { + return this.input.getString(); + } + @Override public void writeNbt(NbtCompound nbt) { String text = input.getString(); @@ -61,9 +65,6 @@ public void readNbt(NbtCompound nbt) { @Override public void writeScreenOpeningData(ServerPlayerEntity player, PacketByteBuf buf) { - String text = this.input.getString(); - buf.writeInt(text.length()); - buf.writeString(text, text.length()); } @Override diff --git a/src/main/java/minescript/screen/TextEditorScreen.java b/src/main/java/minescript/screen/TextEditorScreen.java index 96a519d..35aa758 100644 --- a/src/main/java/minescript/screen/TextEditorScreen.java +++ b/src/main/java/minescript/screen/TextEditorScreen.java @@ -1,25 +1,23 @@ package minescript.screen; -import io.netty.buffer.ByteBuf; -import io.wispforest.owo.client.screens.ScreenInternals; import io.wispforest.owo.ui.base.BaseUIModelHandledScreen; import io.wispforest.owo.ui.base.BaseUIModelScreen; import io.wispforest.owo.ui.component.ButtonComponent; import io.wispforest.owo.ui.container.FlowLayout; -import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; import net.minecraft.client.gui.widget.EditBoxWidget; +import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.player.PlayerInventory; -import net.minecraft.nbt.NbtCompound; import net.minecraft.network.PacketByteBuf; import net.minecraft.text.Text; import net.minecraft.util.Identifier; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; public class TextEditorScreen extends BaseUIModelHandledScreen { + private EditBoxWidget editor; + private boolean isTriggerSent = false; + private boolean isTextSet = false; public TextEditorScreen(TextEditorScreenHandler handler, PlayerInventory inventory, Text title) { // super(handler, inventory, title, FlowLayout.class, BaseUIModelScreen.DataSource.file("../src/main/resources/assets/minescript/owo_ui/editor.xml")); // For development @@ -29,11 +27,11 @@ public TextEditorScreen(TextEditorScreenHandler handler, PlayerInventory invento @Override protected void build(FlowLayout rootComponent) { - var editor = rootComponent.childById(EditBoxWidget.class, "edit-box"); + editor = rootComponent.childById(EditBoxWidget.class, "edit-box"); if (editor == null) throw new NullPointerException("editor is null"); editor.active = true; - editor.setText(handler.getInputText()); + editor.mouseDown().subscribe((mouseX, mouseY, button) -> { editor.setFocused(true); @@ -69,6 +67,21 @@ protected void build(FlowLayout rootComponent) { handler.sendMessage(new TextEditorScreenHandler.StartInterpreterMessage(text.length(), buf)); this.close(); }); + + } + + @Override + public void render (MatrixStack matrices, int mouseX, int mouseY, float delta) { + if (!isTextSet && handler.isClientTextUpdated()) { + editor.setText(handler.getInputText()); + isTextSet = true; + } + + if (!isTriggerSent) { + handler.sendMessage(new TextEditorScreenHandler.TriggerSendInputMessage()); + isTriggerSent = true; + } + super.render(matrices, mouseX, mouseY, delta); } @Override diff --git a/src/main/java/minescript/screen/TextEditorScreenHandler.java b/src/main/java/minescript/screen/TextEditorScreenHandler.java index 391efbf..8cff18d 100644 --- a/src/main/java/minescript/screen/TextEditorScreenHandler.java +++ b/src/main/java/minescript/screen/TextEditorScreenHandler.java @@ -1,6 +1,5 @@ package minescript.screen; -import io.netty.buffer.ByteBuf; import minescript.MineScript; import minescript.block.entity.TurtleBlockEntity; import minescript.network.MineScriptPackets; @@ -9,21 +8,18 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NbtCompound; import net.minecraft.network.PacketByteBuf; import net.minecraft.screen.ScreenHandler; -import net.minecraft.text.Text; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; - public class TextEditorScreenHandler extends ScreenHandler { private String inputText; + private boolean isClientTextUpdated; private final @Nullable TurtleBlockEntity entity; public TextEditorScreenHandler(int syncId, PlayerInventory inventory, PacketByteBuf buf) { this(syncId, inventory, (TurtleBlockEntity) null); - inputText = buf.readString(buf.readInt()); + isClientTextUpdated = false; } public TextEditorScreenHandler(int syncId, PlayerInventory inventory, @Nullable TurtleBlockEntity entity) { @@ -32,11 +28,50 @@ public TextEditorScreenHandler(int syncId, PlayerInventory inventory, @Nullable inputText = "placeholder"; this.entity = entity; + this.addClientboundMessage(SendInputToClientMessage.class, this::handleSendInputToClient); this.addServerboundMessage(StartInterpreterMessage.class, this::handleSetInputText); + this.addServerboundMessage(TriggerSendInputMessage.class, this::handleTriggerSendInput); } - public String getInputText() { - return inputText; + private void handleTriggerSendInput(TriggerSendInputMessage message) { + assert entity != null; + String text = entity.getTurtleInput(); + int length = text.length(); + + int splits = (int) Math.ceil((double) length / 50000); + PacketByteBuf buf = PacketByteBufs.create(); + + int splitLength; + + for (int i = 0; i < splits; i++) { + if (i == splits - 1) { + splitLength = text.substring(i * 50000).length(); + buf.writeString(text.substring(i * 50000), splitLength); + this.sendMessage(new SendInputToClientMessage(i, splits, splitLength, buf)); + } + else { + String substring = text.substring(i * 50000, (i + 1) * 50000); + buf.writeString(substring, substring.length()); + splitLength = substring.length(); + this.sendMessage(new SendInputToClientMessage(i, splits, splitLength, buf)); + } + } + } + + private void handleSendInputToClient(SendInputToClientMessage message) { + int splits = message.totalSplits; + int currentSplit = message.current; + int splitLength = message.splitLength; + PacketByteBuf buf = message.buf; + + if (currentSplit == 0) + this.inputText = buf.readString(splitLength); + else + this.inputText += buf.readString(splitLength); + + // if last split then set clientTextUpdated to true + if (currentSplit == splits - 1) + isClientTextUpdated = true; } private void handleSetInputText(StartInterpreterMessage message) { @@ -54,6 +89,13 @@ private void handleSetInputText(StartInterpreterMessage message) { ClientPlayNetworking.send(MineScriptPackets.START_INTERPRETER_ID, buf); } + public String getInputText() { + return inputText; + } + public boolean isClientTextUpdated() { return isClientTextUpdated; } + + public record TriggerSendInputMessage() {} + public record SendInputToClientMessage(int current, int totalSplits, int splitLength, PacketByteBuf buf) {} public record StartInterpreterMessage(int length, PacketByteBuf buf) {} @Override