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 super B, T> register(CustomPayload.Id id, PacketCodec super B, T> 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 super B, T> register(CustomPayload.Id id, PacketCodec super B, T> 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")