Paper/CraftBukkit-Patches/0144-Filter-attribute-modifiers-which-cause-the-attribute.patch
Thinkofdeath 461353e2cb SPIGOT-522: Remove the global api cache option
This was useful when plugins first started upgrading to uuid because each
plugin would implement their own way for grabbing uuid's from mojang. Because
none of them shared the result they would quickly hit the limits on the api
causing the conversion to either fail or pause for long periods of time. The
global api cache was a (very hacky) way to force all plugins to share a cache
but caused a few issues with plugins that expected a full implementation of
the HTTPURLConnection. Due to the fact that most servers/plugins have updated
now it seems to be a good time to remove this as its usefulness mostly has
expired.
2015-02-06 09:03:19 -06:00

148 lines
6.6 KiB
Diff

From 37fb7bb5623fa984c30102af7dd732e698e4e543 Mon Sep 17 00:00:00 2001
From: Thinkofdeath <thinkofdeath@spigotmc.org>
Date: Thu, 31 Jul 2014 17:48:20 +0100
Subject: [PATCH] Filter attribute modifiers which cause the attribute to go
out of its range
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
index cea57d4..02f727a 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
@@ -41,6 +41,8 @@ import java.util.Set;
// Spigot start
import static org.spigotmc.ValidateUtils.*;
+import net.minecraft.server.GenericAttributes;
+import net.minecraft.server.IAttribute;
// Spigot end
/**
@@ -267,6 +269,123 @@ class CraftMetaItem implements ItemMeta, Repairable {
NBTTagList save = null;
NBTTagList nbttaglist = tag.getList(ATTRIBUTES.NBT, 10);
+ // Spigot start
+ gnu.trove.map.hash.TObjectDoubleHashMap<String> attributeTracker = new gnu.trove.map.hash.TObjectDoubleHashMap<String>();
+ gnu.trove.map.hash.TObjectDoubleHashMap<String> attributeTrackerX = new gnu.trove.map.hash.TObjectDoubleHashMap<String>();
+ Map<String, IAttribute> attributesByName = new HashMap<String, IAttribute>();
+ attributeTracker.put( "generic.maxHealth", 20.0 );
+ attributesByName.put( "generic.maxHealth", GenericAttributes.maxHealth );
+ attributeTracker.put( "generic.followRange", 32.0 );
+ attributesByName.put( "generic.followRange", GenericAttributes.b );
+ attributeTracker.put( "generic.knockbackResistance", 0.0 );
+ attributesByName.put( "generic.knockbackResistance", GenericAttributes.c );
+ attributeTracker.put( "generic.movementSpeed", 0.7 );
+ attributesByName.put( "generic.movementSpeed", GenericAttributes.d );
+ attributeTracker.put( "generic.attackDamage", 1.0 );
+ attributesByName.put( "generic.attackDamage", GenericAttributes.e );
+ NBTTagList oldList = nbttaglist;
+ nbttaglist = new NBTTagList();
+
+ List<NBTTagCompound> op0 = new ArrayList<NBTTagCompound>();
+ List<NBTTagCompound> op1 = new ArrayList<NBTTagCompound>();
+ List<NBTTagCompound> op2 = new ArrayList<NBTTagCompound>();
+
+ for ( int i = 0; i < oldList.size(); ++i )
+ {
+ NBTTagCompound nbttagcompound = oldList.get( i );
+ if ( nbttagcompound == null ) continue;
+
+ if ( !nbttagcompound.hasKeyOfType(ATTRIBUTES_UUID_HIGH.NBT, 99) )
+ {
+ continue;
+ }
+ if ( !nbttagcompound.hasKeyOfType(ATTRIBUTES_UUID_LOW.NBT, 99) )
+ {
+ continue;
+ }
+ if ( !( nbttagcompound.get( ATTRIBUTES_IDENTIFIER.NBT ) instanceof NBTTagString ) || !CraftItemFactory.KNOWN_NBT_ATTRIBUTE_NAMES.contains( nbttagcompound.getString( ATTRIBUTES_IDENTIFIER.NBT ) ) )
+ {
+ continue;
+ }
+ if ( !( nbttagcompound.get( ATTRIBUTES_NAME.NBT ) instanceof NBTTagString ) || nbttagcompound.getString( ATTRIBUTES_NAME.NBT ).isEmpty() )
+ {
+ continue;
+ }
+ if ( !nbttagcompound.hasKeyOfType(ATTRIBUTES_VALUE.NBT, 99) )
+ {
+ continue;
+ }
+ if ( !nbttagcompound.hasKeyOfType(ATTRIBUTES_TYPE.NBT, 99) || nbttagcompound.getInt( ATTRIBUTES_TYPE.NBT ) < 0 || nbttagcompound.getInt( ATTRIBUTES_TYPE.NBT ) > 2 )
+ {
+ continue;
+ }
+
+ switch ( nbttagcompound.getInt( ATTRIBUTES_TYPE.NBT ) )
+ {
+ case 0:
+ op0.add( nbttagcompound );
+ break;
+ case 1:
+ op1.add( nbttagcompound );
+ break;
+ case 2:
+ op2.add( nbttagcompound );
+ break;
+ }
+ }
+ for ( NBTTagCompound nbtTagCompound : op0 )
+ {
+ String name = nbtTagCompound.getString( ATTRIBUTES_IDENTIFIER.NBT );
+ if ( attributeTracker.containsKey( name ) )
+ {
+ double val = attributeTracker.get( name );
+ val += nbtTagCompound.getDouble( ATTRIBUTES_VALUE.NBT );
+ if ( val != attributesByName.get( name ).a( val ) )
+ {
+ continue;
+ }
+ attributeTracker.put( name, val );
+ }
+ nbttaglist.add( nbtTagCompound );
+ }
+ for ( String name : attributeTracker.keySet() )
+ {
+ attributeTrackerX.put( name, attributeTracker.get( name ) );
+ }
+ for ( NBTTagCompound nbtTagCompound : op1 )
+ {
+ String name = nbtTagCompound.getString( ATTRIBUTES_IDENTIFIER.NBT );
+ if ( attributeTracker.containsKey( name ) )
+ {
+ double val = attributeTracker.get( name );
+ double valX = attributeTrackerX.get( name );
+ val += valX * nbtTagCompound.getDouble( ATTRIBUTES_VALUE.NBT );
+ if ( val != attributesByName.get( name ).a( val ) )
+ {
+ continue;
+ }
+ attributeTracker.put( name, val );
+ }
+ nbttaglist.add( nbtTagCompound );
+ }
+ for ( NBTTagCompound nbtTagCompound : op2 )
+ {
+ String name = nbtTagCompound.getString( ATTRIBUTES_IDENTIFIER.NBT );
+ if ( attributeTracker.containsKey( name ) )
+ {
+ double val = attributeTracker.get( name );
+ val += val * nbtTagCompound.getDouble( ATTRIBUTES_VALUE.NBT );
+ if ( val != attributesByName.get( name ).a( val ) )
+ {
+ continue;
+ }
+ attributeTracker.put( name, val );
+ }
+ nbttaglist.add( nbtTagCompound );
+ }
+
+ // Spigot end
+
for (int i = 0; i < nbttaglist.size(); ++i) {
if (!(nbttaglist.get(i) instanceof NBTTagCompound)) {
continue;
--
2.1.0