Rewrite NameManager to support multiple short names per user

This should fix the issue where the player's short name on the shop sign does not reflect the actual player's name. This works by storing every uuid-username combination together with the associated short name and the last time the player logged in with that combination.
This commit is contained in:
Phoenix616 2017-07-01 17:14:41 +01:00
parent aa2437f76b
commit 0525c70452
12 changed files with 230 additions and 178 deletions

View File

@ -1,9 +1,11 @@
package com.Acrobot.ChestShop.Database; package com.Acrobot.ChestShop.Database;
import com.Acrobot.Breeze.Utils.NameUtil; import com.Acrobot.Breeze.Utils.NameUtil;
import com.j256.ormlite.field.DataType;
import com.j256.ormlite.field.DatabaseField; import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable; import com.j256.ormlite.table.DatabaseTable;
import java.util.Date;
import java.util.UUID; import java.util.UUID;
/** /**
@ -14,18 +16,18 @@ import java.util.UUID;
@DatabaseFileName("users.db") @DatabaseFileName("users.db")
public class Account { public class Account {
@DatabaseField(canBeNull = false) @DatabaseField(index = true, canBeNull = false, uniqueCombo = true)
private String lastSeenName;
@DatabaseField(id = true, canBeNull = false)
private String name; private String name;
@DatabaseField(index = true, canBeNull = false) @DatabaseField(id = true, index = true, canBeNull = false)
private String shortName; private String shortName;
@DatabaseField(canBeNull = false) @DatabaseField(index = true, canBeNull = false, uniqueCombo = true)
private UUID uuid; private UUID uuid;
@DatabaseField(canBeNull = false, dataType = DataType.DATE_LONG, defaultValue = "0")
private Date lastSeen;
public Account() { public Account() {
//empty constructor, needed for ORMLite //empty constructor, needed for ORMLite
} }
@ -33,18 +35,9 @@ public class Account {
public Account(String name, UUID uuid) { public Account(String name, UUID uuid) {
this.name = name; this.name = name;
this.shortName = NameUtil.stripUsername(name); this.shortName = NameUtil.stripUsername(name);
this.lastSeenName = name;
this.uuid = uuid; this.uuid = uuid;
} }
public String getLastSeenName() {
return lastSeenName;
}
public void setLastSeenName(String lastSeenName) {
this.lastSeenName = lastSeenName;
}
public String getName() { public String getName() {
return name; return name;
} }
@ -68,4 +61,12 @@ public class Account {
public void setUuid(UUID uuid) { public void setUuid(UUID uuid) {
this.uuid = uuid; this.uuid = uuid;
} }
public Date getLastSeen() {
return lastSeen;
}
public void setLastSeen(Date lastSeen) {
this.lastSeen = lastSeen;
}
} }

View File

@ -11,7 +11,7 @@ import java.sql.SQLException;
* @author Andrzej Pomirski * @author Andrzej Pomirski
*/ */
public class Migrations { public class Migrations {
public static final int CURRENT_DATABASE_VERSION = 2; public static final int CURRENT_DATABASE_VERSION = 3;
/** /**
* Migrates a database from the given version * Migrates a database from the given version
@ -33,9 +33,19 @@ public class Migrations {
if (migrated) { if (migrated) {
currentVersion++; currentVersion++;
} }
break;
case 2: case 2:
boolean migrated3 = migrateTo3();
if (migrated3) {
currentVersion++;
}
break;
case 3:
break;
default: default:
break;
//do nothing //do nothing
} }
@ -53,4 +63,19 @@ public class Migrations {
return false; return false;
} }
} }
private static boolean migrateTo3() {
try {
Dao<Account, String> accountsOld = DaoCreator.getDao(Account.class);
accountsOld.executeRaw("ALTER TABLE `accounts` RENAME TO `accounts-old`");
Dao<Account, String> accounts = DaoCreator.getDaoAndCreateTable(Account.class);
accounts.executeRaw("INSERT INTO `accounts` (name, shortName, uuid) SELECT name, shortName, uuid FROM `accounts-old`");
return true;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
} }

View File

@ -142,6 +142,8 @@ public class PreShopCreationEvent extends Event {
INVALID_PRICE, INVALID_PRICE,
INVALID_QUANTITY, INVALID_QUANTITY,
UNKNOWN_PLAYER,
SELL_PRICE_HIGHER_THAN_BUY_PRICE, SELL_PRICE_HIGHER_THAN_BUY_PRICE,
NO_CHEST, NO_CHEST,

View File

@ -21,7 +21,7 @@ public class ServerAccountCorrector implements Listener {
public static void onCurrencyAdd(CurrencyAddEvent event) { public static void onCurrencyAdd(CurrencyAddEvent event) {
UUID target = event.getTarget(); UUID target = event.getTarget();
if (!NameManager.isAdminShop(target) || NameManager.getUsername(target).equals(SERVER_ECONOMY_ACCOUNT)) { if (!NameManager.isAdminShop(target) || SERVER_ECONOMY_ACCOUNT.equals(NameManager.getUsername(target))) {
return; return;
} }
@ -42,7 +42,7 @@ public class ServerAccountCorrector implements Listener {
public static void onCurrencySubtract(CurrencySubtractEvent event) { public static void onCurrencySubtract(CurrencySubtractEvent event) {
UUID target = event.getTarget(); UUID target = event.getTarget();
if (!NameManager.isAdminShop(target) || NameManager.getUsername(target).equals(SERVER_ECONOMY_ACCOUNT)) { if (!NameManager.isAdminShop(target) || SERVER_ECONOMY_ACCOUNT.equals(NameManager.getUsername(target))) {
return; return;
} }
@ -63,7 +63,7 @@ public class ServerAccountCorrector implements Listener {
public static void onCurrencyCheck(CurrencyCheckEvent event) { public static void onCurrencyCheck(CurrencyCheckEvent event) {
UUID target = event.getAccount(); UUID target = event.getAccount();
if (!NameManager.isAdminShop(target) || NameManager.getUsername(target).equals(SERVER_ECONOMY_ACCOUNT)) { if (!NameManager.isAdminShop(target) || SERVER_ECONOMY_ACCOUNT.equals(NameManager.getUsername(target))) {
return; return;
} }
@ -84,7 +84,7 @@ public class ServerAccountCorrector implements Listener {
public static void onCurrencyHoldCheck(CurrencyHoldEvent event) { public static void onCurrencyHoldCheck(CurrencyHoldEvent event) {
UUID target = event.getAccount(); UUID target = event.getAccount();
if (!NameManager.isAdminShop(target) || NameManager.getUsername(target).equals(SERVER_ECONOMY_ACCOUNT)) { if (!NameManager.isAdminShop(target) || SERVER_ECONOMY_ACCOUNT.equals(NameManager.getUsername(target))) {
return; return;
} }
@ -96,7 +96,7 @@ public class ServerAccountCorrector implements Listener {
public static void onBalanceCheck(CurrencyAmountEvent event) { public static void onBalanceCheck(CurrencyAmountEvent event) {
UUID target = event.getAccount(); UUID target = event.getAccount();
if (!NameManager.isAdminShop(target) || NameManager.getUsername(target).equals(SERVER_ECONOMY_ACCOUNT)) { if (!NameManager.isAdminShop(target) || SERVER_ECONOMY_ACCOUNT.equals(NameManager.getUsername(target))) {
return; return;
} }

View File

@ -33,7 +33,7 @@ public class TaxModule implements Listener {
UUID target = event.getTarget(); UUID target = event.getTarget();
if (NameManager.getUsername(target).equals(Economy.getServerAccountName())) { if (Economy.getServerAccountName().equals(NameManager.getUsername(target))) {
return; return;
} }

View File

@ -4,6 +4,7 @@ import com.Acrobot.Breeze.Utils.*;
import com.Acrobot.ChestShop.Configuration.Messages; import com.Acrobot.ChestShop.Configuration.Messages;
import com.Acrobot.ChestShop.Configuration.Properties; import com.Acrobot.ChestShop.Configuration.Properties;
import com.Acrobot.ChestShop.Containers.AdminInventory; import com.Acrobot.ChestShop.Containers.AdminInventory;
import com.Acrobot.ChestShop.Database.Account;
import com.Acrobot.ChestShop.Events.PreTransactionEvent; import com.Acrobot.ChestShop.Events.PreTransactionEvent;
import com.Acrobot.ChestShop.Events.TransactionEvent; import com.Acrobot.ChestShop.Events.TransactionEvent;
import com.Acrobot.ChestShop.Listeners.Economy.Plugins.VaultListener; import com.Acrobot.ChestShop.Listeners.Economy.Plugins.VaultListener;
@ -112,15 +113,11 @@ public class PlayerInteract implements Listener {
String prices = sign.getLine(PRICE_LINE); String prices = sign.getLine(PRICE_LINE);
String material = sign.getLine(ITEM_LINE); String material = sign.getLine(ITEM_LINE);
String ownerName = NameManager.getFullUsername(name); Account account = NameManager.getAccountFromShortName(name);
if (ownerName == null || ownerName.isEmpty()) if (account == null)
return null; return null;
UUID uuid = NameManager.getUUID(ownerName); OfflinePlayer owner = Bukkit.getOfflinePlayer(account.getUuid());
if (uuid == null)
return null;
OfflinePlayer owner = Bukkit.getOfflinePlayer(uuid);
// check if player exists in economy // check if player exists in economy
if(!ChestShopSign.isAdminShop(sign) && (owner == null || owner.getName() == null || !VaultListener.getProvider().hasAccount(owner))) if(!ChestShopSign.isAdminShop(sign) && (owner == null || owner.getName() == null || !VaultListener.getProvider().hasAccount(owner)))

View File

@ -33,7 +33,6 @@ public class TransactionMessageSender implements Listener {
protected static void sendBuyMessage(TransactionEvent event) { protected static void sendBuyMessage(TransactionEvent event) {
String itemName = parseItemInformation(event.getStock()); String itemName = parseItemInformation(event.getStock());
String owner = NameManager.getUsername(event.getOwner().getUniqueId());
Player player = event.getClient(); Player player = event.getClient();
@ -41,7 +40,7 @@ public class TransactionMessageSender implements Listener {
if (Properties.SHOW_TRANSACTION_INFORMATION_CLIENT) { if (Properties.SHOW_TRANSACTION_INFORMATION_CLIENT) {
String message = formatMessage(Messages.YOU_BOUGHT_FROM_SHOP, itemName, price); String message = formatMessage(Messages.YOU_BOUGHT_FROM_SHOP, itemName, price);
message = message.replace("%owner", owner); message = message.replace("%owner", event.getOwner().getName());
player.sendMessage(message); player.sendMessage(message);
} }
@ -56,7 +55,6 @@ public class TransactionMessageSender implements Listener {
protected static void sendSellMessage(TransactionEvent event) { protected static void sendSellMessage(TransactionEvent event) {
String itemName = parseItemInformation(event.getStock()); String itemName = parseItemInformation(event.getStock());
String owner = NameManager.getUsername(event.getOwner().getUniqueId());
Player player = event.getClient(); Player player = event.getClient();
@ -64,7 +62,7 @@ public class TransactionMessageSender implements Listener {
if (Properties.SHOW_TRANSACTION_INFORMATION_CLIENT) { if (Properties.SHOW_TRANSACTION_INFORMATION_CLIENT) {
String message = formatMessage(Messages.YOU_SOLD_TO_SHOP, itemName, price); String message = formatMessage(Messages.YOU_SOLD_TO_SHOP, itemName, price);
message = message.replace("%buyer", owner); message = message.replace("%buyer", event.getOwner().getName());
player.sendMessage(message); player.sendMessage(message);
} }

View File

@ -1,6 +1,6 @@
package com.Acrobot.ChestShop.Listeners.PreShopCreation; package com.Acrobot.ChestShop.Listeners.PreShopCreation;
import com.Acrobot.Breeze.Utils.NameUtil; import com.Acrobot.ChestShop.Database.Account;
import com.Acrobot.ChestShop.Events.PreShopCreationEvent; import com.Acrobot.ChestShop.Events.PreShopCreationEvent;
import com.Acrobot.ChestShop.Permission; import com.Acrobot.ChestShop.Permission;
import com.Acrobot.ChestShop.UUIDs.NameManager; import com.Acrobot.ChestShop.UUIDs.NameManager;
@ -10,6 +10,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import static com.Acrobot.ChestShop.Signs.ChestShopSign.NAME_LINE; import static com.Acrobot.ChestShop.Signs.ChestShopSign.NAME_LINE;
import static com.Acrobot.ChestShop.Events.PreShopCreationEvent.CreationOutcome.UNKNOWN_PLAYER;
/** /**
* @author Acrobot * @author Acrobot
@ -22,8 +23,12 @@ public class NameChecker implements Listener {
Player player = event.getPlayer(); Player player = event.getPlayer();
if (name.isEmpty() || (!NameManager.canUseName(player, name) && !Permission.has(player, Permission.ADMIN))) { if (name.isEmpty() || (!NameManager.canUseName(player, name) && !Permission.has(player, Permission.ADMIN))) {
String shortName = NameUtil.stripUsername(NameManager.getUsername(player.getUniqueId())); Account account = NameManager.getAccount(player.getName());
event.setSignLine(NAME_LINE, shortName); if (account != null) {
event.setSignLine(NAME_LINE, account.getShortName());
} else {
event.setOutcome(UNKNOWN_PLAYER);
}
} }
} }
} }

View File

@ -3,6 +3,7 @@ package com.Acrobot.ChestShop.Listeners.ShopRemoval;
import com.Acrobot.ChestShop.ChestShop; import com.Acrobot.ChestShop.ChestShop;
import com.Acrobot.ChestShop.Configuration.Messages; import com.Acrobot.ChestShop.Configuration.Messages;
import com.Acrobot.ChestShop.Configuration.Properties; import com.Acrobot.ChestShop.Configuration.Properties;
import com.Acrobot.ChestShop.Database.Account;
import com.Acrobot.ChestShop.Economy.Economy; import com.Acrobot.ChestShop.Economy.Economy;
import com.Acrobot.ChestShop.Events.Economy.CurrencyAddEvent; import com.Acrobot.ChestShop.Events.Economy.CurrencyAddEvent;
import com.Acrobot.ChestShop.Events.Economy.CurrencySubtractEvent; import com.Acrobot.ChestShop.Events.Economy.CurrencySubtractEvent;
@ -31,14 +32,12 @@ public class ShopRefundListener implements Listener {
return; return;
} }
String ownerName = NameManager.getFullUsername(event.getSign().getLine(NAME_LINE)); Account account = NameManager.getAccountFromShortName(event.getSign().getLine(NAME_LINE));
if (ownerName == null || ownerName.isEmpty()) { if (account == null) {
return; return;
} }
UUID owner = NameManager.getUUID(ownerName); CurrencyAddEvent currencyEvent = new CurrencyAddEvent(BigDecimal.valueOf(refundPrice), account.getUuid(), event.getSign().getWorld());
CurrencyAddEvent currencyEvent = new CurrencyAddEvent(BigDecimal.valueOf(refundPrice), owner, event.getSign().getWorld());
ChestShop.callEvent(currencyEvent); ChestShop.callEvent(currencyEvent);
if (!Economy.getServerAccountName().isEmpty()) { if (!Economy.getServerAccountName().isEmpty()) {

View File

@ -1,6 +1,7 @@
package com.Acrobot.ChestShop.Plugins; package com.Acrobot.ChestShop.Plugins;
import com.Acrobot.Breeze.Utils.NameUtil; import com.Acrobot.Breeze.Utils.NameUtil;
import com.Acrobot.ChestShop.Database.Account;
import com.Acrobot.ChestShop.Events.Protection.ProtectionCheckEvent; import com.Acrobot.ChestShop.Events.Protection.ProtectionCheckEvent;
import com.Acrobot.ChestShop.UUIDs.NameManager; import com.Acrobot.ChestShop.UUIDs.NameManager;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@ -26,9 +27,8 @@ public class Lockette implements Listener {
return; return;
} }
String shortPlayerName = NameUtil.stripUsername(NameManager.getUsername(player.getUniqueId())); Account account = NameManager.getAccount(player.getUniqueId());
if (account != null && !org.yi.acru.bukkit.Lockette.Lockette.isUser(block, account.getName(), true)) {
if (!org.yi.acru.bukkit.Lockette.Lockette.isUser(block, shortPlayerName, true)) {
event.setResult(Event.Result.DENY); event.setResult(Event.Result.DENY);
} }
} }

View File

@ -3,6 +3,7 @@ package com.Acrobot.ChestShop;
import com.Acrobot.Breeze.Utils.BlockUtil; import com.Acrobot.Breeze.Utils.BlockUtil;
import com.Acrobot.Breeze.Utils.NameUtil; import com.Acrobot.Breeze.Utils.NameUtil;
import com.Acrobot.ChestShop.Configuration.Properties; import com.Acrobot.ChestShop.Configuration.Properties;
import com.Acrobot.ChestShop.Database.Account;
import com.Acrobot.ChestShop.Events.Protection.ProtectBlockEvent; import com.Acrobot.ChestShop.Events.Protection.ProtectBlockEvent;
import com.Acrobot.ChestShop.Events.Protection.ProtectionCheckEvent; import com.Acrobot.ChestShop.Events.Protection.ProtectionCheckEvent;
import com.Acrobot.ChestShop.Signs.ChestShopSign; import com.Acrobot.ChestShop.Signs.ChestShopSign;
@ -64,9 +65,6 @@ public class Security {
} }
private static boolean anotherShopFound(Block baseBlock, Block signBlock, Player player) { private static boolean anotherShopFound(Block baseBlock, Block signBlock, Player player) {
String playerName = NameManager.getUsername(player.getUniqueId());
String shortName = NameUtil.stripUsername(playerName);
for (BlockFace face : SIGN_CONNECTION_FACES) { for (BlockFace face : SIGN_CONNECTION_FACES) {
Block block = baseBlock.getRelative(face); Block block = baseBlock.getRelative(face);
@ -80,7 +78,8 @@ public class Security {
continue; continue;
} }
if (!sign.getLine(ChestShopSign.NAME_LINE).equals(shortName)) { Account account = NameManager.getAccountFromShortName(sign.getLine(ChestShopSign.NAME_LINE));
if (account != null && !account.getUuid().equals(player.getUniqueId())) {
return true; return true;
} }
} }

View File

@ -10,7 +10,6 @@ import com.Acrobot.ChestShop.Permission;
import com.Acrobot.ChestShop.Signs.ChestShopSign; import com.Acrobot.ChestShop.Signs.ChestShopSign;
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.j256.ormlite.dao.CloseableIterator;
import com.j256.ormlite.dao.Dao; import com.j256.ormlite.dao.Dao;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
@ -19,6 +18,7 @@ import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Date;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.logging.Level; import java.util.logging.Level;
@ -32,118 +32,167 @@ import java.util.logging.Level;
public class NameManager { public class NameManager {
private static Dao<Account, String> accounts; private static Dao<Account, String> accounts;
private static Cache<String, UUID> usernameToUUID = CacheBuilder.newBuilder().maximumSize(Properties.CACHE_SIZE).build(); private static Cache<String, Account> usernameToAccount = CacheBuilder.newBuilder().maximumSize(Properties.CACHE_SIZE).build();
private static Cache<UUID, String> uuidToUsername = CacheBuilder.newBuilder().maximumSize(Properties.CACHE_SIZE).build(); private static Cache<UUID, Account> uuidToAccount = CacheBuilder.newBuilder().maximumSize(Properties.CACHE_SIZE).build();
private static Cache<String, String> shortToLongName = CacheBuilder.newBuilder().maximumSize(Properties.CACHE_SIZE).build(); private static Cache<String, Account> shortToAccount = CacheBuilder.newBuilder().maximumSize(Properties.CACHE_SIZE).build();
/** /**
* Get the UUID from a player's (non-shortened) username * Get account info from a UUID
* @param username The player's username * @param uuid The UUID of the player to get the account info
* @return The UUID or <tt>null</tt> if the UUID can't be found or an error occurred * @return The account info or <tt>null</tt> if none was found
*/ */
public static UUID getUUID(String username) { public static Account getAccount(UUID uuid) {
Validate.notEmpty(username, "username cannot be null or empty!");
try { try {
return usernameToUUID.get(username, () -> { return uuidToAccount.get(uuid, () -> {
UUID uuid = null; try {
Player player = Bukkit.getPlayer(username); Account account = accounts.queryBuilder().orderBy("lastSeen", false).where().eq("uuid", uuid).queryForFirst();
if (player != null) { if (account != null) {
uuid = player.getUniqueId(); 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);
if (uuid == null) { usernameToAccount.put(account.getName(), account);
try { return account;
Account account = accounts.queryBuilder().selectColumns("uuid").where().eq("lastSeenName", username).queryForFirst();
if (account != null) {
uuid = account.getUuid();
}
} catch (SQLException e) {
ChestShop.getBukkitLogger().log(Level.WARNING, "Error while getting uuid for " + username + ":", e);
} }
} catch (SQLException e) {
ChestShop.getBukkitLogger().log(Level.WARNING, "Error while getting account for " + uuid + ":", e);
} }
if (uuid == null) { throw new Exception("Could not find account for " + uuid);
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(username);
if (offlinePlayer != null && offlinePlayer.hasPlayedBefore() && offlinePlayer.getUniqueId() != null) {
uuid = offlinePlayer.getUniqueId();
}
}
if (uuid != null) {
uuidToUsername.put(uuid, username);
return uuid;
}
throw new Exception("Could not find username for " + uuid);
}); });
} catch (ExecutionException e) { } catch (ExecutionException ignored) {
return null; return null;
} }
} }
/**
* 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!");
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;
}
}
/**
* 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!");
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 * Get the username from a player's UUID
* @param uuid The UUID of the player * @param uuid The UUID of the player
* @return The username that is stored, an empty string if none was found or <tt>null</tt> if an error occurred * @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) { public static String getUsername(UUID uuid) {
try { Player player = Bukkit.getPlayer(uuid);
return uuidToUsername.get(uuid, () -> { if (player != null) {
String name = null; return player.getName();
Player player = Bukkit.getPlayer(uuid);
if (player != null) {
name = player.getName();
}
if (name == null) {
try {
Account account = accounts.queryBuilder().selectColumns("lastSeenName").where().eq("uuid", uuid).queryForFirst();
if (account != null) {
name = account.getLastSeenName();
}
} catch (SQLException e) {
ChestShop.getBukkitLogger().log(Level.WARNING, "Error while getting username for " + uuid + ":", e);
}
}
if (name == null) {
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(uuid);
if (offlinePlayer != null && offlinePlayer.hasPlayedBefore() && offlinePlayer.getName() != null) {
name = offlinePlayer.getName();
}
}
if (name != null) {
usernameToUUID.put(name, uuid);
return name;
}
throw new Exception("Could not find username for " + uuid);
});
} catch (ExecutionException e) {
return "";
} }
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 * Get the full username from another username that might be shortened
* @param shortName The name of the player to get the full username for * @param shortName The name of the player to get the full username for
* @return The full username, an empty string if none was found or <tt>null</tt> if an error occurred * @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 * @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) { public static String getFullUsername(String shortName) {
Validate.isTrue(shortName.length() < 16, "Username is not a shortened name and longer than 15 chars!"); Account account = getAccountFromShortName(shortName); // first get the account associated with the short name
if (ChestShopSign.isAdminShop(shortName)) { if (account != null) {
return Properties.ADMIN_SHOP_NAME; account = getAccount(account.getUuid()); // then get the last account that was online with that UUID
if (account != null) {
return account.getName();
}
} }
return null;
}
try { /**
return shortToLongName.get(shortName, () -> { * Get the short username from a full username
try { * @param fullName The name of the player to get the short username for
Account account = accounts.queryBuilder().selectColumns("lastSeenName").where().eq("shortName", shortName).queryForFirst(); * @return The short username or <tt>null</tt> if none was found
if (account != null) { * @deprecated Use {@link NameManager#getAccount(String)}
return account.getLastSeenName(); */
} @Deprecated
} catch (SQLException e) { public static String getShortUsername(String fullName) {
ChestShop.getBukkitLogger().log(Level.WARNING, "Error while getting full name for " + shortName + ":", e); Account account = getAccount(fullName);
} return account != null ? account.getShortName() : null;
throw new Exception("Could not find full name for " + shortName);
});
} catch (ExecutionException ignored) {
return "";
}
} }
/** /**
@ -153,35 +202,9 @@ public class NameManager {
public static void storeUsername(final PlayerDTO player) { public static void storeUsername(final PlayerDTO player) {
final UUID uuid = player.getUniqueId(); final UUID uuid = player.getUniqueId();
CloseableIterator<Account> existingAccounts = null;
try {
existingAccounts = accounts.queryBuilder().where().eq("uuid", uuid).ne("lastSeenName", player.getName()).iterator();
while (existingAccounts.hasNext()) {
Account account = existingAccounts.next();
account.setUuid(uuid); //HOW IS IT EVEN POSSIBLE THAT UUID IS NOT SET EVEN IF WE HAVE FOUND THE PLAYER?!
account.setLastSeenName(player.getName());
try {
accounts.update(account);
} catch (SQLException e) {
ChestShop.getBukkitLogger().log(Level.WARNING, "Error while updating account " + account + ":", e);
}
}
} catch (SQLException e) {
ChestShop.getBukkitLogger().log(Level.WARNING, "Error getting all entries for " + uuid + ":", e);
return;
} finally {
if (existingAccounts != null) {
try {
existingAccounts.close();
} catch (SQLException e) {
ChestShop.getBukkitLogger().log(Level.WARNING, "Error while closing query iterator for " + uuid + ":", e);
}
}
}
Account latestAccount = null; Account latestAccount = null;
try { try {
latestAccount = accounts.queryBuilder().where().eq("uuid", uuid).eq("name", player.getName()).queryForFirst(); latestAccount = accounts.queryBuilder().where().eq("uuid", uuid).and().eq("name", player.getName()).queryForFirst();
} catch (SQLException e) { } catch (SQLException e) {
ChestShop.getBukkitLogger().log(Level.WARNING, "Error while searching for latest account of " + player.getName() + "/" + uuid + ":", e); ChestShop.getBukkitLogger().log(Level.WARNING, "Error while searching for latest account of " + player.getName() + "/" + uuid + ":", e);
} }
@ -189,18 +212,18 @@ public class NameManager {
if (latestAccount == null) { if (latestAccount == null) {
latestAccount = new Account(player.getName(), player.getUniqueId()); latestAccount = new Account(player.getName(), player.getUniqueId());
latestAccount.setShortName(getNewShortenedName(player)); latestAccount.setShortName(getNewShortenedName(player));
try {
accounts.create(latestAccount);
} catch (SQLException e) {
ChestShop.getBukkitLogger().log(Level.WARNING, "Error while updating account " + latestAccount + ":", e);
}
} }
usernameToUUID.put(latestAccount.getLastSeenName(), uuid); latestAccount.setLastSeen(new Date());
uuidToUsername.put(uuid, latestAccount.getLastSeenName()); try {
accounts.createOrUpdate(latestAccount);
} catch (SQLException e) {
ChestShop.getBukkitLogger().log(Level.WARNING, "Error while updating account " + latestAccount + ":", e);
}
shortToLongName.put(latestAccount.getShortName(), latestAccount.getLastSeenName()); usernameToAccount.put(latestAccount.getName(), latestAccount);
uuidToAccount.put(uuid, latestAccount);
shortToAccount.put(latestAccount.getShortName(), latestAccount);
} }
/** /**
@ -211,27 +234,30 @@ public class NameManager {
private static String getNewShortenedName(PlayerDTO player) { private static String getNewShortenedName(PlayerDTO player) {
String shortenedName = NameUtil.stripUsername(player.getName()); String shortenedName = NameUtil.stripUsername(player.getName());
String fullName = getFullUsername(shortenedName); Account account = getAccountFromShortName(shortenedName);
if (fullName != null && fullName.isEmpty()) { if (account == null) {
return shortenedName; return shortenedName;
} }
for (int id = 0; fullName != null && !fullName.isEmpty(); id++) { for (int id = 0; account != null; id++) {
String baseId = Base62.encode(id); String baseId = Base62.encode(id);
shortenedName = NameUtil.stripUsername(player.getName(), 15 - 1 - baseId.length()) + ":" + baseId; shortenedName = NameUtil.stripUsername(player.getName(), 15 - 1 - baseId.length()) + ":" + baseId;
fullName = getFullUsername(shortenedName); account = getAccountFromShortName(shortenedName);
} }
return shortenedName; return shortenedName;
} }
public static boolean canUseName(Player player, String name) { public static boolean canUseName(Player player, String name) {
String shortenedName = NameUtil.stripUsername(getUsername(player.getUniqueId()));
if (ChestShopSign.isAdminShop(name)) { if (ChestShopSign.isAdminShop(name)) {
return false; return false;
} }
return shortenedName.equals(name) || Permission.otherName(player, name) || (!name.isEmpty() && player.getName().equals(getFullUsername(name))); if (Permission.otherName(player, name)) {
return true;
}
Account account = getAccountFromShortName(name);
return account != null && account.getUuid().equals(player.getUniqueId());
} }
public static boolean isAdminShop(UUID uuid) { public static boolean isAdminShop(UUID uuid) {