- Added statistics to the plugin

- Added shop refund message
- Recoded Register for ChestShop
- Added VAULT support (Register is used when no Vault is found)
- Added Heroes exp option for granting exp for shop creation
- EXPERIMENTAL: Option to cause BlockState.update() every transaction (probably doesn't work, as Block.applyPhysics() is needed)
- Added ChestShop.nofee permission for free shop creation (and no refunds)
- Added a separate Admin Shop tax option
-
This commit is contained in:
Acrobot 2012-01-25 16:32:34 +01:00
parent dc4d9961c1
commit c3b084fd1a
21 changed files with 587 additions and 308 deletions

View File

@ -65,6 +65,9 @@ public class ChestShop extends JavaPlugin {
getCommand("iteminfo").setExecutor(new ItemInfo()); getCommand("iteminfo").setExecutor(new ItemInfo());
getCommand("csVersion").setExecutor(new Version()); getCommand("csVersion").setExecutor(new Version());
//Start the statistics pinger
startStatistics();
System.out.println('[' + getPluginName() + "] version " + getVersion() + " initialized!"); System.out.println('[' + getPluginName() + "] version " + getVersion() + " initialized!");
} }
@ -72,7 +75,7 @@ public class ChestShop extends JavaPlugin {
System.out.println('[' + getPluginName() + "] version " + getVersion() + " shutting down!"); System.out.println('[' + getPluginName() + "] version " + getVersion() + " shutting down!");
} }
////////////////// REGISTER EVENTS & SCHEDULER /////////////////////////// ////////////////// REGISTER EVENTS, SCHEDULER & STATS ///////////////////////////
private void registerEvents() { private void registerEvents() {
blockBreak blockBreak = new blockBreak(); blockBreak blockBreak = new blockBreak();
registerEvent(Event.Type.BLOCK_BREAK, blockBreak); registerEvent(Event.Type.BLOCK_BREAK, blockBreak);
@ -80,7 +83,6 @@ public class ChestShop extends JavaPlugin {
registerEvent(Event.Type.SIGN_CHANGE, new signChange()); registerEvent(Event.Type.SIGN_CHANGE, new signChange());
registerEvent(Event.Type.PLAYER_INTERACT, new playerInteract(), Event.Priority.Highest); registerEvent(Event.Type.PLAYER_INTERACT, new playerInteract(), Event.Priority.Highest);
registerEvent(Event.Type.PLUGIN_ENABLE, new pluginEnable()); registerEvent(Event.Type.PLUGIN_ENABLE, new pluginEnable());
registerEvent(Event.Type.PLUGIN_DISABLE, new pluginDisable());
if (!Config.getBoolean(Property.USE_BUILT_IN_PROTECTION)) return; if (!Config.getBoolean(Property.USE_BUILT_IN_PROTECTION)) return;
registerEvent(Event.Type.BLOCK_PISTON_EXTEND, blockBreak); registerEvent(Event.Type.BLOCK_PISTON_EXTEND, blockBreak);
registerEvent(Event.Type.BLOCK_PISTON_RETRACT, blockBreak); registerEvent(Event.Type.BLOCK_PISTON_RETRACT, blockBreak);
@ -99,6 +101,14 @@ public class ChestShop extends JavaPlugin {
server.getScheduler().scheduleAsyncRepeatingTask(this, runnable, startTime, repetetionTime); server.getScheduler().scheduleAsyncRepeatingTask(this, runnable, startTime, repetetionTime);
} }
private void startStatistics(){
try{
new Metrics().beginMeasuringPlugin(this);
} catch (Exception ex){
System.out.println(chatPrefix + "There was an error while submitting statistics.");
}
}
///////////////////// DATABASE STUFF //////////////////////////////// ///////////////////// DATABASE STUFF ////////////////////////////////
private static Configuration getBukkitConfig() { private static Configuration getBukkitConfig() {
Configuration config = new Configuration(new File("bukkit.yml")); Configuration config = new Configuration(new File("bukkit.yml"));

View File

@ -35,6 +35,7 @@ public enum Language {
PROTECTED_SHOP("Successfully protected the shop with LWC!"), PROTECTED_SHOP("Successfully protected the shop with LWC!"),
SHOP_CREATED("Shop successfully created!"), SHOP_CREATED("Shop successfully created!"),
SHOP_REFUNDED("You have been refunded %amount."),
NO_PERMISSION("You don't have permissions to do that!"), NO_PERMISSION("You don't have permissions to do that!"),
INCORRECT_ITEM_ID("You have specified invalid item id!"), INCORRECT_ITEM_ID("You have specified invalid item id!"),

View File

@ -4,7 +4,7 @@ package com.Acrobot.ChestShop.Config;
* @author Acrobot * @author Acrobot
*/ */
public enum Property { public enum Property {
PREFERRED_ECONOMY_PLUGIN("", "Preferred economy plugin (iConomy, BOSEconomy, Essentials). If you do not want to specify this, leave it blank."), PREFERRED_ECONOMY_PLUGIN("", "WHEN NOT USING VAULT. Preferred economy plugin (iConomy, BOSEconomy, Essentials). If you do not want to specify this, leave it blank."),
REVERSE_BUTTONS(false, "If true, people will buy with left-click and sell with right-click."), REVERSE_BUTTONS(false, "If true, people will buy with left-click and sell with right-click."),
ALLOW_LEFT_CLICK_DESTROYING(true, "If true, if you left-click your own shop sign you won't open chest's inventory, but instead you will start destroying the sign."), ALLOW_LEFT_CLICK_DESTROYING(true, "If true, if you left-click your own shop sign you won't open chest's inventory, but instead you will start destroying the sign."),
STACK_UNSTACKABLES(false, "If true, ALL things (including food, etc.) will stack up to 64"), STACK_UNSTACKABLES(false, "If true, ALL things (including food, etc.) will stack up to 64"),
@ -30,9 +30,12 @@ public enum Property {
TOWNY_SHOPS_FOR_OWNERS_ONLY(true, "If true, only plot owners are able to build inside a shop plot. If false, every town's resident is able to build there."), TOWNY_SHOPS_FOR_OWNERS_ONLY(true, "If true, only plot owners are able to build inside a shop plot. If false, every town's resident is able to build there."),
WORLDGUARD_INTEGRATION(false, "Do you want to only let people build inside plots?"), WORLDGUARD_INTEGRATION(false, "Do you want to only let people build inside plots?"),
TAX_AMOUNT(0, "Percent of the price that should go to the server's account. (100 = 100 percent)"), TAX_AMOUNT(0, "Percent of the price that should go to the server's account. (100 = 100 percent)"),
SERVER_TAX_AMOUNT(0, "Percent of the price that should go to the server's account when buying from an Admin Shop"),
SHOP_REFUND_PRICE(0, "How much money do you get back when destroying a sign?"), SHOP_REFUND_PRICE(0, "How much money do you get back when destroying a sign?"),
ALLOW_MULTIPLE_SHOPS_AT_ONE_BLOCK(false, "Do you want to allow other players to build a shop on a block where there's one already?"), ALLOW_MULTIPLE_SHOPS_AT_ONE_BLOCK(false, "Do you want to allow other players to build a shop on a block where there's one already?"),
SHOP_INTERACTION_INTERVAL(100, "(In 1/1000th of a second) How often can a player use a shop sign?"); SHOP_INTERACTION_INTERVAL(100, "(In 1/1000th of a second) How often can a player use a shop sign?"),
HEROES_EXP(100, "How much Heroes exp should people get for creating a ChestShop?"),
BLOCK_UPDATE(false, "EXPERIMENTAL: Should every ChestShop transaction result in a block update?");
private final Object value; private final Object value;

View File

@ -1,43 +0,0 @@
package com.Acrobot.ChestShop;
import com.Acrobot.ChestShop.Config.Config;
import com.Acrobot.ChestShop.Config.Property;
import com.Acrobot.ChestShop.Utils.uLongName;
import com.nijikokun.register.payment.forChestShop.Method;
/**
* @author Acrobot
* Economy management
*/
public class Economy {
public static Method economy;
public static boolean hasAccount(String p) {
return economy.hasAccount(uLongName.getName(p));
}
public static void add(String name, float amount) {
if (Config.getFloat(Property.TAX_AMOUNT) != 0F && !Config.getString(Property.SERVER_ECONOMY_ACCOUNT).isEmpty()) {
float tax = (Config.getFloat(Property.TAX_AMOUNT) / 100F) * amount;
economy.getAccount(Config.getString(Property.SERVER_ECONOMY_ACCOUNT)).add(tax);
amount = amount - tax;
}
economy.getAccount(uLongName.getName(name)).add(amount);
}
public static void substract(String name, float amount) {
economy.getAccount(uLongName.getName(name)).subtract(amount);
}
public static boolean hasEnough(String name, float amount) {
return economy.getAccount(uLongName.getName(name)).hasEnough(amount);
}
public static double balance(String name) {
return economy.getAccount(uLongName.getName(name)).balance();
}
public static String formatBalance(double amount) {
return economy.format(amount);
}
}

View File

@ -0,0 +1,13 @@
package com.Acrobot.ChestShop.Economy;
/**
* @author Acrobot
*/
public interface EcoPlugin {
public boolean hasAccount(String player);
public void add(String player, double amount);
public void subtract(String player, double amount);
public boolean hasEnough(String player, double amount);
public double balance(String player);
public String format(double amount);
}

View File

@ -0,0 +1,58 @@
package com.Acrobot.ChestShop.Economy;
import com.Acrobot.ChestShop.Config.Config;
import com.Acrobot.ChestShop.Config.Property;
import com.Acrobot.ChestShop.Utils.uLongName;
/**
* @author Acrobot
* Economy management
*/
public class Economy {
public static EcoPlugin economy;
public static boolean hasAccount(String p) {
return economy.hasAccount(uLongName.getName(p));
}
public static void add(String name, float amount) {
String account = Config.getString(Property.SERVER_ECONOMY_ACCOUNT);
if (!account.isEmpty()) {
float tax = getTax(Property.TAX_AMOUNT, amount);
economy.add(account, tax);
amount = amount - tax;
}
economy.add(uLongName.getName(name), amount);
}
public static void addServer(String name, float amount){
String account = Config.getString(Property.SERVER_ECONOMY_ACCOUNT);
if (!account.isEmpty()) {
float tax = getTax(Property.SERVER_TAX_AMOUNT, amount);
economy.add(account, tax);
amount = amount - tax;
}
economy.add(uLongName.getName(name), amount);
}
public static float getTax(Property tax, float price){
return (Config.getFloat(tax) / 100F) * price;
}
public static void subtract(String name, float amount) {
economy.subtract(name, amount);
}
public static boolean hasEnough(String name, float amount) {
return economy.hasEnough(uLongName.getName(name), amount);
}
public static double balance(String name) {
return economy.balance(uLongName.getName(name));
}
public static String formatBalance(double amount) {
return economy.format(amount);
}
}

View File

@ -0,0 +1,34 @@
package com.Acrobot.ChestShop.Economy;
/**
* @author Acrobot
*/
public class NoProvider implements EcoPlugin{
public boolean hasAccount(String player) {
System.out.println("[ChestShop] You haven't got any economy plugin!");
return false;
}
public void add(String player, double amount) {
System.out.println("[ChestShop] You haven't got any economy plugin!");
}
public void subtract(String player, double amount) {
System.out.println("[ChestShop] You haven't got any economy plugin!");
}
public boolean hasEnough(String player, double amount) {
System.out.println("[ChestShop] You haven't got any economy plugin!");
return false;
}
public double balance(String player) {
System.out.println("[ChestShop] You haven't got any economy plugin!");
return 0;
}
public String format(double amount) {
System.out.println("[ChestShop] You haven't got any economy plugin!");
return null;
}
}

View File

@ -0,0 +1,33 @@
package com.Acrobot.ChestShop.Economy;
import com.nijikokun.register.payment.forChestShop.Method;
/**
* @author Acrobot
*/
public class Register implements EcoPlugin{
public static Method eco;
public boolean hasAccount(String player) {
return eco.hasAccount(player);
}
public void add(String player, double amount) {
eco.getAccount(player).add(amount);
}
public void subtract(String player, double amount) {
eco.getAccount(player).subtract(amount);
}
public boolean hasEnough(String player, double amount) {
return eco.getAccount(player).hasEnough(amount);
}
public double balance(String player) {
return eco.getAccount(player).balance();
}
public String format(double amount) {
return eco.format(amount);
}
}

View File

@ -0,0 +1,32 @@
package com.Acrobot.ChestShop.Economy;
/**
* @author Acrobot
*/
public class Vault implements EcoPlugin {
public static net.milkbowl.vault.economy.Economy economy;
public boolean hasAccount(String player) {
return economy.hasAccount(player);
}
public void add(String player, double amount) {
economy.depositPlayer(player, amount);
}
public void subtract(String player, double amount) {
economy.withdrawPlayer(player, amount);
}
public boolean hasEnough(String player, double amount) {
return economy.has(player, amount);
}
public double balance(String player) {
return economy.getBalance(player);
}
public String format(double amount) {
return economy.format(amount);
}
}

View File

@ -1,8 +1,9 @@
package com.Acrobot.ChestShop.Listeners; package com.Acrobot.ChestShop.Listeners;
import com.Acrobot.ChestShop.Config.Config; import com.Acrobot.ChestShop.Config.Config;
import com.Acrobot.ChestShop.Config.Language;
import com.Acrobot.ChestShop.Config.Property; import com.Acrobot.ChestShop.Config.Property;
import com.Acrobot.ChestShop.Economy; import com.Acrobot.ChestShop.Economy.Economy;
import com.Acrobot.ChestShop.Permission; import com.Acrobot.ChestShop.Permission;
import com.Acrobot.ChestShop.Signs.restrictedSign; import com.Acrobot.ChestShop.Signs.restrictedSign;
import com.Acrobot.ChestShop.Utils.uBlock; import com.Acrobot.ChestShop.Utils.uBlock;
@ -37,7 +38,11 @@ public class blockBreak extends BlockListener {
Sign sign = uBlock.findSign(block, (player != null ? uLongName.stripName(player.getName()) : null)); Sign sign = uBlock.findSign(block, (player != null ? uLongName.stripName(player.getName()) : null));
if (!isCorrectSign(sign, block)) return false; //It's not a correct shop sign, so don't cancel it if (!isCorrectSign(sign, block)) return false; //It's not a correct shop sign, so don't cancel it
if (playerIsNotOwner(player, sign)) return true; //Player is not the owner of the shop - cancel! if (playerIsNotOwner(player, sign)) return true; //Player is not the owner of the shop - cancel!
if (weShouldReturnMoney()) Economy.add(uLongName.getName(sign.getLine(0)), Config.getFloat(Property.SHOP_REFUND_PRICE)); //Add some money if (weShouldReturnMoney() && !Permission.has(player, Permission.NOFEE)){
float refundPrice = Config.getFloat(Property.SHOP_REFUND_PRICE);
Economy.add(uLongName.getName(sign.getLine(0)), refundPrice); //Add some money
player.sendMessage(Config.getLocal(Language.SHOP_REFUNDED).replace("%amount", Economy.formatBalance(refundPrice)));
}
return false; //Player is the owner, so we don't want to cancel this :) return false; //Player is the owner, so we don't want to cancel this :)
} }

View File

@ -1,18 +0,0 @@
package com.Acrobot.ChestShop.Listeners;
import com.Acrobot.ChestShop.Economy;
import com.nijikokun.register.payment.forChestShop.Methods;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.server.ServerListener;
/**
* @author Acrobot
*/
public class pluginDisable extends ServerListener {
public void onPluginDisable(PluginDisableEvent event) {
if (Economy.economy != null && Methods.hasMethod() && Methods.checkDisabled(event.getPlugin())) {
Economy.economy = null;
System.out.println("[ChestShop] Economy plugin disabled!");
}
}
}

View File

@ -1,7 +1,8 @@
package com.Acrobot.ChestShop.Listeners; package com.Acrobot.ChestShop.Listeners;
import com.Acrobot.ChestShop.ChestShop; import com.Acrobot.ChestShop.ChestShop;
import com.Acrobot.ChestShop.Economy; import com.Acrobot.ChestShop.Economy.Register;
import com.Acrobot.ChestShop.Economy.Vault;
import com.Acrobot.ChestShop.Items.Odd; import com.Acrobot.ChestShop.Items.Odd;
import com.Acrobot.ChestShop.Permission; import com.Acrobot.ChestShop.Permission;
import com.Acrobot.ChestShop.Protection.Plugins.DeadboltPlugin; import com.Acrobot.ChestShop.Protection.Plugins.DeadboltPlugin;
@ -9,19 +10,23 @@ import com.Acrobot.ChestShop.Protection.Plugins.Default;
import com.Acrobot.ChestShop.Protection.Plugins.LWCplugin; import com.Acrobot.ChestShop.Protection.Plugins.LWCplugin;
import com.Acrobot.ChestShop.Protection.Plugins.LockettePlugin; import com.Acrobot.ChestShop.Protection.Plugins.LockettePlugin;
import com.Acrobot.ChestShop.Protection.Security; import com.Acrobot.ChestShop.Protection.Security;
import com.Acrobot.ChestShop.Utils.uHeroes;
import com.Acrobot.ChestShop.Utils.uNumber; import com.Acrobot.ChestShop.Utils.uNumber;
import com.Acrobot.ChestShop.Utils.uSign; import com.Acrobot.ChestShop.Utils.uSign;
import com.Acrobot.ChestShop.Utils.uWorldGuard; import com.Acrobot.ChestShop.Utils.uWorldGuard;
import com.daemitus.deadbolt.Deadbolt; import com.daemitus.deadbolt.Deadbolt;
import com.griefcraft.lwc.LWCPlugin; import com.griefcraft.lwc.LWCPlugin;
import com.herocraftonline.dev.heroes.Heroes;
import com.nijikokun.bukkit.Permissions.Permissions; import com.nijikokun.bukkit.Permissions.Permissions;
import com.nijikokun.register.payment.forChestShop.Method;
import com.nijikokun.register.payment.forChestShop.Methods; import com.nijikokun.register.payment.forChestShop.Methods;
import com.palmergames.bukkit.towny.Towny; import com.palmergames.bukkit.towny.Towny;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import org.bukkit.event.server.PluginEnableEvent; import net.milkbowl.vault.economy.Economy;
import org.bukkit.event.server.ServerListener; import org.bukkit.event.server.ServerListener;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.yi.acru.bukkit.Lockette.Lockette; import org.yi.acru.bukkit.Lockette.Lockette;
/** /**
@ -29,35 +34,35 @@ import org.yi.acru.bukkit.Lockette.Lockette;
*/ */
public class pluginEnable extends ServerListener { public class pluginEnable extends ServerListener {
public void onPluginEnable(PluginEnableEvent event) {
if (!Methods.hasMethod() && Methods.setMethod(ChestShop.pm)) {
Economy.economy = Methods.getMethod();
System.out.println(ChestShop.chatPrefix + Economy.economy.getName() + ' ' + Economy.economy.getVersion() + " loaded.");
}
}
public static void initializePlugins() { public static void initializePlugins() {
Security.protections.add(new Default()); //Initialize basic protection Security.protections.add(new Default()); //Initialize basic protection
for (Object plugin : ChestShop.getDependencies()) { for (Object plugin : ChestShop.getDependencies()) {
Plugin pl = ChestShop.pm.getPlugin((String) plugin); Plugin pl = ChestShop.pm.getPlugin((String) plugin);
if (pl != null) initializePlugin((String) plugin, pl); if (pl != null) initializePlugin((String) plugin, pl);
} }
loadRegister();
}
private static void loadRegister(){
if (com.Acrobot.ChestShop.Economy.Economy.economy == null) {
Method m = Methods.load(ChestShop.pm);
if (m == null) return;
Register.eco = m;
com.Acrobot.ChestShop.Economy.Economy.economy = new Register();
System.out.println(ChestShop.chatPrefix + m.getName() + " loaded.");
}
} }
private static void initializePlugin(String name, Plugin plugin) { //Really messy, right? But it's short and fast :) private static void initializePlugin(String name, Plugin plugin) { //Really messy, right? But it's short and fast :)
if (name.equals("Permissions")) { if (name.equals("Permissions")) {
if (Permission.permissions != null) return;
Permission.permissions = ((Permissions) plugin).getHandler(); Permission.permissions = ((Permissions) plugin).getHandler();
} else if (name.equals("LWC")) { } else if (name.equals("LWC")) {
if (LWCplugin.lwc != null) return;
LWCplugin.setLWC(((LWCPlugin) plugin).getLWC()); LWCplugin.setLWC(((LWCPlugin) plugin).getLWC());
Security.protections.add(new LWCplugin()); Security.protections.add(new LWCplugin());
} else if (name.equals("Lockette")) { } else if (name.equals("Lockette")) {
if (LockettePlugin.lockette != null) return;
LockettePlugin.lockette = (Lockette) plugin; LockettePlugin.lockette = (Lockette) plugin;
Security.protections.add(new LockettePlugin()); Security.protections.add(new LockettePlugin());
} else if (name.equals("Deadbolt")) { } else if (name.equals("Deadbolt")) {
if (DeadboltPlugin.deadbolt != null) return;
DeadboltPlugin.deadbolt = (Deadbolt) plugin; DeadboltPlugin.deadbolt = (Deadbolt) plugin;
Security.protections.add(new DeadboltPlugin()); Security.protections.add(new DeadboltPlugin());
} else if (name.equals("OddItem")) { } else if (name.equals("OddItem")) {
@ -65,16 +70,25 @@ public class pluginEnable extends ServerListener {
if (plugin.getDescription().getVersion().startsWith("0.7")) { System.out.println(generateOutdatedVersion(name, plugin.getDescription().getVersion(), "0.8")); return; } if (plugin.getDescription().getVersion().startsWith("0.7")) { System.out.println(generateOutdatedVersion(name, plugin.getDescription().getVersion(), "0.8")); return; }
Odd.isInitialized = true; Odd.isInitialized = true;
} else if (name.equals("Towny")) { } else if (name.equals("Towny")) {
if (uSign.towny != null) return;
int versionNumber = 0; int versionNumber = 0;
String[] split = plugin.getDescription().getVersion().split("\\."); String[] split = plugin.getDescription().getVersion().split("\\.");
for (int i = 0; i < 4; i++) if (split.length >= i + 1 && uNumber.isInteger(split[i])) versionNumber += (Math.pow(10, (3 - i) << 1) * Integer.parseInt(split[i])); //EPIC CODE RIGHT HERE for (int i = 0; i < 4; i++) if (split.length >= i + 1 && uNumber.isInteger(split[i])) versionNumber += (Math.pow(10, (3 - i) << 1) * Integer.parseInt(split[i])); //EPIC CODE RIGHT HERE
if (versionNumber < 760047) { System.out.println(generateOutdatedVersion(name, plugin.getDescription().getVersion(), "0.76.0.47")); return; } if (versionNumber < 760047) { System.out.println(generateOutdatedVersion(name, plugin.getDescription().getVersion(), "0.76.0.47")); return; }
uSign.towny = (Towny) plugin; uSign.towny = (Towny) plugin;
} else if (name.equals("WorldGuard")) { } else if (name.equals("WorldGuard")) {
if (uWorldGuard.worldGuard != null) return;
uWorldGuard.worldGuard = (WorldGuardPlugin) plugin; uWorldGuard.worldGuard = (WorldGuardPlugin) plugin;
} else if (name.equals("Vault")) {
if (com.Acrobot.ChestShop.Economy.Economy.economy != null) return;
RegisteredServiceProvider<Economy> rsp = ChestShop.getBukkitServer().getServicesManager().getRegistration(Economy.class);
Vault.economy = rsp.getProvider();
if (Vault.economy == null) return;
com.Acrobot.ChestShop.Economy.Economy.economy = new Vault();
System.out.println(ChestShop.chatPrefix + "Vault loaded using economy plugin " + Vault.economy.getName());
return;
} else if (name.equals("Heroes")){
uHeroes.heroes = (Heroes) plugin;
} }
PluginDescriptionFile description = plugin.getDescription(); PluginDescriptionFile description = plugin.getDescription();
System.out.println(ChestShop.chatPrefix + description.getName() + " version " + description.getVersion() + " loaded."); System.out.println(ChestShop.chatPrefix + description.getName() + " version " + description.getVersion() + " loaded.");
} }

View File

@ -3,7 +3,7 @@ package com.Acrobot.ChestShop.Listeners;
import com.Acrobot.ChestShop.Config.Config; import com.Acrobot.ChestShop.Config.Config;
import com.Acrobot.ChestShop.Config.Language; import com.Acrobot.ChestShop.Config.Language;
import com.Acrobot.ChestShop.Config.Property; import com.Acrobot.ChestShop.Config.Property;
import com.Acrobot.ChestShop.Economy; import com.Acrobot.ChestShop.Economy.Economy;
import com.Acrobot.ChestShop.Items.Items; import com.Acrobot.ChestShop.Items.Items;
import com.Acrobot.ChestShop.Permission; import com.Acrobot.ChestShop.Permission;
import com.Acrobot.ChestShop.Protection.Security; import com.Acrobot.ChestShop.Protection.Security;
@ -108,7 +108,7 @@ public class signChange extends BlockListener {
float shopCreationPrice = Config.getFloat(Property.SHOP_CREATION_PRICE); float shopCreationPrice = Config.getFloat(Property.SHOP_CREATION_PRICE);
boolean paid = shopCreationPrice != 0 && !isAdminShop; boolean paid = shopCreationPrice != 0 && !isAdminShop && !Permission.has(player, Permission.NOFEE);
if (paid) { if (paid) {
if (!Economy.hasEnough(player.getName(), shopCreationPrice)) { if (!Economy.hasEnough(player.getName(), shopCreationPrice)) {
player.sendMessage(Config.getLocal(Language.NOT_ENOUGH_MONEY)); player.sendMessage(Config.getLocal(Language.NOT_ENOUGH_MONEY));
@ -116,7 +116,7 @@ public class signChange extends BlockListener {
return; return;
} }
Economy.substract(player.getName(), shopCreationPrice); Economy.subtract(player.getName(), shopCreationPrice);
} }
if (Config.getBoolean(Property.PROTECT_SIGN_WITH_LWC)) { if (Config.getBoolean(Property.PROTECT_SIGN_WITH_LWC)) {
@ -128,6 +128,8 @@ public class signChange extends BlockListener {
uLongName.saveName(player.getName()); uLongName.saveName(player.getName());
player.sendMessage(Config.getLocal(Language.SHOP_CREATED) + (paid ? " - " + Economy.formatBalance(shopCreationPrice) : "")); player.sendMessage(Config.getLocal(Language.SHOP_CREATED) + (paid ? " - " + Economy.formatBalance(shopCreationPrice) : ""));
uHeroes.addHeroExp(player);
} }
private static boolean canCreateShop(Player player, boolean isAdmin, int ID) { private static boolean canCreateShop(Player player, boolean isAdmin, int ID) {

View File

@ -0,0 +1,263 @@
package com.Acrobot.ChestShop;
/*
* Copyright 2011 Tyler Blair. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and contributors and should not be interpreted as representing official policies,
* either expressed or implied, of anybody else.
*/
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
/**
* Tooling to post to metrics.griefcraft.com
*/
public class Metrics {
/**
* Interface used to collect custom data for a plugin
*/
public static abstract class Plotter {
/**
* Get the column name for the plotted point
*
* @return the plotted point's column name
*/
public abstract String getColumnName();
/**
* Get the current value for the plotted point
*
* @return
*/
public abstract int getValue();
@Override
public int hashCode() {
return getColumnName().hashCode() + getValue();
}
@Override
public boolean equals(Object object) {
if (!(object instanceof Plotter)) {
return false;
}
Plotter plotter = (Plotter) object;
return plotter.getColumnName().equals(getColumnName()) && plotter.getValue() == getValue();
}
}
/**
* The metrics revision number
*/
private final static int REVISION = 3;
/**
* The base url of the metrics domain
*/
private static final String BASE_URL = "http://metrics.griefcraft.com";
/**
* The url used to report a server's status
*/
private static final String REPORT_URL = "/report/%s";
/**
* The file where guid and opt out is stored in
*/
private static final String CONFIG_FILE = "plugins/PluginMetrics/config.yml";
/**
* Interval of time to ping in minutes
*/
private final static int PING_INTERVAL = 10;
/**
* A map of the custom data plotters for plugins
*/
private Map<Plugin, Set<Plotter>> customData = Collections.synchronizedMap(new HashMap<Plugin, Set<Plotter>>());
/**
* The plugin configuration file
*/
private final YamlConfiguration configuration;
/**
* Unique server id
*/
private String guid;
public Metrics() throws IOException {
// load the config
File file = new File(CONFIG_FILE);
configuration = YamlConfiguration.loadConfiguration(file);
// add some defaults
configuration.addDefault("opt-out", false);
configuration.addDefault("guid", UUID.randomUUID().toString());
// Do we need to create the file?
if (configuration.get("guid", null) == null) {
configuration.options().header("http://metrics.griefcraft.com").copyDefaults(true);
configuration.save(file);
}
// Load the guid then
guid = configuration.getString("guid");
}
/**
* Adds a custom data plotter for a given plugin
*
* @param plugin
* @param plotter
*/
public void addCustomData(Plugin plugin, Plotter plotter) {
Set<Plotter> plotters = customData.get(plugin);
if (plotters == null) {
plotters = Collections.synchronizedSet(new LinkedHashSet<Plotter>());
customData.put(plugin, plotters);
}
plotters.add(plotter);
}
/**
* Begin measuring a plugin
*
* @param plugin
*/
public void beginMeasuringPlugin(final Plugin plugin) throws IOException {
// Did we opt out?
if (configuration.getBoolean("opt-out", false)) return;
// First tell the server about us
postPlugin(plugin, false);
// Ping the server in intervals
plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable() {
public void run() {
try {
postPlugin(plugin, true);
} catch (IOException e) {
System.out.println("[ChestShop] There was an error while submitting statistics.");
}
}
}, PING_INTERVAL * 1200, PING_INTERVAL * 1200);
}
/**
* Generates a field
* @param name Field name
* @param data Data assigned to the field
* @return Field
* @throws UnsupportedEncodingException
*/
private static String gField(String name, String data) throws UnsupportedEncodingException {
return '&' + encode(name) + '=' + encode(data);
}
/**
* Generic method that posts a plugin to the metrics website
*
* @param plugin
*/
private void postPlugin(Plugin plugin, boolean isPing) throws IOException {
// Construct the post data
String response = "ERR No response";
String data = encode("guid") + '=' + encode(guid)
+ gField("version", plugin.getDescription().getVersion())
+ gField("server", Bukkit.getVersion())
+ gField("players", String.valueOf(Bukkit.getServer().getOnlinePlayers().length))
+ gField("revision", String.valueOf(REVISION));
// If we're pinging, append it
if (isPing) {
data += gField("ping", "true");
}
// Add any custom data (if applicable)
Set<Plotter> plotters = customData.get(plugin);
if (plotters != null) {
for (Plotter plotter : plotters) {
data += gField("Custom" + plotter.getColumnName(), Integer.toString(plotter.getValue()));
}
}
// Create the url
URL url = new URL(BASE_URL + String.format(REPORT_URL, plugin.getDescription().getName()));
// Connect to the website
URLConnection connection = url.openConnection();
connection.setDoOutput(true);
// Write the data
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
writer.write(data);
writer.flush();
// Now read the response
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
response = reader.readLine();
// close resources
writer.close();
reader.close();
if (response.startsWith("ERR")) throw new IOException(response);
}
/**
* Encode text as UTF-8
*
* @param text
* @return
*/
private static String encode(String text) throws UnsupportedEncodingException {
return URLEncoder.encode(text, "UTF-8");
}
}

View File

@ -15,7 +15,8 @@ public enum Permission {
ADMIN("ChestShop.admin"), ADMIN("ChestShop.admin"),
MOD("ChestShop.mod"), MOD("ChestShop.mod"),
OTHER_NAME("ChestShop.name."), OTHER_NAME("ChestShop.name."),
GROUP("ChestShop.group."); GROUP("ChestShop.group."),
NOFEE("ChestShop.nofee");
private final String permission; private final String permission;
@ -35,6 +36,7 @@ public enum Permission {
} }
public static boolean otherName(Player p, String name){ public static boolean otherName(Player p, String name){
if (has(p, Permission.ADMIN)) return false;
String node = OTHER_NAME + name; String node = OTHER_NAME + name;
if (permissions != null) return permissions.has(p, node) || permissions.has(p, node.toLowerCase()); if (permissions != null) return permissions.has(p, node) || permissions.has(p, node.toLowerCase());
return hasPermissionSet(p, node) || hasPermissionSet(p, node.toLowerCase()); return hasPermissionSet(p, node) || hasPermissionSet(p, node.toLowerCase());

View File

@ -5,9 +5,10 @@ import com.Acrobot.ChestShop.Chests.ChestObject;
import com.Acrobot.ChestShop.Config.Config; import com.Acrobot.ChestShop.Config.Config;
import com.Acrobot.ChestShop.Config.Language; import com.Acrobot.ChestShop.Config.Language;
import com.Acrobot.ChestShop.Config.Property; import com.Acrobot.ChestShop.Config.Property;
import com.Acrobot.ChestShop.Economy; import com.Acrobot.ChestShop.Economy.Economy;
import com.Acrobot.ChestShop.Logging.Logging; import com.Acrobot.ChestShop.Logging.Logging;
import com.Acrobot.ChestShop.Permission; import com.Acrobot.ChestShop.Permission;
import com.Acrobot.ChestShop.Utils.uBlock;
import com.Acrobot.ChestShop.Utils.uInventory; import com.Acrobot.ChestShop.Utils.uInventory;
import com.Acrobot.ChestShop.Utils.uSign; import com.Acrobot.ChestShop.Utils.uSign;
import org.bukkit.block.Sign; import org.bukkit.block.Sign;
@ -26,6 +27,7 @@ public class Shop {
public final float buyPrice; public final float buyPrice;
public final float sellPrice; public final float sellPrice;
public final String owner; public final String owner;
private final Sign sign;
public Shop(ChestObject chest, boolean buy, Sign sign, ItemStack... itemStacks) { public Shop(ChestObject chest, boolean buy, Sign sign, ItemStack... itemStacks) {
this.stock = itemStacks[0]; this.stock = itemStacks[0];
@ -35,6 +37,7 @@ public class Shop {
this.sellPrice = (!buy ? uSign.sellPrice(sign.getLine(2)) : -1); this.sellPrice = (!buy ? uSign.sellPrice(sign.getLine(2)) : -1);
this.owner = sign.getLine(0); this.owner = sign.getLine(0);
this.stockAmount = uSign.itemAmount(sign.getLine(1)); this.stockAmount = uSign.itemAmount(sign.getLine(1));
this.sign = sign;
} }
public void buy(Player player) { public void buy(Player player) {
@ -70,9 +73,12 @@ public class Shop {
} }
String account = getOwnerAccount(); String account = getOwnerAccount();
if (!account.isEmpty() && Economy.hasAccount(account)) Economy.add(account, buyPrice); if (!account.isEmpty() && Economy.hasAccount(account)) {
if (!isAdminShop()) Economy.add(account, buyPrice);
else Economy.addServer(account, buyPrice);
}
Economy.substract(playerName, buyPrice); Economy.subtract(playerName, buyPrice);
if (!isAdminShop()) chest.removeItem(stock, durability, stockAmount); if (!isAdminShop()) chest.removeItem(stock, durability, stockAmount);
@ -96,6 +102,8 @@ public class Shop {
.replace("%buyer", playerName) .replace("%buyer", playerName)
.replace("%price", formatedPrice)); .replace("%price", formatedPrice));
} }
if (Config.getBoolean(Property.BLOCK_UPDATE)) uBlock.blockUpdate(sign.getBlock());
} }
public void sell(Player player) { public void sell(Player player) {
@ -130,10 +138,11 @@ public class Shop {
} }
if (accountExists) Economy.substract(account, sellPrice); if (accountExists) Economy.subtract(account, sellPrice);
if (!isAdminShop()) chest.addItem(stock, stockAmount); if (!isAdminShop()) chest.addItem(stock, stockAmount);
Economy.add(player.getName(), sellPrice); if (!isAdminShop()) Economy.add(player.getName(), sellPrice);
else Economy.addServer(player.getName(), sellPrice);
String materialName = stock.getType().name(); String materialName = stock.getType().name();
String formatedBalance = Economy.formatBalance(sellPrice); String formatedBalance = Economy.formatBalance(sellPrice);
@ -157,6 +166,7 @@ public class Shop {
.replace("%seller", player.getName()) .replace("%seller", player.getName())
.replace("%price", formatedBalance)); .replace("%price", formatedBalance));
} }
if (Config.getBoolean(Property.BLOCK_UPDATE)) uBlock.blockUpdate(sign.getBlock());
} }
private String getOwnerAccount() { private String getOwnerAccount() {

View File

@ -29,6 +29,12 @@ public class uBlock {
return null; return null;
} }
public static void blockUpdate(Block block){
for (BlockFace bf : shopFaces){
block.getRelative(bf).getState().update(true);
}
}
public static Sign findSign(Block block, String originalName) { public static Sign findSign(Block block, String originalName) {
for (BlockFace bf : shopFaces) { for (BlockFace bf : shopFaces) {
Block faceBlock = block.getRelative(bf); Block faceBlock = block.getRelative(bf);

View File

@ -0,0 +1,26 @@
package com.Acrobot.ChestShop.Utils;
import com.Acrobot.ChestShop.Config.Config;
import com.Acrobot.ChestShop.Config.Property;
import com.herocraftonline.dev.heroes.Heroes;
import com.herocraftonline.dev.heroes.classes.HeroClass;
import com.herocraftonline.dev.heroes.hero.Hero;
import org.bukkit.entity.Player;
/**
* @author Acrobot
*/
public class uHeroes {
public static Heroes heroes;
public static void addHeroExp(Player p) {
if (uHeroes.heroes != null) {
Hero hero = uHeroes.heroes.getHeroManager().getHero(p);
if (hero.hasParty()) {
hero.getParty().gainExp(Config.getDouble(Property.HEROES_EXP), HeroClass.ExperienceType.EXTERNAL, p.getLocation());
} else {
hero.gainExp(Config.getDouble(Property.HEROES_EXP), HeroClass.ExperienceType.EXTERNAL);
}
}
}
}

View File

@ -1,105 +1,56 @@
package com.nijikokun.register.payment.forChestShop; package com.nijikokun.register.payment.forChestShop;
import com.nijikokun.register.payment.forChestShop.methods.*;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
import java.util.HashSet;
import java.util.Set;
/** /**
* The <code>methods</code> initializes methods that utilize the Method interface * @author Acrobot
* based on a "first come, first served" basis.
* <p/>
* Allowing you to check whether a payment method exists or not.
* <p/>
* methods also allows you to set a preferred method of payment before it captures
* payment plugins in the initialization process.
* <p/>
* in <code>bukkit.yml</code>:
* <blockquote><pre>
* economy:
* preferred: "iConomy"
* </pre></blockquote>
*
* @author: Nijikokun <nijikokun@shortmail.com> (@nijikokun)
* @copyright: Copyright (C) 2011
* @license: AOL license <http://aol.nexua.org>
*/ */
public class Methods { public class Methods {
private static String version = null; private static String preferred;
private static boolean self = false; private static final String[] toLoad = new String[]{
private static Method Method = null; "iConomy",
private static String preferred = ""; "BOSEconomy",
private static Set<Method> methods = new HashSet<Method>(); "Essentials",
private static Set<String> dependencies = new HashSet<String>(); "Currency",
private static Set<Method> attachables = new HashSet<Method>(); "MultiCurrency",
"3co"
};
private static final Method[] methods = new Method[]{
new iCo4(),
new iCo5(),
new iCo6(),
new BOSE6(),
new BOSE7(),
new MCUR(),
new ECO3(),
new EE17()
};
static { public static void setPreferred(String plugin) {
init(); preferred = plugin;
} }
/** public static Method load(PluginManager pm) {
* Implement all methods along with their respective name & class. if (!preferred.isEmpty()){
*/ Plugin plugin = pm.getPlugin(preferred);
private static void init() { if (plugin != null){
addMethod("iConomy", new com.nijikokun.register.payment.forChestShop.methods.iCo6()); Method m = createMethod(plugin);
addMethod("iConomy", new com.nijikokun.register.payment.forChestShop.methods.iCo5()); if (m != null) return m;
addMethod("iConomy", new com.nijikokun.register.payment.forChestShop.methods.iCo4()); }
addMethod("BOSEconomy", new com.nijikokun.register.payment.forChestShop.methods.BOSE6());
addMethod("BOSEconomy", new com.nijikokun.register.payment.forChestShop.methods.BOSE7());
addMethod("Essentials", new com.nijikokun.register.payment.forChestShop.methods.EE17());
addMethod("Currency", new com.nijikokun.register.payment.forChestShop.methods.MCUR());
addMethod("3co", new com.nijikokun.register.payment.forChestShop.methods.ECO3());
dependencies.add("MultiCurrency");
} }
/** for (String plugin : toLoad){
* Used by the plugin to setup version Plugin pl = pm.getPlugin(plugin);
* if (pl != null){
* @param v version Method m = createMethod(pl);
*/ if (m != null) return m;
public static void setVersion(String v) { }
version = v; }
return null;
} }
/**
* Use to reset methods during disable
*/
public static void reset() {
version = null;
self = false;
Method = null;
preferred = "";
attachables.clear();
}
/**
* Use to get version of Register plugin
*
* @return version
*/
public static String getVersion() {
return version;
}
/**
* Returns an array of payment method names that have been loaded
* through the <code>init</code> method.
*
* @return <code>Set<String></code> - Array of payment methods that are loaded.
* @see #setMethod(org.bukkit.plugin.PluginManager)
*/
public static Set<String> getDependencies() {
return dependencies;
}
/**
* Interprets Plugin class data to verify whether it is compatible with an existing payment
* method to use for payments and other various economic activity.
*
* @param plugin Plugin data from bukkit, Internal Class file.
* @return Method <em>or</em> Null
*/
public static Method createMethod(Plugin plugin) { public static Method createMethod(Plugin plugin) {
for (Method method : methods){ for (Method method : methods){
if (method.isCompatible(plugin)) { if (method.isCompatible(plugin)) {
@ -109,129 +60,4 @@ public class Methods {
} }
return null; return null;
} }
private static void addMethod(String name, Method method) {
dependencies.add(name);
methods.add(method);
}
/**
* Verifies if Register has set a payment method for usage yet.
*
* @return <code>boolean</code>
* @see #setMethod(org.bukkit.plugin.PluginManager)
* @see #checkDisabled(org.bukkit.plugin.Plugin)
*/
public static boolean hasMethod() {
return (Method != null);
}
/**
* Checks Plugin Class against a multitude of checks to verify it's usability
* as a payment method.
*
* @param manager the plugin manager for the server
* @return <code>boolean</code> True on success, False on failure.
*/
public static boolean setMethod(PluginManager manager) {
if (hasMethod())
return true;
if (self) {
self = false;
return false;
}
int count = 0;
boolean match = false;
Plugin plugin;
for (String name : dependencies) {
if (hasMethod())
break;
plugin = manager.getPlugin(name);
if (plugin == null || !plugin.isEnabled())
continue;
Method current = createMethod(plugin);
if (current == null)
continue;
if (preferred.isEmpty())
Method = current;
else
attachables.add(current);
}
if (!preferred.isEmpty()) {
do {
if (hasMethod())
match = true;
else {
for (Method attached : attachables) {
if (attached == null) continue;
if (hasMethod()) {
match = true; break;
}
if (preferred.isEmpty())
Method = attached;
if (count == 0) {
if (preferred.equalsIgnoreCase(attached.getName())) Method = attached;
} else {
Method = attached;
}
}
count++;
}
} while (!match);
}
return hasMethod();
}
/**
* Sets the preferred economy
*
* @param check The plugin name to check
* @return <code>boolean</code>
*/
public static boolean setPreferred(String check) {
if (dependencies.contains(check)) {
preferred = check;
return true;
}
return false;
}
/**
* Grab the existing and initialized (hopefully) Method Class.
*
* @return <code>Method</code> <em>or</em> <code>Null</code>
*/
public static Method getMethod() {
return Method;
}
/**
* Verify is a plugin is disabled, only does this if we there is an existing payment
* method initialized in Register.
*
* @param method Plugin data from bukkit, Internal Class file.
* @return <code>boolean</code>
*/
public static boolean checkDisabled(Plugin method) {
if (!hasMethod())
return true;
if (Method.isCompatible(method))
Method = null;
return (Method == null);
}
} }

View File

@ -155,7 +155,7 @@ public class BOSE7 implements Method {
} }
} }
public class BOSEBankAccount implements MethodBankAccount { public class BOSEBankAccount implements MethodBankAccount, MethodAccount {
private String bank; private String bank;
private BOSEconomy BOSEconomy; private BOSEconomy BOSEconomy;

View File

@ -2,7 +2,7 @@ name: ChestShop
main: com.Acrobot.ChestShop.ChestShop main: com.Acrobot.ChestShop.ChestShop
version: 3.32 version: 3.34
author: Acrobot author: Acrobot
@ -10,7 +10,7 @@ description: >
A chest shop for economy plugins. A chest shop for economy plugins.
softdepend: [Permissions, LWC, Lockette, Deadbolt, OddItem, Towny, WorldGuard] softdepend: [Permissions, LWC, Lockette, Deadbolt, OddItem, Towny, WorldGuard, Vault, Heroes]
commands: commands:
iteminfo: iteminfo:
aliases: [iinfo] aliases: [iinfo]
@ -51,6 +51,8 @@ permissions:
description: Allows user to buy from a shop description: Allows user to buy from a shop
ChestShop.shop.sell: ChestShop.shop.sell:
description: Allows user to sell to a shop description: Allows user to sell to a shop
ChestShop.nofee:
description: User doesn't have to pay the shop creation fee.
ChestShop.admin: ChestShop.admin:
description: Allows user to modify/destroy other stores and create an Admin Shops description: Allows user to modify/destroy other stores and create an Admin Shops
default: op default: op