From a844e8b5adb7cee8fe9a28846a6ae875165e10f2 Mon Sep 17 00:00:00 2001 From: mickare Date: Wed, 30 Sep 2015 03:56:04 +0200 Subject: [PATCH] Fix for offline player functionality (including /seen), implement automatic usermap repair --- .../com/earth2me/essentials/Essentials.java | 2 +- .../essentials/EssentialsPlayerListener.java | 11 ++- .../essentials/EssentialsUpgrade.java | 88 +++++++++++++++++++ .../essentials/commands/Commandtree.java | 2 +- 4 files changed, 99 insertions(+), 4 deletions(-) diff --git a/Essentials/src/com/earth2me/essentials/Essentials.java b/Essentials/src/com/earth2me/essentials/Essentials.java index 09b7b1113..da8c979a7 100644 --- a/Essentials/src/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/com/earth2me/essentials/Essentials.java @@ -441,7 +441,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials { return true; } catch (Exception ex) { showError(sender, ex, commandLabel); - if(settings.isDebug()) { + if (settings.isDebug()) { ex.printStackTrace(); } return true; diff --git a/Essentials/src/com/earth2me/essentials/EssentialsPlayerListener.java b/Essentials/src/com/earth2me/essentials/EssentialsPlayerListener.java index 1bb5684b5..69440b334 100644 --- a/Essentials/src/com/earth2me/essentials/EssentialsPlayerListener.java +++ b/Essentials/src/com/earth2me/essentials/EssentialsPlayerListener.java @@ -133,6 +133,7 @@ public class EssentialsPlayerListener implements Listener { event.setQuitMessage(ess.getSettings().getCustomQuitMessage().replace("{PLAYER}", player.getDisplayName()).replace("{USERNAME}", player.getName())); } + user.startTransaction(); if (ess.getSettings().removeGodOnDisconnect() && user.isGodModeEnabled()) { user.setGodModeEnabled(false); } @@ -154,6 +155,11 @@ public class EssentialsPlayerListener implements Listener { } user.updateActivity(false); + if (!user.isHidden()) { + user.setLastLogout(System.currentTimeMillis()); + } + user.stopTransaction(); + user.dispose(); } @@ -179,7 +185,7 @@ public class EssentialsPlayerListener implements Listener { ess.getBackup().onPlayerJoin(); final User dUser = ess.getUser(player); - + dUser.startTransaction(); if (dUser.isNPC()) { dUser.setNPC(false); } @@ -187,6 +193,7 @@ public class EssentialsPlayerListener implements Listener { final long currentTime = System.currentTimeMillis(); dUser.checkMuteTimeout(currentTime); dUser.updateActivity(false); + dUser.stopTransaction(); IText tempInput = null; @@ -362,7 +369,7 @@ public class EssentialsPlayerListener implements Listener { return; } if (ess.getSettings().getSocialSpyCommands().contains(cmd) || ess.getSettings().getSocialSpyCommands().contains("*")) { - if(!player.hasPermission("essentials.chat.spy.exempt")) { + if (!player.hasPermission("essentials.chat.spy.exempt")) { for (User spyer : ess.getOnlineUsers()) { if (spyer.isSocialSpyEnabled() && !player.equals(spyer.getBase())) { spyer.sendMessage(player.getDisplayName() + " : " + event.getMessage()); diff --git a/Essentials/src/com/earth2me/essentials/EssentialsUpgrade.java b/Essentials/src/com/earth2me/essentials/EssentialsUpgrade.java index 03e86f7fa..d645a35b7 100644 --- a/Essentials/src/com/earth2me/essentials/EssentialsUpgrade.java +++ b/Essentials/src/com/earth2me/essentials/EssentialsUpgrade.java @@ -6,6 +6,7 @@ import com.earth2me.essentials.settings.Spawns; import com.earth2me.essentials.storage.YamlStorageWriter; import com.earth2me.essentials.utils.StringUtil; import com.google.common.base.Charsets; +import com.google.common.collect.Maps; import net.ess3.api.IEssentials; import org.bukkit.BanList; import org.bukkit.Bukkit; @@ -16,9 +17,12 @@ import java.io.*; import java.math.BigInteger; import java.security.DigestInputStream; import java.security.MessageDigest; +import java.text.DecimalFormat; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import static com.earth2me.essentials.I18n.tl; @@ -583,6 +587,89 @@ public class EssentialsUpgrade { } } + private static final FileFilter YML_FILTER = new FileFilter() { + @Override + public boolean accept(File pathname) { + return pathname.isFile() && pathname.getName().endsWith(".yml"); + } + }; + + private static final String PATTERN_CONFIG_UUID_REGEX = "(?mi)^uuid:\\s*([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\\s*$"; + private static final Pattern PATTERN_CONFIG_UUID = Pattern.compile(PATTERN_CONFIG_UUID_REGEX); + + private static final String PATTERN_CONFIG_NAME_REGEX = "(?mi)^lastAccountName:\\s*[\"\']?(\\w+)[\"\']?\\s*$"; + private static final Pattern PATTERN_CONFIG_NAME = Pattern.compile(PATTERN_CONFIG_NAME_REGEX); + + private void repairUserMap() { + if (doneFile.getBoolean("userMapRepaired", false)) { + return; + } + ess.getLogger().info("Starting usermap repair"); + + File userdataFolder = new File(ess.getDataFolder(), "userdata"); + if (!userdataFolder.isDirectory()) { + ess.getLogger().warning("Missing userdata folder, aborting"); + return; + } + File[] files = userdataFolder.listFiles(YML_FILTER); + + final DecimalFormat format = new DecimalFormat("#0.00"); + final Map names = Maps.newHashMap(); + + for (int index = 0; index < files.length; index++) { + final File file = files[index]; + try { + UUID uuid = null; + final String filename = file.getName(); + final String configData = new String(java.nio.file.Files.readAllBytes(file.toPath()), Charsets.UTF_8); + + if (filename.length() > 36) { + try { + // ".yml" ending has 4 chars... + uuid = UUID.fromString(filename.substring(0, filename.length() - 4)); + } catch (IllegalArgumentException ignored) { + } + } + + final Matcher uuidMatcher = PATTERN_CONFIG_UUID.matcher(configData); + if (uuidMatcher.find()) { + try { + uuid = UUID.fromString(uuidMatcher.group(1)); + } catch (IllegalArgumentException ignored) { + } + } + + if (uuid == null) { + // Don't import + continue; + } + + final Matcher nameMatcher = PATTERN_CONFIG_NAME.matcher(configData); + if (nameMatcher.find()) { + final String username = nameMatcher.group(1); + if (username != null && username.length() > 0) { + names.put(StringUtil.safeString(username), uuid); + } + } + + if (index % 1000 == 0) { + ess.getLogger().info("Reading: " + format.format((100d * (double) index) / files.length) + + "%"); + } + } catch (final IOException e) { + ess.getLogger().log(Level.SEVERE, "Error while reading file: ", e); + return; + } + } + + ess.getUserMap().getNames().putAll(names); + ess.getUserMap().reloadConfig(); + + doneFile.setProperty("userMapRepaired", true); + doneFile.save(); + ess.getLogger().info("Completed usermap repair."); + } + public void beforeSettings() { if (!ess.getDataFolder().exists()) { ess.getDataFolder().mkdirs(); @@ -601,5 +688,6 @@ public class EssentialsUpgrade { uuidFileChange(); banFormatChange(); warnMetrics(); + repairUserMap(); } } diff --git a/Essentials/src/com/earth2me/essentials/commands/Commandtree.java b/Essentials/src/com/earth2me/essentials/commands/Commandtree.java index 1437cdc46..953594c07 100644 --- a/Essentials/src/com/earth2me/essentials/commands/Commandtree.java +++ b/Essentials/src/com/earth2me/essentials/commands/Commandtree.java @@ -18,7 +18,7 @@ public class Commandtree extends EssentialsCommand { TreeType tree = null; if (args.length < 1) { throw new NotEnoughArgumentsException(); - } else { + } else { for (TreeType type : TreeType.values()) { if (type.name().replace("_", "").equalsIgnoreCase(args[0])) { tree = type;