geforkt von Mirrors/Paper
SPIGOT-6025: Do not NPE when target world of a compass no longer exists
Dieser Commit ist enthalten in:
Ursprung
00bff02703
Commit
6008e6660a
@ -9,7 +9,9 @@ import net.minecraft.server.DynamicOpsNBT;
|
|||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.NBTBase;
|
import net.minecraft.server.NBTBase;
|
||||||
import net.minecraft.server.NBTTagCompound;
|
import net.minecraft.server.NBTTagCompound;
|
||||||
|
import net.minecraft.server.NBTTagString;
|
||||||
import net.minecraft.server.ResourceKey;
|
import net.minecraft.server.ResourceKey;
|
||||||
|
import net.minecraft.server.WorldServer;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
@ -22,9 +24,16 @@ public class CraftMetaCompass extends CraftMetaItem implements CompassMeta {
|
|||||||
|
|
||||||
static final ItemMetaKey LODESTONE_DIMENSION = new ItemMetaKey("LodestoneDimension");
|
static final ItemMetaKey LODESTONE_DIMENSION = new ItemMetaKey("LodestoneDimension");
|
||||||
static final ItemMetaKey LODESTONE_POS = new ItemMetaKey("LodestonePos", "lodestone");
|
static final ItemMetaKey LODESTONE_POS = new ItemMetaKey("LodestonePos", "lodestone");
|
||||||
|
static final ItemMetaKey LODESTONE_POS_WORLD = new ItemMetaKey("LodestonePosWorld");
|
||||||
|
static final ItemMetaKey LODESTONE_POS_X = new ItemMetaKey("LodestonePosX");
|
||||||
|
static final ItemMetaKey LODESTONE_POS_Y = new ItemMetaKey("LodestonePosY");
|
||||||
|
static final ItemMetaKey LODESTONE_POS_Z = new ItemMetaKey("LodestonePosZ");
|
||||||
static final ItemMetaKey LODESTONE_TRACKED = new ItemMetaKey("LodestoneTracked");
|
static final ItemMetaKey LODESTONE_TRACKED = new ItemMetaKey("LodestoneTracked");
|
||||||
|
|
||||||
private Location lodestone;
|
private NBTTagString lodestoneWorld;
|
||||||
|
private int lodestoneX;
|
||||||
|
private int lodestoneY;
|
||||||
|
private int lodestoneZ;
|
||||||
private Boolean tracked;
|
private Boolean tracked;
|
||||||
|
|
||||||
CraftMetaCompass(CraftMetaItem meta) {
|
CraftMetaCompass(CraftMetaItem meta) {
|
||||||
@ -33,21 +42,21 @@ public class CraftMetaCompass extends CraftMetaItem implements CompassMeta {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CraftMetaCompass compassMeta = (CraftMetaCompass) meta;
|
CraftMetaCompass compassMeta = (CraftMetaCompass) meta;
|
||||||
lodestone = compassMeta.lodestone.clone();
|
lodestoneWorld = compassMeta.lodestoneWorld;
|
||||||
|
lodestoneX = compassMeta.lodestoneX;
|
||||||
|
lodestoneY = compassMeta.lodestoneY;
|
||||||
|
lodestoneZ = compassMeta.lodestoneZ;
|
||||||
tracked = compassMeta.tracked;
|
tracked = compassMeta.tracked;
|
||||||
}
|
}
|
||||||
|
|
||||||
CraftMetaCompass(NBTTagCompound tag) {
|
CraftMetaCompass(NBTTagCompound tag) {
|
||||||
super(tag);
|
super(tag);
|
||||||
if (tag.hasKey(LODESTONE_DIMENSION.NBT) && tag.hasKey(LODESTONE_POS.NBT)) {
|
if (tag.hasKey(LODESTONE_DIMENSION.NBT) && tag.hasKey(LODESTONE_POS.NBT)) {
|
||||||
Optional<ResourceKey<net.minecraft.server.World>> key = net.minecraft.server.World.f.parse(DynamicOpsNBT.a, tag.get(LODESTONE_DIMENSION.NBT)).result();
|
lodestoneWorld = (NBTTagString) tag.get(LODESTONE_DIMENSION.NBT);
|
||||||
|
|
||||||
if (key.isPresent()) {
|
|
||||||
World world = MinecraftServer.getServer().getWorldServer(key.get()).getWorld();
|
|
||||||
|
|
||||||
NBTTagCompound pos = tag.getCompound(LODESTONE_POS.NBT);
|
NBTTagCompound pos = tag.getCompound(LODESTONE_POS.NBT);
|
||||||
lodestone = new Location(world, pos.getInt("X"), pos.getInt("Y"), pos.getInt("Z"));
|
lodestoneX = pos.getInt("X");
|
||||||
}
|
lodestoneY = pos.getInt("Y");
|
||||||
|
lodestoneZ = pos.getInt("Z");
|
||||||
}
|
}
|
||||||
if (tag.hasKey(LODESTONE_TRACKED.NBT)) {
|
if (tag.hasKey(LODESTONE_TRACKED.NBT)) {
|
||||||
tracked = tag.getBoolean(LODESTONE_TRACKED.NBT);
|
tracked = tag.getBoolean(LODESTONE_TRACKED.NBT);
|
||||||
@ -56,8 +65,19 @@ public class CraftMetaCompass extends CraftMetaItem implements CompassMeta {
|
|||||||
|
|
||||||
CraftMetaCompass(Map<String, Object> map) {
|
CraftMetaCompass(Map<String, Object> map) {
|
||||||
super(map);
|
super(map);
|
||||||
|
String lodestoneWorldString = SerializableMeta.getString(map, LODESTONE_POS_WORLD.BUKKIT, true);
|
||||||
lodestone = SerializableMeta.getObject(Location.class, map, LODESTONE_POS.BUKKIT, true);
|
if (lodestoneWorldString != null) {
|
||||||
|
lodestoneWorld = NBTTagString.a(lodestoneWorldString);
|
||||||
|
lodestoneX = (Integer) map.get(LODESTONE_POS_X.BUKKIT);
|
||||||
|
lodestoneY = (Integer) map.get(LODESTONE_POS_Y.BUKKIT);
|
||||||
|
lodestoneZ = (Integer) map.get(LODESTONE_POS_Z.BUKKIT);
|
||||||
|
} else {
|
||||||
|
// legacy
|
||||||
|
Location lodestone = SerializableMeta.getObject(Location.class, map, LODESTONE_POS.BUKKIT, true);
|
||||||
|
if (lodestone != null && lodestone.getWorld() != null) {
|
||||||
|
setLodestone(lodestone);
|
||||||
|
}
|
||||||
|
}
|
||||||
tracked = SerializableMeta.getBoolean(map, LODESTONE_TRACKED.BUKKIT);
|
tracked = SerializableMeta.getBoolean(map, LODESTONE_TRACKED.BUKKIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,17 +85,13 @@ public class CraftMetaCompass extends CraftMetaItem implements CompassMeta {
|
|||||||
void applyToItem(NBTTagCompound tag) {
|
void applyToItem(NBTTagCompound tag) {
|
||||||
super.applyToItem(tag);
|
super.applyToItem(tag);
|
||||||
|
|
||||||
if (lodestone != null) {
|
if (lodestoneWorld != null) {
|
||||||
NBTTagCompound pos = new NBTTagCompound();
|
NBTTagCompound pos = new NBTTagCompound();
|
||||||
pos.setInt("X", lodestone.getBlockX());
|
pos.setInt("X", lodestoneX);
|
||||||
pos.setInt("Y", lodestone.getBlockY());
|
pos.setInt("Y", lodestoneY);
|
||||||
pos.setInt("Z", lodestone.getBlockZ());
|
pos.setInt("Z", lodestoneZ);
|
||||||
|
|
||||||
tag.set(LODESTONE_POS.NBT, pos);
|
tag.set(LODESTONE_POS.NBT, pos);
|
||||||
|
tag.set(LODESTONE_DIMENSION.NBT, lodestoneWorld);
|
||||||
ResourceKey<net.minecraft.server.World> key = ((CraftWorld) lodestone.getWorld()).getHandle().getDimensionKey();
|
|
||||||
DataResult<NBTBase> dataresult = net.minecraft.server.World.f.encodeStart(DynamicOpsNBT.a, key);
|
|
||||||
tag.set(LODESTONE_DIMENSION.NBT, dataresult.get().orThrow());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tracked != null) {
|
if (tracked != null) {
|
||||||
@ -100,25 +116,38 @@ public class CraftMetaCompass extends CraftMetaItem implements CompassMeta {
|
|||||||
@Override
|
@Override
|
||||||
public CraftMetaCompass clone() {
|
public CraftMetaCompass clone() {
|
||||||
CraftMetaCompass clone = ((CraftMetaCompass) super.clone());
|
CraftMetaCompass clone = ((CraftMetaCompass) super.clone());
|
||||||
clone.lodestone = (lodestone == null) ? null : lodestone.clone();
|
|
||||||
clone.tracked = tracked;
|
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasLodestone() {
|
public boolean hasLodestone() {
|
||||||
return lodestone != null;
|
return lodestoneWorld != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Location getLodestone() {
|
public Location getLodestone() {
|
||||||
return lodestone;
|
if (lodestoneWorld == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Optional<ResourceKey<net.minecraft.server.World>> key = net.minecraft.server.World.f.parse(DynamicOpsNBT.a, lodestoneWorld).result();
|
||||||
|
WorldServer worldServer = key.isPresent() ? MinecraftServer.getServer().getWorldServer(key.get()) : null;
|
||||||
|
World world = worldServer != null ? worldServer.getWorld() : null;
|
||||||
|
return new Location(world, lodestoneX, lodestoneY, lodestoneZ); // world may be null here, if the referenced world is not loaded
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLodestone(Location lodestone) {
|
public void setLodestone(Location lodestone) {
|
||||||
Preconditions.checkArgument(lodestone != null && lodestone.getWorld() != null, "Location or world null");
|
Preconditions.checkArgument(lodestone == null || lodestone.getWorld() != null, "world is null");
|
||||||
this.lodestone = lodestone;
|
if (lodestone == null) {
|
||||||
|
this.lodestoneWorld = null;
|
||||||
|
} else {
|
||||||
|
ResourceKey<net.minecraft.server.World> key = ((CraftWorld) lodestone.getWorld()).getHandle().getDimensionKey();
|
||||||
|
DataResult<NBTBase> dataresult = net.minecraft.server.World.f.encodeStart(DynamicOpsNBT.a, key);
|
||||||
|
this.lodestoneWorld = (NBTTagString) dataresult.get().orThrow();
|
||||||
|
this.lodestoneX = lodestone.getBlockX();
|
||||||
|
this.lodestoneY = lodestone.getBlockY();
|
||||||
|
this.lodestoneZ = lodestone.getBlockZ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean hasLodestoneTracked() {
|
boolean hasLodestoneTracked() {
|
||||||
@ -140,7 +169,10 @@ public class CraftMetaCompass extends CraftMetaItem implements CompassMeta {
|
|||||||
final int original;
|
final int original;
|
||||||
int hash = original = super.applyHash();
|
int hash = original = super.applyHash();
|
||||||
if (hasLodestone()) {
|
if (hasLodestone()) {
|
||||||
hash = 73 * hash + lodestone.hashCode();
|
hash = 73 * hash + lodestoneWorld.hashCode();
|
||||||
|
hash = 73 * hash + lodestoneX;
|
||||||
|
hash = 73 * hash + lodestoneY;
|
||||||
|
hash = 73 * hash + lodestoneZ;
|
||||||
}
|
}
|
||||||
if (hasLodestoneTracked()) {
|
if (hasLodestoneTracked()) {
|
||||||
hash = 73 * hash + (isLodestoneTracked() ? 1231 : 1237);
|
hash = 73 * hash + (isLodestoneTracked() ? 1231 : 1237);
|
||||||
@ -157,7 +189,9 @@ public class CraftMetaCompass extends CraftMetaItem implements CompassMeta {
|
|||||||
if (meta instanceof CraftMetaCompass) {
|
if (meta instanceof CraftMetaCompass) {
|
||||||
CraftMetaCompass that = (CraftMetaCompass) meta;
|
CraftMetaCompass that = (CraftMetaCompass) meta;
|
||||||
|
|
||||||
return (this.hasLodestone() ? that.hasLodestone() && this.lodestone.equals(that.lodestone) : !that.hasLodestone())
|
return (this.hasLodestone() ? that.hasLodestone() && this.lodestoneWorld.asString().equals(that.lodestoneWorld.asString())
|
||||||
|
&& this.lodestoneX == that.lodestoneX && this.lodestoneY == that.lodestoneY
|
||||||
|
&& this.lodestoneZ == that.lodestoneZ : !that.hasLodestone())
|
||||||
&& this.tracked == that.tracked;
|
&& this.tracked == that.tracked;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -173,7 +207,10 @@ public class CraftMetaCompass extends CraftMetaItem implements CompassMeta {
|
|||||||
super.serialize(builder);
|
super.serialize(builder);
|
||||||
|
|
||||||
if (hasLodestone()) {
|
if (hasLodestone()) {
|
||||||
builder.put(LODESTONE_POS.BUKKIT, lodestone);
|
builder.put(LODESTONE_POS_WORLD.BUKKIT, lodestoneWorld.asString());
|
||||||
|
builder.put(LODESTONE_POS_X.BUKKIT, lodestoneX);
|
||||||
|
builder.put(LODESTONE_POS_Y.BUKKIT, lodestoneY);
|
||||||
|
builder.put(LODESTONE_POS_Z.BUKKIT, lodestoneZ);
|
||||||
}
|
}
|
||||||
if (hasLodestoneTracked()) {
|
if (hasLodestoneTracked()) {
|
||||||
builder.put(LODESTONE_TRACKED.BUKKIT, tracked);
|
builder.put(LODESTONE_TRACKED.BUKKIT, tracked);
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren