Fix Attribute problem

This commit is contained in:
Xephi59 2015-06-17 21:48:38 +02:00
parent 17bfb57a97
commit 6d84cdabe7
5 changed files with 18 additions and 1642 deletions

View File

@ -120,12 +120,12 @@
</repository>
<!-- End of Spout Repo -->
<!-- Attribute Repo
<!-- Attribute Repo -->
<repository>
<id>comphenix-snapshots</id>
<name>Comphenix Maven Snapshots</name>
<url>http://repo.comphenix.net/content/repositories/snapshots/</url>
</repository> -->
</repository>
</repositories>
@ -165,13 +165,12 @@
<artifactId>mail</artifactId>
<version>1.5.0-b01</version>
</dependency>
<!-- Attribute, THIS DOESN?T WORK BECAUSE XEPHI USED A MODIFIED VERSION
<dependency>
<groupId>com.comphenix.attribute</groupId>
<artifactId>AttributeStorage</artifactId>
<version>0.0.2-SNAPSHOT</version>
</dependency> -->
</dependency>
<!-- Maxmind GeoIp API -->
<dependency>

View File

@ -1,144 +0,0 @@
package com.comphenix.attribute;
import java.util.UUID;
import org.bukkit.inventory.ItemStack;
import com.comphenix.attribute.Attributes.Attribute;
import com.comphenix.attribute.Attributes.AttributeType;
import com.comphenix.attribute.Attributes.Operation;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
/**
* Store meta-data in an ItemStack as attributes.
*
* @author Kristian
*/
public class AttributeStorage {
private ItemStack target;
private final UUID uniqueKey;
private AttributeStorage(ItemStack target, UUID uniqueKey) {
this.target = Preconditions.checkNotNull(target, "target cannot be NULL");
this.uniqueKey = Preconditions.checkNotNull(uniqueKey, "uniqueKey cannot be NULL");
}
/**
* Construct a new attribute storage system.
* <p>
* The key must be the same in order to retrieve the same data.
*
* @param target
* - the item stack where the data will be stored.
* @param uniqueKey
* - the unique key used to retrieve the correct data.
*/
public static AttributeStorage newTarget(ItemStack target, UUID uniqueKey) {
return new AttributeStorage(target, uniqueKey);
}
/**
* Retrieve the data stored in the item's attribute.
*
* @param defaultValue
* - the default value to return if no data can be found.
* @return The stored data, or defaultValue if not found.
*/
public String getData(String defaultValue) {
Attribute current = getAttribute(new Attributes(target), uniqueKey);
return current != null ? current.getName() : defaultValue;
}
/**
* Determine if we are storing any data.
*
* @return TRUE if we are, FALSE otherwise.
*/
public boolean hasData() {
return getAttribute(new Attributes(target), uniqueKey) != null;
}
/**
* Set the data stored in the attributes.
*
* @param data
* - the data.
*/
public void setData(String data) {
Attributes attributes = new Attributes(target);
Attribute current = getAttribute(attributes, uniqueKey);
if (current == null) {
attributes.add(Attribute.newBuilder().name(data).amount(getBaseDamage(target)).uuid(uniqueKey).operation(Operation.ADD_NUMBER).type(AttributeType.GENERIC_ATTACK_DAMAGE).build());
} else {
current.setName(data);
}
this.target = attributes.getStack();
}
/**
* Retrieve the base damage of the given item.
*
* @param stack
* - the stack.
* @return The base damage.
*/
private int getBaseDamage(ItemStack stack) {
// Yes - we have to hard code these values. Cannot use
// Operation.ADD_PERCENTAGE either.
switch (stack.getType()) {
case WOOD_SWORD:
return 4;
case GOLD_SWORD:
return 4;
case STONE_SWORD:
return 5;
case IRON_SWORD:
return 6;
case DIAMOND_SWORD:
return 7;
case WOOD_AXE:
return 3;
case GOLD_AXE:
return 3;
case STONE_AXE:
return 4;
case IRON_AXE:
return 5;
case DIAMOND_AXE:
return 6;
default:
return 0;
}
}
/**
* Retrieve the target stack. May have been changed.
*
* @return The target stack.
*/
public ItemStack getTarget() {
return target;
}
/**
* Retrieve an attribute by UUID.
*
* @param attributes
* - the attribute.
* @param id
* - the UUID to search for.
* @return The first attribute associated with this UUID, or NULL.
*/
private Attribute getAttribute(Attributes attributes, UUID id) {
for (Attribute attribute : attributes.values()) {
if (Objects.equal(attribute.getUUID(), id)) {
return attribute;
}
}
return null;
}
}

View File

@ -1,369 +0,0 @@
package com.comphenix.attribute;
import java.util.Collections;
import java.util.Iterator;
import java.util.UUID;
import java.util.concurrent.ConcurrentMap;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.bukkit.inventory.ItemStack;
import com.comphenix.attribute.NbtFactory.NbtCompound;
import com.comphenix.attribute.NbtFactory.NbtList;
import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.collect.Iterators;
import com.google.common.collect.Maps;
public class Attributes {
public enum Operation {
ADD_NUMBER(0),
MULTIPLY_PERCENTAGE(1),
ADD_PERCENTAGE(2);
private int id;
private Operation(int id) {
this.id = id;
}
public int getId() {
return id;
}
public static Operation fromId(int id) {
// Linear scan is very fast for small N
for (Operation op : values()) {
if (op.getId() == id) {
return op;
}
}
throw new IllegalArgumentException("Corrupt operation ID " + id + " detected.");
}
}
public static class AttributeType {
private static ConcurrentMap<String, AttributeType> LOOKUP = Maps.newConcurrentMap();
public static final AttributeType GENERIC_MAX_HEALTH = new AttributeType("generic.maxHealth").register();
public static final AttributeType GENERIC_FOLLOW_RANGE = new AttributeType("generic.followRange").register();
public static final AttributeType GENERIC_ATTACK_DAMAGE = new AttributeType("generic.attackDamage").register();
public static final AttributeType GENERIC_MOVEMENT_SPEED = new AttributeType("generic.movementSpeed").register();
public static final AttributeType GENERIC_KNOCKBACK_RESISTANCE = new AttributeType("generic.knockbackResistance").register();
private final String minecraftId;
/**
* Construct a new attribute type.
* <p>
* Remember to {@link #register()} the type.
*
* @param minecraftId
* - the ID of the type.
*/
public AttributeType(String minecraftId) {
this.minecraftId = minecraftId;
}
/**
* Retrieve the associated minecraft ID.
*
* @return The associated ID.
*/
public String getMinecraftId() {
return minecraftId;
}
/**
* Register the type in the central registry.
*
* @return The registered type.
*/
// Constructors should have no side-effects!
public AttributeType register() {
AttributeType old = LOOKUP.putIfAbsent(minecraftId, this);
return old != null ? old : this;
}
/**
* Retrieve the attribute type associated with a given ID.
*
* @param minecraftId
* The ID to search for.
* @return The attribute type, or NULL if not found.
*/
public static AttributeType fromId(String minecraftId) {
return LOOKUP.get(minecraftId);
}
/**
* Retrieve every registered attribute type.
*
* @return Every type.
*/
public static Iterable<AttributeType> values() {
return LOOKUP.values();
}
}
public static class Attribute {
private NbtCompound data;
public Attribute(Builder builder) {
data = NbtFactory.createCompound();
setAmount(builder.amount);
setOperation(builder.operation);
setAttributeType(builder.type);
setName(builder.name);
setUUID(builder.uuid);
}
private Attribute(NbtCompound data) {
this.data = data;
}
public double getAmount() {
return data.getDouble("Amount", 0.0);
}
public void setAmount(double amount) {
data.put("Amount", amount);
}
public Operation getOperation() {
return Operation.fromId(data.getInteger("Operation", 0));
}
public void setOperation(@Nonnull Operation operation) {
Preconditions.checkNotNull(operation, "operation cannot be NULL.");
data.put("Operation", operation.getId());
}
public AttributeType getAttributeType() {
return AttributeType.fromId(data.getString("AttributeName", null));
}
public void setAttributeType(@Nonnull AttributeType type) {
Preconditions.checkNotNull(type, "type cannot be NULL.");
data.put("AttributeName", type.getMinecraftId());
}
public String getName() {
return data.getString("Name", null);
}
public void setName(@Nonnull String name) {
Preconditions.checkNotNull(name, "name cannot be NULL.");
data.put("Name", name);
}
public UUID getUUID() {
return new UUID(data.getLong("UUIDMost", null), data.getLong("UUIDLeast", null));
}
public void setUUID(@Nonnull UUID id) {
Preconditions.checkNotNull("id", "id cannot be NULL.");
data.put("UUIDLeast", id.getLeastSignificantBits());
data.put("UUIDMost", id.getMostSignificantBits());
}
/**
* Construct a new attribute builder with a random UUID and default
* operation of adding numbers.
*
* @return The attribute builder.
*/
public static Builder newBuilder() {
return new Builder().uuid(UUID.randomUUID()).operation(Operation.ADD_NUMBER);
}
// Makes it easier to construct an attribute
public static class Builder {
private double amount;
private Operation operation = Operation.ADD_NUMBER;
private AttributeType type;
private String name;
private UUID uuid;
private Builder() {
// Don't make this accessible
}
public Builder(double amount, Operation operation,
AttributeType type, String name, UUID uuid) {
this.amount = amount;
this.operation = operation;
this.type = type;
this.name = name;
this.uuid = uuid;
}
public Builder amount(double amount) {
this.amount = amount;
return this;
}
public Builder operation(Operation operation) {
this.operation = operation;
return this;
}
public Builder type(AttributeType type) {
this.type = type;
return this;
}
public Builder name(String name) {
this.name = name;
return this;
}
public Builder uuid(UUID uuid) {
this.uuid = uuid;
return this;
}
public Attribute build() {
return new Attribute(this);
}
}
}
// This may be modified
public ItemStack stack;
private NbtList attributes;
public Attributes(ItemStack stack) {
// Create a CraftItemStack (under the hood)
this.stack = NbtFactory.getCraftItemStack(stack);
loadAttributes(false);
}
/**
* Load the NBT list from the TAG compound.
*
* @param createIfMissing
* - create the list if its missing.
*/
private void loadAttributes(boolean createIfMissing) {
if (this.attributes == null) {
NbtCompound nbt = NbtFactory.fromItemTag(this.stack);
this.attributes = nbt.getList("AttributeModifiers", createIfMissing);
}
}
/**
* Remove the NBT list from the TAG compound.
*/
private void removeAttributes() {
NbtCompound nbt = NbtFactory.fromItemTag(this.stack);
nbt.remove("AttributeModifiers");
this.attributes = null;
}
/**
* Retrieve the modified item stack.
*
* @return The modified item stack.
*/
public ItemStack getStack() {
return stack;
}
/**
* Retrieve the number of attributes.
*
* @return Number of attributes.
*/
public int size() {
return attributes != null ? attributes.size() : 0;
}
/**
* Add a new attribute to the list.
*
* @param attribute
* - the new attribute.
*/
public void add(Attribute attribute) {
Preconditions.checkNotNull(attribute.getName(), "must specify an attribute name.");
loadAttributes(true);
attributes.add(attribute.data);
}
/**
* Remove the first instance of the given attribute.
* <p>
* The attribute will be removed using its UUID.
*
* @param attribute
* - the attribute to remove.
* @return TRUE if the attribute was removed, FALSE otherwise.
*/
public boolean remove(Attribute attribute) {
if (attributes == null)
return false;
UUID uuid = attribute.getUUID();
for (Iterator<Attribute> it = values().iterator(); it.hasNext();) {
if (Objects.equal(it.next().getUUID(), uuid)) {
it.remove();
// Last removed attribute?
if (size() == 0) {
removeAttributes();
}
return true;
}
}
return false;
}
/**
* Remove every attribute.
*/
public void clear() {
removeAttributes();
}
/**
* Retrieve the attribute at a given index.
*
* @param index
* - the index to look up.
* @return The attribute at that index.
*/
public Attribute get(int index) {
if (size() == 0)
throw new IllegalStateException("Attribute list is empty.");
return new Attribute((NbtCompound) attributes.get(index));
}
// We can't make Attributes itself iterable without splitting it up into
// separate classes
public Iterable<Attribute> values() {
return new Iterable<Attribute>() {
@Override
public Iterator<Attribute> iterator() {
// Handle the empty case
if (size() == 0)
return Collections.<Attribute> emptyList().iterator();
return Iterators.transform(attributes.iterator(), new Function<Object, Attribute>() {
@Override
public Attribute apply(@Nullable Object element) {
return new Attribute((NbtCompound) element);
}
});
}
};
}
}

File diff suppressed because it is too large Load Diff

View File

@ -414,8 +414,13 @@ public class FileCache {
double amount = Double.parseDouble(args[2]);
Operation operation = Operation.fromId(Integer.parseInt(args[3]));
UUID uuid = UUID.fromString(args[4]);
Attribute attribute = new Attribute(new Builder(amount, operation, type, name, uuid));
attributes.add(attribute);
Builder build = Attribute.newBuilder();
build.amount(amount);
build.operation(operation);
build.type(type);
build.name(name);
build.uuid(uuid);
attributes.add(build.build());
} catch (Exception e) {
}
}
@ -488,8 +493,13 @@ public class FileCache {
double amount = Double.parseDouble(args[2]);
Operation operation = Operation.fromId(Integer.parseInt(args[3]));
UUID uuid = UUID.fromString(args[4]);
Attribute attribute = new Attribute(new Builder(amount, operation, type, name, uuid));
attributes.add(attribute);
Builder build = Attribute.newBuilder();
build.amount(amount);
build.operation(operation);
build.type(type);
build.name(name);
build.uuid(uuid);
attributes.add(build.build());
} catch (Exception e) {
}
}