Initial commit

This commit is contained in:
AppleDash 2016-06-13 23:06:58 -04:00
commit 1c54dc8085
19 changed files with 765 additions and 0 deletions

13
.gitignore vendored Normal file
View File

@ -0,0 +1,13 @@
gradle/
.gradle/
gradlew*
.idea/
.metadata/
.settings/
bin/
build/
.classpath
.project
RemoteSystemsTempFiles/.project
*.iml
*.eml

48
build.gradle Normal file
View File

@ -0,0 +1,48 @@
group 'org.appledash'
version '0.1.3-SNAPSHOT'
apply plugin: 'java'
sourceCompatibility = 1.8
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.3'
}
}
apply plugin: 'com.github.johnrengelman.shadow'
shadowJar {
dependencies {
include(dependency('org.mcstats.bukkit:.*'))
}
}
repositories {
mavenCentral()
// Spigot/Bukkit
maven {
url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/'
}
// PluginMetrics
maven {
url 'http://repo.mcstats.org/content/repositories/public'
}
// Sonatype
maven {
url 'https://oss.sonatype.org/content/repositories/snapshots/'
}
}
dependencies {
compile group: 'org.spigotmc', name: 'spigot-api', version: '1.9-R0.1-SNAPSHOT'
compile group: 'org.bukkit', name: 'bukkit', version: '1.9-R0.1-SNAPSHOT'
compile group: 'org.mcstats.bukkit', name: 'metrics', version: 'R7'
}

2
settings.gradle Normal file
View File

@ -0,0 +1,2 @@
rootProject.name = 'saneeconomy'

View File

@ -0,0 +1,91 @@
package org.appledash.saneeconomy;
import org.appledash.saneeconomy.command.type.BalanceCommand;
import org.appledash.saneeconomy.command.type.EconomyAdminCommand;
import org.appledash.saneeconomy.economy.Currency;
import org.appledash.saneeconomy.economy.EconomyManager;
import org.appledash.saneeconomy.economy.backend.EconomyStorageBackend;
import org.appledash.saneeconomy.economy.backend.type.EconomyStorageBackendFlatfile;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Created by AppleDash on 6/13/2016.
* Blackjack is still best pony.
*/
public class SaneEconomy extends JavaPlugin {
private static SaneEconomy instance;
private EconomyManager economyManager;
public SaneEconomy() {
instance = this;
}
@Override
public void onEnable() {
new File(getDataFolder(), "config.yml").delete();
saveDefaultConfig();
getLogger().setLevel(Level.ALL);
getLogger().fine("Initializing currency...");
Currency currency = Currency.fromConfig(getConfig(), "currency");
getLogger().fine("Initialized currency: " + currency.getPluralName());
EconomyStorageBackend backend;
getLogger().fine("Initializing economy storage backend...");
String backendType = getConfig().getString("backend.type");
/* Flatfile database, currently only supported. */
if (backendType.equalsIgnoreCase("flatfile")) {
String backendFileName = getConfig().getString("backend.file", "economy.db");
File backendFile = new File(getDataFolder(), backendFileName);
backend = new EconomyStorageBackendFlatfile(backendFile);
getLogger().fine("Initialized flatfile backend with file " + backendFile.getAbsolutePath());
} else {
getLogger().severe("Unknown storage backend " + backendType + "!");
shutdown();
return;
}
economyManager = new EconomyManager(currency, backend);
getLogger().fine("Initializing commands...");
getCommand("balance").setExecutor(new BalanceCommand());
getCommand("ecoadmin").setExecutor(new EconomyAdminCommand());
getLogger().fine("Commands initialized!");
}
private void shutdown(){
getServer().getPluginManager().disablePlugin(this);
}
/**
* Get the active EconomyManager.
* @return EconomyManager
*/
public EconomyManager getEconomyManager() {
return economyManager;
}
/**
* Get the current plugin instance.
* @return Instance
*/
public static SaneEconomy getInstance() {
return instance;
}
/**
* Get the logger for the plugin.
* @return Plugin logger.
*/
public static Logger logger(){
return getInstance().getLogger();
}
}

View File

@ -0,0 +1,37 @@
package org.appledash.saneeconomy.command;
import org.appledash.saneeconomy.command.exception.*;
import org.appledash.saneeconomy.utils.MessageUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
/**
* Created by AppleDash on 6/13/2016.
* Blackjack is still best pony.
*/
public abstract class SaneEconomyCommand implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
try {
if (!sender.hasPermission(getPermission())) {
throw new NoPermissionException();
}
return onCommand(sender, args);
} catch (TooFewArgumentsException | NeedPlayerException | InvalidUsageException e) {
MessageUtils.sendMessage(sender, e.getMessage());
for (String s : getUsage()) {
MessageUtils.sendMessage(sender, String.format("Usage: %s", s.replace("<command>", label)));
}
return true;
} catch (CommandException e) {
MessageUtils.sendMessage(sender, e.getMessage());
return true;
}
}
public abstract String getPermission();
public abstract String[] getUsage();
public abstract boolean onCommand(CommandSender sender, String[] args) throws CommandException;
}

View File

@ -0,0 +1,8 @@
package org.appledash.saneeconomy.command.exception;
/**
* Created by AppleDash on 6/13/2016.
* Blackjack is still best pony.
*/
public class CommandException extends Exception {
}

View File

@ -0,0 +1,12 @@
package org.appledash.saneeconomy.command.exception;
/**
* Created by AppleDash on 6/13/2016.
* Blackjack is still best pony.
*/
public class InvalidUsageException extends CommandException {
@Override
public String getMessage() {
return "Invalid syntax for that command!";
}
}

View File

@ -0,0 +1,12 @@
package org.appledash.saneeconomy.command.exception;
/**
* Created by AppleDash on 6/13/2016.
* Blackjack is still best pony.
*/
public class NeedPlayerException extends CommandException {
@Override
public String getMessage() {
return "That command requires a player argument when not run by a player.";
}
}

View File

@ -0,0 +1,12 @@
package org.appledash.saneeconomy.command.exception;
/**
* Created by AppleDash on 6/13/2016.
* Blackjack is still best pony.
*/
public class NoPermissionException extends CommandException {
@Override
public String getMessage() {
return "You do not have permission to do that.";
}
}

View File

@ -0,0 +1,12 @@
package org.appledash.saneeconomy.command.exception;
/**
* Created by AppleDash on 6/13/2016.
* Blackjack is still best pony.
*/
public class TooFewArgumentsException extends CommandException {
@Override
public String getMessage() {
return "Wrong number of arguments for that command!";
}
}

View File

@ -0,0 +1,54 @@
package org.appledash.saneeconomy.command.type;
import org.appledash.saneeconomy.SaneEconomy;
import org.appledash.saneeconomy.command.SaneEconomyCommand;
import org.appledash.saneeconomy.command.exception.CommandException;
import org.appledash.saneeconomy.command.exception.NeedPlayerException;
import org.appledash.saneeconomy.utils.MessageUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
/**
* Created by AppleDash on 6/13/2016.
* Blackjack is still best pony.
*/
public class BalanceCommand extends SaneEconomyCommand {
@Override
public String getPermission() {
return "saneeconomy.balance";
}
@Override
public String[] getUsage() {
return new String[] {
"/<command> [player]"
};
}
@Override
public boolean onCommand(CommandSender sender, String[] args) throws CommandException {
String playerName;
if (args.length == 0) {
if (!(sender instanceof Player)) {
throw new NeedPlayerException();
}
playerName = sender.getName();
} else {
playerName = args[0];
}
Player player = Bukkit.getServer().getPlayer(playerName);
if (player == null) {
MessageUtils.sendMessage(sender, "That player is not online.");
return true;
}
MessageUtils.sendMessage(sender, "Balance of %s is %s.", playerName, SaneEconomy.getInstance().getEconomyManager().getFormattedBalance(player));
return true;
}
}

View File

@ -0,0 +1,92 @@
package org.appledash.saneeconomy.command.type;
import org.appledash.saneeconomy.SaneEconomy;
import org.appledash.saneeconomy.command.SaneEconomyCommand;
import org.appledash.saneeconomy.command.exception.CommandException;
import org.appledash.saneeconomy.command.exception.InvalidUsageException;
import org.appledash.saneeconomy.command.exception.NeedPlayerException;
import org.appledash.saneeconomy.command.exception.TooFewArgumentsException;
import org.appledash.saneeconomy.utils.MessageUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
/**
* Created by AppleDash on 6/13/2016.
* Blackjack is still best pony.
*/
public class EconomyAdminCommand extends SaneEconomyCommand {
@Override
public String getPermission() {
return "saneeconomy.admin";
}
@Override
public String[] getUsage() {
return new String[] {
"/<command> <give/take/set> [player] <amount>"
};
}
@Override
public boolean onCommand(CommandSender sender, String[] args) throws CommandException {
if (args.length < 2) {
throw new TooFewArgumentsException();
}
String subCommand = args[0];
String sTargetPlayer;
String sAmount;
if (args.length == 2) {
if (!(sender instanceof Player)) {
throw new NeedPlayerException();
}
sTargetPlayer = sender.getName();
sAmount = args[1];
} else {
sTargetPlayer = args[1];
sAmount = args[2];
}
Player targetPlayer = Bukkit.getServer().getPlayer(sTargetPlayer);
if (targetPlayer == null) {
MessageUtils.sendMessage(sender, "That player is not online!");
return true;
}
double amount;
try {
amount = Double.valueOf(sAmount);
} catch (NumberFormatException e) {
MessageUtils.sendMessage(sender, "%s is not a number!", sAmount);
return true;
}
if (amount < 0) {
MessageUtils.sendMessage(sender, "%s is not a positive number.", sAmount);
return true;
}
if (subCommand.equalsIgnoreCase("give")) {
double newAmount = SaneEconomy.getInstance().getEconomyManager().addBalance(targetPlayer, amount);
MessageUtils.sendMessage(sender, "New balance for %s is %s", sTargetPlayer, SaneEconomy.getInstance().getEconomyManager().getCurrency().formatAmount(newAmount));
return true;
} else if (subCommand.equalsIgnoreCase("take")) {
double newAmount = SaneEconomy.getInstance().getEconomyManager().subtractBalance(targetPlayer, amount);
MessageUtils.sendMessage(sender, "New balance for %s is %s", sTargetPlayer, SaneEconomy.getInstance().getEconomyManager().getCurrency().formatAmount(newAmount));
return true;
} else if (subCommand.equalsIgnoreCase("set")) {
SaneEconomy.getInstance().getEconomyManager().setBalance(targetPlayer, amount);
MessageUtils.sendMessage(sender, "Balance for %s set to %s", sTargetPlayer, SaneEconomy.getInstance().getEconomyManager().getCurrency().formatAmount(amount));
return true;
}
throw new InvalidUsageException();
}
}

View File

@ -0,0 +1,62 @@
package org.appledash.saneeconomy.economy;
import org.bukkit.configuration.file.FileConfiguration;
import java.text.DecimalFormat;
/**
* Created by AppleDash on 6/13/2016.
* Blackjack is still best pony.
*
* Represents an in-game currency.
*/
public class Currency {
private String nameSingular;
private String namePlural;
private DecimalFormat format;
public Currency(String nameSingular, String namePlural, DecimalFormat format) {
this.nameSingular = nameSingular;
this.namePlural = namePlural;
this.format = format;
}
public static Currency fromConfig(FileConfiguration config, String baseNode) {
return new Currency(
config.getString(String.format("%s.name.singular", baseNode), "dollar"),
config.getString(String.format("%s.name.plural", baseNode), "dollars"),
new DecimalFormat(config.getString(String.format("%s.format", baseNode), "0.00"))
);
}
/**
* Format a money amount with this currency's format.
* @param amount Money amount.
* @return Formatted amount string.
*/
public String formatAmount(double amount) {
if (amount == 1) {
return String.format("%s %s", format.format(amount), nameSingular);
}
return String.format("%s %s", format.format(amount), namePlural);
}
/**
* Get this currency's singular name.
* Example: "Dollar"
* @return Singular name.
*/
public String getSingularName() {
return nameSingular;
}
/**
* Get this currency's plural name.
* Example: "Dollars"
* @return Plural name.
*/
public String getPluralName() {
return namePlural;
}
}

View File

@ -0,0 +1,131 @@
package org.appledash.saneeconomy.economy;
import org.appledash.saneeconomy.economy.backend.EconomyStorageBackend;
import org.bukkit.entity.Player;
/**
* Created by AppleDash on 6/13/2016.
* Blackjack is still best pony.
*
* Represents our EconomyManager, which manages players' balances.
*/
public class EconomyManager {
private Currency currency;
private EconomyStorageBackend backend;
public EconomyManager(Currency currency, EconomyStorageBackend backend) {
this.currency = currency;
this.backend = backend;
}
/**
* Get the Currency we're using/
* @return Currency
*/
public Currency getCurrency() {
return currency;
}
/**
* Get the balance of a player, formatted according to our Currency's format.
* @param player Player
* @return Formatted balance
*/
public String getFormattedBalance(Player player) {
return currency.formatAmount(backend.getBalance(player));
}
/**
* Get a player's balance.
* @param targetPlayer Player to get balance of
* @return Player's balance
*/
public double getBalance(Player targetPlayer) {
return backend.getBalance(targetPlayer);
}
/**
* Check if a player has a certain amount of money.
* @param targetPlayer Player to check balance of
* @param requiredBalance How much money we're checking for
* @return True if they have requiredBalance or more, false otherwise
*/
public boolean hasBalance(Player targetPlayer, double requiredBalance) {
return getBalance(targetPlayer) >= requiredBalance;
}
/**
* Add to a player's balance.
* @param targetPlayer Player to add to
* @param amount Amount to add
* @return Player's new balance
* @throws IllegalArgumentException If amount is negative
*/
public double addBalance(Player targetPlayer, double amount) {
if (amount < 0) {
throw new IllegalArgumentException("Cannot add a negative amount!");
}
return backend.addBalance(targetPlayer, amount);
}
/**
* Subtract from a player's balance.
* If the subtraction would result in a negative balance, the balance is instead set to 0.
* @param targetPlayer Player to subtract from
* @param amount Amount to subtract
* @return Player's new balance
* @throws IllegalArgumentException If amount is negative
*/
public double subtractBalance(Player targetPlayer, double amount) {
if (amount < 0) {
throw new IllegalArgumentException("Cannot subtract a negative amount!");
}
/* Subtracting that much would result in a negative balance - don't do that */
if (backend.getBalance(targetPlayer) - amount <= 0.0D) {
backend.setBalance(targetPlayer, 0.0D);
return 0.0D;
}
return backend.subtractBalance(targetPlayer, amount);
}
/**
* Set a player's balance.
* @param targetPlayer Player to set balance of
* @param amount Amount to set balance to
* @throws IllegalArgumentException If amount is negative
*/
public void setBalance(Player targetPlayer, double amount) {
if (amount < 0) {
throw new IllegalArgumentException("Cannot set balance to a negative value!");
}
backend.setBalance(targetPlayer, amount);
}
/**
* Transfer money from one player to another.
* @param fromPlayer Player to transfer from
* @param toPlayer Player to transfer to
* @param amount Amount to transfer
* @return True if success, false if fromPlayer has insufficient funds.
* @throws IllegalArgumentException If amount is negative
*/
public boolean transfer(Player fromPlayer, Player toPlayer, double amount) {
if (amount < 0) {
throw new IllegalArgumentException("Cannot transfer a negative amount!");
}
if (!hasBalance(fromPlayer, amount)) {
return false;
}
/* Perform the actual transfer. TODO: Maybe return their new balances in some way? */
subtractBalance(fromPlayer, amount);
addBalance(toPlayer, amount);
return true;
}
}

View File

@ -0,0 +1,41 @@
package org.appledash.saneeconomy.economy.backend;
import org.bukkit.entity.Player;
/**
* Created by AppleDash on 6/13/2016.
* Blackjack is still best pony.
*
* Represents our economy storage backend - whatever we're using to store economy data.
*/
public interface EconomyStorageBackend {
/**
* Get the balance of a player.
* @param player Player
* @return Player's current balance
*/
double getBalance(Player player);
/**
* Set the balance of a player, overwriting the old balance.
* @param player Player
* @param newBalance Player's new balance
*/
void setBalance(Player player, double newBalance);
/**
* Add to a player's balance.
* @param player Player
* @param amount Amount to add to the balance
* @return Player's new balance
*/
double addBalance(Player player, double amount);
/**
* Subtract from a player's balance.
* @param player Player
* @param amount Amount to subtract from the balance
* @return Player's new balance
*/
double subtractBalance(Player player, double amount);
}

View File

@ -0,0 +1,97 @@
package org.appledash.saneeconomy.economy.backend.type;
import org.appledash.saneeconomy.SaneEconomy;
import org.appledash.saneeconomy.economy.backend.EconomyStorageBackend;
import org.bukkit.entity.Player;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* Created by AppleDash on 6/13/2016.
* Blackjack is still best pony.
*/
public class EconomyStorageBackendFlatfile implements EconomyStorageBackend {
private static final int SCHEMA_VERSION = 1;
private File file;
private Map<UUID, Double> playerBalances = new HashMap<>();
public EconomyStorageBackendFlatfile(File file) {
this.file = file;
loadDatabase();
}
private void loadDatabase() {
if (!file.exists()) {
return;
}
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
int schemaVer = ois.readInt();
if (schemaVer != SCHEMA_VERSION) { // Eventually, if I change the schema there will be code to detect such changes and update it on load.
// ???
SaneEconomy.logger().severe("Unrecognized flatfile database version " + schemaVer + ", cannot load database!");
return;
}
playerBalances = (HashMap<UUID, Double>)ois.readObject();
ois.close();
} catch (IOException | ClassNotFoundException e) {
SaneEconomy.logger().severe("Failed to load flatfile database!");
e.printStackTrace();
}
}
private void saveDatabase() {
if (file.exists()) {
file.delete();
}
try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
oos.writeInt(SCHEMA_VERSION);
oos.writeObject(playerBalances);
oos.close();
} catch (IOException e) {
SaneEconomy.logger().severe("Failed to save flatfile database!");
}
}
@Override
public double getBalance(Player player) {
if (!playerBalances.containsKey(player.getUniqueId())) {
return 0.0D;
}
return playerBalances.get(player.getUniqueId());
}
@Override
public void setBalance(Player player, double newBalance) {
playerBalances.put(player.getUniqueId(), newBalance);
saveDatabase();
}
@Override
public double addBalance(Player player, double amount) {
double newAmount = getBalance(player) + amount;
setBalance(player, newAmount);
return newAmount;
}
@Override
public double subtractBalance(Player player, double amount) {
double newAmount = getBalance(player) - amount;
setBalance(player, newAmount);
return newAmount;
}
}

View File

@ -0,0 +1,16 @@
package org.appledash.saneeconomy.utils;
import net.md_5.bungee.api.ChatColor;
import org.appledash.saneeconomy.SaneEconomy;
import org.bukkit.command.CommandSender;
/**
* Created by AppleDash on 6/13/2016.
* Blackjack is still best pony.
*/
public class MessageUtils {
public static void sendMessage(CommandSender sender, String fmt, String... args) {
String prefix = ChatColor.translateAlternateColorCodes('&', SaneEconomy.getInstance().getConfig().getString("chat.prefix", "[SaneEcon] "));;
sender.sendMessage(prefix + String.format(fmt, args));
}
}

View File

@ -0,0 +1,11 @@
backend:
type: flatfile
currency:
name:
singular: 'bit'
plural: 'bits'
format: '0.00'
chat:
prefix: '&b[&9SaneEcon&b]&r '

View File

@ -0,0 +1,14 @@
name: SaneEconomy
main: org.appledash.saneeconomy.SaneEconomy
version: 0.1.2
commands:
balance:
aliases: [bal]
description: Get your current balance.
usage: /<command> [player name]
permission: saneeconomy.balance
ecoadmin:
aliases: [eco]
description: Administer the economy.
usage: /<command> <give/take/set> <player name> <amount>
permission: saneeconomy.ecoadmin