Essentials UUID conversion.

This commit is contained in:
KHobbits 2014-04-13 06:53:11 +01:00
parent 36e580474f
commit 9e9409da1e
16 changed files with 364 additions and 374 deletions

View file

@ -40,6 +40,7 @@ import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -102,7 +103,6 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials
public Essentials() public Essentials()
{ {
} }
public Essentials(final Server server) public Essentials(final Server server)
@ -187,12 +187,12 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials
settings = new Settings(this); settings = new Settings(this);
confList.add(settings); confList.add(settings);
execTimer.mark("Settings"); execTimer.mark("Settings");
upgrade.afterSettings();
execTimer.mark("Upgrade2");
i18n.updateLocale(settings.getLocale());
userMap = new UserMap(this); userMap = new UserMap(this);
confList.add(userMap); confList.add(userMap);
execTimer.mark("Init(Usermap)"); execTimer.mark("Init(Usermap)");
upgrade.afterSettings();
execTimer.mark("Upgrade2");
i18n.updateLocale(settings.getLocale());
warps = new Warps(getServer(), this.getDataFolder()); warps = new Warps(getServer(), this.getDataFolder());
confList.add(warps); confList.add(warps);
execTimer.mark("Init(Spawn/Warp)"); execTimer.mark("Init(Spawn/Warp)");
@ -634,7 +634,14 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials
@Override @Override
public User getUser(final String base) public User getUser(final String base)
{ {
return getOfflineUser((String)base); return getOfflineUser(base);
}
//This will return null if there is not a match.
@Override
public User getUser(final UUID base)
{
return userMap.getUser(base);
} }
//This will return null if there is not a match. //This will return null if there is not a match.
@ -664,7 +671,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials
return null; return null;
} }
User user = userMap.getUser(base.getName()); User user = userMap.getUser(base.getUniqueId());
if (user == null) if (user == null)
{ {

View file

@ -31,11 +31,11 @@ import org.bukkit.util.Vector;
public class EssentialsConf extends YamlConfiguration public class EssentialsConf extends YamlConfiguration
{ {
private static final Logger LOGGER = Logger.getLogger("Essentials"); protected static final Logger LOGGER = Logger.getLogger("Essentials");
private final File configFile; protected final File configFile;
private String templateName = null; protected String templateName = null;
private Class<?> resourceClass = EssentialsConf.class; protected static final Charset UTF8 = Charset.forName("UTF-8");
private static final Charset UTF8 = Charset.forName("UTF-8"); private Class<?> resourceClass = EssentialsConf.class;
private static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor(); private static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor();
private final AtomicInteger pendingDiskWrites = new AtomicInteger(0); private final AtomicInteger pendingDiskWrites = new AtomicInteger(0);
@ -95,10 +95,14 @@ public class EssentialsConf extends YamlConfiguration
LOGGER.log(Level.SEVERE, null, ex); LOGGER.log(Level.SEVERE, null, ex);
} }
} }
if (!configFile.exists()) if (!configFile.exists())
{ {
if (templateName != null) if (legacyFileExists())
{
convertLegacyFile();
}
else if (templateName != null)
{ {
LOGGER.log(Level.INFO, tl("creatingConfigFromTemplate", configFile.toString())); LOGGER.log(Level.INFO, tl("creatingConfigFromTemplate", configFile.toString()));
createFromTemplate(); createFromTemplate();
@ -166,6 +170,7 @@ public class EssentialsConf extends YamlConfiguration
finally finally
{ {
inputStream.close(); inputStream.close();
save();
} }
} }
catch (IOException ex) catch (IOException ex)
@ -179,6 +184,16 @@ public class EssentialsConf extends YamlConfiguration
LOGGER.log(Level.SEVERE, "The file " + configFile.toString() + " is broken, it has been renamed to " + broken.toString(), ex.getCause()); LOGGER.log(Level.SEVERE, "The file " + configFile.toString() + " is broken, it has been renamed to " + broken.toString(), ex.getCause());
} }
} }
public boolean legacyFileExists()
{
return false;
}
public void convertLegacyFile()
{
LOGGER.log(Level.SEVERE, "Unable to import legacy config file.");
}
private void createFromTemplate() private void createFromTemplate()
{ {

View file

@ -230,7 +230,7 @@ public class EssentialsPlayerListener implements Listener
return; return;
} }
user.trackUUID(); user.setLastAccountName(user.getBase().getName());
user.setLastLogin(currentTime); user.setLastLogin(currentTime);
user.setDisplayNick(); user.setDisplayNick();
updateCompass(user); updateCompass(user);

View file

@ -15,9 +15,7 @@ import java.util.logging.Logger;
import net.ess3.api.IEssentials; import net.ess3.api.IEssentials;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.inventory.ItemStack;
public class EssentialsUpgrade public class EssentialsUpgrade
@ -37,46 +35,6 @@ public class EssentialsUpgrade
doneFile.load(); doneFile.load();
} }
private void moveWorthValuesToWorthYml()
{
if (doneFile.getBoolean("moveWorthValuesToWorthYml", false))
{
return;
}
try
{
final File configFile = new File(ess.getDataFolder(), "config.yml");
if (!configFile.exists())
{
return;
}
final EssentialsConf conf = new EssentialsConf(configFile);
conf.load();
final Worth worth = new Worth(ess.getDataFolder());
boolean found = false;
for (Material mat : Material.values())
{
final int id = mat.getId();
final double value = conf.getDouble("worth-" + id, Double.NaN);
if (!Double.isNaN(value))
{
found = true;
worth.setPrice(new ItemStack(mat, 1, (short)0, (byte)0), value);
}
}
if (found)
{
removeLinesFromConfig(configFile, "\\s*#?\\s*worth-[0-9]+.*", "# Worth values have been moved to worth.yml");
}
doneFile.setProperty("moveWorthValuesToWorthYml", true);
doneFile.save();
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, tl("upgradingFilesError"), e);
}
}
private void moveMotdRulesToFile(String name) private void moveMotdRulesToFile(String name)
{ {
if (doneFile.getBoolean("move" + name + "ToFile", false)) if (doneFile.getBoolean("move" + name + "ToFile", false))
@ -180,73 +138,6 @@ public class EssentialsUpgrade
} }
} }
private void updateUsersToNewDefaultHome()
{
if (doneFile.getBoolean("updateUsersToNewDefaultHome", false))
{
return;
}
final File userdataFolder = new File(ess.getDataFolder(), "userdata");
if (!userdataFolder.exists() || !userdataFolder.isDirectory())
{
return;
}
final File[] userFiles = userdataFolder.listFiles();
for (File file : userFiles)
{
if (!file.isFile() || !file.getName().endsWith(".yml"))
{
continue;
}
final EssentialsConf config = new EssentialsConf(file);
try
{
config.load();
if (config.hasProperty("home") && !config.hasProperty("home.default"))
{
@SuppressWarnings("unchecked")
final List<Object> vals = (List<Object>)config.getProperty("home");
if (vals == null)
{
continue;
}
World world = ess.getServer().getWorlds().get(0);
if (vals.size() > 5)
{
world = ess.getServer().getWorld((String)vals.get(5));
}
if (world != null)
{
final Location loc = new Location(
world,
((Number)vals.get(0)).doubleValue(),
((Number)vals.get(1)).doubleValue(),
((Number)vals.get(2)).doubleValue(),
((Number)vals.get(3)).floatValue(),
((Number)vals.get(4)).floatValue());
final String worldName = world.getName().toLowerCase(Locale.ENGLISH);
if (worldName != null && !worldName.isEmpty())
{
config.removeProperty("home");
config.setProperty("home.default", worldName);
config.setProperty("home.worlds." + worldName, loc);
config.forceSave();
}
}
}
}
catch (RuntimeException ex)
{
LOGGER.log(Level.INFO, "File: " + file.toString());
throw ex;
}
}
doneFile.setProperty("updateUsersToNewDefaultHome", true);
doneFile.save();
}
private void updateUsersPowerToolsFormat() private void updateUsersPowerToolsFormat()
{ {
if (doneFile.getBoolean("updateUsersPowerToolsFormat", false)) if (doneFile.getBoolean("updateUsersPowerToolsFormat", false))
@ -374,195 +265,6 @@ public class EssentialsUpgrade
doneFile.save(); doneFile.save();
} }
private void moveUsersDataToUserdataFolder()
{
final File usersFile = new File(ess.getDataFolder(), "users.yml");
if (!usersFile.exists())
{
return;
}
final EssentialsConf usersConfig = new EssentialsConf(usersFile);
usersConfig.load();
for (String username : usersConfig.getKeys(false))
{
final User user = new User(new OfflinePlayer(username, ess), ess);
final String nickname = usersConfig.getString(username + ".nickname");
if (nickname != null && !nickname.isEmpty() && !nickname.equals(username))
{
user.setNickname(nickname);
}
final List<String> mails = usersConfig.getStringList(username + ".mail");
if (mails != null && !mails.isEmpty())
{
user.setMails(mails);
}
if (!user.hasHome())
{
@SuppressWarnings("unchecked")
final List<Object> vals = (List<Object>)usersConfig.getProperty(username + ".home");
if (vals != null)
{
World world = ess.getServer().getWorlds().get(0);
if (vals.size() > 5)
{
world = getFakeWorld((String)vals.get(5));
}
if (world != null)
{
user.setHome("home", new Location(world,
((Number)vals.get(0)).doubleValue(),
((Number)vals.get(1)).doubleValue(),
((Number)vals.get(2)).doubleValue(),
((Number)vals.get(3)).floatValue(),
((Number)vals.get(4)).floatValue()));
}
}
}
}
usersFile.renameTo(new File(usersFile.getAbsolutePath() + ".old"));
}
private void convertWarps()
{
final File warpsFolder = new File(ess.getDataFolder(), "warps");
if (!warpsFolder.exists())
{
warpsFolder.mkdirs();
}
final File[] listOfFiles = warpsFolder.listFiles();
if (listOfFiles.length >= 1)
{
for (int i = 0; i < listOfFiles.length; i++)
{
final String filename = listOfFiles[i].getName();
if (listOfFiles[i].isFile() && filename.endsWith(".dat"))
{
try
{
final BufferedReader rx = new BufferedReader(new FileReader(listOfFiles[i]));
double x, y, z;
float yaw, pitch;
String worldName;
try
{
if (!rx.ready())
{
continue;
}
x = Double.parseDouble(rx.readLine().trim());
if (!rx.ready())
{
continue;
}
y = Double.parseDouble(rx.readLine().trim());
if (!rx.ready())
{
continue;
}
z = Double.parseDouble(rx.readLine().trim());
if (!rx.ready())
{
continue;
}
yaw = Float.parseFloat(rx.readLine().trim());
if (!rx.ready())
{
continue;
}
pitch = Float.parseFloat(rx.readLine().trim());
worldName = rx.readLine();
}
finally
{
rx.close();
}
World w = null;
for (World world : ess.getServer().getWorlds())
{
if (world.getEnvironment() != World.Environment.NETHER)
{
w = world;
break;
}
}
if (worldName != null)
{
worldName = worldName.trim();
World w1 = null;
w1 = getFakeWorld(worldName);
if (w1 != null)
{
w = w1;
}
}
final Location loc = new Location(w, x, y, z, yaw, pitch);
ess.getWarps().setWarp(filename.substring(0, filename.length() - 4), loc);
if (!listOfFiles[i].renameTo(new File(warpsFolder, filename + ".old")))
{
throw new Exception(tl("fileRenameError", filename));
}
}
catch (Exception ex)
{
LOGGER.log(Level.SEVERE, null, ex);
}
}
}
}
final File warpFile = new File(ess.getDataFolder(), "warps.txt");
if (warpFile.exists())
{
try
{
final BufferedReader rx = new BufferedReader(new FileReader(warpFile));
try
{
for (String[] parts = new String[0]; rx.ready(); parts = rx.readLine().split(":"))
{
if (parts.length < 6)
{
continue;
}
final String name = parts[0];
final double x = Double.parseDouble(parts[1].trim());
final double y = Double.parseDouble(parts[2].trim());
final double z = Double.parseDouble(parts[3].trim());
final float yaw = Float.parseFloat(parts[4].trim());
final float pitch = Float.parseFloat(parts[5].trim());
if (name.isEmpty())
{
continue;
}
World w = null;
for (World world : ess.getServer().getWorlds())
{
if (world.getEnvironment() != World.Environment.NETHER)
{
w = world;
break;
}
}
final Location loc = new Location(w, x, y, z, yaw, pitch);
ess.getWarps().setWarp(name, loc);
if (!warpFile.renameTo(new File(ess.getDataFolder(), "warps.txt.old")))
{
throw new Exception(tl("fileRenameError", "warps.txt"));
}
}
}
finally
{
rx.close();
}
}
catch (Exception ex)
{
LOGGER.log(Level.SEVERE, null, ex);
}
}
}
private void sanitizeAllUserFilenames() private void sanitizeAllUserFilenames()
{ {
if (doneFile.getBoolean("sanitizeAllUserFilenames", false)) if (doneFile.getBoolean("sanitizeAllUserFilenames", false))
@ -791,13 +493,74 @@ public class EssentialsUpgrade
doneFile.save(); doneFile.save();
} }
private void uuidFileChange()
{
if (doneFile.getBoolean("uuidFileChange", false))
{
return;
}
final File userdir = new File(ess.getDataFolder(), "userdata");
if (!userdir.exists())
{
return;
}
for (String string : userdir.list())
{
if (!string.endsWith(".yml"))
{
continue;
}
final String name = string.substring(0, string.length() - 4);
EssentialsUserConf config;
UUID uuid = null;
try
{
uuid = UUID.fromString(name);
}
catch (IllegalArgumentException ex)
{
File file = new File(userdir, string);
EssentialsConf conf = new EssentialsConf(file);
conf.load();
conf.setProperty("lastAccountName", name);
conf.forceSave();
String uuidString = conf.getString("uuid", null);
try
{
uuid = UUID.fromString(uuidString);
}
catch (Exception ex2)
{
org.bukkit.OfflinePlayer player = ess.getServer().getOfflinePlayer(name);
uuid = player.getUniqueId();
}
if (uuid == null && conf.getBoolean("npc", false))
{
uuid = UUID.randomUUID();
}
if (uuid != null)
{
config = new EssentialsUserConf(name, uuid, new File(userdir, uuid + ".yml"));
config.convertLegacyFile();
ess.getUserMap().trackUUID(uuid, name);
}
}
}
doneFile.setProperty("uuidFileChange", true);
doneFile.save();
}
public void beforeSettings() public void beforeSettings()
{ {
if (!ess.getDataFolder().exists()) if (!ess.getDataFolder().exists())
{ {
ess.getDataFolder().mkdirs(); ess.getDataFolder().mkdirs();
} }
moveWorthValuesToWorthYml();
moveMotdRulesToFile("motd"); moveMotdRulesToFile("motd");
moveMotdRulesToFile("rules"); moveMotdRulesToFile("rules");
} }
@ -805,14 +568,12 @@ public class EssentialsUpgrade
public void afterSettings() public void afterSettings()
{ {
sanitizeAllUserFilenames(); sanitizeAllUserFilenames();
updateUsersToNewDefaultHome();
moveUsersDataToUserdataFolder();
convertWarps();
updateUsersPowerToolsFormat(); updateUsersPowerToolsFormat();
updateUsersHomesFormat(); updateUsersHomesFormat();
deleteOldItemsCsv(); deleteOldItemsCsv();
updateSpawnsToNewSpawnsConfig(); updateSpawnsToNewSpawnsConfig();
updateJailsToNewJailsConfig(); updateJailsToNewJailsConfig();
uuidFileChange();
warnMetrics(); warnMetrics();
} }
} }

View file

@ -0,0 +1,45 @@
package com.earth2me.essentials;
import com.google.common.io.Files;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
import java.util.logging.Level;
import org.bukkit.Bukkit;
public class EssentialsUserConf extends EssentialsConf
{
final String username;
final UUID uuid;
public EssentialsUserConf(final String username, final UUID uuid, final File configFile)
{
super(configFile);
this.username = username;
this.uuid = uuid;
}
@Override
public boolean legacyFileExists()
{
File file = new File(configFile.getParentFile(), username + ".yml");
return file.exists();
}
@Override
public void convertLegacyFile()
{
File file = new File(configFile.getParentFile(), username + ".yml");
try
{
Files.move(file, new File(configFile.getParentFile(), uuid + ".yml"));
}
catch (IOException ex)
{
Bukkit.getLogger().log(Level.WARNING, "Failed to migrate user: " + username, ex);
}
setProperty("lastAccountName", username);
}
}

View file

@ -7,6 +7,7 @@ import com.earth2me.essentials.metrics.Metrics;
import com.earth2me.essentials.perm.PermissionsHandler; import com.earth2me.essentials.perm.PermissionsHandler;
import com.earth2me.essentials.register.payment.Methods; import com.earth2me.essentials.register.payment.Methods;
import java.util.List; import java.util.List;
import java.util.UUID;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -27,6 +28,8 @@ public interface IEssentials extends Plugin
@Deprecated @Deprecated
User getUser(Object base); User getUser(Object base);
User getUser(UUID base);
User getUser(String base); User getUser(String base);
User getUser(Player base); User getUser(Player base);

View file

@ -35,6 +35,13 @@ public class OfflinePlayer implements Player
private boolean allowFlight = false; private boolean allowFlight = false;
private boolean isFlying = false; private boolean isFlying = false;
public OfflinePlayer(final UUID uuid, final IEssentials ess)
{
this.ess = ess;
this.world = ess.getServer().getWorlds().get(0);
this.base = ess.getServer().getOfflinePlayer(uuid);
}
public OfflinePlayer(final String name, final IEssentials ess) public OfflinePlayer(final String name, final IEssentials ess)
{ {
this.ess = ess; this.ess = ess;

View file

@ -1,6 +1,9 @@
package com.earth2me.essentials; package com.earth2me.essentials;
import lombok.Delegate; import lombok.Delegate;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
@ -13,12 +16,6 @@ import org.bukkit.permissions.ServerOperator;
public class PlayerExtension public class PlayerExtension
{ {
@Delegate(types =
{
Player.class, Entity.class, CommandSender.class, ServerOperator.class,
HumanEntity.class, ConfigurationSerializable.class, LivingEntity.class,
Permissible.class
})
protected Player base; protected Player base;
public PlayerExtension(final Player base) public PlayerExtension(final Player base)
@ -35,4 +32,17 @@ public class PlayerExtension
{ {
return this.base = base; return this.base = base;
} }
public Server getServer()
{
return base.getServer();
}
public World getWorld() {
return base.getWorld();
}
public Location getLocation() {
return base.getLocation();
}
} }

View file

@ -135,7 +135,7 @@ public class User extends UserData implements Comparable<User>, IReplyTo, net.es
} }
@Override @Override
public void giveMoney(final BigDecimal value) throws MaxMoneyException public void giveMoney(final BigDecimal value) throws MaxMoneyException
{ {
giveMoney(value, (CommandSource)null); giveMoney(value, (CommandSource)null);
} }
@ -225,7 +225,7 @@ public class User extends UserData implements Comparable<User>, IReplyTo, net.es
public void dispose() public void dispose()
{ {
this.base = new OfflinePlayer(getName(), ess); this.base = new OfflinePlayer(base.getUniqueId(), ess);
} }
@Override @Override
@ -493,7 +493,7 @@ public class User extends UserData implements Comparable<User>, IReplyTo, net.es
{ {
return; return;
} }
this.getBase().setSleepingIgnored(this.isAuthorized("essentials.sleepingignored") ? true : set); this.getBase().setSleepingIgnored(this.isAuthorized("essentials.sleepingignored") ? true : set);
if (set && !isAfk()) if (set && !isAfk())
{ {
@ -505,7 +505,7 @@ public class User extends UserData implements Comparable<User>, IReplyTo, net.es
} }
_setAfk(set); _setAfk(set);
} }
public boolean toggleAfk() public boolean toggleAfk()
{ {
setAfk(!isAfk()); setAfk(!isAfk());

View file

@ -18,7 +18,7 @@ import org.bukkit.inventory.ItemStack;
public abstract class UserData extends PlayerExtension implements IConf public abstract class UserData extends PlayerExtension implements IConf
{ {
protected final transient IEssentials ess; protected final transient IEssentials ess;
private final EssentialsConf config; private final EssentialsUserConf config;
private final File folder; private final File folder;
protected UserData(Player base, IEssentials ess) protected UserData(Player base, IEssentials ess)
@ -30,7 +30,20 @@ public abstract class UserData extends PlayerExtension implements IConf
{ {
folder.mkdirs(); folder.mkdirs();
} }
config = new EssentialsConf(new File(folder, StringUtil.sanitizeFileName(base.getName()) + ".yml"));
String filename;
try
{
filename = base.getUniqueId().toString();
}
catch (Throwable ex)
{
ess.getLogger().warning("Falling back to old username system for " + base.getName());
filename = base.getName();
}
ess.getLogger().info("Loading yml: " + filename + ".yml");
config = new EssentialsUserConf(base.getName(), base.getUniqueId(), new File(folder, filename + ".yml"));
reloadConfig(); reloadConfig();
} }
@ -71,6 +84,7 @@ public abstract class UserData extends PlayerExtension implements IConf
nickname = _getNickname(); nickname = _getNickname();
ignoredPlayers = _getIgnoredPlayers(); ignoredPlayers = _getIgnoredPlayers();
logoutLocation = _getLogoutLocation(); logoutLocation = _getLogoutLocation();
lastAccountName = _getLastAccountName();
} }
private BigDecimal money; private BigDecimal money;
@ -799,6 +813,25 @@ public abstract class UserData extends PlayerExtension implements IConf
{ {
return isNPC; return isNPC;
} }
private String lastAccountName = null;
public String getLastAccountName()
{
return lastAccountName;
}
public String _getLastAccountName()
{
return config.getString("lastAccountName", null);
}
public void setLastAccountName(String lastAccountName)
{
this.lastAccountName = lastAccountName;
config.setProperty("lastAccountName", lastAccountName);
config.save();
ess.getUserMap().trackUUID(base.getUniqueId(), lastAccountName);
}
public void setNPC(boolean set) public void setNPC(boolean set)
{ {
@ -873,12 +906,6 @@ public abstract class UserData extends PlayerExtension implements IConf
config.save(); config.save();
} }
public void trackUUID()
{
config.setProperty("uuid", base.getUniqueId().toString());
config.save();
}
public void setConfigProperty(String node, Object object) public void setConfigProperty(String node, Object object)
{ {
final String prefix = "info."; final String prefix = "info.";

View file

@ -4,27 +4,44 @@ import com.earth2me.essentials.utils.StringUtil;
import com.google.common.cache.Cache; import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
import com.google.common.io.Files;
import com.google.common.util.concurrent.UncheckedExecutionException; import com.google.common.util.concurrent.UncheckedExecutionException;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File; import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Collections; import java.util.Collections;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.ConcurrentSkipListSet; import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import net.ess3.api.IEssentials; import net.ess3.api.IEssentials;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public class UserMap extends CacheLoader<String, User> implements IConf public class UserMap extends CacheLoader<UUID, User> implements IConf
{ {
private final transient IEssentials ess; private final transient IEssentials ess;
private final transient Cache<String, User> users; private final transient Cache<UUID, User> users;
private final transient ConcurrentSkipListSet<String> keys = new ConcurrentSkipListSet<String>(); private final transient ConcurrentSkipListSet<UUID> keys = new ConcurrentSkipListSet<UUID>();
private final transient ConcurrentSkipListMap<String, UUID> names = new ConcurrentSkipListMap<String, UUID>();
private final transient Pattern splitPattern = Pattern.compile(",");
private File userList;
public UserMap(final IEssentials ess) public UserMap(final IEssentials ess)
{ {
super(); super();
this.ess = ess; this.ess = ess;
users = CacheBuilder.newBuilder().maximumSize(ess.getSettings().getMaxUserCacheCount()).softValues().build(this); userList = new File(ess.getDataFolder(), "usermap.csv");
users = CacheBuilder.newBuilder().maximumSize(ess.getSettings().getMaxUserCacheCount()).softValues().build(this);
loadAllUsersAsync(ess); loadAllUsersAsync(ess);
} }
@ -41,6 +58,7 @@ public class UserMap extends CacheLoader<String, User> implements IConf
return; return;
} }
keys.clear(); keys.clear();
names.clear();
users.invalidateAll(); users.invalidateAll();
for (String string : userdir.list()) for (String string : userdir.list())
{ {
@ -49,23 +67,76 @@ public class UserMap extends CacheLoader<String, User> implements IConf
continue; continue;
} }
final String name = string.substring(0, string.length() - 4); final String name = string.substring(0, string.length() - 4);
keys.add(StringUtil.sanitizeFileName(name)); try
{
keys.add(UUID.fromString(name));
}
catch (IllegalArgumentException ex)
{
//Ignore these users till they rejoin.
}
} }
try
{
if (!userList.exists())
{
userList.createNewFile();
}
final BufferedReader reader = new BufferedReader(new FileReader(userList));
try
{
do
{
final String line = reader.readLine();
if (line == null)
{
break;
}
else
{
String[] values = splitPattern.split(line);
if (values.length == 2)
{
names.put(values[0], UUID.fromString(values[1]));
}
}
}
while (true);
}
finally
{
reader.close();
}
}
catch (IOException ex)
{
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
}
} }
}); });
} }
public boolean userExists(final String name) public boolean userExists(final UUID uuid)
{ {
return keys.contains(StringUtil.sanitizeFileName(name)); return keys.contains(uuid);
} }
public User getUser(final String name) public User getUser(final String name)
{ {
try try
{ {
String sanitizedName = StringUtil.sanitizeFileName(name); final String sanitizedName = StringUtil.sanitizeFileName(name);
return users.get(sanitizedName); if (names.containsKey(sanitizedName))
{
ess.getLogger().info("Trying to grab user via string, found matching key.");
final UUID uuid = names.get(sanitizedName);
return users.get(uuid);
}
ess.getLogger().info("Trying to grab user via string, failed, returning null.");
return null; // TODO: THIS IS PROBABLY NOT RIGHT
} }
catch (ExecutionException ex) catch (ExecutionException ex)
{ {
@ -77,24 +148,67 @@ public class UserMap extends CacheLoader<String, User> implements IConf
} }
} }
@Override public User getUser(final UUID uuid)
public User load(final String sanitizedName) throws Exception
{ {
for (Player player : ess.getServer().getOnlinePlayers()) try
{ {
String sanitizedPlayer = StringUtil.sanitizeFileName(player.getName()); return users.get(uuid);
if (sanitizedPlayer.equalsIgnoreCase(sanitizedName))
{
keys.add(sanitizedName);
return new User(player, ess);
}
} }
final File userFile = getUserFile2(sanitizedName); catch (ExecutionException ex)
{
return null;
}
catch (UncheckedExecutionException ex)
{
return null;
}
}
public void trackUUID(final UUID uuid, final String name)
{
names.put(StringUtil.sanitizeFileName(name), uuid);
writeUUIDMap();
}
public void writeUUIDMap()
{
try
{
final File tempFile = File.createTempFile("usermap", ".tmp.yml", ess.getDataFolder());
final BufferedWriter bWriter = new BufferedWriter(new FileWriter(tempFile));
for (Map.Entry<String, UUID> entry : names.entrySet())
{
bWriter.write(entry.getKey() + "," + entry.getValue().toString());
bWriter.newLine();
}
bWriter.close();
Files.move(tempFile, userList);
}
catch (IOException ex)
{
Logger.getLogger(UserMap.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Override
public User load(final UUID uuid) throws Exception
{
Player player = ess.getServer().getPlayer(uuid);
if (player != null)
{
return new User(player, ess);
}
final File userFile = getUserFileFromID(uuid);
if (userFile.exists()) if (userFile.exists())
{ {
keys.add(sanitizedName); keys.add(uuid);
return new User(new OfflinePlayer(sanitizedName, ess), ess); return new User(new OfflinePlayer(uuid, ess), ess);
} }
throw new Exception("User not found!"); throw new Exception("User not found!");
} }
@ -106,12 +220,14 @@ public class UserMap extends CacheLoader<String, User> implements IConf
public void removeUser(final String name) public void removeUser(final String name)
{ {
keys.remove(StringUtil.sanitizeFileName(name)); UUID uuid = names.get(name);
users.invalidate(StringUtil.sanitizeFileName(name)); keys.remove(uuid);
users.invalidate(name); users.invalidate(uuid);
names.remove(name);
names.remove(StringUtil.sanitizeFileName(name));
} }
public Set<String> getAllUniqueUsers() public Set<UUID> getAllUniqueUsers()
{ {
return Collections.unmodifiableSet(keys); return Collections.unmodifiableSet(keys);
} }
@ -121,14 +237,9 @@ public class UserMap extends CacheLoader<String, User> implements IConf
return keys.size(); return keys.size();
} }
public File getUserFile(final String name) private File getUserFileFromID(final UUID uuid)
{
return getUserFile2(StringUtil.sanitizeFileName(name));
}
private File getUserFile2(final String name)
{ {
final File userFolder = new File(ess.getDataFolder(), "userdata"); final File userFolder = new File(ess.getDataFolder(), "userdata");
return new File(userFolder, name + ".yml"); return new File(userFolder, uuid.toString() + ".yml");
} }
} }

View file

@ -119,7 +119,7 @@ public class Commandbalancetop extends EssentialsCommand
} }
else else
{ {
for (String u : ess.getUserMap().getAllUniqueUsers()) for (UUID u : ess.getUserMap().getAllUniqueUsers())
{ {
final User user = ess.getUserMap().getUser(u); final User user = ess.getUserMap().getUser(u);
if (user != null) if (user != null)

View file

@ -10,6 +10,7 @@ import com.earth2me.essentials.utils.NumberUtil;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.UUID;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.Sound; import org.bukkit.Sound;
@ -269,7 +270,7 @@ public class Commandessentials extends EssentialsCommand
public void run() public void run()
{ {
Long currTime = System.currentTimeMillis(); Long currTime = System.currentTimeMillis();
for (String u : userMap.getAllUniqueUsers()) for (UUID u : userMap.getAllUniqueUsers())
{ {
final User user = ess.getUserMap().getUser(u); final User user = ess.getUserMap().getUser(u);
if (user == null) if (user == null)

View file

@ -9,6 +9,7 @@ import org.bukkit.Server;
import java.util.List; import java.util.List;
import static com.earth2me.essentials.I18n.tl; import static com.earth2me.essentials.I18n.tl;
import java.util.UUID;
public class Commandmail extends EssentialsCommand public class Commandmail extends EssentialsCommand
@ -154,9 +155,9 @@ public class Commandmail extends EssentialsCommand
@Override @Override
public void run() public void run()
{ {
for (String username : ess.getUserMap().getAllUniqueUsers()) for (UUID userid : ess.getUserMap().getAllUniqueUsers())
{ {
User user = ess.getUserMap().getUser(username); User user = ess.getUserMap().getUser(userid);
if (user != null) if (user != null)
{ {
user.addMail(message); user.addMail(message);

View file

@ -9,6 +9,7 @@ import com.earth2me.essentials.utils.FormatUtil;
import com.earth2me.essentials.utils.StringUtil; import com.earth2me.essentials.utils.StringUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Server; import org.bukkit.Server;
@ -149,7 +150,7 @@ public class Commandseen extends EssentialsCommand
public void run() public void run()
{ {
final List<String> matches = new ArrayList<String>(); final List<String> matches = new ArrayList<String>();
for (final String u : userMap.getAllUniqueUsers()) for (final UUID u : userMap.getAllUniqueUsers())
{ {
final User user = ess.getUserMap().getUser(u); final User user = ess.getUserMap().getUser(u);
if (user == null) if (user == null)

View file

@ -4,6 +4,7 @@ import com.earth2me.essentials.ChargeException;
import com.earth2me.essentials.CommandSource; import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.User; import com.earth2me.essentials.User;
import java.util.List; import java.util.List;
import java.util.UUID;
import net.ess3.api.MaxMoneyException; import net.ess3.api.MaxMoneyException;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -26,7 +27,7 @@ public abstract class EssentialsLoopCommand extends EssentialsCommand
if (matchWildcards && searchTerm.contentEquals("**")) if (matchWildcards && searchTerm.contentEquals("**"))
{ {
for (String sUser : ess.getUserMap().getAllUniqueUsers()) for (UUID sUser : ess.getUserMap().getAllUniqueUsers())
{ {
final User matchedUser = ess.getUser(sUser); final User matchedUser = ess.getUser(sUser);
updatePlayer(server, sender, matchedUser, commandArgs); updatePlayer(server, sender, matchedUser, commandArgs);