Fix 'Unable to find method createTag' on 1.15 servers (#2642)

* Fix 'Unable to find method createTag' on 1.15 servers (#2629)

Mojang apparently refactored their NBT code in 1.15, so the NBT
parsing code in NbtFactory that used Mojang's NBT code via Reflection
broke. Since PlotSquared now depends on WorldEdit, it is much easier
to use their NBT parsing library than to update the Reflection-based
code.

* Clean up NBT streams properly
This commit is contained in:
Traks 2019-12-23 21:35:37 +01:00 committed by dordsor21
parent 3abb35e506
commit 519d3ee2d6
2 changed files with 34 additions and 1060 deletions

View File

@ -1,6 +1,5 @@
package com.github.intellectualsites.plotsquared.bukkit.uuid; package com.github.intellectualsites.plotsquared.bukkit.uuid;
import com.github.intellectualsites.plotsquared.bukkit.util.NbtFactory;
import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.config.Captions; import com.github.intellectualsites.plotsquared.plot.config.Captions;
import com.github.intellectualsites.plotsquared.plot.config.Settings; import com.github.intellectualsites.plotsquared.plot.config.Settings;
@ -15,6 +14,13 @@ import com.github.intellectualsites.plotsquared.plot.util.expiry.ExpireManager;
import com.github.intellectualsites.plotsquared.plot.uuid.UUIDWrapper; import com.github.intellectualsites.plotsquared.plot.uuid.UUIDWrapper;
import com.google.common.collect.HashBiMap; import com.google.common.collect.HashBiMap;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.NBTInputStream;
import com.sk89q.jnbt.Tag;
import java.io.BufferedInputStream;
import java.io.FileNotFoundException;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.World; import org.bukkit.World;
@ -38,6 +44,16 @@ public class FileUUIDHandler extends UUIDHandlerImplementation {
return super.startCaching(whenDone) && cache(whenDone); return super.startCaching(whenDone) && cache(whenDone);
} }
private Tag readTag(File file) throws IOException {
// Don't chain the creation of the GZIP stream and the NBT stream, because their
// constructors may throw an IOException.
try (BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file));
GZIPInputStream gzipInputStream = new GZIPInputStream(inputStream);
NBTInputStream nbtInputStream = new NBTInputStream(gzipInputStream)) {
return nbtInputStream.readNamedTag().getTag();
}
}
public boolean cache(final Runnable whenDone) { public boolean cache(final Runnable whenDone) {
final File container = Bukkit.getWorldContainer(); final File container = Bukkit.getWorldContainer();
List<World> worlds = Bukkit.getWorlds(); List<World> worlds = Bukkit.getWorlds();
@ -94,18 +110,18 @@ public class FileUUIDHandler extends UUIDHandlerImplementation {
UUID uuid = UUID.fromString(s); UUID uuid = UUID.fromString(s);
if (check || all.remove(uuid)) { if (check || all.remove(uuid)) {
File file = new File(playerDataFolder, current); File file = new File(playerDataFolder, current);
NbtFactory.NbtCompound compound = NbtFactory CompoundTag compound = (CompoundTag) readTag(file);
.fromStream(new FileInputStream(file),
NbtFactory.StreamOptions.GZIP_COMPRESSION);
if (!compound.containsKey("bukkit")) { if (!compound.containsKey("bukkit")) {
PlotSquared.debug("ERROR: Player data (" + uuid.toString() PlotSquared.debug("ERROR: Player data (" + uuid.toString()
+ ".dat) does not contain the the key \"bukkit\""); + ".dat) does not contain the the key \"bukkit\"");
} else { } else {
NbtFactory.NbtCompound bukkit = Map<String, Tag> compoundMap = compound.getValue();
(NbtFactory.NbtCompound) compound.get("bukkit"); CompoundTag bukkit = (CompoundTag) compoundMap.get("bukkit");
String name = (String) bukkit.get("lastKnownName"); Map<String, Tag> bukkitMap = bukkit.getValue();
long last = (long) bukkit.get("lastPlayed"); String name =
long first = (long) bukkit.get("firstPlayed"); (String) bukkitMap.get("lastKnownName").getValue();
long last = (long) bukkitMap.get("lastPlayed").getValue();
long first = (long) bukkitMap.get("firstPlayed").getValue();
if (ExpireManager.IMP != null) { if (ExpireManager.IMP != null) {
ExpireManager.IMP.storeDate(uuid, last); ExpireManager.IMP.storeDate(uuid, last);
ExpireManager.IMP.storeAccountAge(uuid, last - first); ExpireManager.IMP.storeAccountAge(uuid, last - first);
@ -167,27 +183,26 @@ public class FileUUIDHandler extends UUIDHandlerImplementation {
if (!file.exists()) { if (!file.exists()) {
continue; continue;
} }
NbtFactory.NbtCompound compound = NbtFactory CompoundTag compound = (CompoundTag) readTag(file);
.fromStream(new FileInputStream(file),
NbtFactory.StreamOptions.GZIP_COMPRESSION);
if (!compound.containsKey("bukkit")) { if (!compound.containsKey("bukkit")) {
PlotSquared.debug("ERROR: Player data (" + uuid.toString() PlotSquared.debug("ERROR: Player data (" + uuid.toString()
+ ".dat) does not contain the the key \"bukkit\""); + ".dat) does not contain the the key \"bukkit\"");
} else { } else {
NbtFactory.NbtCompound bukkit = Map<String, Tag> compoundMap = compound.getValue();
(NbtFactory.NbtCompound) compound.get("bukkit"); CompoundTag bukkit = (CompoundTag) compoundMap.get("bukkit");
String name = (String) bukkit.get("lastKnownName"); Map<String, Tag> bukkitMap = bukkit.getValue();
String name = (String) bukkitMap.get("lastKnownName").getValue();
StringWrapper wrap = new StringWrapper(name); StringWrapper wrap = new StringWrapper(name);
if (!toAdd.containsKey(wrap)) { if (!toAdd.containsKey(wrap)) {
long last = (long) bukkit.get("lastPlayed"); long last = (long) bukkitMap.get("lastPlayed").getValue();
long first = (long) bukkit.get("firstPlayed"); long first = (long) bukkitMap.get("firstPlayed").getValue();
if (Settings.UUID.OFFLINE) { if (Settings.UUID.OFFLINE) {
if (Settings.UUID.FORCE_LOWERCASE && !name.toLowerCase() if (Settings.UUID.FORCE_LOWERCASE && !name.toLowerCase()
.equals(name)) { .equals(name)) {
uuid = FileUUIDHandler.this.uuidWrapper.getUUID(name); uuid = FileUUIDHandler.this.uuidWrapper.getUUID(name);
} else { } else {
long most = (long) compound.get("UUIDMost"); long most = (long) compoundMap.get("UUIDMost").getValue();
long least = (long) compound.get("UUIDLeast"); long least = (long) compoundMap.get("UUIDLeast").getValue();
uuid = new UUID(most, least); uuid = new UUID(most, least);
} }
} }