Breaking changes:

- Permissions 2/3 are no longer supported
- Changed ChestShop.shop.create permission to consist of 2 different permissions: ChestShop.shop.create.buy and ChestShop.shop.create.sell
- (Experimental) Ability to add max item prices to the config
- (Experimental) Added a custom "chestshop" WorldGuard flag using reflection

- Switched to new Config system
- Updated Metrics
- Removed chest masking option
This commit is contained in:
Acrobot 2012-03-01 22:03:59 +01:00
parent a49d51ce97
commit 7f8af7b5b3
27 changed files with 679 additions and 302 deletions

View File

@ -0,0 +1,30 @@
package com.Acrobot.ChestShop.BukkitFixes;
import com.Acrobot.ChestShop.Chests.MinecraftChest;
import net.minecraft.server.TileEntityChest;
import org.bukkit.block.Chest;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.inventory.CraftInventory;
import org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest;
import org.bukkit.inventory.Inventory;
/**
* Temporary class until this is fixed in Bukkit
* @author Acrobot
*/
public class bInventoryFix {
public static Inventory getInventory(Chest chest) {
MinecraftChest mchest = new MinecraftChest(chest);
TileEntityChest teChest = (TileEntityChest) ((CraftWorld) chest.getWorld()).getTileEntityAt(chest.getX(), chest.getY(), chest.getZ());
CraftInventory ci = new CraftInventory(teChest);
if (mchest.getNeighbor() != null) {
Chest nb = mchest.getNeighbor();
TileEntityChest neighbor = (TileEntityChest) ((CraftWorld) chest.getWorld()).getTileEntityAt(nb.getX(), nb.getY(), nb.getZ());
return new CraftInventoryDoubleChest(ci, new CraftInventory(neighbor));
}
return ci;
}
}

View File

@ -13,10 +13,10 @@ import com.Acrobot.ChestShop.Logging.FileWriterQueue;
import com.avaje.ebean.EbeanServer; import com.avaje.ebean.EbeanServer;
import com.lennardf1989.bukkitex.Database; import com.lennardf1989.bukkitex.Database;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.config.Configuration;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
@ -56,7 +56,6 @@ public class ChestShop extends JavaPlugin {
if (Config.getBoolean(Property.LOG_TO_DATABASE) || Config.getBoolean(Property.GENERATE_STATISTICS_PAGE)) setupDB(); if (Config.getBoolean(Property.LOG_TO_DATABASE) || Config.getBoolean(Property.GENERATE_STATISTICS_PAGE)) setupDB();
if (Config.getBoolean(Property.GENERATE_STATISTICS_PAGE)) scheduleTask(new Generator(), 300L, (long) Config.getDouble(Property.STATISTICS_PAGE_GENERATION_INTERVAL) * 20L); if (Config.getBoolean(Property.GENERATE_STATISTICS_PAGE)) scheduleTask(new Generator(), 300L, (long) Config.getDouble(Property.STATISTICS_PAGE_GENERATION_INTERVAL) * 20L);
if (Config.getBoolean(Property.LOG_TO_FILE)) scheduleTask(new FileWriterQueue(), 201L, 201L); if (Config.getBoolean(Property.LOG_TO_FILE)) scheduleTask(new FileWriterQueue(), 201L, 201L);
//if (Config.getBoolean(Property.MASK_CHESTS_AS_OTHER_BLOCKS)) scheduleTask(new MaskChest(), 40L, 40L); //Disabled due to bug //TODO Fix that
playerInteract.interval = Config.getInteger(Property.SHOP_INTERACTION_INTERVAL); playerInteract.interval = Config.getInteger(Property.SHOP_INTERACTION_INTERVAL);
//Register our commands! //Register our commands!
@ -65,12 +64,10 @@ public class ChestShop extends JavaPlugin {
//Start the statistics pinger //Start the statistics pinger
startStatistics(); startStatistics();
System.out.println('[' + getPluginName() + "] version " + getVersion() + " initialized!");
} }
public void onDisable() { public void onDisable() {
System.out.println('[' + getPluginName() + "] version " + getVersion() + " shutting down!"); getServer().getScheduler().cancelTasks(this);
} }
////////////////// REGISTER EVENTS, SCHEDULER & STATS /////////////////////////// ////////////////// REGISTER EVENTS, SCHEDULER & STATS ///////////////////////////
@ -97,10 +94,8 @@ public class ChestShop extends JavaPlugin {
} }
///////////////////// DATABASE STUFF //////////////////////////////// ///////////////////// DATABASE STUFF ////////////////////////////////
private static Configuration getBukkitConfig() { private static YamlConfiguration getBukkitConfig() {
Configuration config = new Configuration(new File("bukkit.yml")); return YamlConfiguration.loadConfiguration(new File("bukkit.yml"));
config.load();
return config;
} }
private static Database database; private static Database database;
@ -114,7 +109,7 @@ public class ChestShop extends JavaPlugin {
} }
}; };
Configuration config = getBukkitConfig(); YamlConfiguration config = getBukkitConfig();
database.initializeDatabase( database.initializeDatabase(
config.getString("database.driver"), config.getString("database.driver"),
@ -150,7 +145,7 @@ public class ChestShop extends JavaPlugin {
return DB; return DB;
} }
public static ArrayList getDependencies() { public static List getDependencies() {
return (ArrayList) description.getSoftDepend(); return (List) description.getSoftDepend();
} }
} }

View File

@ -74,7 +74,7 @@ public class MinecraftChest implements ChestObject {
return main.getInventory().getSize() + (neighbor != null ? neighbor.getInventory().getSize() : 0); return main.getInventory().getSize() + (neighbor != null ? neighbor.getInventory().getSize() : 0);
} }
private Chest getNeighbor() { public Chest getNeighbor() {
return uBlock.findNeighbor(main); return uBlock.findNeighbor(main);
} }

View File

@ -20,6 +20,10 @@ public class Config {
public static float getFloat(Property value) { public static float getFloat(Property value) {
return new Float(getValue(value.name()).toString()); return new Float(getValue(value.name()).toString());
} }
public static float getFloat(String value) {
return new Float(getValue(value).toString());
}
public static String getString(Property value) { public static String getString(Property value) {
return (String) getValue(value.name()); return (String) getValue(value.name());
@ -40,6 +44,10 @@ public class Config {
public static String getLocal(Language lang) { public static String getLocal(Language lang) {
return getColored(config.getLanguageConfig().getString(Language.prefix.name()) + config.getLanguageConfig().getString(lang.name())); return getColored(config.getLanguageConfig().getString(Language.prefix.name()) + config.getLanguageConfig().getString(lang.name()));
} }
public static boolean exists(String value) {
return getValue(value) != null;
}
private static Object getValue(String node) { private static Object getValue(String node) {
return config.getProperty(node); return config.getProperty(node);

View File

@ -2,7 +2,9 @@ package com.Acrobot.ChestShop.Config;
import com.Acrobot.ChestShop.ChestShop; import com.Acrobot.ChestShop.ChestShop;
import com.Acrobot.ChestShop.Utils.uLongName; import com.Acrobot.ChestShop.Utils.uLongName;
import org.bukkit.util.config.Configuration; import org.bukkit.configuration.Configuration;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
@ -13,35 +15,33 @@ import java.io.FileWriter;
public class ConfigObject { public class ConfigObject {
private final File configFile = new File(ChestShop.folder, "config.yml"); private final File configFile = new File(ChestShop.folder, "config.yml");
private final File langFile = new File(ChestShop.folder, "local.yml"); private final File langFile = new File(ChestShop.folder, "local.yml");
private final Configuration config = new Configuration(configFile); private final YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
private final Configuration language = new Configuration(langFile); private final YamlConfiguration language = YamlConfiguration.loadConfiguration(langFile);
public ConfigObject() { public ConfigObject() {
if (!ChestShop.folder.exists()) ChestShop.folder.mkdir(); if (!ChestShop.folder.exists()) ChestShop.folder.mkdir();
reloadConfig(); reloadConfig();
config.load(); load(config, configFile);
reloadLanguage(); reloadLanguage();
language.load(); load(language, langFile);
uLongName.config = new Configuration(new File(ChestShop.folder, "longName.storage")); uLongName.configFile = new File(ChestShop.folder, "longName.storage");
uLongName.config.load(); uLongName.config = YamlConfiguration.loadConfiguration(uLongName.configFile);
} }
private void reloadConfig() { private void reloadConfig() {
config.load();
for (Property def : Property.values()) { for (Property def : Property.values()) {
if (config.getProperty(def.name()) == null) { if (config.get(def.name()) == null) {
writeToFile('\n' + def.name() + ": " + def.getValue() + "\n#" + def.getComment(), configFile); writeToFile('\n' + def.name() + ": " + def.getValue() + "\n#" + def.getComment(), configFile);
} }
} }
} }
private void reloadLanguage() { private void reloadLanguage() {
language.load();
for (Language def : Language.values()) { for (Language def : Language.values()) {
if (language.getProperty(def.name()) == null) { if (language.get(def.name()) == null) {
writeToFile('\n' + def.name() + ": \"" + def.toString() + '\"', langFile); writeToFile('\n' + def.name() + ": \"" + def.toString() + '\"', langFile);
} }
} }
@ -62,6 +62,27 @@ public class ConfigObject {
} }
public Object getProperty(String property) { public Object getProperty(String property) {
return config.getProperty(property); return config.get(property);
}
public static void load(FileConfiguration config, File file) {
try {
config.load(file);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void save(FileConfiguration config, File file) {
try {
config.save(file);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void reloadConfig(FileConfiguration config, File file) {
save(config, file);
load(config, file);
} }
} }

View File

@ -0,0 +1,29 @@
package com.Acrobot.ChestShop.Config;
import org.bukkit.Material;
/**
* @author Acrobot
*/
public class MaxPrice {
public static boolean canCreate(float buyPrice, float sellPrice, Material mat) {
float bPrice = maxBuyPrice(mat.getId());
float sPrice = maxSellPrice(mat.getId());
return (bPrice == -1 || buyPrice <= maxBuyPrice(mat.getId()))
&& (sPrice == -1 || sellPrice <= maxSellPrice(mat.getId()));
}
public static float maxBuyPrice(int itemID) {
return getPrice("buy", itemID);
}
public static float maxSellPrice(int itemID) {
return getPrice("sell", itemID);
}
public static float getPrice(String value, int itemID) {
String node = "max-" + value + "-price-" + itemID;
return Config.exists(node) ? Config.getFloat(node) : -1;
}
}

View File

@ -21,14 +21,13 @@ public enum Property {
USE_BUILT_IN_PROTECTION(true, "Do you want to use built-in protection against chest destruction?"), USE_BUILT_IN_PROTECTION(true, "Do you want to use built-in protection against chest destruction?"),
PROTECT_CHEST_WITH_LWC(false, "Do you want to protect shop chests with LWC?"), PROTECT_CHEST_WITH_LWC(false, "Do you want to protect shop chests with LWC?"),
PROTECT_SIGN_WITH_LWC(false, "Do you want to protect shop signs with LWC?"), PROTECT_SIGN_WITH_LWC(false, "Do you want to protect shop signs with LWC?"),
//MASK_CHESTS_AS_OTHER_BLOCKS(false, "Do you want to mask shop chests as other blocks? HIGHLY EXPERIMENTAL, CAN LAG!"),
IGNORE_CREATIVE_MODE(true, "Do you want to allow using shops to people in creative mode?"), IGNORE_CREATIVE_MODE(true, "Do you want to allow using shops to people in creative mode?"),
SHOW_MESSAGE_OUT_OF_STOCK(true, "Do you want to show \"Out of stock\" messages?"), SHOW_MESSAGE_OUT_OF_STOCK(true, "Do you want to show \"Out of stock\" messages?"),
SHOW_TRANSACTION_INFORMATION_CLIENT(true, "Do you want to show \"You bought/sold... \" messages?"), SHOW_TRANSACTION_INFORMATION_CLIENT(true, "Do you want to show \"You bought/sold... \" messages?"),
SHOW_TRANSACTION_INFORMATION_OWNER(true, "Do you want to show \"Somebody bought/sold... \" messages?"), SHOW_TRANSACTION_INFORMATION_OWNER(true, "Do you want to show \"Somebody bought/sold... \" messages?"),
TOWNY_INTEGRATION(false, "Do you want to only let people build inside shop plots?"), TOWNY_INTEGRATION(false, "Do you want to only let people build inside shop plots?"),
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 regions with /region flag chestshop allowed?"),
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"), 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?"),

View File

@ -17,13 +17,17 @@ public class Generator implements Runnable {
private static double generationTime; private static double generationTime;
private static final String header = fileToString("header"); private static String header;
private static final String row = fileToString("row"); private static String row;
private static final String footer = fileToString("footer"); private static String footer;
private static BufferedWriter buf; private static BufferedWriter buf;
public void run() { public void run() {
header = fileToString("header");
row = fileToString("row");
footer = fileToString("footer");
if (row.isEmpty()) System.out.println(ChestShop.chatPrefix + "You lack the necessary HTML files in your plugins/ChestShop/HTML folder!"); if (row.isEmpty()) System.out.println(ChestShop.chatPrefix + "You lack the necessary HTML files in your plugins/ChestShop/HTML folder!");
generateStats(); generateStats();
} }
@ -42,7 +46,7 @@ public class Generator implements Runnable {
private static String fileToString(String fileName) { private static String fileToString(String fileName) {
try { try {
File f = new File(ChestShop.folder + "/HTML/" + fileName + ".html"); File f = new File(ChestShop.folder + File.separator + "HTML" + File.separator + fileName + ".html");
FileReader rd = new FileReader(f); FileReader rd = new FileReader(f);
char[] buf = new char[(int) f.length()]; char[] buf = new char[(int) f.length()];
rd.read(buf); rd.read(buf);
@ -113,6 +117,7 @@ public class Generator implements Runnable {
private static void generateStats() { private static void generateStats() {
try { try {
File f = new File(filePath).getParentFile(); File f = new File(filePath).getParentFile();
if (!f.exists()) f.mkdir(); if (!f.exists()) f.mkdir();

View File

@ -19,7 +19,8 @@ public class Queue implements Runnable {
} }
public void run() { public void run() {
deleteOld(); if (Config.getInteger(Property.RECORD_TIME_TO_LIVE) != -1)
deleteOld();
ChestShop.getDB().save(queue); ChestShop.getDB().save(queue);
queue.clear(); queue.clear();

View File

@ -58,6 +58,8 @@ public class Items {
String first = split[0]; String first = split[0];
String[] space = first.split(" "); String[] space = first.split(" ");
if (space.length == 0) return null;
Material material = getMaterial(first); Material material = getMaterial(first);
for (int i = (space.length > 1 ? 1 : 0); i >= 0 && material == null; i--) material = getMaterial(space[i]); for (int i = (space.length > 1 ? 1 : 0); i >= 0 && material == null; i--) material = getMaterial(space[i]);

View File

@ -1,5 +1,6 @@
package com.Acrobot.ChestShop.Listeners; package com.Acrobot.ChestShop.Listeners;
import com.Acrobot.ChestShop.BukkitFixes.bInventoryFix;
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;
@ -9,21 +10,18 @@ import com.Acrobot.ChestShop.Shop.ShopManagement;
import com.Acrobot.ChestShop.Signs.restrictedSign; import com.Acrobot.ChestShop.Signs.restrictedSign;
import com.Acrobot.ChestShop.Utils.uBlock; import com.Acrobot.ChestShop.Utils.uBlock;
import com.Acrobot.ChestShop.Utils.uSign; import com.Acrobot.ChestShop.Utils.uSign;
import net.minecraft.server.IInventory;
import net.minecraft.server.InventoryLargeChest;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.Chest; import org.bukkit.block.Chest;
import org.bukkit.block.Sign; import org.bukkit.block.Sign;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.craftbukkit.inventory.CraftInventory;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.block.Action; import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.Inventory;
import java.util.HashMap; import java.util.HashMap;
@ -96,12 +94,7 @@ public class playerInteract implements Listener {
player.sendMessage(Config.getLocal(Language.NO_CHEST_DETECTED)); player.sendMessage(Config.getLocal(Language.NO_CHEST_DETECTED));
return; return;
} }
Inventory chestInv = bInventoryFix.getInventory(chest);
IInventory inventory = ((CraftInventory) chest.getInventory()).getInventory(); player.openInventory(chestInv);
chest = uBlock.findNeighbor(chest);
if (chest != null) inventory = new InventoryLargeChest("Large chest", inventory, ((CraftInventory) chest.getInventory()).getInventory());
((CraftPlayer) player).getHandle().a(inventory); //Show inventory on the screen
} }
} }

View File

@ -5,17 +5,15 @@ import com.Acrobot.ChestShop.Economy.NoProvider;
import com.Acrobot.ChestShop.Economy.Register; import com.Acrobot.ChestShop.Economy.Register;
import com.Acrobot.ChestShop.Economy.Vault; 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.Protection.Plugins.*; import com.Acrobot.ChestShop.Protection.Plugins.*;
import com.Acrobot.ChestShop.Protection.Security; import com.Acrobot.ChestShop.Protection.Security;
import com.Acrobot.ChestShop.Utils.WorldGuard.uWorldGuard;
import com.Acrobot.ChestShop.Utils.uHeroes; 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.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.herocraftonline.dev.heroes.Heroes;
import com.nijikokun.bukkit.Permissions.Permissions;
import com.nijikokun.register.payment.forChestShop.Method; 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;
@ -50,14 +48,12 @@ public class pluginEnable {
} }
Register.eco = m; Register.eco = m;
com.Acrobot.ChestShop.Economy.Economy.economy = new Register(); com.Acrobot.ChestShop.Economy.Economy.economy = new Register();
System.out.println(ChestShop.chatPrefix + m.getName() + " loaded."); System.out.println(ChestShop.chatPrefix + m.getName() + " version " + 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("LWC")) {
Permission.permissions = ((Permissions) plugin).getHandler();
} else if (name.equals("LWC")) {
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")) {
@ -77,6 +73,7 @@ public class pluginEnable {
uSign.towny = (Towny) plugin; uSign.towny = (Towny) plugin;
} else if (name.equals("WorldGuard")) { } else if (name.equals("WorldGuard")) {
uWorldGuard.worldGuard = (WorldGuardPlugin) plugin; uWorldGuard.worldGuard = (WorldGuardPlugin) plugin;
uWorldGuard.injectHax(); //Inject hax into WorldGuard
} else if (name.equals("Vault")) { } else if (name.equals("Vault")) {
if (com.Acrobot.ChestShop.Economy.Economy.economy != null) return; if (com.Acrobot.ChestShop.Economy.Economy.economy != null) return;
RegisteredServiceProvider<Economy> rsp = ChestShop.getBukkitServer().getServicesManager().getRegistration(Economy.class); RegisteredServiceProvider<Economy> rsp = ChestShop.getBukkitServer().getServicesManager().getRegistration(Economy.class);
@ -90,6 +87,8 @@ public class pluginEnable {
} else if (name.equals("SimpleChestLock")) { } else if (name.equals("SimpleChestLock")) {
SCLplugin.scl = (SCL) plugin; SCLplugin.scl = (SCL) plugin;
Security.protections.add(new SCLplugin()); Security.protections.add(new SCLplugin());
} else {
return;
} }
PluginDescriptionFile description = plugin.getDescription(); PluginDescriptionFile description = plugin.getDescription();

View File

@ -2,6 +2,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.MaxPrice;
import com.Acrobot.ChestShop.Config.Property; import com.Acrobot.ChestShop.Config.Property;
import com.Acrobot.ChestShop.Economy.Economy; import com.Acrobot.ChestShop.Economy.Economy;
import com.Acrobot.ChestShop.Items.Items; import com.Acrobot.ChestShop.Items.Items;
@ -9,6 +10,7 @@ import com.Acrobot.ChestShop.Permission;
import com.Acrobot.ChestShop.Protection.Security; import com.Acrobot.ChestShop.Protection.Security;
import com.Acrobot.ChestShop.Signs.restrictedSign; import com.Acrobot.ChestShop.Signs.restrictedSign;
import com.Acrobot.ChestShop.Utils.*; import com.Acrobot.ChestShop.Utils.*;
import com.Acrobot.ChestShop.Utils.WorldGuard.uWorldGuard;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
@ -38,18 +40,12 @@ public class signChange implements Listener {
boolean playerIsAdmin = Permission.has(player, Permission.ADMIN); boolean playerIsAdmin = Permission.has(player, Permission.ADMIN);
if (isAlmostReady) { if (isAlmostReady) {
if (mat == null) { if (mat == null) {
player.sendMessage(Config.getLocal(Language.INCORRECT_ITEM_ID)); player.sendMessage(Config.getLocal(Language.INCORRECT_ITEM_ID));
dropSign(event); dropSign(event);
return; return;
} }
if (!canCreateShop(player, mat.getId())) {
player.sendMessage(Config.getLocal(Language.YOU_CANNOT_CREATE_SHOP));
dropSign(event);
return;
}
} else { } else {
if (restrictedSign.isRestricted(line)) { if (restrictedSign.isRestricted(line)) {
if (!restrictedSign.hasPermission(player, line)) { if (!restrictedSign.hasPermission(player, line)) {
@ -91,8 +87,9 @@ public class signChange implements Listener {
} }
Block chestBlock = chest.getBlock(); Block chestBlock = chest.getBlock();
boolean cantBuildTowny = uSign.towny != null && !uTowny.canBuild(player, signBlock.getLocation(), chestBlock.getLocation());
if (!uWorldGuard.isNotOutsideWGplot(signBlock.getLocation()) || (uSign.towny != null && !uTowny.canBuild(player, signBlock.getLocation(), chestBlock.getLocation()))) { if (!uWorldGuard.canBuildShopHere(signBlock.getLocation()) && cantBuildTowny){
player.sendMessage(Config.getLocal(Language.TOWNY_CANNOT_CREATE_SHOP_HERE)); player.sendMessage(Config.getLocal(Language.TOWNY_CANNOT_CREATE_SHOP_HERE));
dropSign(event); dropSign(event);
return; return;
@ -107,7 +104,14 @@ public class signChange implements Listener {
} }
} }
float buyPrice = uSign.buyPrice(thirdLine);
float sellPrice = uSign.sellPrice(thirdLine);
if (!playerIsAdmin && (!canCreateShop(player, mat.getId(), buyPrice != -1, sellPrice != -1) || !MaxPrice.canCreate(buyPrice, sellPrice, mat))) {
player.sendMessage(Config.getLocal(Language.YOU_CANNOT_CREATE_SHOP));
dropSign(event);
return;
}
float shopCreationPrice = Config.getFloat(Property.SHOP_CREATION_PRICE); float shopCreationPrice = Config.getFloat(Property.SHOP_CREATION_PRICE);
boolean paid = shopCreationPrice != 0 && !isAdminShop && !Permission.has(player, Permission.NOFEE); boolean paid = shopCreationPrice != 0 && !isAdminShop && !Permission.has(player, Permission.NOFEE);
@ -134,14 +138,13 @@ public class signChange implements Listener {
uHeroes.addHeroExp(player); uHeroes.addHeroExp(player);
} }
private static boolean canCreateShop(Player player, boolean isAdmin, int ID) { private static boolean canCreateShop(Player player, int ID, boolean buy, boolean sell) {
return isAdmin || if (Permission.has(player, Permission.SHOP_CREATION_ID + Integer.toString(ID))) return true;
Permission.has(player, Permission.SHOP_CREATION) ||
Permission.has(player, Permission.SHOP_CREATION.toString() + '.' + ID); if (buy && !Permission.has(player, Permission.SHOP_CREATION_BUY)) return false;
} if (sell && !Permission.has(player, Permission.SHOP_CREATION_SELL)) return false;
private static boolean canCreateShop(Player player, int ID) { return true;
return canCreateShop(player, Permission.has(player, Permission.ADMIN), ID);
} }
private static String formatThirdLine(String thirdLine) { private static String formatThirdLine(String thirdLine) {

View File

@ -1,92 +1,63 @@
package com.Acrobot.ChestShop;/* package com.Acrobot.ChestShop;
* Copyright 2011 Tyler Blair. All rights reserved.
* /*
* Redistribution and use in source and binary forms, with or without modification, are * Copyright 2011 Tyler Blair. All rights reserved.
* permitted provided that the following conditions are met: *
* * Redistribution and use in source and binary forms, with or without modification, are
* 1. Redistributions of source code must retain the above copyright notice, this list of * permitted provided that the following conditions are met:
* conditions and the following disclaimer. *
* * 1. Redistributions of source code must retain the above copyright notice, this list of
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * conditions and the following disclaimer.
* of conditions and the following disclaimer in the documentation and/or other materials *
* provided with the distribution. * 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
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED * provided with the distribution.
* 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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 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
* The views and conclusions contained in the software and documentation are those of the * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* authors and contributors and should not be interpreted as representing official policies, *
* either expressed or implied, of anybody else. * 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.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import java.io.*; 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.Proxy;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.*; import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
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 { public class Metrics {
/** /**
* Interface used to collect custom data for a plugin * The current revision number
*/ */
public static abstract class Plotter { private final static int REVISION = 5;
/**
* 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();
/**
* Called after the website graphs have been updated
*/
public void reset() {
}
@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 = 4;
/** /**
* The base url of the metrics domain * The base url of the metrics domain
@ -104,14 +75,25 @@ public class Metrics {
private static final String CONFIG_FILE = "plugins/PluginMetrics/config.yml"; private static final String CONFIG_FILE = "plugins/PluginMetrics/config.yml";
/** /**
* Interval of time to ping in minutes * The separator to use for custom data. This MUST NOT change unless you are hosting your own
* version of metrics and want to change it.
*/
private static final String CUSTOM_DATA_SEPARATOR = "~~";
/**
* Interval of time to ping (in minutes)
*/ */
private final static int PING_INTERVAL = 10; private final static int PING_INTERVAL = 10;
/** /**
* A map of the custom data plotters for plugins * A map of all of the graphs for each plugin
*/ */
private Map<Plugin, Set<Plotter>> customData = Collections.synchronizedMap(new HashMap<Plugin, Set<Plotter>>()); private Map<Plugin, Set<Graph>> graphs = Collections.synchronizedMap(new HashMap<Plugin, Set<Graph>>());
/**
* A convenient map of the default Graph objects (used by addCustomData mainly)
*/
private Map<Plugin, Graph> defaultGraphs = Collections.synchronizedMap(new HashMap<Plugin, Graph>());
/** /**
* The plugin configuration file * The plugin configuration file
@ -142,6 +124,33 @@ public class Metrics {
guid = configuration.getString("guid"); guid = configuration.getString("guid");
} }
/**
* Construct and create a Graph that can be used to separate specific plotters to their own graphs
* on the metrics website. Plotters can be added to the graph object returned.
*
* @param plugin
* @param type
* @param name
* @return Graph object created. Will never return NULL under normal circumstances unless bad parameters are given
*/
public Graph createGraph(Plugin plugin, Graph.Type type, String name) {
if (plugin == null || type == null || name == null) {
throw new IllegalArgumentException("All arguments must not be null");
}
// Construct the graph object
Graph graph = new Graph(type, name);
// Get the graphs for the plugin
Set<Graph> graphs = getOrCreateGraphs(plugin);
// Now we can add our graph
graphs.add(graph);
// and return back
return graph;
}
/** /**
* Adds a custom data plotter for a given plugin * Adds a custom data plotter for a given plugin
* *
@ -149,14 +158,14 @@ public class Metrics {
* @param plotter * @param plotter
*/ */
public void addCustomData(Plugin plugin, Plotter plotter) { public void addCustomData(Plugin plugin, Plotter plotter) {
Set<Plotter> plotters = customData.get(plugin); // The default graph for the plugin
Graph graph = getOrCreateDefaultGraph(plugin);
if (plotters == null) { // Add the plotter to the graph o/
plotters = Collections.synchronizedSet(new LinkedHashSet<Plotter>()); graph.addPlotter(plotter);
customData.put(plugin, plotters);
}
plotters.add(plotter); // Ensure the default graph is included in the submitted graphs
getOrCreateGraphs(plugin).add(graph);
} }
/** /**
@ -164,33 +173,31 @@ public class Metrics {
* *
* @param plugin * @param plugin
*/ */
public void beginMeasuringPlugin(final Plugin plugin) throws IOException { public void beginMeasuringPlugin(final Plugin plugin) {
// Did we opt out? // Did we opt out?
if (configuration.getBoolean("opt-out", false)) { if (configuration.getBoolean("opt-out", false)) {
return; return;
} }
// First tell the server about us // Begin hitting the server with glorious data
plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, new Runnable() {
public void run() {
try {
postPlugin(plugin, false);
} catch (IOException e) {
System.out.println("[Metrics] " + e.getMessage());
}
}
}, 20L);
// Ping the server in intervals
plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable() { plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable() {
private boolean firstPost = true;
public void run() { public void run() {
try { try {
postPlugin(plugin, true); // We use the inverse of firstPost because if it is the first time we are posting,
// it is not a interval ping, so it evaluates to FALSE
// Each time thereafter it will evaluate to TRUE, i.e PING!
postPlugin(plugin, !firstPost);
// After the first post we set firstPost to false
// Each post thereafter will be a ping
firstPost = false;
} catch (IOException e) { } catch (IOException e) {
System.out.println("[Metrics] " + e.getMessage()); System.out.println("[Metrics] " + e.getMessage());
} }
} }
}, PING_INTERVAL * 1200, PING_INTERVAL * 1200); }, 0, PING_INTERVAL * 1200);
} }
/** /**
@ -199,26 +206,61 @@ public class Metrics {
* @param plugin * @param plugin
*/ */
private void postPlugin(Plugin plugin, boolean isPing) throws IOException { private void postPlugin(Plugin plugin, boolean isPing) throws IOException {
// The plugin's description file containg all of the plugin data such as name, version, author, etc
PluginDescriptionFile description = plugin.getDescription();
// The author string, created with description.getAuthors()
// Authors are separated by a comma
String authors = "";
// Add each author to the string
for (String author : description.getAuthors()) {
authors += author + ", ";
}
// If there were any authors at all, we need to remove the last 2 characters
// the last 2 characters are the last comma and space
if (!authors.isEmpty()) {
authors = authors.substring(0, authors.length() - 2);
}
// Construct the post data // Construct the post data
String response = "ERR No response"; String data = encode("guid") + '=' + encode(guid)
StringBuilder data = new StringBuilder(10); + encodeDataPair("authors", authors)
data.append(encode("guid")).append('=').append(encode(guid)) + encodeDataPair("version", description.getVersion())
.append(gField("version", plugin.getDescription().getVersion())) + encodeDataPair("server", Bukkit.getVersion())
.append(gField("server", Bukkit.getVersion())) + encodeDataPair("players", Integer.toString(Bukkit.getServer().getOnlinePlayers().length))
.append(gField("players", String.valueOf(Bukkit.getServer().getOnlinePlayers().length))) + encodeDataPair("revision", String.valueOf(REVISION));
.append(gField("revision", String.valueOf(REVISION)));
// If we're pinging, append it // If we're pinging, append it
if (isPing) { if (isPing) {
data.append(gField("ping", "true")); data += encodeDataPair("ping", "true");
} }
// Add any custom data (if applicable) // Add any custom data available for the plugin
Set<Plotter> plotters = customData.get(plugin); Set<Graph> graphs = getOrCreateGraphs(plugin);
if (plotters != null) { // Acquire a lock on the graphs, which lets us make the assumption we also lock everything
for (Plotter plotter : plotters) { // inside of the graph (e.g plotters)
data.append(gField("Custom" + plotter.getColumnName(), Integer.toString(plotter.getValue()))); synchronized(graphs) {
for (Graph graph : graphs) {
// Because we have a lock on the graphs set already, it is reasonable to assume
// that our lock transcends down to the individual plotters in the graphs also.
// Because our methods are private, no one but us can reasonably access this list
// without reflection so this is a safe assumption without adding more code.
for (Plotter plotter : graph.getPlotters()) {
// The key name to send to the metrics server
// The format is C-GRAPHNAME-PLOTTERNAME where separator - is defined at the top
// Legacy (R4) submitters use the format Custom%s, or CustomPLOTTERNAME
String key = String.format("C%s%s%s%s", CUSTOM_DATA_SEPARATOR, graph.getName(), CUSTOM_DATA_SEPARATOR, plotter.getColumnName());
// The value to send, which for the foreseeable future is just the string
// value of plotter.getValue()
String value = Integer.toString(plotter.getValue());
// Add it to the http post data :)
data += encodeDataPair(key, value);
}
} }
} }
@ -226,17 +268,26 @@ public class Metrics {
URL url = new URL(BASE_URL + String.format(REPORT_URL, plugin.getDescription().getName())); URL url = new URL(BASE_URL + String.format(REPORT_URL, plugin.getDescription().getName()));
// Connect to the website // Connect to the website
URLConnection connection = url.openConnection(); URLConnection connection;
// Mineshafter creates a socks proxy, so we can safely bypass it
// It does not reroute POST requests so we need to go around it
if (isMineshafterPresent()) {
connection = url.openConnection(Proxy.NO_PROXY);
} else {
connection = url.openConnection();
}
connection.setDoOutput(true); connection.setDoOutput(true);
// Write the data // Write the data
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream()); OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
writer.write(data.toString()); writer.write(data);
writer.flush(); writer.flush();
// Now read the response // Now read the response
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
response = reader.readLine(); String response = reader.readLine();
// close resources // close resources
writer.close(); writer.close();
@ -247,9 +298,15 @@ public class Metrics {
} else { } else {
// Is this the first update this hour? // Is this the first update this hour?
if (response.contains("OK This is your first update this hour")) { if (response.contains("OK This is your first update this hour")) {
if (plotters != null) { synchronized (graphs) {
for (Plotter plotter : plotters) { Iterator<Graph> iter = graphs.iterator();
plotter.reset();
while (iter.hasNext()) {
Graph graph = iter.next();
for (Plotter plotter : graph.getPlotters()) {
plotter.reset();
}
} }
} }
} }
@ -258,14 +315,68 @@ public class Metrics {
} }
/** /**
* Generates a field * Get or create the Set of graphs for a specific plugin
* @param name Field name *
* @param data Data assigned to the field * @param plugin
* @return Field * @return
* @throws UnsupportedEncodingException
*/ */
private static String gField(String name, String data) throws UnsupportedEncodingException { private Set<Graph> getOrCreateGraphs(Plugin plugin) {
return '&' + encode(name) + '=' + encode(data); Set<Graph> theGraphs = graphs.get(plugin);
// Create the Set if it does not already exist
if (theGraphs == null) {
theGraphs = Collections.synchronizedSet(new HashSet<Graph>());
graphs.put(plugin, theGraphs);
}
return theGraphs;
}
/**
* Get the default graph for a plugin and if it does not exist, create one
*
* @param plugin
* @return
*/
private Graph getOrCreateDefaultGraph(Plugin plugin) {
Graph graph = defaultGraphs.get(plugin);
// Not yet created :(
if (graph == null) {
graph = new Graph(Graph.Type.Line, "Default");
defaultGraphs.put(plugin, graph);
}
return graph;
}
/**
* Check if mineshafter is present. If it is, we need to bypass it to send POST requests
*
* @return
*/
private static boolean isMineshafterPresent() {
try {
Class.forName("mineshafter.MineServer");
return true;
} catch (Exception e) {
return false;
}
}
/**
* Encode a key/value data pair to be used in a HTTP post request. This INCLUDES a & so the first
* key/value pair MUST be included manually, e.g:
* <p>
* String httpData = encode("guid") + "=" + encode("1234") + encodeDataPair("authors") + "..";
* </p>
*
* @param key
* @param value
* @return
*/
private static String encodeDataPair(String key, String value) throws UnsupportedEncodingException {
return '&' + encode(key) + '=' + encode(value);
} }
/** /**
@ -278,4 +389,177 @@ public class Metrics {
return URLEncoder.encode(text, "UTF-8"); return URLEncoder.encode(text, "UTF-8");
} }
/**
* Represents a custom graph on the website
*/
public static class Graph {
/**
* The graph's type that will be visible on the website
*/
public static enum Type {
/**
* A simple line graph which also includes a scrollable timeline viewer to view
* as little or as much of the data as possible.
*/
Line,
/**
* An area graph. This is the same as a line graph except the area under the curve is shaded
*/
Area,
/**
* A column graph, which is a graph where the data is represented by columns on the vertical axis,
* i.e they go up and down.
*/
Column,
/**
* A pie graph. The graph is generated by taking the data for the last hour and summing it
* together. Then the percentage for each plotter is calculated via round( (plot / total) * 100, 2 )
*/
Pie
}
/**
* What the graph should be plotted as
*/
private final Type type;
/**
* The graph's name, alphanumeric and spaces only :)
* If it does not comply to the above when submitted, it is rejected
*/
private final String name;
/**
* The set of plotters that are contained within this graph
*/
private final Set<Plotter> plotters = new LinkedHashSet<Plotter>();
private Graph(Type type, String name) {
this.type = type;
this.name = name;
}
/**
* Gets the graph's name
*
* @return
*/
public String getName() {
return name;
}
/**
* Add a plotter to the graph, which will be used to plot entries
*
* @param plotter
*/
public void addPlotter(Plotter plotter) {
plotters.add(plotter);
}
/**
* Remove a plotter from the graph
*
* @param plotter
*/
public void removePlotter(Plotter plotter) {
plotters.remove(plotter);
}
/**
* Gets an <b>unmodifiable</b> set of the plotter objects in the graph
* @return
*/
public Set<Plotter> getPlotters() {
return Collections.unmodifiableSet(plotters);
}
@Override
public int hashCode() {
return (type.hashCode() * 17) ^ name.hashCode();
}
@Override
public boolean equals(Object object) {
if (!(object instanceof Graph)) {
return false;
}
Graph graph = (Graph) object;
return graph.type == type && graph.name.equals(name);
}
}
/**
* Interface used to collect custom data for a plugin
*/
public static abstract class Plotter {
/**
* The plot's name
*/
private final String name;
/**
* Construct a plotter with the default plot name
*/
public Plotter() {
this("Default");
}
/**
* Construct a plotter with a specific plot name
*
* @param name
*/
public Plotter(String name) {
this.name = name;
}
/**
* Get the current value for the plotted point
*
* @return
*/
public abstract int getValue();
/**
* Get the column name for the plotted point
*
* @return the plotted point's column name
*/
public String getColumnName() {
return name;
}
/**
* Called after the website graphs have been updated
*/
public void reset() {
}
@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.name.equals(name) && plotter.getValue() == getValue();
}
}
} }

View File

@ -1,17 +1,22 @@
package com.Acrobot.ChestShop; package com.Acrobot.ChestShop;
import com.nijiko.permissions.PermissionHandler;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/** /**
* @author Acrobot * @author Acrobot
*/ */
public enum Permission { public enum Permission {
SHOP_CREATION("ChestShop.shop.create"), SHOP_CREATION_BUY("ChestShop.shop.create.buy"),
SHOP_CREATION_SELL("ChestShop.shop.create.sell"),
SHOP_CREATION_ID("ChestShop.shop.create."),
BUY("ChestShop.shop.buy"), BUY("ChestShop.shop.buy"),
BUY_ID("ChestShop.shop.buy."), BUY_ID("ChestShop.shop.buy."),
SELL_ID("ChestShop.shop.sell."), SELL_ID("ChestShop.shop.sell."),
SELL("ChestShop.shop.sell"), SELL("ChestShop.shop.sell"),
ADMIN("ChestShop.admin"), ADMIN("ChestShop.admin"),
MOD("ChestShop.mod"), MOD("ChestShop.mod"),
OTHER_NAME("ChestShop.name."), OTHER_NAME("ChestShop.name."),
@ -24,21 +29,17 @@ public enum Permission {
this.permission = permission; this.permission = permission;
} }
public static PermissionHandler permissions;
public static boolean has(Player player, Permission permission) { public static boolean has(Player player, Permission permission) {
return has(player, permission.permission); return has(player, permission.permission);
} }
public static boolean has(Player player, String node) { public static boolean has(Player player, String node) {
if (permissions != null) return permissions.has(player, node) || permissions.has(player, node.toLowerCase());
return player.hasPermission(node) || player.hasPermission(node.toLowerCase()); return player.hasPermission(node) || player.hasPermission(node.toLowerCase());
} }
public static boolean otherName(Player p, String name){ public static boolean otherName(Player p, String name){
if (has(p, Permission.ADMIN)) return false; 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());
return hasPermissionSet(p, node) || hasPermissionSet(p, node.toLowerCase()); return hasPermissionSet(p, node) || hasPermissionSet(p, node.toLowerCase());
} }

View File

@ -1,62 +0,0 @@
package com.Acrobot.ChestShop.Protection;
import com.Acrobot.ChestShop.ChestShop;
import com.Acrobot.ChestShop.Utils.uBlock;
import com.Acrobot.ChestShop.Utils.uSign;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Chest;
import org.bukkit.entity.Player;
/**
* @author Acrobot
*/
public class MaskChest implements Runnable {
private final BlockFace[] bf = {BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST, BlockFace.UP, BlockFace.DOWN};
public void run() {
Player[] players = ChestShop.getBukkitServer().getOnlinePlayers();
for (Player player : players) {
World world = player.getWorld();
Location location = player.getLocation();
int pX = location.getBlockX();
int pY = location.getBlockY();
int pZ = location.getBlockZ();
int radius = 25;
for (int x = -radius; x < radius; x++) {
for (int y = -radius; y < radius; y++) {
for (int z = -radius; z < radius; z++) {
Block block = world.getBlockAt(x + pX, y + pY, z + pZ);
if (block.getType() == Material.CHEST) {
if (uBlock.findSign2(block) != null) {
Chest neighbor = uBlock.findNeighbor(block);
Material nMat = returnNearestMat(block);
if (neighbor != null) {
player.sendBlockChange(neighbor.getBlock().getLocation(), nMat, (byte) 0);
}
player.sendBlockChange(block.getLocation(), nMat, (byte) 0);
}
}
}
}
}
}
}
private Material returnNearestMat(Block block) {
for (BlockFace face : bf) {
Block faceBlock = block.getRelative(face);
Material type = faceBlock.getType();
if (type != Material.AIR && !uSign.isSign(faceBlock) && type != Material.CHEST) return type;
}
return Material.CHEST;
}
}

View File

@ -43,10 +43,7 @@ public class restrictedSign {
public static boolean hasPermission(Player p, String[] lines){ public static boolean hasPermission(Player p, String[] lines){
if (Permission.has(p, Permission.ADMIN)) return true; if (Permission.has(p, Permission.ADMIN)) return true;
String world = p.getWorld().getName();
String playerName = p.getName();
for (int i = 1; i <= 3; i++) { for (int i = 1; i <= 3; i++) {
if (Permission.permissions != null && Permission.permissions.inGroup(world, playerName, lines[i])) return true;
if (p.hasPermission(Permission.GROUP.toString() + lines[i])) return true; if (p.hasPermission(Permission.GROUP.toString() + lines[i])) return true;
} }
return false; return false;

View File

@ -0,0 +1,87 @@
package com.Acrobot.ChestShop.Utils.WorldGuard;
import com.Acrobot.ChestShop.ChestShop;
import com.Acrobot.ChestShop.Config.Config;
import com.Acrobot.ChestShop.Config.Property;
import com.sk89q.worldguard.bukkit.BukkitUtil;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.GlobalRegionManager;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.StateFlag;
import org.bukkit.Location;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author Acrobot
*/
public class uWorldGuard {
public static WorldGuardPlugin worldGuard;
private static final ChestShopFlag flag = new ChestShopFlag();
/*public static boolean isNotOutsideWGplot(Location l2) {
return worldGuard == null || !Config.getBoolean(Property.WORLDGUARD_INTEGRATION) || worldGuard.getGlobalRegionManager().get(l2.getWorld()).getApplicableRegions(BukkitUtil.toVector(l2)).size() != 0;
}*/
public static void injectHax() {
if (!Config.getBoolean(Property.WORLDGUARD_INTEGRATION)) return;
try {
Field field = DefaultFlag.class.getDeclaredField("flagsList");
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.setAccessible(true);
List<Flag> elements = new ArrayList(Arrays.asList(DefaultFlag.getFlags()));
elements.add(flag);
Flag<?> list[] = new Flag<?>[elements.size()];
for (int i = 0; i < elements.size(); i++) {
list[i] = elements.get(i);
}
field.set(null, list);
Field grm = WorldGuardPlugin.class.getDeclaredField("globalRegionManager");
grm.setAccessible(true);
GlobalRegionManager globalRegionManager = (GlobalRegionManager) grm.get(ChestShop.getBukkitServer().getPluginManager().getPlugin("WorldGuard"));
globalRegionManager.preload();
} catch (Exception e) {
System.out.println(ChestShop.chatPrefix + "Oh noes! Something wrong happened! Be sure to paste that in your bug report:");
e.printStackTrace();
}
}
public static boolean canBuildShopHere(Location loc) {
return turnedOn() && canCreateShops(getRegions(loc));
}
public static boolean canCreateShops(ApplicableRegionSet set){
return set.allows(flag);
}
public static ApplicableRegionSet getRegions(Location loc) {
return worldGuard.getGlobalRegionManager().get(loc.getWorld()).getApplicableRegions(BukkitUtil.toVector(loc));
}
private static boolean turnedOn() {
return worldGuard != null && Config.getBoolean(Property.WORLDGUARD_INTEGRATION);
}
private static class ChestShopFlag extends StateFlag {
public ChestShopFlag() {
super("chestshop", false);
}
}
}

View File

@ -1,7 +1,7 @@
package com.Acrobot.ChestShop.Utils; package com.Acrobot.ChestShop.Utils;
import com.Acrobot.ChestShop.ChestShop; import com.Acrobot.ChestShop.Config.ConfigObject;
import org.bukkit.util.config.Configuration; import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File; import java.io.File;
@ -9,7 +9,8 @@ import java.io.File;
* @author Acrobot * @author Acrobot
*/ */
public class uLongName { public class uLongName {
public static Configuration config = new Configuration(new File(ChestShop.folder, "longName.storage")); public static YamlConfiguration config;
public static File configFile;
public static String getName(final String shortName) { public static String getName(final String shortName) {
return config.getString(shortName, shortName); return config.getString(shortName, shortName);
@ -17,16 +18,11 @@ public class uLongName {
public static void saveName(String name) { public static void saveName(String name) {
if (name.length() != 16) return; if (name.length() != 16) return;
config.setProperty(name.substring(0, 15), name); config.set(name.substring(0, 15), name);
reloadConfig(); ConfigObject.reloadConfig(config, configFile);
} }
public static String stripName(String name) { public static String stripName(String name) {
return (name.length() > 15 ? name.substring(0, 15) : name); return (name.length() > 15 ? name.substring(0, 15) : name);
} }
private static void reloadConfig() {
config.save();
config.load();
}
} }

View File

@ -1,18 +0,0 @@
package com.Acrobot.ChestShop.Utils;
import com.Acrobot.ChestShop.Config.Config;
import com.Acrobot.ChestShop.Config.Property;
import com.sk89q.worldguard.bukkit.BukkitUtil;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import org.bukkit.Location;
/**
* @author Acrobot
*/
public class uWorldGuard {
public static WorldGuardPlugin worldGuard;
public static boolean isNotOutsideWGplot(Location l2) {
return worldGuard == null || !Config.getBoolean(Property.WORLDGUARD_INTEGRATION) || worldGuard.getGlobalRegionManager().get(l2.getWorld()).getApplicableRegions(BukkitUtil.toVector(l2)).size() != 0;
}
}

View File

@ -99,7 +99,7 @@ public class BOSE6 implements Method {
BOSEconomy = (BOSEconomy) plugin; BOSEconomy = (BOSEconomy) plugin;
} }
public class BOSEAccount implements MethodAccount { public static class BOSEAccount implements MethodAccount {
private final String name; private final String name;
private final BOSEconomy BOSEconomy; private final BOSEconomy BOSEconomy;
@ -161,7 +161,7 @@ public class BOSE6 implements Method {
} }
} }
public class BOSEBankAccount implements MethodBankAccount { public static class BOSEBankAccount implements MethodBankAccount {
private final String bank; private final String bank;
private final BOSEconomy BOSEconomy; private final BOSEconomy BOSEconomy;

View File

@ -28,7 +28,7 @@ public class EE17 implements Method {
} }
public String getVersion() { public String getVersion() {
return "2.2"; return "2.8.2";
} }
public int fractionalDigits() { public int fractionalDigits() {
@ -102,7 +102,7 @@ public class EE17 implements Method {
Essentials = (Essentials)plugin; Essentials = (Essentials)plugin;
} }
public class EEcoAccount implements MethodAccount { public static class EEcoAccount implements MethodAccount {
private String name; private String name;
public EEcoAccount(String name) { public EEcoAccount(String name) {

View File

@ -81,7 +81,7 @@ public class MCUR implements Method {
currencyList = (Currency) plugin; currencyList = (Currency) plugin;
} }
public class MCurrencyAccount implements MethodAccount{ public static class MCurrencyAccount implements MethodAccount{
private String name; private String name;
public MCurrencyAccount(String name) { public MCurrencyAccount(String name) {

View File

@ -97,7 +97,7 @@ public class iCo4 implements Method {
iConomy = (iConomy)plugin; iConomy = (iConomy)plugin;
} }
public class iCoAccount implements MethodAccount { public static class iCoAccount implements MethodAccount {
private Account account; private Account account;
public iCoAccount(Account account) { public iCoAccount(Account account) {

View File

@ -91,7 +91,7 @@ public class iCo5 implements Method {
iConomy = (iConomy)plugin; iConomy = (iConomy)plugin;
} }
public class iCoAccount implements MethodAccount { public static class iCoAccount implements MethodAccount {
private Account account; private Account account;
private Holdings holdings; private Holdings holdings;
@ -161,7 +161,7 @@ public class iCo5 implements Method {
} }
} }
public class iCoBankAccount implements MethodBankAccount { public static class iCoBankAccount implements MethodBankAccount {
private BankAccount account; private BankAccount account;
private Holdings holdings; private Holdings holdings;

View File

@ -83,7 +83,7 @@ public class iCo6 implements Method {
iConomy = (iConomy)plugin; iConomy = (iConomy)plugin;
} }
public class iCoAccount implements MethodAccount { public static class iCoAccount implements MethodAccount {
private Account account; private Account account;
private Holdings holdings; private Holdings holdings;

View File

@ -2,7 +2,7 @@ name: ChestShop
main: com.Acrobot.ChestShop.ChestShop main: com.Acrobot.ChestShop.ChestShop
version: 3.35 version: 3.36
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, Vault, Heroes, softdepend: [LWC, Lockette, Deadbolt, OddItem, Towny, WorldGuard, Vault, Heroes,
iConomy, BOSEconomy, Essentials, 3co, MultiCurrency, Currency, SimpleChestLock] iConomy, BOSEconomy, Essentials, 3co, MultiCurrency, Currency, SimpleChestLock]
commands: commands:
iteminfo: iteminfo:
@ -40,14 +40,21 @@ permissions:
ChestShop.shop.buy: true ChestShop.shop.buy: true
ChestShop.shop.sell: true ChestShop.shop.sell: true
default: true default: true
ChestShop.shop.create:
description: Allows the user to create a shop that sells and buys any item
children:
ChestShop.shop.create.buy: true
ChestShop.shop.create.sell: true
ChestShop.shop.create.buy:
description: Allows the user to create a shop that sells any item
ChestShop.shop.create.sell:
description: Allows the user to create a shop that buy any item
ChestShop.shop.create.(itemID): ChestShop.shop.create.(itemID):
description: Allows user to create a shop that sells item with itemID like in the permission node (replace (itemID) with NUMERICAL item ID) description: Allows user to create a shop that sells item with itemID like in the permission node (replace (itemID) with NUMERICAL item ID)
ChestShop.shop.buy.(itemID): ChestShop.shop.buy.(itemID):
description: Allows user to buy certain (itemID) from a shop (replace (itemID) with NUMERICAL item ID) description: Allows user to buy certain (itemID) from a shop (replace (itemID) with NUMERICAL item ID)
ChestShop.shop.sell.(itemID): ChestShop.shop.sell.(itemID):
description: Allows user to sell certain (itemID) from a shop (replace (itemID) with NUMERICAL item ID) description: Allows user to sell certain (itemID) from a shop (replace (itemID) with NUMERICAL item ID)
ChestShop.shop.create:
description: Allows user to create a shop that sells any item
ChestShop.shop.buy: ChestShop.shop.buy:
description: Allows user to buy from a shop description: Allows user to buy from a shop
ChestShop.shop.sell: ChestShop.shop.sell: