From 3cda1d88a1be03563f67f217ca826ad180bba6ef Mon Sep 17 00:00:00 2001 From: Bixilon Date: Mon, 22 Aug 2022 22:28:43 +0200 Subject: [PATCH] forbid interaction if out of world --- .../entities/block/CampfireBlockEntity.kt | 1 - .../data/registries/items/block/BlockItem.kt | 9 ++-- .../de/bixilon/minosoft/data/world/World.kt | 6 ++- .../world/container/SectionDataProvider.kt | 10 ++--- .../interaction/InteractInteractionHandler.kt | 42 ++++++++++++------- .../input/interaction/InteractionResults.kt | 8 +++- .../packets/s2c/play/tab/TabListS2CP.kt | 2 +- .../protocol/protocol/ProtocolDefinition.java | 14 ++----- 8 files changed, 53 insertions(+), 39 deletions(-) diff --git a/src/main/java/de/bixilon/minosoft/data/entities/block/CampfireBlockEntity.kt b/src/main/java/de/bixilon/minosoft/data/entities/block/CampfireBlockEntity.kt index fbf10763e..db14d54b8 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/block/CampfireBlockEntity.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/block/CampfireBlockEntity.kt @@ -92,7 +92,6 @@ class CampfireBlockEntity(connection: PlayConnection) : BlockEntity(connection) for (i in 0 until 4) { connection.world.addParticle(SmokeParticle(connection, position, Vec3d(0.0, 5.0E-4, 0.0))) } - } } diff --git a/src/main/java/de/bixilon/minosoft/data/registries/items/block/BlockItem.kt b/src/main/java/de/bixilon/minosoft/data/registries/items/block/BlockItem.kt index 374235593..dc7b1c187 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/items/block/BlockItem.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/items/block/BlockItem.kt @@ -13,6 +13,7 @@ package de.bixilon.minosoft.data.registries.items.block +import de.bixilon.kotlinglm.vec3.Vec3i import de.bixilon.kutil.cast.CastUtil.unsafeNull import de.bixilon.kutil.concurrent.pool.DefaultThreadPool import de.bixilon.minosoft.data.abilities.Gamemodes @@ -41,10 +42,10 @@ open class BlockItem( override fun interactBlock(connection: PlayConnection, target: BlockTarget, hand: Hands, stack: ItemStack): InteractionResults { if (!connection.player.gamemode.canBuild) { - return InteractionResults.PASS + return InteractionResults.ERROR } - val placePosition = target.blockPosition + val placePosition = Vec3i(target.blockPosition) if (!target.blockState.material.replaceable) { placePosition += target.direction @@ -54,7 +55,7 @@ open class BlockItem( } if (!connection.world.isPositionChangeable(placePosition)) { - return InteractionResults.PASS + return InteractionResults.ERROR } if (connection.world.getBlockEntity(placePosition) != null && !connection.player.isSneaking) { @@ -71,7 +72,7 @@ open class BlockItem( val collisionShape = placeBlockState.collisionShape + placePosition if (connection.world.entities.isEntityIn(collisionShape)) { - return InteractionResults.CONSUME + return InteractionResults.ERROR } diff --git a/src/main/java/de/bixilon/minosoft/data/world/World.kt b/src/main/java/de/bixilon/minosoft/data/world/World.kt index 8c1c8510d..722a92881 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/World.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/World.kt @@ -208,8 +208,12 @@ class World( if (border.isOutside(blockPosition)) { return false } + return isValidPosition(blockPosition) + } + + fun isValidPosition(blockPosition: Vec3i): Boolean { val dimension = connection.world.dimension!! - return (blockPosition.y >= dimension.minY || blockPosition.y < dimension.maxY) + return (blockPosition.y >= dimension.minY && blockPosition.y < dimension.maxY) } fun forceSetBlockState(blockPosition: Vec3i, blockState: BlockState?, check: Boolean = false) { diff --git a/src/main/java/de/bixilon/minosoft/data/world/container/SectionDataProvider.kt b/src/main/java/de/bixilon/minosoft/data/world/container/SectionDataProvider.kt index e65ae4e60..7357fcb5e 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/container/SectionDataProvider.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/container/SectionDataProvider.kt @@ -72,9 +72,9 @@ open class SectionDataProvider( } var count = 0 - var minX = 16 - var minY = 16 - var minZ = 16 + var minX = ProtocolDefinition.SECTION_WIDTH_X + var minY = ProtocolDefinition.SECTION_HEIGHT_Y + var minZ = ProtocolDefinition.SECTION_WIDTH_Z var maxX = 0 var maxY = 0 @@ -112,8 +112,8 @@ open class SectionDataProvider( if (z > maxZ) { maxZ = z } - } + this.minPosition = Vec3i(minX, minY, minZ) this.maxPosition = Vec3i(maxX, maxY, maxZ) this.count = count @@ -219,6 +219,6 @@ open class SectionDataProvider( companion object { - private val EMPTY_ITERATOR = listOf().iterator() + private val EMPTY_ITERATOR = emptyArray().iterator() } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/input/interaction/InteractInteractionHandler.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/input/interaction/InteractInteractionHandler.kt index 40986eda3..d227f3ba9 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/input/interaction/InteractInteractionHandler.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/input/interaction/InteractInteractionHandler.kt @@ -50,11 +50,11 @@ class InteractInteractionHandler( fun init() { - renderWindow.inputHandler.registerCheckCallback(USE_ITEM_KEYBINDING to KeyBinding( - mapOf( + renderWindow.inputHandler.registerCheckCallback( + USE_ITEM_KEYBINDING to KeyBinding( KeyActions.CHANGE to setOf(KeyCodes.MOUSE_BUTTON_RIGHT), - ), - )) + ) + ) } fun stopUsingItem() { @@ -80,14 +80,15 @@ class InteractInteractionHandler( } // if out of world (border): return CONSUME + var result: InteractionResults = InteractionResults.PASS try { if (connection.player.gamemode == Gamemodes.SPECTATOR) { return InteractionResults.SUCCESS } - val result = target.blockState.block.onUse(connection, target, hand, stack) - if (result == InteractionResults.SUCCESS) { - return InteractionResults.SUCCESS + result = target.blockState.block.onUse(connection, target, hand, stack) + if (result != InteractionResults.PASS) { + return result } if (stack == null) { @@ -97,17 +98,22 @@ class InteractInteractionHandler( return InteractionResults.PASS // ToDo: Check } - return stack.item.item.interactBlock(connection, target, hand, stack) + result = stack.item.item.interactBlock(connection, target, hand, stack) } finally { - connection.sendPacket(BlockInteractC2SP( - position = target.blockPosition, - direction = target.direction, - cursorPosition = Vec3(target.hitPosition), - item = stack, - hand = hand, - insideBlock = false, // ToDo: insideBlock - )) + if (result != InteractionResults.ERROR) { + connection.sendPacket( + BlockInteractC2SP( + position = target.blockPosition, + direction = target.direction, + cursorPosition = Vec3(target.hitPosition), + item = stack, + hand = hand, + insideBlock = false, // ToDo: insideBlock + ) + ) + } } + return result } fun interactEntityAt(target: EntityTarget, hand: Hands): InteractionResults { @@ -187,7 +193,11 @@ class InteractInteractionHandler( return } } + is BlockTarget -> { + if (!connection.world.isValidPosition(target.blockPosition)) { + return + } val result = interactBlock(target, item, hand) if (result == InteractionResults.SUCCESS) { interactionManager.swingHand(hand) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/input/interaction/InteractionResults.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/input/interaction/InteractionResults.kt index 106ece80c..26c2d5a3e 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/input/interaction/InteractionResults.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/input/interaction/InteractionResults.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2021 Moritz Zwerger + * Copyright (C) 2020-2022 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -28,5 +28,11 @@ enum class InteractionResults { * Nothing happens from block side (e.g. right clicking on dirt). You can maybe place a block, whatever */ PASS, + + + /** + * Like consume, but with an error (no packet will be sent to the server) + */ + ERROR, ; } diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/tab/TabListS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/tab/TabListS2CP.kt index 01b16bf2d..a214d5de6 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/tab/TabListS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/tab/TabListS2CP.kt @@ -133,8 +133,8 @@ class TabListS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { entity.tabListItem = tabListItem } - } + connection.fireEvent(TabListEntryChangeEvent(connection, this)) } diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/ProtocolDefinition.java b/src/main/java/de/bixilon/minosoft/protocol/protocol/ProtocolDefinition.java index 7e7bae318..fee1c5fae 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/ProtocolDefinition.java +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/ProtocolDefinition.java @@ -23,7 +23,6 @@ import java.util.regex.Pattern; public final class ProtocolDefinition { public static final int STRING_MAX_LENGTH = 32767; public static final int DEFAULT_PORT = 25565; - public static final int SOCKET_CONNECT_TIMEOUT = 5000; public static final int SOCKET_TIMEOUT = 30000; public static final int STATUS_PROTOCOL_PACKET_MAX_SIZE = 1 << 16; public static final float ANGLE_CALCULATION_CONSTANT = 360.0F / 256.0F; @@ -51,10 +50,7 @@ public final class ProtocolDefinition { public static final Pattern MINECRAFT_NAME_VALIDATOR = Pattern.compile("\\w{3,16}"); - public static final Pattern RESOURCE_LOCATION_PATTERN = Pattern.compile("([a-z_0-9]+:)?[a-zA-Z_0-9.]+"); - public static final Pattern SCOREBOARD_OBJECTIVE_PATTERN = Pattern.compile("[a-zA-z-.+]{1,16}"); - public static final int SECTION_SIZE = 16; public static final int SECTION_WIDTH_X = 16; public static final int SECTION_MAX_X = SECTION_WIDTH_X - 1; public static final int SECTION_WIDTH_Z = 16; @@ -92,17 +88,15 @@ public final class ProtocolDefinition { public static final float TICKS_PER_DAYf = (float) TICKS_PER_DAY; public static final byte LIGHT_LEVELS = 16; - public static final byte MAX_LIGHT_LEVEL = LIGHT_LEVELS - 1; static { - // java does (why ever) not allow to directly assign a null - InetAddress tempInetAddress; + InetAddress inetAddress; try { - tempInetAddress = InetAddress.getByName(LAN_SERVER_BROADCAST_ADDRESS); + inetAddress = InetAddress.getByName(LAN_SERVER_BROADCAST_ADDRESS); } catch (Exception e) { e.printStackTrace(); - tempInetAddress = null; + inetAddress = null; } - LAN_SERVER_BROADCAST_INET_ADDRESS = tempInetAddress; + LAN_SERVER_BROADCAST_INET_ADDRESS = inetAddress; } }