From ca8be52f9e496ba7943bd74556775f445e930d56 Mon Sep 17 00:00:00 2001 From: noramibu <50046813+noramibu@users.noreply.github.com> Date: Sat, 27 Jun 2026 21:08:48 +0300 Subject: [PATCH 1/2] Remove Fabric API dependency from Spoutcraft client --- spoutcraft-fabric/build.gradle.kts | 3 - spoutcraft-fabric/gradle.properties | 3 - .../loadingoverlay/SpoutLogoIdentifier.java | 13 ++ .../ReplaceColorsAndSizesOverlayMixin.java | 2 +- ...egisteringTexturesLoadingOverlayMixin.java | 2 +- .../ClientModCustomContentReceiving.java | 15 ++ .../clientmod/protocol/ClientModState.java | 11 +- .../clientmod/protocol/SpoutProtocol.java | 203 +++++++++--------- .../ClientCommonPacketListenerImplMixin.java | 31 +++ ...tConfigurationPacketListenerImplMixin.java | 27 +++ ...lientHandshakePacketListenerImplMixin.java | 67 ++++++ .../mixin/ClientPacketListenerMixin.java | 18 ++ .../ClientboundCustomQueryPacketMixin.java | 27 +++ .../mixin/CustomPacketPayloadCodecMixin.java | 26 +++ .../main/SpoutcraftClientModInitializer.java | 13 -- ....clientview.clientmod.protocol.mixins.json | 8 +- .../spout/main/SpoutcraftModInitializer.java | 22 -- .../src/main/resources/fabric.mod.json | 11 +- .../main/resources/spoutcraft.classtweaker | 6 + 19 files changed, 339 insertions(+), 169 deletions(-) create mode 100644 spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientCommonPacketListenerImplMixin.java create mode 100644 spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientConfigurationPacketListenerImplMixin.java create mode 100644 spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientHandshakePacketListenerImplMixin.java create mode 100644 spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientPacketListenerMixin.java create mode 100644 spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientboundCustomQueryPacketMixin.java create mode 100644 spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/CustomPacketPayloadCodecMixin.java delete mode 100644 spoutcraft-fabric/src/client/java/spout/main/SpoutcraftClientModInitializer.java delete mode 100644 spoutcraft-fabric/src/main/java/spout/main/SpoutcraftModInitializer.java diff --git a/spoutcraft-fabric/build.gradle.kts b/spoutcraft-fabric/build.gradle.kts index b365883e..48bece3e 100644 --- a/spoutcraft-fabric/build.gradle.kts +++ b/spoutcraft-fabric/build.gradle.kts @@ -46,9 +46,6 @@ dependencies { implementation("net.fabricmc:fabric-loader:${providers.gradleProperty("loader_version").get()}") - // Fabric API. This is technically optional, but you probably want it anyway. - implementation("net.fabricmc.fabric-api:fabric-api:${providers.gradleProperty("fabric_api_version").get()}") - } tasks.processResources { diff --git a/spoutcraft-fabric/gradle.properties b/spoutcraft-fabric/gradle.properties index a95e01cc..9f68b82a 100644 --- a/spoutcraft-fabric/gradle.properties +++ b/spoutcraft-fabric/gradle.properties @@ -15,6 +15,3 @@ loom_version=1.16-SNAPSHOT mod_version=1.15-SNAPSHOT maven_group=spout.client.fabric archives_base_name=spoutcraft - -# Dependencies -fabric_api_version=0.150.0+26.1.2 diff --git a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/SpoutLogoIdentifier.java b/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/SpoutLogoIdentifier.java index 3ca1365a..581990fb 100644 --- a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/SpoutLogoIdentifier.java +++ b/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/SpoutLogoIdentifier.java @@ -1,5 +1,8 @@ package spout.clientui.resourcepack.loadingoverlay; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; import net.minecraft.resources.Identifier; import spout.branding.SpoutNamespace; @@ -8,10 +11,20 @@ */ public final class SpoutLogoIdentifier { + private static final String RESOURCE_PATH = "assets/spout/icon.png"; + private SpoutLogoIdentifier() { throw new UnsupportedOperationException(); } public static final Identifier IDENTIFIER = Identifier.fromNamespaceAndPath(SpoutNamespace.SPOUT, "icon.png"); + public static InputStream open() throws IOException { + InputStream input = SpoutLogoIdentifier.class.getClassLoader().getResourceAsStream(RESOURCE_PATH); + if (input == null) { + throw new FileNotFoundException(RESOURCE_PATH); + } + return input; + } + } diff --git a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceColorsAndSizesOverlayMixin.java b/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceColorsAndSizesOverlayMixin.java index db7c6527..8a1ff2ab 100644 --- a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceColorsAndSizesOverlayMixin.java +++ b/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceColorsAndSizesOverlayMixin.java @@ -70,7 +70,7 @@ public abstract class ReplaceColorsAndSizesOverlayMixin { @Override public TextureContents loadContents(ResourceManager resourceManager) throws IOException { - try (InputStream input = resourceManager.open(SpoutLogoIdentifier.IDENTIFIER)) { + try (InputStream input = SpoutLogoIdentifier.open()) { TextureContents result = new TextureContents(NativeImage.read(input), new TextureMetadataSection(true, true, MipmapStrategy.MEAN, 0.0f)); return result; diff --git a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceLogoWhenRegisteringTexturesLoadingOverlayMixin.java b/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceLogoWhenRegisteringTexturesLoadingOverlayMixin.java index a2aed265..7dd92a71 100644 --- a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceLogoWhenRegisteringTexturesLoadingOverlayMixin.java +++ b/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceLogoWhenRegisteringTexturesLoadingOverlayMixin.java @@ -25,7 +25,7 @@ public abstract class ReplaceLogoWhenRegisteringTexturesLoadingOverlayMixin { @Override public TextureContents loadContents(ResourceManager resourceManager) throws IOException { - try (InputStream input = resourceManager.open(SpoutLogoIdentifier.IDENTIFIER)) { + try (InputStream input = SpoutLogoIdentifier.open()) { TextureContents result = new TextureContents(NativeImage.read(input), new TextureMetadataSection(true, true, MipmapStrategy.MEAN, 0.0f)); return result; diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/ClientModCustomContentReceiving.java b/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/ClientModCustomContentReceiving.java index d5e03f5d..aa71db16 100644 --- a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/ClientModCustomContentReceiving.java +++ b/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/ClientModCustomContentReceiving.java @@ -72,6 +72,17 @@ public static void handlePacket(ClientModCustomContentPacketPayload payload) { }); }).toList() ); + RemappedBlockStateRegistry blockStateRegistry = + (RemappedBlockStateRegistry) Block.BLOCK_STATE_REGISTRY; + for (var keyedValue : receivedContent.getBlocks()) { + Block block = BuiltInRegistries.BLOCK.get(keyedValue.identifier()).orElseThrow().value(); + for (BlockState state : block.getStateDefinition().getPossibleStates()) { + state.initCache(); + if (blockStateRegistry.getIdUnmapped(state) == -1) { + Block.BLOCK_STATE_REGISTRY.add(state); + } + } + } // Set up registry id mappings where necessary for (RegistryEntryIdList list : receivedContent.getRegistryEntryIdLists()) { Registry registry = BuiltInRegistries.REGISTRY.getValue(list.registryIdentifier()); @@ -111,4 +122,8 @@ public static void handlePacket(ClientModCustomContentPacketPayload payload) { } } + static void clear() { + receivedContent = null; + } + } diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/ClientModState.java b/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/ClientModState.java index fadfde31..ec459916 100644 --- a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/ClientModState.java +++ b/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/ClientModState.java @@ -8,12 +8,7 @@ *
  • {@link #HANDSHAKE_STARTED} -> {@link #CLIENT_MOD_NOT_DETECTED} - When the configuration phase starts without having received a client mod detection packet
  • *
  • {@link #CLIENT_MOD_DETECTED} -> {@link #RECEIVED_CUSTOM_CONTENT} - When the custom content packet has been received
  • *
  • {@link #RECEIVED_CUSTOM_CONTENT} -> {@link #ADDED_CUSTOM_CONTENT} - When the custom content packet has been processed
  • - *
  • {@link #IDLE} -> {@link #REMOVED_CUSTOM_CONTENT} - When the client is disconnecting and the custom content was never added
  • - *
  • {@link #HANDSHAKE_STARTED} -> {@link #REMOVED_CUSTOM_CONTENT} - When the client is disconnecting and the custom content was never added
  • - *
  • {@link #CLIENT_MOD_DETECTED} -> {@link #REMOVED_CUSTOM_CONTENT} - When the client is disconnecting and the custom content was never added
  • - *
  • {@link #CLIENT_MOD_NOT_DETECTED} -> {@link #REMOVED_CUSTOM_CONTENT} - When the client is disconnecting and the client mod was never detected
  • - *
  • {@link #ADDED_CUSTOM_CONTENT} -> {@link #REMOVED_CUSTOM_CONTENT} - When the client is disconnecting and the custom content has been removed
  • - *
  • {@link #REMOVED_CUSTOM_CONTENT} -> {@link #IDLE} - When the client has disconnected
  • + *
  • Any state -> {@link #IDLE} - When the client disconnects or starts a new login
  • * */ public enum ClientModState { @@ -41,8 +36,4 @@ public enum ClientModState { * All custom content has been received and added (e.g. registered). */ ADDED_CUSTOM_CONTENT, - /** - * Received custom content has been removed, or we are disconnecting and it was never successfully added. - */ - REMOVED_CUSTOM_CONTENT, } diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/SpoutProtocol.java b/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/SpoutProtocol.java index 3bc1a47a..394be709 100644 --- a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/SpoutProtocol.java +++ b/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/SpoutProtocol.java @@ -1,14 +1,11 @@ package spout.clientview.clientmod.protocol; import io.netty.buffer.Unpooled; -import net.fabricmc.fabric.api.client.networking.v1.ClientConfigurationConnectionEvents; -import net.fabricmc.fabric.api.client.networking.v1.ClientConfigurationNetworking; -import net.fabricmc.fabric.api.client.networking.v1.ClientLoginConnectionEvents; -import net.fabricmc.fabric.api.client.networking.v1.ClientLoginNetworking; -import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; -import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; +import net.minecraft.client.multiplayer.ClientCommonPacketListenerImpl; import net.minecraft.client.multiplayer.ServerData; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.protocol.login.custom.CustomQueryAnswerPayload; +import net.minecraft.network.protocol.login.custom.CustomQueryPayload; import net.minecraft.resources.Identifier; import spout.clientview.clientmod.protocol.mixin.ClientCommonPacketListenerImplAccessor; import spout.gamecontent.datadriven.common.registry.temporarymodification.TemporaryRegistryModifiers; @@ -16,8 +13,6 @@ import spout.clientview.clientmod.registryidmapping.RegistryIdMappings; import spout.clientui.resourcepack.loadingoverlay.SwitchOverlayStyle; import spout.branding.SpoutNamespace; -import java.util.Set; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicReference; /** @@ -26,7 +21,7 @@ */ public final class SpoutProtocol { - private static final Identifier CLIENT_MOD_DETECTION_PACKET_ID = Identifier.fromNamespaceAndPath(SpoutNamespace.SPOUT, "detect_client_mod"); + public static final Identifier CLIENT_MOD_DETECTION_PACKET_ID = Identifier.fromNamespaceAndPath(SpoutNamespace.SPOUT, "detect_client_mod"); private static final int MIN_PROTOCOL_VERSION = 5; private static final int MAX_PROTOCOL_VERSION = 5; @@ -36,92 +31,84 @@ private SpoutProtocol() { throw new UnsupportedOperationException(); } - public static void initialize() { - ClientLoginNetworking.registerGlobalReceiver(CLIENT_MOD_DETECTION_PACKET_ID, (client, handler, buf, callbacksConsumer) -> { - // First, the server will send a 0, if not, then there must be a protocol difference that we are unaware of - int zero = buf.readVarInt(); - if (zero == 0) { - // Read the nonce - int nonce = buf.readVarInt(); - // Read the protocol versions supported by the server (and perform basic validation on what we read) - int minServerProtocolVersion = buf.readVarInt(); - if (minServerProtocolVersion >= 1) { - int maxServerProtocolVersion = buf.readVarInt(); - if (maxServerProtocolVersion >= minServerProtocolVersion) { - // The best protocol version is the highest supported by both client and server - int bestProtocolVersion = Math.min(maxServerProtocolVersion, MAX_PROTOCOL_VERSION); - boolean isBestProtocolVersionAcceptable = bestProtocolVersion >= minServerProtocolVersion && bestProtocolVersion >= MIN_PROTOCOL_VERSION; - int responseProtocolVersion = -1; // In case of failure, respond with an invalid version - if (isBestProtocolVersionAcceptable) { - changeState(ClientModState.HANDSHAKE_STARTED, ClientModState.CLIENT_MOD_DETECTED); - SwitchOverlayStyle.setSpout(); - responseProtocolVersion = bestProtocolVersion; - } - // Respond - FriendlyByteBuf response = new FriendlyByteBuf(Unpooled.buffer(15)); - response.writeVarInt(0); - response.writeVarInt(nonce); - response.writeVarInt(responseProtocolVersion); - return CompletableFuture.completedFuture(response); - } - } - } - // We did not understand this protocol - return CompletableFuture.completedFuture(null); - }); - PayloadTypeRegistry.clientboundConfiguration().register(ClientModCustomContentPacketPayload.TYPE, ClientModCustomContentPacketPayload.STREAM_CODEC); - ClientConfigurationNetworking.registerGlobalReceiver(ClientModCustomContentPacketPayload.TYPE, (payload, context) -> { - ClientModCustomContentReceiving.handlePacket(payload); - }); - ClientLoginConnectionEvents.INIT.register((handler, client) -> { - SpoutProtocol.changeState(ClientModState.IDLE, ClientModState.HANDSHAKE_STARTED); - }); - ClientConfigurationConnectionEvents.INIT.register((handler, client) -> { - // Make sure the state is valid - while (true) { - if (SpoutProtocol.getState() == ClientModState.CLIENT_MOD_DETECTED) { - // Force accepting of packs - ClientCommonPacketListenerImplAccessor accessor = (ClientCommonPacketListenerImplAccessor) handler; - ServerData serverData = accessor.getServerData(); - serverData.setResourcePackStatus(ServerData.ServerPackStatus.ENABLED); - - break; - } - if (SpoutProtocol.tryChangeState(ClientModState.HANDSHAKE_STARTED, ClientModState.CLIENT_MOD_NOT_DETECTED)) { - break; - } - Thread.onSpinWait(); - } - }); - ClientLoginConnectionEvents.DISCONNECT.register((handler, client) -> { - onDisconnect(); - }); - ClientConfigurationConnectionEvents.DISCONNECT.register((handler, client) -> { - onDisconnect(); - }); - ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> { - onDisconnect(); - }); + public static void onLoginStart() { + SpoutProtocol.onDisconnect(); + state.set(ClientModState.HANDSHAKE_STARTED); } - private static void onDisconnect() { + public static ClientModDetectionQueryPayload readClientModDetectionQuery(FriendlyByteBuf input) { + ClientModDetectionQueryPayload payload = new ClientModDetectionQueryPayload( + input.readVarInt(), + input.readVarInt(), + input.readVarInt(), + input.readVarInt() + ); + input.skipBytes(input.readableBytes()); + return payload; + } + + public static CustomQueryAnswerPayload createClientModDetectionAnswer(CustomQueryPayload payload) { + ClientModDetectionQueryPayload detectionPayload = getClientModDetectionQuery(payload); + // First, the server will send a 0. If not, then there must be a protocol difference that we are unaware of. + if (detectionPayload.protocolMarker != 0 + || detectionPayload.minProtocolVersion < 1 + || detectionPayload.maxProtocolVersion < detectionPayload.minProtocolVersion) { + return null; + } + // The best protocol version is the highest supported by both client and server. + int bestProtocolVersion = Math.min( + detectionPayload.maxProtocolVersion, + MAX_PROTOCOL_VERSION + ); + int responseProtocolVersion = -1; // In case of failure, respond with an invalid version. + if (bestProtocolVersion >= detectionPayload.minProtocolVersion + && bestProtocolVersion >= MIN_PROTOCOL_VERSION) { + changeState(ClientModState.HANDSHAKE_STARTED, ClientModState.CLIENT_MOD_DETECTED); + SwitchOverlayStyle.setSpout(); + responseProtocolVersion = bestProtocolVersion; + } + int selectedProtocolVersion = responseProtocolVersion; + return output -> { + output.writeVarInt(0); + output.writeVarInt(detectionPayload.nonce); + output.writeVarInt(selectedProtocolVersion); + }; + } + + private static ClientModDetectionQueryPayload getClientModDetectionQuery(CustomQueryPayload payload) { + if (payload instanceof ClientModDetectionQueryPayload detectionPayload) { + return detectionPayload; + } + // Fixes Spout login when Fabric API is present; fabric-networking-api-v1 wraps login payloads in a generic buffer payload. + FriendlyByteBuf buffer = new FriendlyByteBuf(Unpooled.buffer()); + try { + payload.write(buffer); + return readClientModDetectionQuery(buffer); + } finally { + buffer.release(); + } + } + + public static void onConfigurationStart(ClientCommonPacketListenerImpl handler) { + if (SpoutProtocol.getState() == ClientModState.CLIENT_MOD_DETECTED) { + // Force accepting of packs. + ClientCommonPacketListenerImplAccessor accessor = (ClientCommonPacketListenerImplAccessor) handler; + ServerData serverData = accessor.getServerData(); + serverData.setResourcePackStatus(ServerData.ServerPackStatus.ENABLED); + return; + } + SpoutProtocol.tryChangeState(ClientModState.HANDSHAKE_STARTED, ClientModState.CLIENT_MOD_NOT_DETECTED); + } + + public static void onDisconnect() { SwitchOverlayStyle.setMojang(); - // Clear custom content, if present - while (true) { - if (SpoutProtocol.getState() == ClientModState.ADDED_CUSTOM_CONTENT) { - TemporaryRegistryModifiers.removeCustomContent(); - RegistryIdMappings.clear(); - BlockStateRegistryIdMappings.clear(); - SpoutProtocol.changeState(ClientModState.ADDED_CUSTOM_CONTENT, ClientModState.REMOVED_CUSTOM_CONTENT); - break; - } - if (SpoutProtocol.tryChangeState(Set.of(ClientModState.IDLE, ClientModState.HANDSHAKE_STARTED, ClientModState.CLIENT_MOD_DETECTED, ClientModState.CLIENT_MOD_NOT_DETECTED), ClientModState.REMOVED_CUSTOM_CONTENT)) { - break; - } - Thread.onSpinWait(); + ClientModState oldState = state.getAndSet(ClientModState.IDLE); + ClientModCustomContentReceiving.clear(); + if (oldState == ClientModState.ADDED_CUSTOM_CONTENT) { + TemporaryRegistryModifiers.removeCustomContent(); + RegistryIdMappings.clear(); + BlockStateRegistryIdMappings.clear(); } - // Reset to idle - SpoutProtocol.changeState(ClientModState.REMOVED_CUSTOM_CONTENT, ClientModState.IDLE); } public static boolean tryChangeState(ClientModState oldState, ClientModState newState) { @@ -134,24 +121,30 @@ public static void changeState(ClientModState oldState, ClientModState newState) } } - public static boolean tryChangeState(Set oldStates, ClientModState newState) { - ClientModState currentState = state.get(); - if (oldStates.contains(currentState)) { - if (state.compareAndSet(currentState, newState)) { - return true; - } - } - return false; + public static ClientModState getState() { + return state.get(); } - public static void changeState(Set oldStates, ClientModState newState) { - while (!tryChangeState(oldStates, newState)) { - Thread.onSpinWait(); + public record ClientModDetectionQueryPayload( + int protocolMarker, + int nonce, + int minProtocolVersion, + int maxProtocolVersion + ) implements CustomQueryPayload { + + @Override + public Identifier id() { + return CLIENT_MOD_DETECTION_PACKET_ID; + } + + @Override + public void write(FriendlyByteBuf output) { + output.writeVarInt(this.protocolMarker); + output.writeVarInt(this.nonce); + output.writeVarInt(this.minProtocolVersion); + output.writeVarInt(this.maxProtocolVersion); } - } - public static ClientModState getState() { - return state.get(); } } diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientCommonPacketListenerImplMixin.java b/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientCommonPacketListenerImplMixin.java new file mode 100644 index 00000000..8cfd2917 --- /dev/null +++ b/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientCommonPacketListenerImplMixin.java @@ -0,0 +1,31 @@ +package spout.clientview.clientmod.protocol.mixin; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientCommonPacketListenerImpl; +import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import spout.clientview.clientmod.protocol.ClientModCustomContentPacketPayload; +import spout.clientview.clientmod.protocol.ClientModCustomContentReceiving; + +@Mixin(ClientCommonPacketListenerImpl.class) +public abstract class ClientCommonPacketListenerImplMixin { + + @Inject(method = "handleCustomPayload", at = @At("HEAD"), cancellable = true) + private void handleSpoutCustomPayload(ClientboundCustomPayloadPacket packet, CallbackInfo ci) { + CustomPacketPayload payload = packet.payload(); + if (payload instanceof ClientModCustomContentPacketPayload spoutPayload) { + Minecraft client = Minecraft.getInstance(); + if (client.isSameThread()) { + ClientModCustomContentReceiving.handlePacket(spoutPayload); + } else { + client.submit(() -> ClientModCustomContentReceiving.handlePacket(spoutPayload)).join(); + } + ci.cancel(); + } + } + +} diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientConfigurationPacketListenerImplMixin.java b/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientConfigurationPacketListenerImplMixin.java new file mode 100644 index 00000000..3d4d1f72 --- /dev/null +++ b/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientConfigurationPacketListenerImplMixin.java @@ -0,0 +1,27 @@ +package spout.clientview.clientmod.protocol.mixin; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientCommonPacketListenerImpl; +import net.minecraft.client.multiplayer.ClientConfigurationPacketListenerImpl; +import net.minecraft.client.multiplayer.CommonListenerCookie; +import net.minecraft.network.Connection; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import spout.clientview.clientmod.protocol.SpoutProtocol; + +@Mixin(ClientConfigurationPacketListenerImpl.class) +public abstract class ClientConfigurationPacketListenerImplMixin { + + @Inject(method = "", at = @At("TAIL")) + private void markConfigurationStart( + Minecraft minecraft, + Connection connection, + CommonListenerCookie cookie, + CallbackInfo ci + ) { + SpoutProtocol.onConfigurationStart((ClientCommonPacketListenerImpl) (Object) this); + } + +} diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientHandshakePacketListenerImplMixin.java b/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientHandshakePacketListenerImplMixin.java new file mode 100644 index 00000000..e645b0ac --- /dev/null +++ b/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientHandshakePacketListenerImplMixin.java @@ -0,0 +1,67 @@ +package spout.clientview.clientmod.protocol.mixin; + +import java.time.Duration; +import java.util.function.Consumer; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.multiplayer.ClientHandshakePacketListenerImpl; +import net.minecraft.client.multiplayer.LevelLoadTracker; +import net.minecraft.client.multiplayer.ServerData; +import net.minecraft.client.multiplayer.TransferState; +import net.minecraft.network.Connection; +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.login.ClientboundCustomQueryPacket; +import net.minecraft.network.protocol.login.ServerboundCustomQueryAnswerPacket; +import net.minecraft.network.protocol.login.custom.CustomQueryPayload; +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; +import spout.clientview.clientmod.protocol.SpoutProtocol; + +@Mixin(ClientHandshakePacketListenerImpl.class) +public abstract class ClientHandshakePacketListenerImplMixin { + + @Shadow + @Final + private Connection connection; + + @Shadow + @Final + private Consumer updateStatus; + + @Inject(method = "", at = @At("TAIL")) + private void markLoginStart( + Connection connection, + Minecraft minecraft, + ServerData serverData, + Screen parent, + boolean newWorld, + Duration worldLoadDuration, + Consumer updateStatus, + LevelLoadTracker levelLoadTracker, + TransferState transferState, + CallbackInfo ci + ) { + SpoutProtocol.onLoginStart(); + } + + @Inject(method = "handleCustomQuery", at = @At("HEAD"), cancellable = true) + private void handleSpoutCustomQuery(ClientboundCustomQueryPacket packet, CallbackInfo ci) { + CustomQueryPayload payload = packet.payload(); + if (!SpoutProtocol.CLIENT_MOD_DETECTION_PACKET_ID.equals(payload.id())) { + return; + } + this.updateStatus.accept(Component.translatable("connect.negotiating")); + this.connection.send( + new ServerboundCustomQueryAnswerPacket( + packet.transactionId(), + SpoutProtocol.createClientModDetectionAnswer(payload) + ) + ); + ci.cancel(); + } + +} diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientPacketListenerMixin.java b/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientPacketListenerMixin.java new file mode 100644 index 00000000..8c387993 --- /dev/null +++ b/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientPacketListenerMixin.java @@ -0,0 +1,18 @@ +package spout.clientview.clientmod.protocol.mixin; + +import net.minecraft.client.multiplayer.ClientPacketListener; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import spout.clientview.clientmod.protocol.SpoutProtocol; + +@Mixin(ClientPacketListener.class) +public abstract class ClientPacketListenerMixin { + + @Inject(method = "clearLevel", at = @At("HEAD")) + private void removeSpoutContentBeforeClearingLevel(CallbackInfo ci) { + SpoutProtocol.onDisconnect(); + } + +} diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientboundCustomQueryPacketMixin.java b/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientboundCustomQueryPacketMixin.java new file mode 100644 index 00000000..8f2019ff --- /dev/null +++ b/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientboundCustomQueryPacketMixin.java @@ -0,0 +1,27 @@ +package spout.clientview.clientmod.protocol.mixin; + +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.protocol.login.ClientboundCustomQueryPacket; +import net.minecraft.network.protocol.login.custom.CustomQueryPayload; +import net.minecraft.resources.Identifier; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import spout.clientview.clientmod.protocol.SpoutProtocol; + +@Mixin(ClientboundCustomQueryPacket.class) +public abstract class ClientboundCustomQueryPacketMixin { + + @Inject(method = "readPayload", at = @At("HEAD"), cancellable = true) + private static void readSpoutPayload( + Identifier identifier, + FriendlyByteBuf input, + CallbackInfoReturnable cir + ) { + if (SpoutProtocol.CLIENT_MOD_DETECTION_PACKET_ID.equals(identifier)) { + cir.setReturnValue(SpoutProtocol.readClientModDetectionQuery(input)); + } + } + +} diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/CustomPacketPayloadCodecMixin.java b/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/CustomPacketPayloadCodecMixin.java new file mode 100644 index 00000000..cc0b74e4 --- /dev/null +++ b/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/CustomPacketPayloadCodecMixin.java @@ -0,0 +1,26 @@ +package spout.clientview.clientmod.protocol.mixin; + +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.Identifier; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import spout.clientview.clientmod.protocol.ClientModCustomContentPacketPayload; + +@Mixin(targets = "net.minecraft.network.protocol.common.custom.CustomPacketPayload$1") +public abstract class CustomPacketPayloadCodecMixin { + + @Inject(method = "findCodec", at = @At("HEAD"), cancellable = true) + private void findSpoutCodec( + Identifier identifier, + CallbackInfoReturnable> cir + ) { + if (ClientModCustomContentPacketPayload.TYPE.id().equals(identifier)) { + cir.setReturnValue((StreamCodec) ClientModCustomContentPacketPayload.STREAM_CODEC); + } + } + +} diff --git a/spoutcraft-fabric/src/client/java/spout/main/SpoutcraftClientModInitializer.java b/spoutcraft-fabric/src/client/java/spout/main/SpoutcraftClientModInitializer.java deleted file mode 100644 index ebc7c30e..00000000 --- a/spoutcraft-fabric/src/client/java/spout/main/SpoutcraftClientModInitializer.java +++ /dev/null @@ -1,13 +0,0 @@ -package spout.main; - -import net.fabricmc.api.ClientModInitializer; -import spout.clientview.clientmod.protocol.SpoutProtocol; - -public class SpoutcraftClientModInitializer implements ClientModInitializer { - - @Override - public void onInitializeClient() { - SpoutProtocol.initialize(); - } - -} diff --git a/spoutcraft-fabric/src/client/resources/spoutcraft.spout.clientview.clientmod.protocol.mixins.json b/spoutcraft-fabric/src/client/resources/spoutcraft.spout.clientview.clientmod.protocol.mixins.json index 937860b6..8ae74370 100644 --- a/spoutcraft-fabric/src/client/resources/spoutcraft.spout.clientview.clientmod.protocol.mixins.json +++ b/spoutcraft-fabric/src/client/resources/spoutcraft.spout.clientview.clientmod.protocol.mixins.json @@ -4,7 +4,13 @@ "compatibilityLevel": "JAVA_25", "client": [ "AllowSpoutServerPacksMixin", - "ClientCommonPacketListenerImplAccessor" + "ClientCommonPacketListenerImplAccessor", + "ClientCommonPacketListenerImplMixin", + "ClientConfigurationPacketListenerImplMixin", + "ClientHandshakePacketListenerImplMixin", + "ClientPacketListenerMixin", + "ClientboundCustomQueryPacketMixin", + "CustomPacketPayloadCodecMixin" ], "injectors": { "defaultRequire": 1 diff --git a/spoutcraft-fabric/src/main/java/spout/main/SpoutcraftModInitializer.java b/spoutcraft-fabric/src/main/java/spout/main/SpoutcraftModInitializer.java deleted file mode 100644 index c309d5d4..00000000 --- a/spoutcraft-fabric/src/main/java/spout/main/SpoutcraftModInitializer.java +++ /dev/null @@ -1,22 +0,0 @@ -package spout.main; - -import net.fabricmc.api.ModInitializer; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SpoutcraftModInitializer implements ModInitializer { - - public static final String MOD_ID = "spoutcraft"; - public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - - @Override - public void onInitialize() { - try { - Class.forName("spout.main.SpoutcraftClientModInitializer"); - } catch (ClassNotFoundException ignored) { - LOGGER.warn("Spoutcraft client mod was loaded on a server - will have no effect"); - } - } - -} diff --git a/spoutcraft-fabric/src/main/resources/fabric.mod.json b/spoutcraft-fabric/src/main/resources/fabric.mod.json index 81b8b81b..c92ca968 100644 --- a/spoutcraft-fabric/src/main/resources/fabric.mod.json +++ b/spoutcraft-fabric/src/main/resources/fabric.mod.json @@ -14,14 +14,6 @@ "license": "See the included LICENSE.txt", "icon": "assets/spout/icon.png", "environment": "*", - "entrypoints": { - "main": [ - "spout.main.SpoutcraftModInitializer" - ], - "client": [ - "spout.main.SpoutcraftClientModInitializer" - ] - }, "accessWidener": "spoutcraft.classtweaker", "mixins": [ { @@ -76,7 +68,6 @@ "depends": { "fabricloader": ">=0.19.2", "minecraft": "~26.1.2", - "java": ">=25", - "fabric-api": "*" + "java": ">=25" } } diff --git a/spoutcraft-fabric/src/main/resources/spoutcraft.classtweaker b/spoutcraft-fabric/src/main/resources/spoutcraft.classtweaker index b6f7186a..0ff51edc 100644 --- a/spoutcraft-fabric/src/main/resources/spoutcraft.classtweaker +++ b/spoutcraft-fabric/src/main/resources/spoutcraft.classtweaker @@ -40,5 +40,11 @@ accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties speedFactor F accessible method net/minecraft/core/registries/BuiltInRegistries internalRegister (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/core/WritableRegistry;Lnet/minecraft/core/registries/BuiltInRegistries$RegistryBootstrap;)Lnet/minecraft/core/WritableRegistry; accessible method net/minecraft/core/registries/BuiltInRegistries registerSimple (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/core/registries/BuiltInRegistries$RegistryBootstrap;)Lnet/minecraft/core/Registry; +accessible method net/minecraft/world/level/block/Blocks always (Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Z +accessible method net/minecraft/world/level/block/Blocks always (Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/EntityType;)Ljava/lang/Boolean; +accessible method net/minecraft/world/level/block/Blocks never (Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Z +accessible method net/minecraft/world/level/block/Blocks never (Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/EntityType;)Ljava/lang/Boolean; +accessible method net/minecraft/world/level/block/Blocks ocelotOrParrot (Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/EntityType;)Ljava/lang/Boolean; +accessible method net/minecraft/world/level/block/StairBlock (Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V accessible method net/minecraft/world/level/block/state/BlockBehaviour propertiesCodec ()Lcom/mojang/serialization/codecs/RecordCodecBuilder; transitive-extendable method net/minecraft/core/IdMapper byId (I)Ljava/lang/Object; From 6d7793c3908b83a19858f1681010789ff1ac5faa Mon Sep 17 00:00:00 2001 From: noramibu <50046813+noramibu@users.noreply.github.com> Date: Sat, 27 Jun 2026 23:10:51 +0300 Subject: [PATCH 2/2] Refactor Spoutcraft client for multiloader support --- settings.gradle.kts | 2 +- ...egisteringTexturesLoadingOverlayMixin.java | 39 --------- ...ojangLogoAfterTexturesRegisteredMixin.java | 25 ------ .../mixin/ClientPacketListenerMixin.java | 18 ----- .../block/RemappedBlockStateRegistry.java | 30 ------- .../MapBlockStateRegistryIdsBlockMixin.java | 28 ------- .../.editorconfig | 0 .../.gitignore | 0 spoutcraft-mod/build.gradle.kts | 8 ++ .../loadingoverlay/SpoutLogoIdentifier.java | 0 .../loadingoverlay/SwitchOverlayStyle.java | 0 ...sitionsOfSpoutLogoLoadingOverlayMixin.java | 2 +- .../LoadingOverlayLogoLocationAccessor.java | 0 .../ReplaceColorsAndSizesOverlayMixin.java | 3 +- .../loadingoverlay/mixin/package-info.java | 0 .../loadingoverlay/package-info.java | 0 .../clientui/resourcepack/package-info.java | 0 ...noreResourcePackDownloadProgressMixin.java | 0 .../toast/mixin/package-info.java | 0 .../resourcepack/toast/package-info.java | 0 .../clientmod/command/SpoutcraftCommand.java | 77 ++++++++++++++++++ .../ClientModCustomContentReceiving.java | 55 ++++++++++--- .../clientmod/protocol/ClientModState.java | 0 .../clientmod/protocol/SpoutProtocol.java | 32 ++++++-- .../mixin/AllowSpoutServerPacksMixin.java | 0 ...lientCommonPacketListenerImplAccessor.java | 0 .../ClientCommonPacketListenerImplMixin.java | 0 ...tConfigurationPacketListenerImplMixin.java | 0 ...lientHandshakePacketListenerImplMixin.java | 0 .../mixin/ClientPacketListenerMixin.java | 38 +++++++++ .../ClientboundCustomQueryPacketMixin.java | 0 .../mixin/CustomPacketPayloadCodecMixin.java | 2 +- .../protocol/mixin/package-info.java | 0 .../registryidmapping/RegistryIdMappings.java | 0 .../mixin/MapIdsByteBufCodecsMixin.java | 0 .../block/BlockStateRegistryIdMappings.java | 0 .../block/TemporaryBlockRegistryModifier.java | 0 .../mixin/BlockCodecAccessorBlockMixin.java | 0 ...MapBlockStateRegistryIdsIdMapperMixin.java | 22 +++++ ...aceBlockBehaviourPropertiesCodecMixin.java | 0 ...rmattedBlockStateCodecStairBlockMixin.java | 0 ...eCodecWeatheringCopperStairBlockMixin.java | 0 ...icalOffsetAccessorBlockBehaviourMixin.java | 0 ...kEntityTypeDataDrivenValidBlocksMixin.java | 0 ...tBlockTypeRegistryMappedRegistryMixin.java | 0 .../CacheByNameCodecMappedRegistryMixin.java | 0 .../TemporaryRegistryModifier.java | 14 +++- .../TemporaryRegistryModifiers.java | 0 .../mixin/HolderSetNamedAccessor.java | 0 .../mixin/MappedRegistryAccessor.java | 0 .../item/TemporaryItemRegistryModifier.java | 5 +- .../DataComponentInitializersAccessor.java | 0 ...alizationDecoratorItemPropertiesMixin.java | 0 .../ItemTypeDecoratorBlockItemMixin.java | 0 ...TypeDecoratorDoubleHighBlockItemMixin.java | 0 .../mixin/ItemTypeDecoratorEggItemMixin.java | 0 .../mixin/ItemTypeDecoratorItemMixin.java | 0 ...eSpoutBootstrapBuiltInRegistriesMixin.java | 0 ...ui.resourcepack.loadingoverlay.mixins.json | 4 +- ...ut.clientui.resourcepack.toast.mixins.json | 0 ....clientview.clientmod.protocol.mixins.json | 0 ...ew.clientmod.registryidmapping.mixins.json | 0 ...t.gamecontent.datadriven.block.mixins.json | 2 +- ...tent.datadriven.block.subtypes.mixins.json | 0 ...content.datadriven.blockentity.mixins.json | 0 ...mecontent.datadriven.blocktype.mixins.json | 0 ...tadriven.common.registry.codec.mixins.json | 0 ...registry.temporarymodification.mixins.json | 0 ...ut.gamecontent.datadriven.item.mixins.json | 0 ...t.spout.gamecontent.datadriven.mixins.json | 0 .../fabric}/build.gradle.kts | 18 +++-- .../src/main/resources/fabric.mod.json | 0 .../main/resources/spoutcraft.classtweaker | 1 - .../gradle.properties | 6 +- spoutcraft-mod/neoforge/build.gradle.kts | 80 +++++++++++++++++++ .../spout/neoforge/SpoutcraftNeoForgeMod.java | 25 ++++++ .../resources/META-INF/accesstransformer.cfg | 47 +++++++++++ .../resources/META-INF/neoforge.mods.toml | 62 ++++++++++++++ .../settings.gradle.kts | 8 ++ 79 files changed, 471 insertions(+), 182 deletions(-) delete mode 100644 spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceLogoWhenRegisteringTexturesLoadingOverlayMixin.java delete mode 100644 spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceMojangLogoAfterTexturesRegisteredMixin.java delete mode 100644 spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientPacketListenerMixin.java delete mode 100644 spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/block/RemappedBlockStateRegistry.java delete mode 100644 spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/block/mixin/MapBlockStateRegistryIdsBlockMixin.java rename {spoutcraft-fabric => spoutcraft-mod}/.editorconfig (100%) rename {spoutcraft-fabric => spoutcraft-mod}/.gitignore (100%) create mode 100644 spoutcraft-mod/build.gradle.kts rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientui/resourcepack/loadingoverlay/SpoutLogoIdentifier.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientui/resourcepack/loadingoverlay/SwitchOverlayStyle.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ChangePositionsOfSpoutLogoLoadingOverlayMixin.java (97%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/LoadingOverlayLogoLocationAccessor.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceColorsAndSizesOverlayMixin.java (95%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/package-info.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientui/resourcepack/loadingoverlay/package-info.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientui/resourcepack/package-info.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientui/resourcepack/toast/mixin/IgnoreResourcePackDownloadProgressMixin.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientui/resourcepack/toast/mixin/package-info.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientui/resourcepack/toast/package-info.java (100%) create mode 100644 spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/command/SpoutcraftCommand.java rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientview/clientmod/protocol/ClientModCustomContentReceiving.java (78%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientview/clientmod/protocol/ClientModState.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientview/clientmod/protocol/SpoutProtocol.java (84%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientview/clientmod/protocol/mixin/AllowSpoutServerPacksMixin.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientCommonPacketListenerImplAccessor.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientCommonPacketListenerImplMixin.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientConfigurationPacketListenerImplMixin.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientHandshakePacketListenerImplMixin.java (100%) create mode 100644 spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientPacketListenerMixin.java rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientboundCustomQueryPacketMixin.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientview/clientmod/protocol/mixin/CustomPacketPayloadCodecMixin.java (88%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientview/clientmod/protocol/mixin/package-info.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientview/clientmod/registryidmapping/RegistryIdMappings.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/clientview/clientmod/registryidmapping/mixin/MapIdsByteBufCodecsMixin.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/gamecontent/datadriven/block/BlockStateRegistryIdMappings.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/gamecontent/datadriven/block/TemporaryBlockRegistryModifier.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/gamecontent/datadriven/block/mixin/BlockCodecAccessorBlockMixin.java (100%) create mode 100644 spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/block/mixin/MapBlockStateRegistryIdsIdMapperMixin.java rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/gamecontent/datadriven/block/mixin/ReplaceBlockBehaviourPropertiesCodecMixin.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/gamecontent/datadriven/block/mixin/UseFormattedBlockStateCodecStairBlockMixin.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/gamecontent/datadriven/block/mixin/UseFormattedBlockStateCodecWeatheringCopperStairBlockMixin.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/gamecontent/datadriven/block/subtypes/mixin/BlockBehaviourMaxVerticalOffsetAccessorBlockBehaviourMixin.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/gamecontent/datadriven/blockentity/mixin/BlockEntityTypeDataDrivenValidBlocksMixin.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/gamecontent/datadriven/blocktype/mixin/MirrorMinecraftBlockTypeRegistryMappedRegistryMixin.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/gamecontent/datadriven/common/registry/codec/mixin/CacheByNameCodecMappedRegistryMixin.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/gamecontent/datadriven/common/registry/temporarymodification/TemporaryRegistryModifier.java (92%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/gamecontent/datadriven/common/registry/temporarymodification/TemporaryRegistryModifiers.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/gamecontent/datadriven/common/registry/temporarymodification/mixin/HolderSetNamedAccessor.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/gamecontent/datadriven/common/registry/temporarymodification/mixin/MappedRegistryAccessor.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/gamecontent/datadriven/item/TemporaryItemRegistryModifier.java (93%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/gamecontent/datadriven/item/mixin/DataComponentInitializersAccessor.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemPropertiesSerializationDecoratorItemPropertiesMixin.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemTypeDecoratorBlockItemMixin.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemTypeDecoratorDoubleHighBlockItemMixin.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemTypeDecoratorEggItemMixin.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemTypeDecoratorItemMixin.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/java/spout/gamecontent/datadriven/mixin/IncludeSpoutBootstrapBuiltInRegistriesMixin.java (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/resources/spoutcraft.spout.clientui.resourcepack.loadingoverlay.mixins.json (64%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/resources/spoutcraft.spout.clientui.resourcepack.toast.mixins.json (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/resources/spoutcraft.spout.clientview.clientmod.protocol.mixins.json (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/resources/spoutcraft.spout.clientview.clientmod.registryidmapping.mixins.json (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/resources/spoutcraft.spout.gamecontent.datadriven.block.mixins.json (89%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/resources/spoutcraft.spout.gamecontent.datadriven.block.subtypes.mixins.json (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/resources/spoutcraft.spout.gamecontent.datadriven.blockentity.mixins.json (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/resources/spoutcraft.spout.gamecontent.datadriven.blocktype.mixins.json (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/resources/spoutcraft.spout.gamecontent.datadriven.common.registry.codec.mixins.json (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/resources/spoutcraft.spout.gamecontent.datadriven.common.registry.temporarymodification.mixins.json (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/resources/spoutcraft.spout.gamecontent.datadriven.item.mixins.json (100%) rename {spoutcraft-fabric => spoutcraft-mod/common}/src/client/resources/spoutcraft.spout.gamecontent.datadriven.mixins.json (100%) rename {spoutcraft-fabric => spoutcraft-mod/fabric}/build.gradle.kts (81%) rename {spoutcraft-fabric => spoutcraft-mod/fabric}/src/main/resources/fabric.mod.json (100%) rename {spoutcraft-fabric => spoutcraft-mod/fabric}/src/main/resources/spoutcraft.classtweaker (98%) rename {spoutcraft-fabric => spoutcraft-mod}/gradle.properties (82%) create mode 100644 spoutcraft-mod/neoforge/build.gradle.kts create mode 100644 spoutcraft-mod/neoforge/src/main/java/spout/neoforge/SpoutcraftNeoForgeMod.java create mode 100644 spoutcraft-mod/neoforge/src/main/resources/META-INF/accesstransformer.cfg create mode 100644 spoutcraft-mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml rename {spoutcraft-fabric => spoutcraft-mod}/settings.gradle.kts (58%) diff --git a/settings.gradle.kts b/settings.gradle.kts index ddf1be50..24f697d8 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,4 +2,4 @@ rootProject.name = "spout-monorepo" includeBuild("spout-fabric") includeBuild("spout-paper") -includeBuild("spoutcraft-fabric") +includeBuild("spoutcraft-mod") diff --git a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceLogoWhenRegisteringTexturesLoadingOverlayMixin.java b/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceLogoWhenRegisteringTexturesLoadingOverlayMixin.java deleted file mode 100644 index 7dd92a71..00000000 --- a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceLogoWhenRegisteringTexturesLoadingOverlayMixin.java +++ /dev/null @@ -1,39 +0,0 @@ -package spout.clientui.resourcepack.loadingoverlay.mixin; - -import com.mojang.blaze3d.platform.NativeImage; -import net.minecraft.client.gui.screens.LoadingOverlay; -import net.minecraft.client.renderer.texture.MipmapStrategy; -import net.minecraft.client.renderer.texture.ReloadableTexture; -import net.minecraft.client.renderer.texture.TextureContents; -import net.minecraft.client.renderer.texture.TextureManager; -import net.minecraft.client.resources.metadata.texture.TextureMetadataSection; -import net.minecraft.server.packs.resources.ResourceManager; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import spout.clientui.resourcepack.loadingoverlay.SpoutLogoIdentifier; -import java.io.IOException; -import java.io.InputStream; - -@Mixin(LoadingOverlay.class) -public abstract class ReplaceLogoWhenRegisteringTexturesLoadingOverlayMixin { - - @Inject(method = "registerTextures", at = @At("HEAD"), cancellable = true) - private static void spout$replaceLogo(TextureManager textureManager, CallbackInfo ci) { - textureManager.registerAndLoad(SpoutLogoIdentifier.IDENTIFIER, new ReloadableTexture(SpoutLogoIdentifier.IDENTIFIER) { - - @Override - public TextureContents loadContents(ResourceManager resourceManager) throws IOException { - try (InputStream input = SpoutLogoIdentifier.open()) { - TextureContents result = new TextureContents(NativeImage.read(input), - new TextureMetadataSection(true, true, MipmapStrategy.MEAN, 0.0f)); - return result; - } - } - - }); - ci.cancel(); // Prevent vanilla logo instance from being created - } - -} diff --git a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceMojangLogoAfterTexturesRegisteredMixin.java b/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceMojangLogoAfterTexturesRegisteredMixin.java deleted file mode 100644 index c9911764..00000000 --- a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceMojangLogoAfterTexturesRegisteredMixin.java +++ /dev/null @@ -1,25 +0,0 @@ -package spout.clientui.resourcepack.loadingoverlay.mixin; - -import net.minecraft.client.gui.screens.LoadingOverlay; -import net.minecraft.client.renderer.texture.ReloadableTexture; -import net.minecraft.client.renderer.texture.TextureManager; -import net.minecraft.resources.Identifier; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(TextureManager.class) -public abstract class ReplaceMojangLogoAfterTexturesRegisteredMixin { - - @Inject( - method = "registerAndLoad(Lnet/minecraft/resources/Identifier;Lnet/minecraft/client/renderer/texture/ReloadableTexture;)V", - at = @At("RETURN") - ) - private void afterTextureRegistered(Identifier id, ReloadableTexture texture, CallbackInfo ci) { - if (id.getNamespace().equals(Identifier.DEFAULT_NAMESPACE) && id.getPath().equals("textures/environment/end_sky.png") && LoadingOverlay.MOJANG_STUDIOS_LOGO_LOCATION.getNamespace().equals(Identifier.DEFAULT_NAMESPACE)) { - // SwitchOverlayLogo.setSpout(); - } - } - -} diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientPacketListenerMixin.java b/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientPacketListenerMixin.java deleted file mode 100644 index 8c387993..00000000 --- a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientPacketListenerMixin.java +++ /dev/null @@ -1,18 +0,0 @@ -package spout.clientview.clientmod.protocol.mixin; - -import net.minecraft.client.multiplayer.ClientPacketListener; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import spout.clientview.clientmod.protocol.SpoutProtocol; - -@Mixin(ClientPacketListener.class) -public abstract class ClientPacketListenerMixin { - - @Inject(method = "clearLevel", at = @At("HEAD")) - private void removeSpoutContentBeforeClearingLevel(CallbackInfo ci) { - SpoutProtocol.onDisconnect(); - } - -} diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/block/RemappedBlockStateRegistry.java b/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/block/RemappedBlockStateRegistry.java deleted file mode 100644 index e9fcba0a..00000000 --- a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/block/RemappedBlockStateRegistry.java +++ /dev/null @@ -1,30 +0,0 @@ -package spout.gamecontent.datadriven.block; - -import net.minecraft.core.IdMapper; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import org.jspecify.annotations.Nullable; - -/** - * The implementation for {@link Block#BLOCK_STATE_REGISTRY}. - */ -public final class RemappedBlockStateRegistry extends IdMapper { - - @Override - public int getId(BlockState thing) { - return BlockStateRegistryIdMappings.applyClientToServer(super.getId(thing)); - } - - public int getIdUnmapped(BlockState thing) { - return super.getId(thing); - } - - public @Nullable BlockState byId(int id) { - return super.byId(BlockStateRegistryIdMappings.applyServerToClient(id)); - } - - public @Nullable BlockState byIdUnmapped(int id) { - return super.byId(id); - } - -} diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/block/mixin/MapBlockStateRegistryIdsBlockMixin.java b/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/block/mixin/MapBlockStateRegistryIdsBlockMixin.java deleted file mode 100644 index 3060df52..00000000 --- a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/block/mixin/MapBlockStateRegistryIdsBlockMixin.java +++ /dev/null @@ -1,28 +0,0 @@ -package spout.gamecontent.datadriven.block.mixin; - -import net.minecraft.core.IdMapper; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Mutable; -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; -import spout.gamecontent.datadriven.block.RemappedBlockStateRegistry; - -@Mixin(Block.class) -public abstract class MapBlockStateRegistryIdsBlockMixin { - - @Shadow - @Final - @Mutable - public static IdMapper BLOCK_STATE_REGISTRY; - - @Inject(method = "", at = @At("TAIL")) - private static void replaceBlockStateRegistry(CallbackInfo ci) { - BLOCK_STATE_REGISTRY = new RemappedBlockStateRegistry(); - } - -} diff --git a/spoutcraft-fabric/.editorconfig b/spoutcraft-mod/.editorconfig similarity index 100% rename from spoutcraft-fabric/.editorconfig rename to spoutcraft-mod/.editorconfig diff --git a/spoutcraft-fabric/.gitignore b/spoutcraft-mod/.gitignore similarity index 100% rename from spoutcraft-fabric/.gitignore rename to spoutcraft-mod/.gitignore diff --git a/spoutcraft-mod/build.gradle.kts b/spoutcraft-mod/build.gradle.kts new file mode 100644 index 00000000..1cf55f0a --- /dev/null +++ b/spoutcraft-mod/build.gradle.kts @@ -0,0 +1,8 @@ +plugins { + base +} + +tasks.named("build") { + dependsOn(":fabric:build") + dependsOn(":neoforge:build") +} diff --git a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/SpoutLogoIdentifier.java b/spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/loadingoverlay/SpoutLogoIdentifier.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/SpoutLogoIdentifier.java rename to spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/loadingoverlay/SpoutLogoIdentifier.java diff --git a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/SwitchOverlayStyle.java b/spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/loadingoverlay/SwitchOverlayStyle.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/SwitchOverlayStyle.java rename to spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/loadingoverlay/SwitchOverlayStyle.java diff --git a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ChangePositionsOfSpoutLogoLoadingOverlayMixin.java b/spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ChangePositionsOfSpoutLogoLoadingOverlayMixin.java similarity index 97% rename from spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ChangePositionsOfSpoutLogoLoadingOverlayMixin.java rename to spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ChangePositionsOfSpoutLogoLoadingOverlayMixin.java index 417eb0a5..a213aa73 100644 --- a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ChangePositionsOfSpoutLogoLoadingOverlayMixin.java +++ b/spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ChangePositionsOfSpoutLogoLoadingOverlayMixin.java @@ -24,7 +24,7 @@ private static void adjustedGraphicsBlit(GuiGraphicsExtractor graphics, RenderPi // Adjust parameters int contentX = (int) ((double) graphics.guiWidth() * (double) 0.5F); int logoY = (int) ((double) graphics.guiHeight() * (double) 0.5F); - double logoHeight = Math.min((double) graphics.guiWidth() * (double) 0.75F, (double) graphics.guiHeight()) * ADJUSTED_GRAPHICS_WIDTH_FACTOR; + double logoHeight = Math.min((double) graphics.guiWidth() * (double) 0.75F, graphics.guiHeight()) * ADJUSTED_GRAPHICS_WIDTH_FACTOR; int logoHeightHalf = (int) (logoHeight * (double) 0.5F); double contentWidth = logoHeight * (double) 4.0F; int logoWidthHalf = (int) (contentWidth * (double) 0.5F); diff --git a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/LoadingOverlayLogoLocationAccessor.java b/spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/LoadingOverlayLogoLocationAccessor.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/LoadingOverlayLogoLocationAccessor.java rename to spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/LoadingOverlayLogoLocationAccessor.java diff --git a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceColorsAndSizesOverlayMixin.java b/spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceColorsAndSizesOverlayMixin.java similarity index 95% rename from spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceColorsAndSizesOverlayMixin.java rename to spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceColorsAndSizesOverlayMixin.java index 8a1ff2ab..bac612c9 100644 --- a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceColorsAndSizesOverlayMixin.java +++ b/spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/ReplaceColorsAndSizesOverlayMixin.java @@ -71,9 +71,8 @@ public abstract class ReplaceColorsAndSizesOverlayMixin { @Override public TextureContents loadContents(ResourceManager resourceManager) throws IOException { try (InputStream input = SpoutLogoIdentifier.open()) { - TextureContents result = new TextureContents(NativeImage.read(input), + return new TextureContents(NativeImage.read(input), new TextureMetadataSection(true, true, MipmapStrategy.MEAN, 0.0f)); - return result; } } diff --git a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/package-info.java b/spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/package-info.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/package-info.java rename to spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/loadingoverlay/mixin/package-info.java diff --git a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/package-info.java b/spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/loadingoverlay/package-info.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/loadingoverlay/package-info.java rename to spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/loadingoverlay/package-info.java diff --git a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/package-info.java b/spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/package-info.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/package-info.java rename to spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/package-info.java diff --git a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/toast/mixin/IgnoreResourcePackDownloadProgressMixin.java b/spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/toast/mixin/IgnoreResourcePackDownloadProgressMixin.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/toast/mixin/IgnoreResourcePackDownloadProgressMixin.java rename to spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/toast/mixin/IgnoreResourcePackDownloadProgressMixin.java diff --git a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/toast/mixin/package-info.java b/spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/toast/mixin/package-info.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/toast/mixin/package-info.java rename to spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/toast/mixin/package-info.java diff --git a/spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/toast/package-info.java b/spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/toast/package-info.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/clientui/resourcepack/toast/package-info.java rename to spoutcraft-mod/common/src/client/java/spout/clientui/resourcepack/toast/package-info.java diff --git a/spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/command/SpoutcraftCommand.java b/spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/command/SpoutcraftCommand.java new file mode 100644 index 00000000..6764af16 --- /dev/null +++ b/spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/command/SpoutcraftCommand.java @@ -0,0 +1,77 @@ +package spout.clientview.clientmod.command; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientSuggestionProvider; +import net.minecraft.network.chat.Component; +import spout.clientview.clientmod.protocol.ClientModCustomContentReceiving; +import spout.clientview.clientmod.protocol.SpoutProtocol; + +/** + * Client-side diagnostics for Spoutcraft. + */ +public final class SpoutcraftCommand { + + private static final String NAME = "spoutcraft"; + private static final String UNKNOWN = "unknown"; + + private SpoutcraftCommand() { + throw new UnsupportedOperationException(); + } + + public static void register(CommandDispatcher dispatcher) { + dispatcher.register( + LiteralArgumentBuilder.literal(NAME) + .executes(context -> { + showInfo(); + return Command.SINGLE_SUCCESS; + }) + ); + } + + public static boolean executeIfSpoutcraftCommand(String command) { + if (!command.equals(NAME)) { + return false; + } + showInfo(); + return true; + } + + private static void showInfo() { + ClientModCustomContentReceiving.LoadedContentSummary summary = + ClientModCustomContentReceiving.getLoadedContentSummary(); + + send("Spoutcraft"); + send("State: " + SpoutProtocol.getState()); + send("Server protocol: " + protocolRange()); + send("Negotiated protocol: " + unknownIfNegative(SpoutProtocol.getSelectedProtocolVersion())); + send("Loaded blocks: " + summary.blocks()); + send("Loaded block states: " + summary.blockStates()); + send("Loaded items: " + summary.items()); + send("Registry id lists: " + summary.registryIdLists()); + send("Block-state id lists: " + summary.blockStateIdLists()); + } + + private static String protocolRange() { + int min = SpoutProtocol.getServerMinProtocolVersion(); + int max = SpoutProtocol.getServerMaxProtocolVersion(); + if (min < 0 || max < 0) { + return UNKNOWN; + } + return min + "-" + max; + } + + private static String unknownIfNegative(int value) { + return value < 0 ? UNKNOWN : Integer.toString(value); + } + + private static void send(String message) { + Minecraft client = Minecraft.getInstance(); + if (client.player != null) { + client.player.sendSystemMessage(Component.literal(message)); + } + } + +} diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/ClientModCustomContentReceiving.java b/spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/ClientModCustomContentReceiving.java similarity index 78% rename from spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/ClientModCustomContentReceiving.java rename to spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/ClientModCustomContentReceiving.java index aa71db16..393649bb 100644 --- a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/ClientModCustomContentReceiving.java +++ b/spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/ClientModCustomContentReceiving.java @@ -12,7 +12,6 @@ import org.jspecify.annotations.Nullable; import spout.gamecontent.datadriven.common.registry.temporarymodification.TemporaryRegistryModifiers; import spout.gamecontent.datadriven.block.BlockStateRegistryIdMappings; -import spout.gamecontent.datadriven.block.RemappedBlockStateRegistry; import spout.clientview.clientmod.registryidmapping.RegistryIdMappings; import spout.clientview.clientmod.registryidmapping.BlockStateRegistryEntryIdList; import spout.gamecontent.datadriven.block.ContextAwareBlockPropertiesDecoding; @@ -36,6 +35,7 @@ private ClientModCustomContentReceiving() { * The current received content, or null if not currently receiving. */ private static volatile @Nullable ClientModCustomContent receivedContent; + private static volatile LoadedContentSummary loadedContentSummary = LoadedContentSummary.empty(); public static void handlePacket(ClientModCustomContentPacketPayload payload) { while (SpoutProtocol.getState() != ClientModState.RECEIVED_CUSTOM_CONTENT && !SpoutProtocol.tryChangeState(ClientModState.CLIENT_MOD_DETECTED, ClientModState.RECEIVED_CUSTOM_CONTENT)) { @@ -72,34 +72,29 @@ public static void handlePacket(ClientModCustomContentPacketPayload payload) { }); }).toList() ); - RemappedBlockStateRegistry blockStateRegistry = - (RemappedBlockStateRegistry) Block.BLOCK_STATE_REGISTRY; + int blockStateCount = 0; for (var keyedValue : receivedContent.getBlocks()) { Block block = BuiltInRegistries.BLOCK.get(keyedValue.identifier()).orElseThrow().value(); for (BlockState state : block.getStateDefinition().getPossibleStates()) { state.initCache(); - if (blockStateRegistry.getIdUnmapped(state) == -1) { + blockStateCount++; + if (Block.BLOCK_STATE_REGISTRY.getId(state) == -1) { Block.BLOCK_STATE_REGISTRY.add(state); } } } // Set up registry id mappings where necessary for (RegistryEntryIdList list : receivedContent.getRegistryEntryIdLists()) { - Registry registry = BuiltInRegistries.REGISTRY.getValue(list.registryIdentifier()); + Registry registry = BuiltInRegistries.REGISTRY.getValue(list.registryIdentifier()); if (registry != null) { - for (IntObjectPair pair : list.entryIds()) { - int currentId = registry.getId(registry.getValue(pair.right())); - if (currentId != pair.leftInt()) { - RegistryIdMappings.add(registry, currentId, pair.leftInt()); - } - } + addRegistryIdMappings(registry, list); } } // Set up block state mappings where necessary for (BlockStateRegistryEntryIdList list : receivedContent.getBlockStateRegistryEntryIdLists()) { for (IntObjectPair pair : list.entryIds()) { BlockState state = BlockStateStringConversion.blockStateFromString(pair.right()); - int idOnClient = ((RemappedBlockStateRegistry) Block.BLOCK_STATE_REGISTRY).getIdUnmapped(state); + int idOnClient = Block.BLOCK_STATE_REGISTRY.getId(state); int receivedId = pair.leftInt(); if (idOnClient != receivedId) { BlockStateRegistryIdMappings.add(idOnClient, receivedId); @@ -107,6 +102,13 @@ public static void handlePacket(ClientModCustomContentPacketPayload payload) { } } // Change the state + loadedContentSummary = new LoadedContentSummary( + receivedContent.getBlocks().size(), + receivedContent.getItems().size(), + blockStateCount, + receivedContent.getRegistryEntryIdLists().size(), + receivedContent.getBlockStateRegistryEntryIdLists().size() + ); SpoutProtocol.changeState(ClientModState.RECEIVED_CUSTOM_CONTENT, ClientModState.ADDED_CUSTOM_CONTENT); receivedContent = null; } @@ -122,8 +124,37 @@ public static void handlePacket(ClientModCustomContentPacketPayload payload) { } } + private static void addRegistryIdMappings(Registry registry, RegistryEntryIdList list) { + for (IntObjectPair pair : list.entryIds()) { + T value = registry.getValue(pair.right()); + int currentId = registry.getId(value); + if (currentId != pair.leftInt()) { + RegistryIdMappings.add(registry, currentId, pair.leftInt()); + } + } + } + static void clear() { receivedContent = null; + loadedContentSummary = LoadedContentSummary.empty(); + } + + public static LoadedContentSummary getLoadedContentSummary() { + return loadedContentSummary; + } + + public record LoadedContentSummary( + int blocks, + int items, + int blockStates, + int registryIdLists, + int blockStateIdLists + ) { + + private static LoadedContentSummary empty() { + return new LoadedContentSummary(0, 0, 0, 0, 0); + } + } } diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/ClientModState.java b/spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/ClientModState.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/ClientModState.java rename to spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/ClientModState.java diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/SpoutProtocol.java b/spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/SpoutProtocol.java similarity index 84% rename from spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/SpoutProtocol.java rename to spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/SpoutProtocol.java index 394be709..653f5ac2 100644 --- a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/SpoutProtocol.java +++ b/spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/SpoutProtocol.java @@ -26,6 +26,9 @@ public final class SpoutProtocol { private static final int MAX_PROTOCOL_VERSION = 5; private static final AtomicReference state = new AtomicReference<>(ClientModState.IDLE); + private static volatile int serverMinProtocolVersion = -1; + private static volatile int serverMaxProtocolVersion = -1; + private static volatile int selectedProtocolVersion = -1; private SpoutProtocol() { throw new UnsupportedOperationException(); @@ -60,18 +63,20 @@ public static CustomQueryAnswerPayload createClientModDetectionAnswer(CustomQuer detectionPayload.maxProtocolVersion, MAX_PROTOCOL_VERSION ); - int responseProtocolVersion = -1; // In case of failure, respond with an invalid version. - if (bestProtocolVersion >= detectionPayload.minProtocolVersion - && bestProtocolVersion >= MIN_PROTOCOL_VERSION) { + int responseProtocolVersion = + bestProtocolVersion >= detectionPayload.minProtocolVersion + && bestProtocolVersion == MIN_PROTOCOL_VERSION ? bestProtocolVersion : -1; + if (responseProtocolVersion != -1) { changeState(ClientModState.HANDSHAKE_STARTED, ClientModState.CLIENT_MOD_DETECTED); SwitchOverlayStyle.setSpout(); - responseProtocolVersion = bestProtocolVersion; } - int selectedProtocolVersion = responseProtocolVersion; + serverMinProtocolVersion = detectionPayload.minProtocolVersion; + serverMaxProtocolVersion = detectionPayload.maxProtocolVersion; + selectedProtocolVersion = responseProtocolVersion; return output -> { output.writeVarInt(0); output.writeVarInt(detectionPayload.nonce); - output.writeVarInt(selectedProtocolVersion); + output.writeVarInt(responseProtocolVersion); }; } @@ -103,6 +108,9 @@ public static void onConfigurationStart(ClientCommonPacketListenerImpl handler) public static void onDisconnect() { SwitchOverlayStyle.setMojang(); ClientModState oldState = state.getAndSet(ClientModState.IDLE); + serverMinProtocolVersion = -1; + serverMaxProtocolVersion = -1; + selectedProtocolVersion = -1; ClientModCustomContentReceiving.clear(); if (oldState == ClientModState.ADDED_CUSTOM_CONTENT) { TemporaryRegistryModifiers.removeCustomContent(); @@ -125,6 +133,18 @@ public static ClientModState getState() { return state.get(); } + public static int getServerMinProtocolVersion() { + return serverMinProtocolVersion; + } + + public static int getServerMaxProtocolVersion() { + return serverMaxProtocolVersion; + } + + public static int getSelectedProtocolVersion() { + return selectedProtocolVersion; + } + public record ClientModDetectionQueryPayload( int protocolMarker, int nonce, diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/AllowSpoutServerPacksMixin.java b/spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/mixin/AllowSpoutServerPacksMixin.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/AllowSpoutServerPacksMixin.java rename to spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/mixin/AllowSpoutServerPacksMixin.java diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientCommonPacketListenerImplAccessor.java b/spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientCommonPacketListenerImplAccessor.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientCommonPacketListenerImplAccessor.java rename to spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientCommonPacketListenerImplAccessor.java diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientCommonPacketListenerImplMixin.java b/spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientCommonPacketListenerImplMixin.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientCommonPacketListenerImplMixin.java rename to spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientCommonPacketListenerImplMixin.java diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientConfigurationPacketListenerImplMixin.java b/spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientConfigurationPacketListenerImplMixin.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientConfigurationPacketListenerImplMixin.java rename to spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientConfigurationPacketListenerImplMixin.java diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientHandshakePacketListenerImplMixin.java b/spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientHandshakePacketListenerImplMixin.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientHandshakePacketListenerImplMixin.java rename to spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientHandshakePacketListenerImplMixin.java diff --git a/spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientPacketListenerMixin.java b/spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientPacketListenerMixin.java new file mode 100644 index 00000000..71e93a8d --- /dev/null +++ b/spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientPacketListenerMixin.java @@ -0,0 +1,38 @@ +package spout.clientview.clientmod.protocol.mixin; + +import com.mojang.brigadier.CommandDispatcher; +import net.minecraft.client.multiplayer.ClientSuggestionProvider; +import net.minecraft.client.multiplayer.ClientPacketListener; +import net.minecraft.network.protocol.game.ClientboundCommandsPacket; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import spout.clientview.clientmod.command.SpoutcraftCommand; +import spout.clientview.clientmod.protocol.SpoutProtocol; + +@Mixin(ClientPacketListener.class) +public abstract class ClientPacketListenerMixin { + + @Shadow + private CommandDispatcher commands; + + @Inject(method = "clearLevel", at = @At("HEAD")) + private void removeSpoutContentBeforeClearingLevel(CallbackInfo ci) { + SpoutProtocol.onDisconnect(); + } + + @Inject(method = "handleCommands", at = @At("TAIL")) + private void registerSpoutcraftCommand(ClientboundCommandsPacket packet, CallbackInfo ci) { + SpoutcraftCommand.register(this.commands); + } + + @Inject(method = "sendCommand", at = @At("HEAD"), cancellable = true) + private void runSpoutcraftCommand(String command, CallbackInfo ci) { + if (SpoutcraftCommand.executeIfSpoutcraftCommand(command)) { + ci.cancel(); + } + } + +} diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientboundCustomQueryPacketMixin.java b/spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientboundCustomQueryPacketMixin.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientboundCustomQueryPacketMixin.java rename to spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/mixin/ClientboundCustomQueryPacketMixin.java diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/CustomPacketPayloadCodecMixin.java b/spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/mixin/CustomPacketPayloadCodecMixin.java similarity index 88% rename from spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/CustomPacketPayloadCodecMixin.java rename to spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/mixin/CustomPacketPayloadCodecMixin.java index cc0b74e4..7eeac8a8 100644 --- a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/CustomPacketPayloadCodecMixin.java +++ b/spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/mixin/CustomPacketPayloadCodecMixin.java @@ -19,7 +19,7 @@ private void findSpoutCodec( CallbackInfoReturnable> cir ) { if (ClientModCustomContentPacketPayload.TYPE.id().equals(identifier)) { - cir.setReturnValue((StreamCodec) ClientModCustomContentPacketPayload.STREAM_CODEC); + cir.setReturnValue(ClientModCustomContentPacketPayload.STREAM_CODEC); } } diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/package-info.java b/spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/mixin/package-info.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/clientview/clientmod/protocol/mixin/package-info.java rename to spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/protocol/mixin/package-info.java diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/registryidmapping/RegistryIdMappings.java b/spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/registryidmapping/RegistryIdMappings.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/clientview/clientmod/registryidmapping/RegistryIdMappings.java rename to spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/registryidmapping/RegistryIdMappings.java diff --git a/spoutcraft-fabric/src/client/java/spout/clientview/clientmod/registryidmapping/mixin/MapIdsByteBufCodecsMixin.java b/spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/registryidmapping/mixin/MapIdsByteBufCodecsMixin.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/clientview/clientmod/registryidmapping/mixin/MapIdsByteBufCodecsMixin.java rename to spoutcraft-mod/common/src/client/java/spout/clientview/clientmod/registryidmapping/mixin/MapIdsByteBufCodecsMixin.java diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/block/BlockStateRegistryIdMappings.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/block/BlockStateRegistryIdMappings.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/block/BlockStateRegistryIdMappings.java rename to spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/block/BlockStateRegistryIdMappings.java diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/block/TemporaryBlockRegistryModifier.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/block/TemporaryBlockRegistryModifier.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/block/TemporaryBlockRegistryModifier.java rename to spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/block/TemporaryBlockRegistryModifier.java diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/block/mixin/BlockCodecAccessorBlockMixin.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/block/mixin/BlockCodecAccessorBlockMixin.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/block/mixin/BlockCodecAccessorBlockMixin.java rename to spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/block/mixin/BlockCodecAccessorBlockMixin.java diff --git a/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/block/mixin/MapBlockStateRegistryIdsIdMapperMixin.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/block/mixin/MapBlockStateRegistryIdsIdMapperMixin.java new file mode 100644 index 00000000..f3b5fb57 --- /dev/null +++ b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/block/mixin/MapBlockStateRegistryIdsIdMapperMixin.java @@ -0,0 +1,22 @@ +package spout.gamecontent.datadriven.block.mixin; + +import net.minecraft.core.IdMapper; +import net.minecraft.world.level.block.Block; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; +import spout.gamecontent.datadriven.block.BlockStateRegistryIdMappings; + +@Mixin(IdMapper.class) +public abstract class MapBlockStateRegistryIdsIdMapperMixin { + + @ModifyVariable(method = "byId", at = @At("HEAD"), argsOnly = true) + private int mapBlockStateId(int id) { + IdMapper registry = (IdMapper) (Object) this; + if (registry == Block.BLOCK_STATE_REGISTRY) { + return BlockStateRegistryIdMappings.applyServerToClient(id); + } + return id; + } + +} diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/block/mixin/ReplaceBlockBehaviourPropertiesCodecMixin.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/block/mixin/ReplaceBlockBehaviourPropertiesCodecMixin.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/block/mixin/ReplaceBlockBehaviourPropertiesCodecMixin.java rename to spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/block/mixin/ReplaceBlockBehaviourPropertiesCodecMixin.java diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/block/mixin/UseFormattedBlockStateCodecStairBlockMixin.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/block/mixin/UseFormattedBlockStateCodecStairBlockMixin.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/block/mixin/UseFormattedBlockStateCodecStairBlockMixin.java rename to spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/block/mixin/UseFormattedBlockStateCodecStairBlockMixin.java diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/block/mixin/UseFormattedBlockStateCodecWeatheringCopperStairBlockMixin.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/block/mixin/UseFormattedBlockStateCodecWeatheringCopperStairBlockMixin.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/block/mixin/UseFormattedBlockStateCodecWeatheringCopperStairBlockMixin.java rename to spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/block/mixin/UseFormattedBlockStateCodecWeatheringCopperStairBlockMixin.java diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/block/subtypes/mixin/BlockBehaviourMaxVerticalOffsetAccessorBlockBehaviourMixin.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/block/subtypes/mixin/BlockBehaviourMaxVerticalOffsetAccessorBlockBehaviourMixin.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/block/subtypes/mixin/BlockBehaviourMaxVerticalOffsetAccessorBlockBehaviourMixin.java rename to spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/block/subtypes/mixin/BlockBehaviourMaxVerticalOffsetAccessorBlockBehaviourMixin.java diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/blockentity/mixin/BlockEntityTypeDataDrivenValidBlocksMixin.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/blockentity/mixin/BlockEntityTypeDataDrivenValidBlocksMixin.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/blockentity/mixin/BlockEntityTypeDataDrivenValidBlocksMixin.java rename to spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/blockentity/mixin/BlockEntityTypeDataDrivenValidBlocksMixin.java diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/blocktype/mixin/MirrorMinecraftBlockTypeRegistryMappedRegistryMixin.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/blocktype/mixin/MirrorMinecraftBlockTypeRegistryMappedRegistryMixin.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/blocktype/mixin/MirrorMinecraftBlockTypeRegistryMappedRegistryMixin.java rename to spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/blocktype/mixin/MirrorMinecraftBlockTypeRegistryMappedRegistryMixin.java diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/common/registry/codec/mixin/CacheByNameCodecMappedRegistryMixin.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/common/registry/codec/mixin/CacheByNameCodecMappedRegistryMixin.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/common/registry/codec/mixin/CacheByNameCodecMappedRegistryMixin.java rename to spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/common/registry/codec/mixin/CacheByNameCodecMappedRegistryMixin.java diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/common/registry/temporarymodification/TemporaryRegistryModifier.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/common/registry/temporarymodification/TemporaryRegistryModifier.java similarity index 92% rename from spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/common/registry/temporarymodification/TemporaryRegistryModifier.java rename to spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/common/registry/temporarymodification/TemporaryRegistryModifier.java index 2a3db759..869596fc 100644 --- a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/common/registry/temporarymodification/TemporaryRegistryModifier.java +++ b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/common/registry/temporarymodification/TemporaryRegistryModifier.java @@ -37,6 +37,7 @@ public TemporaryRegistryModifier(R registry) { this.registry = registry; } + @SuppressWarnings("unchecked") public MappedRegistryAccessor getRegistryAccessor() { return (MappedRegistryAccessor) this.registry; } @@ -125,8 +126,8 @@ public void remove(ResourceKey resourceKey, T resource) { } - private static Field allTagsField; - private static Method unboundMethod; + private static final Field allTagsField; + private static final Method unboundMethod; static { try { allTagsField = Arrays.stream(MappedRegistry.class.getDeclaredFields()) @@ -152,13 +153,18 @@ private Map, HolderSet.Named> copyFrozenTags(Map, HolderS Map, HolderSet.Named> target = new IdentityHashMap<>(); for (Map.Entry, HolderSet.Named> entry : source.entrySet()) { HolderSet.Named holderSet = this.getRegistryAccessor().callCreateTag(entry.getValue().key()); - @Nullable List> contents = ((HolderSetNamedAccessor) entry.getValue()).getContents(); + List> contents = this.getHolderSetAccessor(entry.getValue()).getContents(); if (contents != null) { - ((HolderSetNamedAccessor) holderSet).callBind(new ArrayList<>(contents)); + this.getHolderSetAccessor(holderSet).callBind(new ArrayList<>(contents)); } target.put(entry.getKey(), holderSet); } return target; } + @SuppressWarnings("unchecked") + private HolderSetNamedAccessor getHolderSetAccessor(HolderSet.Named holderSet) { + return (HolderSetNamedAccessor) holderSet; + } + } diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/common/registry/temporarymodification/TemporaryRegistryModifiers.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/common/registry/temporarymodification/TemporaryRegistryModifiers.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/common/registry/temporarymodification/TemporaryRegistryModifiers.java rename to spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/common/registry/temporarymodification/TemporaryRegistryModifiers.java diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/common/registry/temporarymodification/mixin/HolderSetNamedAccessor.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/common/registry/temporarymodification/mixin/HolderSetNamedAccessor.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/common/registry/temporarymodification/mixin/HolderSetNamedAccessor.java rename to spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/common/registry/temporarymodification/mixin/HolderSetNamedAccessor.java diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/common/registry/temporarymodification/mixin/MappedRegistryAccessor.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/common/registry/temporarymodification/mixin/MappedRegistryAccessor.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/common/registry/temporarymodification/mixin/MappedRegistryAccessor.java rename to spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/common/registry/temporarymodification/mixin/MappedRegistryAccessor.java diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/item/TemporaryItemRegistryModifier.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/item/TemporaryItemRegistryModifier.java similarity index 93% rename from spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/item/TemporaryItemRegistryModifier.java rename to spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/item/TemporaryItemRegistryModifier.java index a23f7bcd..5b8c49b4 100644 --- a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/item/TemporaryItemRegistryModifier.java +++ b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/item/TemporaryItemRegistryModifier.java @@ -48,7 +48,10 @@ public void removeWhileUnfrozen(List, Item>> resources) { private static ResourceKey getInitializerResourceKey(Object initializer) { if (initializerResourceKeyField == null) { - initializerResourceKeyField = Arrays.stream(initializer.getClass().getDeclaredFields()).filter(field -> field.getType() == ResourceKey.class).findFirst().get(); + initializerResourceKeyField = Arrays.stream(initializer.getClass().getDeclaredFields()) + .filter(field -> field.getType() == ResourceKey.class) + .findFirst() + .orElseThrow(); initializerResourceKeyField.setAccessible(true); } try { diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/item/mixin/DataComponentInitializersAccessor.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/item/mixin/DataComponentInitializersAccessor.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/item/mixin/DataComponentInitializersAccessor.java rename to spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/item/mixin/DataComponentInitializersAccessor.java diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemPropertiesSerializationDecoratorItemPropertiesMixin.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemPropertiesSerializationDecoratorItemPropertiesMixin.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemPropertiesSerializationDecoratorItemPropertiesMixin.java rename to spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemPropertiesSerializationDecoratorItemPropertiesMixin.java diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemTypeDecoratorBlockItemMixin.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemTypeDecoratorBlockItemMixin.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemTypeDecoratorBlockItemMixin.java rename to spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemTypeDecoratorBlockItemMixin.java diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemTypeDecoratorDoubleHighBlockItemMixin.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemTypeDecoratorDoubleHighBlockItemMixin.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemTypeDecoratorDoubleHighBlockItemMixin.java rename to spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemTypeDecoratorDoubleHighBlockItemMixin.java diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemTypeDecoratorEggItemMixin.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemTypeDecoratorEggItemMixin.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemTypeDecoratorEggItemMixin.java rename to spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemTypeDecoratorEggItemMixin.java diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemTypeDecoratorItemMixin.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemTypeDecoratorItemMixin.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemTypeDecoratorItemMixin.java rename to spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/item/mixin/ItemTypeDecoratorItemMixin.java diff --git a/spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/mixin/IncludeSpoutBootstrapBuiltInRegistriesMixin.java b/spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/mixin/IncludeSpoutBootstrapBuiltInRegistriesMixin.java similarity index 100% rename from spoutcraft-fabric/src/client/java/spout/gamecontent/datadriven/mixin/IncludeSpoutBootstrapBuiltInRegistriesMixin.java rename to spoutcraft-mod/common/src/client/java/spout/gamecontent/datadriven/mixin/IncludeSpoutBootstrapBuiltInRegistriesMixin.java diff --git a/spoutcraft-fabric/src/client/resources/spoutcraft.spout.clientui.resourcepack.loadingoverlay.mixins.json b/spoutcraft-mod/common/src/client/resources/spoutcraft.spout.clientui.resourcepack.loadingoverlay.mixins.json similarity index 64% rename from spoutcraft-fabric/src/client/resources/spoutcraft.spout.clientui.resourcepack.loadingoverlay.mixins.json rename to spoutcraft-mod/common/src/client/resources/spoutcraft.spout.clientui.resourcepack.loadingoverlay.mixins.json index e943836b..14cee7cd 100644 --- a/spoutcraft-fabric/src/client/resources/spoutcraft.spout.clientui.resourcepack.loadingoverlay.mixins.json +++ b/spoutcraft-mod/common/src/client/resources/spoutcraft.spout.clientui.resourcepack.loadingoverlay.mixins.json @@ -5,9 +5,7 @@ "client": [ "ChangePositionsOfSpoutLogoLoadingOverlayMixin", "LoadingOverlayLogoLocationAccessor", - "ReplaceColorsAndSizesOverlayMixin", - "ReplaceLogoWhenRegisteringTexturesLoadingOverlayMixin", - "ReplaceMojangLogoAfterTexturesRegisteredMixin" + "ReplaceColorsAndSizesOverlayMixin" ], "injectors": { "defaultRequire": 1 diff --git a/spoutcraft-fabric/src/client/resources/spoutcraft.spout.clientui.resourcepack.toast.mixins.json b/spoutcraft-mod/common/src/client/resources/spoutcraft.spout.clientui.resourcepack.toast.mixins.json similarity index 100% rename from spoutcraft-fabric/src/client/resources/spoutcraft.spout.clientui.resourcepack.toast.mixins.json rename to spoutcraft-mod/common/src/client/resources/spoutcraft.spout.clientui.resourcepack.toast.mixins.json diff --git a/spoutcraft-fabric/src/client/resources/spoutcraft.spout.clientview.clientmod.protocol.mixins.json b/spoutcraft-mod/common/src/client/resources/spoutcraft.spout.clientview.clientmod.protocol.mixins.json similarity index 100% rename from spoutcraft-fabric/src/client/resources/spoutcraft.spout.clientview.clientmod.protocol.mixins.json rename to spoutcraft-mod/common/src/client/resources/spoutcraft.spout.clientview.clientmod.protocol.mixins.json diff --git a/spoutcraft-fabric/src/client/resources/spoutcraft.spout.clientview.clientmod.registryidmapping.mixins.json b/spoutcraft-mod/common/src/client/resources/spoutcraft.spout.clientview.clientmod.registryidmapping.mixins.json similarity index 100% rename from spoutcraft-fabric/src/client/resources/spoutcraft.spout.clientview.clientmod.registryidmapping.mixins.json rename to spoutcraft-mod/common/src/client/resources/spoutcraft.spout.clientview.clientmod.registryidmapping.mixins.json diff --git a/spoutcraft-fabric/src/client/resources/spoutcraft.spout.gamecontent.datadriven.block.mixins.json b/spoutcraft-mod/common/src/client/resources/spoutcraft.spout.gamecontent.datadriven.block.mixins.json similarity index 89% rename from spoutcraft-fabric/src/client/resources/spoutcraft.spout.gamecontent.datadriven.block.mixins.json rename to spoutcraft-mod/common/src/client/resources/spoutcraft.spout.gamecontent.datadriven.block.mixins.json index 898a0d1a..03df290b 100644 --- a/spoutcraft-fabric/src/client/resources/spoutcraft.spout.gamecontent.datadriven.block.mixins.json +++ b/spoutcraft-mod/common/src/client/resources/spoutcraft.spout.gamecontent.datadriven.block.mixins.json @@ -4,7 +4,7 @@ "compatibilityLevel": "JAVA_25", "mixins": [ "BlockCodecAccessorBlockMixin", - "MapBlockStateRegistryIdsBlockMixin", + "MapBlockStateRegistryIdsIdMapperMixin", "ReplaceBlockBehaviourPropertiesCodecMixin", "UseFormattedBlockStateCodecStairBlockMixin", "UseFormattedBlockStateCodecWeatheringCopperStairBlockMixin" diff --git a/spoutcraft-fabric/src/client/resources/spoutcraft.spout.gamecontent.datadriven.block.subtypes.mixins.json b/spoutcraft-mod/common/src/client/resources/spoutcraft.spout.gamecontent.datadriven.block.subtypes.mixins.json similarity index 100% rename from spoutcraft-fabric/src/client/resources/spoutcraft.spout.gamecontent.datadriven.block.subtypes.mixins.json rename to spoutcraft-mod/common/src/client/resources/spoutcraft.spout.gamecontent.datadriven.block.subtypes.mixins.json diff --git a/spoutcraft-fabric/src/client/resources/spoutcraft.spout.gamecontent.datadriven.blockentity.mixins.json b/spoutcraft-mod/common/src/client/resources/spoutcraft.spout.gamecontent.datadriven.blockentity.mixins.json similarity index 100% rename from spoutcraft-fabric/src/client/resources/spoutcraft.spout.gamecontent.datadriven.blockentity.mixins.json rename to spoutcraft-mod/common/src/client/resources/spoutcraft.spout.gamecontent.datadriven.blockentity.mixins.json diff --git a/spoutcraft-fabric/src/client/resources/spoutcraft.spout.gamecontent.datadriven.blocktype.mixins.json b/spoutcraft-mod/common/src/client/resources/spoutcraft.spout.gamecontent.datadriven.blocktype.mixins.json similarity index 100% rename from spoutcraft-fabric/src/client/resources/spoutcraft.spout.gamecontent.datadriven.blocktype.mixins.json rename to spoutcraft-mod/common/src/client/resources/spoutcraft.spout.gamecontent.datadriven.blocktype.mixins.json diff --git a/spoutcraft-fabric/src/client/resources/spoutcraft.spout.gamecontent.datadriven.common.registry.codec.mixins.json b/spoutcraft-mod/common/src/client/resources/spoutcraft.spout.gamecontent.datadriven.common.registry.codec.mixins.json similarity index 100% rename from spoutcraft-fabric/src/client/resources/spoutcraft.spout.gamecontent.datadriven.common.registry.codec.mixins.json rename to spoutcraft-mod/common/src/client/resources/spoutcraft.spout.gamecontent.datadriven.common.registry.codec.mixins.json diff --git a/spoutcraft-fabric/src/client/resources/spoutcraft.spout.gamecontent.datadriven.common.registry.temporarymodification.mixins.json b/spoutcraft-mod/common/src/client/resources/spoutcraft.spout.gamecontent.datadriven.common.registry.temporarymodification.mixins.json similarity index 100% rename from spoutcraft-fabric/src/client/resources/spoutcraft.spout.gamecontent.datadriven.common.registry.temporarymodification.mixins.json rename to spoutcraft-mod/common/src/client/resources/spoutcraft.spout.gamecontent.datadriven.common.registry.temporarymodification.mixins.json diff --git a/spoutcraft-fabric/src/client/resources/spoutcraft.spout.gamecontent.datadriven.item.mixins.json b/spoutcraft-mod/common/src/client/resources/spoutcraft.spout.gamecontent.datadriven.item.mixins.json similarity index 100% rename from spoutcraft-fabric/src/client/resources/spoutcraft.spout.gamecontent.datadriven.item.mixins.json rename to spoutcraft-mod/common/src/client/resources/spoutcraft.spout.gamecontent.datadriven.item.mixins.json diff --git a/spoutcraft-fabric/src/client/resources/spoutcraft.spout.gamecontent.datadriven.mixins.json b/spoutcraft-mod/common/src/client/resources/spoutcraft.spout.gamecontent.datadriven.mixins.json similarity index 100% rename from spoutcraft-fabric/src/client/resources/spoutcraft.spout.gamecontent.datadriven.mixins.json rename to spoutcraft-mod/common/src/client/resources/spoutcraft.spout.gamecontent.datadriven.mixins.json diff --git a/spoutcraft-fabric/build.gradle.kts b/spoutcraft-mod/fabric/build.gradle.kts similarity index 81% rename from spoutcraft-fabric/build.gradle.kts rename to spoutcraft-mod/fabric/build.gradle.kts index 48bece3e..a8af2bbf 100644 --- a/spoutcraft-fabric/build.gradle.kts +++ b/spoutcraft-mod/fabric/build.gradle.kts @@ -7,7 +7,7 @@ version = providers.gradleProperty("mod_version").get() group = providers.gradleProperty("maven_group").get() base { - archivesName = providers.gradleProperty("archives_base_name") + archivesName = providers.gradleProperty("archives_base_name").map { "$it-fabric" } } repositories { @@ -32,12 +32,14 @@ loom { } sourceSets.getByName("client") { - java.srcDir("../common-src/src/main/java") - java.srcDir("../common-minecraft-src/src/main/java") - java.srcDir("../common-fabric-src/src/main/java") - resources.srcDir("../common-src/src/main/resources") - resources.srcDir("../common-minecraft-src/src/main/resources") - resources.srcDir("../common-fabric-src/src/main/resources") + java.srcDir("../common/src/client/java") + java.srcDir("../../common-src/src/main/java") + java.srcDir("../../common-minecraft-src/src/main/java") + java.srcDir("../../common-fabric-src/src/main/java") + resources.srcDir("../common/src/client/resources") + resources.srcDir("../../common-src/src/main/resources") + resources.srcDir("../../common-minecraft-src/src/main/resources") + resources.srcDir("../../common-fabric-src/src/main/resources") } dependencies { @@ -77,7 +79,7 @@ tasks.jar { inputs.property("archivesName", archivesName) inputs.property("projectName", projectName) - from("LICENSE.md") { + from(rootProject.file("../LICENSE.md")) { rename { "${it}_${projectName}" } } diff --git a/spoutcraft-fabric/src/main/resources/fabric.mod.json b/spoutcraft-mod/fabric/src/main/resources/fabric.mod.json similarity index 100% rename from spoutcraft-fabric/src/main/resources/fabric.mod.json rename to spoutcraft-mod/fabric/src/main/resources/fabric.mod.json diff --git a/spoutcraft-fabric/src/main/resources/spoutcraft.classtweaker b/spoutcraft-mod/fabric/src/main/resources/spoutcraft.classtweaker similarity index 98% rename from spoutcraft-fabric/src/main/resources/spoutcraft.classtweaker rename to spoutcraft-mod/fabric/src/main/resources/spoutcraft.classtweaker index 0ff51edc..9abb16d0 100644 --- a/spoutcraft-fabric/src/main/resources/spoutcraft.classtweaker +++ b/spoutcraft-mod/fabric/src/main/resources/spoutcraft.classtweaker @@ -47,4 +47,3 @@ accessible method net/minecraft/world/level/block/Blocks never (Lnet/minecraft/w accessible method net/minecraft/world/level/block/Blocks ocelotOrParrot (Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/EntityType;)Ljava/lang/Boolean; accessible method net/minecraft/world/level/block/StairBlock (Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V accessible method net/minecraft/world/level/block/state/BlockBehaviour propertiesCodec ()Lcom/mojang/serialization/codecs/RecordCodecBuilder; -transitive-extendable method net/minecraft/core/IdMapper byId (I)Ljava/lang/Object; diff --git a/spoutcraft-fabric/gradle.properties b/spoutcraft-mod/gradle.properties similarity index 82% rename from spoutcraft-fabric/gradle.properties rename to spoutcraft-mod/gradle.properties index 9f68b82a..b5c5cfc8 100644 --- a/spoutcraft-fabric/gradle.properties +++ b/spoutcraft-mod/gradle.properties @@ -11,7 +11,11 @@ minecraft_version=26.1.2 loader_version=0.19.2 loom_version=1.16-SNAPSHOT +# NeoForge Properties +neoforge_version=26.1.2.76 +moddevgradle_version=2.0.141 + # Mod Properties mod_version=1.15-SNAPSHOT -maven_group=spout.client.fabric +maven_group=spout.client archives_base_name=spoutcraft diff --git a/spoutcraft-mod/neoforge/build.gradle.kts b/spoutcraft-mod/neoforge/build.gradle.kts new file mode 100644 index 00000000..a85e923f --- /dev/null +++ b/spoutcraft-mod/neoforge/build.gradle.kts @@ -0,0 +1,80 @@ +plugins { + id("net.neoforged.moddev") + `maven-publish` +} + +version = providers.gradleProperty("mod_version").get() +group = providers.gradleProperty("maven_group").get() + +base { + archivesName = providers.gradleProperty("archives_base_name").map { "$it-neoforge" } +} + +repositories { + mavenCentral() +} + +neoForge { + version = providers.gradleProperty("neoforge_version").get() + + accessTransformers { + file("src/main/resources/META-INF/accesstransformer.cfg") + } + + mods { + register("spoutcraft_mod") { + sourceSet(sourceSets.main.get()) + } + } +} + +sourceSets.main { + java.srcDir("../common/src/client/java") + java.srcDir("../../common-src/src/main/java") + java.srcDir("../../common-minecraft-src/src/main/java") + java.srcDir("../../common-fabric-src/src/main/java") + resources.srcDir("../common/src/client/resources") + resources.srcDir("../../common-src/src/main/resources") + resources.srcDir("../../common-minecraft-src/src/main/resources") + resources.srcDir("../../common-fabric-src/src/main/resources") +} + +tasks.processResources { + val version = project.version + inputs.property("version", version) + + filesMatching("META-INF/neoforge.mods.toml") { + expand("version" to version) + } +} + +tasks.withType().configureEach { + options.release = 25 +} + +java { + withSourcesJar() + + sourceCompatibility = JavaVersion.VERSION_25 + targetCompatibility = JavaVersion.VERSION_25 +} + +tasks.jar { + val archivesName = base.archivesName + val projectName = project.name + inputs.property("archivesName", archivesName) + inputs.property("projectName", projectName) + + from(rootProject.file("../LICENSE.md")) { + rename { "${it}_${projectName}" } + } +} + +publishing { + publications { + register("mavenJava") { + artifactId = base.archivesName.get() + from(components["java"]) + } + } +} diff --git a/spoutcraft-mod/neoforge/src/main/java/spout/neoforge/SpoutcraftNeoForgeMod.java b/spoutcraft-mod/neoforge/src/main/java/spout/neoforge/SpoutcraftNeoForgeMod.java new file mode 100644 index 00000000..93eee3fe --- /dev/null +++ b/spoutcraft-mod/neoforge/src/main/java/spout/neoforge/SpoutcraftNeoForgeMod.java @@ -0,0 +1,25 @@ +package spout.neoforge; + +import net.neoforged.bus.api.IEventBus; +import net.neoforged.fml.common.Mod; +import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; +import net.neoforged.neoforge.network.registration.HandlerThread; +import spout.clientview.clientmod.protocol.ClientModCustomContentPacketPayload; +import spout.clientview.clientmod.protocol.ClientModCustomContentReceiving; + +@Mod("spoutcraft_mod") +public final class SpoutcraftNeoForgeMod { + + public SpoutcraftNeoForgeMod(IEventBus modEventBus) { + modEventBus.addListener(this::registerPayloadHandlers); + } + + private void registerPayloadHandlers(RegisterPayloadHandlersEvent event) { + event.registrar("1").optional().executesOn(HandlerThread.NETWORK).commonToClient( + ClientModCustomContentPacketPayload.TYPE, + ClientModCustomContentPacketPayload.STREAM_CODEC, + (payload, context) -> ClientModCustomContentReceiving.handlePacket(payload) + ); + } + +} diff --git a/spoutcraft-mod/neoforge/src/main/resources/META-INF/accesstransformer.cfg b/spoutcraft-mod/neoforge/src/main/resources/META-INF/accesstransformer.cfg new file mode 100644 index 00000000..8b26dba6 --- /dev/null +++ b/spoutcraft-mod/neoforge/src/main/resources/META-INF/accesstransformer.cfg @@ -0,0 +1,47 @@ +public net.minecraft.core.registries.BuiltInRegistries$RegistryBootstrap +public net.minecraft.world.item.Item$Properties componentInitializer +public net.minecraft.world.item.Item$Properties id +public net.minecraft.world.item.Item$Properties requiredFeatures +public net.minecraft.world.flag.FeatureFlagRegistry names +public net.minecraft.world.level.block.Blocks NOT_EXTENDED_PISTON +public net.minecraft.world.level.block.Blocks NOT_CLOSED_SHULKER +public net.minecraft.world.level.block.StairBlock baseState +public net.minecraft.world.level.block.state.BlockBehaviour$Properties canOcclude +public net.minecraft.world.level.block.state.BlockBehaviour$Properties destroyTime +public net.minecraft.world.level.block.state.BlockBehaviour$Properties dynamicShape +public net.minecraft.world.level.block.state.BlockBehaviour$Properties emissiveRendering +public net.minecraft.world.level.block.state.BlockBehaviour$Properties explosionResistance +public net.minecraft.world.level.block.state.BlockBehaviour$Properties friction +public net.minecraft.world.level.block.state.BlockBehaviour$Properties forceSolidOff +public net.minecraft.world.level.block.state.BlockBehaviour$Properties forceSolidOn +public net.minecraft.world.level.block.state.BlockBehaviour$Properties hasCollision +public net.minecraft.world.level.block.state.BlockBehaviour$Properties id +public net.minecraft.world.level.block.state.BlockBehaviour$Properties ignitedByLava +public net.minecraft.world.level.block.state.BlockBehaviour$Properties instrument +public net.minecraft.world.level.block.state.BlockBehaviour$Properties isAir +public net.minecraft.world.level.block.state.BlockBehaviour$Properties isRandomlyTicking +public net.minecraft.world.level.block.state.BlockBehaviour$Properties isRedstoneConductor +public net.minecraft.world.level.block.state.BlockBehaviour$Properties isSuffocating +public net.minecraft.world.level.block.state.BlockBehaviour$Properties isViewBlocking +public net.minecraft.world.level.block.state.BlockBehaviour$Properties jumpFactor +public net.minecraft.world.level.block.state.BlockBehaviour$Properties lightEmission +public net.minecraft.world.level.block.state.BlockBehaviour$Properties liquid +public net.minecraft.world.level.block.state.BlockBehaviour$Properties mapColor +public net.minecraft.world.level.block.state.BlockBehaviour$Properties offsetFunction +public net.minecraft.world.level.block.state.BlockBehaviour$Properties postProcess +public net.minecraft.world.level.block.state.BlockBehaviour$Properties pushReaction +public net.minecraft.world.level.block.state.BlockBehaviour$Properties replaceable +public net.minecraft.world.level.block.state.BlockBehaviour$Properties requiredFeatures +public net.minecraft.world.level.block.state.BlockBehaviour$Properties requiresCorrectToolForDrops +public net.minecraft.world.level.block.state.BlockBehaviour$Properties soundType +public net.minecraft.world.level.block.state.BlockBehaviour$Properties spawnTerrainParticles +public net.minecraft.world.level.block.state.BlockBehaviour$Properties speedFactor +public net.minecraft.core.registries.BuiltInRegistries internalRegister(Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/core/WritableRegistry;Lnet/minecraft/core/registries/BuiltInRegistries$RegistryBootstrap;)Lnet/minecraft/core/WritableRegistry; +public net.minecraft.core.registries.BuiltInRegistries registerSimple(Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/core/registries/BuiltInRegistries$RegistryBootstrap;)Lnet/minecraft/core/Registry; +public net.minecraft.world.level.block.Blocks always(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Z +public net.minecraft.world.level.block.Blocks always(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/EntityType;)Ljava/lang/Boolean; +public net.minecraft.world.level.block.Blocks never(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Z +public net.minecraft.world.level.block.Blocks never(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/EntityType;)Ljava/lang/Boolean; +public net.minecraft.world.level.block.Blocks ocelotOrParrot(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/EntityType;)Ljava/lang/Boolean; +public net.minecraft.world.level.block.StairBlock (Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.state.BlockBehaviour propertiesCodec()Lcom/mojang/serialization/codecs/RecordCodecBuilder; diff --git a/spoutcraft-mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/spoutcraft-mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml new file mode 100644 index 00000000..85718a0b --- /dev/null +++ b/spoutcraft-mod/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -0,0 +1,62 @@ +modLoader = "javafml" +loaderVersion = "[5,)" +license = "See the included LICENSE.txt" +issueTrackerURL = "https://github.com/ModernSpout/Spout/issues" + +[[mods]] +modId = "spoutcraft_mod" +version = "${version}" +displayName = "Spoutcraft" +logoFile = "assets/spout/icon.png" +description = "Automatically downloads and installs modded content when joining Spout servers" +authors = "Martijn Muijsers, Spoutcraft authors and contributors" + +[[dependencies."spoutcraft_mod"]] +modId = "neoforge" +type = "required" +versionRange = "[26.1.2,)" +ordering = "NONE" +side = "CLIENT" + +[[dependencies."spoutcraft_mod"]] +modId = "minecraft" +type = "required" +versionRange = "[26.1.2,26.2)" +ordering = "NONE" +side = "CLIENT" + +[[mixins]] +config = "spoutcraft.spout.clientui.resourcepack.loadingoverlay.mixins.json" + +[[mixins]] +config = "spoutcraft.spout.clientui.resourcepack.toast.mixins.json" + +[[mixins]] +config = "spoutcraft.spout.clientview.clientmod.protocol.mixins.json" + +[[mixins]] +config = "spoutcraft.spout.clientview.clientmod.registryidmapping.mixins.json" + +[[mixins]] +config = "spoutcraft.spout.gamecontent.datadriven.block.mixins.json" + +[[mixins]] +config = "spoutcraft.spout.gamecontent.datadriven.block.subtypes.mixins.json" + +[[mixins]] +config = "spoutcraft.spout.gamecontent.datadriven.blockentity.mixins.json" + +[[mixins]] +config = "spoutcraft.spout.gamecontent.datadriven.blocktype.mixins.json" + +[[mixins]] +config = "spoutcraft.spout.gamecontent.datadriven.common.registry.codec.mixins.json" + +[[mixins]] +config = "spoutcraft.spout.gamecontent.datadriven.common.registry.temporarymodification.mixins.json" + +[[mixins]] +config = "spoutcraft.spout.gamecontent.datadriven.item.mixins.json" + +[[mixins]] +config = "spoutcraft.spout.gamecontent.datadriven.mixins.json" diff --git a/spoutcraft-fabric/settings.gradle.kts b/spoutcraft-mod/settings.gradle.kts similarity index 58% rename from spoutcraft-fabric/settings.gradle.kts rename to spoutcraft-mod/settings.gradle.kts index c2e4278a..c1f0a49e 100644 --- a/spoutcraft-fabric/settings.gradle.kts +++ b/spoutcraft-mod/settings.gradle.kts @@ -4,13 +4,21 @@ pluginManagement { name = "Fabric" url = uri("https://maven.fabricmc.net/") } + maven { + name = "NeoForge" + url = uri("https://maven.neoforged.net/releases/") + } mavenCentral() gradlePluginPortal() } plugins { id("net.fabricmc.fabric-loom") version providers.gradleProperty("loom_version") + id("net.neoforged.moddev") version providers.gradleProperty("moddevgradle_version") } } rootProject.name = "spoutcraft-mod" + +include("fabric") +include("neoforge")