[Bleeding] Implement Metadata framework for Entities, Blocks, and Worlds

This commit is contained in:
rmichela 2011-12-08 00:33:59 -05:00 committed by Erik Broes
parent 403f874784
commit 1394926e53
12 changed files with 305 additions and 2 deletions

View File

@ -35,6 +35,10 @@ public class CraftChunk implements Chunk {
return worldServer.getWorld();
}
public CraftWorld getCraftWorld() {
return (CraftWorld) getWorld();
}
public net.minecraft.server.Chunk getHandle() {
net.minecraft.server.Chunk c = weakChunk.get();
if (c == null) {

View File

@ -2,6 +2,7 @@ package org.bukkit.craftbukkit;
import java.io.File;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import net.minecraft.server.EntityPlayer;
import net.minecraft.server.NBTTagCompound;
@ -13,6 +14,8 @@ import org.bukkit.Server;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.SerializableAs;
import org.bukkit.entity.Player;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin;
@SerializableAs("Player")
public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializable {
@ -198,4 +201,20 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa
}
return null;
}
public void setMetadata(String metadataKey, MetadataValue metadataValue) {
server.getPlayerMetadata().setMetadata(this, metadataKey, metadataValue);
}
public List<MetadataValue> getMetadata(String metadataKey) {
return server.getPlayerMetadata().getMetadata(this, metadataKey);
}
public boolean hasMetadata(String metadataKey) {
return server.getPlayerMetadata().hasMetadata(this, metadataKey);
}
public void removeMetadata(String metadataKey, Plugin plugin) {
server.getPlayerMetadata().removeMetadata(this, metadataKey, plugin);
}
}

View File

@ -64,6 +64,9 @@ import org.bukkit.craftbukkit.inventory.CraftShapedRecipe;
import org.bukkit.craftbukkit.inventory.CraftShapelessRecipe;
import org.bukkit.craftbukkit.inventory.RecipeIterator;
import org.bukkit.craftbukkit.map.CraftMapView;
import org.bukkit.craftbukkit.metadata.EntityMetadataStore;
import org.bukkit.craftbukkit.metadata.PlayerMetadataStore;
import org.bukkit.craftbukkit.metadata.WorldMetadataStore;
import org.bukkit.craftbukkit.potion.CraftPotionBrewer;
import org.bukkit.craftbukkit.scheduler.CraftScheduler;
import org.bukkit.craftbukkit.updater.AutoUpdater;
@ -127,6 +130,9 @@ public final class CraftServer implements Server {
private final Yaml yaml = new Yaml(new SafeConstructor());
private final Map<String, OfflinePlayer> offlinePlayers = new MapMaker().softValues().makeMap();
private AutoUpdater updater;
private final EntityMetadataStore entityMetadata = new EntityMetadataStore();
private final PlayerMetadataStore playerMetadata = new PlayerMetadataStore();
private final WorldMetadataStore worldMetadata = new WorldMetadataStore();
static {
ConfigurationSerialization.registerClass(CraftOfflinePlayer.class);
@ -1015,6 +1021,18 @@ public final class CraftServer implements Server {
return console.console;
}
public EntityMetadataStore getEntityMetadata() {
return entityMetadata;
}
public PlayerMetadataStore getPlayerMetadata() {
return playerMetadata;
}
public WorldMetadataStore getWorldMetadata() {
return worldMetadata;
}
public void detectListNameConflict(EntityPlayer entityPlayer) {
// Collisions will make for invisible people
for (int i = 0; i < getHandle().players.size(); ++i) {

View File

@ -6,6 +6,7 @@ import java.util.Set;
import org.apache.commons.lang.Validate;
import org.bukkit.craftbukkit.entity.*;
import org.bukkit.craftbukkit.metadata.BlockMetadataStore;
import org.bukkit.entity.*;
import org.bukkit.entity.Entity;
@ -30,6 +31,7 @@ import org.bukkit.block.BlockFace;
import org.bukkit.entity.Boat;
import org.bukkit.Chunk;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.Vector;
import org.bukkit.BlockChangeDelegate;
@ -53,6 +55,7 @@ public class CraftWorld implements World {
private ConcurrentMap<Integer, CraftChunk> unloadedChunks = new MapMaker().weakValues().makeMap();
private final ChunkGenerator generator;
private final List<BlockPopulator> populators = new ArrayList<BlockPopulator>();
private final BlockMetadataStore blockMetadata = new BlockMetadataStore(this);
private static final Random rand = new Random();
@ -631,6 +634,10 @@ public class CraftWorld implements World {
return Difficulty.getByValue(this.getHandle().difficulty);
}
public BlockMetadataStore getBlockMetadata() {
return blockMetadata;
}
public boolean hasStorm() {
return world.worldData.hasStorm();
}
@ -1031,4 +1038,20 @@ public class CraftWorld implements World {
public void setTicksPerMonsterSpawns(int ticksPerMonsterSpawns) {
world.ticksPerMonsterSpawns = ticksPerMonsterSpawns;
}
public void setMetadata(String metadataKey, MetadataValue newMetadataValue) {
server.getWorldMetadata().setMetadata(this, metadataKey, newMetadataValue);
}
public List<MetadataValue> getMetadata(String metadataKey) {
return server.getWorldMetadata().getMetadata(this, metadataKey);
}
public boolean hasMetadata(String metadataKey) {
return server.getWorldMetadata().hasMetadata(this, metadataKey);
}
public void removeMetadata(String metadataKey, Plugin owningPlugin) {
server.getWorldMetadata().removeMetadata(this, metadataKey, owningPlugin);
}
}

View File

@ -3,7 +3,6 @@ package org.bukkit.craftbukkit.block;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import net.minecraft.server.BiomeBase;
import net.minecraft.server.BlockRedstoneWire;
@ -20,8 +19,12 @@ import org.bukkit.block.BlockState;
import org.bukkit.block.PistonMoveReaction;
import org.bukkit.craftbukkit.CraftChunk;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.BlockVector;
import java.util.List;
public class CraftBlock implements Block {
private final CraftChunk chunk;
private final int x;
@ -404,4 +407,20 @@ public class CraftBlock implements Block {
}
}
}
public void setMetadata(String metadataKey, MetadataValue newMetadataValue) {
chunk.getCraftWorld().getBlockMetadata().setMetadata(this, metadataKey, newMetadataValue);
}
public List<MetadataValue> getMetadata(String metadataKey) {
return chunk.getCraftWorld().getBlockMetadata().getMetadata(this, metadataKey);
}
public boolean hasMetadata(String metadataKey) {
return chunk.getCraftWorld().getBlockMetadata().hasMetadata(this, metadataKey);
}
public void removeMetadata(String metadataKey, Plugin owningPlugin) {
chunk.getCraftWorld().getBlockMetadata().removeMetadata(this, metadataKey, owningPlugin);
}
}

View File

@ -9,6 +9,10 @@ import org.bukkit.block.BlockState;
import org.bukkit.craftbukkit.CraftChunk;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.material.MaterialData;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin;
import java.util.List;
public class CraftBlockState implements BlockState {
private final CraftWorld world;
@ -189,4 +193,20 @@ public class CraftBlockState implements BlockState {
hash = 73 * hash + (this.data != null ? this.data.hashCode() : 0);
return hash;
}
public void setMetadata(String metadataKey, MetadataValue newMetadataValue) {
chunk.getCraftWorld().getBlockMetadata().setMetadata(getBlock(), metadataKey, newMetadataValue);
}
public List<MetadataValue> getMetadata(String metadataKey) {
return chunk.getCraftWorld().getBlockMetadata().getMetadata(getBlock(), metadataKey);
}
public boolean hasMetadata(String metadataKey) {
return chunk.getCraftWorld().getBlockMetadata().hasMetadata(getBlock(), metadataKey);
}
public void removeMetadata(String metadataKey, Plugin owningPlugin) {
chunk.getCraftWorld().getBlockMetadata().removeMetadata(getBlock(), metadataKey, owningPlugin);
}
}

View File

@ -10,6 +10,8 @@ import org.bukkit.World;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.Vector;
import java.util.List;
@ -324,4 +326,20 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
hash = 29 * hash + this.getEntityId();
return hash;
}
public void setMetadata(String metadataKey, MetadataValue newMetadataValue) {
server.getEntityMetadata().setMetadata(this, metadataKey, newMetadataValue);
}
public List<MetadataValue> getMetadata(String metadataKey) {
return server.getEntityMetadata().getMetadata(this, metadataKey);
}
public boolean hasMetadata(String metadataKey) {
return server.getEntityMetadata().hasMetadata(this, metadataKey);
}
public void removeMetadata(String metadataKey, Plugin owningPlugin) {
server.getEntityMetadata().removeMetadata(this, metadataKey, owningPlugin);
}
}

View File

@ -8,6 +8,7 @@ import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
@ -29,6 +30,7 @@ import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerGameModeChangeEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.map.MapView;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.messaging.StandardMessenger;
@ -705,4 +707,23 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
public EntityType getType() {
return EntityType.PLAYER;
}
public void setMetadata(String metadataKey, MetadataValue newMetadataValue) {
server.getPlayerMetadata().setMetadata(this, metadataKey, newMetadataValue);
}
@Override
public List<MetadataValue> getMetadata(String metadataKey) {
return server.getPlayerMetadata().getMetadata(this, metadataKey);
}
@Override
public boolean hasMetadata(String metadataKey) {
return server.getPlayerMetadata().hasMetadata(this, metadataKey);
}
@Override
public void removeMetadata(String metadataKey, Plugin owningPlugin) {
server.getPlayerMetadata().removeMetadata(this, metadataKey, owningPlugin);
}
}

View File

@ -0,0 +1,94 @@
package org.bukkit.craftbukkit.metadata;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.metadata.MetadataStore;
import org.bukkit.metadata.MetadataStoreBase;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin;
import java.util.List;
/**
* A BlockMetadataStore stores metadata values for {@link Block} objects.
*/
public class BlockMetadataStore extends MetadataStoreBase<Block> implements MetadataStore<Block> {
private World owningWorld;
/**
* Initializes a BlockMetadataStore.
* @param owningWorld The world to which this BlockMetadataStore belongs.
*/
public BlockMetadataStore(World owningWorld) {
this.owningWorld = owningWorld;
}
/**
* Generates a unique metadata key for a {@link Block} object based on its coordinates in the world.
* @see MetadataStoreBase#disambiguate(Object, String)
* @param block the block
* @param metadataKey The name identifying the metadata value
* @return a unique metadata key
*/
@Override
protected String disambiguate(Block block, String metadataKey) {
return Integer.toString(block.getX()) + ":" + Integer.toString(block.getY()) + ":" + Integer.toString(block.getZ()) + ":" + metadataKey;
}
/**
* Retrieves the metadata for a {@link Block}, ensuring the block being asked for actually belongs to this BlockMetadataStore's
* owning world.
* @see MetadataStoreBase#getMetadata(Object, String)
*/
@Override
public List<MetadataValue> getMetadata(Block block, String metadataKey) {
if(block.getWorld() == owningWorld) {
return super.getMetadata(block, metadataKey);
} else {
throw new IllegalArgumentException("Block does not belong to world " + owningWorld.getName());
}
}
/**
* Tests to see if a metadata value has been added to a {@link Block}, ensuring the block being interrogated belongs
* to this BlockMetadataStore's owning world.
* @see MetadataStoreBase#hasMetadata(Object, String)
*/
@Override
public boolean hasMetadata(Block block, String metadataKey) {
if(block.getWorld() == owningWorld) {
return super.hasMetadata(block, metadataKey);
} else {
throw new IllegalArgumentException("Block does not belong to world " + owningWorld.getName());
}
}
/**
* Removes metadata from from a {@link Block} belonging to a given {@link Plugin}, ensuring the block being deleted from belongs
* to this BlockMetadataStore's owning world.
* @see MetadataStoreBase#removeMetadata(Object, String, org.bukkit.plugin.Plugin)
*/
@Override
public void removeMetadata(Block block, String metadataKey, Plugin owningPlugin) {
if(block.getWorld() == owningWorld) {
super.removeMetadata(block, metadataKey, owningPlugin);
} else {
throw new IllegalArgumentException("Block does not belong to world " + owningWorld.getName());
}
}
/**
* Sets or overwrites a metadata value on a {@link Block} from a given {@link Plugin}, ensuring the target block belongs
* to this BlockMetadataStore's owning world.
* @see MetadataStoreBase#setMetadata(Object, String, org.bukkit.metadata.MetadataValue)
*/
@Override
public void setMetadata(Block block, String metadataKey, MetadataValue newMetadataValue) {
if(block.getWorld() == owningWorld) {
super.setMetadata(block, metadataKey, newMetadataValue);
} else {
throw new IllegalArgumentException("Block does not belong to world " + owningWorld.getName());
}
}
}

View File

@ -0,0 +1,22 @@
package org.bukkit.craftbukkit.metadata;
import org.bukkit.entity.Entity;
import org.bukkit.metadata.MetadataStore;
import org.bukkit.metadata.MetadataStoreBase;
/**
* An EntityMetadataStore stores metadata values for all {@link Entity} classes an their descendants.
*/
public class EntityMetadataStore extends MetadataStoreBase<Entity> implements MetadataStore<Entity> {
/**
* Generates a unique metadata key for an {@link Entity} entity ID.
* @see MetadataStoreBase#disambiguate(Object, String)
* @param entity the entity
* @param metadataKey The name identifying the metadata value
* @return a unique metadata key
*/
@Override
protected String disambiguate(Entity entity, String metadataKey) {
return Integer.toString(entity.getEntityId()) + ":" + metadataKey;
}
}

View File

@ -0,0 +1,23 @@
package org.bukkit.craftbukkit.metadata;
import org.bukkit.OfflinePlayer;
import org.bukkit.metadata.MetadataStore;
import org.bukkit.metadata.MetadataStoreBase;
/**
* A PlayerMetadataStore stores metadata for {@link org.bukkit.entity.Player} and {@link OfflinePlayer} objects.
*/
public class PlayerMetadataStore extends MetadataStoreBase<OfflinePlayer> implements MetadataStore<OfflinePlayer> {
/**
* Generates a unique metadata key for {@link org.bukkit.entity.Player} and {@link OfflinePlayer} using the player
* name.
* @see MetadataStoreBase#disambiguate(Object, String)
* @param player the player
* @param metadataKey The name identifying the metadata value
* @return a unique metadata key
*/
@Override
protected String disambiguate(OfflinePlayer player, String metadataKey) {
return player.getName().toLowerCase() + ":" + metadataKey;
}
}

View File

@ -0,0 +1,22 @@
package org.bukkit.craftbukkit.metadata;
import org.bukkit.World;
import org.bukkit.metadata.MetadataStore;
import org.bukkit.metadata.MetadataStoreBase;
/**
* An WorldMetadataStore stores metadata values for {@link World} objects.
*/
public class WorldMetadataStore extends MetadataStoreBase<World> implements MetadataStore<World> {
/**
* Generates a unique metadata key for a {@link World} object based on the world UID.
* @see WorldMetadataStore#disambiguate(Object, String)
* @param world the world
* @param metadataKey The name identifying the metadata value
* @return a unique metadata key
*/
@Override
protected String disambiguate(World world, String metadataKey) {
return world.getUID().toString() + ":" + metadataKey;
}
}