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>>>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>>>> 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 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>> 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 intoBlockableEventLoop() { - return (BlockableEventLoop)(Object) this; + return (BlockableEventLoop) 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" ],