use of net.glowstone.block.entity.BlockEntity in project Glowstone by GlowstoneMC.
the class GlowChunk method toMessage.
/**
* Creates a new {@link ChunkDataMessage} which can be sent to a client to stream
* parts of this chunk to them.
*
* @param skylight Whether to include skylight data.
* @param entireChunk Whether to send all chunk sections.
* @return The {@link ChunkDataMessage}.
*/
public ChunkDataMessage toMessage(boolean skylight, boolean entireChunk) {
load();
int sectionBitmask = 0;
// filter sectionBitmask based on actual chunk contents
if (sections != null) {
int maxBitmask = (1 << sections.length) - 1;
if (entireChunk) {
sectionBitmask = maxBitmask;
} else {
sectionBitmask &= maxBitmask;
}
for (int i = 0; i < sections.length; ++i) {
if (sections[i] == null || sections[i].isEmpty()) {
// remove empty sections from bitmask
sectionBitmask &= ~(1 << i);
}
}
}
ByteBuf buf = Unpooled.buffer();
if (sections != null) {
// get the list of sections
for (int i = 0; i < sections.length; ++i) {
if ((sectionBitmask & 1 << i) == 0) {
continue;
}
sections[i].writeToBuf(buf, skylight);
}
}
// biomes
if (entireChunk && biomes != null) {
buf.writeBytes(biomes);
}
ArrayList<CompoundTag> blockEntities = new ArrayList<>();
for (BlockEntity blockEntity : getRawBlockEntities()) {
CompoundTag tag = new CompoundTag();
blockEntity.saveNbt(tag);
blockEntities.add(tag);
}
return new ChunkDataMessage(x, z, entireChunk, sectionBitmask, buf, blockEntities.toArray(new CompoundTag[blockEntities.size()]));
}
use of net.glowstone.block.entity.BlockEntity in project Glowstone by GlowstoneMC.
the class BlockPlacementHandler method revert.
static void revert(GlowPlayer player, GlowBlock target) {
player.sendBlockChange(target.getLocation(), target.getType(), target.getData());
BlockEntity entity = target.getBlockEntity();
if (entity != null) {
entity.update(player);
}
}
use of net.glowstone.block.entity.BlockEntity in project Glowstone by GlowstoneMC.
the class AnvilChunkIoService method read.
@Override
public boolean read(GlowChunk chunk) throws IOException {
int x = chunk.getX();
int z = chunk.getZ();
RegionFile region = cache.getRegionFile(x, z);
int regionX = x & REGION_SIZE - 1;
int regionZ = z & REGION_SIZE - 1;
if (!region.hasChunk(regionX, regionZ)) {
return false;
}
DataInputStream in = region.getChunkDataInputStream(regionX, regionZ);
CompoundTag levelTag;
try (NbtInputStream nbt = new NbtInputStream(in, false)) {
CompoundTag root = nbt.readCompound();
// NON-NLS
levelTag = root.getCompound("Level");
}
// read the vertical sections
// NON-NLS
List<CompoundTag> sectionList = levelTag.getCompoundList("Sections");
ChunkSection[] sections = new ChunkSection[GlowChunk.SEC_COUNT];
for (CompoundTag sectionTag : sectionList) {
// NON-NLS
int y = sectionTag.getByte("Y");
if (y < 0 || y > GlowChunk.SEC_COUNT) {
ConsoleMessages.Warn.Chunk.SECTION_OOB.log(y, chunk);
continue;
}
if (sections[y] != null) {
ConsoleMessages.Warn.Chunk.SECTION_DUP.log(y, chunk);
continue;
}
sections[y] = ChunkSection.fromNbt(sectionTag);
}
// initialize the chunk
chunk.initializeSections(sections);
// NON-NLS
chunk.setPopulated(levelTag.getBoolean("TerrainPopulated", false));
levelTag.readLong("InhabitedTime", chunk::setInhabitedTime);
// read biomes
// NON-NLS
levelTag.readByteArray("Biomes", chunk::setBiomes);
// read height map
if (!levelTag.readIntArray("HeightMap", chunk::setHeightMap)) {
// NON-NLS
chunk.automaticHeightMap();
}
// read slime chunk
// NON-NLS
levelTag.readByte("isSlimeChunk", chunk::setIsSlimeChunk);
// read entities
levelTag.iterateCompoundList("Entities", entityTag -> {
// NON-NLS
try {
// note that creating the entity is sufficient to add it to the world
EntityStorage.loadEntity(chunk.getWorld(), entityTag);
} catch (UnknownEntityTypeException e) {
ConsoleMessages.Warn.Entity.UNKNOWN.log(chunk, e.getIdOrTag());
} catch (Exception e) {
ConsoleMessages.Warn.Entity.LOAD_FAILED.log(e, chunk);
}
});
// read block entities
// NON-NLS
List<CompoundTag> storedBlockEntities = levelTag.getCompoundList("TileEntities");
BlockEntity blockEntity;
for (CompoundTag blockEntityTag : storedBlockEntities) {
// NON-NLS
int tx = blockEntityTag.getInt("x");
// NON-NLS
int ty = blockEntityTag.getInt("y");
// NON-NLS
int tz = blockEntityTag.getInt("z");
blockEntity = chunk.createEntity(tx & 0xf, ty, tz & 0xf, chunk.getType(tx & 0xf, tz & 0xf, ty));
if (blockEntity != null) {
try {
blockEntity.loadNbt(blockEntityTag);
} catch (Exception ex) {
// NON-NLS
String id = blockEntityTag.tryGetString("id").orElse("<missing>");
ConsoleMessages.Error.BlockEntity.LOAD_FAILED.log(ex, blockEntity.getBlock(), id);
}
} else {
String id = // NON-NLS
blockEntityTag.tryGetString("id").orElse("<missing>");
ConsoleMessages.Warn.BlockEntity.UNKNOWN.log(chunk.getWorld().getName(), tx, ty, tz, id);
}
}
levelTag.iterateCompoundList("TileTicks", tileTick -> {
// NON-NLS
// NON-NLS
int tileX = tileTick.getInt("x");
// NON-NLS
int tileY = tileTick.getInt("y");
// NON-NLS
int tileZ = tileTick.getInt("z");
// NON-NLS
String id = tileTick.getString("i");
Material material = ItemIds.getBlock(id);
if (material == null) {
ConsoleMessages.Warn.Chunk.UNKNOWN_BLOCK_TO_TICK.log(id);
return;
}
GlowBlock block = chunk.getBlock(tileX, tileY, tileZ);
if (material != block.getType()) {
return;
}
// TODO tick delay: tileTick.getInt("t");
// TODO ordering: tileTick.getInt("p");
BlockType type = ItemTable.instance().getBlock(material);
if (type == null) {
return;
}
block.getWorld().requestPulse(block);
});
return true;
}
use of net.glowstone.block.entity.BlockEntity in project Glowstone by GlowstoneMC.
the class BlockDispenser method trigger.
/**
* Dispense an item from the given block if it's a dispenser.
*
* @param block the dispenser block
*/
public void trigger(GlowBlock block) {
BlockEntity te = block.getBlockEntity();
if (!(te instanceof DispenserEntity)) {
return;
}
DispenserEntity teDispenser = (DispenserEntity) te;
GlowDispenser dispenser = (GlowDispenser) teDispenser.getState();
dispenser.dispense();
}
use of net.glowstone.block.entity.BlockEntity in project Glowstone by GlowstoneMC.
the class CloneCommand method execute.
@Override
public boolean execute(CommandSender sender, String label, String[] args, CommandMessages messages) {
if (!testPermission(sender, messages.getPermissionMessage())) {
return true;
}
if (args.length < 9) {
sendUsageMessage(sender, messages);
return false;
}
final ResourceBundle bundle = messages.getResourceBundle();
if (!CommandUtils.isPhysical(sender)) {
messages.getGeneric(GenericMessage.NOT_PHYSICAL).send(sender);
return false;
}
GlowWorld world = CommandUtils.getWorld(sender);
Location parsedFrom1 = CommandUtils.getLocation(sender, args[0], args[1], args[2]);
Location parsedFrom2 = CommandUtils.getLocation(sender, args[3], args[4], args[5]);
Location to = CommandUtils.getLocation(sender, args[6], args[7], args[8]);
MaskMode maskMode = args.length >= 10 ? MaskMode.fromCommandName(args[9]) : MaskMode.REPLACE;
CloneMode cloneMode = args.length >= 11 ? CloneMode.fromCommandName(args[10]) : CloneMode.NORMAL;
// TODO: Investigate what happens when maskMode or cloneMode are invalid (thus, null).
if (maskMode == null || cloneMode == null) {
sendUsageMessage(sender, messages);
return false;
}
BlockFilter blockFilter;
switch(maskMode) {
case REPLACE:
blockFilter = new ReplaceBlockFilter();
break;
case MASKED:
blockFilter = new MaskedBlockFilter();
break;
case FILTERED:
if (args.length >= 12) {
Material blockType = ItemIds.getItem(args[11]);
if (args.length >= 13) {
Byte data;
try {
data = Byte.parseByte(args[12]);
} catch (NumberFormatException ignored) {
data = null;
}
if (data == null || 0 > data || data > 15) {
new LocalizedStringImpl("clone.bad-blockdata", bundle).sendInColor(ChatColor.RED, sender);
return false;
} else {
blockFilter = new FilteredWithDataBlockFilter(blockType, data);
}
} else {
blockFilter = new FilteredBlockFilter(blockType);
}
} else {
new LocalizedStringImpl("clone.usage.filtered", bundle).sendInColor(ChatColor.RED, sender);
return false;
}
break;
default:
sendUsageMessage(sender, messages);
return false;
}
RectangularRegion fromRegion = new RectangularRegion(parsedFrom1, parsedFrom2);
RectangularRegion toRegion = fromRegion.moveTo(to);
Location lowCorner = fromRegion.getLowCorner();
Location highCorner = fromRegion.getHighCorner();
boolean overlaps = between(lowCorner.getBlockX(), highCorner.getBlockX(), to.getBlockX()) || between(lowCorner.getBlockY(), highCorner.getBlockY(), to.getBlockY()) || between(lowCorner.getBlockZ(), highCorner.getBlockZ(), to.getBlockZ());
if (overlaps && !cloneMode.isAllowedToOverlap()) {
sendUsageMessage(sender, messages);
return false;
}
int blocksCloned = 0;
IterationDirection directionX = to.getBlockX() < lowCorner.getBlockX() ? IterationDirection.FORWARDS : IterationDirection.BACKWARDS;
IterationDirection directionY = to.getBlockY() < lowCorner.getBlockY() ? IterationDirection.FORWARDS : IterationDirection.BACKWARDS;
IterationDirection directionZ = to.getBlockZ() < lowCorner.getBlockZ() ? IterationDirection.FORWARDS : IterationDirection.BACKWARDS;
Iterator<Location> fromIterator = fromRegion.blockLocations(directionX, directionY, directionZ).iterator();
Iterator<Location> toIterator = toRegion.blockLocations(directionX, directionY, directionZ).iterator();
while (fromIterator.hasNext() && toIterator.hasNext()) {
Location fromLocation = fromIterator.next();
Location toLocation = toIterator.next();
GlowBlock fromBlock = world.getBlockAt(fromLocation);
if (blockFilter.shouldClone(fromBlock)) {
GlowBlock toBlock = world.getBlockAt(toLocation);
toBlock.setType(fromBlock.getType());
toBlock.setBlockData(fromBlock.getBlockData());
BlockEntity fromEntity = fromBlock.getBlockEntity();
if (fromEntity != null) {
BlockEntity toEntity = toBlock.getChunk().createEntity(toBlock.getX(), toBlock.getY(), toBlock.getZ(), toBlock.getType());
if (toEntity != null) {
CompoundTag entityTag = new CompoundTag();
fromEntity.saveNbt(entityTag);
toEntity.loadNbt(entityTag);
}
}
if (cloneMode == CloneMode.MOVE) {
fromBlock.setType(Material.AIR, false);
}
blocksCloned++;
}
}
switch(blocksCloned) {
case 0:
new LocalizedStringImpl("clone.done.zero", bundle).sendInColor(ChatColor.RED, sender);
break;
case 1:
new LocalizedStringImpl("clone.done.singular", bundle).send(sender);
break;
default:
new LocalizedStringImpl("clone.done", bundle).send(sender, blocksCloned);
}
return true;
}
Aggregations