From 08637c98f5380af1a1a7830ff4c8bc17cf790b85 Mon Sep 17 00:00:00 2001 From: TexTrue <65154269+TexBlock@users.noreply.github.com> Date: Sun, 13 Oct 2024 11:38:47 +0800 Subject: [PATCH] wip --- gradle/example/common/build.gradle | 1 - networking/common/build.gradle | 9 + .../lib/api/networking/KessokuNetworking.java | 10 + .../api/networking/util/ChannelRegister.java | 56 ++++++ .../util/NetworkHandlerExtension.java | 7 + .../networking/util/PacketByteBufHelper.java | 186 ++++++++++++++++++ ...rConfigurationNetworkHandlerExtension.java | 31 +++ .../impl/networking/AbstractNetworkAddon.java | 9 + .../impl/networking/ChannelRegisterImpl.java | 64 ++++++ networking/fabric/build.gradle | 12 ++ .../kessoku/lib/KessokuNetworkingFabric.java | 4 + ...erverConfigurationNetworkHandlerMixin.java | 8 + networking/neo/build.gradle | 12 ++ networking/neo/gradle.properties | 1 + settings.gradle | 1 + 15 files changed, 410 insertions(+), 1 deletion(-) create mode 100644 networking/common/build.gradle create mode 100644 networking/common/src/main/java/band/kessoku/lib/api/networking/KessokuNetworking.java create mode 100644 networking/common/src/main/java/band/kessoku/lib/api/networking/util/ChannelRegister.java create mode 100644 networking/common/src/main/java/band/kessoku/lib/api/networking/util/NetworkHandlerExtension.java create mode 100644 networking/common/src/main/java/band/kessoku/lib/api/networking/util/PacketByteBufHelper.java create mode 100644 networking/common/src/main/java/band/kessoku/lib/api/networking/util/ServerConfigurationNetworkHandlerExtension.java create mode 100644 networking/common/src/main/java/band/kessoku/lib/impl/networking/AbstractNetworkAddon.java create mode 100644 networking/common/src/main/java/band/kessoku/lib/impl/networking/ChannelRegisterImpl.java create mode 100644 networking/fabric/build.gradle create mode 100644 networking/fabric/src/main/java/band/kessoku/lib/KessokuNetworkingFabric.java create mode 100644 networking/fabric/src/main/java/band/kessoku/lib/mixin/networking/fabric/ServerConfigurationNetworkHandlerMixin.java create mode 100644 networking/neo/build.gradle create mode 100644 networking/neo/gradle.properties diff --git a/gradle/example/common/build.gradle b/gradle/example/common/build.gradle index df81fc1b..4775fbfc 100644 --- a/gradle/example/common/build.gradle +++ b/gradle/example/common/build.gradle @@ -1,6 +1,5 @@ apply from: rootProject.file("gradle/scripts/klib-common.gradle") -group = "band.kessoku.lib.package" base.archivesName = rootProject.name + "-package" // You can delete this section if you need to diff --git a/networking/common/build.gradle b/networking/common/build.gradle new file mode 100644 index 00000000..dc21f7ca --- /dev/null +++ b/networking/common/build.gradle @@ -0,0 +1,9 @@ +apply from: rootProject.file("gradle/scripts/klib-common.gradle") + +base.archivesName = rootProject.name + "-package" + +kessoku { + modules(["base", "event-base"], "common") + + testModule("event-base", "common") +} diff --git a/networking/common/src/main/java/band/kessoku/lib/api/networking/KessokuNetworking.java b/networking/common/src/main/java/band/kessoku/lib/api/networking/KessokuNetworking.java new file mode 100644 index 00000000..80568673 --- /dev/null +++ b/networking/common/src/main/java/band/kessoku/lib/api/networking/KessokuNetworking.java @@ -0,0 +1,10 @@ +package band.kessoku.lib.api.networking; + +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; + +public class KessokuNetworking { + public static final String MOD_ID = "kessoku_networking"; + public static final String NAME = "Kessoku Networking API"; + public static final Marker MARKER = MarkerFactory.getMarker("[" + NAME + "]"); +} diff --git a/networking/common/src/main/java/band/kessoku/lib/api/networking/util/ChannelRegister.java b/networking/common/src/main/java/band/kessoku/lib/api/networking/util/ChannelRegister.java new file mode 100644 index 00000000..9a7fb872 --- /dev/null +++ b/networking/common/src/main/java/band/kessoku/lib/api/networking/util/ChannelRegister.java @@ -0,0 +1,56 @@ +package band.kessoku.lib.api.networking.util; + +import band.kessoku.lib.impl.networking.ChannelRegisterImpl; +import net.minecraft.network.PacketByteBuf; +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.packet.CustomPayload; +import org.jetbrains.annotations.ApiStatus; + +/** + * A registry for payload types. + */ +@ApiStatus.NonExtendable +public interface ChannelRegister { + + /** + * Registers a custom payload type. + * + *

This must be done on both the sending and receiving side, usually during mod initialization + * and before registering a packet handler. + * + * @param id the id of the payload type + * @param codec the codec for the payload type + * @param the payload type + * @return the registered payload type + */ + CustomPayload.Type register(CustomPayload.Id id, PacketCodec codec); + + /** + * @return the {@link ChannelRegister} instance for the client to server configuration channel. + */ + static ChannelRegister configC2S() { + return ChannelRegisterImpl.CONFIG_C2S; + } + + /** + * @return the {@link ChannelRegister} instance for the server to client configuration channel. + */ + static ChannelRegister configS2C() { + return ChannelRegisterImpl.CONFIG_S2C; + } + + /** + * @return the {@link ChannelRegister} instance for the client to server play channel. + */ + static ChannelRegister playC2S() { + return ChannelRegisterImpl.PLAY_C2S; + } + + /** + * @return the {@link ChannelRegister} instance for the server to client play channel. + */ + static ChannelRegister playS2C() { + return ChannelRegisterImpl.PLAY_S2C; + } +} diff --git a/networking/common/src/main/java/band/kessoku/lib/api/networking/util/NetworkHandlerExtension.java b/networking/common/src/main/java/band/kessoku/lib/api/networking/util/NetworkHandlerExtension.java new file mode 100644 index 00000000..52e6ffe3 --- /dev/null +++ b/networking/common/src/main/java/band/kessoku/lib/api/networking/util/NetworkHandlerExtension.java @@ -0,0 +1,7 @@ +package band.kessoku.lib.api.networking.util; + +import band.kessoku.lib.impl.networking.AbstractNetworkAddon; + +public interface NetworkHandlerExtension { + AbstractNetworkAddon getAddon(); +} diff --git a/networking/common/src/main/java/band/kessoku/lib/api/networking/util/PacketByteBufHelper.java b/networking/common/src/main/java/band/kessoku/lib/api/networking/util/PacketByteBufHelper.java new file mode 100644 index 00000000..e928b7ce --- /dev/null +++ b/networking/common/src/main/java/band/kessoku/lib/api/networking/util/PacketByteBufHelper.java @@ -0,0 +1,186 @@ +package band.kessoku.lib.api.networking.util; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import net.minecraft.network.PacketByteBuf; + +import java.util.Objects; + +/** + * Helper methods for working with and creating {@link PacketByteBuf}s. + */ +public final class PacketByteBufHelper { + private static final PacketByteBuf EMPTY_PACKET_BYTE_BUF = new PacketByteBuf(Unpooled.EMPTY_BUFFER); + + /** + * Returns an empty instance of packet byte buf. + * + * @return an empty buf + */ + public static PacketByteBuf empty() { + return EMPTY_PACKET_BYTE_BUF; + } + + /** + * Returns a new heap memory-backed instance of packet byte buf. + * + * @return a new buf + */ + public static PacketByteBuf create() { + return new PacketByteBuf(Unpooled.buffer()); + } + + // Convenience methods for byte buf methods that return a new byte buf + + /** + * Wraps the newly created buf from {@code buf.readBytes} in a packet byte buf. + * + * @param buf the original buf + * @param length the number of bytes to transfer + * @return the transferred bytes + * @see ByteBuf#readBytes(int) + */ + public static PacketByteBuf readBytes(ByteBuf buf, int length) { + Objects.requireNonNull(buf, "ByteBuf cannot be null"); + + return new PacketByteBuf(buf.readBytes(length)); + } + + /** + * Wraps the newly created buf from {@code buf.readSlice} in a packet byte buf. + * + * @param buf the original buf + * @param length the size of the new slice + * @return the newly created slice + * @see ByteBuf#readSlice(int) + */ + public static PacketByteBuf readSlice(ByteBuf buf, int length) { + Objects.requireNonNull(buf, "ByteBuf cannot be null"); + + return new PacketByteBuf(buf.readSlice(length)); + } + + /** + * Wraps the newly created buf from {@code buf.readRetainedSlice} in a packet byte buf. + * + * @param buf the original buf + * @param length the size of the new slice + * @return the newly created slice + * @see ByteBuf#readRetainedSlice(int) + */ + public static PacketByteBuf readRetainedSlice(ByteBuf buf, int length) { + Objects.requireNonNull(buf, "ByteBuf cannot be null"); + + return new PacketByteBuf(buf.readRetainedSlice(length)); + } + + /** + * Wraps the newly created buf from {@code buf.copy} in a packet byte buf. + * + * @param buf the original buf + * @return a copy of the buf + * @see ByteBuf#copy() + */ + public static PacketByteBuf copy(ByteBuf buf) { + Objects.requireNonNull(buf, "ByteBuf cannot be null"); + + return new PacketByteBuf(buf.copy()); + } + + /** + * Wraps the newly created buf from {@code buf.copy} in a packet byte buf. + * + * @param buf the original buf + * @param index the starting index + * @param length the size of the copy + * @return a copy of the buf + * @see ByteBuf#copy(int, int) + */ + public static PacketByteBuf copy(ByteBuf buf, int index, int length) { + Objects.requireNonNull(buf, "ByteBuf cannot be null"); + + return new PacketByteBuf(buf.copy(index, length)); + } + + /** + * Wraps the newly created buf from {@code buf.slice} in a packet byte buf. + * + * @param buf the original buf + * @return a slice of the buf + * @see ByteBuf#slice() + */ + public static PacketByteBuf slice(ByteBuf buf) { + Objects.requireNonNull(buf, "ByteBuf cannot be null"); + + return new PacketByteBuf(buf.slice()); + } + + /** + * Wraps the newly created buf from {@code buf.retainedSlice} in a packet byte buf. + * + * @param buf the original buf + * @return a slice of the buf + * @see ByteBuf#retainedSlice() + */ + public static PacketByteBuf retainedSlice(ByteBuf buf) { + Objects.requireNonNull(buf, "ByteBuf cannot be null"); + + return new PacketByteBuf(buf.retainedSlice()); + } + + /** + * Wraps the newly created buf from {@code buf.slice} in a packet byte buf. + * + * @param buf the original buf + * @param index the starting index + * @param length the size of the copy + * @return a slice of the buf + * @see ByteBuf#slice(int, int) + */ + public static PacketByteBuf slice(ByteBuf buf, int index, int length) { + Objects.requireNonNull(buf, "ByteBuf cannot be null"); + + return new PacketByteBuf(buf.slice(index, length)); + } + + /** + * Wraps the newly created buf from {@code buf.retainedSlice} in a packet byte buf. + * + * @param buf the original buf + * @param index the starting index + * @param length the size of the copy + * @return a slice of the buf + * @see ByteBuf#retainedSlice(int, int) + */ + public static PacketByteBuf retainedSlice(ByteBuf buf, int index, int length) { + Objects.requireNonNull(buf, "ByteBuf cannot be null"); + + return new PacketByteBuf(buf.retainedSlice(index, length)); + } + + /** + * Wraps the newly created buf from {@code buf.duplicate} in a packet byte buf. + * + * @param buf the original buf + * @return a duplicate of the buf + * @see ByteBuf#duplicate() + */ + public static PacketByteBuf duplicate(ByteBuf buf) { + Objects.requireNonNull(buf, "ByteBuf cannot be null"); + + return new PacketByteBuf(buf.duplicate()); + } + + /** + * Wraps the newly created buf from {@code buf.retainedDuplicate} in a packet byte buf. + * + * @param buf the original buf + * @return a duplicate of the buf + * @see ByteBuf#retainedDuplicate() + */ + public static PacketByteBuf retainedDuplicate(ByteBuf buf) { + Objects.requireNonNull(buf, "ByteBuf cannot be null"); + + return new PacketByteBuf(buf.retainedDuplicate()); + } +} diff --git a/networking/common/src/main/java/band/kessoku/lib/api/networking/util/ServerConfigurationNetworkHandlerExtension.java b/networking/common/src/main/java/band/kessoku/lib/api/networking/util/ServerConfigurationNetworkHandlerExtension.java new file mode 100644 index 00000000..cf6692a0 --- /dev/null +++ b/networking/common/src/main/java/band/kessoku/lib/api/networking/util/ServerConfigurationNetworkHandlerExtension.java @@ -0,0 +1,31 @@ +package band.kessoku.lib.api.networking.util; + +import net.minecraft.server.network.ServerPlayerConfigurationTask; + +public interface ServerConfigurationNetworkHandlerExtension { + /** + * Enqueues a {@link ServerPlayerConfigurationTask} task to be processed. + * + *

Before adding a task use {@link ServerConfigurationNetworking#canSend(ServerConfigurationNetworkHandler, Identifier)} + * to ensure that the client can process this task. + * + *

Once the client has handled the task a packet should be sent to the server. + * Upon receiving this packet the server should call {@link ServerConfigurationNetworkHandlerExtension#kessokulib$completeTask(ServerPlayerConfigurationTask.Key)}, + * otherwise the client cannot join the world. + * + * @param task the task + */ + default void kessokulib$addTask(ServerPlayerConfigurationTask task) { + throw new UnsupportedOperationException("Implemented via mixin"); + } + + /** + * Completes the task identified by {@code key}. + * + * @param key the task key + * @throws IllegalStateException if the current task is not {@code key} + */ + default void kessokulib$completeTask(ServerPlayerConfigurationTask.Key key) { + throw new UnsupportedOperationException("Implemented via mixin"); + } +} diff --git a/networking/common/src/main/java/band/kessoku/lib/impl/networking/AbstractNetworkAddon.java b/networking/common/src/main/java/band/kessoku/lib/impl/networking/AbstractNetworkAddon.java new file mode 100644 index 00000000..3451fd33 --- /dev/null +++ b/networking/common/src/main/java/band/kessoku/lib/impl/networking/AbstractNetworkAddon.java @@ -0,0 +1,9 @@ +package band.kessoku.lib.impl.networking; + +/** + * A network addon is a simple abstraction to hold information about a player's registered channels. + * + * @param the channel handler type + */ +public abstract class AbstractNetworkAddon { +} diff --git a/networking/common/src/main/java/band/kessoku/lib/impl/networking/ChannelRegisterImpl.java b/networking/common/src/main/java/band/kessoku/lib/impl/networking/ChannelRegisterImpl.java new file mode 100644 index 00000000..163bfd1c --- /dev/null +++ b/networking/common/src/main/java/band/kessoku/lib/impl/networking/ChannelRegisterImpl.java @@ -0,0 +1,64 @@ +package band.kessoku.lib.impl.networking; + +import band.kessoku.lib.api.networking.util.ChannelRegister; +import net.minecraft.network.NetworkPhase; +import net.minecraft.network.NetworkSide; +import net.minecraft.network.PacketByteBuf; +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.packet.CustomPayload; +import net.minecraft.util.Identifier; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +public class ChannelRegisterImpl implements ChannelRegister { + public static final ChannelRegisterImpl CONFIG_C2S = new ChannelRegisterImpl<>(NetworkPhase.CONFIGURATION, NetworkSide.SERVERBOUND); + public static final ChannelRegisterImpl CONFIG_S2C = new ChannelRegisterImpl<>(NetworkPhase.CONFIGURATION, NetworkSide.CLIENTBOUND); + public static final ChannelRegisterImpl PLAY_C2S = new ChannelRegisterImpl<>(NetworkPhase.PLAY, NetworkSide.SERVERBOUND); + public static final ChannelRegisterImpl PLAY_S2C = new ChannelRegisterImpl<>(NetworkPhase.PLAY, NetworkSide.CLIENTBOUND); + + private final Map> packetTypes = new HashMap<>(); + private final NetworkPhase state; + private final NetworkSide side; + + private ChannelRegisterImpl(NetworkPhase state, NetworkSide side) { + this.state = state; + this.side = side; + } + @Override + public CustomPayload.Type register(CustomPayload.Id id, PacketCodec codec) { + Objects.requireNonNull(id, "id"); + Objects.requireNonNull(codec, "codec"); + + final CustomPayload.Type payloadType = new CustomPayload.Type<>(id, codec.cast()); + + if (packetTypes.containsKey(id.id())) { + throw new IllegalArgumentException("Packet type " + id + " is already registered!"); + } + + packetTypes.put(id.id(), payloadType); + return payloadType; + } + + @Nullable + public CustomPayload.Type get(Identifier id) { + return packetTypes.get(id); + } + + @Nullable + public CustomPayload.Type get(CustomPayload.Id id) { + //noinspection unchecked + return (CustomPayload.Type) packetTypes.get(id.id()); + } + + public NetworkPhase getPhase() { + return state; + } + + public NetworkSide getSide() { + return side; + } +} diff --git a/networking/fabric/build.gradle b/networking/fabric/build.gradle new file mode 100644 index 00000000..0580c67f --- /dev/null +++ b/networking/fabric/build.gradle @@ -0,0 +1,12 @@ +import net.fabricmc.loom.util.ModPlatform + +apply from: rootProject.file("gradle/scripts/klib-fabric.gradle") + +base.archivesName = rootProject.name + "-networking" + +kessoku { + module("base", "common") + + common("networking", ModPlatform.FABRIC) + shadowBundle("networking", ModPlatform.FABRIC) +} diff --git a/networking/fabric/src/main/java/band/kessoku/lib/KessokuNetworkingFabric.java b/networking/fabric/src/main/java/band/kessoku/lib/KessokuNetworkingFabric.java new file mode 100644 index 00000000..7a779794 --- /dev/null +++ b/networking/fabric/src/main/java/band/kessoku/lib/KessokuNetworkingFabric.java @@ -0,0 +1,4 @@ +package band.kessoku.lib; + +public class KessokuNetworkingFabric { +} diff --git a/networking/fabric/src/main/java/band/kessoku/lib/mixin/networking/fabric/ServerConfigurationNetworkHandlerMixin.java b/networking/fabric/src/main/java/band/kessoku/lib/mixin/networking/fabric/ServerConfigurationNetworkHandlerMixin.java new file mode 100644 index 00000000..df470b98 --- /dev/null +++ b/networking/fabric/src/main/java/band/kessoku/lib/mixin/networking/fabric/ServerConfigurationNetworkHandlerMixin.java @@ -0,0 +1,8 @@ +package band.kessoku.lib.mixin.networking.fabric; + +import band.kessoku.lib.api.networking.util.ServerConfigurationNetworkHandlerExtension; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(ServerConfigurationNetworkHandlerExtension.class) +public class ServerConfigurationNetworkHandlerMixin implements ServerConfigurationNetworkHandlerExtension { +} diff --git a/networking/neo/build.gradle b/networking/neo/build.gradle new file mode 100644 index 00000000..c2a5208c --- /dev/null +++ b/networking/neo/build.gradle @@ -0,0 +1,12 @@ +import net.fabricmc.loom.util.ModPlatform + +apply from: rootProject.file("gradle/scripts/klib-neo.gradle") + +base.archivesName = rootProject.name + "-networking" + +kessoku { + module("base", "common") + + common("networking", ModPlatform.NEOFORGE) + shadowBundle("networking", ModPlatform.NEOFORGE) +} diff --git a/networking/neo/gradle.properties b/networking/neo/gradle.properties new file mode 100644 index 00000000..2914393d --- /dev/null +++ b/networking/neo/gradle.properties @@ -0,0 +1 @@ +loom.platform=neoforge \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index e8dd999b..bf994acd 100644 --- a/settings.gradle +++ b/settings.gradle @@ -23,6 +23,7 @@ includeModule("keybinding") // Keybinding API includeModule("config") // Config API includeModule("entrypoint") // Entrypoint API includeModule("entity-events") // Entity Events +includeModule("networking") // Networking API void includeWrapper(String platform) { include("wrapper/$platform")