354 lines
10 KiB
Java
Executable file
354 lines
10 KiB
Java
Executable file
package game.entity;
|
|
|
|
import java.io.IOException;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.concurrent.locks.ReadWriteLock;
|
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|
|
|
import com.google.common.collect.Lists;
|
|
import com.google.common.collect.Maps;
|
|
|
|
import game.item.ItemStack;
|
|
import game.network.PacketBuffer;
|
|
import game.world.BlockPos;
|
|
|
|
public class DataWatcher {
|
|
private static final Map<Class<?>, Integer> dataTypes = Maps.<Class<?>, Integer>newHashMap();
|
|
|
|
private final Entity owner;
|
|
private final Map<Integer, DataWatcher.WatchableObject> objects = Maps.<Integer, DataWatcher.WatchableObject>newHashMap();
|
|
private final ReadWriteLock lock = new ReentrantReadWriteLock();
|
|
|
|
private boolean blank = true;
|
|
private boolean changed;
|
|
|
|
public DataWatcher(Entity owner) {
|
|
this.owner = owner;
|
|
}
|
|
|
|
public <T> void addObject(int id, T object) {
|
|
Integer integer = (Integer)dataTypes.get(object.getClass());
|
|
|
|
if(integer == null) {
|
|
throw new IllegalArgumentException("Unknown data type: " + object.getClass());
|
|
}
|
|
else if(id > 31) {
|
|
throw new IllegalArgumentException("Data value id is too big with " + id + "! (Max is " + 31 + ")");
|
|
}
|
|
else if(this.objects.containsKey(Integer.valueOf(id))) {
|
|
throw new IllegalArgumentException("Duplicate id value for " + id + "!");
|
|
}
|
|
else {
|
|
DataWatcher.WatchableObject datawatcher$watchableobject = new DataWatcher.WatchableObject(integer.intValue(), id, object);
|
|
this.lock.writeLock().lock();
|
|
this.objects.put(Integer.valueOf(id), datawatcher$watchableobject);
|
|
this.lock.writeLock().unlock();
|
|
this.blank = false;
|
|
}
|
|
}
|
|
|
|
public void addObjectByDataType(int id, int type) {
|
|
DataWatcher.WatchableObject datawatcher$watchableobject = new DataWatcher.WatchableObject(type, id, (Object)null);
|
|
this.lock.writeLock().lock();
|
|
this.objects.put(Integer.valueOf(id), datawatcher$watchableobject);
|
|
this.lock.writeLock().unlock();
|
|
this.blank = false;
|
|
}
|
|
|
|
public byte getWatchableObjectByte(int id) {
|
|
return ((Byte)this.getWatchedObject(id).getObject()).byteValue();
|
|
}
|
|
|
|
public short getWatchableObjectShort(int id) {
|
|
return ((Short)this.getWatchedObject(id).getObject()).shortValue();
|
|
}
|
|
|
|
public int getWatchableObjectInt(int id) {
|
|
return ((Integer)this.getWatchedObject(id).getObject()).intValue();
|
|
}
|
|
|
|
public float getWatchableObjectFloat(int id) {
|
|
return ((Float)this.getWatchedObject(id).getObject()).floatValue();
|
|
}
|
|
|
|
public String getWatchableObjectString(int id) {
|
|
return (String)this.getWatchedObject(id).getObject();
|
|
}
|
|
|
|
public ItemStack getWatchableObjectItemStack(int id) {
|
|
return (ItemStack)this.getWatchedObject(id).getObject();
|
|
}
|
|
|
|
private DataWatcher.WatchableObject getWatchedObject(int id) {
|
|
this.lock.readLock().lock();
|
|
DataWatcher.WatchableObject datawatcher$watchableobject = (DataWatcher.WatchableObject)this.objects.get(Integer.valueOf(id));
|
|
|
|
this.lock.readLock().unlock();
|
|
return datawatcher$watchableobject;
|
|
}
|
|
|
|
// public Rotations getWatchableObjectRotations(int id) {
|
|
// return (Rotations)this.getWatchedObject(id).getObject();
|
|
// }
|
|
|
|
public <T> void updateObject(int id, T newData) {
|
|
DataWatcher.WatchableObject datawatcher$watchableobject = this.getWatchedObject(id);
|
|
|
|
if(!(newData == datawatcher$watchableobject.getObject()
|
|
|| (newData != null && datawatcher$watchableobject.getObject() != null ? newData.equals(datawatcher$watchableobject.getObject())
|
|
: false))) {
|
|
datawatcher$watchableobject.setObject(newData);
|
|
this.owner.onDataWatcherUpdate(id);
|
|
datawatcher$watchableobject.setWatched(true);
|
|
this.changed = true;
|
|
}
|
|
}
|
|
|
|
public void setObjectWatched(int id) {
|
|
this.getWatchedObject(id).watched = true;
|
|
this.changed = true;
|
|
}
|
|
|
|
public boolean hasObjectChanged() {
|
|
return this.changed;
|
|
}
|
|
|
|
public static void writeWatchedListToPacketBuffer(List<DataWatcher.WatchableObject> objectsList, PacketBuffer buffer) throws IOException {
|
|
if(objectsList != null) {
|
|
for(DataWatcher.WatchableObject datawatcher$watchableobject : objectsList) {
|
|
writeWatchableObjectToPacketBuffer(buffer, datawatcher$watchableobject);
|
|
}
|
|
}
|
|
|
|
buffer.writeByte(127);
|
|
}
|
|
|
|
public List<DataWatcher.WatchableObject> getChanged() {
|
|
List<DataWatcher.WatchableObject> list = null;
|
|
|
|
if(this.changed) {
|
|
this.lock.readLock().lock();
|
|
|
|
for(DataWatcher.WatchableObject datawatcher$watchableobject : this.objects.values()) {
|
|
if(datawatcher$watchableobject.isWatched()) {
|
|
datawatcher$watchableobject.setWatched(false);
|
|
|
|
if(list == null) {
|
|
list = Lists.<DataWatcher.WatchableObject>newArrayList();
|
|
}
|
|
|
|
list.add(datawatcher$watchableobject);
|
|
}
|
|
}
|
|
|
|
this.lock.readLock().unlock();
|
|
}
|
|
|
|
this.changed = false;
|
|
return list;
|
|
}
|
|
|
|
public void writeTo(PacketBuffer buffer) throws IOException {
|
|
this.lock.readLock().lock();
|
|
|
|
for(DataWatcher.WatchableObject datawatcher$watchableobject : this.objects.values()) {
|
|
writeWatchableObjectToPacketBuffer(buffer, datawatcher$watchableobject);
|
|
}
|
|
|
|
this.lock.readLock().unlock();
|
|
buffer.writeByte(127);
|
|
}
|
|
|
|
public List<DataWatcher.WatchableObject> getAllWatched() {
|
|
List<DataWatcher.WatchableObject> list = null;
|
|
this.lock.readLock().lock();
|
|
|
|
for(DataWatcher.WatchableObject datawatcher$watchableobject : this.objects.values()) {
|
|
if(list == null) {
|
|
list = Lists.<DataWatcher.WatchableObject>newArrayList();
|
|
}
|
|
|
|
list.add(datawatcher$watchableobject);
|
|
}
|
|
|
|
this.lock.readLock().unlock();
|
|
return list;
|
|
}
|
|
|
|
private static void writeWatchableObjectToPacketBuffer(PacketBuffer buffer, DataWatcher.WatchableObject object) throws IOException {
|
|
int i = (object.getObjectType() << 5 | object.getDataValueId() & 31) & 255;
|
|
buffer.writeByte(i);
|
|
|
|
switch(object.getObjectType()) {
|
|
case 0:
|
|
buffer.writeByte(((Byte)object.getObject()).byteValue());
|
|
break;
|
|
|
|
case 1:
|
|
buffer.writeShort(((Short)object.getObject()).shortValue());
|
|
break;
|
|
|
|
case 2:
|
|
buffer.writeInt(((Integer)object.getObject()).intValue());
|
|
break;
|
|
|
|
case 3:
|
|
buffer.writeFloat(((Float)object.getObject()).floatValue());
|
|
break;
|
|
|
|
case 4:
|
|
buffer.writeString((String)object.getObject());
|
|
break;
|
|
|
|
case 5:
|
|
ItemStack itemstack = (ItemStack)object.getObject();
|
|
buffer.writeItemStackToBuffer(itemstack);
|
|
break;
|
|
|
|
case 6:
|
|
BlockPos blockpos = (BlockPos)object.getObject();
|
|
buffer.writeInt(blockpos.getX());
|
|
buffer.writeInt(blockpos.getY());
|
|
buffer.writeInt(blockpos.getZ());
|
|
// break;
|
|
//
|
|
// case 7:
|
|
// Rotations rotations = (Rotations)object.getObject();
|
|
// buffer.writeFloat(rotations.getX());
|
|
// buffer.writeFloat(rotations.getY());
|
|
// buffer.writeFloat(rotations.getZ());
|
|
}
|
|
}
|
|
|
|
public static List<DataWatcher.WatchableObject> readWatchedListFromPacketBuffer(PacketBuffer buffer) throws IOException {
|
|
List<DataWatcher.WatchableObject> list = null;
|
|
|
|
for(int i = buffer.readByte(); i != 127; i = buffer.readByte()) {
|
|
if(list == null) {
|
|
list = Lists.<DataWatcher.WatchableObject>newArrayList();
|
|
}
|
|
|
|
int j = (i & 224) >> 5;
|
|
int k = i & 31;
|
|
DataWatcher.WatchableObject datawatcher$watchableobject = null;
|
|
|
|
switch(j) {
|
|
case 0:
|
|
datawatcher$watchableobject = new DataWatcher.WatchableObject(j, k, Byte.valueOf(buffer.readByte()));
|
|
break;
|
|
|
|
case 1:
|
|
datawatcher$watchableobject = new DataWatcher.WatchableObject(j, k, Short.valueOf(buffer.readShort()));
|
|
break;
|
|
|
|
case 2:
|
|
datawatcher$watchableobject = new DataWatcher.WatchableObject(j, k, Integer.valueOf(buffer.readInt()));
|
|
break;
|
|
|
|
case 3:
|
|
datawatcher$watchableobject = new DataWatcher.WatchableObject(j, k, Float.valueOf(buffer.readFloat()));
|
|
break;
|
|
|
|
case 4:
|
|
datawatcher$watchableobject = new DataWatcher.WatchableObject(j, k, buffer.readStringFromBuffer(32767));
|
|
break;
|
|
|
|
case 5:
|
|
datawatcher$watchableobject = new DataWatcher.WatchableObject(j, k, buffer.readItemStackFromBuffer());
|
|
break;
|
|
|
|
case 6:
|
|
int l = buffer.readInt();
|
|
int i1 = buffer.readInt();
|
|
int j1 = buffer.readInt();
|
|
datawatcher$watchableobject = new DataWatcher.WatchableObject(j, k, new BlockPos(l, i1, j1));
|
|
// break;
|
|
//
|
|
// case 7:
|
|
// float f = buffer.readFloat();
|
|
// float f1 = buffer.readFloat();
|
|
// float f2 = buffer.readFloat();
|
|
// datawatcher$watchableobject = new DataWatcher.WatchableObject(j, k, new Rotations(f, f1, f2));
|
|
}
|
|
|
|
list.add(datawatcher$watchableobject);
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
public void updateWatchedObjectsFromList(List<DataWatcher.WatchableObject> p_75687_1_) {
|
|
this.lock.writeLock().lock();
|
|
|
|
for(DataWatcher.WatchableObject datawatcher$watchableobject : p_75687_1_) {
|
|
DataWatcher.WatchableObject datawatcher$watchableobject1 = (DataWatcher.WatchableObject)this.objects
|
|
.get(Integer.valueOf(datawatcher$watchableobject.getDataValueId()));
|
|
|
|
if(datawatcher$watchableobject1 != null) {
|
|
datawatcher$watchableobject1.setObject(datawatcher$watchableobject.getObject());
|
|
this.owner.onDataWatcherUpdate(datawatcher$watchableobject.getDataValueId());
|
|
}
|
|
}
|
|
|
|
this.lock.writeLock().unlock();
|
|
this.changed = true;
|
|
}
|
|
|
|
public boolean isBlank() {
|
|
return this.blank;
|
|
}
|
|
|
|
public void markUnchanged() {
|
|
this.changed = false;
|
|
}
|
|
|
|
static {
|
|
dataTypes.put(Byte.class, Integer.valueOf(0));
|
|
dataTypes.put(Short.class, Integer.valueOf(1));
|
|
dataTypes.put(Integer.class, Integer.valueOf(2));
|
|
dataTypes.put(Float.class, Integer.valueOf(3));
|
|
dataTypes.put(String.class, Integer.valueOf(4));
|
|
dataTypes.put(ItemStack.class, Integer.valueOf(5));
|
|
dataTypes.put(BlockPos.class, Integer.valueOf(6));
|
|
// dataTypes.put(Rotations.class, Integer.valueOf(7));
|
|
}
|
|
|
|
public static class WatchableObject {
|
|
private final int objectType;
|
|
private final int dataValueId;
|
|
private Object watchedObject;
|
|
private boolean watched;
|
|
|
|
public WatchableObject(int type, int id, Object object) {
|
|
this.dataValueId = id;
|
|
this.watchedObject = object;
|
|
this.objectType = type;
|
|
this.watched = true;
|
|
}
|
|
|
|
public int getDataValueId() {
|
|
return this.dataValueId;
|
|
}
|
|
|
|
public void setObject(Object object) {
|
|
this.watchedObject = object;
|
|
}
|
|
|
|
public Object getObject() {
|
|
return this.watchedObject;
|
|
}
|
|
|
|
public int getObjectType() {
|
|
return this.objectType;
|
|
}
|
|
|
|
public boolean isWatched() {
|
|
return this.watched;
|
|
}
|
|
|
|
public void setWatched(boolean watched) {
|
|
this.watched = watched;
|
|
}
|
|
}
|
|
}
|