diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 0000000..709ebe4 --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,30 @@ +name: Build + +on: [pull_request] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Java + uses: actions/setup-java@v4 + with: + java-version: 21 + distribution: temurin + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v3 + + - name: Build with Gradle + shell: bash + run: ./gradlew build + + - name: Upload Build Artifacts + uses: actions/upload-artifact@v4 + with: + name: jar + path: build/libs/* \ No newline at end of file diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..34b1ab0 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,34 @@ +name: Release + +on: [release, workflow_dispatch] + +jobs: + build: + runs-on: ubuntu-latest + + permissions: + contents: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Java + uses: actions/setup-java@v4 + with: + java-version: 21 + distribution: temurin + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v3 + + - name: Build with Gradle + shell: bash + run: ./gradlew build + + - uses: Kir-Antipov/mc-publish@v3.3 + with: + modrinth-id: Xv9MHBa1 + modrinth-token: ${{ secrets.MODRINTH_TOKEN }} + + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/build.gradle.kts b/build.gradle.kts index 755c895..228ef75 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -java.sourceCompatibility = JavaVersion.VERSION_1_8 -java.targetCompatibility = JavaVersion.VERSION_1_8 +java.sourceCompatibility = JavaVersion.VERSION_21 +java.targetCompatibility = JavaVersion.VERSION_21 plugins { id("fabric-loom") @@ -30,10 +30,6 @@ tasks.named("processResources") { } } -tasks.withType { - kotlinOptions.jvmTarget = "1.8" -} - tasks.withType { from("LICENSE") } diff --git a/gradle.properties b/gradle.properties index e25937f..d59e3ec 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,12 +1,12 @@ kotlin.code.style=official org.gradle.jvmargs=-Xmx1G -version=3.1.0+1.20.2 +version=3.1.0+1.20.6 # Versions (https://fabricmc.net/develop) -minecraft=1.20.2 -yarn=1.20.2+build.4 -loader=0.14.23 +minecraft=1.20.6 +yarn=1.20.6+build.1 +loader=0.15.11 -fabric_api=0.90.0+1.20.2 -fabric_kotlin=1.10.10+kotlin.1.9.10 \ No newline at end of file +fabric_api=0.98.0+1.20.6 +fabric_kotlin=1.10.20+kotlin.1.9.24 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 62f495d..b82aa23 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/settings.gradle.kts b/settings.gradle.kts index 02d0777..94af941 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,7 +5,7 @@ pluginManagement { } plugins { - id("fabric-loom") version "1.3-SNAPSHOT" - kotlin("jvm") version "1.9.10" + id("fabric-loom") version "1.6-SNAPSHOT" + kotlin("jvm") version "1.9.24" } } diff --git a/src/main/java/dev/auxves/vibes/mixin/BlockMixin.java b/src/main/java/dev/auxves/vibes/mixin/BlockMixin.java index 03412e5..ec6aea9 100644 --- a/src/main/java/dev/auxves/vibes/mixin/BlockMixin.java +++ b/src/main/java/dev/auxves/vibes/mixin/BlockMixin.java @@ -2,11 +2,19 @@ import dev.auxves.vibes.server.BridgesKt; import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.component.DataComponentTypes; import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; 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.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(Block.class) class BlockMixin { @@ -15,7 +23,13 @@ class BlockMixin { at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;spawnEntity(Lnet/minecraft/entity/Entity;)Z") ) private static boolean onSpawnEntity(World world, Entity entity) { - BridgesKt.onBreakShulkerBox(entity); + BridgesKt.onBreak(entity); return world.spawnEntity(entity); } + + @Inject(method = "onPlaced", at = @At("HEAD")) + private void onPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack, CallbackInfo ci) { + BlockEntity entity = world.getBlockEntity(pos); + if (entity != null && itemStack.contains(DataComponentTypes.CONTAINER)) BridgesKt.changePosition(itemStack, entity); + } } diff --git a/src/main/java/dev/auxves/vibes/mixin/ShulkerBoxBlockMixin.java b/src/main/java/dev/auxves/vibes/mixin/ShulkerBoxBlockMixin.java deleted file mode 100644 index 85dac58..0000000 --- a/src/main/java/dev/auxves/vibes/mixin/ShulkerBoxBlockMixin.java +++ /dev/null @@ -1,23 +0,0 @@ -package dev.auxves.vibes.mixin; - -import dev.auxves.vibes.server.BridgesKt; -import net.minecraft.block.BlockState; -import net.minecraft.block.ShulkerBoxBlock; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; -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(ShulkerBoxBlock.class) -class ShulkerBoxBlockMixin { - @Inject(method = "onPlaced", at = @At("HEAD")) - private void onPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack, CallbackInfo ci) { - BlockEntity entity = world.getBlockEntity(pos); - if (entity != null) BridgesKt.changePosition(itemStack, entity); - } -} diff --git a/src/main/kotlin/dev/auxves/vibes/Entrypoint.kt b/src/main/kotlin/dev/auxves/vibes/Entrypoint.kt index 41b3dd6..a544965 100644 --- a/src/main/kotlin/dev/auxves/vibes/Entrypoint.kt +++ b/src/main/kotlin/dev/auxves/vibes/Entrypoint.kt @@ -1,7 +1,9 @@ package dev.auxves.vibes import dev.auxves.vibes.item.Vibe +import dev.auxves.vibes.network.initNetwork import dev.auxves.vibes.server.initServer +import dev.auxves.vibes.util.DataComponents import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents import net.minecraft.item.ItemGroups import net.minecraft.registry.Registries @@ -14,11 +16,15 @@ object Vibes { @Suppress("unused") fun init() { + Registry.register(Registries.DATA_COMPONENT_TYPE, Vibes.id("uuid"), DataComponents.UUID) + Registry.register(Registries.DATA_COMPONENT_TYPE, Vibes.id("disc"), DataComponents.DISC) + Registry.register(Registries.ITEM, Vibe.id, Vibe) ItemGroupEvents.modifyEntriesEvent(ItemGroups.TOOLS).register { it.add(Vibe) } + initNetwork() initServer() } diff --git a/src/main/kotlin/dev/auxves/vibes/client/Client.kt b/src/main/kotlin/dev/auxves/vibes/client/Client.kt index 221e943..2ab8f6a 100644 --- a/src/main/kotlin/dev/auxves/vibes/client/Client.kt +++ b/src/main/kotlin/dev/auxves/vibes/client/Client.kt @@ -2,11 +2,12 @@ package dev.auxves.vibes.client import dev.auxves.vibes.mixin.SoundManagerAccessor import dev.auxves.vibes.mixin.SoundSystemAccessor -import dev.auxves.vibes.network.packet.* +import dev.auxves.vibes.network.payloads.* import dev.auxves.vibes.sound.BlockPositionProvider import dev.auxves.vibes.sound.EntityPositionProvider import dev.auxves.vibes.sound.VibeInstance import kotlinx.coroutines.* +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking import net.minecraft.client.MinecraftClient import net.minecraft.sound.SoundEvent import java.util.* @@ -33,19 +34,19 @@ fun init() { soundSystem.sources } - register { data -> + ClientPlayNetworking.registerGlobalReceiver(Play.ID) { data, _ -> stop(data.uuid) - val entity = getEntity(data.player) ?: return@register + val entity = getEntity(data.player) ?: return@registerGlobalReceiver val instance = VibeInstance(EntityPositionProvider(entity), SoundEvent.of(data.sound)) instances[data.uuid] = instance client.soundManager.play(instance) } - register { data -> stop(data.uuid) } + ClientPlayNetworking.registerGlobalReceiver(Stop.ID) { data, _ -> stop(data.uuid) } - register { data -> + ClientPlayNetworking.registerGlobalReceiver(ChangePositionEntity.ID) { data, _ -> instances[data.uuid]?.let { scope.launch { delay(100) @@ -55,13 +56,13 @@ fun init() { } } - register { data -> + ClientPlayNetworking.registerGlobalReceiver(ChangePositionBlock.ID) { data, _ -> instances[data.uuid]?.let { it.position = BlockPositionProvider(data.blockPos) } } - register { data -> + ClientPlayNetworking.registerGlobalReceiver(ChangeDistance.ID) { data, _ -> instances[data.uuid]?.let { sources[it]?.run { source -> source.setAttenuation(data.distance) } } diff --git a/src/main/kotlin/dev/auxves/vibes/item/Vibe.kt b/src/main/kotlin/dev/auxves/vibes/item/Vibe.kt index 85f9bfe..1c36c06 100644 --- a/src/main/kotlin/dev/auxves/vibes/item/Vibe.kt +++ b/src/main/kotlin/dev/auxves/vibes/item/Vibe.kt @@ -1,15 +1,14 @@ package dev.auxves.vibes.item import dev.auxves.vibes.Vibes -import dev.auxves.vibes.network.packet.* -import dev.auxves.vibes.util.disc -import dev.auxves.vibes.util.isPlaying -import dev.auxves.vibes.util.uuid -import net.fabricmc.fabric.api.item.v1.FabricItemSettings +import dev.auxves.vibes.network.sendAll +import dev.auxves.vibes.network.payloads.* +import dev.auxves.vibes.util.* +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking import net.minecraft.block.Blocks import net.minecraft.block.JukeboxBlock import net.minecraft.block.entity.JukeboxBlockEntity -import net.minecraft.client.item.TooltipContext +import net.minecraft.client.item.TooltipType import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.* import net.minecraft.screen.slot.Slot @@ -18,18 +17,22 @@ import net.minecraft.util.ActionResult import net.minecraft.util.ClickType import net.minecraft.util.Formatting import net.minecraft.util.Rarity -import net.minecraft.world.World import net.minecraft.world.event.GameEvent -private val settings = FabricItemSettings() +private val settings = Item.Settings() .rarity(Rarity.RARE) .maxCount(1) object Vibe : Item(settings) { val id = Vibes.id("vibe") - override fun appendTooltip(stack: ItemStack, world: World?, tooltip: MutableList, context: TooltipContext) { - stack.disc?.item?.appendTooltip(stack, world, tooltip, context) + override fun appendTooltip( + stack: ItemStack, + context: TooltipContext, + tooltip: MutableList, + type: TooltipType + ) { + stack.disc?.item?.appendTooltip(stack, context, tooltip, type) val helpKey = if (stack.disc == null) ".play" else ".stop" tooltip.add(Text.translatable(translationKey + helpKey).formatted(Formatting.DARK_GRAY)) @@ -38,7 +41,7 @@ object Vibe : Item(settings) { override fun onStackClicked(stack: ItemStack, slot: Slot, clickType: ClickType, player: PlayerEntity): Boolean { if (clickType != ClickType.RIGHT) return false - val packet = when (val item = slot.stack.item) { + val payload = when (val item = slot.stack.item) { is MusicDiscItem -> { val disc = stack.disc ?: ItemStack.EMPTY stack.disc = slot.stack @@ -59,7 +62,7 @@ object Vibe : Item(settings) { else -> return false } - if (player.world.isClient) send(packet) + if (player.world.isClient) ClientPlayNetworking.send(payload) return true } diff --git a/src/main/kotlin/dev/auxves/vibes/network/Network.kt b/src/main/kotlin/dev/auxves/vibes/network/Network.kt new file mode 100644 index 0000000..38f2de6 --- /dev/null +++ b/src/main/kotlin/dev/auxves/vibes/network/Network.kt @@ -0,0 +1,26 @@ +package dev.auxves.vibes.network + +import dev.auxves.vibes.network.payloads.* +import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking +import net.minecraft.network.packet.CustomPayload +import net.minecraft.server.world.ServerWorld +import net.minecraft.world.World + +fun initNetwork() { + PayloadTypeRegistry.playC2S().register(Play.ID, Play.PACKET_CODEC) + PayloadTypeRegistry.playS2C().register(Play.ID, Play.PACKET_CODEC) + + PayloadTypeRegistry.playC2S().register(Stop.ID, Stop.PACKET_CODEC) + PayloadTypeRegistry.playS2C().register(Stop.ID, Stop.PACKET_CODEC) + + PayloadTypeRegistry.playS2C().register(ChangeDistance.ID, ChangeDistance.PACKET_CODEC) + PayloadTypeRegistry.playS2C().register(ChangePositionBlock.ID, ChangePositionBlock.PACKET_CODEC) + PayloadTypeRegistry.playS2C().register(ChangePositionEntity.ID, ChangePositionEntity.PACKET_CODEC) +} + +/** Sends a packet to every client */ +fun World.sendAll(payload: CustomPayload) { + val world = this as? ServerWorld ?: return + world.players.forEach { ServerPlayNetworking.send(it, payload) } +} diff --git a/src/main/kotlin/dev/auxves/vibes/network/packet/ChangeDistance.kt b/src/main/kotlin/dev/auxves/vibes/network/packet/ChangeDistance.kt deleted file mode 100644 index 6625406..0000000 --- a/src/main/kotlin/dev/auxves/vibes/network/packet/ChangeDistance.kt +++ /dev/null @@ -1,21 +0,0 @@ -package dev.auxves.vibes.network.packet - -import dev.auxves.vibes.Vibes -import net.minecraft.network.PacketByteBuf -import java.util.UUID - -data class ChangeDistance(val uuid: UUID, val distance: Float) : Packet { - companion object : PacketCompanion { - override val id = Vibes.id("change-distance") - - override fun fromBuf(buf: PacketByteBuf) = ChangeDistance( - buf.readUuid(), - buf.readFloat() - ) - } - - override val buffer = createPacket { - writeUuid(uuid) - writeFloat(distance) - } -} \ No newline at end of file diff --git a/src/main/kotlin/dev/auxves/vibes/network/packet/ChangePositionBlock.kt b/src/main/kotlin/dev/auxves/vibes/network/packet/ChangePositionBlock.kt deleted file mode 100644 index b8c475c..0000000 --- a/src/main/kotlin/dev/auxves/vibes/network/packet/ChangePositionBlock.kt +++ /dev/null @@ -1,22 +0,0 @@ -package dev.auxves.vibes.network.packet - -import dev.auxves.vibes.Vibes -import net.minecraft.network.PacketByteBuf -import net.minecraft.util.math.BlockPos -import java.util.UUID - -data class ChangePositionBlock(val uuid: UUID, val blockPos: BlockPos) : Packet { - companion object : PacketCompanion { - override val id = Vibes.id("change-position-block") - - override fun fromBuf(buf: PacketByteBuf) = ChangePositionBlock( - buf.readUuid(), - buf.readBlockPos() - ) - } - - override val buffer = createPacket { - writeUuid(uuid) - writeBlockPos(blockPos) - } -} \ No newline at end of file diff --git a/src/main/kotlin/dev/auxves/vibes/network/packet/ChangePositionEntity.kt b/src/main/kotlin/dev/auxves/vibes/network/packet/ChangePositionEntity.kt deleted file mode 100644 index f209fae..0000000 --- a/src/main/kotlin/dev/auxves/vibes/network/packet/ChangePositionEntity.kt +++ /dev/null @@ -1,21 +0,0 @@ -package dev.auxves.vibes.network.packet - -import dev.auxves.vibes.Vibes -import net.minecraft.network.PacketByteBuf -import java.util.UUID - -data class ChangePositionEntity(val uuid: UUID, val entityUUID: UUID) : Packet { - companion object : PacketCompanion { - override val id = Vibes.id("change-position-entity") - - override fun fromBuf(buf: PacketByteBuf) = ChangePositionEntity( - buf.readUuid(), - buf.readUuid() - ) - } - - override val buffer = createPacket { - writeUuid(uuid) - writeUuid(entityUUID) - } -} \ No newline at end of file diff --git a/src/main/kotlin/dev/auxves/vibes/network/packet/Packets.kt b/src/main/kotlin/dev/auxves/vibes/network/packet/Packets.kt deleted file mode 100644 index ac98918..0000000 --- a/src/main/kotlin/dev/auxves/vibes/network/packet/Packets.kt +++ /dev/null @@ -1,60 +0,0 @@ -package dev.auxves.vibes.network.packet - -import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking -import net.fabricmc.fabric.api.networking.v1.PacketByteBufs -import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking -import net.minecraft.network.PacketByteBuf -import net.minecraft.server.network.ServerPlayerEntity -import net.minecraft.server.world.ServerWorld -import net.minecraft.util.Identifier -import net.minecraft.world.World -import kotlin.reflect.full.companionObjectInstance - -interface Packet { - val buffer: PacketByteBuf -} - -interface PacketCompanion { - val id: Identifier - fun fromBuf(buf: PacketByteBuf): Packet -} - -/** Registers a server receiver */ -inline fun register(crossinline handler: (packet: T) -> Unit) { - val companion = T::class.companionObjectInstance as PacketCompanion - - ClientPlayNetworking.registerGlobalReceiver(companion.id) { client, _, buf, _ -> - val packet = companion.fromBuf(buf) as T - client.execute { handler(packet) } - } -} - -/** Sends a packet from the server to the client associated with this player */ -fun ServerPlayerEntity.send(packet: Packet) { - val companion = packet::class.companionObjectInstance as PacketCompanion - ServerPlayNetworking.send(this, companion.id, packet.buffer) -} - -/** Registers a client receiver */ -inline fun register(crossinline handler: (packet: T, player: ServerPlayerEntity) -> Unit) { - val companion = T::class.companionObjectInstance as PacketCompanion - - ServerPlayNetworking.registerGlobalReceiver(companion.id) { server, player, _, buf, _ -> - val packet = companion.fromBuf(buf) as T - server.execute { handler(packet, player) } - } -} - -/** Sends a packet from the client to the server */ -fun send(packet: Packet) { - val companion = packet::class.companionObjectInstance as PacketCompanion - ClientPlayNetworking.send(companion.id, packet.buffer) -} - -/** Sends a packet to every client */ -fun World.sendAll(packet: Packet) { - val world = this as? ServerWorld ?: return - world.players.forEach { it.send(packet) } -} - -fun createPacket(block: PacketByteBuf.() -> Unit) = PacketByteBufs.create().apply(block)!! diff --git a/src/main/kotlin/dev/auxves/vibes/network/packet/Play.kt b/src/main/kotlin/dev/auxves/vibes/network/packet/Play.kt deleted file mode 100644 index e0c23c0..0000000 --- a/src/main/kotlin/dev/auxves/vibes/network/packet/Play.kt +++ /dev/null @@ -1,24 +0,0 @@ -package dev.auxves.vibes.network.packet - -import dev.auxves.vibes.Vibes -import net.minecraft.network.PacketByteBuf -import net.minecraft.util.Identifier -import java.util.UUID - -data class Play(val uuid: UUID, val player: UUID, val sound: Identifier) : Packet { - companion object : PacketCompanion { - override val id = Vibes.id("play") - - override fun fromBuf(buf: PacketByteBuf) = Play( - buf.readUuid(), - buf.readUuid(), - buf.readIdentifier() - ) - } - - override val buffer = createPacket { - writeUuid(uuid) - writeUuid(player) - writeIdentifier(sound) - } -} \ No newline at end of file diff --git a/src/main/kotlin/dev/auxves/vibes/network/packet/Stop.kt b/src/main/kotlin/dev/auxves/vibes/network/packet/Stop.kt deleted file mode 100644 index 9fefc1d..0000000 --- a/src/main/kotlin/dev/auxves/vibes/network/packet/Stop.kt +++ /dev/null @@ -1,15 +0,0 @@ -package dev.auxves.vibes.network.packet - -import dev.auxves.vibes.Vibes -import net.minecraft.network.PacketByteBuf -import java.util.UUID - -data class Stop(val uuid: UUID) : Packet { - companion object : PacketCompanion { - override val id = Vibes.id("stop") - - override fun fromBuf(buf: PacketByteBuf) = Stop(buf.readUuid()) - } - - override val buffer = createPacket { writeUuid(uuid) } -} \ No newline at end of file diff --git a/src/main/kotlin/dev/auxves/vibes/network/payloads/ChangeDistance.kt b/src/main/kotlin/dev/auxves/vibes/network/payloads/ChangeDistance.kt new file mode 100644 index 0000000..0b5fc75 --- /dev/null +++ b/src/main/kotlin/dev/auxves/vibes/network/payloads/ChangeDistance.kt @@ -0,0 +1,29 @@ +package dev.auxves.vibes.network.payloads + +import dev.auxves.vibes.Vibes +import io.netty.buffer.ByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.codec.PacketCodecs +import net.minecraft.network.packet.CustomPayload +import net.minecraft.util.Uuids +import java.util.UUID + +data class ChangeDistance(val uuid: UUID, val distance: Float) : CustomPayload { + companion object { + val ID = CustomPayload.Id(Vibes.id("change-distance")) + + val PACKET_CODEC = object: PacketCodec { + override fun decode(buf: ByteBuf) = ChangeDistance( + Uuids.PACKET_CODEC.decode(buf), + PacketCodecs.FLOAT.decode(buf) + ) + + override fun encode(buf: ByteBuf, value: ChangeDistance) { + Uuids.PACKET_CODEC.encode(buf, value.uuid) + PacketCodecs.FLOAT.encode(buf, value.distance) + } + } + } + + override fun getId() = ID +} diff --git a/src/main/kotlin/dev/auxves/vibes/network/payloads/ChangePositionBlock.kt b/src/main/kotlin/dev/auxves/vibes/network/payloads/ChangePositionBlock.kt new file mode 100644 index 0000000..f50777c --- /dev/null +++ b/src/main/kotlin/dev/auxves/vibes/network/payloads/ChangePositionBlock.kt @@ -0,0 +1,29 @@ +package dev.auxves.vibes.network.payloads + +import dev.auxves.vibes.Vibes +import io.netty.buffer.ByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.packet.CustomPayload +import net.minecraft.util.Uuids +import net.minecraft.util.math.BlockPos +import java.util.UUID + +data class ChangePositionBlock(val uuid: UUID, val blockPos: BlockPos) : CustomPayload { + companion object { + val ID = CustomPayload.Id(Vibes.id("change-position-block")) + + val PACKET_CODEC = object: PacketCodec { + override fun decode(buf: ByteBuf) = ChangePositionBlock( + Uuids.PACKET_CODEC.decode(buf), + BlockPos.PACKET_CODEC.decode(buf) + ) + + override fun encode(buf: ByteBuf, value: ChangePositionBlock) { + Uuids.PACKET_CODEC.encode(buf, value.uuid) + BlockPos.PACKET_CODEC.encode(buf, value.blockPos) + } + } + } + + override fun getId() = ID +} diff --git a/src/main/kotlin/dev/auxves/vibes/network/payloads/ChangePositionEntity.kt b/src/main/kotlin/dev/auxves/vibes/network/payloads/ChangePositionEntity.kt new file mode 100644 index 0000000..3302714 --- /dev/null +++ b/src/main/kotlin/dev/auxves/vibes/network/payloads/ChangePositionEntity.kt @@ -0,0 +1,28 @@ +package dev.auxves.vibes.network.payloads + +import dev.auxves.vibes.Vibes +import io.netty.buffer.ByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.packet.CustomPayload +import net.minecraft.util.Uuids +import java.util.UUID + +data class ChangePositionEntity(val uuid: UUID, val entityUUID: UUID) : CustomPayload { + companion object { + val ID = CustomPayload.Id(Vibes.id("change-position-entity")) + + val PACKET_CODEC = object: PacketCodec { + override fun decode(buf: ByteBuf) = ChangePositionEntity( + Uuids.PACKET_CODEC.decode(buf), + Uuids.PACKET_CODEC.decode(buf) + ) + + override fun encode(buf: ByteBuf, value: ChangePositionEntity) { + Uuids.PACKET_CODEC.encode(buf, value.uuid) + Uuids.PACKET_CODEC.encode(buf, value.entityUUID) + } + } + } + + override fun getId() = ID +} diff --git a/src/main/kotlin/dev/auxves/vibes/network/payloads/Play.kt b/src/main/kotlin/dev/auxves/vibes/network/payloads/Play.kt new file mode 100644 index 0000000..9364c64 --- /dev/null +++ b/src/main/kotlin/dev/auxves/vibes/network/payloads/Play.kt @@ -0,0 +1,31 @@ +package dev.auxves.vibes.network.payloads + +import dev.auxves.vibes.Vibes +import io.netty.buffer.ByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.packet.CustomPayload +import net.minecraft.util.Identifier +import net.minecraft.util.Uuids +import java.util.UUID + +data class Play(val uuid: UUID, val player: UUID, val sound: Identifier) : CustomPayload { + companion object { + val ID = CustomPayload.Id(Vibes.id("play")) + + val PACKET_CODEC = object: PacketCodec { + override fun decode(buf: ByteBuf) = Play( + Uuids.PACKET_CODEC.decode(buf), + Uuids.PACKET_CODEC.decode(buf), + Identifier.PACKET_CODEC.decode(buf) + ) + + override fun encode(buf: ByteBuf, value: Play) { + Uuids.PACKET_CODEC.encode(buf, value.uuid) + Uuids.PACKET_CODEC.encode(buf, value.player) + Identifier.PACKET_CODEC.encode(buf, value.sound) + } + } + } + + override fun getId() = ID +} \ No newline at end of file diff --git a/src/main/kotlin/dev/auxves/vibes/network/payloads/Stop.kt b/src/main/kotlin/dev/auxves/vibes/network/payloads/Stop.kt new file mode 100644 index 0000000..bdc30b6 --- /dev/null +++ b/src/main/kotlin/dev/auxves/vibes/network/payloads/Stop.kt @@ -0,0 +1,26 @@ +package dev.auxves.vibes.network.payloads + +import dev.auxves.vibes.Vibes +import io.netty.buffer.ByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.packet.CustomPayload +import net.minecraft.util.Uuids +import java.util.UUID + +data class Stop(val uuid: UUID) : CustomPayload { + companion object { + val ID = CustomPayload.Id(Vibes.id("stop")) + + val PACKET_CODEC = object: PacketCodec { + override fun decode(buf: ByteBuf) = Stop( + Uuids.PACKET_CODEC.decode(buf) + ) + + override fun encode(buf: ByteBuf, value: Stop) { + Uuids.PACKET_CODEC.encode(buf, value.uuid) + } + } + } + + override fun getId() = ID +} \ No newline at end of file diff --git a/src/main/kotlin/dev/auxves/vibes/server/Bridges.kt b/src/main/kotlin/dev/auxves/vibes/server/Bridges.kt index 424f00f..33393d3 100644 --- a/src/main/kotlin/dev/auxves/vibes/server/Bridges.kt +++ b/src/main/kotlin/dev/auxves/vibes/server/Bridges.kt @@ -1,9 +1,11 @@ package dev.auxves.vibes.server import dev.auxves.vibes.mixin.EnderChestInventoryAccessor -import dev.auxves.vibes.network.packet.* +import dev.auxves.vibes.network.sendAll +import dev.auxves.vibes.network.payloads.* import dev.auxves.vibes.util.* import net.minecraft.block.entity.BlockEntity +import net.minecraft.component.DataComponentTypes import net.minecraft.entity.Entity import net.minecraft.entity.ItemEntity import net.minecraft.entity.player.PlayerEntity @@ -24,9 +26,9 @@ fun handleEnderChest(inventory: Inventory, stack: ItemStack) { stopPlaying(stack, world) } -fun onBreakShulkerBox(entity: Entity) { +fun onBreak(entity: Entity) { if (entity !is ItemEntity) return - if (vibeTypeOf(entity.stack) != VibeType.SHULKER) return + if (!entity.stack.contains(DataComponentTypes.CONTAINER)) return changePosition(entity.stack, entity) } diff --git a/src/main/kotlin/dev/auxves/vibes/server/Server.kt b/src/main/kotlin/dev/auxves/vibes/server/Server.kt index 51f85e5..2fcf648 100644 --- a/src/main/kotlin/dev/auxves/vibes/server/Server.kt +++ b/src/main/kotlin/dev/auxves/vibes/server/Server.kt @@ -1,11 +1,13 @@ package dev.auxves.vibes.server -import dev.auxves.vibes.network.packet.* +import dev.auxves.vibes.network.payloads.* +import dev.auxves.vibes.network.sendAll import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking fun initServer() { - register { data, player -> player.world.sendAll(data) } - register { data, player -> player.world.sendAll(data) } + ServerPlayNetworking.registerGlobalReceiver(Play.ID) { data, ctx -> ctx.player().world.sendAll(data) } + ServerPlayNetworking.registerGlobalReceiver(Stop.ID) { data, ctx -> ctx.player().world.sendAll(data) } ServerPlayConnectionEvents.DISCONNECT.register { handler, server -> server.execute { onDisconnect(handler.player) } diff --git a/src/main/kotlin/dev/auxves/vibes/util/Components.kt b/src/main/kotlin/dev/auxves/vibes/util/Components.kt new file mode 100644 index 0000000..ae5ff3c --- /dev/null +++ b/src/main/kotlin/dev/auxves/vibes/util/Components.kt @@ -0,0 +1,38 @@ +package dev.auxves.vibes.util + +import net.minecraft.component.DataComponentType +import net.minecraft.component.DataComponentTypes +import net.minecraft.item.ItemStack +import net.minecraft.util.Uuids +import java.util.* + +object DataComponents { + val UUID: DataComponentType = DataComponentType.builder() + .codec(Uuids.CODEC) + .packetCodec(Uuids.PACKET_CODEC) + .build() + + val DISC: DataComponentType = DataComponentType.builder() + .codec(ItemStack.CODEC) + .packetCodec(ItemStack.PACKET_CODEC) + .build() +} + +var ItemStack.uuid: UUID + get() = get(DataComponents.UUID) ?: run { + uuid = UUID.randomUUID() + uuid + } + set(new) { set(DataComponents.UUID, new) } + +var ItemStack.disc: ItemStack? + get() = get(DataComponents.DISC) + set(stack) { + if (stack == null || stack == ItemStack.EMPTY) remove(DataComponents.DISC) + else set(DataComponents.DISC, stack) + } + +fun containerInventoryOf(stack: ItemStack): List { + val data = stack.get(DataComponentTypes.CONTAINER) ?: return listOf() + return data.stream().toList() +} \ No newline at end of file diff --git a/src/main/kotlin/dev/auxves/vibes/util/Items.kt b/src/main/kotlin/dev/auxves/vibes/util/Items.kt index f2a6126..f58ddf9 100644 --- a/src/main/kotlin/dev/auxves/vibes/util/Items.kt +++ b/src/main/kotlin/dev/auxves/vibes/util/Items.kt @@ -1,38 +1,17 @@ package dev.auxves.vibes.util import dev.auxves.vibes.item.Vibe -import net.minecraft.block.ShulkerBoxBlock -import net.minecraft.item.BlockItem +import net.minecraft.component.DataComponentTypes import net.minecraft.item.ItemStack -import java.util.UUID -enum class VibeType { - VIBE, - SHULKER -} - -fun isPlaying(stack: ItemStack): Boolean = when (vibeTypeOf(stack)) { - VibeType.VIBE -> stack.disc != null - VibeType.SHULKER -> shulkerInventoryOf(stack).any(::isPlaying) +fun isPlaying(stack: ItemStack): Boolean = when { + stack.item is Vibe -> stack.disc != null + stack.contains(DataComponentTypes.CONTAINER) -> containerInventoryOf(stack).any(::isPlaying) else -> false } -fun ensureUuid(stack: ItemStack): ItemStack { - if (stack.item is Vibe && !stack.orCreateNbt.containsUuid(Tags.UUID)) { - stack.uuid = UUID.randomUUID() - } - - return stack -} - -fun vibeTypeOf(stack: ItemStack): VibeType? = when { - stack.item is Vibe -> VibeType.VIBE - (stack.item as? BlockItem)?.block is ShulkerBoxBlock -> VibeType.SHULKER - else -> null -} - -fun vibesIn(stack: ItemStack): Sequence = when (vibeTypeOf(stack)) { - VibeType.VIBE -> sequenceOf(stack) - VibeType.SHULKER -> shulkerInventoryOf(stack).asSequence().flatMap(::vibesIn) +fun vibesIn(stack: ItemStack): Sequence = when { + stack.item is Vibe -> sequenceOf(stack) + stack.contains(DataComponentTypes.CONTAINER) -> containerInventoryOf(stack).asSequence().flatMap(::vibesIn) else -> sequenceOf() -}.map(::ensureUuid).filter(::isPlaying) +}.filter(::isPlaying) diff --git a/src/main/kotlin/dev/auxves/vibes/util/Tags.kt b/src/main/kotlin/dev/auxves/vibes/util/Tags.kt deleted file mode 100644 index d39422c..0000000 --- a/src/main/kotlin/dev/auxves/vibes/util/Tags.kt +++ /dev/null @@ -1,32 +0,0 @@ -package dev.auxves.vibes.util - -import net.minecraft.inventory.Inventories -import net.minecraft.item.ItemStack -import net.minecraft.nbt.NbtCompound -import net.minecraft.util.collection.DefaultedList -import java.util.UUID - -object Tags { - const val DISC = "Disc" - const val UUID = "VibeUUID" - - const val SHULKER = "BlockEntityTag" -} - -var ItemStack.uuid: UUID - get() = orCreateNbt.getUuid(Tags.UUID) - set(new) = orCreateNbt.putUuid(Tags.UUID, new) - -var ItemStack.disc: ItemStack? - get() = getSubNbt(Tags.DISC)?.let { ItemStack.fromNbt(it) } - set(stack) { - if (stack == null || stack == ItemStack.EMPTY) return removeSubNbt(Tags.DISC) - setSubNbt(Tags.DISC, stack.writeNbt(NbtCompound())) - } - -fun shulkerInventoryOf(stack: ItemStack): List { - val nbt = stack.getSubNbt(Tags.SHULKER) ?: return listOf() - val inventory = DefaultedList.ofSize(27, ItemStack.EMPTY) - Inventories.readNbt(nbt, inventory) - return inventory.toList() -} \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index e60557a..e491374 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -9,7 +9,7 @@ "homepage": "https://github.com/auxves/vibes", "sources": "https://github.com/auxves/vibes" }, - "license": "MIT", + "license": ["GPL-3.0"], "icon": "assets/vibes/icon.png", "environment": "*", "entrypoints": { @@ -18,8 +18,13 @@ }, "mixins": ["vibes.mixins.json"], "depends": { - "minecraft": "1.20.x", + "minecraft": ">=1.20.5", "fabric-api": "*", "fabric-language-kotlin": "*" + }, + "custom": { + "mc-publish": { + "loaders": ["fabric"] + } } } diff --git a/src/main/resources/vibes.mixins.json b/src/main/resources/vibes.mixins.json index 488d9d8..026d104 100644 --- a/src/main/resources/vibes.mixins.json +++ b/src/main/resources/vibes.mixins.json @@ -2,7 +2,7 @@ "required": true, "minVersion": "0.8", "package": "dev.auxves.vibes.mixin", - "compatibilityLevel": "JAVA_17", + "compatibilityLevel": "JAVA_21", "server": [], "client": [], "mixins": [ @@ -17,7 +17,6 @@ "LootableContainerBlockEntityMixin", "PlayerEntityMixin", "PlayerInventoryMixin", - "ShulkerBoxBlockMixin", "SimpleInventoryMixin", "SoundManagerAccessor", "SoundSystemAccessor",