From 6384adc602a11df6c57f6d79ced4b92a0692d068 Mon Sep 17 00:00:00 2001 From: marcus8448 Date: Wed, 10 Jul 2024 17:33:33 -0700 Subject: [PATCH] fix: add some additional sync handlers --- .../entity/RecipeMachineBlockEntity.java | 4 +- .../machinelib/api/menu/MachineMenu.java | 3 +- .../machinelib/api/menu/MenuData.java | 78 +++++++++++++++--- .../api/menu/RecipeMachineMenu.java | 19 ++++- .../menu/sync/BitsPacketSerializable.java | 80 +++++++++++++++++++ .../menu/sync/BytePacketSerializable.java | 58 ++++++++++++++ .../menu/sync/DoublePacketSerializable.java | 58 ++++++++++++++ .../menu/sync/FloatPacketSerializable.java | 57 +++++++++++++ .../menu/sync/ShortPacketSerializable.java | 58 ++++++++++++++ 9 files changed, 401 insertions(+), 14 deletions(-) create mode 100644 src/main/java/dev/galacticraft/machinelib/impl/menu/sync/BitsPacketSerializable.java create mode 100644 src/main/java/dev/galacticraft/machinelib/impl/menu/sync/BytePacketSerializable.java create mode 100644 src/main/java/dev/galacticraft/machinelib/impl/menu/sync/DoublePacketSerializable.java create mode 100644 src/main/java/dev/galacticraft/machinelib/impl/menu/sync/FloatPacketSerializable.java create mode 100644 src/main/java/dev/galacticraft/machinelib/impl/menu/sync/ShortPacketSerializable.java diff --git a/src/main/java/dev/galacticraft/machinelib/api/block/entity/RecipeMachineBlockEntity.java b/src/main/java/dev/galacticraft/machinelib/api/block/entity/RecipeMachineBlockEntity.java index a4b6c31..4c012d0 100644 --- a/src/main/java/dev/galacticraft/machinelib/api/block/entity/RecipeMachineBlockEntity.java +++ b/src/main/java/dev/galacticraft/machinelib/api/block/entity/RecipeMachineBlockEntity.java @@ -302,13 +302,13 @@ protected void setActiveRecipe(@Nullable RecipeHolder recipe) { } @Override - protected void saveAdditional(@NotNull CompoundTag tag, HolderLookup.Provider lookup) { + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider lookup) { super.saveAdditional(tag, lookup); tag.putInt(Constant.Nbt.PROGRESS, this.getProgress()); } @Override - public void loadAdditional(@NotNull CompoundTag tag, HolderLookup.Provider lookup) { + public void loadAdditional(CompoundTag tag, HolderLookup.Provider lookup) { super.loadAdditional(tag, lookup); this.progress = tag.getInt(Constant.Nbt.PROGRESS); } diff --git a/src/main/java/dev/galacticraft/machinelib/api/menu/MachineMenu.java b/src/main/java/dev/galacticraft/machinelib/api/menu/MachineMenu.java index f065028..b77ed54 100644 --- a/src/main/java/dev/galacticraft/machinelib/api/menu/MachineMenu.java +++ b/src/main/java/dev/galacticraft/machinelib/api/menu/MachineMenu.java @@ -61,6 +61,7 @@ public class MachineMenu extends ConfiguredM * Constructs a new menu for a machine. * Called on the logical server * + * @param type The type of menu this is. * @param syncId The sync id for this menu. * @param player The player who is interacting with this menu. * @param machine The machine this menu is for. @@ -82,10 +83,10 @@ public MachineMenu(MenuType> type, int syncId, @N * Called on the logical client. * You must add the player inventory slots manually. * + * @param type The type of menu this is. * @param syncId The sync id for this menu. * @param buf The synchronization buffer from the server. * @param inventory The inventory of the player interacting with this menu. - * @param type The type of menu this is. */ protected MachineMenu(MenuType> type, int syncId, @NotNull Inventory inventory, @NotNull RegistryFriendlyByteBuf buf) { super(type, syncId, inventory, buf); diff --git a/src/main/java/dev/galacticraft/machinelib/api/menu/MenuData.java b/src/main/java/dev/galacticraft/machinelib/api/menu/MenuData.java index f0dc0cc..f90e763 100644 --- a/src/main/java/dev/galacticraft/machinelib/api/menu/MenuData.java +++ b/src/main/java/dev/galacticraft/machinelib/api/menu/MenuData.java @@ -22,11 +22,11 @@ package dev.galacticraft.machinelib.api.menu; +import dev.architectury.utils.value.FloatSupplier; import dev.galacticraft.machinelib.api.misc.DeltaPacketSerializable; -import dev.galacticraft.machinelib.impl.menu.sync.EnumPacketSerializable; -import dev.galacticraft.machinelib.impl.menu.sync.IntPacketSerializable; -import dev.galacticraft.machinelib.impl.menu.sync.LongPacketSerializable; -import dev.galacticraft.machinelib.impl.menu.sync.StreamCodecPacketSerializable; +import dev.galacticraft.machinelib.impl.menu.sync.*; +import it.unimi.dsi.fastutil.booleans.BooleanConsumer; +import it.unimi.dsi.fastutil.floats.FloatConsumer; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; import org.jetbrains.annotations.ApiStatus; @@ -78,6 +78,36 @@ public void register(StreamCodec codec, this.register(new StreamCodecPacketSerializable<>(codec, getter, setter)); } + /** + * Registers a byte field to be synchronized. + * + * @param getter provides the current value of the data + * @param setter sets the value of the data + */ + public void registerBoolean(BooleanSupplier getter, BooleanConsumer setter) { + this.register(new BytePacketSerializable(() -> getter.getAsBoolean() ? 1 : 0, b -> setter.accept(b != 0))); + } + + /** + * Registers a byte field to be synchronized. + * + * @param getter provides the current value of the data + * @param setter sets the value of the data + */ + public void registerByte(IntSupplier getter, IntConsumer setter) { + this.register(new BytePacketSerializable(getter, setter)); + } + + /** + * Registers a short field to be synchronized. + * + * @param getter provides the current value of the data + * @param setter sets the value of the data + */ + public void registerShort(IntSupplier getter, IntConsumer setter) { + this.register(new ShortPacketSerializable(getter, setter)); + } + /** * Registers an integer field to be synchronized. * @@ -88,6 +118,36 @@ public void registerInt(IntSupplier getter, IntConsumer setter) { this.register(new IntPacketSerializable(getter, setter)); } + /** + * Registers a long field to be synchronized. + * + * @param getter provides the current value of the data + * @param setter sets the value of the data + */ + public void registerLong(LongSupplier getter, LongConsumer setter) { + this.register(new LongPacketSerializable(getter, setter)); + } + + /** + * Registers a float field to be synchronized. + * + * @param getter provides the current value of the data + * @param setter sets the value of the data + */ + public void registerFloat(FloatSupplier getter, FloatConsumer setter) { + this.register(new FloatPacketSerializable(getter, setter)); + } + + /** + * Registers a double field to be synchronized. + * + * @param getter provides the current value of the data + * @param setter sets the value of the data + */ + public void registerDouble(DoubleSupplier getter, DoubleConsumer setter) { + this.register(new DoublePacketSerializable(getter, setter)); + } + /** * Registers an enum field to be synchronized. * @@ -101,13 +161,13 @@ public > void registerEnum(E[] world, Supplier getter, Cons } /** - * Registers a long field to be synchronized. + * Registers an array of booleans to be synchronized. * - * @param getter provides the current value of the data - * @param setter sets the value of the data + * @param source the source array + * @param dest the destination array */ - public void registerLong(LongSupplier getter, LongConsumer setter) { - this.register(new LongPacketSerializable(getter, setter)); + public void registerBits(int len, boolean[] source, boolean[] dest) { + this.register(new BitsPacketSerializable(len, source, dest)); } @ApiStatus.Internal diff --git a/src/main/java/dev/galacticraft/machinelib/api/menu/RecipeMachineMenu.java b/src/main/java/dev/galacticraft/machinelib/api/menu/RecipeMachineMenu.java index 9ffe823..2760adb 100644 --- a/src/main/java/dev/galacticraft/machinelib/api/menu/RecipeMachineMenu.java +++ b/src/main/java/dev/galacticraft/machinelib/api/menu/RecipeMachineMenu.java @@ -40,7 +40,7 @@ * @param The type of storage the recipe uses * @see MachineMenu */ -public abstract class RecipeMachineMenu, Machine extends RecipeMachineBlockEntity> extends MachineMenu { +public class RecipeMachineMenu, Machine extends RecipeMachineBlockEntity> extends MachineMenu { /** * The amount of progress the machine has made in crafting a recipe. * Counts from zero to {@link #maxProgress}, if {@link #maxProgress} > 0. @@ -55,6 +55,7 @@ public abstract class RecipeMachineMenu> ty /** * Constructs a new recipe menu for a machine. * + * @param type The type of machine associated with this menu. * @param syncId The sync id for this menu. * @param inventory The inventory of the player interacting with this menu. * @param buf The data buffer containing the information needed to initialize the menu. - * @param type The type of machine associated with this menu. */ protected RecipeMachineMenu(MenuType> type, int syncId, @NotNull Inventory inventory, @NotNull RegistryFriendlyByteBuf buf) { super(type, syncId, inventory, buf); } + /** + * Constructs a new recipe menu for a machine. + * + * @param type The type of machine associated with this menu. + * @param syncId The sync id for this menu. + * @param inventory The inventory of the player interacting with this menu. + * @param buf The data buffer containing the information needed to initialize the menu. + * @param invX The x position of the inventory in the menu. + * @param invY The y position of the inventory in the menu. + */ + public RecipeMachineMenu(MenuType> type, int syncId, @NotNull Inventory inventory, @NotNull RegistryFriendlyByteBuf buf, int invX, int invY) { + super(type, syncId, inventory, buf, invX, invY); + } + @Override public void registerData(@NotNull MenuData data) { super.registerData(data); diff --git a/src/main/java/dev/galacticraft/machinelib/impl/menu/sync/BitsPacketSerializable.java b/src/main/java/dev/galacticraft/machinelib/impl/menu/sync/BitsPacketSerializable.java new file mode 100644 index 0000000..a8d45bf --- /dev/null +++ b/src/main/java/dev/galacticraft/machinelib/impl/menu/sync/BitsPacketSerializable.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021-2024 Team Galacticraft + * + * 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. + */ + +package dev.galacticraft.machinelib.impl.menu.sync; + +import dev.galacticraft.machinelib.api.misc.DeltaPacketSerializable; +import io.netty.buffer.ByteBuf; +import org.jetbrains.annotations.NotNull; + +public record BitsPacketSerializable(int len, boolean[] source, boolean[] dest) implements DeltaPacketSerializable { + public BitsPacketSerializable { + assert len == source.length; + assert len == dest.length; + } + + @Override + public boolean hasChanged(boolean[] previous) { + for (int i = 0; i < this.len; i++) { + if (previous[i] != this.source[i]) { + return true; + } + } + return false; + } + + @Override + public void copyInto(boolean[] other) { + System.arraycopy(this.source, 0, other, 0, this.len); + } + + @Override + public void readPacket(@NotNull ByteBuf buf) { + int bytes = (this.len / 8) + 1; + for (int i = 0; i < bytes; i++) { + byte b = buf.readByte(); + for (int j = 0; j < 8 && i * 8 + j < this.len; j++) { + this.dest[i * 8 + j] = (b & (0b1 << j)) != 0; + } + } + } + + @Override + public void writePacket(@NotNull ByteBuf buf) { + int bytes = (this.len / 8) + 1; + for (int i = 0; i < bytes; i++) { + byte b = 0; + for (int j = 0; j < 8 && i * 8 + j < this.len; j++) { + if (this.source[i * 8 + j]) { + b |= (byte) (0b1 << j); + } + } + buf.writeByte(b); + } + } + + @Override + public boolean[] createEquivalent() { + return new boolean[this.len]; + } + +} diff --git a/src/main/java/dev/galacticraft/machinelib/impl/menu/sync/BytePacketSerializable.java b/src/main/java/dev/galacticraft/machinelib/impl/menu/sync/BytePacketSerializable.java new file mode 100644 index 0000000..bac167d --- /dev/null +++ b/src/main/java/dev/galacticraft/machinelib/impl/menu/sync/BytePacketSerializable.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021-2024 Team Galacticraft + * + * 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. + */ + +package dev.galacticraft.machinelib.impl.menu.sync; + +import dev.galacticraft.machinelib.api.misc.DeltaPacketSerializable; +import io.netty.buffer.ByteBuf; +import org.jetbrains.annotations.NotNull; + +import java.util.function.IntConsumer; +import java.util.function.IntSupplier; + +public record BytePacketSerializable(IntSupplier getter, + IntConsumer setter) implements DeltaPacketSerializable { + @Override + public boolean hasChanged(int[] previous) { + return previous[0] != this.getter.getAsInt(); + } + + @Override + public void copyInto(int[] other) { + other[0] = this.getter.getAsInt(); + } + + @Override + public void readPacket(@NotNull ByteBuf buf) { + this.setter.accept(buf.readByte()); + } + + @Override + public void writePacket(@NotNull ByteBuf buf) { + buf.writeByte(this.getter.getAsInt()); + } + + @Override + public int[] createEquivalent() { + return new int[1]; + } +} diff --git a/src/main/java/dev/galacticraft/machinelib/impl/menu/sync/DoublePacketSerializable.java b/src/main/java/dev/galacticraft/machinelib/impl/menu/sync/DoublePacketSerializable.java new file mode 100644 index 0000000..f25a5bd --- /dev/null +++ b/src/main/java/dev/galacticraft/machinelib/impl/menu/sync/DoublePacketSerializable.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021-2024 Team Galacticraft + * + * 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. + */ + +package dev.galacticraft.machinelib.impl.menu.sync; + +import dev.galacticraft.machinelib.api.misc.DeltaPacketSerializable; +import io.netty.buffer.ByteBuf; +import org.jetbrains.annotations.NotNull; + +import java.util.function.DoubleConsumer; +import java.util.function.DoubleSupplier; + +public record DoublePacketSerializable(DoubleSupplier getter, + DoubleConsumer setter) implements DeltaPacketSerializable { + @Override + public boolean hasChanged(double[] previous) { + return previous[0] != this.getter.getAsDouble(); + } + + @Override + public void copyInto(double[] other) { + other[0] = this.getter.getAsDouble(); + } + + @Override + public void readPacket(@NotNull ByteBuf buf) { + this.setter.accept(buf.readDouble()); + } + + @Override + public void writePacket(@NotNull ByteBuf buf) { + buf.writeDouble(this.getter.getAsDouble()); + } + + @Override + public double[] createEquivalent() { + return new double[1]; + } +} diff --git a/src/main/java/dev/galacticraft/machinelib/impl/menu/sync/FloatPacketSerializable.java b/src/main/java/dev/galacticraft/machinelib/impl/menu/sync/FloatPacketSerializable.java new file mode 100644 index 0000000..9e3633d --- /dev/null +++ b/src/main/java/dev/galacticraft/machinelib/impl/menu/sync/FloatPacketSerializable.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021-2024 Team Galacticraft + * + * 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. + */ + +package dev.galacticraft.machinelib.impl.menu.sync; + +import dev.architectury.utils.value.FloatSupplier; +import dev.galacticraft.machinelib.api.misc.DeltaPacketSerializable; +import io.netty.buffer.ByteBuf; +import it.unimi.dsi.fastutil.floats.FloatConsumer; +import org.jetbrains.annotations.NotNull; + +public record FloatPacketSerializable(FloatSupplier getter, + FloatConsumer setter) implements DeltaPacketSerializable { + @Override + public boolean hasChanged(float[] previous) { + return previous[0] != this.getter.getAsFloat(); + } + + @Override + public void copyInto(float[] other) { + other[0] = this.getter.getAsFloat(); + } + + @Override + public void readPacket(@NotNull ByteBuf buf) { + this.setter.accept(buf.readFloat()); + } + + @Override + public void writePacket(@NotNull ByteBuf buf) { + buf.writeFloat(this.getter.getAsFloat()); + } + + @Override + public float[] createEquivalent() { + return new float[1]; + } +} diff --git a/src/main/java/dev/galacticraft/machinelib/impl/menu/sync/ShortPacketSerializable.java b/src/main/java/dev/galacticraft/machinelib/impl/menu/sync/ShortPacketSerializable.java new file mode 100644 index 0000000..141792f --- /dev/null +++ b/src/main/java/dev/galacticraft/machinelib/impl/menu/sync/ShortPacketSerializable.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021-2024 Team Galacticraft + * + * 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. + */ + +package dev.galacticraft.machinelib.impl.menu.sync; + +import dev.galacticraft.machinelib.api.misc.DeltaPacketSerializable; +import io.netty.buffer.ByteBuf; +import org.jetbrains.annotations.NotNull; + +import java.util.function.IntConsumer; +import java.util.function.IntSupplier; + +public record ShortPacketSerializable(IntSupplier getter, + IntConsumer setter) implements DeltaPacketSerializable { + @Override + public boolean hasChanged(int[] previous) { + return previous[0] != this.getter.getAsInt(); + } + + @Override + public void copyInto(int[] other) { + other[0] = this.getter.getAsInt(); + } + + @Override + public void readPacket(@NotNull ByteBuf buf) { + this.setter.accept(buf.readShort()); + } + + @Override + public void writePacket(@NotNull ByteBuf buf) { + buf.writeShort(this.getter.getAsInt()); + } + + @Override + public int[] createEquivalent() { + return new int[1]; + } +}