Block Tracking
Block Tracking
Section titled “Block Tracking”The block tracking system tracks which player placed blocks and maintains placement counts per chunk.
Package Location
Section titled “Package Location”- Components:
com.hypixel.hytale.server.core.modules.interaction.components - Block Track:
com.hypixel.hytale.server.core.modules.interaction.blocktrack
Overview
Section titled “Overview”When blocks are placed via the interaction system, two tracking mechanisms are available:
- PlacedByInteractionComponent - Tracks who placed a specific block
- TrackedPlacement + BlockCounter - Counts placements by block type
PlacedByInteractionComponent
Section titled “PlacedByInteractionComponent”Tracks which player placed a block:
package com.hypixel.hytale.server.core.modules.interaction.components;
public class PlacedByInteractionComponent implements Component<ChunkStore> { // Constructor public PlacedByInteractionComponent(UUID whoPlacedUuid);
// Get placer UUID public UUID getWhoPlacedUuid();
// Get component type public static ComponentType<ChunkStore, PlacedByInteractionComponent> getComponentType();}Usage Example
Section titled “Usage Example”import com.hypixel.hytale.server.core.modules.interaction.components.PlacedByInteractionComponent;import com.hypixel.hytale.server.core.modules.interaction.InteractionModule;import java.util.UUID;
// Get component from blockRef<ChunkStore> blockRef = /* block reference */;PlacedByInteractionComponent placedBy = commandBuffer.getComponent( blockRef, InteractionModule.get().getPlacedByComponentType());
if (placedBy != null) { UUID placerUuid = placedBy.getWhoPlacedUuid();
// Find the player who placed it Ref<EntityStore> placerRef = entityStore.getRefFromUUID(placerUuid); if (placerRef != null && placerRef.isValid()) { // Player is online }}Listening for Block Placements
Section titled “Listening for Block Placements”import com.hypixel.hytale.component.system.RefChangeSystem;import com.hypixel.hytale.server.core.modules.interaction.components.PlacedByInteractionComponent;
public class BlockPlaceListener extends RefChangeSystem<ChunkStore, PlacedByInteractionComponent> {
@Override public void onComponentAdded( Ref<ChunkStore> blockRef, PlacedByInteractionComponent placedBy, Store<ChunkStore> chunkStore, CommandBuffer<ChunkStore> commandBuffer ) { UUID placerUuid = placedBy.getWhoPlacedUuid();
// Get block info BlockModule.BlockStateInfo blockInfo = chunkStore.getComponent( blockRef, BlockModule.BlockStateInfo.getComponentType() );
String blockType = blockInfo.getBlockTypeName();
// React to placement getLogger().info(placerUuid + " placed " + blockType); }
@Override public void onComponentRemoved( Ref<ChunkStore> blockRef, PlacedByInteractionComponent placedBy, Store<ChunkStore> chunkStore, CommandBuffer<ChunkStore> commandBuffer ) { // Block was destroyed }}TrackedPlacement
Section titled “TrackedPlacement”Tracks block type for counting:
package com.hypixel.hytale.server.core.modules.interaction.blocktrack;
public class TrackedPlacement implements Component<ChunkStore> { // Constructor public TrackedPlacement(String blockName);
// Get block name public String getBlockName();
// Get component type public static ComponentType<ChunkStore, TrackedPlacement> getComponentType();}BlockCounter
Section titled “BlockCounter”Resource maintaining per-chunk block placement counts:
package com.hypixel.hytale.server.core.modules.interaction.blocktrack;
public class BlockCounter implements Resource<ChunkStore> { // Track a block placement public void trackBlock(String blockName);
// Untrack a block (when destroyed) public void untrackBlock(String blockName);
// Get count for block type public int getBlockPlacementCount(String blockName);}Usage Example
Section titled “Usage Example”import com.hypixel.hytale.server.core.modules.interaction.blocktrack.BlockCounter;import com.hypixel.hytale.server.core.modules.interaction.InteractionModule;
// Get block counter for chunkBlockCounter counter = commandBuffer.getResource( InteractionModule.get().getBlockCounterResourceType());
// Check how many stone blocks placedint stoneCount = counter.getBlockPlacementCount("Stone");
// Check grass blocksint grassCount = counter.getBlockPlacementCount("Grass");
// Total player-placed blocksint total = stoneCount + grassCount; // etc.Automatic Tracking
Section titled “Automatic Tracking”The system automatically:
- Adds
TrackedPlacementwhen a block is placed via interaction - Updates
BlockCounterwhenTrackedPlacementis added/removed - Removes tracking when blocks are destroyed
Block Placed → TrackedPlacement Added → BlockCounter.trackBlock()Block Broken → TrackedPlacement Removed → BlockCounter.untrackBlock()Practical Example: Protected Blocks
Section titled “Practical Example: Protected Blocks”Track blocks that only the placer can break:
import com.hypixel.hytale.server.core.event.events.ecs.BreakBlockEvent;
@Overrideprotected void setup() { getEventRegistry().register(BreakBlockEvent.class, this::onBreakBlock);}
private void onBreakBlock(BreakBlockEvent event) { // Get block reference Ref<ChunkStore> blockRef = event.getBlockRef();
// Check who placed it PlacedByInteractionComponent placedBy = getComponent( blockRef, InteractionModule.get().getPlacedByComponentType() );
if (placedBy != null) { UUID placerUuid = placedBy.getWhoPlacedUuid(); UUID breakerUuid = event.getPlayerUuid();
// Only placer can break if (!placerUuid.equals(breakerUuid)) { event.setCancelled(true); // Send message to player } }}Practical Example: Placement Limits
Section titled “Practical Example: Placement Limits”Limit how many blocks of a type can be placed:
import com.hypixel.hytale.server.core.event.events.ecs.PlaceBlockEvent;
private static final int MAX_TNT_PER_CHUNK = 10;
private void onPlaceBlock(PlaceBlockEvent event) { BlockType blockType = event.getBlockType();
if (blockType.getId().equals("tnt")) { // Get block counter BlockCounter counter = getBlockCounter(event.getChunk());
int tntCount = counter.getBlockPlacementCount("TNT");
if (tntCount >= MAX_TNT_PER_CHUNK) { event.setCancelled(true); // Send limit message } }}Serialization
Section titled “Serialization”Both components serialize with entity/chunk data:
PlacedByInteractionComponent:
{ "PlacedByInteraction": { "UUID": "550e8400-e29b-41d4-a716-446655440000" }}TrackedPlacement:
{ "TrackedPlacement": { "BlockName": "Stone" }}BlockCounter:
{ "BlockCounter": { "Stone": 42, "Grass": 15, "Wood": 23 }}Related
Section titled “Related”- Interaction System - Interaction overview
- Event System - Block events
- Block System - Block types