veconomie-1.0.1.jar
Curse Maven Snippet
What's new
Summary of changes (shop chests + hoppers)
A. Protecting shop chests and signs (breaking)
1. Shared helpers
- getShopRecordAt(Level, BlockPos) — Returns the ShopRecord if the block is a shop sign or chest (sign + chest/cluster), otherwise null.
- isShopBlockProtectedFrom(Level, BlockPos, ServerPlayer) — True when the block is a shop block and the player is not the owner (used to block breaking).
2. Blocking mining at click time (LeftClickBlock)
- onLeftClickBlock(PlayerInteractEvent.LeftClickBlock) — Server-side: if isShopBlockProtectedFrom(level, pos, sp), the event is cancelled (setCanceled, setUseBlock/setUseItem/setCancellationResult via reflection), ClientboundBlockUpdatePacket(level, pos) is sent for resync, and the message “This chest/sign belongs to a shop and cannot be broken.” is shown.
3. Safety net (BreakEvent)
- onBlockBreak(BlockEvent.BreakEvent) — When a non-owner breaks a shop sign or chest: cancel + visual resync player.connection.send(new ClientboundBlockUpdatePacket(level, pos)) + message. Owners can still break (shop is removed).
4. Break speed (BreakSpeed)
- onBreakSpeed(PlayerEvent.BreakSpeed) — Server-side: if isShopBlockProtectedFrom(level, pos, sp), event.setNewSpeed(0.0f) so the break progress bar does not advance.
5. Explosions
- onExplosionDetonate — Shop blocks (including chests) are removed from the explosion-affected block list (isShopBlockAt).
B. Opening shop chests (existing, unchanged)
- RightClickBlock (chest) — If the clicked block is a shop chest and the player is not the owner: opening is cancelled, ShopManager.markForceClose, container is closed, message “This chest is connected to a shop’s stock. Only the owner can open it.” (sneak + BlockItem still allows placing a block next to it).
C. Hoppers near shop chests
1. Hopper helpers
- isShopChestAt(Level, BlockPos) — True if the block at the position is a ChestBlock and getShopRecordAt returns a shop (shop chest only).
- isHopperPlacementForbidden(Level, BlockPos) — True if a shop chest is above (placePos.above()) or on any of the four horizontal sides (N/S/E/W).
- getHopperForbiddenPositionsAroundChest(BlockPos) — Returns a Set<BlockPos>: below chest, 4 sides, 4 below-adjacent (for cleanup).
- forceResync(ServerPlayer, Level, BlockPos) — Sends ClientboundBlockUpdatePacket for pos, pos.above(), and pos.below(), and calls level.sendBlockUpdated for those three positions (to reduce ghost blocks).
2. Blocking hopper placement
- At the start of onRightClickBlock: if the held item is a BlockItem whose block is a HopperBlock, compute placePos = clicked.relative(face). If isHopperPlacementForbidden(level, placePos): cancel, resync placePos and clicked, show message “Cannot place a hopper near or under a shop chest.” (and !stack.isEmpty() check).
- onBlockPlace — Server-side: if the placed block is a hopper and isHopperPlacementForbidden(level, event.getPos()): cancel, forceResync(sp, level, placePos), message, and log [HOPPER-BLOCK] CANCELED placement at {}. Debug log [HOPPER-BLOCK] fired dim=... client=... on each hopper placement.
- onBlockMultiPlace — Check main position event.getPos() then snapshots. As soon as a hopper position is forbidden: cancel, forceResync for that position, same message.
3. Cleanup of illegal hoppers (server cleanup)
- cleanupIllegalHoppers(ServerLevel level) — For the level’s dimension: collect all forbidden positions (via getHopperForbiddenPositionsAroundChest for each chest of each shop), deduplicated in a Set<BlockPos>. For each position: if the chunk is loaded and the block is a hopper, level.destroyBlock(pos, false) (no drop) and log [HOPPER-CLEANUP] removed hopper at {} dim={}.
- onServerTick — Every 20 ticks (1 second), for each ServerLevel: call cleanupIllegalHoppers(level).
D. Logging
- RightClickBlock: the always-on log was moved to debug (LOGGER.debug) to reduce spam.
- Hoppers: [HOPPER-BLOCK] fired ... and [HOPPER-BLOCK] CANCELED ... at info level; [HOPPER-CLEANUP] removed ... when an illegal hopper is destroyed.
E. Imports added (for these changes)
- Direction, ClientboundBlockUpdatePacket, Result, PlayerEvent, BlockItem, ItemStack, Block, ChestBlock, HopperBlock, HashSet, Set, ServerLevel.
This mod has no additional files

