ChestShop-3/src/main/java/com/Acrobot/ChestShop/UUIDs/NameManager.java

285 lines
12 KiB
Java
Raw Normal View History

2014-04-06 19:51:30 +02:00
package com.Acrobot.ChestShop.UUIDs;
import com.Acrobot.Breeze.Utils.Encoding.Base62;
2014-04-06 19:51:47 +02:00
import com.Acrobot.Breeze.Utils.NameUtil;
2017-06-30 22:00:30 +02:00
import com.Acrobot.ChestShop.ChestShop;
2014-04-12 16:52:21 +02:00
import com.Acrobot.ChestShop.Configuration.Properties;
2014-04-10 21:52:05 +02:00
import com.Acrobot.ChestShop.Database.Account;
2015-05-22 13:26:07 +02:00
import com.Acrobot.ChestShop.Database.DaoCreator;
2014-04-12 13:57:39 +02:00
import com.Acrobot.ChestShop.Permission;
2014-08-13 17:22:52 +02:00
import com.Acrobot.ChestShop.Signs.ChestShopSign;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
2014-04-10 21:52:05 +02:00
import com.j256.ormlite.dao.Dao;
2016-09-20 21:45:18 +02:00
import org.apache.commons.lang.Validate;
2014-04-12 16:52:21 +02:00
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
2014-04-06 19:51:47 +02:00
import org.bukkit.entity.Player;
2014-04-10 21:52:05 +02:00
import java.sql.SQLException;
import java.util.Date;
2014-04-06 19:51:47 +02:00
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
2014-04-06 19:51:47 +02:00
2014-04-06 19:51:30 +02:00
/**
2014-04-06 19:51:47 +02:00
* Lets you save/cache username and UUID relations
2014-04-11 17:23:04 +02:00
*
2014-04-06 19:51:30 +02:00
* @author Andrzej Pomirski (Acrobot)
*/
@SuppressWarnings("UnusedAssignment") // I deliberately set the variables to null while initializing
2014-04-12 13:57:39 +02:00
public class NameManager {
2014-04-10 21:52:05 +02:00
private static Dao<Account, String> accounts;
private static Cache<String, Account> usernameToAccount = CacheBuilder.newBuilder().maximumSize(Properties.CACHE_SIZE).build();
private static Cache<UUID, Account> uuidToAccount = CacheBuilder.newBuilder().maximumSize(Properties.CACHE_SIZE).build();
private static Cache<String, Account> shortToAccount = CacheBuilder.newBuilder().maximumSize(Properties.CACHE_SIZE).build();
/**
* Get account info from a UUID
* @param uuid The UUID of the player to get the account info
* @return The account info or <tt>null</tt> if none was found
*/
public static Account getAccount(UUID uuid) {
2014-04-10 21:52:05 +02:00
try {
return uuidToAccount.get(uuid, () -> {
try {
Account account = accounts.queryBuilder().orderBy("lastSeen", false).where().eq("uuid", uuid).queryForFirst();
if (account != null) {
account.setUuid(uuid); //HOW IS IT EVEN POSSIBLE THAT UUID IS NOT SET EVEN IF WE HAVE FOUND THE PLAYER?!
shortToAccount.put(account.getShortName(), account);
usernameToAccount.put(account.getName(), account);
return account;
}
} catch (SQLException e) {
ChestShop.getBukkitLogger().log(Level.WARNING, "Error while getting account for " + uuid + ":", e);
}
throw new Exception("Could not find account for " + uuid);
});
} catch (ExecutionException ignored) {
2014-04-10 21:52:05 +02:00
return null;
}
2014-04-06 19:51:47 +02:00
}
/**
* Get account info from a non-shortened username
* @param fullName The full name of the player to get the account info
* @return The account info or <tt>null</tt> if none was found
* @throws IllegalArgumentException if the username is empty or null
*/
public static Account getAccount(String fullName) {
Validate.notEmpty(fullName, "fullName cannot be null or empty!");
2014-04-10 21:52:05 +02:00
try {
return usernameToAccount.get(fullName, () -> {
try {
Account account = accounts.queryBuilder().orderBy("lastSeen", false).where().eq("name", fullName).queryForFirst();
if (account != null) {
account.setName(fullName); //HOW IS IT EVEN POSSIBLE THAT UUID IS NOT SET EVEN IF WE HAVE FOUND THE PLAYER?!
shortToAccount.put(account.getShortName(), account);
return account;
}
} catch (SQLException e) {
ChestShop.getBukkitLogger().log(Level.WARNING, "Error while getting account for " + fullName + ":", e);
}
throw new Exception("Could not find account for " + fullName);
});
} catch (ExecutionException ignored) {
return null;
2014-04-11 17:17:20 +02:00
}
2014-04-06 19:51:47 +02:00
}
/**
* Get account info from a username that might be shortened
* @param shortName The name of the player to get the account info
* @return The account info or <tt>null</tt> if none was found
* @throws IllegalArgumentException if the username is not a shortened name and longer than 15 chars
*/
public static Account getAccountFromShortName(String shortName) {
Validate.notEmpty(shortName, "shortName cannot be null or empty!");
Validate.isTrue(shortName.length() < 16, "Username is not a shortened name and longer than 15 chars!");
2014-08-13 17:22:52 +02:00
try {
return shortToAccount.get(shortName, () -> {
try {
Account account = accounts.queryBuilder().where().eq("shortName", shortName).queryForFirst();
if (account != null) {
account.setShortName(shortName); //HOW IS IT EVEN POSSIBLE THAT UUID IS NOT SET EVEN IF WE HAVE FOUND THE PLAYER?!
return account;
}
} catch (SQLException e) {
ChestShop.getBukkitLogger().log(Level.WARNING, "Error while getting account for " + shortName + ":", e);
}
throw new Exception("Could not find account for " + shortName);
});
} catch (ExecutionException ignored) {
return null;
}
}
/**
* Get the UUID from a player's (non-shortened) username
* @param username The player's username
* @return The UUID or <tt>null</tt> if the UUID can't be found or an error occurred
* @deprecated Use {@link NameManager#getAccount(String)}
*/
@Deprecated
public static UUID getUUID(String username) {
Validate.notEmpty(username, "username cannot be null or empty!");
Player player = Bukkit.getPlayer(username);
if (player != null) {
return player.getUniqueId();
}
Account account = getAccount(username);
if (account != null) {
return account.getUuid();
}
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(username);
if (offlinePlayer != null && offlinePlayer.hasPlayedBefore() && offlinePlayer.getUniqueId() != null) {
return offlinePlayer.getUniqueId();
}
return null;
}
/**
* Get the username from a player's UUID
* @param uuid The UUID of the player
* @return The username that is stored or <tt>null</tt> if none was found
* @deprecated Use {@link NameManager#getAccount(UUID)}
*/
@Deprecated
public static String getUsername(UUID uuid) {
Player player = Bukkit.getPlayer(uuid);
if (player != null) {
return player.getName();
}
Account account = getAccount(uuid);
if (account != null) {
return account.getName();
}
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(uuid);
if (offlinePlayer != null && offlinePlayer.hasPlayedBefore() && offlinePlayer.getName() != null) {
return offlinePlayer.getName();
}
return null;
}
/**
* Get the full username from another username that might be shortened
* @param shortName The name of the player to get the full username for
* @return The full username or <tt>null</tt> if none was found
* @throws IllegalArgumentException if the username is not a shortened name and longer than 15 chars
* @deprecated Use {@link NameManager#getAccountFromShortName(String)}
*/
@Deprecated
public static String getFullUsername(String shortName) {
Account account = getAccountFromShortName(shortName); // first get the account associated with the short name
if (account != null) {
account = getAccount(account.getUuid()); // then get the last account that was online with that UUID
if (account != null) {
return account.getName();
}
2014-04-06 19:51:47 +02:00
}
return null;
}
/**
* Get the short username from a full username
* @param fullName The name of the player to get the short username for
* @return The short username or <tt>null</tt> if none was found
* @deprecated Use {@link NameManager#getAccount(String)}
*/
@Deprecated
public static String getShortUsername(String fullName) {
Account account = getAccount(fullName);
return account != null ? account.getShortName() : null;
2014-05-06 11:55:33 +02:00
}
2014-04-06 19:51:47 +02:00
/**
* Store the username of a player into the database and the username-uuid cache
* @param player The data transfer object of the player to store
*/
2015-07-05 21:56:42 +02:00
public static void storeUsername(final PlayerDTO player) {
2014-05-06 11:55:33 +02:00
final UUID uuid = player.getUniqueId();
2014-04-06 19:51:47 +02:00
Account latestAccount = null;
try {
latestAccount = accounts.queryBuilder().where().eq("uuid", uuid).and().eq("name", player.getName()).queryForFirst();
} catch (SQLException e) {
2017-06-30 22:00:30 +02:00
ChestShop.getBukkitLogger().log(Level.WARNING, "Error while searching for latest account of " + player.getName() + "/" + uuid + ":", e);
}
2015-07-05 21:56:42 +02:00
if (latestAccount == null) {
latestAccount = new Account(player.getName(), player.getUniqueId());
latestAccount.setShortName(getNewShortenedName(player));
}
2014-05-06 11:55:33 +02:00
latestAccount.setLastSeen(new Date());
try {
accounts.createOrUpdate(latestAccount);
} catch (SQLException e) {
ChestShop.getBukkitLogger().log(Level.WARNING, "Error while updating account " + latestAccount + ":", e);
}
usernameToAccount.put(latestAccount.getName(), latestAccount);
uuidToAccount.put(uuid, latestAccount);
shortToAccount.put(latestAccount.getShortName(), latestAccount);
2014-04-06 19:51:47 +02:00
}
/**
* Get a new unique shortened name that hasn't been used by another player yet
* @param player The player data to get the shortened name for
* @return A new shortened name that hasn't been used before and is a maximum of 15 chars long
*/
private static String getNewShortenedName(PlayerDTO player) {
String shortenedName = NameUtil.stripUsername(player.getName());
Account account = getAccountFromShortName(shortenedName);
if (account == null) {
return shortenedName;
}
for (int id = 0; account != null; id++) {
String baseId = Base62.encode(id);
shortenedName = NameUtil.stripUsername(player.getName(), 15 - 1 - baseId.length()) + ":" + baseId;
account = getAccountFromShortName(shortenedName);
}
return shortenedName;
}
2014-04-12 13:57:39 +02:00
public static boolean canUseName(Player player, String name) {
2015-03-21 16:11:33 +01:00
if (ChestShopSign.isAdminShop(name)) {
return false;
}
if (Permission.otherName(player, name)) {
return true;
}
Account account = getAccountFromShortName(name);
return account != null && account.getUuid().equals(player.getUniqueId());
2014-04-12 13:57:39 +02:00
}
2014-06-14 20:46:59 +02:00
public static boolean isAdminShop(UUID uuid) {
2015-05-22 13:26:07 +02:00
return Properties.ADMIN_SHOP_NAME.equals(getUsername(uuid));
2014-06-14 20:46:59 +02:00
}
2014-04-06 19:51:47 +02:00
public static void load() {
try {
2015-05-22 13:26:07 +02:00
accounts = DaoCreator.getDaoAndCreateTable(Account.class);
2014-04-12 16:52:21 +02:00
Account adminAccount = new Account(Properties.ADMIN_SHOP_NAME, Bukkit.getOfflinePlayer(Properties.ADMIN_SHOP_NAME).getUniqueId());
2014-07-28 20:51:04 +02:00
accounts.createOrUpdate(adminAccount);
if (!Properties.SERVER_ECONOMY_ACCOUNT.isEmpty()) {
Account serverEconomyAccount = getAccount(Properties.SERVER_ECONOMY_ACCOUNT);
if (serverEconomyAccount == null || serverEconomyAccount.getUuid() == null) {
ChestShop.getBukkitLogger().log(Level.WARNING, "Server economy account setting '" + Properties.SERVER_ECONOMY_ACCOUNT + "' doesn't seem to be the name of a known player! Please log in at least once in order for the server economy account to work.");
}
}
2014-04-10 21:52:05 +02:00
} catch (SQLException e) {
2014-04-06 19:51:47 +02:00
e.printStackTrace();
}
}
2014-04-06 19:51:30 +02:00
}