mirror of
https://github.com/AppleDash/SaneEconomy.git
synced 2025-02-19 21:21:20 +01:00
Add Economable interface and appropriate database migrations. (The MySQL one is very gross)
This commit is contained in:
parent
143604b80c
commit
f33eb1d7f4
@ -6,10 +6,10 @@
|
||||
<parent>
|
||||
<groupId>org.appledash</groupId>
|
||||
<artifactId>SaneEconomy</artifactId>
|
||||
<version>0.5.8-SNAPSHOT</version>
|
||||
<version>0.6.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>SaneEconomyCore</artifactId>
|
||||
<version>0.5.8-SNAPSHOT</version>
|
||||
<version>0.6.0-SNAPSHOT</version>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
@ -61,7 +61,7 @@ public class SaneEconomy extends JavaPlugin {
|
||||
getServer().getScheduler().scheduleAsyncDelayedTask(this, GithubVersionChecker::checkUpdateAvailable);
|
||||
|
||||
getServer().getScheduler().runTaskTimerAsynchronously(this, () -> {
|
||||
economyManager.getBackend().reloadTopBalances();
|
||||
economyManager.getBackend().reloadTopPlayerBalances();
|
||||
}, 0, (20 * 300) /* Update baltop every 5 minutes */);
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import org.appledash.saneeconomy.SaneEconomy;
|
||||
import org.appledash.saneeconomy.command.SaneEconomyCommand;
|
||||
import org.appledash.saneeconomy.command.exception.CommandException;
|
||||
import org.appledash.saneeconomy.command.exception.type.usage.NeedPlayerException;
|
||||
import org.appledash.saneeconomy.economy.economable.Economable;
|
||||
import org.appledash.saneeconomy.utils.MessageUtils;
|
||||
import org.appledash.saneeconomy.utils.PlayerUtils;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
@ -53,6 +54,6 @@ public class BalanceCommand extends SaneEconomyCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
MessageUtils.sendMessage(sender, "Balance for %s is %s.", playerName, SaneEconomy.getInstance().getEconomyManager().getFormattedBalance(player));
|
||||
MessageUtils.sendMessage(sender, "Balance for %s is %s.", playerName, SaneEconomy.getInstance().getEconomyManager().getFormattedBalance(Economable.wrap(player)));
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ public class BalanceTopCommand extends SaneEconomyCommand {
|
||||
throw new TooManyArgumentsException();
|
||||
}
|
||||
|
||||
Map<OfflinePlayer, Double> topBalances = SaneEconomy.getInstance().getEconomyManager().getTopBalances(10);
|
||||
Map<OfflinePlayer, Double> topBalances = SaneEconomy.getInstance().getEconomyManager().getTopPlayerBalances(10);
|
||||
AtomicInteger index = new AtomicInteger(1); /* I know it's stupid, but you can't do some_int++ from within the lambda. */
|
||||
|
||||
MessageUtils.sendMessage(sender, "Top %d players:", topBalances.size());
|
||||
|
@ -7,6 +7,7 @@ import org.appledash.saneeconomy.command.exception.type.usage.InvalidUsageExcept
|
||||
import org.appledash.saneeconomy.command.exception.type.usage.NeedPlayerException;
|
||||
import org.appledash.saneeconomy.command.exception.type.usage.TooFewArgumentsException;
|
||||
import org.appledash.saneeconomy.economy.EconomyManager;
|
||||
import org.appledash.saneeconomy.economy.economable.Economable;
|
||||
import org.appledash.saneeconomy.utils.MessageUtils;
|
||||
import org.appledash.saneeconomy.utils.NumberUtils;
|
||||
import org.appledash.saneeconomy.utils.PlayerUtils;
|
||||
@ -60,6 +61,8 @@ public class EconomyAdminCommand extends SaneEconomyCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
Economable economable = Economable.wrap(targetPlayer);
|
||||
|
||||
double amount = NumberUtils.parseAndFilter(sAmount);
|
||||
|
||||
if (amount <= 0) {
|
||||
@ -70,7 +73,7 @@ public class EconomyAdminCommand extends SaneEconomyCommand {
|
||||
EconomyManager ecoMan = SaneEconomy.getInstance().getEconomyManager();
|
||||
|
||||
if (subCommand.equalsIgnoreCase("give")) {
|
||||
double newAmount = ecoMan.addBalance(targetPlayer, amount);
|
||||
double newAmount = ecoMan.addBalance(economable, amount);
|
||||
|
||||
MessageUtils.sendMessage(sender, "Added %s to %s. Their balance is now %s.",
|
||||
ecoMan.getCurrency().formatAmount(amount),
|
||||
@ -79,7 +82,7 @@ public class EconomyAdminCommand extends SaneEconomyCommand {
|
||||
);
|
||||
return;
|
||||
} else if (subCommand.equalsIgnoreCase("take")) {
|
||||
double newAmount = ecoMan.subtractBalance(targetPlayer, amount);
|
||||
double newAmount = ecoMan.subtractBalance(economable, amount);
|
||||
|
||||
MessageUtils.sendMessage(sender, "Took %s from %s. Their balance is now %s.",
|
||||
ecoMan.getCurrency().formatAmount(amount),
|
||||
@ -88,7 +91,7 @@ public class EconomyAdminCommand extends SaneEconomyCommand {
|
||||
);
|
||||
return;
|
||||
} else if (subCommand.equalsIgnoreCase("set")) {
|
||||
ecoMan.setBalance(targetPlayer, amount);
|
||||
ecoMan.setBalance(economable, amount);
|
||||
MessageUtils.sendMessage(sender, "Balance for %s set to %s", sTargetPlayer, ecoMan.getCurrency().formatAmount(amount));
|
||||
return;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import org.appledash.saneeconomy.command.SaneEconomyCommand;
|
||||
import org.appledash.saneeconomy.command.exception.CommandException;
|
||||
import org.appledash.saneeconomy.command.exception.type.usage.NeedPlayerException;
|
||||
import org.appledash.saneeconomy.economy.EconomyManager;
|
||||
import org.appledash.saneeconomy.economy.economable.Economable;
|
||||
import org.appledash.saneeconomy.utils.MessageUtils;
|
||||
import org.appledash.saneeconomy.utils.NumberUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -67,7 +68,7 @@ public class PayCommand extends SaneEconomyCommand {
|
||||
EconomyManager ecoMan = SaneEconomy.getInstance().getEconomyManager();
|
||||
|
||||
/* Perform the actual transfer. False == They didn't have enough money */
|
||||
boolean result = ecoMan.transfer(fromPlayer, toPlayer, amount);
|
||||
boolean result = ecoMan.transfer(Economable.wrap(fromPlayer), Economable.wrap(toPlayer), amount);
|
||||
|
||||
if (!result) {
|
||||
MessageUtils.sendMessage(sender, "You do not have enough money to transfer %s to %s.",
|
||||
|
@ -1,10 +1,10 @@
|
||||
package org.appledash.saneeconomy.economy;
|
||||
|
||||
import org.appledash.saneeconomy.economy.backend.EconomyStorageBackend;
|
||||
import org.appledash.saneeconomy.economy.economable.Economable;
|
||||
import org.appledash.saneeconomy.utils.NumberUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
@ -38,7 +38,7 @@ public class EconomyManager {
|
||||
* @param player Player
|
||||
* @return Formatted balance
|
||||
*/
|
||||
public String getFormattedBalance(OfflinePlayer player) {
|
||||
public String getFormattedBalance(Economable player) {
|
||||
return currency.formatAmount(backend.getBalance(player));
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ public class EconomyManager {
|
||||
* @param player Player to check
|
||||
* @return True if they have used the economy system before, false otherwise
|
||||
*/
|
||||
public boolean accountExists(OfflinePlayer player) {
|
||||
public boolean accountExists(Economable player) {
|
||||
return backend.accountExists(player);
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ public class EconomyManager {
|
||||
* @param targetPlayer Player to get balance of
|
||||
* @return Player's balance
|
||||
*/
|
||||
public double getBalance(OfflinePlayer targetPlayer) {
|
||||
public double getBalance(Economable targetPlayer) {
|
||||
return backend.getBalance(targetPlayer);
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ public class EconomyManager {
|
||||
* @param requiredBalance How much money we're checking for
|
||||
* @return True if they have requiredBalance or more, false otherwise
|
||||
*/
|
||||
public boolean hasBalance(OfflinePlayer targetPlayer, double requiredBalance) {
|
||||
public boolean hasBalance(Economable targetPlayer, double requiredBalance) {
|
||||
return getBalance(targetPlayer) >= requiredBalance;
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ public class EconomyManager {
|
||||
* @return Player's new balance
|
||||
* @throws IllegalArgumentException If amount is negative
|
||||
*/
|
||||
public double addBalance(OfflinePlayer targetPlayer, double amount) {
|
||||
public double addBalance(Economable targetPlayer, double amount) {
|
||||
amount = NumberUtils.filterAmount(amount);
|
||||
|
||||
if (amount < 0) {
|
||||
@ -100,7 +100,7 @@ public class EconomyManager {
|
||||
* @return Player's new balance
|
||||
* @throws IllegalArgumentException If amount is negative
|
||||
*/
|
||||
public double subtractBalance(OfflinePlayer targetPlayer, double amount) {
|
||||
public double subtractBalance(Economable targetPlayer, double amount) {
|
||||
amount = NumberUtils.filterAmount(amount);
|
||||
|
||||
if (amount < 0) {
|
||||
@ -126,7 +126,7 @@ public class EconomyManager {
|
||||
* @param amount Amount to set balance to
|
||||
* @throws IllegalArgumentException If amount is negative
|
||||
*/
|
||||
public void setBalance(OfflinePlayer targetPlayer, double amount) {
|
||||
public void setBalance(Economable targetPlayer, double amount) {
|
||||
amount = NumberUtils.filterAmount(amount);
|
||||
|
||||
if (amount < 0) {
|
||||
@ -144,7 +144,7 @@ public class EconomyManager {
|
||||
* @return True if success, false if fromPlayer has insufficient funds.
|
||||
* @throws IllegalArgumentException If amount is negative
|
||||
*/
|
||||
public boolean transfer(OfflinePlayer fromPlayer, Player toPlayer, double amount) {
|
||||
public boolean transfer(Economable fromPlayer, Economable toPlayer, double amount) {
|
||||
amount = NumberUtils.filterAmount(amount);
|
||||
|
||||
if (amount < 0) {
|
||||
@ -167,8 +167,8 @@ public class EconomyManager {
|
||||
* @param amount Maximum number of players to show.
|
||||
* @return Map of OfflinePlayer to Double
|
||||
*/
|
||||
public Map<OfflinePlayer, Double> getTopBalances(int amount) {
|
||||
Map<UUID, Double> uuidBalances = backend.getTopBalances(amount);
|
||||
public Map<OfflinePlayer, Double> getTopPlayerBalances(int amount) {
|
||||
Map<UUID, Double> uuidBalances = backend.getTopPlayerBalances(amount);
|
||||
Map<OfflinePlayer, Double> playerBalances = new LinkedHashMap<>();
|
||||
|
||||
uuidBalances.forEach((uuid, balance) -> playerBalances.put(Bukkit.getServer().getOfflinePlayer(uuid), balance));
|
||||
|
@ -1,6 +1,6 @@
|
||||
package org.appledash.saneeconomy.economy.backend;
|
||||
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.appledash.saneeconomy.economy.economable.Economable;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
@ -17,28 +17,28 @@ public interface EconomyStorageBackend {
|
||||
* @param player Player
|
||||
* @return True if they have, false otherwise.
|
||||
*/
|
||||
boolean accountExists(OfflinePlayer player);
|
||||
boolean accountExists(Economable player);
|
||||
|
||||
/**
|
||||
* Get the balance of a player.
|
||||
* @param player Player
|
||||
* @return Player's current balance
|
||||
*/
|
||||
double getBalance(OfflinePlayer player);
|
||||
double getBalance(Economable player);
|
||||
|
||||
/**
|
||||
* Set the balance of a player, overwriting the old balance.
|
||||
* @param player Player
|
||||
* @param newBalance Player's new balance
|
||||
*/
|
||||
void setBalance(OfflinePlayer player, double newBalance);
|
||||
void setBalance(Economable player, double newBalance);
|
||||
|
||||
/**
|
||||
* Get the UUIDs of the players who have the most money, along with how much money they have.
|
||||
* @param amount Maximum number to get.
|
||||
* @return Map of player UUIDs to amounts.
|
||||
*/
|
||||
Map<UUID, Double> getTopBalances(int amount);
|
||||
Map<UUID, Double> getTopPlayerBalances(int amount);
|
||||
|
||||
/**
|
||||
* Reload this backend's database from disk.
|
||||
@ -48,5 +48,5 @@ public interface EconomyStorageBackend {
|
||||
/**
|
||||
* Reload this backend's top balances.
|
||||
*/
|
||||
void reloadTopBalances();
|
||||
void reloadTopPlayerBalances();
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package org.appledash.saneeconomy.economy.backend.type;
|
||||
|
||||
import org.appledash.saneeconomy.economy.backend.EconomyStorageBackend;
|
||||
import org.appledash.saneeconomy.economy.economable.Economable;
|
||||
import org.appledash.saneeconomy.utils.MapUtil;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
@ -14,30 +14,38 @@ import java.util.UUID;
|
||||
* Blackjack is still best pony.
|
||||
*/
|
||||
public abstract class EconomyStorageBackendCaching implements EconomyStorageBackend {
|
||||
protected HashMap<UUID, Double> playerBalances = new HashMap<>();
|
||||
protected Map<UUID, Double> topBalances = new LinkedHashMap<>();
|
||||
protected HashMap<String, Double> balances = new HashMap<>();
|
||||
protected Map<UUID, Double> topPlayerBalances = new LinkedHashMap<>();
|
||||
|
||||
@Override
|
||||
public boolean accountExists(OfflinePlayer player) {
|
||||
return playerBalances.containsKey(player.getUniqueId());
|
||||
public boolean accountExists(Economable economable) {
|
||||
return balances.containsKey(economable.getUniqueIdentifier());
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized double getBalance(OfflinePlayer player) {
|
||||
if (!accountExists(player)) {
|
||||
public synchronized double getBalance(Economable economable) {
|
||||
if (!accountExists(economable)) {
|
||||
return 0.0D;
|
||||
}
|
||||
|
||||
return playerBalances.get(player.getUniqueId());
|
||||
return balances.get(economable.getUniqueIdentifier());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, Double> getTopBalances(int amount) {
|
||||
return MapUtil.takeFromMap(topBalances, amount);
|
||||
public Map<UUID, Double> getTopPlayerBalances(int amount) {
|
||||
return MapUtil.takeFromMap(topPlayerBalances, amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadTopBalances() {
|
||||
topBalances = MapUtil.sortByValue(playerBalances);
|
||||
public void reloadTopPlayerBalances() {
|
||||
Map<UUID, Double> playerBalances = new HashMap<>();
|
||||
|
||||
balances.forEach((identifier, balance) -> {
|
||||
if (identifier.startsWith("player:")) { // FIXME: Come on now...
|
||||
playerBalances.put(UUID.fromString(identifier.substring("player:".length())), balance);
|
||||
}
|
||||
});
|
||||
|
||||
topPlayerBalances = MapUtil.sortByValue(playerBalances);
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
package org.appledash.saneeconomy.economy.backend.type;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import org.appledash.saneeconomy.SaneEconomy;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.appledash.saneeconomy.economy.economable.Economable;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
@ -12,7 +14,7 @@ import java.util.UUID;
|
||||
* Blackjack is still best pony.
|
||||
*/
|
||||
public class EconomyStorageBackendFlatfile extends EconomyStorageBackendCaching {
|
||||
private static final int SCHEMA_VERSION = 1;
|
||||
private static final int SCHEMA_VERSION = 2;
|
||||
private final File file;
|
||||
|
||||
public EconomyStorageBackendFlatfile(File file) {
|
||||
@ -28,13 +30,20 @@ public class EconomyStorageBackendFlatfile extends EconomyStorageBackendCaching
|
||||
try {
|
||||
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
|
||||
int schemaVer = ois.readInt();
|
||||
if (schemaVer != SCHEMA_VERSION) { // Eventually, if I change the schema there will be code to detect such changes and update it on load.
|
||||
|
||||
if (schemaVer == 1) {
|
||||
ois.close();
|
||||
loadSchemaVersion1(file);
|
||||
return;
|
||||
}
|
||||
|
||||
if (schemaVer != SCHEMA_VERSION) {
|
||||
// ???
|
||||
SaneEconomy.logger().severe("Unrecognized flatfile database version " + schemaVer + ", cannot load database!");
|
||||
return;
|
||||
}
|
||||
|
||||
playerBalances = (HashMap<UUID, Double>)ois.readObject();
|
||||
balances = (HashMap<String, Double>) ois.readObject();
|
||||
|
||||
ois.close();
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
@ -43,6 +52,35 @@ public class EconomyStorageBackendFlatfile extends EconomyStorageBackendCaching
|
||||
}
|
||||
}
|
||||
|
||||
private void loadSchemaVersion1(File file) {
|
||||
SaneEconomy.logger().info("Upgrading flatfile database from version 1.");
|
||||
try {
|
||||
Files.copy(file, new File(file.getParentFile(), file.getName() + "-backup"));
|
||||
SaneEconomy.logger().info("Backed up old flatfile database.");
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to back up flatfile database!");
|
||||
}
|
||||
|
||||
try {
|
||||
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
|
||||
ois.readInt(); // We already know it's 1.
|
||||
|
||||
|
||||
Map<UUID, Double> oldBalances = (HashMap<UUID, Double>)ois.readObject();
|
||||
oldBalances.forEach((uuid, balance) -> balances.put("player:" + uuid, balance));
|
||||
|
||||
ois.close();
|
||||
|
||||
|
||||
/* Yes, this is kind of bad, but we want to make sure we're loading AND saving the new version of the DB. */
|
||||
saveDatabase();
|
||||
reloadDatabase();
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
SaneEconomy.logger().severe("Failed to upgrade flatfile database! Recommend reporting this bug and reverting to an older version of the plugin.");
|
||||
throw new RuntimeException("Failed to upgrade flatfile database!", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveDatabase() {
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
@ -51,7 +89,7 @@ public class EconomyStorageBackendFlatfile extends EconomyStorageBackendCaching
|
||||
try {
|
||||
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
|
||||
oos.writeInt(SCHEMA_VERSION);
|
||||
oos.writeObject(playerBalances);
|
||||
oos.writeObject(balances);
|
||||
oos.close();
|
||||
} catch (IOException e) {
|
||||
SaneEconomy.logger().severe("Failed to save flatfile database!");
|
||||
@ -59,8 +97,8 @@ public class EconomyStorageBackendFlatfile extends EconomyStorageBackendCaching
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setBalance(OfflinePlayer player, double newBalance) {
|
||||
playerBalances.put(player.getUniqueId(), newBalance);
|
||||
public synchronized void setBalance(Economable player, double newBalance) {
|
||||
balances.put(player.getUniqueIdentifier(), newBalance);
|
||||
saveDatabase();
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
package org.appledash.saneeconomy.economy.backend.type;
|
||||
|
||||
import org.appledash.saneeconomy.SaneEconomy;
|
||||
import org.appledash.saneeconomy.economy.economable.Economable;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.UUID;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by AppleDash on 6/14/2016.
|
||||
@ -39,35 +40,101 @@ public class EconomyStorageBackendMySQL extends EconomyStorageBackendCaching {
|
||||
public boolean testConnection() {
|
||||
try {
|
||||
openConnection().close();
|
||||
createTable();
|
||||
createTables();
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void createTable() {
|
||||
private void createTables() {
|
||||
Connection conn = openConnection();
|
||||
try {
|
||||
PreparedStatement ps = conn.prepareStatement("CREATE TABLE IF NOT EXISTS `player_balances` (player_uuid CHAR(36), balance DECIMAL(18, 2))");
|
||||
ps.executeUpdate();
|
||||
int schemaVersion;
|
||||
if (!checkTableExists("saneeconomy_schema")) {
|
||||
if (checkTableExists("player_balances")) {
|
||||
schemaVersion = 1;
|
||||
} else {
|
||||
schemaVersion = 0;
|
||||
}
|
||||
} else {
|
||||
PreparedStatement ps = conn.prepareStatement("SELECT `val` FROM saneeconomy_schema WHERE `key` = 'schema_version'");
|
||||
ps.executeQuery();
|
||||
ResultSet rs = ps.getResultSet();
|
||||
|
||||
if (!rs.next()) {
|
||||
throw new RuntimeException("Invalid database schema!");
|
||||
}
|
||||
|
||||
schemaVersion = Integer.valueOf(rs.getString("val"));
|
||||
}
|
||||
|
||||
if (schemaVersion < 2) {
|
||||
if (schemaVersion < 1) {
|
||||
PreparedStatement ps = conn.prepareStatement("CREATE TABLE IF NOT EXISTS `player_balances` (player_uuid CHAR(36), balance DECIMAL(18, 2))");
|
||||
ps.executeUpdate();
|
||||
}
|
||||
conn.prepareStatement("CREATE TABLE IF NOT EXISTS `saneeconomy_schema` (`key` VARCHAR(32) PRIMARY KEY, `val` TEXT)").executeUpdate();
|
||||
upgradeSchema1To2(conn);
|
||||
}
|
||||
|
||||
conn.close();
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("Failed to create tables!", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void upgradeSchema1To2(Connection conn) throws SQLException {
|
||||
SaneEconomy.logger().info("Upgrading database schema from version 1 to version 2. This might take a little while...");
|
||||
PreparedStatement ps = conn.prepareStatement("REPLACE INTO `saneeconomy_schema` (`key`, `val`) VALUES ('schema_version', '2')");
|
||||
ps.executeUpdate();
|
||||
conn.prepareStatement("CREATE TABLE `saneeconomy_balances` (unique_identifier VARCHAR(128) PRIMARY KEY, balance DECIMAL(18, 2))").executeUpdate();
|
||||
ps = conn.prepareStatement("SELECT * FROM `player_balances`");
|
||||
ResultSet rs = ps.executeQuery();
|
||||
|
||||
Map<String, Double> oldBalances = new HashMap<>();
|
||||
|
||||
while (rs.next()) {
|
||||
oldBalances.put(rs.getString("player_uuid"), rs.getDouble("balance"));
|
||||
}
|
||||
|
||||
for (Map.Entry<String, Double> e : oldBalances.entrySet()) {
|
||||
ps = conn.prepareStatement("INSERT INTO `saneeconomy_balances` (unique_identifier, balance) VALUES (?, ?)");
|
||||
ps.setString(1, "player:" + e.getKey());
|
||||
ps.setDouble(2, e.getValue());
|
||||
ps.executeUpdate();
|
||||
}
|
||||
reloadDatabase();
|
||||
SaneEconomy.logger().info("Schema upgrade complete!");
|
||||
}
|
||||
|
||||
private boolean checkTableExists(String tableName) {
|
||||
Connection conn = openConnection();
|
||||
try {
|
||||
PreparedStatement ps = conn.prepareStatement("SELECT * FROM information_schema.tables WHERE table_schema = ? AND table_name = ? LIMIT 1");
|
||||
ps.setString(1, dbUrl.substring("jdbc:mysql://".length()).split("/")[1]); // FIXME: There has to be a better way.
|
||||
ps.setString(2, tableName);
|
||||
ps.executeQuery();
|
||||
ResultSet rs = ps.getResultSet();
|
||||
|
||||
return rs.next();
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("Failed to check if table exists!", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadDatabase() {
|
||||
Connection conn = openConnection();
|
||||
try {
|
||||
PreparedStatement ps = conn.prepareStatement("SELECT * FROM `player_balances`");
|
||||
PreparedStatement ps = conn.prepareStatement("SELECT * FROM `saneeconomy_balances`");
|
||||
ResultSet rs = ps.executeQuery();
|
||||
|
||||
playerBalances.clear();
|
||||
balances.clear();
|
||||
|
||||
while (rs.next()) {
|
||||
playerBalances.put(UUID.fromString(rs.getString("player_uuid")), rs.getDouble("balance"));
|
||||
balances.put(rs.getString("unique_identifier"), rs.getDouble("balance"));
|
||||
}
|
||||
|
||||
conn.close();
|
||||
@ -77,9 +144,9 @@ public class EconomyStorageBackendMySQL extends EconomyStorageBackendCaching {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setBalance(final OfflinePlayer player, final double newBalance) {
|
||||
public synchronized void setBalance(final Economable player, final double newBalance) {
|
||||
final double oldBalance = getBalance(player);
|
||||
playerBalances.put(player.getUniqueId(), newBalance);
|
||||
balances.put(player.getUniqueIdentifier(), newBalance);
|
||||
|
||||
Bukkit.getServer().getScheduler().scheduleAsyncDelayedTask(SaneEconomy.getInstance(), () -> {
|
||||
Connection conn = openConnection();
|
||||
@ -87,22 +154,22 @@ public class EconomyStorageBackendMySQL extends EconomyStorageBackendCaching {
|
||||
try {
|
||||
PreparedStatement statement = conn.prepareStatement("UPDATE `player_balances` SET balance = ? WHERE `player_uuid` = ?");
|
||||
statement.setDouble(1, newBalance);
|
||||
statement.setString(2, player.getUniqueId().toString());
|
||||
statement.setString(2, player.getUniqueIdentifier().toString());
|
||||
statement.executeUpdate();
|
||||
conn.close();
|
||||
} catch (SQLException e) {
|
||||
/* Roll it back */
|
||||
playerBalances.put(player.getUniqueId(), oldBalance);
|
||||
balances.put(player.getUniqueIdentifier(), oldBalance);
|
||||
throw new RuntimeException("SQL error has occurred.", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void ensureAccountExists(OfflinePlayer player, Connection conn) {
|
||||
private void ensureAccountExists(Economable player, Connection conn) {
|
||||
if (!accountExists(player, conn)) {
|
||||
try {
|
||||
PreparedStatement statement = conn.prepareStatement("INSERT INTO `player_balances` (player_uuid, balance) VALUES (?, 0.0)");
|
||||
statement.setString(1, player.getUniqueId().toString());
|
||||
statement.setString(1, player.getUniqueIdentifier());
|
||||
statement.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("SQL error has occurred.", e);
|
||||
@ -110,10 +177,10 @@ public class EconomyStorageBackendMySQL extends EconomyStorageBackendCaching {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean accountExists(OfflinePlayer player, Connection conn) {
|
||||
private boolean accountExists(Economable player, Connection conn) {
|
||||
try {
|
||||
PreparedStatement statement = conn.prepareStatement("SELECT 1 FROM `player_balances` WHERE `player_uuid` = ?");
|
||||
statement.setString(1, player.getUniqueId().toString());
|
||||
statement.setString(1, player.getUniqueIdentifier());
|
||||
|
||||
ResultSet rs = statement.executeQuery();
|
||||
|
||||
|
@ -0,0 +1,19 @@
|
||||
package org.appledash.saneeconomy.economy.economable;
|
||||
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
/**
|
||||
* Created by appledash on 7/19/16.
|
||||
* Blackjack is still best pony.
|
||||
*/
|
||||
public interface Economable {
|
||||
String getUniqueIdentifier();
|
||||
|
||||
static Economable wrap(OfflinePlayer player) {
|
||||
return new EconomablePlayer(player);
|
||||
}
|
||||
|
||||
static Economable wrap(String playerName) {
|
||||
return () -> "wtf:" + playerName;
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package org.appledash.saneeconomy.economy.economable;
|
||||
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
/**
|
||||
* Created by appledash on 7/19/16.
|
||||
* Blackjack is still best pony.
|
||||
*/
|
||||
public class EconomablePlayer implements Economable {
|
||||
private OfflinePlayer handle;
|
||||
|
||||
public EconomablePlayer(OfflinePlayer handle) {
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUniqueIdentifier() {
|
||||
return "player:" + handle.getUniqueId().toString();
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package org.appledash.saneeconomy.listeners;
|
||||
|
||||
import org.appledash.saneeconomy.SaneEconomy;
|
||||
import org.appledash.saneeconomy.economy.economable.Economable;
|
||||
import org.appledash.saneeconomy.updates.GithubVersionChecker;
|
||||
import org.appledash.saneeconomy.utils.MessageUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -22,11 +23,12 @@ public class JoinQuitListener implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent evt) {
|
||||
Player player = evt.getPlayer();
|
||||
Economable economable = Economable.wrap(player);
|
||||
double startBalance = plugin.getConfig().getDouble("economy.start-balance", 0.0D);
|
||||
|
||||
/* A starting balance is configured AND they haven't been given it yet. */
|
||||
if (startBalance > 0 && !plugin.getEconomyManager().accountExists(player)) {
|
||||
plugin.getEconomyManager().setBalance(player, startBalance);
|
||||
if (startBalance > 0 && !plugin.getEconomyManager().accountExists(economable)) {
|
||||
plugin.getEconomyManager().setBalance(economable, startBalance);
|
||||
MessageUtils.sendMessage(player, "You've been issued a starting balance of %s!", plugin.getEconomyManager().getCurrency().formatAmount(startBalance));
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableList;
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import net.milkbowl.vault.economy.EconomyResponse;
|
||||
import org.appledash.saneeconomy.SaneEconomy;
|
||||
import org.appledash.saneeconomy.economy.economable.Economable;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
@ -51,13 +52,20 @@ public class EconomySaneEconomy implements Economy {
|
||||
|
||||
@Override
|
||||
public boolean hasAccount(String playerName) {
|
||||
return validatePlayer(playerName) && SaneEconomy.getInstance().getEconomyManager().accountExists(Bukkit.getServer().getPlayer(playerName));
|
||||
Economable economable;
|
||||
if (validatePlayer(playerName)) {
|
||||
economable = Economable.wrap(Bukkit.getPlayer(playerName));
|
||||
} else {
|
||||
economable = Economable.wrap(playerName);
|
||||
}
|
||||
|
||||
return SaneEconomy.getInstance().getEconomyManager().accountExists(economable);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAccount(OfflinePlayer offlinePlayer) {
|
||||
return SaneEconomy.getInstance().getEconomyManager().accountExists(offlinePlayer);
|
||||
return SaneEconomy.getInstance().getEconomyManager().accountExists(Economable.wrap(offlinePlayer));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -71,17 +79,20 @@ public class EconomySaneEconomy implements Economy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getBalance(String s) {
|
||||
if (!validatePlayer(s)) {
|
||||
return 0.0;
|
||||
public double getBalance(String playerName) {
|
||||
Economable economable;
|
||||
if (validatePlayer(playerName)) {
|
||||
economable = Economable.wrap(Bukkit.getPlayer(playerName));
|
||||
} else {
|
||||
economable = Economable.wrap(playerName);
|
||||
}
|
||||
|
||||
return SaneEconomy.getInstance().getEconomyManager().getBalance(Bukkit.getPlayer(s));
|
||||
return SaneEconomy.getInstance().getEconomyManager().getBalance(economable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getBalance(OfflinePlayer offlinePlayer) {
|
||||
return SaneEconomy.getInstance().getEconomyManager().getBalance(offlinePlayer);
|
||||
return SaneEconomy.getInstance().getEconomyManager().getBalance(Economable.wrap(offlinePlayer));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -96,15 +107,19 @@ public class EconomySaneEconomy implements Economy {
|
||||
|
||||
@Override
|
||||
public boolean has(String playerName, double v) {
|
||||
if (!validatePlayer(playerName)) {
|
||||
return false;
|
||||
Economable economable;
|
||||
if (validatePlayer(playerName)) {
|
||||
economable = Economable.wrap(Bukkit.getPlayer(playerName));
|
||||
} else {
|
||||
economable = Economable.wrap(playerName);
|
||||
}
|
||||
return SaneEconomy.getInstance().getEconomyManager().hasBalance(Bukkit.getPlayer(playerName), v);
|
||||
|
||||
return SaneEconomy.getInstance().getEconomyManager().hasBalance(economable, v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(OfflinePlayer offlinePlayer, double v) {
|
||||
return SaneEconomy.getInstance().getEconomyManager().hasBalance(offlinePlayer, v);
|
||||
return SaneEconomy.getInstance().getEconomyManager().hasBalance(Economable.wrap(offlinePlayer), v);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -119,16 +134,19 @@ public class EconomySaneEconomy implements Economy {
|
||||
|
||||
@Override
|
||||
public EconomyResponse withdrawPlayer(String playerName, double v) {
|
||||
if (!validatePlayer(playerName)) {
|
||||
return new EconomyResponse(0.0, 0.0, EconomyResponse.ResponseType.FAILURE, "Invalid player name supplied!");
|
||||
Economable economable;
|
||||
if (validatePlayer(playerName)) {
|
||||
economable = Economable.wrap(Bukkit.getPlayer(playerName));
|
||||
} else {
|
||||
economable = Economable.wrap(playerName);
|
||||
}
|
||||
|
||||
return new EconomyResponse(v, SaneEconomy.getInstance().getEconomyManager().subtractBalance(Bukkit.getPlayer(playerName), v), EconomyResponse.ResponseType.SUCCESS, null);
|
||||
return new EconomyResponse(v, SaneEconomy.getInstance().getEconomyManager().subtractBalance(economable, v), EconomyResponse.ResponseType.SUCCESS, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EconomyResponse withdrawPlayer(OfflinePlayer offlinePlayer, double v) {
|
||||
return new EconomyResponse(v, SaneEconomy.getInstance().getEconomyManager().subtractBalance(offlinePlayer, v), EconomyResponse.ResponseType.SUCCESS, null);
|
||||
return new EconomyResponse(v, SaneEconomy.getInstance().getEconomyManager().subtractBalance(Economable.wrap(offlinePlayer), v), EconomyResponse.ResponseType.SUCCESS, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -143,16 +161,19 @@ public class EconomySaneEconomy implements Economy {
|
||||
|
||||
@Override
|
||||
public EconomyResponse depositPlayer(String playerName, double v) {
|
||||
if (!validatePlayer(playerName)) {
|
||||
return new EconomyResponse(0.0, 0.0, EconomyResponse.ResponseType.FAILURE, "Invalid player name supplied!");
|
||||
Economable economable;
|
||||
if (validatePlayer(playerName)) {
|
||||
economable = Economable.wrap(Bukkit.getPlayer(playerName));
|
||||
} else {
|
||||
economable = Economable.wrap(playerName);
|
||||
}
|
||||
|
||||
return new EconomyResponse(v, SaneEconomy.getInstance().getEconomyManager().addBalance(Bukkit.getPlayer(playerName), v), EconomyResponse.ResponseType.SUCCESS, null);
|
||||
return new EconomyResponse(v, SaneEconomy.getInstance().getEconomyManager().addBalance(economable, v), EconomyResponse.ResponseType.SUCCESS, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EconomyResponse depositPlayer(OfflinePlayer offlinePlayer, double v) {
|
||||
return new EconomyResponse(v, SaneEconomy.getInstance().getEconomyManager().addBalance(offlinePlayer, v), EconomyResponse.ResponseType.SUCCESS, null);
|
||||
return new EconomyResponse(v, SaneEconomy.getInstance().getEconomyManager().addBalance(Economable.wrap(offlinePlayer), v), EconomyResponse.ResponseType.SUCCESS, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -246,12 +267,6 @@ public class EconomySaneEconomy implements Economy {
|
||||
}
|
||||
|
||||
private boolean validatePlayer(String playerName) {
|
||||
boolean valid = Bukkit.getServer().getPlayer(playerName) != null;
|
||||
|
||||
if (!valid) {
|
||||
SaneEconomy.getInstance().getLogger().warning("Some plugin has passed an invalid player name to a Vault API method! (Name: " + playerName + ")");
|
||||
}
|
||||
|
||||
return valid;
|
||||
return Bukkit.getServer().getPlayer(playerName) != null;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user