diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..aa00ffa
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_github_cryptomorin_XSeries_7_2_1.xml b/.idea/libraries/Maven__com_github_cryptomorin_XSeries_7_2_1.xml
new file mode 100644
index 0000000..4ad4b7b
--- /dev/null
+++ b/.idea/libraries/Maven__com_github_cryptomorin_XSeries_7_2_1.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_google_code_gson_gson_2_8_6.xml b/.idea/libraries/Maven__com_google_code_gson_gson_2_8_6.xml
new file mode 100644
index 0000000..82a9f20
--- /dev/null
+++ b/.idea/libraries/Maven__com_google_code_gson_gson_2_8_6.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Maven__com_google_guava_guava_17_0.xml b/.idea/libraries/Maven__com_google_guava_guava_17_0.xml
new file mode 100644
index 0000000..2a9069c
--- /dev/null
+++ b/.idea/libraries/Maven__com_google_guava_guava_17_0.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Maven__javax_persistence_persistence_api_1_0.xml b/.idea/libraries/Maven__javax_persistence_persistence_api_1_0.xml
new file mode 100644
index 0000000..e60370e
--- /dev/null
+++ b/.idea/libraries/Maven__javax_persistence_persistence_api_1_0.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Maven__net_md_5_bungeecord_chat_1_8_SNAPSHOT.xml b/.idea/libraries/Maven__net_md_5_bungeecord_chat_1_8_SNAPSHOT.xml
new file mode 100644
index 0000000..2e39f35
--- /dev/null
+++ b/.idea/libraries/Maven__net_md_5_bungeecord_chat_1_8_SNAPSHOT.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_avaje_ebean_2_8_1.xml b/.idea/libraries/Maven__org_avaje_ebean_2_8_1.xml
new file mode 100644
index 0000000..91f161a
--- /dev/null
+++ b/.idea/libraries/Maven__org_avaje_ebean_2_8_1.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_jetbrains_annotations_20_1_0.xml b/.idea/libraries/Maven__org_jetbrains_annotations_20_1_0.xml
new file mode 100644
index 0000000..de125e3
--- /dev/null
+++ b/.idea/libraries/Maven__org_jetbrains_annotations_20_1_0.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_spigotmc_spigot_api_1_8_8_R0_1_SNAPSHOT.xml b/.idea/libraries/Maven__org_spigotmc_spigot_api_1_8_8_R0_1_SNAPSHOT.xml
new file mode 100644
index 0000000..15cce87
--- /dev/null
+++ b/.idea/libraries/Maven__org_spigotmc_spigot_api_1_8_8_R0_1_SNAPSHOT.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_yaml_snakeyaml_1_15.xml b/.idea/libraries/Maven__org_yaml_snakeyaml_1_15.xml
new file mode 100644
index 0000000..02d9152
--- /dev/null
+++ b/.idea/libraries/Maven__org_yaml_snakeyaml_1_15.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..e96534f
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 432bc90..5d5076f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
net.epconsortium
CryptoMarket
- 1.1.0
+ 2.0.0
CryptoMarket
A plugin that brings the cryptocoins market experience to your server!
https://www.spigotmc.org/resources/cryptomarket.69031/
@@ -106,11 +106,4 @@
-
-
- bintray-roinujnosde-bukkit-plugins
- roinujnosde-bukkit-plugins
- https://api.bintray.com/maven/roinujnosde/bukkit-plugins/CryptoMarket/;publish=1
-
-
diff --git a/src/main/java/net/epconsortium/cryptomarket/CryptoMarket.java b/src/main/java/net/epconsortium/cryptomarket/CryptoMarket.java
index b023286..81dda94 100644
--- a/src/main/java/net/epconsortium/cryptomarket/CryptoMarket.java
+++ b/src/main/java/net/epconsortium/cryptomarket/CryptoMarket.java
@@ -1,22 +1,18 @@
package net.epconsortium.cryptomarket;
import net.epconsortium.cryptomarket.commands.CryptoMarketCommand;
+import net.epconsortium.cryptomarket.database.dao.InvestorDao;
+import net.epconsortium.cryptomarket.finances.Economy;
import net.epconsortium.cryptomarket.finances.ExchangeRates;
+import net.epconsortium.cryptomarket.listeners.PlayerListeners;
+import net.epconsortium.cryptomarket.task.SaveInvestorsTask;
import net.epconsortium.cryptomarket.task.UpdateExchangeRatesTask;
-import net.epconsortium.cryptomarket.ui.MenuListener;
-import net.milkbowl.vault.economy.Economy;
-import org.bukkit.Bukkit;
+import net.epconsortium.cryptomarket.task.UpdateRichersListTask;
+import net.epconsortium.cryptomarket.ui.InventoryController;
import org.bukkit.command.PluginCommand;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
-import org.bukkit.scheduler.BukkitRunnable;
-
-import java.util.logging.Level;
-import net.epconsortium.cryptomarket.database.dao.InvestorDao;
-import net.epconsortium.cryptomarket.task.SaveInvestorsTask;
-import net.epconsortium.cryptomarket.ui.CalendarListener;
-import net.epconsortium.cryptomarket.ui.RankingListener;
/**
* Main class of the plugin
@@ -26,12 +22,8 @@
public class CryptoMarket extends JavaPlugin {
private static CryptoMarket cm;
-
- private Economy econ = null;
- private SaveInvestorsTask saveInvestors;
- private UpdateExchangeRatesTask updateRates;
-
private static boolean debug;
+ private net.milkbowl.vault.economy.Economy econ = null;
@Override
public void onEnable() {
@@ -41,9 +33,8 @@ public void onEnable() {
// Eventos
PluginManager pluginManager = getServer().getPluginManager();
- pluginManager.registerEvents(new MenuListener(this), this);
- pluginManager.registerEvents(new CalendarListener(this), this);
- pluginManager.registerEvents(new RankingListener(this), this);
+ pluginManager.registerEvents(InventoryController.getInstance(), this);
+ pluginManager.registerEvents(new PlayerListeners(this), this);
//Comandos
PluginCommand command = getCommand("cryptomarket");
@@ -60,39 +51,28 @@ public void onEnable() {
debug = getConfig().getBoolean("debug", false);
- InvestorDao.configureDatabase(this, (success) -> {
- new BukkitRunnable() {
-
- @Override
- public void run() {
- if (!success) {
- getServer().getPluginManager().disablePlugin(CryptoMarket.this);
- } else {
- getServer().getConsoleSender().sendMessage(
- "[CryptoMarket] Database configured successfuly!");
-
- ExchangeRates rates = new ExchangeRates(CryptoMarket.this);
- rates.updateAll();
-
- updateRates = new UpdateExchangeRatesTask(rates);
- updateRates.start(CryptoMarket.this);
-
- saveInvestors = new SaveInvestorsTask(CryptoMarket.this);
- saveInvestors.start();
- }
- }
- }.runTask(this);
+ getInvestorDao().configureDatabase(this, (success) -> {
+ if (!success) {
+ getServer().getPluginManager().disablePlugin(this);
+ } else {
+ getLogger().info("Database configured successfuly!");
+ getExchangeRates().updateAll();
+ startTasks();
+ }
});
}
+ private void startTasks() {
+ new UpdateExchangeRatesTask(this).start();
+ new SaveInvestorsTask(this).start();
+ new UpdateRichersListTask(this).start();
+ }
+
@Override
public void onDisable() {
- if (saveInvestors == null || updateRates == null) return;
-
- new InvestorDao(this).saveAll();
- saveInvestors.cancel();
- updateRates.cancel();
+ getServer().getScheduler().cancelTasks(this);
+ getInvestorDao().saveAll();
}
/**
@@ -102,7 +82,7 @@ public void onDisable() {
*/
public static void debug(String message) {
if (debug) {
- Bukkit.getServer().getLogger().log(Level.INFO, "[CryptoMarket] {0}", message);
+ getInstance().getLogger().info(message);
}
}
@@ -112,7 +92,7 @@ public static void debug(String message) {
* @param message message
*/
public static void warn(String message) {
- Bukkit.getServer().getLogger().log(Level.WARNING, "[CryptoMarket] {0}", message);
+ getInstance().getLogger().warning(message);
}
/**
@@ -124,8 +104,8 @@ private boolean setupEconomy() {
if (getServer().getPluginManager().getPlugin("Vault") == null) {
return false;
}
- RegisteredServiceProvider rsp = getServer()
- .getServicesManager().getRegistration(Economy.class);
+ RegisteredServiceProvider rsp = getServer()
+ .getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class);
if (rsp == null) {
return false;
}
@@ -133,21 +113,33 @@ private boolean setupEconomy() {
return econ != null;
}
+ public InvestorDao getInvestorDao() {
+ return InvestorDao.getInstance(this);
+ }
+
+ public ExchangeRates getExchangeRates() {
+ return ExchangeRates.getInstance(this);
+ }
+
/**
* Returns Vault's Economy
*
* @return economy
*/
- public Economy getEconomy() {
+ public net.milkbowl.vault.economy.Economy getVaultEconomy() {
return econ;
}
+ public Economy getEconomy() {
+ return Economy.getInstance(this);
+ }
+
/**
* Returns the instance of CryptoMarket
*
* @return the instance
*/
- public static CryptoMarket getCryptoMarket() {
+ public static CryptoMarket getInstance() {
return cm;
}
}
diff --git a/src/main/java/net/epconsortium/cryptomarket/commands/CryptoMarketCommand.java b/src/main/java/net/epconsortium/cryptomarket/commands/CryptoMarketCommand.java
index d5b9caf..bfb9c66 100644
--- a/src/main/java/net/epconsortium/cryptomarket/commands/CryptoMarketCommand.java
+++ b/src/main/java/net/epconsortium/cryptomarket/commands/CryptoMarketCommand.java
@@ -2,10 +2,11 @@
import java.math.BigDecimal;
import net.epconsortium.cryptomarket.CryptoMarket;
-import net.epconsortium.cryptomarket.database.dao.InvestorDao;
+import net.epconsortium.cryptomarket.database.dao.Investor;
import net.epconsortium.cryptomarket.finances.ExchangeRate;
import net.epconsortium.cryptomarket.finances.ExchangeRates;
-import net.epconsortium.cryptomarket.ui.Menu;
+import net.epconsortium.cryptomarket.ui.InventoryDrawer;
+import net.epconsortium.cryptomarket.ui.frames.MenuFrame;
import net.epconsortium.cryptomarket.util.Configuration;
import net.epconsortium.cryptomarket.util.Formatter;
import org.bukkit.command.Command;
@@ -67,7 +68,11 @@ public boolean onCommand(CommandSender commandSender, Command command,
}
} else {
if (player.hasPermission("cryptomarket.menu")) {
- new Menu(plugin, player).open();
+ if (plugin.getInvestorDao().getInvestor(player) == null) {
+ player.sendMessage(config.getMessageErrorConnectingToDatabase());
+ return true;
+ }
+ InventoryDrawer.getInstance().open(new MenuFrame(null, player));
} else {
player.sendMessage(config.getMessageErrorNoPermission());
}
@@ -87,16 +92,14 @@ public boolean onCommand(CommandSender commandSender, Command command,
*/
private boolean processUpdateCommand(Player player) {
if (player.hasPermission("cryptomarket.update")) {
- if (ExchangeRates.errorOcurred()) {
- ExchangeRates rates = new ExchangeRates(plugin);
+ if (ExchangeRates.errorOccurred()) {
+ ExchangeRates rates = plugin.getExchangeRates();
rates.updateAll();
String mensagem = config.getMessageUpdatingContent();
- mensagem = MessageFormat.format(mensagem,
- rates.getMinutesToUpdate());
+ mensagem = MessageFormat.format(mensagem, rates.getMinutesToUpdate());
player.sendMessage(mensagem);
} else {
- player.sendMessage(
- config.getMessageContentAlreadyUptodate());
+ player.sendMessage(config.getMessageContentAlreadyUptodate());
}
} else {
player.sendMessage(config.getMessageErrorNoPermission());
@@ -112,16 +115,14 @@ private boolean processUpdateCommand(Player player) {
*/
private boolean processTodayCommand(Player player) {
if (player.hasPermission("cryptomarket.today")) {
- ExchangeRate er = new ExchangeRates(plugin).getExchangeRate(
- LocalDate.now());
+ ExchangeRate er = plugin.getExchangeRates().getExchangeRate(LocalDate.now());
if (er == null) {
player.sendMessage(config.getMessageCommandOutdatedData());
return true;
}
player.sendMessage(config.getMessageCurrentExchangeRate());
for (String coin : config.getCoins()) {
- player.sendMessage(MessageFormat.format(
- config.getMessageCurrentExchangeRatePerCoin(), coin,
+ player.sendMessage(MessageFormat.format(config.getMessageCurrentExchangeRatePerCoin(), coin,
Formatter.formatCryptocoin(er.getCoinValue(coin))));
}
} else {
@@ -161,29 +162,21 @@ public List onTabComplete(CommandSender commandSender,
*/
private boolean processBalanceCommand(Player player) {
if (player.hasPermission("cryptomarket.balance")) {
- new InvestorDao(plugin).getInvestor(player, (investor) -> {
- new BukkitRunnable() {
- @Override
- public void run() {
- if (!player.isOnline()) {
- return;
- }
- if (investor == null) {
- player.sendMessage(config
- .getMessageErrorConnectingToDatabase());
- return;
- }
- player.sendMessage(config.getMessageBalance());
- config.getCoins().forEach((coin) -> {
- player.sendMessage(MessageFormat.format(
- config.getMessageBalancePerCoin(), coin,
- Formatter.formatCryptocoin(investor
- .getBalance(coin).getValue())));
- });
- }
- }.runTask(plugin);
+ Investor investor = plugin.getInvestorDao().getInvestor(player);
+ if (!player.isOnline()) {
+ return true;
+ }
+ if (investor == null) {
+ player.sendMessage(config.getMessageErrorConnectingToDatabase());
+ return true;
+ }
+ player.sendMessage(config.getMessageBalance());
+ config.getCoins().forEach((coin) -> {
+ player.sendMessage(MessageFormat.format(config.getMessageBalancePerCoin(), coin,
+ Formatter.formatCryptocoin(investor.getBalance(coin).getValue())));
});
+
} else {
player.sendMessage(config.getMessageErrorNoPermission());
}
@@ -202,7 +195,7 @@ private boolean processSaveCommand(Player player) {
new BukkitRunnable() {
@Override
public void run() {
- new InvestorDao(plugin).saveAll();
+ plugin.getInvestorDao().saveAll();
}
}.runTaskAsynchronously(plugin);
} else {
@@ -244,23 +237,15 @@ private boolean processGiveCommand(Player player, String[] args) {
player.sendMessage(config.getMessageErrorInvalidCoin());
return false;
}
- new InvestorDao(plugin).getInvestor(target, (investor) -> {
- new BukkitRunnable() {
- @Override
- public void run() {
- if (investor == null) {
- player.sendMessage(config
- .getMessageErrorConnectingToDatabase());
- return;
- }
- Economy economy = new Economy(plugin, coin);
- economy.deposit(investor, amount);
- player.sendMessage(MessageFormat.format(
- config.getMessagePlayerBalanceUpdated(),
- target.getName()));
- }
- }.runTask(plugin);
- });
+ Investor investor = plugin.getInvestorDao().getInvestor(target);
+ if (investor == null) {
+ player.sendMessage(config.getMessageErrorConnectingToDatabase());
+ return true;
+ }
+ plugin.getEconomy().deposit(coin, investor, amount);
+ player.sendMessage(MessageFormat.format(config.getMessagePlayerBalanceUpdated(), target.getName()));
+
+
} else {
player.sendMessage(config.getMessageErrorNoPermission());
}
@@ -272,7 +257,7 @@ public void run() {
* Process the take command
*
* @param player player
- * @param args args
+ * @param args args
* @return true if the syntax is ok
*/
private boolean processTakeCommand(Player player, String[] args) {
@@ -301,28 +286,19 @@ private boolean processTakeCommand(Player player, String[] args) {
player.sendMessage(config.getMessageErrorInvalidCoin());
return false;
}
- new InvestorDao(plugin).getInvestor(target, (investor) -> {
- new BukkitRunnable() {
- @Override
- public void run() {
- if (investor == null) {
- player.sendMessage(config
- .getMessageErrorConnectingToDatabase());
- return;
- }
- Economy economy = new Economy(plugin, coin);
- if (economy.has(investor, amount)) {
- economy.withdraw(investor, amount);
- player.sendMessage(MessageFormat.format(
- config.getMessagePlayerBalanceUpdated(),
- target.getName()));
- } else {
- player.sendMessage(config
- .getMessageErrorInsufficientBalance());
- }
- }
- }.runTask(plugin);
- });
+ Investor investor = plugin.getInvestorDao().getInvestor(target);
+
+ if (investor == null) {
+ player.sendMessage(config.getMessageErrorConnectingToDatabase());
+ return true;
+ }
+ Economy economy = plugin.getEconomy();
+ if (economy.has(coin, investor, amount)) {
+ economy.withdraw(coin, investor, amount);
+ player.sendMessage(MessageFormat.format(config.getMessagePlayerBalanceUpdated(), target.getName()));
+ } else {
+ player.sendMessage(config.getMessageErrorInsufficientBalance());
+ }
} else {
player.sendMessage(config.getMessageErrorNoPermission());
}
@@ -363,23 +339,13 @@ private boolean processSetCommand(Player player, String[] args) {
player.sendMessage(config.getMessageErrorInvalidCoin());
return false;
}
- new InvestorDao(plugin).getInvestor(target, (investor) -> {
- new BukkitRunnable() {
- @Override
- public void run() {
- if (investor == null) {
- player.sendMessage(config
- .getMessageErrorConnectingToDatabase());
- return;
- }
- Economy economy = new Economy(plugin, coin);
- economy.set(investor, amount);
- player.sendMessage(MessageFormat.format(
- config.getMessagePlayerBalanceUpdated(),
- target.getName()));
- }
- }.runTask(plugin);
- });
+ Investor investor = plugin.getInvestorDao().getInvestor(target);
+ if (investor == null) {
+ player.sendMessage(config.getMessageErrorConnectingToDatabase());
+ return true;
+ }
+ plugin.getEconomy().set(coin, investor, amount);
+ player.sendMessage(MessageFormat.format(config.getMessagePlayerBalanceUpdated(), target.getName()));
} else {
player.sendMessage(config.getMessageErrorNoPermission());
}
diff --git a/src/main/java/net/epconsortium/cryptomarket/conversation/NegotiationConversation.java b/src/main/java/net/epconsortium/cryptomarket/conversation/NegotiationConversation.java
index b940b27..409afbb 100644
--- a/src/main/java/net/epconsortium/cryptomarket/conversation/NegotiationConversation.java
+++ b/src/main/java/net/epconsortium/cryptomarket/conversation/NegotiationConversation.java
@@ -41,22 +41,15 @@ public NegotiationConversation(CryptoMarket plugin, Negotiation negotiation, Pla
* Starts the Negotiation Conversation with the Player
*/
public void start() {
- new InvestorDao(plugin).getInvestor(player, (investor) -> {
- new BukkitRunnable() {
- @Override
- public void run() {
- if (!player.isOnline()) {
- return;
- }
- if (investor == null) {
- player.sendMessage(config.
- getMessageErrorConnectingToDatabase());
- return;
- }
- createConversation(investor).begin();
- }
- }.runTask(plugin);
- });
+ if (!player.isOnline()) {
+ return;
+ }
+ Investor investor = plugin.getInvestorDao().getInvestor(player);
+ if (investor == null) {
+ player.sendMessage(config.getMessageErrorConnectingToDatabase());
+ return;
+ }
+ createConversation(investor).begin();
}
/**
diff --git a/src/main/java/net/epconsortium/cryptomarket/conversation/prompt/AmountPrompt.java b/src/main/java/net/epconsortium/cryptomarket/conversation/prompt/AmountPrompt.java
index 8a8f236..1474514 100644
--- a/src/main/java/net/epconsortium/cryptomarket/conversation/prompt/AmountPrompt.java
+++ b/src/main/java/net/epconsortium/cryptomarket/conversation/prompt/AmountPrompt.java
@@ -20,10 +20,9 @@ protected Prompt acceptValidatedInput(ConversationContext context, Number number
CryptoMarket plugin = (CryptoMarket) context.getPlugin();
Configuration config = new Configuration(plugin);
String coin = ((String) context.getSessionData("coin"));
- Economy economia = new Economy(plugin, coin);
BigDecimal amount = new BigDecimal(number.toString());
- if (economia.convert(amount).doubleValue() < 0) {
+ if (plugin.getEconomy().convert(coin, amount).doubleValue() < 0) {
return new OutdatedDataPrompt();
}
context.setSessionData("amount", amount);
diff --git a/src/main/java/net/epconsortium/cryptomarket/conversation/prompt/ConfirmationPrompt.java b/src/main/java/net/epconsortium/cryptomarket/conversation/prompt/ConfirmationPrompt.java
index 3917172..175af57 100644
--- a/src/main/java/net/epconsortium/cryptomarket/conversation/prompt/ConfirmationPrompt.java
+++ b/src/main/java/net/epconsortium/cryptomarket/conversation/prompt/ConfirmationPrompt.java
@@ -27,16 +27,14 @@ public ConfirmationPrompt(String yes, String cancel) {
}
@Override
- protected Prompt acceptValidatedInput(ConversationContext context,
- String s) {
+ protected Prompt acceptValidatedInput(ConversationContext context, String s) {
if (s.equals(cancel)) {
return END_OF_CONVERSATION;
}
CryptoMarket plugin = (CryptoMarket) context.getPlugin();
String coin = (String) context.getSessionData("coin");
- Economy economy = new Economy(plugin, coin);
-
+ Economy economy = plugin.getEconomy();
Investor investor = (Investor) context.getSessionData("investor");
BigDecimal value = (BigDecimal) context.getSessionData("amount");
@@ -44,12 +42,12 @@ protected Prompt acceptValidatedInput(ConversationContext context,
Negotiation negotiation = getNegotiation(context);
switch (negotiation) {
case PURCHASE:
- if (!economy.buy(investor, value)) {
+ if (!economy.buy(coin, investor, value)) {
return new ErrorPrompt();
}
break;
case SELL:
- if (!economy.sell(investor, value)) {
+ if (!economy.sell(coin, investor, value)) {
return new ErrorPrompt();
}
break;
@@ -62,7 +60,6 @@ protected Prompt acceptValidatedInput(ConversationContext context,
public String getPromptText(ConversationContext context) {
CryptoMarket plugin = (CryptoMarket) context.getPlugin();
String coin = (String) context.getSessionData("coin");
- Economy economy = new Economy(plugin, coin);
Configuration config = new Configuration(plugin);
String message = config.getMessageNegotiationConfirmation();
String action = null;
@@ -78,10 +75,9 @@ public String getPromptText(ConversationContext context) {
}
BigDecimal amount = ((BigDecimal) context.getSessionData("amount"));
- BigDecimal value = economy.convert(amount);
+ BigDecimal value = plugin.getEconomy().convert(coin, amount);
- return MessageFormat.format(message, action, amount, coin, value) +
- " " + formatFixedSet();
+ return MessageFormat.format(message, action, amount, coin, value) + " " + formatFixedSet();
}
private Negotiation getNegotiation(ConversationContext context) {
diff --git a/src/main/java/net/epconsortium/cryptomarket/database/dao/Investor.java b/src/main/java/net/epconsortium/cryptomarket/database/dao/Investor.java
index a114d9b..c5242fa 100644
--- a/src/main/java/net/epconsortium/cryptomarket/database/dao/Investor.java
+++ b/src/main/java/net/epconsortium/cryptomarket/database/dao/Investor.java
@@ -1,12 +1,12 @@
package net.epconsortium.cryptomarket.database.dao;
+import net.epconsortium.cryptomarket.finances.ExchangeRate;
import org.bukkit.OfflinePlayer;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.math.BigDecimal;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Objects;
-import java.util.UUID;
+import java.util.*;
/**
* Class representing an Investor
@@ -26,7 +26,7 @@ public class Investor {
/**
* Returns the OfflinePlayer linked to the Investor
*
- * @return offlineplayer
+ * @return the {@link OfflinePlayer}
*/
public OfflinePlayer getPlayer() {
return player;
@@ -48,6 +48,32 @@ public Balance getBalance(String coin) {
return balance;
}
+ /**
+ * Converts this Investor's balance in cryptocoins to the server's currency
+ *
+ * @param rate the {@link ExchangeRate} used to calculate the patrimony
+ * @return the converted patrimony or -1 if the rate is null
+ */
+ public BigDecimal getConvertedPatrimony(@Nullable ExchangeRate rate) {
+ if (rate == null) {
+ return new BigDecimal(-1);
+ }
+ BigDecimal patrimony = BigDecimal.ZERO;
+ for (Map.Entry entry : getBalances().entrySet()) {
+ patrimony = patrimony.add(rate.getCoinValue(entry.getKey()).multiply(entry.getValue().getValue()));
+ }
+
+ return patrimony;
+ }
+
+ public static Comparator comparator(@NotNull ExchangeRate exchangeRate) {
+ return (o1, o2) -> o1.compareTo(o2, exchangeRate);
+ }
+
+ public int compareTo(@NotNull Investor other, @NotNull ExchangeRate rate) {
+ return getConvertedPatrimony(rate).compareTo(other.getConvertedPatrimony(rate));
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -55,12 +81,12 @@ public boolean equals(Object o) {
Investor that = (Investor) o;
- return player.equals(that.player);
+ return player.getUniqueId().equals(that.player.getUniqueId());
}
@Override
public int hashCode() {
- return player.hashCode();
+ return player.getUniqueId().hashCode();
}
/**
diff --git a/src/main/java/net/epconsortium/cryptomarket/database/dao/InvestorDao.java b/src/main/java/net/epconsortium/cryptomarket/database/dao/InvestorDao.java
index 070b1e4..49f0416 100644
--- a/src/main/java/net/epconsortium/cryptomarket/database/dao/InvestorDao.java
+++ b/src/main/java/net/epconsortium/cryptomarket/database/dao/InvestorDao.java
@@ -2,17 +2,20 @@
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
+import net.epconsortium.cryptomarket.CryptoMarket;
+import net.epconsortium.cryptomarket.database.ConnectionFactory;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
+import org.bukkit.scheduler.BukkitRunnable;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Type;
import java.sql.*;
import java.util.*;
-import net.epconsortium.cryptomarket.CryptoMarket;
+import java.util.concurrent.CopyOnWriteArrayList;
+
import static net.epconsortium.cryptomarket.CryptoMarket.debug;
-import net.epconsortium.cryptomarket.database.ConnectionFactory;
-import org.bukkit.entity.Player;
-import org.bukkit.scheduler.BukkitRunnable;
/**
* Class used to manage the Investors
@@ -21,190 +24,143 @@
*/
public class InvestorDao {
- private static final Map INVESTORS_ONLINE = new HashMap<>();
+ private static InvestorDao instance;
+ private static final List ONLINE_INVESTORS = new CopyOnWriteArrayList<>();
+ private static ConnectionFactory connectionFactory;
private final Gson gson = new Gson();
- private static final Type BALANCES_TYPE = TypeToken.getParameterized(
- Map.class, String.class, Balance.class).getType();
+ private static final Type BALANCES_TYPE = TypeToken.getParameterized(Map.class, String.class, Balance.class)
+ .getType();
private final CryptoMarket plugin;
-
- public InvestorDao(CryptoMarket plugin) {
+
+ private InvestorDao(CryptoMarket plugin) {
this.plugin = Objects.requireNonNull(plugin);
+ connectionFactory = new ConnectionFactory(plugin);
+ }
+
+ public static InvestorDao getInstance(@NotNull CryptoMarket plugin) {
+ if (instance == null) {
+ instance = new InvestorDao(plugin);
+ }
+ return instance;
}
/**
* Creates the table if it does not exist
- *
- * @param plugin
- * @param callback
*/
- public static void configureDatabase(CryptoMarket plugin,
- DatabaseConfigurationCallback callback) {
+ public void configureDatabase(CryptoMarket plugin, DatabaseConfigurationCallback callback) {
Objects.requireNonNull(plugin);
Objects.requireNonNull(callback);
new BukkitRunnable() {
@Override
public void run() {
boolean success;
- try (Connection connection = new ConnectionFactory(
- plugin).getConnection()) {
- connection.createStatement().execute("CREATE TABLE IF NOT"
- + " EXISTS investors (uuid VARCHAR(255), "
- + "balances TEXT);");
+ try (Connection connection = connectionFactory.getConnection()) {
+ connection.createStatement().execute("CREATE TABLE IF NOT EXISTS investors (uuid VARCHAR(255), balances TEXT);");
success = true;
} catch (SQLException ex) {
CryptoMarket.warn("Error configuring the database:");
ex.printStackTrace();
success = false;
}
- callback.onDatabaseConfigured(success);
+ boolean finalSuccess = success;
+ Bukkit.getScheduler().runTask(plugin, () -> callback.onDatabaseConfigured(finalSuccess));
}
}.runTaskAsynchronously(plugin);
}
/**
- * Saves the Investor data on the database
+ * Inserts the Investor data into the database
*
- * @param investor investor to save
+ * @param investor investor to insert
*/
- private void save(Investor investor) {
- Objects.requireNonNull(investor);
-
+ private void insert(@NotNull Investor investor) {
try (Connection connection = new ConnectionFactory(plugin).getConnection()) {
PreparedStatement s = connection.prepareStatement("INSERT INTO investors (uuid, balances) VALUES (?,?);");
s.setString(1, investor.getPlayer().getUniqueId().toString());
s.setString(2, gson.toJson(investor.getBalances(), BALANCES_TYPE));
s.execute();
- INVESTORS_ONLINE.put(investor.getUniqueId(), investor);
+ ONLINE_INVESTORS.add(investor);
} catch (SQLException ex) {
CryptoMarket.warn("Error saving the Investor to the database: " + investor);
ex.printStackTrace();
}
}
- /**
- * Retrieves an Investor from a Player
- *
- * @param player player
- * @param callback callback
- */
- public void getInvestor(Player player, InvestorDataCallback callback) {
- Objects.requireNonNull(player);
- Objects.requireNonNull(callback);
-
- Investor i = INVESTORS_ONLINE.get(player.getUniqueId());
- if (i != null) {
- callback.onInvestorDataReady(i);
- return;
+ public @Nullable Investor getInvestor(@NotNull final OfflinePlayer player) {
+ for (Investor investor : ONLINE_INVESTORS) {
+ if (investor.getUniqueId().equals(player.getUniqueId())) {
+ return investor;
+ }
}
- new BukkitRunnable() {
- @Override
- public void run() {
- try (Connection connection = new ConnectionFactory(plugin)
- .getConnection()) {
- PreparedStatement statement = connection.
- prepareStatement("SELECT * FROM investors"
- + " WHERE uuid = ?;");
- statement.setString(1, player.getUniqueId().toString());
- ResultSet set = statement.executeQuery();
- Investor investor;
- if (set.next()) {
- Map balances = gson.fromJson(
- set.getString("balances"), BALANCES_TYPE);
-
- investor = new Investor(player, balances);
- debug("Successfully retrieved data from "
- + player.getName());
- } else {
- debug(player.getName() + " was not an Investor. "
- + "Creating data...");
- investor = new Investor(player, new HashMap<>());
- save(investor);
- }
- INVESTORS_ONLINE.put(investor.getUniqueId(), investor);
- callback.onInvestorDataReady(investor);
- } catch (SQLException ex) {
- CryptoMarket.warn("An error ocurred while retrieving "
- + "data from " + player.getName());
- ex.printStackTrace();
- callback.onInvestorDataReady(null);
- }
+ return null;
+ }
+
+ public void unloadInvestor(@NotNull final OfflinePlayer player) {
+ ONLINE_INVESTORS.removeIf(i -> i.getUniqueId().equals(player.getUniqueId()));
+ }
+
+ public void loadInvestor(@NotNull final OfflinePlayer player) {
+ try (Connection connection = new ConnectionFactory(plugin).getConnection()) {
+ PreparedStatement statement = connection.prepareStatement("SELECT * FROM investors WHERE uuid = ?;");
+ statement.setString(1, player.getUniqueId().toString());
+ ResultSet set = statement.executeQuery();
+ Investor investor;
+ if (set.next()) {
+ Map balances = gson.fromJson(set.getString("balances"), BALANCES_TYPE);
+
+ investor = new Investor(player, balances);
+ debug("Successfully retrieved data for " + player.getName());
+ ONLINE_INVESTORS.add(investor);
+ } else {
+ debug(player.getName() + " was not an Investor. Creating data...");
+ investor = new Investor(player, new HashMap<>());
+ insert(investor);
}
- }.runTaskAsynchronously(plugin);
+ } catch (SQLException ex) {
+ CryptoMarket.warn("An error occurred while retrieving data for " + player.getName());
+ ex.printStackTrace();
+ }
}
- /**
- * Returns all Investors saved in the database
- *
- * @param callback callback
- */
- public void getInvestors(InvestorsDataCallback callback) {
- Objects.requireNonNull(callback);
-
- new BukkitRunnable() {
- @Override
- public void run() {
- debug("Retrieving investors from the database...");
- try (Connection connection = new ConnectionFactory(plugin)
- .getConnection()) {
- Statement statement = connection.createStatement();
- ResultSet set = statement.executeQuery("SELECT * FROM "
- + "investors;");
-
- Set investors = new HashSet<>();
- while (set.next()) {
- Map balances = gson.fromJson(
- set.getString("balances"), BALANCES_TYPE);
- UUID uuid = UUID.fromString(set.getString("uuid"));
- OfflinePlayer player = Bukkit.getOfflinePlayer(uuid);
- Investor investor = new Investor(player, balances);
- if (INVESTORS_ONLINE.containsKey(uuid)) {
- investor = INVESTORS_ONLINE.get(uuid);
- }
- investors.add(investor);
- }
- callback.onInvestorsDataReady(investors);
- } catch (SQLException ex) {
- CryptoMarket.warn("Error retrieving all investors "
- + "from the database:");
- ex.printStackTrace();
- callback.onInvestorsDataReady(null);
+ public @Nullable List getInvestors() {
+ List investors = new ArrayList<>();
+ try (Connection connection = new ConnectionFactory(plugin).getConnection()) {
+ Statement statement = connection.createStatement();
+ ResultSet set = statement.executeQuery("SELECT * FROM investors;");
+ while (set.next()) {
+ Map balances = gson.fromJson(set.getString("balances"), BALANCES_TYPE);
+ UUID uuid = UUID.fromString(set.getString("uuid"));
+ OfflinePlayer player = Bukkit.getOfflinePlayer(uuid);
+ Investor investor = getInvestor(player);
+ if (investor == null) {
+ investor = new Investor(player, balances);
}
+ investors.add(investor);
}
- }.runTaskAsynchronously(plugin);
+ } catch (SQLException ex) {
+ CryptoMarket.warn("Error retrieving all investors from the database:");
+ ex.printStackTrace();
+ return null;
+ }
+
+ return investors;
}
/**
* Saves the last modifications to the database
- *
*/
public void saveAll() {
debug("Saving online investors...");
- try (Connection connection =
- new ConnectionFactory(plugin).getConnection()) {
- try (PreparedStatement ps = connection.prepareStatement(
- "UPDATE investors SET balances=? WHERE uuid=?;")) {
- Set offline = new HashSet<>();
- for (Map.Entry entry :
- INVESTORS_ONLINE.entrySet()) {
- Investor investor = entry.getValue();
- ps.setString(1, gson.toJson(investor.getBalances(),
- BALANCES_TYPE));
- ps.setString(2, investor.getPlayer().getUniqueId()
- .toString());
+ try (Connection connection = new ConnectionFactory(plugin).getConnection()) {
+ try (PreparedStatement ps = connection.prepareStatement("UPDATE investors SET balances=? WHERE uuid=?;")) {
+ for (Investor investor : ONLINE_INVESTORS) {
+ ps.setString(1, gson.toJson(investor.getBalances(), BALANCES_TYPE));
+ ps.setString(2, investor.getPlayer().getUniqueId().toString());
ps.addBatch();
-
- if (!investor.getPlayer().isOnline()) {
- debug(investor + " is not online. "
- + "Removing from the map...");
- offline.add(entry.getKey());
- }
}
ps.executeBatch();
-
- //Removing the offline investors
- INVESTORS_ONLINE.keySet().removeAll(offline);
}
} catch (SQLException ex) {
CryptoMarket.warn("Error saving online investors!");
@@ -212,33 +168,13 @@ public void saveAll() {
}
}
- public static interface DatabaseConfigurationCallback {
+ public interface DatabaseConfigurationCallback {
/**
* Called when the database configuration is finished
*
* @param success true if success
*/
- public void onDatabaseConfigured(boolean success);
- }
-
- public static interface InvestorsDataCallback {
-
- /**
- * Notifies when the Investors set is ready
- *
- * @param investors set of all investors, null if an error ocurred
- */
- void onInvestorsDataReady(Set investors);
- }
-
- public static interface InvestorDataCallback {
-
- /**
- * Notifies when the Investor object is ready
- *
- * @param investor the investor, null if an error ocurred
- */
- void onInvestorDataReady(Investor investor);
+ void onDatabaseConfigured(boolean success);
}
}
diff --git a/src/main/java/net/epconsortium/cryptomarket/finances/Economy.java b/src/main/java/net/epconsortium/cryptomarket/finances/Economy.java
index 8a23399..7cd86d8 100644
--- a/src/main/java/net/epconsortium/cryptomarket/finances/Economy.java
+++ b/src/main/java/net/epconsortium/cryptomarket/finances/Economy.java
@@ -1,10 +1,13 @@
package net.epconsortium.cryptomarket.finances;
import net.epconsortium.cryptomarket.CryptoMarket;
+import net.epconsortium.cryptomarket.database.dao.Investor;
import net.epconsortium.cryptomarket.util.Configuration;
import net.epconsortium.cryptomarket.util.Formatter;
+import net.epconsortium.cryptomarket.util.Logger;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
import java.math.BigDecimal;
import java.text.MessageFormat;
@@ -13,15 +16,12 @@
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
-import java.util.Set;
import java.util.stream.Collectors;
import static net.epconsortium.cryptomarket.CryptoMarket.debug;
-import net.epconsortium.cryptomarket.database.dao.InvestorDao;
-import net.epconsortium.cryptomarket.database.dao.Investor;
-import net.epconsortium.cryptomarket.util.Logger;
/**
* Class used to perform operations like purchase, sell, etc.
@@ -31,27 +31,28 @@
*/
public class Economy {
+ private static Economy instance;
private final CryptoMarket plugin;
- private final net.milkbowl.vault.economy.Economy economy;
+ private final net.milkbowl.vault.economy.Economy vaultEconomy;
private final Configuration config;
- private final String coin;
private final Logger logger;
- private static List richers = new ArrayList<>();
- private static long richersUpdate = -1;
- private static double totalInvestments = 0;
- private static long totalInvestmentsUpdate = -1;
+ private List investors = new ArrayList<>();
+ private long richersUpdate = -1;
+ private double totalInvestments = 0;
- public Economy(CryptoMarket plugin, String coin) {
- this.plugin = Objects.requireNonNull(plugin);
+ private Economy(@NotNull CryptoMarket plugin) {
+ this.plugin = plugin;
config = new Configuration(plugin);
- economy = plugin.getEconomy();
+ vaultEconomy = plugin.getVaultEconomy();
logger = new Logger(plugin);
+ }
- if (coin == null) {
- coin = "BTC";
+ public static Economy getInstance(@NotNull CryptoMarket plugin) {
+ if (instance == null) {
+ instance = new Economy(plugin);
}
- this.coin = coin;
+ return instance;
}
/**
@@ -63,8 +64,7 @@ public Economy(CryptoMarket plugin, String coin) {
* @throws IllegalArgumentException if amount is equal or less than 0 or
* investor does not have the amount
*/
- public void withdraw(Investor investor, BigDecimal amount)
- throws IllegalArgumentException {
+ public void withdraw(String coin, Investor investor, BigDecimal amount) throws IllegalArgumentException {
Objects.requireNonNull(investor);
Objects.requireNonNull(amount);
@@ -73,13 +73,13 @@ public void withdraw(Investor investor, BigDecimal amount)
+ "than 0");
}
BigDecimal value = investor.getBalance(coin).getValue();
- if (!(has(investor, amount))) {
+ if (!(has(coin, investor, amount))) {
throw new IllegalArgumentException("investor does not have enough "
+ "balance");
}
value = value.subtract(amount);
investor.getBalance(coin).setValue(value);
- sendNewBalance(investor, value);
+ sendNewBalance(coin, investor, value);
}
/**
@@ -87,7 +87,7 @@ public void withdraw(Investor investor, BigDecimal amount)
*
* @param investor investor
*/
- private void sendNewBalance(Investor investor, BigDecimal newBalance) {
+ private void sendNewBalance(String coin, Investor investor, BigDecimal newBalance) {
Objects.requireNonNull(investor);
Objects.requireNonNull(newBalance);
@@ -95,8 +95,7 @@ private void sendNewBalance(Investor investor, BigDecimal newBalance) {
debug("New balance: " + newBalance);
Player player = Bukkit.getPlayer(investor.getPlayer().getUniqueId());
String newBalanceMsg = config.getMessageNewBalance();
- newBalanceMsg = MessageFormat.format(newBalanceMsg, coin, Formatter
- .formatCryptocoin(newBalance));
+ newBalanceMsg = MessageFormat.format(newBalanceMsg, coin, Formatter.formatCryptocoin(newBalance));
if (player != null) {
player.sendMessage(newBalanceMsg);
} else {
@@ -112,7 +111,7 @@ private void sendNewBalance(Investor investor, BigDecimal newBalance) {
* @param amount new balance
* @throws IllegalArgumentException if amount is negative or equal to 0
*/
- public void set(Investor investor, BigDecimal amount) {
+ public void set(String coin, Investor investor, BigDecimal amount) {
Objects.requireNonNull(investor);
Objects.requireNonNull(amount);
@@ -121,7 +120,7 @@ public void set(Investor investor, BigDecimal amount) {
}
investor.getBalance(coin).setValue(amount);
- sendNewBalance(investor, amount);
+ sendNewBalance(coin, investor, amount);
}
/**
@@ -132,7 +131,7 @@ public void set(Investor investor, BigDecimal amount) {
* @param amount amount to deposit
* @throws IllegalArgumentException if amount is negative or equal to 0
*/
- public void deposit(Investor investor, BigDecimal amount)
+ public void deposit(String coin, Investor investor, BigDecimal amount)
throws IllegalArgumentException {
Objects.requireNonNull(investor);
Objects.requireNonNull(amount);
@@ -144,9 +143,8 @@ public void deposit(Investor investor, BigDecimal amount)
BigDecimal value = investor.getBalance(coin).getValue();
value = value.add(amount);
investor.getBalance(coin).setValue(value);
- debug("Processing deposit of " + amount + " " + coin + ". New balance:"
- + " " + value);
- sendNewBalance(investor, value);
+ debug("Processing deposit of " + amount + " " + coin + ". New balance: " + value);
+ sendNewBalance(coin, investor, value);
}
/**
@@ -157,22 +155,20 @@ public void deposit(Investor investor, BigDecimal amount)
* @param amount amount to buy
* @return true if success
*/
- public boolean buy(Investor investor, BigDecimal amount) {
+ public boolean buy(String coin, Investor investor, BigDecimal amount) {
Objects.requireNonNull(investor);
Objects.requireNonNull(amount);
debug("Processing the purchase of crypto for " + investor);
debug("Amount: " + amount);
- double toPay = convert(amount).doubleValue();
+ double toPay = convert(coin, amount).doubleValue();
debug("To pay: " + toPay);
- if (economy.has(investor.getPlayer(), toPay)) {
+ if (vaultEconomy.has(investor.getPlayer(), toPay)) {
if (amount.doubleValue() > 0) {
- economy.withdrawPlayer(investor.getPlayer(), toPay);
+ vaultEconomy.withdrawPlayer(investor.getPlayer(), toPay);
//deposit(investor, amount);
- investor.getBalance(coin).increase(amount,
- new BigDecimal(toPay));
- logger.log(investor, Negotiation.PURCHASE, amount, coin,
- toPay);
+ investor.getBalance(coin).increase(amount, new BigDecimal(toPay));
+ logger.log(investor, Negotiation.PURCHASE, amount, coin, toPay);
return true;
} else {
debug("amount is less than 0");
@@ -189,23 +185,22 @@ public boolean buy(Investor investor, BigDecimal amount) {
*
* @param investor investor
* @param amount amount to sell
- * @return true if sucess
+ * @return true if success
*/
- public boolean sell(Investor investor, BigDecimal amount) {
+ public boolean sell(String coin, Investor investor, BigDecimal amount) {
Objects.requireNonNull(investor);
Objects.requireNonNull(amount);
debug("Processing the sell of crypto for " + investor);
debug("Amount: " + amount);
- double toReceive = convert(amount).doubleValue();
+ double toReceive = convert(coin, amount).doubleValue();
debug("To receive: " + toReceive);
if (amount.doubleValue() > 0) {
- if (has(investor, amount)) {
- economy.depositPlayer(investor.getPlayer(), toReceive);
+ if (has(coin, investor, amount)) {
+ vaultEconomy.depositPlayer(investor.getPlayer(), toReceive);
//withdraw(investor, amount);
- investor.getBalance(coin).decrease(amount,
- new BigDecimal(toReceive));
+ investor.getBalance(coin).decrease(amount, new BigDecimal(toReceive));
logger.log(investor, Negotiation.SELL, amount, coin, toReceive);
return true;
}
@@ -220,11 +215,10 @@ public boolean sell(Investor investor, BigDecimal amount) {
* @param amount amount to convert
* @return value in the server currency
*/
- public BigDecimal convert(BigDecimal amount) {
+ public BigDecimal convert(String coin, BigDecimal amount) {
Objects.requireNonNull(amount);
- ExchangeRate er = new ExchangeRates(plugin).getExchangeRate(
- LocalDate.now());
+ ExchangeRate er = plugin.getExchangeRates().getExchangeRate(LocalDate.now());
if (er == null) {
er = new ExchangeRate();
}
@@ -240,12 +234,11 @@ public BigDecimal convert(BigDecimal amount) {
* @param amount amount
* @return true if success
*/
- public boolean transfer(Investor debited, Investor favored,
- BigDecimal amount) {
+ public boolean transfer(String coin, Investor debited, Investor favored, BigDecimal amount) {
if (!(amount.doubleValue() <= 0)) {
- if (has(debited, amount)) {
- withdraw(debited, amount);
- deposit(favored, amount);
+ if (has(coin, debited, amount)) {
+ withdraw(coin, debited, amount);
+ deposit(coin, favored, amount);
return true;
}
}
@@ -259,71 +252,20 @@ public boolean transfer(Investor debited, Investor favored,
* @param amount amount
* @return true if he does
*/
- public boolean has(Investor investor, BigDecimal amount) {
+ public boolean has(String coin, Investor investor, BigDecimal amount) {
Objects.requireNonNull(investor);
Objects.requireNonNull(amount);
- return investor.getBalance(coin).getValue().doubleValue()
- >= amount.doubleValue();
- }
-
- /**
- * Returns the total investments of the Investor converted to the server
- * currency
- *
- * @param investor investor
- * @return patrimony
- */
- @SuppressWarnings("LocalVariableHidesMemberVariable")
- public BigDecimal getConvertedPatrimony(Investor investor) {
- Objects.requireNonNull(investor);
-
- BigDecimal patrimony = new BigDecimal(0);
- for (String coin : investor.getBalances().keySet()) {
- patrimony = patrimony.add(new Economy(plugin, coin)
- .convert(investor.getBalance(coin).getValue()));
- }
-
- return patrimony;
+ return investor.getBalance(coin).getValue().doubleValue() >= amount.doubleValue();
}
/**
* Returns the total balance of cryptocoins on the server converted to the
* server coin
*
- * @param callback callback
*/
- public void getTotalInvestments(InvestmentsCallback callback) {
- Objects.requireNonNull(callback);
-
- if (totalInvestmentsUpdate == -1 || System.currentTimeMillis()
- > (totalInvestmentsUpdate + config
- .getIntervalRichersUpdateInMillis())) {
- new InvestorDao(plugin).getInvestors((investors) -> {
- updateTotalInvestments(investors);
- callback.onTotalInvestmentsReady(totalInvestments);
- });
- } else {
- callback.onTotalInvestmentsReady(totalInvestments);
- }
- }
-
- /**
- * Updates the total balance of cryptocoins and its last update time
- *
- * @param investors investors to calculate, can be null
- */
- private void updateTotalInvestments(Set investors) {
- if (investors != null) {
- totalInvestments = investors
- .stream()
- .map(this::getConvertedPatrimony)
- .mapToDouble(BigDecimal::doubleValue)
- .sum();
- } else {
- totalInvestments = -1;
- }
- totalInvestmentsUpdate = System.currentTimeMillis();
+ public double getTotalInvestments() {
+ return totalInvestments;
}
/**
@@ -332,80 +274,52 @@ private void updateTotalInvestments(Set investors) {
* list in case the update interval has not passed yet...
*
* @param max max number of investors
- * @param callback callback
- * @throws IllegalArgumentException if max is equal or less than 0
+ * @throws IllegalArgumentException if max is negative
+ * @return the list of richest investors or empty if an error occurred
*/
- public void getRichestInvestors(final int max,
- RichestInvestorsCallback callback) throws IllegalArgumentException {
- Objects.requireNonNull(callback);
-
- if (max < 1) {
- throw new IllegalArgumentException("max cannot be equal or less "
- + "than 0");
+ public @NotNull List getTopInvestors(int max) throws IllegalArgumentException {
+ if (max < 0) {
+ throw new IllegalArgumentException("max cannot be negative");
}
- //Checking if the update interval has passed or not
- if (richersUpdate == -1
- || (System.currentTimeMillis() - config
- .getIntervalRichersUpdateInMillis())
- >= richersUpdate) {
-
- //Getting all investors
- new InvestorDao(plugin).getInvestors((investors) -> {
- updateTotalInvestments(investors);
-
- if (investors == null) {
- callback.onRichestInvestorsDataReady(null);
- debug("Economy: investors list returned null");
- return;
- }
- Economy eco = new Economy(plugin, "");
- debug("Economy: investors list empty? " + investors.isEmpty());
- richers = investors
- .stream()
- .sorted((i1, i2) -> (eco.getConvertedPatrimony(i1)
- .compareTo(eco.getConvertedPatrimony(i2)) * -1))
- .limit(max).collect(Collectors.toList());
-
- richersUpdate = System.currentTimeMillis();
-
- debug("Richers updated");
- callback.onRichestInvestorsDataReady(richers);
- });
- } else {
- debug("The interval has not passed,"
- + " the previous list is going to be returned.");
- //todo: isto deveria levar em consideração o parâmetro max
- callback.onRichestInvestorsDataReady(richers);
+ if (max == 0) {
+ max = investors.size();
+ }
+
+ ExchangeRate rate = plugin.getExchangeRates().getExchangeRate(LocalDate.now());
+ if (rate == null) {
+ return Collections.emptyList();
}
+ return investors.stream().sorted(Investor.comparator(rate)).limit(max).collect(Collectors.toList());
}
/**
- * Returns the time of the last update of the Richers list
- *
- * @return the last update
+ * @return the top 10 richest investors
*/
- public static LocalDateTime getRichersLastUpdate() {
- return LocalDateTime.ofInstant(Instant.ofEpochMilli(richersUpdate),
- ZoneId.systemDefault());
+ public List getTopInvestors() {
+ return getTopInvestors(10);
}
- public static interface InvestmentsCallback {
-
- /**
- * Notifies when the total investments is ready
- *
- * @param total total investments
- */
- void onTotalInvestmentsReady(double total);
+ public void setInvestors(@NotNull List investors) {
+ this.investors = investors;
+ ExchangeRate rate = plugin.getExchangeRates().getExchangeRate(LocalDate.now());
+ if (rate == null) {
+ totalInvestments = 0;
+ } else {
+ totalInvestments = investors.stream().map(i -> i.getConvertedPatrimony(rate))
+ .mapToDouble(BigDecimal::doubleValue).sum();
+ }
}
- public static interface RichestInvestorsCallback {
+ public void setRichersLastUpdate(long timestamp) {
+ this.richersUpdate = timestamp;
+ }
- /**
- * Notifies when the ordered list of richest investors is ready
- *
- * @param investors richer investors, null if an error ocurred
- */
- void onRichestInvestorsDataReady(List investors);
+ /**
+ * Returns the time of the last update of the Richers list
+ *
+ * @return the last update
+ */
+ public LocalDateTime getRichersLastUpdate() {
+ return LocalDateTime.ofInstant(Instant.ofEpochMilli(richersUpdate), ZoneId.systemDefault());
}
}
diff --git a/src/main/java/net/epconsortium/cryptomarket/finances/ExchangeRates.java b/src/main/java/net/epconsortium/cryptomarket/finances/ExchangeRates.java
index d2dce45..9e0d253 100644
--- a/src/main/java/net/epconsortium/cryptomarket/finances/ExchangeRates.java
+++ b/src/main/java/net/epconsortium/cryptomarket/finances/ExchangeRates.java
@@ -6,6 +6,8 @@
import net.epconsortium.cryptomarket.CryptoMarket;
import net.epconsortium.cryptomarket.util.Configuration;
import org.bukkit.scheduler.BukkitRunnable;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.InputStream;
@@ -25,6 +27,7 @@
*/
public class ExchangeRates {
+ private static ExchangeRates instance;
private final CryptoMarket plugin;
private final Configuration config;
@@ -36,16 +39,23 @@ public class ExchangeRates {
private static boolean dailyError;
private static boolean currentError;
- public ExchangeRates(CryptoMarket plugin) {
+ private ExchangeRates(CryptoMarket plugin) {
this.plugin = Objects.requireNonNull(plugin);
config = new Configuration(plugin);
}
+ public static ExchangeRates getInstance(@NotNull CryptoMarket plugin) {
+ if (instance == null) {
+ instance = new ExchangeRates(plugin);
+ }
+ return instance;
+ }
+
/**
* Updates all exchange rates and allocates them on memory
*/
public void updateAll() {
- //Reseting the errors
+ //Resetting the errors
setCurrentError(false);
setDailyError(false);
//Updating
@@ -65,16 +75,12 @@ public void run() {
for (String coin : config.getCoins()) {
awaitServerLimit();
try {
- HttpURLConnection connection
- = openHttpConnection(getExchangeRateUrl(coin));
-
+ HttpURLConnection connection = openHttpConnection(getExchangeRateUrl(coin));
int responseCode = connection.getResponseCode();
if (responseCode >= 200 && responseCode <= 299) {
JsonObject json = extractJsonFrom(connection);
- BigDecimal exchangeRate = json
- .get("Realtime Currency Exchange Rate")
- .getAsJsonObject()
+ BigDecimal exchangeRate = json.get("Realtime Currency Exchange Rate").getAsJsonObject()
.get("5. Exchange Rate").getAsBigDecimal();
LocalDate date = LocalDate.now();
@@ -89,8 +95,8 @@ public void run() {
error = true;
}
} catch (Exception e) {
- warn("Error updating the coins values. "
- + "Wait a few minutes and try again!");
+ warn("Error updating the coins values. Wait a few minutes and try again!");
+ e.printStackTrace();
error = true;
}
}
@@ -118,20 +124,13 @@ public void run() {
if (responseCode >= 200 && responseCode <= 299) {
JsonObject json = extractJsonFrom(connection);
- JsonObject jo = json.getAsJsonObject(
- "Time Series (Digital Currency Daily)");
- Set> entries
- = jo.entrySet();
+ JsonObject jo = json.getAsJsonObject("Time Series (Digital Currency Daily)");
+ Set> entries = jo.entrySet();
entries.forEach(entry -> {
- LocalDate date
- = LocalDate.parse(entry.getKey());
- BigDecimal value = entry.getValue()
- .getAsJsonObject()
- .get("4a. close ("
- + config.getPhysicalCurrency()
- + ")")
- .getAsBigDecimal();
+ LocalDate date = LocalDate.parse(entry.getKey());
+ BigDecimal value = entry.getValue().getAsJsonObject().get("4a. close ("
+ + config.getPhysicalCurrency() + ")").getAsBigDecimal();
ExchangeRate er = getExchangeRate(date);
if (er == null) {
er = new ExchangeRate();
@@ -143,8 +142,8 @@ public void run() {
errors.put(coin, true);
}
} catch (Exception ex) {
- warn("Error updating the coins values. "
- + "Wait a few minutes and try again!");
+ warn("Error updating the coins values. Wait a few minutes and try again!");
+ ex.printStackTrace();
errors.put(coin, true);
}
}
@@ -163,14 +162,10 @@ public void run() {
*
* @param coin coin
* @return the URL
- * @throws MalformedURLException
*/
private URL getExchangeRateUrl(String coin) throws MalformedURLException {
- URL url = new URL("https://www.alphavantage.co/query?function="
- + "CURRENCY_EXCHANGE_RATE&from_currency=" + coin
- + "&to_currency=" + config.getPhysicalCurrency()
- + "&apikey=" + config.getApiKey());
- return url;
+ return new URL("https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE&from_currency=" + coin
+ + "&to_currency=" + config.getPhysicalCurrency() + "&apikey=" + config.getApiKey());
}
/**
@@ -178,25 +173,20 @@ private URL getExchangeRateUrl(String coin) throws MalformedURLException {
*
* @param coin coin
* @return the URL
- * @throws MalformedURLException
*/
private URL getCurrencyDailyUrl(String coin) throws MalformedURLException {
- URL url = new URL("https://www.alphavantage.co/query?function="
- + "DIGITAL_CURRENCY_DAILY&symbol=" + coin + "&market="
- + config.getPhysicalCurrency() + "&apikey="
- + config.getApiKey());
- return url;
+ return new URL("https://www.alphavantage.co/query?function=DIGITAL_CURRENCY_DAILY&symbol=" + coin + "&market="
+ + config.getPhysicalCurrency() + "&apikey=" + config.getApiKey());
}
/**
* Returns the Exchange Rate from the date
*
* @param date date
- * @return Exchange Rate, or null if an error ocurred
+ * @return Exchange Rate, or null if an error occurred
* @throws IllegalArgumentException if date is after today
*/
- public ExchangeRate getExchangeRate(LocalDate date) throws
- IllegalArgumentException {
+ public @Nullable ExchangeRate getExchangeRate(LocalDate date) throws IllegalArgumentException {
Objects.requireNonNull(date);
final LocalDate now = LocalDate.now();
if (date.isAfter(now)) {
@@ -236,7 +226,7 @@ private static synchronized void awaitServerLimit() {
} catch (InterruptedException ex) {
ex.printStackTrace();
}
- //Reseting requests count
+ //Resetting requests count
requests = 1;
}
@@ -245,7 +235,7 @@ private static synchronized void awaitServerLimit() {
*
* @param connection connection
* @return json object
- * @throws IOException if an error ocurred reading the response
+ * @throws IOException if an error occurred reading the response
*/
private JsonObject extractJsonFrom(HttpURLConnection connection) throws IOException {
JsonObject json;
@@ -289,27 +279,27 @@ public int getMinutesToUpdate() {
/**
* Verifies if an error happened during an update
*
- * @return true if an error ocurred
+ * @return true if an error occurred
*/
- public static boolean errorOcurred() {
+ public static boolean errorOccurred() {
return dailyError || currentError;
}
/**
- * Sets if an error ocurred during the daily exchange rate update
+ * Sets if an error occurred during the daily exchange rate update
*
- * @param error true if ocurred
+ * @param error true if occurred
*/
private void setDailyError(boolean error) {
dailyError = error;
}
/**
- * Sets if an error ocurred during the current exchange rate update
+ * Sets if an error occurred during the current exchange rate update
*
- * @param error true if ocurred
+ * @param error true if occurred
*/
- private void setCurrentError(boolean error) {
+ private static void setCurrentError(boolean error) {
currentError = error;
}
}
diff --git a/src/main/java/net/epconsortium/cryptomarket/listeners/PlayerListeners.java b/src/main/java/net/epconsortium/cryptomarket/listeners/PlayerListeners.java
new file mode 100644
index 0000000..29a3f16
--- /dev/null
+++ b/src/main/java/net/epconsortium/cryptomarket/listeners/PlayerListeners.java
@@ -0,0 +1,32 @@
+package net.epconsortium.cryptomarket.listeners;
+
+import net.epconsortium.cryptomarket.CryptoMarket;
+import net.epconsortium.cryptomarket.database.dao.InvestorDao;
+import org.bukkit.Bukkit;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
+import org.jetbrains.annotations.NotNull;
+
+public class PlayerListeners implements Listener {
+
+ private final CryptoMarket plugin;
+ private final InvestorDao investorDao;
+
+ public PlayerListeners(@NotNull CryptoMarket plugin) {
+ this.plugin = plugin;
+ investorDao = plugin.getInvestorDao();
+ }
+
+ @EventHandler
+ public void onJoin(PlayerJoinEvent event) {
+ Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> investorDao.loadInvestor(event.getPlayer()));
+ }
+
+ @EventHandler
+ public void onQuit(PlayerQuitEvent event) {
+ investorDao.unloadInvestor(event.getPlayer());
+ }
+
+}
diff --git a/src/main/java/net/epconsortium/cryptomarket/task/SaveInvestorsTask.java b/src/main/java/net/epconsortium/cryptomarket/task/SaveInvestorsTask.java
index fd7ac66..a048f5d 100644
--- a/src/main/java/net/epconsortium/cryptomarket/task/SaveInvestorsTask.java
+++ b/src/main/java/net/epconsortium/cryptomarket/task/SaveInvestorsTask.java
@@ -1,40 +1,36 @@
package net.epconsortium.cryptomarket.task;
-import java.util.Objects;
import net.epconsortium.cryptomarket.CryptoMarket;
-import net.epconsortium.cryptomarket.database.dao.InvestorDao;
-import net.epconsortium.cryptomarket.util.Configuration;
-import org.bukkit.scheduler.BukkitRunnable;
+import org.jetbrains.annotations.NotNull;
/**
* Task that save all investors to the database
*
* @author roinujnosde
*/
-public class SaveInvestorsTask extends BukkitRunnable {
-
- private final CryptoMarket plugin;
+public class SaveInvestorsTask extends Task {
public SaveInvestorsTask(CryptoMarket plugin) {
- this.plugin = Objects.requireNonNull(plugin);
+ super(plugin);
}
- /**
- * Used internally!
- */
@Override
- public void run() {
- InvestorDao dao = new InvestorDao(plugin);
- dao.saveAll();
+ public @NotNull Runnable getRunnable() {
+ return () -> plugin.getInvestorDao().saveAll();
}
- /**
- * Starts the repetitive task
- */
- public void start() {
- Configuration config = new Configuration(plugin);
- long delay = config.getIntervalSavingInvestorsInTicks();
+ @Override
+ public boolean isAsync() {
+ return true;
+ }
- this.runTaskTimerAsynchronously(plugin, delay, delay);
+ @Override
+ public long getDelay() {
+ return configuration.getIntervalSavingInvestorsInTicks();
+ }
+
+ @Override
+ public long getPeriod() {
+ return configuration.getIntervalSavingInvestorsInTicks();
}
}
diff --git a/src/main/java/net/epconsortium/cryptomarket/task/Task.java b/src/main/java/net/epconsortium/cryptomarket/task/Task.java
new file mode 100644
index 0000000..c84e17a
--- /dev/null
+++ b/src/main/java/net/epconsortium/cryptomarket/task/Task.java
@@ -0,0 +1,43 @@
+package net.epconsortium.cryptomarket.task;
+
+import net.epconsortium.cryptomarket.CryptoMarket;
+import net.epconsortium.cryptomarket.util.Configuration;
+import org.bukkit.scheduler.BukkitScheduler;
+import org.bukkit.scheduler.BukkitTask;
+import org.jetbrains.annotations.NotNull;
+
+public abstract class Task {
+
+ protected final CryptoMarket plugin;
+ protected final Configuration configuration;
+ protected BukkitTask bukkitTask;
+
+ public Task(@NotNull CryptoMarket plugin) {
+ this.plugin = plugin;
+ this.configuration = new Configuration(plugin);
+ }
+
+ public void start() {
+ BukkitScheduler scheduler = plugin.getServer().getScheduler();
+ if (!isAsync()) {
+ bukkitTask = scheduler.runTaskTimer(plugin, getRunnable(), getDelay(), getPeriod());
+ } else {
+ bukkitTask = scheduler.runTaskTimerAsynchronously(plugin, getRunnable(), getDelay(), getPeriod());
+ }
+ }
+
+ public void cancel() {
+ if (bukkitTask != null) {
+ bukkitTask.cancel();
+ bukkitTask = null;
+ }
+ }
+
+ public abstract @NotNull Runnable getRunnable();
+
+ public abstract boolean isAsync();
+
+ public abstract long getDelay();
+
+ public abstract long getPeriod();
+}
diff --git a/src/main/java/net/epconsortium/cryptomarket/task/UpdateExchangeRatesTask.java b/src/main/java/net/epconsortium/cryptomarket/task/UpdateExchangeRatesTask.java
index e01e571..27101e9 100644
--- a/src/main/java/net/epconsortium/cryptomarket/task/UpdateExchangeRatesTask.java
+++ b/src/main/java/net/epconsortium/cryptomarket/task/UpdateExchangeRatesTask.java
@@ -8,49 +8,48 @@
import net.epconsortium.cryptomarket.util.Configuration;
import net.epconsortium.cryptomarket.finances.ExchangeRates;
import org.bukkit.scheduler.BukkitRunnable;
+import org.jetbrains.annotations.NotNull;
/**
* Task that updates the exchanges rates
*
* @author roinujnosde
*/
-public class UpdateExchangeRatesTask extends BukkitRunnable {
+public class UpdateExchangeRatesTask extends Task {
- private final ExchangeRates exchangeRates;
-
- public UpdateExchangeRatesTask(ExchangeRates exchangeRates) {
- this.exchangeRates = Objects.requireNonNull(exchangeRates);
+ public UpdateExchangeRatesTask(@NotNull CryptoMarket plugin) {
+ super(plugin);
}
- /**
- * Used internally!
- */
@Override
- public void run() {
- //Se ocorreu erro, atualiza as cotações diárias e atual
- if (ExchangeRates.errorOcurred()) {
- exchangeRates.updateAll();
- //Se não, atualiza apenas a atual
- } else {
- exchangeRates.updateCurrentExchangeRate();
- }
+ public @NotNull Runnable getRunnable() {
+ ExchangeRates exchangeRates = plugin.getExchangeRates();
+ return () -> {
+ //Se ocorreu erro, atualiza as cotações diárias e atual
+ if (ExchangeRates.errorOccurred()) {
+ exchangeRates.updateAll();
+ //Se não, atualiza apenas a atual
+ } else {
+ exchangeRates.updateCurrentExchangeRate();
+ }
+ };
}
- /**
- * Starts the repetitive task
- *
- * @param plugin plugin
- */
- public void start(CryptoMarket plugin) {
- Objects.requireNonNull(plugin);
-
- Configuration config = new Configuration(plugin);
- long period = config.getIntervalExchangeRatesUpdateInTicks();
+ @Override
+ public boolean isAsync() {
+ return false;
+ }
+ @Override
+ public long getDelay() {
LocalDateTime tomorrow = LocalDate.now().plusDays(1).atTime(0, 1);
long delay = LocalDateTime.now().until(tomorrow, ChronoUnit.SECONDS) * 20;
- delay = delay % period;
- this.runTaskTimer(plugin, delay, period);
+ return delay % getPeriod();
+ }
+
+ @Override
+ public long getPeriod() {
+ return configuration.getIntervalExchangeRatesUpdateInTicks();
}
}
diff --git a/src/main/java/net/epconsortium/cryptomarket/task/UpdateRichersListTask.java b/src/main/java/net/epconsortium/cryptomarket/task/UpdateRichersListTask.java
new file mode 100644
index 0000000..a27855f
--- /dev/null
+++ b/src/main/java/net/epconsortium/cryptomarket/task/UpdateRichersListTask.java
@@ -0,0 +1,43 @@
+package net.epconsortium.cryptomarket.task;
+
+import net.epconsortium.cryptomarket.CryptoMarket;
+import net.epconsortium.cryptomarket.database.dao.Investor;
+import net.epconsortium.cryptomarket.finances.Economy;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+public class UpdateRichersListTask extends Task {
+
+ public UpdateRichersListTask(@NotNull CryptoMarket plugin) {
+ super(plugin);
+ }
+
+ @Override
+ public @NotNull Runnable getRunnable() {
+ return () -> {
+ List investors = plugin.getInvestorDao().getInvestors();
+ if (investors == null) {
+ return;
+ }
+ Economy economy = plugin.getEconomy();
+ economy.setInvestors(investors);
+ economy.setRichersLastUpdate(System.currentTimeMillis());
+ };
+ }
+
+ @Override
+ public boolean isAsync() {
+ return true;
+ }
+
+ @Override
+ public long getDelay() {
+ return 0;
+ }
+
+ @Override
+ public long getPeriod() {
+ return configuration.getIntervalRichersUpdateInTicks();
+ }
+}
diff --git a/src/main/java/net/epconsortium/cryptomarket/ui/Calendar.java b/src/main/java/net/epconsortium/cryptomarket/ui/Calendar.java
index 7e5b7cc..c331cbf 100644
--- a/src/main/java/net/epconsortium/cryptomarket/ui/Calendar.java
+++ b/src/main/java/net/epconsortium/cryptomarket/ui/Calendar.java
@@ -143,8 +143,7 @@ private void loadValues() {
lore.add(config.getCalendarMenuNoExchangeRate());
dayMeta.setLore(lore);
} else {
- ExchangeRates rates = new ExchangeRates(plugin);
- ExchangeRate er = rates.getExchangeRate(date);
+ ExchangeRate er = plugin.getExchangeRates().getExchangeRate(date);
if (er == null) {
er = new ExchangeRate();
diff --git a/src/main/java/net/epconsortium/cryptomarket/ui/CalendarListener.java b/src/main/java/net/epconsortium/cryptomarket/ui/CalendarListener.java
index 9e912eb..d963506 100644
--- a/src/main/java/net/epconsortium/cryptomarket/ui/CalendarListener.java
+++ b/src/main/java/net/epconsortium/cryptomarket/ui/CalendarListener.java
@@ -28,10 +28,6 @@ public CalendarListener(CryptoMarket plugin) {
public void onInventoryClickEvent(InventoryClickEvent event) {
Player player = (Player) event.getWhoClicked();
- if (!Helper.isCustomInventory(event)) {
- return;
- }
-
if (event.getView().getTitle().equals(
config.getCalendarMenuName())) {
event.setCancelled(true);
diff --git a/src/main/java/net/epconsortium/cryptomarket/ui/Component.java b/src/main/java/net/epconsortium/cryptomarket/ui/Component.java
new file mode 100644
index 0000000..4970148
--- /dev/null
+++ b/src/main/java/net/epconsortium/cryptomarket/ui/Component.java
@@ -0,0 +1,48 @@
+package net.epconsortium.cryptomarket.ui;
+
+import org.bukkit.event.inventory.ClickType;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.HashMap;
+
+public abstract class Component {
+
+ private final HashMap listeners = new HashMap<>();
+ private final HashMap permissions = new HashMap<>();
+
+ @NotNull
+ public abstract ItemStack getItem();
+
+ public abstract int getSlot();
+
+ @Nullable
+ public ItemMeta getItemMeta() {
+ return getItem().getItemMeta();
+ }
+
+ public void setItemMeta(@NotNull ItemMeta itemMeta) {
+ getItem().setItemMeta(itemMeta);
+ }
+
+ public void setPermission(@NotNull ClickType click, @Nullable String permission) {
+ permissions.put(click, permission);
+ }
+
+ @Nullable
+ public String getPermission(@NotNull ClickType click) {
+ return permissions.get(click);
+ }
+
+ public void setListener(@NotNull ClickType click, @Nullable Runnable listener) {
+ listeners.put(click, listener);
+ }
+
+ @Nullable
+ public Runnable getListener(@NotNull ClickType click) {
+ return listeners.get(click);
+ }
+}
+
diff --git a/src/main/java/net/epconsortium/cryptomarket/ui/ComponentImpl.java b/src/main/java/net/epconsortium/cryptomarket/ui/ComponentImpl.java
new file mode 100644
index 0000000..661fef8
--- /dev/null
+++ b/src/main/java/net/epconsortium/cryptomarket/ui/ComponentImpl.java
@@ -0,0 +1,116 @@
+package net.epconsortium.cryptomarket.ui;
+
+import com.cryptomorin.xseries.XMaterial;
+import org.bukkit.Material;
+import org.bukkit.inventory.ItemFlag;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ComponentImpl extends Component {
+
+ @NotNull
+ private ItemStack item;
+ private int slot;
+
+ private ComponentImpl() {
+ item = new ItemStack(Material.STONE);
+ slot = 0;
+ }
+
+ public ComponentImpl(@Nullable String displayName, @Nullable List lore, @NotNull Material material,
+ int slot) {
+ this(displayName, lore, new ItemStack(material), slot);
+ }
+
+ public ComponentImpl(@Nullable String displayName, @Nullable List lore, @NotNull XMaterial material,
+ int slot) {
+ this(displayName, lore, material.parseItem(true), slot);
+ }
+
+ public ComponentImpl(@Nullable String displayName, @Nullable List lore, @Nullable ItemStack item,
+ int slot) {
+ if (item == null) {
+ item = new ItemStack(Material.STONE);
+ }
+ this.item = item;
+ ItemMeta itemMeta = item.getItemMeta();
+ if (itemMeta != null) {
+ itemMeta.setDisplayName(displayName);
+ itemMeta.setLore(lore);
+ itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
+ item.setItemMeta(itemMeta);
+ }
+ this.slot = slot;
+ }
+
+ @Override
+ public @NotNull ItemStack getItem() {
+ return item;
+ }
+
+ @Override
+ public int getSlot() {
+ return slot;
+ }
+
+ public static class Builder {
+ private final ComponentImpl component = new ComponentImpl();
+ private @Nullable List lore;
+
+ public Builder(@NotNull XMaterial material) {
+ this(material.parseItem(true));
+ }
+
+ public Builder(@NotNull Material material) {
+ component.item = new ItemStack(material);
+ }
+
+ public Builder(@Nullable ItemStack item) {
+ if (item == null) {
+ item = new ItemStack(Material.STONE);
+ }
+ component.item = item;
+ }
+
+ public Builder withDisplayName(@Nullable String displayName) {
+ ItemMeta itemMeta = component.getItemMeta();
+ if (itemMeta != null) {
+ itemMeta.setDisplayName(displayName);
+ component.setItemMeta(itemMeta);
+ }
+ return this;
+ }
+
+ public Builder withLore(@Nullable List lore) {
+ this.lore = lore;
+ return this;
+ }
+
+ public Builder withLoreLine(@NotNull String line) {
+ if (lore == null) {
+ lore = new ArrayList<>();
+ }
+ lore.add(line);
+ return this;
+ }
+
+ public Builder withSlot(int slot) {
+ component.slot = slot;
+ return this;
+ }
+
+ public Component build() {
+ ItemMeta itemMeta = component.getItemMeta();
+ if (itemMeta != null) {
+ itemMeta.setLore(lore);
+ component.setItemMeta(itemMeta);
+ }
+ return component;
+ }
+ }
+}
diff --git a/src/main/java/net/epconsortium/cryptomarket/ui/Components.java b/src/main/java/net/epconsortium/cryptomarket/ui/Components.java
new file mode 100644
index 0000000..c7fa401
--- /dev/null
+++ b/src/main/java/net/epconsortium/cryptomarket/ui/Components.java
@@ -0,0 +1,19 @@
+package net.epconsortium.cryptomarket.ui;
+
+import com.cryptomorin.xseries.XMaterial;
+
+public class Components {
+
+ private Components() {
+ }
+
+ public static Component generic(XMaterial material, String displayName, int slot) {
+ return new ComponentImpl(displayName, null, material, slot);
+ }
+
+ public static void addPanels(Frame frame, XMaterial material, int[] slots) {
+ for (int slot : slots) {
+ frame.add(generic(material, " ", slot));
+ }
+ }
+}
diff --git a/src/main/java/net/epconsortium/cryptomarket/ui/Frame.java b/src/main/java/net/epconsortium/cryptomarket/ui/Frame.java
new file mode 100644
index 0000000..5bfc57f
--- /dev/null
+++ b/src/main/java/net/epconsortium/cryptomarket/ui/Frame.java
@@ -0,0 +1,83 @@
+package net.epconsortium.cryptomarket.ui;
+
+import net.epconsortium.cryptomarket.CryptoMarket;
+import net.epconsortium.cryptomarket.util.Configuration;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+public abstract class Frame {
+
+ protected final CryptoMarket plugin;
+ protected final Configuration configuration;
+ private final Frame parent;
+ private final Player viewer;
+ private final Set components = ConcurrentHashMap.newKeySet();
+
+ public Frame(@Nullable Frame parent, @NotNull Player viewer) {
+ this.parent = parent;
+ this.viewer = viewer;
+ plugin = CryptoMarket.getInstance();
+ configuration = new Configuration(plugin);
+ }
+
+ @NotNull
+ public abstract String getTitle();
+
+ @NotNull
+ public Player getViewer() {
+ return viewer;
+ }
+
+ @Nullable
+ public Frame getParent() {
+ return parent;
+ }
+
+ public abstract int getSize();
+
+ public abstract void createComponents();
+
+ @Nullable
+ public Component getComponent(int slot) {
+ for (Component c : getComponents()) {
+ if (c.getSlot() == slot) {
+ return c;
+ }
+ }
+ return null;
+ }
+
+ public void add(@NotNull Component c) {
+ components.add(c);
+ }
+
+ public void clear() {
+ components.clear();
+ }
+
+ @NotNull
+ public Set getComponents() {
+ return components;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other instanceof Frame) {
+ Frame otherFrame = (Frame) other;
+ return getSize() == otherFrame.getSize() && getTitle().equals(otherFrame.getTitle())
+ && getComponents().equals(otherFrame.getComponents());
+ }
+
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return getTitle().hashCode() + Integer.hashCode(getSize()) + getComponents().hashCode();
+ }
+
+}
diff --git a/src/main/java/net/epconsortium/cryptomarket/ui/Helper.java b/src/main/java/net/epconsortium/cryptomarket/ui/Helper.java
deleted file mode 100644
index ef9993b..0000000
--- a/src/main/java/net/epconsortium/cryptomarket/ui/Helper.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package net.epconsortium.cryptomarket.ui;
-
-import java.util.Objects;
-import org.bukkit.event.inventory.InventoryClickEvent;
-
-class Helper {
-
- /**
- * Checks if this is not a regular inventory (like a Chest or something)
- *
- * @param event event
- * @return true if it is a custom inventory
- */
- static boolean isCustomInventory(InventoryClickEvent event) {
- Objects.requireNonNull(event);
-
- return event.getView().getTitle() != null
- && event.getCurrentItem() != null
- && event.getCurrentItem().hasItemMeta()
- && event.getCurrentItem().getItemMeta().hasDisplayName();
- }
-}
diff --git a/src/main/java/net/epconsortium/cryptomarket/ui/InventoryController.java b/src/main/java/net/epconsortium/cryptomarket/ui/InventoryController.java
new file mode 100644
index 0000000..68d0333
--- /dev/null
+++ b/src/main/java/net/epconsortium/cryptomarket/ui/InventoryController.java
@@ -0,0 +1,114 @@
+package net.epconsortium.cryptomarket.ui;
+
+import net.epconsortium.cryptomarket.CryptoMarket;
+import net.epconsortium.cryptomarket.util.Configuration;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.HumanEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.inventory.ClickType;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryCloseEvent;
+import org.bukkit.event.inventory.InventoryType;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+
+public class InventoryController implements Listener {
+ private static InventoryController instance;
+
+ private final Map frames = new HashMap<>();
+ private final Configuration configuration = new Configuration(CryptoMarket.getInstance());
+
+ private InventoryController() {}
+
+ public static InventoryController getInstance() {
+ if (instance == null) {
+ instance = new InventoryController();
+ }
+ return instance;
+ }
+
+ @EventHandler(ignoreCancelled = true)
+ public void onClose(InventoryCloseEvent event) {
+ HumanEntity entity = event.getPlayer();
+ if (!(entity instanceof Player)) {
+ return;
+ }
+
+ frames.remove(entity.getUniqueId());
+ }
+
+ @EventHandler(ignoreCancelled = true)
+ public void onInteract(InventoryClickEvent event) {
+ HumanEntity entity = event.getWhoClicked();
+ if (!(entity instanceof Player)) {
+ return;
+ }
+
+ Frame frame = frames.get(entity.getUniqueId());
+ if (frame == null) {
+ return;
+ }
+
+ event.setCancelled(true);
+
+ if (event.getClickedInventory() == null || event.getClickedInventory().getType() == InventoryType.PLAYER) {
+ return;
+ }
+
+ Component component = frame.getComponent(event.getSlot());
+ if (component == null) {
+ return;
+ }
+
+ ClickType click = event.getClick();
+ Runnable listener = component.getListener(click);
+ if (listener == null) {
+ return;
+ }
+
+ String permission = component.getPermission(click);
+ if (permission != null) {
+ if (!entity.hasPermission(permission)) {
+ entity.sendMessage(configuration.getMessageErrorNoPermission());
+ return;
+ }
+ }
+
+ Bukkit.getScheduler().runTask(CryptoMarket.getInstance(), () -> {
+ ItemStack currentItem = event.getCurrentItem();
+ if (currentItem == null) return;
+
+ ItemMeta itemMeta = currentItem.getItemMeta();
+ Objects.requireNonNull(itemMeta).setLore(Collections.singletonList("..."));
+ currentItem.setItemMeta(itemMeta);
+
+ listener.run();
+ });
+ }
+
+ /**
+ * Registers the frame in the InventoryController
+ * @param frame the frame
+ *
+ * @author RoinujNosde
+ */
+ public void register(@NotNull Frame frame) {
+ frames.put(frame.getViewer().getUniqueId(), frame);
+ }
+
+ /**
+ * Checks if the Player is registered
+ *
+ * @param player the Player
+ * @return if they are registered
+ */
+ public boolean isRegistered(@NotNull Player player) {
+ return frames.containsKey(player.getUniqueId());
+ }
+}
+
diff --git a/src/main/java/net/epconsortium/cryptomarket/ui/InventoryDrawer.java b/src/main/java/net/epconsortium/cryptomarket/ui/InventoryDrawer.java
new file mode 100644
index 0000000..3289de4
--- /dev/null
+++ b/src/main/java/net/epconsortium/cryptomarket/ui/InventoryDrawer.java
@@ -0,0 +1,79 @@
+package net.epconsortium.cryptomarket.ui;
+
+import net.epconsortium.cryptomarket.CryptoMarket;
+import org.bukkit.Bukkit;
+import org.bukkit.inventory.Inventory;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class InventoryDrawer {
+ private static InventoryDrawer instance;
+ private final CryptoMarket plugin = CryptoMarket.getInstance();
+ private final ConcurrentHashMap OPENING = new ConcurrentHashMap<>();
+
+ private InventoryDrawer() {
+ }
+
+ public static InventoryDrawer getInstance() {
+ if (instance == null) {
+ instance = new InventoryDrawer();
+ }
+ return instance;
+ }
+
+ public void open(@Nullable Frame frame) {
+ if (frame == null) {
+ return;
+ }
+ UUID uuid = frame.getViewer().getUniqueId();
+ if (frame.equals(OPENING.get(uuid))) {
+ return;
+ }
+
+ OPENING.put(uuid, frame);
+ Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
+
+ Inventory inventory = prepareInventory(frame);
+
+ if (!frame.equals(OPENING.get(uuid))) {
+ return;
+ }
+ Bukkit.getScheduler().runTask(plugin, () -> {
+ frame.getViewer().openInventory(inventory);
+ InventoryController.getInstance().register(frame);
+ OPENING.remove(uuid);
+ });
+ });
+ }
+
+ @NotNull
+ private Inventory prepareInventory(@NotNull Frame frame) {
+ Inventory inventory = Bukkit.createInventory(frame.getViewer(), frame.getSize(), frame.getTitle());
+ setComponents(inventory, frame);
+ return inventory;
+ }
+
+
+ private void setComponents(@NotNull Inventory inventory, @NotNull Frame frame) {
+ frame.clear();
+ frame.createComponents();
+
+ Set components = frame.getComponents();
+ if (components.isEmpty()) {
+ plugin.getLogger().warning(String.format("Frame %s has no components", frame.getTitle()));
+ return;
+ }
+ for (Component c : frame.getComponents()) {
+ if (c.getSlot() >= frame.getSize()) {
+ continue;
+ }
+ inventory.setItem(c.getSlot(), c.getItem());
+ }
+ }
+
+}
+
diff --git a/src/main/java/net/epconsortium/cryptomarket/ui/Menu.java b/src/main/java/net/epconsortium/cryptomarket/ui/Menu.java
deleted file mode 100644
index ed3fecb..0000000
--- a/src/main/java/net/epconsortium/cryptomarket/ui/Menu.java
+++ /dev/null
@@ -1,350 +0,0 @@
-package net.epconsortium.cryptomarket.ui;
-
-import java.math.BigDecimal;
-
-import com.cryptomorin.xseries.XMaterial;
-import org.bukkit.Bukkit;
-import org.bukkit.Material;
-import org.bukkit.enchantments.Enchantment;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.Inventory;
-import org.bukkit.inventory.ItemFlag;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.meta.ItemMeta;
-
-import java.text.MessageFormat;
-import java.time.LocalDate;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import net.epconsortium.cryptomarket.CryptoMarket;
-import net.epconsortium.cryptomarket.database.dao.Investor;
-import net.epconsortium.cryptomarket.database.dao.InvestorDao;
-import net.epconsortium.cryptomarket.finances.ExchangeRate;
-import net.epconsortium.cryptomarket.finances.ExchangeRates;
-import net.epconsortium.cryptomarket.util.Configuration;
-import net.epconsortium.cryptomarket.util.Formatter;
-import org.bukkit.scheduler.BukkitRunnable;
-
-/**
- * Represents the Main menu
- *
- * @author roinujnosde
- */
-public class Menu {
-
- private final CryptoMarket plugin;
- private final Configuration config;
- private final ExchangeRates rates;
-
- private final Player player;
- private final Inventory inventory;
- private Investor investor;
-
- public Menu(CryptoMarket plugin, Player player) {
- this.plugin = Objects.requireNonNull(plugin);
- this.player = Objects.requireNonNull(player);
- rates = new ExchangeRates(this.plugin);
- config = new Configuration(plugin);
- inventory = Bukkit.createInventory(null, 54, config.getMenuName());
- }
-
- /**
- * Opens the Menu
- */
- @SuppressWarnings("LocalVariableHidesMemberVariable")
- public void open() {
- new InvestorDao(plugin).getInvestor(player, (investor) -> {
- new BukkitRunnable() {
- @Override
- public void run() {
- if (!player.isOnline()) {
- return;
- }
- if (investor == null) {
- player.sendMessage(config.getMessageErrorConnectingToDatabase());
- return;
- }
- Menu.this.investor = investor;
- configureInventory();
- player.openInventory(inventory);
- }
- }.runTask(plugin);
- });
- }
-
- /**
- * Configures the inventory
- */
- private void configureInventory() {
- ItemStack coins = configureItemCoins();
- ItemStack wallet = configureItemWallet();
- ItemStack ranking = configureItemRanking();
- ItemStack profit = configureProfitItem();
- ItemStack calendar = configureGenericItem(XMaterial.FILLED_MAP,
- config.getButtonCalendarName());
- ItemStack update = configureGenericItem(XMaterial.STRUCTURE_VOID,
- config.getButtonUpdateName());
- ItemStack blackGlass = configureGenericItem(
- XMaterial.BLACK_STAINED_GLASS_PANE, " ");
- ItemStack grayGlass = configureGenericItem(XMaterial.GRAY_STAINED_GLASS_PANE, " ");
-
- setButtonsPositions(coins, wallet, profit, calendar, update, blackGlass,
- grayGlass, ranking);
- }
-
- /**
- * Configures the Profit item
- *
- * @return the profit item
- */
- private ItemStack configureProfitItem() {
- ItemStack profit = XMaterial.LIME_DYE.parseItem(true);
- if (profit == null) {
- profit = new ItemStack(Material.STONE);
- }
- ItemMeta profitMeta = profit.getItemMeta();
- profitMeta.setDisplayName(config.getButtonProfitName());
-
- List lore = configureProfitItemLore();
-
- profitMeta.setLore(lore);
- profit.setItemMeta(profitMeta);
-
- return profit;
- }
-
- /**
- * Configures the lore of Profit item
- *
- */
- private List configureProfitItemLore() {
- List coinLines = new ArrayList<>();
- String coinLine = config.getButtonProfitCoinLine();
- ExchangeRate rate = rates.getExchangeRate(LocalDate.now());
- if (rate == null) {
- rate = new ExchangeRate();
- }
- for (String coin : config.getCoins()) {
- BigDecimal profitD = investor.getBalance(coin).getProfitPercentage(
- rate.getCoinValue(coin));
- String color = config.getButtonProfitNeuterColor();
- if (profitD.compareTo(BigDecimal.ZERO) > 0) {
- color = config.getButtonProfitPositiveColor();
- } else if (profitD.compareTo(BigDecimal.ZERO) < 0) {
- color = config.getButtonProfitNegativeColor();
- }
-
- coinLines.add(MessageFormat.format(coinLine, coin, color,
- Formatter.formatServerCurrency(profitD)));
- }
- List lore = config.getButtonProfitLore();
- int indexPlaceholder = 0;
- String tempLine = "{0}";
- for (int i = 0; i < lore.size(); i++) {
- String l = lore.get(i);
- if (l.contains("{0}")) {
- indexPlaceholder = i;
- tempLine = l;
- }
- }
- lore.addAll(indexPlaceholder, coinLines);
- lore.remove(tempLine);
- return lore;
- }
-
- /**
- * Configures an item with a name and material only
- *
- * @param material material
- * @param name name
- * @return item
- */
- private ItemStack configureGenericItem(XMaterial material, String name) {
- ItemStack stack = material.parseItem(true);
- if (stack == null) {
- stack = new ItemStack(Material.STONE);
- }
- ItemMeta meta = stack.getItemMeta();
- meta.setDisplayName(name);
- stack.setItemMeta(meta);
-
- return stack;
- }
-
- /**
- * Configures the Wallet item
- *
- * @return Wallet item
- */
- private ItemStack configureItemWallet() {
- ItemStack wallet = XMaterial.BOOK.parseItem(true);
- if (wallet == null) {
- wallet = new ItemStack(Material.STONE);
- }
- ItemMeta meta = wallet.getItemMeta();
- meta.setDisplayName(config.getButtonWalletName());
- configureItemWalletLore(meta);
- wallet.setItemMeta(meta);
- return wallet;
- }
-
- /**
- * Configures the Coins item
- *
- * @return Coins item
- */
- private ItemStack configureItemCoins() {
- ItemStack coins = XMaterial.SUNFLOWER.parseItem(true);
- if (coins == null) {
- coins = new ItemStack(Material.STONE);
- }
- ItemMeta meta = coins.getItemMeta();
- meta.addEnchant(Enchantment.ARROW_DAMAGE, 1, false);
- meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
- meta.setDisplayName(config.getButtonCoinsName());
-
- configureItemCoinsLore(meta);
- coins.setItemMeta(meta);
- return coins;
- }
-
- /**
- * Configures the lore of Wallet item
- *
- * @param meta Wallet meta
- */
- private void configureItemWalletLore(ItemMeta meta) {
- List lore = config.getButtonWalletLore();
- double vaultBalance = plugin.getEconomy().getBalance(player);
-
- int balanceIndex = 0;
- String tempBalance = "{0}";
- int coinsIndex = 1;
- String coinsLineTemp = "{1}";
- for (int i = 0; i < lore.size(); i++) {
- String l = lore.get(i);
- if (l.contains("{0}")) {
- balanceIndex = i;
- tempBalance = l;
- }
- if (l.contains("{1}")) {
- coinsIndex = i;
- coinsLineTemp = l;
- }
- }
- lore.add(balanceIndex, MessageFormat.format(tempBalance,
- Formatter.formatServerCurrency(vaultBalance)));
- lore.remove(tempBalance);
-
- List coinsTemp = new ArrayList<>();
- String coinLine = config.getButtonWalletCoinLine();
- for (String coin : config.getCoins()) {
- String format = MessageFormat.format(coinLine, coin,
- Formatter.formatCryptocoin(investor.getBalance(coin)
- .getValue()));
- coinsTemp.add(format);
- }
-
- lore.addAll(coinsIndex, coinsTemp);
- lore.remove(coinsLineTemp);
-
- meta.setLore(lore);
- }
-
- /**
- * Configures the lore of the Coins item
- *
- * @param meta Coins meta
- */
- private void configureItemCoinsLore(ItemMeta meta) {
- ExchangeRate er = rates.getExchangeRate(LocalDate.now());
- List lore = config.getButtonCoinsLore();
- if (er == null) {
- er = new ExchangeRate();
- }
-
- //Configuring the line of values of the item
- List coinsLine = new ArrayList<>();
- for (String coin : config.getCoins()) {
- BigDecimal coinValue = er.getCoinValue(coin);
- String format;
- if (coinValue.equals(new BigDecimal(-1))) {
- format = MessageFormat.format(config.getButtonCoinsCoinLine(),
- coin, config.getButtonCoinsError());
- } else {
- format = MessageFormat.format(config.getButtonCoinsCoinLine(),
- coin, Formatter.formatServerCurrency(coinValue));
- }
- coinsLine.add(format);
- }
-
- //Adding the line of values to the lore
- int index = 0;
- String remove = null;
- for (int i = 0; i < lore.size(); i++) {
- String s = lore.get(i);
- if (s.contains("{0}")) {
- index = i;
- remove = s;
- }
- }
- lore.addAll(index, coinsLine);
- if (remove != null) {
- lore.remove(remove);
- }
- meta.setLore(lore);
- }
-
- /**
- * Configures the Ranking item
- *
- * @return Ranking item
- */
- private ItemStack configureItemRanking() {
- ItemStack ranking = XMaterial.PLAYER_HEAD.parseItem(true);
- if (ranking == null) {
- ranking = new ItemStack(Material.STONE);
- }
- ItemMeta rankingMeta = ranking.getItemMeta();
- rankingMeta.setDisplayName(config.getButtonRankingName());
- ranking.setItemMeta(rankingMeta);
- return ranking;
- }
-
- /**
- * Sets the Buttons on the inventory
- *
- * @param coins
- * @param wallet
- * @param profit
- * @param calendar
- * @param update
- * @param blackGlass
- * @param greyGlass
- * @param ranking
- */
- private void setButtonsPositions(ItemStack coins, ItemStack wallet,
- ItemStack profit, ItemStack calendar, ItemStack update,
- ItemStack blackGlass, ItemStack greyGlass, ItemStack ranking) {
-
- int[] grey = {1, 2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 24, 26, 22, 27,
- 29, 47, 48, 51, 50, 30, 36, 38, 39, 40, 41, 42, 44, 32, 33, 35};
- for (int i : grey) {
- inventory.setItem(i, greyGlass);
- }
-
- int[] black = {28, 0, 3, 5, 8, 10, 16, 21, 23, 34, 45, 46, 49, 52, 52,
- 31};
- for (int i : black) {
- inventory.setItem(i, blackGlass);
- }
-
- inventory.setItem(37, ranking);
- inventory.setItem(12, coins);
- inventory.setItem(14, wallet);
- inventory.setItem(19, profit);
- inventory.setItem(25, calendar);
- inventory.setItem(43, update);
- }
-}
diff --git a/src/main/java/net/epconsortium/cryptomarket/ui/MenuListener.java b/src/main/java/net/epconsortium/cryptomarket/ui/MenuListener.java
index a2c407e..bbfb955 100644
--- a/src/main/java/net/epconsortium/cryptomarket/ui/MenuListener.java
+++ b/src/main/java/net/epconsortium/cryptomarket/ui/MenuListener.java
@@ -4,6 +4,7 @@
import net.epconsortium.cryptomarket.conversation.NegotiationConversation;
import net.epconsortium.cryptomarket.finances.ExchangeRates;
import net.epconsortium.cryptomarket.finances.Negotiation;
+import net.epconsortium.cryptomarket.ui.frames.RankingFrame;
import net.epconsortium.cryptomarket.util.Configuration;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -12,6 +13,7 @@
import java.text.MessageFormat;
import java.util.Objects;
+import java.util.concurrent.ExecutionException;
/**
* Class used to listen to clicks on the Menu menu and process them
@@ -32,10 +34,6 @@ public MenuListener(CryptoMarket plugin) {
public void onInventoryClick(InventoryClickEvent event) {
Player player = (Player) event.getWhoClicked();
- if (!Helper.isCustomInventory(event)) {
- return;
- }
-
if (event.getView().getTitle().equals(config.getMenuName())) {
event.setCancelled(true);
@@ -59,8 +57,8 @@ private boolean processUpdateButton(InventoryClickEvent event, Player player) {
player.closeInventory();
return true;
}
- if (ExchangeRates.errorOcurred()) {
- ExchangeRates er = new ExchangeRates(plugin);
+ if (ExchangeRates.errorOccurred()) {
+ ExchangeRates er = plugin.getExchangeRates();
er.updateAll();
player.closeInventory();
@@ -112,8 +110,13 @@ private boolean processRankingButton(InventoryClickEvent event, Player player) {
player.closeInventory();
return true;
}
- Ranking ranking = new Ranking(plugin, player);
- ranking.open();
+ //todo trocar parent para o MenuFrame
+ try {
+ InventoryDrawer.getInstance().open(new RankingFrame(null, player));
+ } catch (ExecutionException | InterruptedException e) {
+ player.sendMessage(config.getMessageErrorAccessingRankingData());
+ e.printStackTrace();
+ }
return true;
}
return false;
diff --git a/src/main/java/net/epconsortium/cryptomarket/ui/Ranking.java b/src/main/java/net/epconsortium/cryptomarket/ui/Ranking.java
deleted file mode 100644
index 6cc7f59..0000000
--- a/src/main/java/net/epconsortium/cryptomarket/ui/Ranking.java
+++ /dev/null
@@ -1,247 +0,0 @@
-package net.epconsortium.cryptomarket.ui;
-
-import com.cryptomorin.xseries.XMaterial;
-import net.epconsortium.cryptomarket.CryptoMarket;
-import net.epconsortium.cryptomarket.database.dao.Investor;
-import net.epconsortium.cryptomarket.finances.Economy;
-import net.epconsortium.cryptomarket.util.Configuration;
-import net.epconsortium.cryptomarket.util.Formatter;
-import org.bukkit.Bukkit;
-import org.bukkit.Material;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.Inventory;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.meta.ItemMeta;
-import org.bukkit.inventory.meta.SkullMeta;
-import org.bukkit.scheduler.BukkitRunnable;
-
-import java.math.BigDecimal;
-import java.text.MessageFormat;
-import java.time.format.DateTimeFormatter;
-import java.time.format.FormatStyle;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-import static net.epconsortium.cryptomarket.CryptoMarket.debug;
-import static org.bukkit.Material.STONE;
-
-/**
- * Represents the Ranking menu
- *
- * @author roinujnosde
- */
-public class Ranking {
-
- private final Player player;
- private final CryptoMarket plugin;
- private final Inventory inventory;
- private final Configuration config;
- private List richersList;
- private double totalInvestments;
-
- public Ranking(CryptoMarket plugin, Player player) {
- this.player = Objects.requireNonNull(player);
- this.plugin = Objects.requireNonNull(plugin);
-
- config = new Configuration(plugin);
- inventory = Bukkit.createInventory(null, 45,
- config.getRankingMenuName());
- }
-
- /**
- * Open the Ranking menu
- */
- public void open() {
- Economy eco = new Economy(plugin, "");
- eco.getRichestInvestors(5, (investors) -> {
- eco.getTotalInvestments(total -> {
- new BukkitRunnable() {
- @Override
- public void run() {
- if (player.isOnline()) {
- if (investors == null || total == -1) {
- player.sendMessage(config
- .getMessageErrorAccessingRankingData());
- return;
- }
- debug("Ranking: investors size: " + investors.size());
- richersList = investors;
- totalInvestments = total;
- configureInventory();
- player.openInventory(inventory);
- }
- }
- }.runTask(plugin);
- });
- });
- }
-
- /**
- * Configures the Richer on the index
- *
- * @param index index
- * @return the Richer item
- */
- private ItemStack getRicher(int index) {
- Economy econ = new Economy(plugin, "");
-
- ItemStack head = XMaterial.PLAYER_HEAD.parseItem(true);
- ItemMeta meta = Objects.requireNonNull(head).getItemMeta();
-
- int rank = index + 1;
-
- if (index >= richersList.size()) {
- meta.setDisplayName(MessageFormat.format(
- config.getRankingMenuNoRicherLore(), rank));
- head.setItemMeta(meta);
- } else {
- Investor richer = richersList.get(index);
- SkullMeta skullMeta = (SkullMeta) head.getItemMeta();
- skullMeta.setOwner(richer.getPlayer().getName());
- skullMeta.setDisplayName(MessageFormat.format(
- config.getRankingMenuRicherItemName(), rank,
- richer.getPlayer().getName()));
-
- List lore1 = config.getRankingMenuRicherItemLore();
- ArrayList lore2 = new ArrayList<>();
- BigDecimal patrimony = econ.getConvertedPatrimony(richer);
- double percentage = 0;
- if (totalInvestments > 0) {
- percentage = (patrimony.doubleValue() / totalInvestments) * 100;
- }
- for (String s : lore1) {
- lore2.add(MessageFormat.format(s,
- Formatter.formatServerCurrency(patrimony),
- Formatter.formatPercentage(percentage)));
- }
-
- skullMeta.setLore(lore2);
- head.setItemMeta(skullMeta);
- }
-
- return head;
- }
-
- /**
- * Configures the inventory
- */
- private void configureInventory() {
- List richers = new ArrayList<>();
- for (int i = 0; i < 5; i++) {
- richers.add(getRicher(i));
- }
-
- ItemStack total = configureTotalInvestmentsItem();
- ItemStack lastUpdated = configureLastUpdated();
- ItemStack back = configureBackButton();
- ItemStack black = configureGenericItem(XMaterial.BLACK_STAINED_GLASS_PANE, " ");
- ItemStack grey = configureGenericItem(XMaterial.GRAY_STAINED_GLASS_PANE, " ");
-
- setItemsPositions(black, grey, back, richers, total, lastUpdated);
- }
-
- private ItemStack configureLastUpdated() {
- ItemStack lastUpdated = XMaterial.CLOCK.parseItem(true);
- ItemMeta lastUpdatedMeta = Objects.requireNonNull(lastUpdated).getItemMeta();
- lastUpdatedMeta.setDisplayName(config.getRankingMenuLastUpdatedItemName());
- List lastUpdateLore = new ArrayList<>();
- for (String s : config.getRankingMenuLastUpdatedItemLore()) {
- lastUpdateLore.add(MessageFormat.format(s,
- Economy.getRichersLastUpdate().format(DateTimeFormatter
- .ofLocalizedDateTime(FormatStyle.SHORT))));
- }
- lastUpdatedMeta.setLore(lastUpdateLore);
- lastUpdated.setItemMeta(lastUpdatedMeta);
- return lastUpdated;
- }
-
- private ItemStack configureTotalInvestmentsItem() {
- ItemStack total = XMaterial.SUNFLOWER.parseItem(true);
- if (total == null) {
- total = new ItemStack(STONE);
- }
- ItemMeta totalMeta = total.getItemMeta();
- totalMeta.setDisplayName(config.getRankingMenuTotalInvestmentsItemName());
- List totalLore = new ArrayList<>();
- for (String s : config.getRankingMenuTotalInvestmentsItemLore()) {
- totalLore.add(MessageFormat.format(s,
- Formatter.formatServerCurrency(totalInvestments)));
- }
- totalMeta.setLore(totalLore);
- total.setItemMeta(totalMeta);
-
- return total;
- }
-
- /**
- * Configures a generic item
- *
- * @param material
- * @param name
- * @return the item
- */
- private ItemStack configureGenericItem(XMaterial material, String name) {
- ItemStack stack = material.parseItem(true);
- if (stack == null) {
- stack = new ItemStack(STONE);
- }
- ItemMeta meta = stack.getItemMeta();
- meta.setDisplayName(name);
- stack.setItemMeta(meta);
-
- return stack;
- }
-
- /**
- * Configures the Back button
- *
- * @return the back button
- */
- private ItemStack configureBackButton() {
- ItemStack back = XMaterial.ARROW.parseItem(true);
- if (back == null) {
- back = new ItemStack(STONE);
- }
- ItemMeta meta = back.getItemMeta();
- meta.setDisplayName(config.getRankingMenuBackButton());
- back.setItemMeta(meta);
- return back;
- }
-
- /**
- * Sets the items' positions
- *
- * @param blackGlass
- * @param grayGlass
- * @param back
- * @param richers
- */
- private void setItemsPositions(ItemStack blackGlass, ItemStack grayGlass,
- ItemStack back, List richers, ItemStack total,
- ItemStack lastUpdated) {
- //black glasses
- int black[] = {0, 3, 5, 8, 9, 11, 12, 14, 15, 17, 18, 19, 25, 26, 27,
- 29, 30, 32, 33, 35, 41, 39, 44};
- for (int b : black) {
- inventory.setItem(b, blackGlass);
- }
- //grey glasses
- int grey[] = {1, 2, 6, 7, 10, 13, 16, 28, 31, 34, 37, 40, 42, 43};
- for (int g : grey) {
- inventory.setItem(g, grayGlass);
- }
- //back button
- inventory.setItem(4, back);
- //total investments
- inventory.setItem(36, total);
- //last updated
- inventory.setItem(38, lastUpdated);
- //richers
- int index = 20;
- for (ItemStack richer : richers) {
- inventory.setItem(index, richer);
- index++;
- }
- }
-}
diff --git a/src/main/java/net/epconsortium/cryptomarket/ui/RankingListener.java b/src/main/java/net/epconsortium/cryptomarket/ui/RankingListener.java
deleted file mode 100644
index 5acd40d..0000000
--- a/src/main/java/net/epconsortium/cryptomarket/ui/RankingListener.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package net.epconsortium.cryptomarket.ui;
-
-import java.util.Objects;
-import org.bukkit.entity.Player;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
-import org.bukkit.event.inventory.InventoryClickEvent;
-
-import net.epconsortium.cryptomarket.CryptoMarket;
-import net.epconsortium.cryptomarket.util.Configuration;
-
-/**
- * Class used to listen to clicks on the Ranking menu and process them
- *
- * @author roinujnosde
- */
-public class RankingListener implements Listener {
-
- private final CryptoMarket plugin;
- private final Configuration config;
-
- public RankingListener(CryptoMarket plugin) {
- this.plugin = Objects.requireNonNull(plugin);
- config = new Configuration(plugin);
- }
-
- @EventHandler
- public void onInventoryClickEvent(InventoryClickEvent event) {
- Player player = (Player) event.getWhoClicked();
-
- if (!Helper.isCustomInventory(event)) {
- return;
- }
-
- if (event.getView().getTitle().equals(config.getRankingMenuName())) {
- event.setCancelled(true);
- processBackButton(event, player);
- }
- }
-
- private boolean processBackButton(InventoryClickEvent event, Player player) {
- if (event.getCurrentItem().getItemMeta().getDisplayName().equals(
- config.getRankingMenuBackButton())) {
- player.closeInventory();
- Menu menu = new Menu(plugin, player);
- menu.open();
- return true;
- }
-
- return false;
- }
-}
diff --git a/src/main/java/net/epconsortium/cryptomarket/ui/frames/MenuFrame.java b/src/main/java/net/epconsortium/cryptomarket/ui/frames/MenuFrame.java
new file mode 100644
index 0000000..8fe6631
--- /dev/null
+++ b/src/main/java/net/epconsortium/cryptomarket/ui/frames/MenuFrame.java
@@ -0,0 +1,212 @@
+package net.epconsortium.cryptomarket.ui.frames;
+
+import com.cryptomorin.xseries.XMaterial;
+import net.epconsortium.cryptomarket.database.dao.Investor;
+import net.epconsortium.cryptomarket.finances.ExchangeRate;
+import net.epconsortium.cryptomarket.finances.ExchangeRates;
+import net.epconsortium.cryptomarket.ui.Component;
+import net.epconsortium.cryptomarket.ui.ComponentImpl;
+import net.epconsortium.cryptomarket.ui.ComponentImpl.Builder;
+import net.epconsortium.cryptomarket.ui.Frame;
+import net.epconsortium.cryptomarket.util.Formatter;
+import org.bukkit.Material;
+import org.bukkit.enchantments.Enchantment;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemFlag;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.math.BigDecimal;
+import java.text.MessageFormat;
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.cryptomorin.xseries.XMaterial.BLACK_STAINED_GLASS_PANE;
+import static com.cryptomorin.xseries.XMaterial.GRAY_STAINED_GLASS_PANE;
+import static net.epconsortium.cryptomarket.ui.Components.addPanels;
+import static net.epconsortium.cryptomarket.ui.Components.generic;
+
+public class MenuFrame extends Frame {
+ private final Investor investor;
+ private final ExchangeRates rates;
+
+ public MenuFrame(@Nullable Frame parent, @NotNull Player viewer) {
+ super(parent, viewer);
+ investor = plugin.getInvestorDao().getInvestor(viewer);
+ rates = plugin.getExchangeRates();
+ }
+
+ @Override
+ public @NotNull String getTitle() {
+ return configuration.getMenuName();
+ }
+
+ @Override
+ public int getSize() {
+ return 54;
+ }
+
+ @Override
+ public void createComponents() {
+ add(profit());
+ add(coins());
+ add(wallet());
+ add(ranking());
+ add(generic(XMaterial.FILLED_MAP, configuration.getButtonCalendarName(), 25));
+ add(generic(XMaterial.STRUCTURE_VOID, configuration.getButtonUpdateName(), 43));
+ addGlasses();
+ }
+
+ private void addGlasses() {
+ int[] blackSlots = {28, 0, 3, 5, 8, 10, 16, 21, 23, 34, 45, 46, 49, 52, 52, 31};
+ addPanels(this, BLACK_STAINED_GLASS_PANE, blackSlots);
+
+ int[] greySlots = {1, 2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 24, 26, 22, 27, 29, 47, 48, 51, 50, 30, 36, 38, 39,
+ 40, 41, 42, 44, 32, 33, 35};
+ addPanels(this, GRAY_STAINED_GLASS_PANE, greySlots);
+ }
+
+ private Component profit() {
+ return new Builder(XMaterial.LIME_DYE).withDisplayName(configuration.getButtonProfitName())
+ .withLore(getProfitItemLore()).withSlot(19).build();
+ }
+
+ private List getProfitItemLore() {
+ List coinLines = new ArrayList<>();
+ String coinLine = configuration.getButtonProfitCoinLine();
+ ExchangeRate rate = rates.getExchangeRate(LocalDate.now());
+ if (rate == null) {
+ rate = new ExchangeRate();
+ }
+ for (String coin : configuration.getCoins()) {
+ BigDecimal profitD = investor.getBalance(coin).getProfitPercentage(
+ rate.getCoinValue(coin));
+ String color = configuration.getButtonProfitNeuterColor();
+ if (profitD.compareTo(BigDecimal.ZERO) > 0) {
+ color = configuration.getButtonProfitPositiveColor();
+ } else if (profitD.compareTo(BigDecimal.ZERO) < 0) {
+ color = configuration.getButtonProfitNegativeColor();
+ }
+
+ coinLines.add(MessageFormat.format(coinLine, coin, color,
+ Formatter.formatServerCurrency(profitD)));
+ }
+ List lore = configuration.getButtonProfitLore();
+ int indexPlaceholder = 0;
+ String tempLine = "{0}";
+ for (int i = 0; i < lore.size(); i++) {
+ String l = lore.get(i);
+ if (l.contains("{0}")) {
+ indexPlaceholder = i;
+ tempLine = l;
+ }
+ }
+ lore.addAll(indexPlaceholder, coinLines);
+ lore.remove(tempLine);
+ return lore;
+ }
+
+ private Component wallet() {
+ return new Builder(XMaterial.BOOK).withDisplayName(configuration.getButtonWalletName())
+ .withLore(getWalletLore()).withSlot(14).build();
+ }
+
+ private Component coins() {
+ ItemStack coins = XMaterial.SUNFLOWER.parseItem(true);
+ if (coins == null) {
+ coins = new ItemStack(Material.STONE);
+ }
+
+ ItemMeta meta = coins.getItemMeta();
+ meta.addEnchant(Enchantment.ARROW_DAMAGE, 1, false);
+ meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
+ meta.setDisplayName(configuration.getButtonCoinsName());
+
+ coins.setItemMeta(meta);
+ return new ComponentImpl(configuration.getButtonCoinsName(), getCoinsLore(), coins, 12);
+ }
+
+ private List getWalletLore() {
+ List lore = configuration.getButtonWalletLore();
+ double vaultBalance = plugin.getVaultEconomy().getBalance(getViewer());
+
+ int balanceIndex = 0;
+ String tempBalance = "{0}";
+ int coinsIndex = 1;
+ String coinsLineTemp = "{1}";
+ for (int i = 0; i < lore.size(); i++) {
+ String l = lore.get(i);
+ if (l.contains("{0}")) {
+ balanceIndex = i;
+ tempBalance = l;
+ }
+ if (l.contains("{1}")) {
+ coinsIndex = i;
+ coinsLineTemp = l;
+ }
+ }
+ lore.add(balanceIndex, MessageFormat.format(tempBalance,
+ Formatter.formatServerCurrency(vaultBalance)));
+ lore.remove(tempBalance);
+
+ List coinsTemp = new ArrayList<>();
+ String coinLine = configuration.getButtonWalletCoinLine();
+ for (String coin : configuration.getCoins()) {
+ String format = MessageFormat.format(coinLine, coin, Formatter.formatCryptocoin(investor.getBalance(coin)
+ .getValue()));
+ coinsTemp.add(format);
+ }
+
+ lore.addAll(coinsIndex, coinsTemp);
+ lore.remove(coinsLineTemp);
+
+ return lore;
+ }
+
+ private List getCoinsLore() {
+ ExchangeRate er = rates.getExchangeRate(LocalDate.now());
+ List lore = configuration.getButtonCoinsLore();
+ if (er == null) {
+ er = new ExchangeRate();
+ }
+
+ //Configuring the line of values of the item
+ List coinsLine = new ArrayList<>();
+ for (String coin : configuration.getCoins()) {
+ BigDecimal coinValue = er.getCoinValue(coin);
+ String format;
+ if (coinValue.equals(new BigDecimal(-1))) {
+ format = MessageFormat.format(configuration.getButtonCoinsCoinLine(), coin,
+ configuration.getButtonCoinsError());
+ } else {
+ format = MessageFormat.format(configuration.getButtonCoinsCoinLine(), coin,
+ Formatter.formatServerCurrency(coinValue));
+ }
+ coinsLine.add(format);
+ }
+
+ //Adding the line of values to the lore
+ int index = 0; // FIXME: 16/05/2021 Duplicate code
+ String remove = null;
+ for (int i = 0; i < lore.size(); i++) {
+ String s = lore.get(i);
+ if (s.contains("{0}")) {
+ index = i;
+ remove = s;
+ }
+ }
+ lore.addAll(index, coinsLine);
+ if (remove != null) {
+ lore.remove(remove);
+ }
+ return lore;
+ }
+
+ private Component ranking() {
+ return new Builder(XMaterial.PLAYER_HEAD).withDisplayName(configuration.getButtonRankingName()).withSlot(37)
+ .build();
+ }
+}
diff --git a/src/main/java/net/epconsortium/cryptomarket/ui/frames/RankingFrame.java b/src/main/java/net/epconsortium/cryptomarket/ui/frames/RankingFrame.java
new file mode 100644
index 0000000..6eb4360
--- /dev/null
+++ b/src/main/java/net/epconsortium/cryptomarket/ui/frames/RankingFrame.java
@@ -0,0 +1,143 @@
+package net.epconsortium.cryptomarket.ui.frames;
+
+import com.cryptomorin.xseries.XMaterial;
+import net.epconsortium.cryptomarket.CryptoMarket;
+import net.epconsortium.cryptomarket.database.dao.Investor;
+import net.epconsortium.cryptomarket.finances.Economy;
+import net.epconsortium.cryptomarket.finances.ExchangeRate;
+import net.epconsortium.cryptomarket.ui.Component;
+import net.epconsortium.cryptomarket.ui.ComponentImpl;
+import net.epconsortium.cryptomarket.ui.Frame;
+import net.epconsortium.cryptomarket.util.Configuration;
+import net.epconsortium.cryptomarket.util.Formatter;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.inventory.meta.SkullMeta;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.math.BigDecimal;
+import java.text.MessageFormat;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.time.format.FormatStyle;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.ExecutionException;
+
+import static com.cryptomorin.xseries.XMaterial.*;
+import static net.epconsortium.cryptomarket.ui.Components.addPanels;
+
+public class RankingFrame extends Frame {
+ private final CryptoMarket plugin = CryptoMarket.getInstance();
+
+ private final Economy econ;
+ private final List richersList;
+ private final double totalInvestments;
+ private final Configuration config;
+
+ public RankingFrame(@Nullable Frame parent, @NotNull Player viewer) throws ExecutionException, InterruptedException {
+ super(parent, viewer);
+ config = new Configuration(plugin);
+ econ = plugin.getEconomy();
+ richersList = econ.getTopInvestors(5);
+ totalInvestments = econ.getTotalInvestments();
+ }
+
+ @Override
+ public @NotNull String getTitle() {
+ return configuration.getRankingMenuName();
+ }
+
+ @Override
+ public int getSize() {
+ return 45;
+ }
+
+ @Override
+ public void createComponents() {
+ addGlasses();
+ add(backButton());
+ add(totalInvestments());
+ add(lastUpdated());
+ for (int i = 0; i < 5; i++) {
+ add(richer(i, i + 20));
+ }
+ }
+
+ /**
+ * Configures the Richer on the index
+ *
+ * @param index index
+ * @return the Richer item
+ */
+ private Component richer(int index, int slot) {
+ ItemStack head = XMaterial.PLAYER_HEAD.parseItem(true);
+ ItemMeta meta = Objects.requireNonNull(head).getItemMeta();
+ int rank = index + 1;
+
+ String displayName;
+ ArrayList lore = new ArrayList<>();
+ if (index >= richersList.size()) {
+ displayName = MessageFormat.format(config.getRankingMenuNoRicherLore(), rank);
+ head.setItemMeta(meta);
+ } else {
+ Investor richer = richersList.get(index);
+ SkullMeta skullMeta = (SkullMeta) head.getItemMeta();
+ skullMeta.setOwner(richer.getPlayer().getName());
+ displayName = MessageFormat.format(config.getRankingMenuRicherItemName(), rank, richer.getPlayer().getName());
+
+ List configLore = config.getRankingMenuRicherItemLore();
+ ExchangeRate exchangeRate = plugin.getExchangeRates().getExchangeRate(LocalDate.now());
+ BigDecimal patrimony = richer.getConvertedPatrimony(exchangeRate);
+ double percentage = 0;
+ if (totalInvestments > 0) {
+ percentage = (patrimony.doubleValue() / totalInvestments) * 100;
+ }
+ for (String s : configLore) {
+ lore.add(MessageFormat.format(s, Formatter.formatServerCurrency(patrimony),
+ Formatter.formatPercentage(percentage)));
+ }
+ head.setItemMeta(skullMeta);
+ }
+
+ return new ComponentImpl(displayName, lore, head, slot);
+ }
+
+ private Component lastUpdated() {
+ List lastUpdateLore = new ArrayList<>();
+ for (String s : config.getRankingMenuLastUpdatedItemLore()) {
+ lastUpdateLore.add(MessageFormat.format(s,
+ econ.getRichersLastUpdate().format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT))));
+ }
+ return new ComponentImpl(config.getRankingMenuLastUpdatedItemName(), lastUpdateLore, CLOCK, 38);
+ }
+
+ private Component totalInvestments() {
+ List totalLore = new ArrayList<>();
+ for (String s : config.getRankingMenuTotalInvestmentsItemLore()) {
+ totalLore.add(MessageFormat.format(s, Formatter.formatServerCurrency(totalInvestments)));
+ }
+
+ return new ComponentImpl(config.getRankingMenuTotalInvestmentsItemName(), totalLore, XMaterial.SUNFLOWER, 36);
+ }
+
+ /**
+ * Configures the Back button
+ *
+ * @return the back button
+ */
+ private Component backButton() {
+ return new ComponentImpl(config.getRankingMenuBackButton(), null, XMaterial.ARROW, 4);
+ }
+
+ private void addGlasses() {
+ int[] blackSlots = {0, 3, 5, 8, 9, 11, 12, 14, 15, 17, 18, 19, 25, 26, 27, 29, 30, 32, 33, 35, 41, 39, 44};
+ addPanels(this, BLACK_STAINED_GLASS_PANE, blackSlots);
+
+ int[] greySlots = {1, 2, 6, 7, 10, 13, 16, 28, 31, 34, 37, 40, 42, 43};
+ addPanels(this, GRAY_STAINED_GLASS_PANE, greySlots);
+ }
+}
diff --git a/src/main/java/net/epconsortium/cryptomarket/util/Configuration.java b/src/main/java/net/epconsortium/cryptomarket/util/Configuration.java
index a9d4e1f..0b30586 100644
--- a/src/main/java/net/epconsortium/cryptomarket/util/Configuration.java
+++ b/src/main/java/net/epconsortium/cryptomarket/util/Configuration.java
@@ -145,12 +145,12 @@ public long getIntervalExchangeRatesUpdateInMillis() {
}
/**
- * Returns the richers update interval in milliseconds
+ * Returns the richers update interval in ticks
*
* @return the interval
*/
- public long getIntervalRichersUpdateInMillis() {
- return getConfig().getInt("richers-update-interval", 15) * 60 * 1000;
+ public long getIntervalRichersUpdateInTicks() {
+ return getConfig().getLong("richers-update-interval", 15) * 60 * 20;
}
/**
@@ -531,7 +531,7 @@ public String getButtonProfitName() {
* @return button name
*/
public String getButtonCalendarName() {
- return getColoredString("menu.item.calendar", "Calendar");
+ return getColoredString("menu.items.calendar", "Calendar");
}
/**
diff --git a/src/main/java/net/epconsortium/cryptomarket/util/Logger.java b/src/main/java/net/epconsortium/cryptomarket/util/Logger.java
index c87d241..ced2322 100644
--- a/src/main/java/net/epconsortium/cryptomarket/util/Logger.java
+++ b/src/main/java/net/epconsortium/cryptomarket/util/Logger.java
@@ -15,7 +15,7 @@
import org.bukkit.scheduler.BukkitRunnable;
/**
- * This class logs the negociations to a file
+ * This class logs the negotiations to a file
*
* @author roinujnosde
*/
@@ -27,10 +27,8 @@ public class Logger {
public Logger(CryptoMarket plugin) {
this.plugin = Objects.requireNonNull(plugin);
- logsFolder = new File(plugin.getDataFolder() + File.separator
- + "logs");
- file = new File(logsFolder,
- LocalDate.now() + ".txt");
+ logsFolder = new File(plugin.getDataFolder() + File.separator + "logs");
+ file = new File(logsFolder, LocalDate.now() + ".txt");
}
/**
@@ -42,8 +40,7 @@ public Logger(CryptoMarket plugin) {
* @param coin
* @param vaultValue
*/
- public void log(Investor investor, Negotiation negotiation,
- BigDecimal cryptoValue, String coin, double vaultValue) {
+ public void log(Investor investor, Negotiation negotiation, BigDecimal cryptoValue, String coin, double vaultValue) {
new BukkitRunnable() {
@Override
public void run() {
@@ -63,7 +60,7 @@ public void run() {
writer.flush();
}
} catch (IOException ex) {
- CryptoMarket.warn("Error logging a negociation to file!");
+ CryptoMarket.warn("Error logging a negotiation to file!");
ex.printStackTrace();
}
}