SPIGOT-4815: Location.equals() not working

By: md_5 <git@md-5.net>
This commit is contained in:
Bukkit/Spigot 2019-04-30 09:36:30 +10:00
parent dc652253ed
commit 4c0157d6de
3 changed files with 79 additions and 4 deletions

View file

@ -543,7 +543,9 @@ public class Location implements Cloneable, ConfigurationSerializable {
}
final Location other = (Location) obj;
if (this.world != other.world && (this.world == null || !this.world.equals(other.world))) {
World world = (this.world == null) ? null : this.world.get();
World otherWorld = (other.world == null) ? null : other.world.get();
if (world != otherWorld && (world == null || !world.equals(otherWorld))) {
return false;
}
if (Double.doubleToLongBits(this.x) != Double.doubleToLongBits(other.x)) {
@ -568,7 +570,7 @@ public class Location implements Cloneable, ConfigurationSerializable {
public int hashCode() {
int hash = 3;
World world = (this.world == null) ? null : getWorld();
World world = (this.world == null) ? null : this.world.get();
hash = 19 * hash + (world != null ? world.hashCode() : 0);
hash = 19 * hash + (int) (Double.doubleToLongBits(this.x) ^ (Double.doubleToLongBits(this.x) >>> 32));
hash = 19 * hash + (int) (Double.doubleToLongBits(this.y) ^ (Double.doubleToLongBits(this.y) >>> 32));
@ -580,7 +582,7 @@ public class Location implements Cloneable, ConfigurationSerializable {
@Override
public String toString() {
World world = (this.world == null) ? null : getWorld();
World world = (this.world == null) ? null : this.world.get();
return "Location{" + "world=" + world + ",x=" + x + ",y=" + y + ",z=" + z + ",pitch=" + pitch + ",yaw=" + yaw + '}';
}

View file

@ -176,12 +176,21 @@ public class LocationTest {
assertThat(vector.getZ(), is(closeTo(z, delta)));
}
@Test
public void testEquals() {
Location first = getLocation().add(getVector());
Location second = getLocation().add(getVector());
assertThat(first.hashCode(), is(second.hashCode()));
assertThat(first, is(second));
}
private Vector getVector() {
return new Vector(x, y, z);
}
private static Location getEmptyLocation() {
return new Location(null, 0, 0, 0);
return new Location(TestWorld.INSTANCE, 0, 0, 0);
}
private Location getLocation() {

View file

@ -0,0 +1,64 @@
package org.bukkit;
import com.google.common.collect.ImmutableMap;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
public final class TestWorld implements InvocationHandler {
private static interface MethodHandler {
Object handle(TestWorld server, Object[] args);
}
private static final Map<Method, MethodHandler> methods;
public static final World INSTANCE;
static {
try {
ImmutableMap.Builder<Method, MethodHandler> methodMap = ImmutableMap.builder();
methodMap.put(
Object.class.getMethod("equals", Object.class),
new MethodHandler() {
@Override
public Object handle(TestWorld server, Object[] args) {
return this == args[0];
}
}
);
methodMap.put(
Object.class.getMethod("hashCode"),
new MethodHandler() {
@Override
public Object handle(TestWorld server, Object[] args) {
return this.hashCode();
}
}
);
methods = methodMap.build();
TestWorld world = new TestWorld();
INSTANCE = Proxy.getProxyClass(World.class.getClassLoader(), World.class).asSubclass(World.class).getConstructor(InvocationHandler.class).newInstance(world);
} catch (Throwable t) {
throw new Error(t);
}
}
private TestWorld() {
}
public static Server getInstance() {
return Bukkit.getServer();
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) {
MethodHandler handler = methods.get(method);
if (handler != null) {
return handler.handle(this, args);
}
throw new UnsupportedOperationException(String.valueOf(method));
}
}