From e7aa4f4c3049221aa7fef02ede9c5b1f60b8cb14 Mon Sep 17 00:00:00 2001 From: xtex Date: Thu, 20 Jul 2023 17:42:50 +0800 Subject: [PATCH] feat: simple projection updater --- build.gradle.kts | 12 +++- common/src/main/kotlin/quaedam/Quaedam.kt | 2 + .../projection/EntityProjectionBlock.kt | 23 +++++-- .../quaedam/projection/ProjectionBlock.kt | 14 ++--- .../quaedam/projection/ProjectionEffect.kt | 6 +- .../projection/SimpleProjectionEntity.kt | 13 ++-- .../projection/SimpleProjectionUpdate.kt | 63 +++++++++++++++++++ .../projection/misc/SkylightProjection.kt | 27 ++++++++ .../projection/swarm/SwarmProjectionEffect.kt | 2 +- .../quaedam/projector/ProjectorBlock.kt | 1 + gradle.properties | 1 + 11 files changed, 142 insertions(+), 22 deletions(-) create mode 100644 common/src/main/kotlin/quaedam/projection/SimpleProjectionUpdate.kt diff --git a/build.gradle.kts b/build.gradle.kts index d3f20e6..b66a650 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -21,7 +21,10 @@ subprojects { dependencies { "minecraft"("com.mojang:minecraft:${project.property("minecraft_version")}") - "mappings"(loom.officialMojangMappings()) + "mappings"(loom.layered { + officialMojangMappings() + parchment("org.parchmentmc.data:parchment-${project.property("minecraft_version")}:${project.property("parchment_version")}@zip") + }) } } @@ -35,6 +38,13 @@ allprojects { version = "1.0.0" group = "quaedam" + repositories { + maven { + name = "ParchmentMC" + setUrl("https://maven.parchmentmc.org") + } + } + dependencies { compileOnly("org.jetbrains.kotlin:kotlin-stdlib") } diff --git a/common/src/main/kotlin/quaedam/Quaedam.kt b/common/src/main/kotlin/quaedam/Quaedam.kt index 62ee12e..392a45c 100644 --- a/common/src/main/kotlin/quaedam/Quaedam.kt +++ b/common/src/main/kotlin/quaedam/Quaedam.kt @@ -11,6 +11,7 @@ import net.minecraft.world.item.ItemStack import org.slf4j.LoggerFactory import quaedam.projection.ProjectionCommand import quaedam.projection.ProjectionEffectType +import quaedam.projection.SimpleProjectionUpdate import quaedam.projection.misc.NoiseProjection import quaedam.projection.misc.SkylightProjection import quaedam.projection.misc.SoundProjection @@ -48,6 +49,7 @@ object Quaedam { SoundProjection NoiseProjection ProjectionCommand + SimpleProjectionUpdate creativeModeTabs.register() items.register() diff --git a/common/src/main/kotlin/quaedam/projection/EntityProjectionBlock.kt b/common/src/main/kotlin/quaedam/projection/EntityProjectionBlock.kt index 93c5208..208f9d6 100644 --- a/common/src/main/kotlin/quaedam/projection/EntityProjectionBlock.kt +++ b/common/src/main/kotlin/quaedam/projection/EntityProjectionBlock.kt @@ -1,12 +1,14 @@ package quaedam.projection import dev.architectury.registry.registries.DeferredSupplier +import net.minecraft.client.Minecraft import net.minecraft.core.BlockPos import net.minecraft.server.level.ServerLevel import net.minecraft.world.level.Level import net.minecraft.world.level.block.EntityBlock import net.minecraft.world.level.block.entity.BlockEntityType import net.minecraft.world.level.block.state.BlockState +import quaedam.utils.sendBlockUpdated abstract class EntityProjectionBlock

(properties: Properties = createProperties()) : ProjectionBlock

(properties), EntityBlock { @@ -17,16 +19,25 @@ abstract class EntityProjectionBlock

(properties: Propertie abstract val blockEntity: DeferredSupplier>> - override fun newBlockEntity(pos: BlockPos, state: BlockState) = blockEntity.get().create(pos, state) + override fun newBlockEntity(pos: BlockPos, state: BlockState) = blockEntity.get().create(pos, state)!! @Suppress("UNCHECKED_CAST") - fun getProjection(level: Level, pos: BlockPos) = (level.getBlockEntity(pos) as SimpleProjectionEntity

).projection + fun getBlockEntity(level: Level, pos: BlockPos) = (level.getBlockEntity(pos) as SimpleProjectionEntity

) - override fun applyProjectionEffect(level: ServerLevel, state: BlockState, pos: BlockPos) = getProjection(level, pos) + override fun applyProjectionEffect(level: ServerLevel, state: BlockState, pos: BlockPos) = + getBlockEntity(level, pos).cloneProjection() - inline fun applyChange(level: Level, pos: BlockPos, func: P.() -> Unit) { - getProjection(level, pos).apply(func) - sendUpdateToProjectors(level, pos) + fun applyChange(level: Level, pos: BlockPos, func: P.() -> Unit) { + val entity = getBlockEntity(level, pos) + val projection = entity.projection + projection.apply(func) + if (level.isClientSide) { + check(level == Minecraft.getInstance().player!!.level()) + SimpleProjectionUpdate.send(pos, projection.toNbt()) + } else { + getBlockEntity(level, pos).sendBlockUpdated() + sendUpdateToProjectors(level, pos) + } } } diff --git a/common/src/main/kotlin/quaedam/projection/ProjectionBlock.kt b/common/src/main/kotlin/quaedam/projection/ProjectionBlock.kt index a3af4e4..340171c 100644 --- a/common/src/main/kotlin/quaedam/projection/ProjectionBlock.kt +++ b/common/src/main/kotlin/quaedam/projection/ProjectionBlock.kt @@ -29,6 +29,13 @@ abstract class ProjectionBlock

(properties: Properties = cr } .toSet() + fun sendUpdateToProjectors(level: Level, pos: BlockPos) { + if (!level.isClientSide) { + findNearbyProjectors(level, pos) + .forEach { (level.getBlockEntity(it) as ProjectorBlockEntity).checkUpdate() } + } + } + } @Suppress("OVERRIDE_DEPRECATION") @@ -52,11 +59,4 @@ abstract class ProjectionBlock

(properties: Properties = cr } } - fun sendUpdateToProjectors(level: Level, pos: BlockPos) { - if (!level.isClientSide) { - findNearbyProjectors(level, pos) - .forEach { (level.getBlockEntity(it) as ProjectorBlockEntity).checkUpdate() } - } - } - } diff --git a/common/src/main/kotlin/quaedam/projection/ProjectionEffect.kt b/common/src/main/kotlin/quaedam/projection/ProjectionEffect.kt index e786252..ad3420c 100644 --- a/common/src/main/kotlin/quaedam/projection/ProjectionEffect.kt +++ b/common/src/main/kotlin/quaedam/projection/ProjectionEffect.kt @@ -10,17 +10,17 @@ import net.minecraft.server.level.ServerLevel import net.minecraft.world.level.Level import net.minecraft.world.level.block.state.BlockState -abstract class ProjectionEffect { +abstract class ProjectionEffect : Cloneable { abstract val type: ProjectionEffectType<*> abstract fun toNbt(tag: CompoundTag) - abstract fun fromNbt(tag: CompoundTag, trusted: Boolean) + abstract fun fromNbt(tag: CompoundTag, trusted: Boolean = true) fun toNbt() = CompoundTag().apply { toNbt(this) } - override fun equals(other: Any?) = other === this + override fun equals(other: Any?): Boolean = other === this override fun hashCode() = type.hashCode() diff --git a/common/src/main/kotlin/quaedam/projection/SimpleProjectionEntity.kt b/common/src/main/kotlin/quaedam/projection/SimpleProjectionEntity.kt index 14c09ae..edd9876 100644 --- a/common/src/main/kotlin/quaedam/projection/SimpleProjectionEntity.kt +++ b/common/src/main/kotlin/quaedam/projection/SimpleProjectionEntity.kt @@ -14,19 +14,20 @@ class SimpleProjectionEntity

( type: BlockEntityType>, pos: BlockPos, state: BlockState, - val projection: P + var projection: P, + val default: () -> P, ) : BlockEntity(type, pos, state) { companion object { const val TAG_PROJECTION_EFFECT = "ProjectionEffect" - fun

> createBlockEntityType( + fun

> createBlockEntityType( block: RegistrySupplier, default: () -> P, ): BlockEntityType> { val type = ValueContainer>>() type.inner = BlockEntityType.Builder.of({ pos, state -> - SimpleProjectionEntity(type.inner!!, pos, state, default()) + SimpleProjectionEntity(type.inner!!, pos, state, default(), default) }, block.get()).build(null) return type.inner!! } @@ -41,11 +42,15 @@ class SimpleProjectionEntity

( override fun load(tag: CompoundTag) { super.load(tag) - projection.fromNbt(tag.getCompound(TAG_PROJECTION_EFFECT), true) + if (TAG_PROJECTION_EFFECT in tag) { + projection.fromNbt(tag.getCompound(TAG_PROJECTION_EFFECT)) + } } override fun getUpdateTag(): CompoundTag = saveWithoutMetadata() override fun getUpdatePacket(): Packet = ClientboundBlockEntityDataPacket.create(this) + fun cloneProjection() = default().apply { fromNbt(projection.toNbt()) } + } \ No newline at end of file diff --git a/common/src/main/kotlin/quaedam/projection/SimpleProjectionUpdate.kt b/common/src/main/kotlin/quaedam/projection/SimpleProjectionUpdate.kt new file mode 100644 index 0000000..c6930d6 --- /dev/null +++ b/common/src/main/kotlin/quaedam/projection/SimpleProjectionUpdate.kt @@ -0,0 +1,63 @@ +package quaedam.projection + +import dev.architectury.networking.NetworkManager +import dev.architectury.networking.NetworkManager.PacketContext +import io.netty.buffer.Unpooled +import net.minecraft.core.BlockPos +import net.minecraft.nbt.CompoundTag +import net.minecraft.network.FriendlyByteBuf +import net.minecraft.network.chat.Component +import net.minecraft.resources.ResourceLocation +import net.minecraft.server.level.ServerPlayer +import quaedam.Quaedam +import quaedam.utils.sendBlockUpdated + +object SimpleProjectionUpdate { + + val id = ResourceLocation("quaedam", "simple_projection_update") + + init { + NetworkManager.registerReceiver(NetworkManager.Side.C2S, id, ::handle) + } + + private fun handle(buf: FriendlyByteBuf, ctx: PacketContext) { + val player = ctx.player!! as ServerPlayer + val level = player.level() + + val pos = buf.readBlockPos() + val data = buf.readNbt()!! + + if (player.blockPosition().distSqr(pos) > 10 * 10) { + Quaedam.logger.info("Player ${player.name} tried to update a projection block far away") + if (player.blockPosition().distSqr(pos) > 50 * 50) { + player.connection.disconnect(Component.literal("[Quaedam] wth r u doing? why not waiting for server?")) + } + return + } + + level.server!!.execute { + val entity = level.getBlockEntity(pos) ?: return@execute + val blockEntity = entity as SimpleProjectionEntity<*> + try { + blockEntity.projection.fromNbt(data, trusted = false) + } catch (e: Throwable) { + Quaedam.logger.error( + "Player ${player.name} tried to update projection " + + "at $pos but caused error: $data", e + ) + player.connection.disconnect(Component.literal("[Quaedam] ? wait what did you send to the server?")) + return@execute + } + blockEntity.sendBlockUpdated() + ProjectionBlock.sendUpdateToProjectors(level, pos) + } + } + + fun send(pos: BlockPos, data: CompoundTag) { + val buf = FriendlyByteBuf(Unpooled.buffer()) + buf.writeBlockPos(pos) + buf.writeNbt(data) + NetworkManager.sendToServer(id, buf) + } + +} \ No newline at end of file diff --git a/common/src/main/kotlin/quaedam/projection/misc/SkylightProjection.kt b/common/src/main/kotlin/quaedam/projection/misc/SkylightProjection.kt index 1aa47e0..861cf4b 100644 --- a/common/src/main/kotlin/quaedam/projection/misc/SkylightProjection.kt +++ b/common/src/main/kotlin/quaedam/projection/misc/SkylightProjection.kt @@ -1,8 +1,15 @@ package quaedam.projection.misc +import net.minecraft.core.BlockPos import net.minecraft.nbt.CompoundTag +import net.minecraft.world.InteractionHand +import net.minecraft.world.InteractionResult +import net.minecraft.world.entity.player.Player import net.minecraft.world.item.BlockItem import net.minecraft.world.item.Item +import net.minecraft.world.level.Level +import net.minecraft.world.level.block.state.BlockState +import net.minecraft.world.phys.BlockHitResult import quaedam.Quaedam import quaedam.projection.EntityProjectionBlock import quaedam.projection.ProjectionEffect @@ -38,6 +45,26 @@ object SkylightProjectionBlock : EntityProjectionBlock override val blockEntity = SkylightProjection.blockEntity + override fun use( + blockState: BlockState, + level: Level, + blockPos: BlockPos, + player: Player, + interactionHand: InteractionHand, + blockHitResult: BlockHitResult + ): InteractionResult { + if (level.isClientSide) { + println("update") + applyChange(level, blockPos) { + factor -= 0.5 + if (factor < 0.5) factor = 2.0 + println("new factor: $factor") + } + return InteractionResult.CONSUME + } + return super.use(blockState, level, blockPos, player, interactionHand, blockHitResult) + } + } data class SkylightProjectionEffect(var factor: Double = 2.0) : ProjectionEffect() { diff --git a/common/src/main/kotlin/quaedam/projection/swarm/SwarmProjectionEffect.kt b/common/src/main/kotlin/quaedam/projection/swarm/SwarmProjectionEffect.kt index 3f38c80..1f9ad21 100644 --- a/common/src/main/kotlin/quaedam/projection/swarm/SwarmProjectionEffect.kt +++ b/common/src/main/kotlin/quaedam/projection/swarm/SwarmProjectionEffect.kt @@ -26,7 +26,7 @@ data class SwarmProjectionEffect( override fun fromNbt(tag: CompoundTag, trusted: Boolean) { maxCount = tag.getInt(TAG_MAX_COUNT) - if (!trusted){ + if (!trusted) { maxCount = min(maxCount, 250) } } diff --git a/common/src/main/kotlin/quaedam/projector/ProjectorBlock.kt b/common/src/main/kotlin/quaedam/projector/ProjectorBlock.kt index 0bc07da..5fe9832 100644 --- a/common/src/main/kotlin/quaedam/projector/ProjectorBlock.kt +++ b/common/src/main/kotlin/quaedam/projector/ProjectorBlock.kt @@ -39,6 +39,7 @@ object ProjectorBlock : Block(Properties.of() blockHitResult: BlockHitResult ): InteractionResult { checkUpdate(level, blockPos) + println(level.getBlockEntity(blockPos)!!.saveWithoutMetadata()) return InteractionResult.SUCCESS } diff --git a/gradle.properties b/gradle.properties index b68309f..bf76fae 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,6 +2,7 @@ org.gradle.parallel=true org.gradle.caching=true org.gradle.jvmargs=-Xmx2048M minecraft_version=1.20.1 +parchment_version=2023.07.16 # https://www.curseforge.com/minecraft/mc-mods/architectury-api architectury_version=9.1.10 # https://files.minecraftforge.net/net/minecraftforge/forge/