diff --git a/settings.gradle b/settings.gradle
index 9b7af0c..3f5a83b 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -29,3 +29,4 @@ include("shearapi-conditions")
include("shearapi-network")
include("shearapi-holderset")
include("shearapi-resource")
+include("shearapi-fmlstuff")
diff --git a/shearapi-fmlstuff/build.gradle b/shearapi-fmlstuff/build.gradle
new file mode 100644
index 0000000..4e967b5
--- /dev/null
+++ b/shearapi-fmlstuff/build.gradle
@@ -0,0 +1,13 @@
+repositories {
+ maven {
+ url "https://maven.neoforged.net/releases/"
+ name "NeoForged Releases"
+ }
+}
+
+dependencies {
+ implementation "net.neoforged.fancymodloader:loader:${project.fancy_mod_loader_version}"
+ api project(path: ":shearapi-runtime", configuration: "namedElements")
+ api project(path: ":shearapi-withpillow", configuration: "namedElements")
+ api project(path: ":shearapi-network", configuration: "namedElements")
+}
diff --git a/shearapi-fmlstuff/src/client/java/net/pillowmc/shearapi/fmlstuff/client/ShearAPIFMLStuffClient.java b/shearapi-fmlstuff/src/client/java/net/pillowmc/shearapi/fmlstuff/client/ShearAPIFMLStuffClient.java
new file mode 100644
index 0000000..4af4f38
--- /dev/null
+++ b/shearapi-fmlstuff/src/client/java/net/pillowmc/shearapi/fmlstuff/client/ShearAPIFMLStuffClient.java
@@ -0,0 +1,105 @@
+package net.pillowmc.shearapi.fmlstuff.client;
+
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import net.fabricmc.api.ClientModInitializer;
+import net.minecraft.client.Minecraft;
+import net.minecraft.network.chat.Component;
+import net.minecraft.resources.ResourceKey;
+import net.minecraft.resources.ResourceLocation;
+import net.neoforged.bus.api.SubscribeEvent;
+import net.neoforged.fml.config.ConfigTracker;
+import net.neoforged.neoforge.network.event.RegisterPayloadHandlerEvent;
+import net.neoforged.neoforge.network.handlers.ClientPayloadHandler;
+import net.neoforged.neoforge.network.handling.ConfigurationPayloadContext;
+import net.neoforged.neoforge.network.handling.IPayloadContext;
+import net.neoforged.neoforge.network.payload.ConfigFilePayload;
+import net.neoforged.neoforge.network.payload.FrozenRegistryPayload;
+import net.neoforged.neoforge.network.payload.FrozenRegistrySyncCompletedPayload;
+import net.neoforged.neoforge.network.payload.FrozenRegistrySyncStartPayload;
+import net.neoforged.neoforge.network.registration.IPayloadRegistrar;
+import net.pillowmc.shearapi.fmlstuff.ShearAPIFMLStuff;
+import net.pillowmc.shearapi.runtime.ShearAPIRuntime;
+import net.pillowmc.shearapi.runtime.ShearAPIVersion;
+import net.pillowmc.shearapi.withpillow.ShearAPIWithPillow;
+
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class ShearAPIFMLStuffClient implements ClientModInitializer {
+ public static Class clazz = ShearAPIFMLStuffClient.class;
+ private static final Map synchronizedRegistries = Maps.newConcurrentMap();
+ private static final Set toSynchronize = Sets.newConcurrentHashSet();
+
+ @Override
+ public void onInitializeClient() {
+ ShearAPIFMLStuff.clientHandleRegistrySyncCompleted = ShearAPIFMLStuffClient::handleRegistrySyncCompleted;
+ }
+
+ @SubscribeEvent
+ public static void onRegisterPayloadHandlerEvent(RegisterPayloadHandlerEvent event) {
+ if (!(ShearAPIRuntime.getRuntime() instanceof ShearAPIWithPillow)) {
+ return;
+ }
+ final IPayloadRegistrar registrar = event.registrar(ShearAPIRuntime.MOD_ID)
+ .versioned(ShearAPIVersion.getSpec())
+ .optional();
+ registrar
+ .configuration(
+ FrozenRegistrySyncStartPayload.ID,
+ FrozenRegistrySyncStartPayload::new,
+ handlers -> handlers.client(ShearAPIFMLStuffClient::handleRegistrySyncStart))
+ .configuration(
+ FrozenRegistryPayload.ID,
+ FrozenRegistryPayload::new,
+ handlers -> handlers.client(ShearAPIFMLStuffClient::handleFrozenRegistry))
+ .configuration(
+ ConfigFilePayload.ID,
+ ConfigFilePayload::new,
+ handlers -> handlers.client(ShearAPIFMLStuffClient::handleConfigFile));
+ }
+
+ private static void handleConfigFile(ConfigFilePayload payload, IPayloadContext context) {
+ if (!Minecraft.getInstance().isLocalServer()) {
+ Optional.ofNullable(
+ ConfigTracker.INSTANCE.fileMap().get(payload.fileName())
+ ).ifPresent(mc -> mc.acceptSyncedConfig(payload.contents()));
+ }
+ }
+
+ public static void handleFrozenRegistry(FrozenRegistryPayload payload, ConfigurationPayloadContext context) {
+ synchronizedRegistries.put(payload.registryName(), payload.snapshot());
+ toSynchronize.remove(payload.registryName());
+ }
+
+ public static void handleRegistrySyncStart(FrozenRegistrySyncStartPayload payload, ConfigurationPayloadContext context) {
+ toSynchronize.addAll(payload.toAccess());
+ synchronizedRegistries.clear();
+ }
+
+ public static void handleRegistrySyncCompleted(FrozenRegistrySyncCompletedPayload payload, ConfigurationPayloadContext context) {
+ if (!toSynchronize.isEmpty()) {
+ context.packetHandler().disconnect(Component.translatable("neoforge.network.registries.sync.missing", this.toSynchronize.stream().map(Object::toString).collect(Collectors.joining(", "))));
+ return;
+ }
+
+ context.workHandler().submitAsync(() -> {
+ //This method normally returns missing entries, but we just accept what the server send us and ignore the rest.
+ Set> keysUnknownToClient = RegistryManager.applySnapshot(synchronizedRegistries, false, false);
+ if (!keysUnknownToClient.isEmpty()) {
+ context.packetHandler().disconnect(Component.translatable("neoforge.network.registries.sync.server-with-unknown-keys", keysUnknownToClient.stream().map(Object::toString).collect(Collectors.joining(", "))));
+ return;
+ }
+
+ toSynchronize.clear();
+ synchronizedRegistries.clear();
+ }).exceptionally(e -> {
+ context.packetHandler().disconnect(Component.translatable("neoforge.network.registries.sync.failed", e.getMessage()));
+ return null;
+ }).thenAccept(v -> {
+ context.replyHandler().send(new FrozenRegistrySyncCompletedPayload());
+ });
+ }
+}
diff --git a/shearapi-withpillow/src/main/java/net/neoforged/neoforge/event/ModMismatchEvent.java b/shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/event/ModMismatchEvent.java
similarity index 100%
rename from shearapi-withpillow/src/main/java/net/neoforged/neoforge/event/ModMismatchEvent.java
rename to shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/event/ModMismatchEvent.java
diff --git a/shearapi-withpillow/src/main/java/net/neoforged/neoforge/network/ConfigSync.java b/shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/ConfigSync.java
similarity index 100%
rename from shearapi-withpillow/src/main/java/net/neoforged/neoforge/network/ConfigSync.java
rename to shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/ConfigSync.java
diff --git a/shearapi-withpillow/src/main/java/net/neoforged/neoforge/network/configuration/SyncConfig.java b/shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/configuration/SyncConfig.java
similarity index 100%
rename from shearapi-withpillow/src/main/java/net/neoforged/neoforge/network/configuration/SyncConfig.java
rename to shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/configuration/SyncConfig.java
diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/configuration/SyncRegistries.java b/shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/configuration/SyncRegistries.java
similarity index 97%
rename from shearapi-network/src/main/java/net/neoforged/neoforge/network/configuration/SyncRegistries.java
rename to shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/configuration/SyncRegistries.java
index 8374471..9a000bc 100644
--- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/configuration/SyncRegistries.java
+++ b/shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/configuration/SyncRegistries.java
@@ -24,7 +24,7 @@
@ApiStatus.Internal
public record SyncRegistries() implements ICustomConfigurationTask {
private static final ResourceLocation ID = new ResourceLocation(ShearAPIRuntime.MOD_ID, "sync_registries");
- public static final Type TYPE = new Type(ID);
+ public static final Type TYPE = new Type(ID.toString());
@Override
public void run(Consumer sender) {
diff --git a/shearapi-withpillow/src/main/java/net/neoforged/neoforge/network/payload/ConfigFilePayload.java b/shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/payload/ConfigFilePayload.java
similarity index 100%
rename from shearapi-withpillow/src/main/java/net/neoforged/neoforge/network/payload/ConfigFilePayload.java
rename to shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/payload/ConfigFilePayload.java
diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistryPayload.java b/shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistryPayload.java
similarity index 100%
rename from shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistryPayload.java
rename to shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistryPayload.java
diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistrySyncCompletedPayload.java b/shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistrySyncCompletedPayload.java
similarity index 100%
rename from shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistrySyncCompletedPayload.java
rename to shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistrySyncCompletedPayload.java
diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistrySyncStartPayload.java b/shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistrySyncStartPayload.java
similarity index 100%
rename from shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistrySyncStartPayload.java
rename to shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistrySyncStartPayload.java
diff --git a/shearapi-fmlstuff/src/main/java/net/pillowmc/shearapi/fmlstuff/ShearAPIFMLStuff.java b/shearapi-fmlstuff/src/main/java/net/pillowmc/shearapi/fmlstuff/ShearAPIFMLStuff.java
new file mode 100644
index 0000000..6d5b766
--- /dev/null
+++ b/shearapi-fmlstuff/src/main/java/net/pillowmc/shearapi/fmlstuff/ShearAPIFMLStuff.java
@@ -0,0 +1,53 @@
+package net.pillowmc.shearapi.fmlstuff;
+
+import net.neoforged.bus.api.SubscribeEvent;
+import net.neoforged.neoforge.network.configuration.SyncConfig;
+import net.neoforged.neoforge.network.configuration.SyncRegistries;
+import net.neoforged.neoforge.network.event.OnGameConfigurationEvent;
+import net.neoforged.neoforge.network.event.RegisterPayloadHandlerEvent;
+import net.neoforged.neoforge.network.handling.ConfigurationPayloadContext;
+import net.neoforged.neoforge.network.handling.IConfigurationPayloadHandler;
+import net.neoforged.neoforge.network.payload.ConfigFilePayload;
+import net.neoforged.neoforge.network.payload.FrozenRegistryPayload;
+import net.neoforged.neoforge.network.payload.FrozenRegistrySyncCompletedPayload;
+import net.neoforged.neoforge.network.payload.FrozenRegistrySyncStartPayload;
+import net.neoforged.neoforge.network.registration.IPayloadRegistrar;
+import net.pillowmc.shearapi.runtime.ShearAPIRuntime;
+import net.pillowmc.shearapi.runtime.ShearAPIVersion;
+import net.pillowmc.shearapi.withpillow.ShearAPIWithPillow;
+
+public class ShearAPIFMLStuff {
+ public static Class clazz = ShearAPIFMLStuff.class;
+ public static IConfigurationPayloadHandler clientHandleRegistrySyncCompleted;
+
+ @SubscribeEvent
+ public static void onGameConfigurationEvent(OnGameConfigurationEvent event) {
+ if (event.getListener().isConnected(FrozenRegistrySyncStartPayload.ID) &&
+ event.getListener().isConnected(FrozenRegistryPayload.ID) &&
+ event.getListener().isConnected(FrozenRegistrySyncCompletedPayload.ID)) {
+ event.register(new SyncRegistries());
+ }
+ if (event.getListener().isConnected(ConfigFilePayload.ID) && ShearAPIRuntime.getRuntime() instanceof ShearAPIWithPillow) {
+ event.register(new SyncConfig(event.getListener()));
+ }
+ }
+ @SubscribeEvent
+ public static void onRegisterPayloadHandlerEvent(RegisterPayloadHandlerEvent event) {
+ if (!(ShearAPIRuntime.getRuntime() instanceof ShearAPIWithPillow)) {
+ return;
+ }
+ final IPayloadRegistrar registrar = event.registrar(ShearAPIRuntime.MOD_ID)
+ .versioned(ShearAPIVersion.getSpec())
+ .optional();
+ registrar
+ .configuration(
+ FrozenRegistrySyncCompletedPayload.ID,
+ FrozenRegistrySyncCompletedPayload::new,
+ handlers -> handlers.client(clientHandleRegistrySyncCompleted)
+ .server(ShearAPIFMLStuff::handleRegistrySyncCompleted));
+ }
+
+ public static void handleRegistrySyncCompleted(FrozenRegistrySyncCompletedPayload payload, ConfigurationPayloadContext context) {
+ context.taskCompletedHandler().onTaskCompleted(SyncRegistries.TYPE);
+ }
+}
diff --git a/shearapi-fmlstuff/src/main/resources/assets/shearapi-fmlstuff/icon.png b/shearapi-fmlstuff/src/main/resources/assets/shearapi-fmlstuff/icon.png
new file mode 100644
index 0000000..a1d73a6
Binary files /dev/null and b/shearapi-fmlstuff/src/main/resources/assets/shearapi-fmlstuff/icon.png differ
diff --git a/shearapi-fmlstuff/src/main/resources/fabric.mod.json b/shearapi-fmlstuff/src/main/resources/fabric.mod.json
new file mode 100644
index 0000000..bc50548
--- /dev/null
+++ b/shearapi-fmlstuff/src/main/resources/fabric.mod.json
@@ -0,0 +1,37 @@
+{
+ "schemaVersion": 1,
+ "id": "shearapi-fmlstuff",
+ "version": "${version}",
+ "name": "Shear API (FML Stuff)",
+ "description": "Deal with stuff things if FML installed",
+ "authors": [
+ "PillowMC"
+ ],
+ "contact": {
+ "homepage": "https://github.com/PillowMC/ShearAPI",
+ "sources": "https://github.com/PillowMC/ShearAPI"
+ },
+ "license": "LGPL-2.1",
+ "icon": "assets/shearapi-fmlstuff/icon.png",
+ "environment": "*",
+ "depends": {
+ "fabricloader": ">=0.15.6",
+ "minecraft": "~1.20.4",
+ "java": ">=17",
+ "fabric-api": "*",
+ "shearapi-runtime": "~${version}",
+ "shearapi-network": "~${version}",
+ "shearapi-withpillow": "~${version}"
+ },
+ "entrypoints": {
+ "client": ["net.pillowmc.shearapi.fmlstuff.client.ShearAPIFMLStuffClient"],
+ "shearapi-runtime:client_mod_bus_subscriber": ["net.pillowmc.shearapi.fmlstuff.client.ShearAPIFMLStuffClient::clazz"],
+ "shearapi-runtime:mod_bus_subscriber": ["net.pillowmc.shearapi.fmlstuff.ShearAPIFMLStuff::clazz"]
+ },
+ "custom": {
+ "modmenu": {
+ "parent": "shearapi",
+ "badges": ["library"]
+ }
+ }
+}
diff --git a/shearapi-network/build.gradle b/shearapi-network/build.gradle
index 41ef612..b39be99 100644
--- a/shearapi-network/build.gradle
+++ b/shearapi-network/build.gradle
@@ -1,4 +1,8 @@
+loom {
+ accessWidenerPath = file("src/main/resources/shearapi-network.accesswidener")
+}
+
dependencies {
api project(path: ":shearapi-utils", configuration: "namedElements")
api project(path: ":shearapi-runtime", configuration: "namedElements")
-}
\ No newline at end of file
+}
diff --git a/shearapi-network/src/client/java/net/neoforged/neoforge/network/handlers/ClientPayloadHandler.java b/shearapi-network/src/client/java/net/neoforged/neoforge/network/handlers/ClientPayloadHandler.java
index 95a7878..f89c7c3 100644
--- a/shearapi-network/src/client/java/net/neoforged/neoforge/network/handlers/ClientPayloadHandler.java
+++ b/shearapi-network/src/client/java/net/neoforged/neoforge/network/handlers/ClientPayloadHandler.java
@@ -5,39 +5,21 @@
package net.neoforged.neoforge.network.handlers;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
import io.netty.buffer.Unpooled;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.MenuScreens;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.MenuAccess;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
-import net.minecraft.resources.ResourceKey;
-import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.MenuType;
-import net.neoforged.neoforge.common.TierSortingRegistry;
import net.neoforged.neoforge.common.world.AuxiliaryLightManager;
import net.neoforged.neoforge.common.world.LevelChunkAuxiliaryLightManager;
-import net.neoforged.neoforge.network.ConfigSync;
-import net.neoforged.neoforge.network.handling.ConfigurationPayloadContext;
-import net.neoforged.neoforge.network.handling.IPayloadContext;
import net.neoforged.neoforge.network.handling.PlayPayloadContext;
import net.neoforged.neoforge.network.payload.AdvancedContainerSetDataPayload;
import net.neoforged.neoforge.network.payload.AdvancedOpenScreenPayload;
import net.neoforged.neoforge.network.payload.AuxiliaryLightDataPayload;
-import net.neoforged.neoforge.network.payload.ConfigFilePayload;
-import net.neoforged.neoforge.network.payload.FrozenRegistryPayload;
-import net.neoforged.neoforge.network.payload.FrozenRegistrySyncCompletedPayload;
-import net.neoforged.neoforge.network.payload.FrozenRegistrySyncStartPayload;
-import net.neoforged.neoforge.network.payload.TierSortingRegistryPayload;
-import net.neoforged.neoforge.registries.RegistryManager;
-import net.neoforged.neoforge.registries.RegistrySnapshot;
import org.jetbrains.annotations.ApiStatus;
@ApiStatus.Internal
@@ -48,52 +30,11 @@ public static ClientPayloadHandler getInstance() {
return INSTANCE;
}
- private final Set toSynchronize = Sets.newConcurrentHashSet();
- private final Map synchronizedRegistries = Maps.newConcurrentMap();
-
private ClientPayloadHandler() {}
- public void handle(FrozenRegistryPayload payload, ConfigurationPayloadContext context) {
- synchronizedRegistries.put(payload.registryName(), payload.snapshot());
- toSynchronize.remove(payload.registryName());
- }
-
- public void handle(FrozenRegistrySyncStartPayload payload, ConfigurationPayloadContext context) {
- this.toSynchronize.addAll(payload.toAccess());
- this.synchronizedRegistries.clear();
- }
-
- public void handle(FrozenRegistrySyncCompletedPayload payload, ConfigurationPayloadContext context) {
- if (!this.toSynchronize.isEmpty()) {
- context.packetHandler().disconnect(Component.translatable("neoforge.network.registries.sync.missing", this.toSynchronize.stream().map(Object::toString).collect(Collectors.joining(", "))));
- return;
- }
-
- context.workHandler().submitAsync(() -> {
- //This method normally returns missing entries, but we just accept what the server send us and ignore the rest.
- Set> keysUnknownToClient = RegistryManager.applySnapshot(synchronizedRegistries, false, false);
- if (!keysUnknownToClient.isEmpty()) {
- context.packetHandler().disconnect(Component.translatable("neoforge.network.registries.sync.server-with-unknown-keys", keysUnknownToClient.stream().map(Object::toString).collect(Collectors.joining(", "))));
- return;
- }
-
- this.toSynchronize.clear();
- this.synchronizedRegistries.clear();
- }).exceptionally(e -> {
- context.packetHandler().disconnect(Component.translatable("neoforge.network.registries.sync.failed", e.getMessage()));
- return null;
- }).thenAccept(v -> {
- context.replyHandler().send(new FrozenRegistrySyncCompletedPayload());
- });
- }
-
- public void handle(ConfigFilePayload payload, IPayloadContext context) {
- ConfigSync.INSTANCE.receiveSyncedConfig(payload.contents(), payload.fileName());
- }
-
- public void handle(TierSortingRegistryPayload payload, IPayloadContext context) {
- TierSortingRegistry.handleSync(payload, context);
- }
+// public void handle(TierSortingRegistryPayload payload, IPayloadContext context) {
+// TierSortingRegistry.handleSync(payload, context);
+// }
public void handle(AdvancedOpenScreenPayload msg, PlayPayloadContext context) {
context.workHandler().submitAsync(() -> {
diff --git a/shearapi-network/src/client/java/net/pillowmc/shearapi/network/client/DualStackUtilsClient.java b/shearapi-network/src/client/java/net/pillowmc/shearapi/network/client/DualStackUtilsClient.java
new file mode 100644
index 0000000..d176779
--- /dev/null
+++ b/shearapi-network/src/client/java/net/pillowmc/shearapi/network/client/DualStackUtilsClient.java
@@ -0,0 +1,28 @@
+package net.pillowmc.shearapi.network.client;
+
+import net.minecraft.client.multiplayer.resolver.ResolvedServerAddress;
+import net.minecraft.client.multiplayer.resolver.ServerAddress;
+import net.minecraft.client.multiplayer.resolver.ServerNameResolver;
+import net.neoforged.neoforge.network.DualStackUtils;
+
+import java.net.InetSocketAddress;
+import java.util.Optional;
+
+public class DualStackUtilsClient {
+
+ /**
+ * Resolve the address and see if Java and the OS return an IPv6 or IPv4 one, then let Netty know
+ * accordingly (it doesn't understand the {@code java.net.preferIPv6Addresses=system} property).
+ *
+ * @param hostAddress The address you want to check
+ * @return true if IPv6, false if IPv4
+ */
+ public static boolean checkIPv6(final String hostAddress) {
+ final Optional hostAddr = ServerNameResolver.DEFAULT
+ .resolveAddress(ServerAddress.parseString(hostAddress))
+ .map(ResolvedServerAddress::asInetSocketAddress);
+
+ if (hostAddr.isPresent()) return DualStackUtils.checkIPv6(hostAddr.get().getAddress());
+ else return false;
+ }
+}
diff --git a/shearapi-network/src/client/java/net/pillowmc/shearapi/network/client/ShearAPINetworkClient.java b/shearapi-network/src/client/java/net/pillowmc/shearapi/network/client/ShearAPINetworkClient.java
index 61304d8..ce3653a 100644
--- a/shearapi-network/src/client/java/net/pillowmc/shearapi/network/client/ShearAPINetworkClient.java
+++ b/shearapi-network/src/client/java/net/pillowmc/shearapi/network/client/ShearAPINetworkClient.java
@@ -3,7 +3,6 @@
import net.fabricmc.api.ClientModInitializer;
import net.neoforged.neoforge.network.event.RegisterPayloadHandlerEvent;
import net.neoforged.neoforge.network.handlers.ClientPayloadHandler;
-import net.neoforged.neoforge.network.handlers.ServerPayloadHandler;
import net.neoforged.neoforge.network.payload.*;
import net.neoforged.neoforge.network.registration.IPayloadRegistrar;
import net.pillowmc.shearapi.runtime.ShearAPIRuntime;
@@ -17,27 +16,14 @@ public void onInitializeClient() {
.versioned(ShearAPIVersion.getSpec())
.optional();
registrar
- .common(
- TierSortingRegistryPayload.ID,
- TierSortingRegistryPayload::new,
- handlers -> handlers.client(ClientPayloadHandler.getInstance()::handle))
- .configuration(
- FrozenRegistrySyncStartPayload.ID,
- FrozenRegistrySyncStartPayload::new,
- handlers -> handlers.client(ClientPayloadHandler.getInstance()::handle))
- .configuration(
- FrozenRegistryPayload.ID,
- FrozenRegistryPayload::new,
- handlers -> handlers.client(ClientPayloadHandler.getInstance()::handle))
- .configuration(
- FrozenRegistrySyncCompletedPayload.ID,
- FrozenRegistrySyncCompletedPayload::new,
- handlers -> handlers.client(ClientPayloadHandler.getInstance()::handle)
- .server(ServerPayloadHandler.getInstance()::handle))
- .configuration(
- TierSortingRegistrySyncCompletePayload.ID,
- TierSortingRegistrySyncCompletePayload::new,
- handlers -> handlers.server(ServerPayloadHandler.getInstance()::handle))
+// .common(
+// TierSortingRegistryPayload.ID,
+// TierSortingRegistryPayload::new,
+// handlers -> handlers.client(ClientPayloadHandler.getInstance()::handle))
+// .configuration(
+// TierSortingRegistrySyncCompletePayload.ID,
+// TierSortingRegistrySyncCompletePayload::new,
+// handlers -> handlers.server(ServerPayloadHandler.getInstance()::handle))
.play(
AdvancedOpenScreenPayload.ID,
AdvancedOpenScreenPayload::new,
diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/ConfigurationInitialization.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/ConfigurationInitialization.java
index 5b2a00e..07f2be1 100644
--- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/ConfigurationInitialization.java
+++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/ConfigurationInitialization.java
@@ -1,31 +1,21 @@
-/*
- * Copyright (c) NeoForged and contributors
- * SPDX-License-Identifier: LGPL-2.1-only
- */
-
-package net.neoforged.neoforge.network;
-
-import net.neoforged.bus.api.SubscribeEvent;
-import net.neoforged.neoforge.network.configuration.SyncRegistries;
-import net.neoforged.neoforge.network.configuration.SyncTierSortingRegistry;
-import net.neoforged.neoforge.network.event.OnGameConfigurationEvent;
-import net.neoforged.neoforge.network.payload.FrozenRegistryPayload;
-import net.neoforged.neoforge.network.payload.FrozenRegistrySyncCompletedPayload;
-import net.neoforged.neoforge.network.payload.FrozenRegistrySyncStartPayload;
-import org.jetbrains.annotations.ApiStatus;
-
-@ApiStatus.Internal
-public class ConfigurationInitialization {
- public static Class clazz = ConfigurationInitialization.class;
- @SubscribeEvent
- private static void configureModdedClient(OnGameConfigurationEvent event) {
- if (event.getListener().isConnected(FrozenRegistrySyncStartPayload.ID) &&
- event.getListener().isConnected(FrozenRegistryPayload.ID) &&
- event.getListener().isConnected(FrozenRegistrySyncCompletedPayload.ID)) {
- event.register(new SyncRegistries());
- }
-
- //These two can always be registered they detect the listener connection type internally and will skip themselves.
- event.register(new SyncTierSortingRegistry(event.getListener()));
- }
-}
+///*
+// * Copyright (c) NeoForged and contributors
+// * SPDX-License-Identifier: LGPL-2.1-only
+// */
+//
+//package net.neoforged.neoforge.network;
+//
+//import net.neoforged.bus.api.SubscribeEvent;
+//import net.neoforged.neoforge.network.configuration.SyncTierSortingRegistry;
+//import net.neoforged.neoforge.network.event.OnGameConfigurationEvent;
+//import org.jetbrains.annotations.ApiStatus;
+//
+//@ApiStatus.Internal
+//public class ConfigurationInitialization {
+// public static Class clazz = ConfigurationInitialization.class;
+// @SubscribeEvent
+// private static void configureModdedClient(OnGameConfigurationEvent event) {
+// //These two can always be registered they detect the listener connection type internally and will skip themselves.
+// event.register(new SyncTierSortingRegistry(event.getListener()));
+// }
+//}
diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/DualStackUtils.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/DualStackUtils.java
index 40ce896..5f18564 100644
--- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/DualStackUtils.java
+++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/DualStackUtils.java
@@ -13,13 +13,8 @@
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.UnknownHostException;
-import java.util.Optional;
import javax.annotation.Nullable;
-import net.minecraft.client.multiplayer.resolver.ResolvedServerAddress;
-import net.minecraft.client.multiplayer.resolver.ServerAddress;
-import net.minecraft.client.multiplayer.resolver.ServerNameResolver;
import net.minecraft.util.HttpUtil;
-import net.neoforged.neoforge.common.NeoForge;
import org.jetbrains.annotations.ApiStatus;
import org.slf4j.Logger;
@@ -37,22 +32,6 @@ public class DualStackUtils {
@ApiStatus.Internal
public static void initialise() {}
- /**
- * Resolve the address and see if Java and the OS return an IPv6 or IPv4 one, then let Netty know
- * accordingly (it doesn't understand the {@code java.net.preferIPv6Addresses=system} property).
- *
- * @param hostAddress The address you want to check
- * @return true if IPv6, false if IPv4
- */
- public static boolean checkIPv6(final String hostAddress) {
- final Optional hostAddr = ServerNameResolver.DEFAULT
- .resolveAddress(ServerAddress.parseString(hostAddress))
- .map(ResolvedServerAddress::asInetSocketAddress);
-
- if (hostAddr.isPresent()) return checkIPv6(hostAddr.get().getAddress());
- else return false;
- }
-
/**
* Checks if an address is an IPv6 one or an IPv4 one, lets Netty know accordingly and returns the result.
*
@@ -123,7 +102,7 @@ public static InetAddress getLocalAddress() {
/**
* Used for the "Open to LAN" feature.
- *
+ *
* @return The multicast group to use for LAN discovery - IPv6 if available, IPv4 otherwise.
*/
public static String getMulticastGroup() {
diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/PacketDistributor.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/PacketDistributor.java
index e6d404c..ecb9f8f 100644
--- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/PacketDistributor.java
+++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/PacketDistributor.java
@@ -12,7 +12,6 @@
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
-import net.minecraft.client.Minecraft;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.PacketFlow;
import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket;
@@ -27,7 +26,9 @@
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.chunk.LevelChunk;
+import net.pillowmc.shearapi.utils.IClientLike;
import net.pillowmc.shearapi.utils.ServerUtils;
+import net.pillowmc.shearapi.utils.Utils;
/**
* Means to distribute packets in various ways
@@ -111,7 +112,7 @@ public TargetPoint(final ServerPlayer excluded, final double x, final double y,
/**
* A target point without excluded entity
- *
+ *
* @param x X
* @param y Y
* @param z Z
@@ -129,7 +130,7 @@ public TargetPoint(final double x, final double y, final double z, final double
/**
* Helper to build a TargetPoint without excluded Entity
- *
+ *
* @param x X
* @param y Y
* @param z Z
@@ -167,7 +168,7 @@ public void send(CustomPacketPayload... payloads) {
for (CustomPacketPayload payload : payloads) {
packets.add(new ClientboundCustomPayloadPacket(payload));
}
- this.send(new ClientboundBundlePacket(packets));
+ this.send(new ClientboundBundlePacket((Iterable>)(Object) packets));
} else if (payloads.length == 1) {
this.send(new ClientboundCustomPayloadPacket(payloads[0]));
}
@@ -197,7 +198,7 @@ public PacketDistributor(Function, Consumer>> fun
/**
* Apply the supplied value to the specific distributor to generate an instance for sending packets to.
- *
+ *
* @param input The input to apply
* @return A curried instance
*/
@@ -229,7 +230,7 @@ private Consumer> playerListAll() {
}
private Consumer> clientToServer() {
- return p -> Objects.requireNonNull(Minecraft.getInstance().getConnection()).send(p);
+ return p -> Utils.getClient().ifPresent(c -> c.shearAPI$sendPacket(p));
}
private Consumer> playerListPointConsumer(final TargetPoint targetPoint) {
diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/configuration/SyncTierSortingRegistry.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/configuration/SyncTierSortingRegistry.java
index d6e8d5f..8a8e03f 100644
--- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/configuration/SyncTierSortingRegistry.java
+++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/configuration/SyncTierSortingRegistry.java
@@ -1,35 +1,35 @@
-/*
- * Copyright (c) NeoForged and contributors
- * SPDX-License-Identifier: LGPL-2.1-only
- */
-
-package net.neoforged.neoforge.network.configuration;
-
-import java.util.function.Consumer;
-import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
-import net.minecraft.network.protocol.configuration.ServerConfigurationPacketListener;
-import net.minecraft.resources.ResourceLocation;
-import net.neoforged.neoforge.common.TierSortingRegistry;
-import net.pillowmc.shearapi.runtime.ShearAPIRuntime;
-import org.jetbrains.annotations.ApiStatus;
-
-/**
- * Syncs the tier sorting registry to the client
- *
- * @param listener the listener to indicate the check if it is a vanilla connection
- */
-@ApiStatus.Internal
-public record SyncTierSortingRegistry(ServerConfigurationPacketListener listener) implements ICustomConfigurationTask {
- private static final ResourceLocation ID = new ResourceLocation(ShearAPIRuntime.MOD_ID, "sync_tier_sorting");
- public static final Type TYPE = new Type(ID);
-
- @Override
- public void run(Consumer sender) {
- TierSortingRegistry.sync(listener(), sender);
- }
-
- @Override
- public Type type() {
- return TYPE;
- }
-}
+///*
+// * Copyright (c) NeoForged and contributors
+// * SPDX-License-Identifier: LGPL-2.1-only
+// */
+//
+//package net.neoforged.neoforge.network.configuration;
+//
+//import java.util.function.Consumer;
+//import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
+//import net.minecraft.network.protocol.configuration.ServerConfigurationPacketListener;
+//import net.minecraft.resources.ResourceLocation;
+//import net.neoforged.neoforge.common.TierSortingRegistry;
+//import net.pillowmc.shearapi.runtime.ShearAPIRuntime;
+//import org.jetbrains.annotations.ApiStatus;
+//
+///**
+// * Syncs the tier sorting registry to the client
+// *
+// * @param listener the listener to indicate the check if it is a vanilla connection
+// */
+//@ApiStatus.Internal
+//public record SyncTierSortingRegistry(ServerConfigurationPacketListener listener) implements ICustomConfigurationTask {
+// private static final ResourceLocation ID = new ResourceLocation(ShearAPIRuntime.MOD_ID, "sync_tier_sorting");
+// public static final Type TYPE = new Type(ID.toString());
+//
+// @Override
+// public void run(Consumer sender) {
+// TierSortingRegistry.sync(listener(), sender);
+// }
+//
+// @Override
+// public Type type() {
+// return TYPE;
+// }
+//}
diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/filters/GenericPacketSplitter.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/filters/GenericPacketSplitter.java
index b02ef66..17ddcb2 100644
--- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/filters/GenericPacketSplitter.java
+++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/filters/GenericPacketSplitter.java
@@ -27,7 +27,6 @@
import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket;
import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket;
import net.neoforged.bus.api.SubscribeEvent;
-import net.neoforged.fml.common.Mod;
import net.pillowmc.shearapi.runtime.ShearAPIRuntime;
import net.neoforged.neoforge.network.connection.ConnectionPhase;
import net.neoforged.neoforge.network.connection.ConnectionType;
@@ -43,9 +42,9 @@
/**
* A generic packet splitter that can be used to split packets that are too large to be sent in one go.
*/
-@Mod.EventBusSubscriber(modid = ShearAPIRuntime.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
@ApiStatus.Internal
public class GenericPacketSplitter extends MessageToMessageEncoder> implements DynamicChannelHandler {
+ public static Class clazz = GenericPacketSplitter.class;
private static final Logger LOGGER = LogManager.getLogger();
private static final int MAX_PACKET_SIZE = CompressionDecoder.MAXIMUM_UNCOMPRESSED_LENGTH;
diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/filters/VanillaConnectionNetworkFilter.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/filters/VanillaConnectionNetworkFilter.java
index 2885b07..aa3b5ae 100644
--- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/filters/VanillaConnectionNetworkFilter.java
+++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/filters/VanillaConnectionNetworkFilter.java
@@ -9,9 +9,12 @@
import com.mojang.brigadier.tree.RootCommandNode;
import com.mojang.logging.LogUtils;
import io.netty.channel.ChannelHandler;
+
+import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
import net.minecraft.commands.CommandBuildContext;
@@ -33,7 +36,7 @@
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagNetworkSerialization;
import net.neoforged.neoforge.network.connection.ConnectionType;
-import net.neoforged.neoforge.registries.RegistryManager;
+import net.pillowmc.shearapi.runtime.ShearAPIRuntime;
import org.slf4j.Logger;
/**
@@ -51,7 +54,7 @@ public VanillaConnectionNetworkFilter(ConnectionType connectionType) {
ImmutableMap.>, BiConsumer, List super Packet>>>>builder()
.put(handler(ClientboundUpdateAttributesPacket.class, VanillaConnectionNetworkFilter::filterEntityProperties))
.put(handler(ClientboundCommandsPacket.class, VanillaConnectionNetworkFilter::filterCommandList))
- .put(handler(ClientboundUpdateTagsPacket.class, VanillaConnectionNetworkFilter::filterCustomTagTypes))
+ .putAll(getFilterCustomTagTypes().stream().toList())
.build());
this.connectionType = connectionType;
@@ -95,6 +98,11 @@ private static ClientboundCommandsPacket filterCommandList(ClientboundCommandsPa
return new ClientboundCommandsPacket(newRoot);
}
+ private static Optional>, BiConsumer, List super Packet>>>>> getFilterCustomTagTypes() {
+ if (!ShearAPIRuntime.getRuntime().isModLoaded("shearapi-registries")) return Optional.empty();
+ return Optional.of(handler(ClientboundUpdateTagsPacket.class, VanillaConnectionNetworkFilter::filterCustomTagTypes));
+ }
+
/**
* Filters out custom tag types that the vanilla client won't recognize.
* It prevents a rare error from logging and reduces the packet size
@@ -107,8 +115,12 @@ private static ClientboundUpdateTagsPacket filterCustomTagTypes(ClientboundUpdat
}
private static boolean isVanillaRegistry(ResourceLocation location) {
- // Checks if the registry name is contained within the static view of both BuiltInRegistries and VanillaRegistries
- return RegistryManager.getVanillaRegistryKeys().contains(location)
- || VanillaRegistries.DATAPACK_REGISTRY_KEYS.stream().anyMatch(k -> k.location().equals(location));
+ try {
+ return (Boolean)Class.forName("net.pillowmc.shearapi.registries.ShearAPIRegistries")
+ .getMethod("isVanillaRegistry", ResourceLocation.class)
+ .invoke(null, location);
+ } catch (NoSuchMethodException | ClassNotFoundException | IllegalAccessException | InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
}
}
diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/handlers/ServerPayloadHandler.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/handlers/ServerPayloadHandler.java
index ee1d298..572871c 100644
--- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/handlers/ServerPayloadHandler.java
+++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/handlers/ServerPayloadHandler.java
@@ -1,32 +1,26 @@
-/*
- * Copyright (c) NeoForged and contributors
- * SPDX-License-Identifier: LGPL-2.1-only
- */
-
-package net.neoforged.neoforge.network.handlers;
-
-import net.neoforged.neoforge.network.configuration.SyncRegistries;
-import net.neoforged.neoforge.network.configuration.SyncTierSortingRegistry;
-import net.neoforged.neoforge.network.handling.ConfigurationPayloadContext;
-import net.neoforged.neoforge.network.payload.FrozenRegistrySyncCompletedPayload;
-import net.neoforged.neoforge.network.payload.TierSortingRegistrySyncCompletePayload;
-import org.jetbrains.annotations.ApiStatus;
-
-@ApiStatus.Internal
-public class ServerPayloadHandler {
- private static final ServerPayloadHandler INSTANCE = new ServerPayloadHandler();
-
- public static ServerPayloadHandler getInstance() {
- return INSTANCE;
- }
-
- private ServerPayloadHandler() {}
-
- public void handle(FrozenRegistrySyncCompletedPayload payload, ConfigurationPayloadContext context) {
- context.taskCompletedHandler().onTaskCompleted(SyncRegistries.TYPE);
- }
-
- public void handle(TierSortingRegistrySyncCompletePayload payload, ConfigurationPayloadContext context) {
- context.taskCompletedHandler().onTaskCompleted(SyncTierSortingRegistry.TYPE);
- }
-}
+///*
+// * Copyright (c) NeoForged and contributors
+// * SPDX-License-Identifier: LGPL-2.1-only
+// */
+//
+//package net.neoforged.neoforge.network.handlers;
+//
+//import net.neoforged.neoforge.network.configuration.SyncTierSortingRegistry;
+//import net.neoforged.neoforge.network.handling.ConfigurationPayloadContext;
+//import net.neoforged.neoforge.network.payload.TierSortingRegistrySyncCompletePayload;
+//import org.jetbrains.annotations.ApiStatus;
+//
+//@ApiStatus.Internal
+//public class ServerPayloadHandler {
+// private static final ServerPayloadHandler INSTANCE = new ServerPayloadHandler();
+//
+// public static ServerPayloadHandler getInstance() {
+// return INSTANCE;
+// }
+//
+// private ServerPayloadHandler() {}
+//
+// public void handle(TierSortingRegistrySyncCompletePayload payload, ConfigurationPayloadContext context) {
+// context.taskCompletedHandler().onTaskCompleted(SyncTierSortingRegistry.TYPE);
+// }
+//}
diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/negotiation/NetworkComponentNegotiator.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/negotiation/NetworkComponentNegotiator.java
index 15abfda..6ea9ad0 100644
--- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/negotiation/NetworkComponentNegotiator.java
+++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/negotiation/NetworkComponentNegotiator.java
@@ -14,7 +14,7 @@
import java.util.Optional;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
-import net.neoforged.fml.ModList;
+import net.pillowmc.shearapi.runtime.ShearAPIRuntime;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.VisibleForTesting;
@@ -80,7 +80,7 @@ public static NegotiationResult negotiate(List serve
final Map failureReasons = new HashMap<>();
client.forEach(c -> {
Component channelFailureReason = Component.translatable("neoforge.network.negotiation.failure.missing.client.server");
- String modDisplayName = ModList.get().getModContainerById(c.id().getNamespace()).map(mc -> mc.getModInfo().getDisplayName()).orElse("");
+ String modDisplayName = ShearAPIRuntime.getRuntime().getModDisplayName(c.id().getNamespace()).orElse("");
failureReasons.put(c.id(), modDisplayName.isEmpty() ? channelFailureReason : Component.translatable("neoforge.network.negotiation.failure.mod", modDisplayName, channelFailureReason));
});
return new NegotiationResult(List.of(), false, failureReasons);
@@ -90,7 +90,7 @@ public static NegotiationResult negotiate(List serve
final Map failureReasons = new HashMap<>();
server.forEach(c -> {
Component channelFailureReason = Component.translatable("neoforge.network.negotiation.failure.missing.server.client");
- String modDisplayName = ModList.get().getModContainerById(c.id().getNamespace()).map(mc -> mc.getModInfo().getDisplayName()).orElse("");
+ String modDisplayName = ShearAPIRuntime.getRuntime().getModDisplayName(c.id().getNamespace()).orElse("");
failureReasons.put(c.id(), modDisplayName.isEmpty() ? channelFailureReason : Component.translatable("neoforge.network.negotiation.failure.mod", modDisplayName, channelFailureReason));
});
return new NegotiationResult(List.of(), false, failureReasons);
@@ -101,7 +101,7 @@ public static NegotiationResult negotiate(List serve
for (Table.Cell match : matches.cellSet()) {
final NegotiableNetworkComponent serverComponent = match.getColumnKey();
final NegotiableNetworkComponent clientComponent = match.getValue();
- final String modDisplayName = ModList.get().getModContainerById(serverComponent.id().getNamespace()).map(mc -> mc.getModInfo().getDisplayName()).orElse("");
+ String modDisplayName = ShearAPIRuntime.getRuntime().getModDisplayName(serverComponent.id().getNamespace()).orElse("");
Optional serverToClientComparison = validateComponent(serverComponent, clientComponent, "client");
if (serverToClientComparison.isPresent() && !serverToClientComparison.get().success()) {
diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/TierSortingRegistryPayload.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/TierSortingRegistryPayload.java
index da71f81..f1f2c2f 100644
--- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/TierSortingRegistryPayload.java
+++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/TierSortingRegistryPayload.java
@@ -1,40 +1,40 @@
-/*
- * Copyright (c) NeoForged and contributors
- * SPDX-License-Identifier: LGPL-2.1-only
- */
-
-package net.neoforged.neoforge.network.payload;
-
-import java.util.List;
-import net.minecraft.network.FriendlyByteBuf;
-import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
-import net.minecraft.resources.ResourceLocation;
-import net.pillowmc.shearapi.runtime.ShearAPIRuntime;
-import org.jetbrains.annotations.ApiStatus;
-
-/**
- * The payload for the tier sorting registry packet.
- *
- * This payload is used to send the tier order to the client.
- *
- *
- * @param tiers The tiers in order.
- */
-@ApiStatus.Internal
-public record TierSortingRegistryPayload(List tiers) implements CustomPacketPayload {
- public static final ResourceLocation ID = new ResourceLocation(ShearAPIRuntime.MOD_ID, "tier_sorting");
-
- public TierSortingRegistryPayload(FriendlyByteBuf buf) {
- this(buf.readList(FriendlyByteBuf::readResourceLocation));
- }
-
- @Override
- public void write(FriendlyByteBuf buf) {
- buf.writeCollection(tiers(), FriendlyByteBuf::writeResourceLocation);
- }
-
- @Override
- public ResourceLocation id() {
- return ID;
- }
-}
+///*
+// * Copyright (c) NeoForged and contributors
+// * SPDX-License-Identifier: LGPL-2.1-only
+// */
+//
+//package net.neoforged.neoforge.network.payload;
+//
+//import java.util.List;
+//import net.minecraft.network.FriendlyByteBuf;
+//import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
+//import net.minecraft.resources.ResourceLocation;
+//import net.pillowmc.shearapi.runtime.ShearAPIRuntime;
+//import org.jetbrains.annotations.ApiStatus;
+//
+///**
+// * The payload for the tier sorting registry packet.
+// *
+// * This payload is used to send the tier order to the client.
+// *
+// *
+// * @param tiers The tiers in order.
+// */
+//@ApiStatus.Internal
+//public record TierSortingRegistryPayload(List tiers) implements CustomPacketPayload {
+// public static final ResourceLocation ID = new ResourceLocation(ShearAPIRuntime.MOD_ID, "tier_sorting");
+//
+// public TierSortingRegistryPayload(FriendlyByteBuf buf) {
+// this(buf.readList(FriendlyByteBuf::readResourceLocation));
+// }
+//
+// @Override
+// public void write(FriendlyByteBuf buf) {
+// buf.writeCollection(tiers(), FriendlyByteBuf::writeResourceLocation);
+// }
+//
+// @Override
+// public ResourceLocation id() {
+// return ID;
+// }
+//}
diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/TierSortingRegistrySyncCompletePayload.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/TierSortingRegistrySyncCompletePayload.java
index 19fd02c..4d4c81f 100644
--- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/TierSortingRegistrySyncCompletePayload.java
+++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/TierSortingRegistrySyncCompletePayload.java
@@ -1,32 +1,32 @@
-/*
- * Copyright (c) NeoForged and contributors
- * SPDX-License-Identifier: LGPL-2.1-only
- */
-
-package net.neoforged.neoforge.network.payload;
-
-import net.minecraft.network.FriendlyByteBuf;
-import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
-import net.minecraft.resources.ResourceLocation;
-import net.pillowmc.shearapi.runtime.ShearAPIRuntime;
-import org.jetbrains.annotations.ApiStatus;
-
-/**
- * This payload is sent by the server to the client when the tier sorting registry has been fully synced.
- */
-@ApiStatus.Internal
-public record TierSortingRegistrySyncCompletePayload() implements CustomPacketPayload {
- public static final ResourceLocation ID = new ResourceLocation(ShearAPIRuntime.MOD_ID, "tier_sorting_registry_sync_complete");
-
- public TierSortingRegistrySyncCompletePayload(FriendlyByteBuf buf) {
- this();
- }
-
- @Override
- public void write(FriendlyByteBuf buf) {}
-
- @Override
- public ResourceLocation id() {
- return ID;
- }
-}
+///*
+// * Copyright (c) NeoForged and contributors
+// * SPDX-License-Identifier: LGPL-2.1-only
+// */
+//
+//package net.neoforged.neoforge.network.payload;
+//
+//import net.minecraft.network.FriendlyByteBuf;
+//import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
+//import net.minecraft.resources.ResourceLocation;
+//import net.pillowmc.shearapi.runtime.ShearAPIRuntime;
+//import org.jetbrains.annotations.ApiStatus;
+//
+///**
+// * This payload is sent by the server to the client when the tier sorting registry has been fully synced.
+// */
+//@ApiStatus.Internal
+//public record TierSortingRegistrySyncCompletePayload() implements CustomPacketPayload {
+// public static final ResourceLocation ID = new ResourceLocation(ShearAPIRuntime.MOD_ID, "tier_sorting_registry_sync_complete");
+//
+// public TierSortingRegistrySyncCompletePayload(FriendlyByteBuf buf) {
+// this();
+// }
+//
+// @Override
+// public void write(FriendlyByteBuf buf) {}
+//
+// @Override
+// public ResourceLocation id() {
+// return ID;
+// }
+//}
diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java
index 1c4ba5b..1eb98e8 100644
--- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java
+++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java
@@ -43,7 +43,6 @@
import net.minecraft.server.network.ServerConfigurationPacketListenerImpl;
import net.minecraft.server.network.ServerPlayerConnection;
import net.minecraft.util.thread.ReentrantBlockableEventLoop;
-import net.neoforged.fml.config.ConfigTracker;
import net.pillowmc.shearapi.runtime.ShearAPIRuntime;
import net.neoforged.neoforge.network.connection.ConnectionPhase;
import net.neoforged.neoforge.network.connection.ConnectionType;
@@ -65,6 +64,7 @@
import net.neoforged.neoforge.network.payload.ModdedNetworkQueryComponent;
import net.neoforged.neoforge.network.payload.ModdedNetworkQueryPayload;
import net.neoforged.neoforge.network.payload.ModdedNetworkSetupFailedPayload;
+import net.pillowmc.shearapi.runtime.ShearAPIVersion;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
@@ -284,11 +284,11 @@ public FriendlyByteBuf.Reader extends CustomPacketPayload> getReader(ResourceL
* @param packet The packet that was received.
*/
public void onModdedPacketAtServer(ServerCommonPacketListener listener, ServerboundCustomPayloadPacket packet) {
- final NetworkPayloadSetup payloadSetup = listener.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).get();
+ final NetworkPayloadSetup payloadSetup = listener.getConnection().channel.attr(ATTRIBUTE_PAYLOAD_SETUP).get();
//Check if this client was even setup properly.
if (payloadSetup == null) {
LOGGER.warn("Received a modded custom payload packet from a client that has not negotiated with the server. Disconnecting client.");
- listener.disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(NeoForgeVersion.getVersion())));
+ listener.disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(ShearAPIVersion.getVersion())));
return;
}
@@ -299,7 +299,7 @@ public void onModdedPacketAtServer(ServerCommonPacketListener listener, Serverbo
//Check if the channel should even be processed.
if (channel == null && !isAdhocConfigurationChannelReadable(packet.payload().id(), PacketFlow.SERVERBOUND)) {
LOGGER.warn("Received a modded custom payload packet from a client with an unknown or not accepted channel. Disconnecting client.");
- listener.disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(NeoForgeVersion.getVersion())));
+ listener.disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(ShearAPIVersion.getVersion())));
return;
}
@@ -319,7 +319,7 @@ public void onModdedPacketAtServer(ServerCommonPacketListener listener, Serverbo
configurationPacketListener::finishCurrentTask,
new EventLoopSynchronizedWorkHandler<>(configurationPacketListener.getMainThreadEventLoop(), packet.payload()),
PacketFlow.SERVERBOUND,
- listener.getConnection().channel().pipeline().lastContext(),
+ listener.getConnection().channel.pipeline().lastContext(),
Optional.empty()));
} else if (listener instanceof ServerGamePacketListener playPacketListener) {
//Get the configuration channel for the packet.
@@ -328,7 +328,7 @@ public void onModdedPacketAtServer(ServerCommonPacketListener listener, Serverbo
//Check if the channel should even be processed.
if (channel == null && !isAdhocPlayChannelReadable(packet.payload().id(), PacketFlow.SERVERBOUND)) {
LOGGER.warn("Received a modded custom payload packet from a client with an unknown or not accepted channel. Disconnecting client.");
- listener.disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(NeoForgeVersion.getVersion())));
+ listener.disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(ShearAPIVersion.getVersion())));
return;
}
@@ -347,7 +347,7 @@ public void onModdedPacketAtServer(ServerCommonPacketListener listener, Serverbo
new ServerPacketHandler(playPacketListener),
new EventLoopSynchronizedWorkHandler<>(playPacketListener.getMainThreadEventLoop(), packet.payload()),
PacketFlow.SERVERBOUND,
- listener.getConnection().channel().pipeline().lastContext(),
+ listener.getConnection().channel.pipeline().lastContext(),
listener instanceof ServerPlayerConnection connection ? Optional.of(connection.getPlayer()) : Optional.empty()));
} else {
LOGGER.error("Received a modded custom payload packet from a client that is not in the configuration or play phase. Disconnecting client.");
@@ -367,12 +367,13 @@ public void onModdedPacketAtServer(ServerCommonPacketListener listener, Serverbo
* @param listener The listener which received the packet.
* @param packet The packet that was received.
*/
+ // TODO: (ShearAPI) move to client
public boolean onModdedPacketAtClient(ClientCommonPacketListener listener, ClientboundCustomPayloadPacket packet) {
if (packet.payload().id().getNamespace().equals("minecraft")) {
return false;
}
- final NetworkPayloadSetup payloadSetup = listener.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).get();
+ final NetworkPayloadSetup payloadSetup = listener.getConnection().channel.attr(ATTRIBUTE_PAYLOAD_SETUP).get();
//Check if this server was even setup properly.
if (payloadSetup == null) {
LOGGER.warn("Received a modded custom payload packet from a server that has not negotiated with the client. Disconnecting server.");
@@ -407,7 +408,7 @@ public boolean onModdedPacketAtClient(ClientCommonPacketListener listener, Clien
(task) -> LOGGER.warn("Tried to finish a task on the client. This should not happen. Ignoring. Task: {}", task),
new EventLoopSynchronizedWorkHandler<>(configurationPacketListener.getMainThreadEventLoop(), packet.payload()),
PacketFlow.CLIENTBOUND,
- listener.getConnection().channel().pipeline().lastContext(),
+ listener.getConnection().channel.pipeline().lastContext(),
Optional.ofNullable(configurationPacketListener.getMinecraft().player)));
} else if (listener instanceof ClientGamePacketListener playPacketListener) {
//Get the configuration channel for the packet.
@@ -416,7 +417,7 @@ public boolean onModdedPacketAtClient(ClientCommonPacketListener listener, Clien
//Check if the channel should even be processed.
if (channel == null && !isAdhocPlayChannelReadable(packet.payload().id(), PacketFlow.CLIENTBOUND)) {
LOGGER.warn("Received a modded custom payload packet from a server with an unknown or not accepted channel. Disconnecting server.");
- listener.getConnection().disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(NeoForgeVersion.getVersion())));
+ listener.getConnection().disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(ShearAPIVersion.getVersion())));
return false;
}
@@ -435,7 +436,7 @@ public boolean onModdedPacketAtClient(ClientCommonPacketListener listener, Clien
new ClientPacketHandler(playPacketListener),
new EventLoopSynchronizedWorkHandler<>(playPacketListener.getMainThreadEventLoop(), packet.payload()),
PacketFlow.CLIENTBOUND,
- listener.getConnection().channel().pipeline().lastContext(),
+ listener.getConnection().channel.pipeline().lastContext(),
Optional.ofNullable(playPacketListener.getMinecraft().player)));
} else {
LOGGER.error("Received a modded custom payload packet from a server that is not in the configuration or play phase. Disconnecting server.");
@@ -469,9 +470,9 @@ public void onModdedConnectionDetectedAtServer(ServerConfigurationPacketListener
.map(entry -> new NegotiableNetworkComponent(entry.id(), entry.version(), entry.flow(), entry.optional()))
.toList());
- sender.getConnection().channel().attr(ATTRIBUTE_CONNECTION_TYPE).set(sender.getConnectionType());
- sender.getConnection().channel().attr(ATTRIBUTE_FLOW).set(PacketFlow.SERVERBOUND);
- sender.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).set(NetworkPayloadSetup.empty());
+ sender.getConnection().channel.attr(ATTRIBUTE_CONNECTION_TYPE).set(sender.getConnectionType());
+ sender.getConnection().channel.attr(ATTRIBUTE_FLOW).set(PacketFlow.SERVERBOUND);
+ sender.getConnection().channel.attr(ATTRIBUTE_PAYLOAD_SETUP).set(NetworkPayloadSetup.empty());
//Negotiation failed. Disconnect the client.
if (!configurationNegotiationResult.success()) {
@@ -479,7 +480,7 @@ public void onModdedConnectionDetectedAtServer(ServerConfigurationPacketListener
sender.send(new ModdedNetworkSetupFailedPayload(configurationNegotiationResult.failureReasons()));
}
- sender.disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(NeoForgeVersion.getVersion())));
+ sender.disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(ShearAPIVersion.getVersion())));
return;
}
@@ -497,7 +498,7 @@ public void onModdedConnectionDetectedAtServer(ServerConfigurationPacketListener
sender.send(new ModdedNetworkSetupFailedPayload(playNegotiationResult.failureReasons()));
}
- sender.disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(NeoForgeVersion.getVersion())));
+ sender.disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(ShearAPIVersion.getVersion())));
}
final NetworkPayloadSetup setup = NetworkPayloadSetup.from(
@@ -508,7 +509,7 @@ public void onModdedConnectionDetectedAtServer(ServerConfigurationPacketListener
.map(entry -> new NetworkChannel(entry.id(), entry.version()))
.collect(Collectors.toSet()));
- sender.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).set(setup);
+ sender.getConnection().channel.attr(ATTRIBUTE_PAYLOAD_SETUP).set(setup);
NetworkFilters.injectIfNecessary(sender.getConnection(), sender.getConnectionType());
@@ -537,13 +538,13 @@ public boolean onVanillaOrOtherConnectionDetectedAtServer(ServerConfigurationPac
List.of());
//Because we are in vanilla land, no matter what we are not able to support any custom channels.
- sender.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).set(NetworkPayloadSetup.empty());
- sender.getConnection().channel().attr(ATTRIBUTE_CONNECTION_TYPE).set(sender.getConnectionType());
- sender.getConnection().channel().attr(ATTRIBUTE_FLOW).set(PacketFlow.SERVERBOUND);
+ sender.getConnection().channel.attr(ATTRIBUTE_PAYLOAD_SETUP).set(NetworkPayloadSetup.empty());
+ sender.getConnection().channel.attr(ATTRIBUTE_CONNECTION_TYPE).set(sender.getConnectionType());
+ sender.getConnection().channel.attr(ATTRIBUTE_FLOW).set(PacketFlow.SERVERBOUND);
//Negotiation failed. Disconnect the client.
if (!configurationNegotiationResult.success()) {
- sender.disconnect(Component.translatableWithFallback("neoforge.network.negotiation.failure.vanilla.client.not_supported", "You are trying to connect to a server that is running NeoForge, but you are not. Please install NeoForge Version: %s to connect to this server.", NeoForgeVersion.getVersion()));
+ sender.disconnect(Component.translatableWithFallback("neoforge.network.negotiation.failure.vanilla.client.not_supported", "You are trying to connect to a server that is running NeoForge, but you are not. Please install NeoForge Version: %s to connect to this server.", ShearAPIVersion.getVersion()));
return false;
}
@@ -555,7 +556,7 @@ public boolean onVanillaOrOtherConnectionDetectedAtServer(ServerConfigurationPac
//Negotiation failed. Disconnect the client.
if (!playNegotiationResult.success()) {
- sender.disconnect(Component.translatableWithFallback("neoforge.network.negotiation.failure.vanilla.client.not_supported", "You are trying to connect to a server that is running NeoForge, but you are not. Please install NeoForge Version: %s to connect to this server.", NeoForgeVersion.getVersion()));
+ sender.disconnect(Component.translatableWithFallback("neoforge.network.negotiation.failure.vanilla.client.not_supported", "You are trying to connect to a server that is running NeoForge, but you are not. Please install NeoForge Version: %s to connect to this server.", ShearAPIVersion.getVersion()));
return false;
}
@@ -644,6 +645,7 @@ public boolean shouldSendPacketRaw(Packet> packet) {
* @param listener The listener that wants to send the packet.
* @return True if the packet can be sent, false otherwise.
*/
+ // TODO: (ShearAPI) move to client
public boolean canSendPacket(Packet> packet, ClientCommonPacketListener listener) {
if (!(packet instanceof ServerboundCustomPayloadPacket customPayloadPacket)) {
return true;
@@ -678,11 +680,11 @@ public boolean canSendPacket(Packet> packet, ClientCommonPacketListener listen
* Returns a mutable map of the currently known ad-hoc channels.
*/
private Set getKnownAdHocChannelsOfOtherEnd(Connection connection) {
- var map = connection.channel().attr(ATTRIBUTE_ADHOC_CHANNELS).get();
+ var map = connection.channel.attr(ATTRIBUTE_ADHOC_CHANNELS).get();
if (map == null) {
map = new HashSet<>();
- connection.channel().attr(ATTRIBUTE_ADHOC_CHANNELS).set(map);
+ connection.channel.attr(ATTRIBUTE_ADHOC_CHANNELS).set(map);
}
return map;
@@ -733,6 +735,7 @@ private boolean isAdhocPlayChannelReadable(ResourceLocation id, PacketFlow flow)
*
* @param listener The listener which received the query.
*/
+ // TODO: (ShearAPI) move to client
public void onNetworkQuery(ClientConfigurationPacketListener listener) {
final ModdedNetworkQueryPayload payload = new ModdedNetworkQueryPayload(
knownConfigurationRegistrations.entrySet().stream()
@@ -755,6 +758,7 @@ public void onNetworkQuery(ClientConfigurationPacketListener listener) {
* @param configuration The configuration channels that were negotiated.
* @param play The play channels that were negotiated.
*/
+ // TODO: (ShearAPI) move to client
public void onModdedNetworkConnectionEstablished(ClientConfigurationPacketListener listener, Set configuration, Set play) {
final NetworkPayloadSetup setup = NetworkPayloadSetup.from(
configuration.stream()
@@ -766,9 +770,9 @@ public void onModdedNetworkConnectionEstablished(ClientConfigurationPacketListen
NetworkFilters.injectIfNecessary(listener.getConnection(), listener.getConnectionType());
- listener.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).set(setup);
- listener.getConnection().channel().attr(ATTRIBUTE_CONNECTION_TYPE).set(listener.getConnectionType());
- listener.getConnection().channel().attr(ATTRIBUTE_FLOW).set(PacketFlow.CLIENTBOUND);
+ listener.getConnection().channel.attr(ATTRIBUTE_PAYLOAD_SETUP).set(setup);
+ listener.getConnection().channel.attr(ATTRIBUTE_CONNECTION_TYPE).set(listener.getConnectionType());
+ listener.getConnection().channel.attr(ATTRIBUTE_FLOW).set(PacketFlow.CLIENTBOUND);
final ImmutableSet.Builder nowListeningOn = ImmutableSet.builder();
nowListeningOn.addAll(getInitialClientListeningChannels());
@@ -788,6 +792,7 @@ public void onModdedNetworkConnectionEstablished(ClientConfigurationPacketListen
* @param sender The listener which received the brand payload.
* @return True if the vanilla connection should be handled by the client, false otherwise.
*/
+ // TODO: (ShearAPI) move to client
public boolean onVanillaNetworkConnectionEstablished(ClientConfigurationPacketListener sender) {
NetworkFilters.cleanIfNecessary(sender.getConnection());
@@ -798,9 +803,9 @@ public boolean onVanillaNetworkConnectionEstablished(ClientConfigurationPacketLi
.toList());
//Because we are in vanilla land, no matter what we are not able to support any custom channels.
- sender.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).set(NetworkPayloadSetup.empty());
- sender.getConnection().channel().attr(ATTRIBUTE_CONNECTION_TYPE).set(sender.getConnectionType());
- sender.getConnection().channel().attr(ATTRIBUTE_FLOW).set(PacketFlow.CLIENTBOUND);
+ sender.getConnection().channel.attr(ATTRIBUTE_PAYLOAD_SETUP).set(NetworkPayloadSetup.empty());
+ sender.getConnection().channel.attr(ATTRIBUTE_CONNECTION_TYPE).set(sender.getConnectionType());
+ sender.getConnection().channel.attr(ATTRIBUTE_FLOW).set(PacketFlow.CLIENTBOUND);
//Negotiation failed. Disconnect the client.
if (!configurationNegotiationResult.success()) {
@@ -854,6 +859,7 @@ public boolean isConnected(ServerCommonPacketListener listener, ResourceLocation
* @param payloadId The payload id to check.
* @return True if the listener has a connection setup that can transmit the given payload id, false otherwise.
*/
+ // TODO: (ShearAPI) move to client
public boolean isConnected(ClientCommonPacketListener listener, ResourceLocation payloadId) {
return isConnected(listener.getConnection(), ConnectionPhase.fromPacketListener(listener), payloadId);
}
@@ -867,7 +873,7 @@ public boolean isConnected(ClientCommonPacketListener listener, ResourceLocation
* @return True if the connection has a connection setup that can transmit the given payload id, false otherwise.
*/
public boolean isConnected(final Connection connection, ConnectionPhase connectionPhase, ResourceLocation payloadId) {
- final NetworkPayloadSetup payloadSetup = connection.channel().attr(ATTRIBUTE_PAYLOAD_SETUP).get();
+ final NetworkPayloadSetup payloadSetup = connection.channel.attr(ATTRIBUTE_PAYLOAD_SETUP).get();
if (payloadSetup == null) {
return getKnownAdHocChannelsOfOtherEnd(connection).contains(payloadId);
}
@@ -933,9 +939,9 @@ public List> filterGameBundlePackets(Channe
* @param connection The connection to configure.
*/
public void configureMockConnection(final Connection connection) {
- connection.channel().attr(ATTRIBUTE_CONNECTION_TYPE).set(ConnectionType.NEOFORGE);
- connection.channel().attr(ATTRIBUTE_FLOW).set(PacketFlow.SERVERBOUND);
- connection.channel().attr(ATTRIBUTE_PAYLOAD_SETUP).set(NetworkPayloadSetup.empty());
+ connection.channel.attr(ATTRIBUTE_CONNECTION_TYPE).set(ConnectionType.NEOFORGE);
+ connection.channel.attr(ATTRIBUTE_FLOW).set(PacketFlow.SERVERBOUND);
+ connection.channel.attr(ATTRIBUTE_PAYLOAD_SETUP).set(NetworkPayloadSetup.empty());
final NetworkPayloadSetup setup = NetworkPayloadSetup.from(
this.knownConfigurationRegistrations.entrySet().stream()
@@ -945,7 +951,7 @@ public void configureMockConnection(final Connection connection) {
.map(entry -> new NetworkChannel(entry.getKey(), entry.getValue().version()))
.collect(Collectors.toSet()));
- connection.channel().attr(ATTRIBUTE_PAYLOAD_SETUP).set(setup);
+ connection.channel.attr(ATTRIBUTE_PAYLOAD_SETUP).set(setup);
NetworkFilters.injectIfNecessary(connection, ConnectionType.NEOFORGE);
}
@@ -956,6 +962,7 @@ public void configureMockConnection(final Connection connection) {
* @param listener The listener which received the payload.
* @param resourceLocations The resource locations that were registered.
*/
+ // TODO: (ShearAPI) move to client
public void onMinecraftRegister(ClientCommonPacketListener listener, Set resourceLocations) {
onMinecraftRegister(resourceLocations, listener.getConnection());
}
@@ -986,6 +993,7 @@ private void onMinecraftRegister(Set resourceLocations, Connec
* @param listener The listener which received the payload.
* @param resourceLocations The resource locations that were unregistered.
*/
+ // TODO: (ShearAPI) move to client
public void onMinecraftUnregister(ClientCommonPacketListener listener, Set resourceLocations) {
onMinecraftUnregister(resourceLocations, listener.getConnection());
}
@@ -1031,6 +1039,7 @@ public Set getInitialServerUnregisterChannels() {
return nowForgottenChannels.build();
}
+ // TODO: (ShearAPI) move to client
private static Set getInitialClientListeningChannels() {
return Set.of(
MinecraftRegisterPayload.ID,
@@ -1041,7 +1050,7 @@ private static Set getInitialClientListeningChannels() {
}
public void onConfigurationFinished(ServerConfigurationPacketListener serverConfigurationPacketListener) {
- final NetworkPayloadSetup setup = serverConfigurationPacketListener.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).get();
+ final NetworkPayloadSetup setup = serverConfigurationPacketListener.getConnection().channel.attr(ATTRIBUTE_PAYLOAD_SETUP).get();
if (setup == null) {
LOGGER.error("Somebody tried to finish the configuration phase of a connection that has not negotiated with the client. Not finishing configuration.");
return;
@@ -1066,8 +1075,9 @@ public void onConfigurationFinished(ServerConfigurationPacketListener serverConf
serverConfigurationPacketListener.send(new MinecraftRegisterPayload(nowListeningOn.build()));
}
+ // TODO: (ShearAPI) move to client
public void onConfigurationFinished(ClientConfigurationPacketListener listener) {
- final NetworkPayloadSetup setup = listener.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).get();
+ final NetworkPayloadSetup setup = listener.getConnection().channel.attr(ATTRIBUTE_PAYLOAD_SETUP).get();
if (setup == null) {
LOGGER.error("Somebody tried to finish the configuration phase of a connection that has not negotiated with the server. Not finishing configuration.");
return;
@@ -1157,6 +1167,7 @@ private static void resolvePacketGenerics(Packet p
}
}
+ // TODO: (ShearAPI) move to client
@SuppressWarnings("unchecked")
private record ClientPacketHandler(ClientCommonPacketListener listener) implements IPacketHandler {
@Override
@@ -1195,6 +1206,7 @@ public void disconnect(Component reason) {
}
}
+ // TODO: (ShearAPI) move to client
private record ClientReplyHandler(ClientCommonPacketListener listener) implements IReplyHandler {
@Override
public void send(CustomPacketPayload payload) {
diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IConnectionExtension.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IConnectionExtension.java
new file mode 100644
index 0000000..a5d889b
--- /dev/null
+++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IConnectionExtension.java
@@ -0,0 +1,7 @@
+package net.pillowmc.shearapi.network.injection;
+
+import io.netty.channel.Channel;
+
+public interface IConnectionExtension {
+ Channel channel();
+}
diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IConnectionProtocolExtension.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IConnectionProtocolExtension.java
new file mode 100644
index 0000000..d497be3
--- /dev/null
+++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IConnectionProtocolExtension.java
@@ -0,0 +1,6 @@
+package net.pillowmc.shearapi.network.injection;
+
+public interface IConnectionProtocolExtension {
+ boolean isPlay();
+ boolean isConfiguration();
+}
diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerCommonPacketListenerExtension.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerCommonPacketListenerExtension.java
index 900faf2..0c3f772 100644
--- a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerCommonPacketListenerExtension.java
+++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerCommonPacketListenerExtension.java
@@ -25,19 +25,15 @@
*
*/
public interface IServerCommonPacketListenerExtension {
- /**
- * {@return the {@link ServerCommonPacketListener} that the extensions is attached to}
- */
- private ServerCommonPacketListener self() {
- return (ServerCommonPacketListener) this;
- }
/**
* Sends a packet to the client which this listener is attached to.
*
* @param packet The packet to send
*/
- void send(Packet> packet);
+ default void send(Packet> packet) {
+ throw new AssertionError("This should be implemented by mixin!");
+ }
/**
* Sends a custom payload to the client which this listener is attached to.
@@ -54,7 +50,9 @@ default void send(CustomPacketPayload packetPayload) {
* @param packet The packet to send
* @param packetSendListener The listener to call when the packet is sent
*/
- void send(Packet> packet, @Nullable PacketSendListener packetSendListener);
+ default void send(Packet> packet, @Nullable PacketSendListener packetSendListener) {
+ throw new AssertionError("This should be implemented by mixin!");
+ }
/**
* Sends a custom payload to the client which this listener is attached to.
@@ -71,21 +69,27 @@ default void send(CustomPacketPayload packetPayload, @Nullable PacketSendListene
*
* @param reason The reason for the disconnection
*/
- void disconnect(Component reason);
+ default void disconnect(Component reason) {
+ throw new AssertionError("This should be implemented by mixin!");
+ }
/**
* {@return the connection this listener is attached to}
*/
- Connection getConnection();
+ default Connection getConnection() {
+ throw new AssertionError("This should be implemented by mixin!");
+ }
/**
* {@return the main thread event loop}
*/
- ReentrantBlockableEventLoop> getMainThreadEventLoop();
+ default ReentrantBlockableEventLoop> getMainThreadEventLoop() {
+ throw new AssertionError("This should be implemented by mixin!");
+ }
/**
* {@return true if the connection is to a vanilla client}
- *
+ *
* @deprecated Use {@link #getConnectionType()} instead
*/
@Deprecated(forRemoval = true)
@@ -99,12 +103,12 @@ default boolean isVanillaConnection() {
* @param payloadId The payload id to check
*/
default boolean isConnected(final ResourceLocation payloadId) {
- return NetworkRegistry.getInstance().isConnected(self(), payloadId);
+ return NetworkRegistry.getInstance().isConnected((ServerCommonPacketListener) this, payloadId);
}
/**
* {@return true if the custom payload is usable by this connection}
- *
+ *
* @param payload The payload to check
*/
default boolean isConnected(final CustomPacketPayload payload) {
@@ -114,5 +118,7 @@ default boolean isConnected(final CustomPacketPayload payload) {
/**
* {@return the connection type of the connection}
*/
- ConnectionType getConnectionType();
+ default ConnectionType getConnectionType() {
+ throw new AssertionError("This should be implemented by mixin!");
+ }
}
diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerConfigurationPacketListenerExtension.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerConfigurationPacketListenerExtension.java
index c9ad80b..6340c4f 100644
--- a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerConfigurationPacketListenerExtension.java
+++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerConfigurationPacketListenerExtension.java
@@ -5,9 +5,11 @@
package net.pillowmc.shearapi.network.injection;
+import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket;
import net.minecraft.network.protocol.configuration.ServerConfigurationPacketListener;
import net.minecraft.server.network.ConfigurationTask;
import net.minecraft.server.network.ServerConfigurationPacketListenerImpl;
+import net.neoforged.neoforge.network.connection.ConnectionType;
/**
* Extension class for {@link ServerConfigurationPacketListener}
@@ -20,4 +22,8 @@ public interface IServerConfigurationPacketListenerExtension extends IServerComm
* @implNote This forces the normally private method implementation in {@link ServerConfigurationPacketListenerImpl#finishCurrentTask(ConfigurationTask.Type)} to become public, and adds this to the signature of {@link ServerConfigurationPacketListener}
*/
void finishCurrentTask(ConfigurationTask.Type task);
+
+ void shearapi$setConnectionType(ConnectionType type);
+ boolean shearapi$isHandlingModdedConfigurationPhase();
+ void shearapi$setHandlingModdedConfigurationPhase();
}
diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerGamePacketListenerExtension.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerGamePacketListenerExtension.java
index 5582cd1..82478a7 100644
--- a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerGamePacketListenerExtension.java
+++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerGamePacketListenerExtension.java
@@ -45,6 +45,6 @@ default void sendBundled(Iterable payloads) {
packets.add(new ClientboundCustomPayloadPacket(payload));
}
- self().send(new ClientboundBundlePacket(packets));
+ self().send(new ClientboundBundlePacket((List>)(Object) packets));
}
}
diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ConnectionMixin.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ConnectionMixin.java
new file mode 100644
index 0000000..92a64da
--- /dev/null
+++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ConnectionMixin.java
@@ -0,0 +1,18 @@
+package net.pillowmc.shearapi.network.mixin;
+
+import io.netty.channel.Channel;
+import net.minecraft.network.Connection;
+import net.pillowmc.shearapi.network.injection.IConnectionExtension;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+
+@Mixin(Connection.class)
+public class ConnectionMixin implements IConnectionExtension {
+ @Shadow
+ public Channel channel;
+
+ @Override
+ public Channel channel() {
+ return this.channel;
+ }
+}
diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ConnectionProtocolMixin.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ConnectionProtocolMixin.java
new file mode 100644
index 0000000..94bbea5
--- /dev/null
+++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ConnectionProtocolMixin.java
@@ -0,0 +1,21 @@
+package net.pillowmc.shearapi.network.mixin;
+
+import net.minecraft.network.ConnectionProtocol;
+import net.pillowmc.shearapi.network.injection.IConnectionProtocolExtension;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+
+@Mixin(ConnectionProtocol.class)
+public class ConnectionProtocolMixin implements IConnectionProtocolExtension {
+
+ @Override
+ public boolean isPlay() {
+ return (Object) this == ConnectionProtocol.PLAY;
+ }
+
+ @Override
+ public boolean isConfiguration() {
+ return (Object) this == ConnectionProtocol.CONFIGURATION;
+ }
+}
diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/FriendlyByteBufMixin.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/FriendlyByteBufMixin.java
new file mode 100644
index 0000000..8b16328
--- /dev/null
+++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/FriendlyByteBufMixin.java
@@ -0,0 +1,9 @@
+package net.pillowmc.shearapi.network.mixin;
+
+import net.minecraft.network.FriendlyByteBuf;
+import net.pillowmc.shearapi.network.injection.IFriendlyByteBufExtension;
+import org.spongepowered.asm.mixin.Mixin;
+
+@Mixin(FriendlyByteBuf.class)
+public class FriendlyByteBufMixin implements IFriendlyByteBufExtension {
+}
diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerCommonPacketListenerImplMixin.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerCommonPacketListenerImplMixin.java
index ed098f0..edff5b1 100644
--- a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerCommonPacketListenerImplMixin.java
+++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerCommonPacketListenerImplMixin.java
@@ -1,10 +1,105 @@
package net.pillowmc.shearapi.network.mixin;
+import net.minecraft.network.Connection;
+import net.minecraft.network.PacketSendListener;
+import net.minecraft.network.chat.Component;
+import net.minecraft.network.protocol.Packet;
+import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket;
+import net.minecraft.network.protocol.common.ServerCommonPacketListener;
+import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket;
+import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerCommonPacketListenerImpl;
+import net.minecraft.server.network.ServerConfigurationPacketListenerImpl;
+import net.minecraft.util.thread.ReentrantBlockableEventLoop;
+import net.neoforged.neoforge.network.connection.ConnectionType;
+import net.neoforged.neoforge.network.payload.MinecraftRegisterPayload;
+import net.neoforged.neoforge.network.payload.MinecraftUnregisterPayload;
+import net.neoforged.neoforge.network.payload.ModdedNetworkQueryPayload;
+import net.neoforged.neoforge.network.registration.NetworkRegistry;
import net.pillowmc.shearapi.network.injection.IServerCommonPacketListenerExtension;
+import org.jetbrains.annotations.Nullable;
+import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ServerCommonPacketListenerImpl.class)
public abstract class ServerCommonPacketListenerImplMixin implements IServerCommonPacketListenerExtension {
+ @Override
+ public Connection getConnection() {
+ return connection;
+ }
+
+ @Shadow
+ @Final
+ protected Connection connection;
+
+ @Shadow
+ @Final
+ protected MinecraftServer server;
+
+ @Shadow
+ @Override
+ public abstract void send(Packet> packet);
+
+ @Shadow
+ @Override
+ public abstract void send(Packet> packet, @Nullable PacketSendListener packetSendListener);
+
+ @Override
+ public ReentrantBlockableEventLoop> getMainThreadEventLoop() {
+ return server;
+ }
+
+ @Inject(method = "send(Lnet/minecraft/network/protocol/Packet;Lnet/minecraft/network/PacketSendListener;)V", at = @At("HEAD"), cancellable = true)
+ private void injectSend(Packet> packet, PacketSendListener packetSendListener, CallbackInfo ci) {
+ if (!NetworkRegistry.getInstance().canSendPacket(packet, (ServerCommonPacketListener) this)) {
+ ci.cancel();
+ }
+ }
+
+ // This should be in ServerConfigurationPacketListenerImplMixin...
+ @Inject(method = "handleCustomPayload", at = @At("HEAD"), cancellable = true)
+ private void handleCustomPayloadHead(ServerboundCustomPayloadPacket packet, CallbackInfo ci) {
+ if (!((Object)this instanceof ServerConfigurationPacketListenerImpl self)) return;
+ if (packet.payload() instanceof MinecraftRegisterPayload payload) {
+ self.shearapi$setConnectionType(self.getConnectionType().withMinecraftRegisterPayload());
+ NetworkRegistry.getInstance().onMinecraftRegister(self, payload.newChannels());
+ return;
+ }
+
+ if (packet.payload() instanceof MinecraftUnregisterPayload payload) {
+ self.shearapi$setConnectionType(self.getConnectionType().withMinecraftRegisterPayload());
+ NetworkRegistry.getInstance().onMinecraftUnregister(self, payload.forgottenChannels());
+ return;
+ }
+
+ if (packet.payload() instanceof ModdedNetworkQueryPayload payload) {
+ self.shearapi$setConnectionType(self.getConnectionType().withNeoForgeQueryPayload());
+ NetworkRegistry.getInstance().onModdedConnectionDetectedAtServer(
+ self,
+ payload.configuration(),
+ payload.play()
+ );
+ return;
+ }
+
+ if (self.shearapi$isHandlingModdedConfigurationPhase()) {
+ NetworkRegistry.getInstance().onModdedPacketAtServer(self, packet);
+ ci.cancel();
+ }
+
+ }
+
+ @Inject(method = "handleCustomPayload", at = @At("TAIL"))
+ private void handleCustomPayloadTail(ServerboundCustomPayloadPacket packet, CallbackInfo ci) {
+ if ((Object)this instanceof ServerConfigurationPacketListenerImpl self) {
+ NetworkRegistry.getInstance().onModdedPacketAtServer(self, packet);
+ }
+ }
}
diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerConfigurationPacketListenerImplMixin.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerConfigurationPacketListenerImplMixin.java
new file mode 100644
index 0000000..82a2a3f
--- /dev/null
+++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerConfigurationPacketListenerImplMixin.java
@@ -0,0 +1,67 @@
+package net.pillowmc.shearapi.network.mixin;
+
+import net.minecraft.network.Connection;
+import net.minecraft.network.protocol.Packet;
+import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket;
+import net.minecraft.network.protocol.configuration.ServerConfigurationPacketListener;
+import net.minecraft.network.protocol.configuration.ServerboundFinishConfigurationPacket;
+import net.minecraft.server.network.ConfigurationTask;
+import net.minecraft.server.network.ServerConfigurationPacketListenerImpl;
+import net.minecraft.util.thread.ReentrantBlockableEventLoop;
+import net.neoforged.neoforge.network.connection.ConnectionType;
+import net.neoforged.neoforge.network.payload.MinecraftRegisterPayload;
+import net.neoforged.neoforge.network.payload.MinecraftUnregisterPayload;
+import net.neoforged.neoforge.network.payload.ModdedNetworkQueryPayload;
+import net.neoforged.neoforge.network.registration.NetworkRegistry;
+import net.pillowmc.shearapi.network.injection.IServerConfigurationPacketListenerExtension;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Overwrite;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.gen.Invoker;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+import java.util.Set;
+
+@Mixin(ServerConfigurationPacketListenerImpl.class)
+public abstract class ServerConfigurationPacketListenerImplMixin implements IServerConfigurationPacketListenerExtension {
+ private ConnectionType connectionType = ConnectionType.VANILLA;
+ private boolean isHandlingModdedConfigurationPhase = false;
+
+ @Override
+ @Shadow
+ public abstract void finishCurrentTask(ConfigurationTask.Type task);
+
+ @Override
+ public ConnectionType getConnectionType() {
+ return connectionType;
+ }
+
+ @Override
+ public void shearapi$setConnectionType(ConnectionType connectionType) {
+ this.connectionType = connectionType;
+ }
+
+ @Override
+ public boolean shearapi$isHandlingModdedConfigurationPhase() {
+ return isHandlingModdedConfigurationPhase;
+ }
+
+ @Override
+ public void shearapi$setHandlingModdedConfigurationPhase() {
+ isHandlingModdedConfigurationPhase = true;
+ }
+
+ @Inject(method = "handleConfigurationFinished", at = @At("HEAD"))
+ private void handleConfigurationFinished(ServerboundFinishConfigurationPacket serverboundFinishConfigurationPacket, CallbackInfo ci) {
+ if (this.connectionType == ConnectionType.OTHER) {
+ NetworkRegistry.getInstance().onModdedConnectionDetectedAtServer(
+ (ServerConfigurationPacketListener) this,
+ Set.of(),
+ Set.of()
+ );
+ }
+ NetworkRegistry.getInstance().onConfigurationFinished((ServerConfigurationPacketListener) this);
+ }
+}
diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerConfigurationPacketListenerMixin.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerConfigurationPacketListenerMixin.java
new file mode 100644
index 0000000..9e3b4f7
--- /dev/null
+++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerConfigurationPacketListenerMixin.java
@@ -0,0 +1,10 @@
+package net.pillowmc.shearapi.network.mixin;
+
+import net.minecraft.network.protocol.configuration.ServerConfigurationPacketListener;
+import net.pillowmc.shearapi.network.injection.IServerConfigurationPacketListenerExtension;
+import org.spongepowered.asm.mixin.Mixin;
+
+@Mixin(ServerConfigurationPacketListener.class)
+public interface ServerConfigurationPacketListenerMixin extends IServerConfigurationPacketListenerExtension {
+
+}
diff --git a/shearapi-network/src/main/resources/fabric.mod.json b/shearapi-network/src/main/resources/fabric.mod.json
index d4e7913..af7b157 100644
--- a/shearapi-network/src/main/resources/fabric.mod.json
+++ b/shearapi-network/src/main/resources/fabric.mod.json
@@ -22,9 +22,12 @@
"shearapi-utils": "~${version}",
"shearapi-runtime": "~${version}"
},
+ "accessWidener": "shearapi-network.accesswidener",
"entrypoints": {
"client": ["net.pillowmc.shearapi.network.client.ShearAPINetworkClient"],
- "shearapi-runtime:mod_bus_subscriber": ["net.neoforged.neoforge.network.ConfigurationInitialization::clazz"]
+ "shearapi-runtime:mod_bus_subscriber": [
+ "net.neoforged.neoforge.network.filters.GenericPacketSplitter::clazz"
+ ]
},
"mixins": ["shearapi-network.mixins.json"],
"custom": {
@@ -32,7 +35,8 @@
"net/minecraft/class_8706": ["net/pillowmc/shearapi/network/injection/IServerCommonPacketListenerExtension"],
"net/minecraft/class_8735": ["net/pillowmc/shearapi/network/injection/IServerConfigurationPacketListenerExtension"],
"net/minecraft/class_2792": ["net/pillowmc/shearapi/network/injection/IServerGamePacketListenerExtension"],
- "net/minecraft/class_2540": ["net/pillowmc/shearapi/network/injection/IFriendlyByteBufExtension"]
+ "net/minecraft/class_2540": ["net/pillowmc/shearapi/network/injection/IFriendlyByteBufExtension"],
+ "net/minecraft/class_2539": ["net/pillowmc/shearapi/network/injection/IConnectionProtocolExtension"]
},
"modmenu": {
"parent": "shearapi",
diff --git a/shearapi-network/src/main/resources/shearapi-network.accesswidener b/shearapi-network/src/main/resources/shearapi-network.accesswidener
new file mode 100644
index 0000000..e0b04e2
--- /dev/null
+++ b/shearapi-network/src/main/resources/shearapi-network.accesswidener
@@ -0,0 +1,5 @@
+accessWidener v1 named
+accessible field net/minecraft/network/Connection channel Lio/netty/channel/Channel;
+accessible method net/minecraft/server/network/ServerConfigurationPacketListenerImpl finishCurrentTask (Lnet/minecraft/server/network/ConfigurationTask$Type;)V
+accessible field net/minecraft/network/protocol/common/ServerboundCustomPayloadPacket KNOWN_TYPES Ljava/util/Map;
+accessible field net/minecraft/network/protocol/common/ClientboundCustomPayloadPacket KNOWN_TYPES Ljava/util/Map;
diff --git a/shearapi-network/src/main/resources/shearapi-network.mixins.json b/shearapi-network/src/main/resources/shearapi-network.mixins.json
index dcd8685..d96013a 100644
--- a/shearapi-network/src/main/resources/shearapi-network.mixins.json
+++ b/shearapi-network/src/main/resources/shearapi-network.mixins.json
@@ -3,7 +3,12 @@
"package": "net.pillowmc.shearapi.network.mixin",
"compatibilityLevel": "JAVA_17",
"mixins": [
- "ServerCommonPacketListenerMixin"
+ "ConnectionMixin",
+ "ConnectionProtocolMixin",
+ "FriendlyByteBufMixin",
+ "ServerCommonPacketListenerImplMixin",
+ "ServerCommonPacketListenerMixin",
+ "ServerConfigurationPacketListenerMixin"
],
"injectors": {
"defaultRequire": 1
diff --git a/shearapi-registries/src/main/java/net/neoforged/neoforge/registries/RegistryManager.java b/shearapi-registries/src/main/java/net/neoforged/neoforge/registries/RegistryManager.java
index 832070b..32b1eec 100644
--- a/shearapi-registries/src/main/java/net/neoforged/neoforge/registries/RegistryManager.java
+++ b/shearapi-registries/src/main/java/net/neoforged/neoforge/registries/RegistryManager.java
@@ -232,9 +232,9 @@ public static void postNewRegistryEvent() {
// return list;
// }
//
-// public static Set getVanillaRegistryKeys() {
-// return vanillaRegistryKeys;
-// }
+ public static Set getVanillaRegistryKeys() {
+ return vanillaRegistryKeys;
+ }
public enum SnapshotType {
/**
diff --git a/shearapi-registries/src/main/java/net/pillowmc/shearapi/registries/ShearAPIRegistries.java b/shearapi-registries/src/main/java/net/pillowmc/shearapi/registries/ShearAPIRegistries.java
index 659d1d2..775633b 100644
--- a/shearapi-registries/src/main/java/net/pillowmc/shearapi/registries/ShearAPIRegistries.java
+++ b/shearapi-registries/src/main/java/net/pillowmc/shearapi/registries/ShearAPIRegistries.java
@@ -2,7 +2,12 @@
import com.chocohead.mm.api.ClassTinkerers;
import net.fabricmc.api.ModInitializer;
+import net.minecraft.core.Registry;
+import net.minecraft.core.RegistrySetBuilder;
import net.minecraft.core.registries.BuiltInRegistries;
+import net.minecraft.data.registries.VanillaRegistries;
+import net.minecraft.resources.ResourceKey;
+import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import net.minecraft.world.level.levelgen.DebugLevelSource;
import net.neoforged.neoforge.registries.GameData;
@@ -11,11 +16,13 @@
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodInsnNode;
+import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
public class ShearAPIRegistries implements ModInitializer {
+ private static final List extends ResourceKey extends Registry>>> VANILLA_REGISTRIES_DATAPACK_REGISTRY_KEYS = VanillaRegistries.BUILDER.entries.stream().map(RegistrySetBuilder.RegistryStub::key).toList()
@Override
public void onInitialize() {
RegistryManager.postNewRegistryEvent();
@@ -27,4 +34,10 @@ public static void initValidStatesInDebugLevelSource() {
DebugLevelSource.GRID_WIDTH = Mth.ceil(Mth.sqrt(DebugLevelSource.ALL_BLOCKS.size()));
DebugLevelSource.GRID_HEIGHT = Mth.ceil((float)DebugLevelSource.ALL_BLOCKS.size() / (float)DebugLevelSource.GRID_WIDTH);
}
+
+ public static boolean isVanillaRegistry(ResourceLocation location) {
+ // Checks if the registry name is contained within the static view of both BuiltInRegistries and VanillaRegistries
+ return RegistryManager.getVanillaRegistryKeys().contains(location)
+ || VANILLA_REGISTRIES_DATAPACK_REGISTRY_KEYS.stream().anyMatch(k -> k.location().equals(location));
+ }
}
diff --git a/shearapi-registries/src/main/resources/shearapi-registries.accesswidener b/shearapi-registries/src/main/resources/shearapi-registries.accesswidener
index eb018c2..9f2f379 100644
--- a/shearapi-registries/src/main/resources/shearapi-registries.accesswidener
+++ b/shearapi-registries/src/main/resources/shearapi-registries.accesswidener
@@ -13,3 +13,6 @@ mutable field net/minecraft/world/level/levelgen/DebugLevelSource GRID_HEIGHT I
#accessible class net/minecraft/core/RegistrySynchronization$NetworkedRegistryData
accessible method net/minecraft/core/RegistrySynchronization$NetworkedRegistryData (Lnet/minecraft/resources/ResourceKey;Lcom/mojang/serialization/Codec;)V
accessible method net/minecraft/core/Holder$Reference bindValue (Ljava/lang/Object;)V
+accessible field net/minecraft/core/RegistrySetBuilder entries Ljava/util/List;
+accessible class net/minecraft/core/RegistrySetBuilder$RegistryStub
+accessible field net/minecraft/data/registries/VanillaRegistries BUILDER Lnet/minecraft/core/RegistrySetBuilder;
diff --git a/shearapi-runtime/src/main/java/net/pillowmc/shearapi/runtime/IRuntime.java b/shearapi-runtime/src/main/java/net/pillowmc/shearapi/runtime/IRuntime.java
index 215cbe9..aa030de 100644
--- a/shearapi-runtime/src/main/java/net/pillowmc/shearapi/runtime/IRuntime.java
+++ b/shearapi-runtime/src/main/java/net/pillowmc/shearapi/runtime/IRuntime.java
@@ -3,6 +3,8 @@
import net.neoforged.bus.api.Event;
import net.neoforged.bus.api.IEventBus;
+import java.util.Optional;
+
public interface IRuntime {
boolean isLoadingStateVaild();
boolean isProduction();
@@ -10,4 +12,5 @@ public interface IRuntime {
void postModBusEvent(T event);
IEventBus getModBus();
boolean isModLoaded(String modid);
+ Optional getModDisplayName(String modid);
}
diff --git a/shearapi-utils/src/client/java/net/pillowmc/shearapi/utils/mixin/client/MinecraftMixin.java b/shearapi-utils/src/client/java/net/pillowmc/shearapi/utils/mixin/client/MinecraftMixin.java
index babb386..508f73c 100644
--- a/shearapi-utils/src/client/java/net/pillowmc/shearapi/utils/mixin/client/MinecraftMixin.java
+++ b/shearapi-utils/src/client/java/net/pillowmc/shearapi/utils/mixin/client/MinecraftMixin.java
@@ -2,17 +2,32 @@
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
+import net.minecraft.client.multiplayer.ClientPacketListener;
+import net.minecraft.network.Connection;
+import net.minecraft.network.protocol.Packet;
import net.minecraft.world.level.Level;
import net.pillowmc.shearapi.utils.IClientLike;
+import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
+import java.util.Objects;
+
@Mixin(Minecraft.class)
-public class MinecraftMixin implements IClientLike {
+public abstract class MinecraftMixin implements IClientLike {
@Shadow
public ClientLevel level;
+ @Shadow
+ @Nullable
+ public abstract ClientPacketListener getConnection();
+
+ @Override
+ public void shearAPI$sendPacket(Packet> packet) {
+ Objects.requireNonNull(this.getConnection()).send(packet);
+ }
+
@Override
public Level shearAPI$getClientLevel() {
return level;
diff --git a/shearapi-utils/src/client/java/net/pillowmc/shearapi/utils/mixin/client/UtilsMixin.java b/shearapi-utils/src/client/java/net/pillowmc/shearapi/utils/mixin/client/UtilsMixin.java
new file mode 100644
index 0000000..768276d
--- /dev/null
+++ b/shearapi-utils/src/client/java/net/pillowmc/shearapi/utils/mixin/client/UtilsMixin.java
@@ -0,0 +1,21 @@
+package net.pillowmc.shearapi.utils.mixin.client;
+
+import net.minecraft.client.Minecraft;
+import net.pillowmc.shearapi.utils.IClientLike;
+import net.pillowmc.shearapi.utils.Utils;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Overwrite;
+
+import java.util.Optional;
+
+@Mixin(value = Utils.class, remap = false)
+public class UtilsMixin {
+ /**
+ * @author heipiao233
+ * @reason Get client.
+ */
+ @Overwrite
+ public static Optional getClient() {
+ return Optional.of((IClientLike) Minecraft.getInstance());
+ }
+}
diff --git a/shearapi-utils/src/client/resources/shearapi-utils.client.mixin.json b/shearapi-utils/src/client/resources/shearapi-utils.client.mixin.json
index 448e531..c33c70a 100644
--- a/shearapi-utils/src/client/resources/shearapi-utils.client.mixin.json
+++ b/shearapi-utils/src/client/resources/shearapi-utils.client.mixin.json
@@ -7,5 +7,8 @@
],
"injectors": {
"defaultRequire": 1
- }
+ },
+ "mixins": [
+ "client.UtilsMixin"
+ ]
}
diff --git a/shearapi-utils/src/main/java/net/pillowmc/shearapi/utils/IClientLike.java b/shearapi-utils/src/main/java/net/pillowmc/shearapi/utils/IClientLike.java
index a892ade..a24e4d9 100644
--- a/shearapi-utils/src/main/java/net/pillowmc/shearapi/utils/IClientLike.java
+++ b/shearapi-utils/src/main/java/net/pillowmc/shearapi/utils/IClientLike.java
@@ -1,12 +1,14 @@
package net.pillowmc.shearapi.utils;
+import net.minecraft.network.protocol.Packet;
import net.minecraft.server.TickTask;
import net.minecraft.util.thread.BlockableEventLoop;
import net.minecraft.world.level.Level;
public interface IClientLike {
Level shearAPI$getClientLevel();
+ void shearAPI$sendPacket(Packet> packet);
default BlockableEventLoop super TickTask> intoBlockableEventLoop() {
- return (BlockableEventLoop super TickTask>)(Object) this;
+ return (BlockableEventLoop super TickTask>) this;
}
}
diff --git a/shearapi-utils/src/main/java/net/pillowmc/shearapi/utils/Utils.java b/shearapi-utils/src/main/java/net/pillowmc/shearapi/utils/Utils.java
index 2eaee39..8fd0ec1 100644
--- a/shearapi-utils/src/main/java/net/pillowmc/shearapi/utils/Utils.java
+++ b/shearapi-utils/src/main/java/net/pillowmc/shearapi/utils/Utils.java
@@ -10,4 +10,8 @@ public enum Utils {;
public static Optional> getItemHolder(Item item) {
return BuiltInRegistries.ITEM.getResourceKey(item).flatMap(BuiltInRegistries.ITEM::getHolder);
}
+
+ public static Optional getClient() {
+ return Optional.empty();
+ }
}
diff --git a/shearapi-withoutpillow/src/main/java/net/pillowmc/shearapi/withoutpillow/ShearAPIWithoutPillow.java b/shearapi-withoutpillow/src/main/java/net/pillowmc/shearapi/withoutpillow/ShearAPIWithoutPillow.java
index 013d570..262d68f 100644
--- a/shearapi-withoutpillow/src/main/java/net/pillowmc/shearapi/withoutpillow/ShearAPIWithoutPillow.java
+++ b/shearapi-withoutpillow/src/main/java/net/pillowmc/shearapi/withoutpillow/ShearAPIWithoutPillow.java
@@ -7,6 +7,8 @@
import net.pillowmc.shearapi.runtime.IModBusEvent;
import net.pillowmc.shearapi.runtime.IRuntime;
+import java.util.Optional;
+
public class ShearAPIWithoutPillow implements IRuntime {
private final IEventBus MODBUS = BusBuilder.builder().markerType(IModBusEvent.class).build();
@@ -39,4 +41,9 @@ public void postModBusEvent(T event) {
public boolean isModLoaded(String modid) {
return FabricLoader.getInstance().isModLoaded(modid);
}
+
+ @Override
+ public Optional getModDisplayName(String modid) {
+ return FabricLoader.getInstance().getModContainer(modid).map(m -> m.getMetadata().getName());
+ }
}
diff --git a/shearapi-withpillow/build.gradle b/shearapi-withpillow/build.gradle
index fd95694..d7df97c 100644
--- a/shearapi-withpillow/build.gradle
+++ b/shearapi-withpillow/build.gradle
@@ -9,5 +9,4 @@ dependencies {
implementation "net.neoforged.fancymodloader:loader:${project.fancy_mod_loader_version}"
api project(path: ":shearapi-runtime", configuration: "namedElements")
api project(path: ":shearapi-withoutpillow", configuration: "namedElements")
- api project(path: ":shearapi-network", configuration: "namedElements")
}
diff --git a/shearapi-withpillow/src/client/java/net/pillowmc/shearapi/withpillow/client/ShearAPIWithPillowClient.java b/shearapi-withpillow/src/client/java/net/pillowmc/shearapi/withpillow/client/ShearAPIWithPillowClient.java
deleted file mode 100644
index 1e58c0d..0000000
--- a/shearapi-withpillow/src/client/java/net/pillowmc/shearapi/withpillow/client/ShearAPIWithPillowClient.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package net.pillowmc.shearapi.withpillow.client;
-
-import net.minecraft.client.Minecraft;
-import net.neoforged.bus.api.SubscribeEvent;
-import net.neoforged.fml.config.ConfigTracker;
-import net.neoforged.neoforge.network.event.RegisterPayloadHandlerEvent;
-import net.neoforged.neoforge.network.handling.IPayloadContext;
-import net.neoforged.neoforge.network.payload.ConfigFilePayload;
-import net.neoforged.neoforge.network.registration.IPayloadRegistrar;
-import net.pillowmc.shearapi.runtime.ShearAPIRuntime;
-import net.pillowmc.shearapi.runtime.ShearAPIVersion;
-import net.pillowmc.shearapi.withpillow.ShearAPIWithPillow;
-
-import java.util.Optional;
-
-public class ShearAPIWithPillowClient {
- public static Class clazz = ShearAPIWithPillowClient.class;
- @SubscribeEvent
- public static void onRegisterPayloadHandlerEvent(RegisterPayloadHandlerEvent event) {
- if (!(ShearAPIRuntime.getRuntime() instanceof ShearAPIWithPillow)) {
- return;
- }
- final IPayloadRegistrar registrar = event.registrar(ShearAPIRuntime.MOD_ID)
- .versioned(ShearAPIVersion.getSpec())
- .optional();
- registrar
- .configuration(
- ConfigFilePayload.ID,
- ConfigFilePayload::new,
- handlers -> handlers.client(ShearAPIWithPillowClient::handleConfigFile));
- }
-
- private static void handleConfigFile(ConfigFilePayload payload, IPayloadContext context) {
- if (!Minecraft.getInstance().isLocalServer()) {
- Optional.ofNullable(
- ConfigTracker.INSTANCE.fileMap().get(payload.fileName())
- ).ifPresent(mc -> mc.acceptSyncedConfig(payload.contents()));
- }
- }
-}
diff --git a/shearapi-withpillow/src/main/java/net/pillowmc/shearapi/withpillow/ShearAPIWithPillow.java b/shearapi-withpillow/src/main/java/net/pillowmc/shearapi/withpillow/ShearAPIWithPillow.java
index 78e2f9e..f1caaca 100644
--- a/shearapi-withpillow/src/main/java/net/pillowmc/shearapi/withpillow/ShearAPIWithPillow.java
+++ b/shearapi-withpillow/src/main/java/net/pillowmc/shearapi/withpillow/ShearAPIWithPillow.java
@@ -1,25 +1,16 @@
package net.pillowmc.shearapi.withpillow;
+import net.fabricmc.loader.api.FabricLoader;
import net.neoforged.bus.api.Event;
-import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.ModList;
import net.neoforged.fml.ModLoader;
import net.neoforged.fml.loading.FMLLoader;
-import net.neoforged.neoforge.network.configuration.SyncConfig;
-import net.neoforged.neoforge.network.event.OnGameConfigurationEvent;
-import net.neoforged.neoforge.network.payload.ConfigFilePayload;
import net.pillowmc.shearapi.runtime.IModBusEvent;
import net.pillowmc.shearapi.withoutpillow.ShearAPIWithoutPillow;
-public class ShearAPIWithPillow extends ShearAPIWithoutPillow {
- public static Class clazz = ShearAPIWithPillow.class;
+import java.util.Optional;
- @SubscribeEvent
- public static void onGameConfigurationEvent(OnGameConfigurationEvent event) {
- if (event.getListener().isConnected(ConfigFilePayload.ID)) {
- event.register(new SyncConfig(event.getListener()));
- }
- }
+public class ShearAPIWithPillow extends ShearAPIWithoutPillow {
@Override
public boolean isProduction() {
@@ -51,4 +42,11 @@ public void postModBusEvent(T event) {
public boolean isModLoaded(String modid) {
return ModList.get().isLoaded(modid);
}
+
+
+ @Override
+ public Optional getModDisplayName(String modid) {
+ return super.getModDisplayName(modid)
+ .or(() -> ModList.get().getModContainerById(modid).map(m -> m.getModInfo().getDisplayName()));
+ }
}
diff --git a/shearapi-withpillow/src/main/resources/fabric.mod.json b/shearapi-withpillow/src/main/resources/fabric.mod.json
index ec6c066..8f7e6bc 100644
--- a/shearapi-withpillow/src/main/resources/fabric.mod.json
+++ b/shearapi-withpillow/src/main/resources/fabric.mod.json
@@ -21,10 +21,6 @@
"fabric-api": "*",
"shearapi-runtime": "~${version}"
},
- "entrypoints": {
- "shearapi-runtime:client_mod_bus_subscriber": ["net.pillowmc.shearapi.withpillow.client.ShearAPIWithPillowClient::clazz"],
- "shearapi-runtime:mod_bus_subscriber": ["net.pillowmc.shearapi.withpillow.ShearAPIWithPillow::clazz"]
- },
"mixins": [
"shearapi-withpillow.mixins.json"
],