mirror of
https://github.com/ChestShop-authors/ChestShop-3.git
synced 2024-12-24 01:07:32 +01:00
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:
parent
a49d51ce97
commit
7f8af7b5b3
30
com/Acrobot/ChestShop/BukkitFixes/bInventoryFix.java
Normal file
30
com/Acrobot/ChestShop/BukkitFixes/bInventoryFix.java
Normal 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;
|
||||
}
|
||||
}
|
@ -13,10 +13,10 @@ import com.Acrobot.ChestShop.Logging.FileWriterQueue;
|
||||
import com.avaje.ebean.EbeanServer;
|
||||
import com.lennardf1989.bukkitex.Database;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.util.config.Configuration;
|
||||
|
||||
import java.io.File;
|
||||
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.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.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);
|
||||
|
||||
//Register our commands!
|
||||
@ -65,12 +64,10 @@ public class ChestShop extends JavaPlugin {
|
||||
|
||||
//Start the statistics pinger
|
||||
startStatistics();
|
||||
|
||||
System.out.println('[' + getPluginName() + "] version " + getVersion() + " initialized!");
|
||||
}
|
||||
|
||||
public void onDisable() {
|
||||
System.out.println('[' + getPluginName() + "] version " + getVersion() + " shutting down!");
|
||||
getServer().getScheduler().cancelTasks(this);
|
||||
}
|
||||
|
||||
////////////////// REGISTER EVENTS, SCHEDULER & STATS ///////////////////////////
|
||||
@ -97,10 +94,8 @@ public class ChestShop extends JavaPlugin {
|
||||
}
|
||||
|
||||
///////////////////// DATABASE STUFF ////////////////////////////////
|
||||
private static Configuration getBukkitConfig() {
|
||||
Configuration config = new Configuration(new File("bukkit.yml"));
|
||||
config.load();
|
||||
return config;
|
||||
private static YamlConfiguration getBukkitConfig() {
|
||||
return YamlConfiguration.loadConfiguration(new File("bukkit.yml"));
|
||||
}
|
||||
|
||||
private static Database database;
|
||||
@ -114,7 +109,7 @@ public class ChestShop extends JavaPlugin {
|
||||
}
|
||||
};
|
||||
|
||||
Configuration config = getBukkitConfig();
|
||||
YamlConfiguration config = getBukkitConfig();
|
||||
|
||||
database.initializeDatabase(
|
||||
config.getString("database.driver"),
|
||||
@ -150,7 +145,7 @@ public class ChestShop extends JavaPlugin {
|
||||
return DB;
|
||||
}
|
||||
|
||||
public static ArrayList getDependencies() {
|
||||
return (ArrayList) description.getSoftDepend();
|
||||
public static List getDependencies() {
|
||||
return (List) description.getSoftDepend();
|
||||
}
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ public class MinecraftChest implements ChestObject {
|
||||
return main.getInventory().getSize() + (neighbor != null ? neighbor.getInventory().getSize() : 0);
|
||||
}
|
||||
|
||||
private Chest getNeighbor() {
|
||||
public Chest getNeighbor() {
|
||||
return uBlock.findNeighbor(main);
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,10 @@ public class Config {
|
||||
public static float getFloat(Property value) {
|
||||
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) {
|
||||
return (String) getValue(value.name());
|
||||
@ -40,6 +44,10 @@ public class Config {
|
||||
public static String getLocal(Language lang) {
|
||||
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) {
|
||||
return config.getProperty(node);
|
||||
|
@ -2,7 +2,9 @@ package com.Acrobot.ChestShop.Config;
|
||||
|
||||
import com.Acrobot.ChestShop.ChestShop;
|
||||
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.FileWriter;
|
||||
@ -13,35 +15,33 @@ import java.io.FileWriter;
|
||||
public class ConfigObject {
|
||||
private final File configFile = new File(ChestShop.folder, "config.yml");
|
||||
private final File langFile = new File(ChestShop.folder, "local.yml");
|
||||
private final Configuration config = new Configuration(configFile);
|
||||
private final Configuration language = new Configuration(langFile);
|
||||
private final YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
|
||||
private final YamlConfiguration language = YamlConfiguration.loadConfiguration(langFile);
|
||||
|
||||
public ConfigObject() {
|
||||
if (!ChestShop.folder.exists()) ChestShop.folder.mkdir();
|
||||
|
||||
reloadConfig();
|
||||
config.load();
|
||||
load(config, configFile);
|
||||
|
||||
reloadLanguage();
|
||||
language.load();
|
||||
load(language, langFile);
|
||||
|
||||
uLongName.config = new Configuration(new File(ChestShop.folder, "longName.storage"));
|
||||
uLongName.config.load();
|
||||
uLongName.configFile = new File(ChestShop.folder, "longName.storage");
|
||||
uLongName.config = YamlConfiguration.loadConfiguration(uLongName.configFile);
|
||||
}
|
||||
|
||||
private void reloadConfig() {
|
||||
config.load();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void reloadLanguage() {
|
||||
language.load();
|
||||
for (Language def : Language.values()) {
|
||||
if (language.getProperty(def.name()) == null) {
|
||||
if (language.get(def.name()) == null) {
|
||||
writeToFile('\n' + def.name() + ": \"" + def.toString() + '\"', langFile);
|
||||
}
|
||||
}
|
||||
@ -62,6 +62,27 @@ public class ConfigObject {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
29
com/Acrobot/ChestShop/Config/MaxPrice.java
Normal file
29
com/Acrobot/ChestShop/Config/MaxPrice.java
Normal 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;
|
||||
}
|
||||
}
|
@ -21,14 +21,13 @@ public enum Property {
|
||||
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_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?"),
|
||||
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_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_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)"),
|
||||
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?"),
|
||||
|
@ -17,13 +17,17 @@ public class Generator implements Runnable {
|
||||
|
||||
private static double generationTime;
|
||||
|
||||
private static final String header = fileToString("header");
|
||||
private static final String row = fileToString("row");
|
||||
private static final String footer = fileToString("footer");
|
||||
private static String header;
|
||||
private static String row;
|
||||
private static String footer;
|
||||
|
||||
private static BufferedWriter buf;
|
||||
|
||||
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!");
|
||||
generateStats();
|
||||
}
|
||||
@ -42,7 +46,7 @@ public class Generator implements Runnable {
|
||||
|
||||
private static String fileToString(String fileName) {
|
||||
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);
|
||||
char[] buf = new char[(int) f.length()];
|
||||
rd.read(buf);
|
||||
@ -113,6 +117,7 @@ public class Generator implements Runnable {
|
||||
|
||||
private static void generateStats() {
|
||||
try {
|
||||
|
||||
File f = new File(filePath).getParentFile();
|
||||
if (!f.exists()) f.mkdir();
|
||||
|
||||
|
@ -19,7 +19,8 @@ public class Queue implements Runnable {
|
||||
}
|
||||
|
||||
public void run() {
|
||||
deleteOld();
|
||||
if (Config.getInteger(Property.RECORD_TIME_TO_LIVE) != -1)
|
||||
deleteOld();
|
||||
|
||||
ChestShop.getDB().save(queue);
|
||||
queue.clear();
|
||||
|
@ -58,6 +58,8 @@ public class Items {
|
||||
String first = split[0];
|
||||
|
||||
String[] space = first.split(" ");
|
||||
if (space.length == 0) return null;
|
||||
|
||||
Material material = getMaterial(first);
|
||||
|
||||
for (int i = (space.length > 1 ? 1 : 0); i >= 0 && material == null; i--) material = getMaterial(space[i]);
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.Acrobot.ChestShop.Listeners;
|
||||
|
||||
import com.Acrobot.ChestShop.BukkitFixes.bInventoryFix;
|
||||
import com.Acrobot.ChestShop.Config.Config;
|
||||
import com.Acrobot.ChestShop.Config.Language;
|
||||
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.Utils.uBlock;
|
||||
import com.Acrobot.ChestShop.Utils.uSign;
|
||||
import net.minecraft.server.IInventory;
|
||||
import net.minecraft.server.InventoryLargeChest;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Chest;
|
||||
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.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@ -96,12 +94,7 @@ public class playerInteract implements Listener {
|
||||
player.sendMessage(Config.getLocal(Language.NO_CHEST_DETECTED));
|
||||
return;
|
||||
}
|
||||
|
||||
IInventory inventory = ((CraftInventory) chest.getInventory()).getInventory();
|
||||
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
|
||||
Inventory chestInv = bInventoryFix.getInventory(chest);
|
||||
player.openInventory(chestInv);
|
||||
}
|
||||
}
|
||||
|
@ -5,17 +5,15 @@ import com.Acrobot.ChestShop.Economy.NoProvider;
|
||||
import com.Acrobot.ChestShop.Economy.Register;
|
||||
import com.Acrobot.ChestShop.Economy.Vault;
|
||||
import com.Acrobot.ChestShop.Items.Odd;
|
||||
import com.Acrobot.ChestShop.Permission;
|
||||
import com.Acrobot.ChestShop.Protection.Plugins.*;
|
||||
import com.Acrobot.ChestShop.Protection.Security;
|
||||
import com.Acrobot.ChestShop.Utils.WorldGuard.uWorldGuard;
|
||||
import com.Acrobot.ChestShop.Utils.uHeroes;
|
||||
import com.Acrobot.ChestShop.Utils.uNumber;
|
||||
import com.Acrobot.ChestShop.Utils.uSign;
|
||||
import com.Acrobot.ChestShop.Utils.uWorldGuard;
|
||||
import com.daemitus.deadbolt.Deadbolt;
|
||||
import com.griefcraft.lwc.LWCPlugin;
|
||||
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.Methods;
|
||||
import com.palmergames.bukkit.towny.Towny;
|
||||
@ -50,14 +48,12 @@ public class pluginEnable {
|
||||
}
|
||||
Register.eco = m;
|
||||
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 :)
|
||||
if (name.equals("Permissions")) {
|
||||
Permission.permissions = ((Permissions) plugin).getHandler();
|
||||
} else if (name.equals("LWC")) {
|
||||
if (name.equals("LWC")) {
|
||||
LWCplugin.setLWC(((LWCPlugin) plugin).getLWC());
|
||||
Security.protections.add(new LWCplugin());
|
||||
} else if (name.equals("Lockette")) {
|
||||
@ -77,6 +73,7 @@ public class pluginEnable {
|
||||
uSign.towny = (Towny) plugin;
|
||||
} else if (name.equals("WorldGuard")) {
|
||||
uWorldGuard.worldGuard = (WorldGuardPlugin) plugin;
|
||||
uWorldGuard.injectHax(); //Inject hax into WorldGuard
|
||||
} else if (name.equals("Vault")) {
|
||||
if (com.Acrobot.ChestShop.Economy.Economy.economy != null) return;
|
||||
RegisteredServiceProvider<Economy> rsp = ChestShop.getBukkitServer().getServicesManager().getRegistration(Economy.class);
|
||||
@ -90,6 +87,8 @@ public class pluginEnable {
|
||||
} else if (name.equals("SimpleChestLock")) {
|
||||
SCLplugin.scl = (SCL) plugin;
|
||||
Security.protections.add(new SCLplugin());
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
PluginDescriptionFile description = plugin.getDescription();
|
||||
|
@ -2,6 +2,7 @@ package com.Acrobot.ChestShop.Listeners;
|
||||
|
||||
import com.Acrobot.ChestShop.Config.Config;
|
||||
import com.Acrobot.ChestShop.Config.Language;
|
||||
import com.Acrobot.ChestShop.Config.MaxPrice;
|
||||
import com.Acrobot.ChestShop.Config.Property;
|
||||
import com.Acrobot.ChestShop.Economy.Economy;
|
||||
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.Signs.restrictedSign;
|
||||
import com.Acrobot.ChestShop.Utils.*;
|
||||
import com.Acrobot.ChestShop.Utils.WorldGuard.uWorldGuard;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
@ -38,18 +40,12 @@ public class signChange implements Listener {
|
||||
|
||||
boolean playerIsAdmin = Permission.has(player, Permission.ADMIN);
|
||||
|
||||
|
||||
if (isAlmostReady) {
|
||||
if (mat == null) {
|
||||
player.sendMessage(Config.getLocal(Language.INCORRECT_ITEM_ID));
|
||||
dropSign(event);
|
||||
return;
|
||||
}
|
||||
if (!canCreateShop(player, mat.getId())) {
|
||||
player.sendMessage(Config.getLocal(Language.YOU_CANNOT_CREATE_SHOP));
|
||||
dropSign(event);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (restrictedSign.isRestricted(line)) {
|
||||
if (!restrictedSign.hasPermission(player, line)) {
|
||||
@ -91,8 +87,9 @@ public class signChange implements Listener {
|
||||
}
|
||||
|
||||
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));
|
||||
dropSign(event);
|
||||
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);
|
||||
boolean paid = shopCreationPrice != 0 && !isAdminShop && !Permission.has(player, Permission.NOFEE);
|
||||
@ -134,14 +138,13 @@ public class signChange implements Listener {
|
||||
uHeroes.addHeroExp(player);
|
||||
}
|
||||
|
||||
private static boolean canCreateShop(Player player, boolean isAdmin, int ID) {
|
||||
return isAdmin ||
|
||||
Permission.has(player, Permission.SHOP_CREATION) ||
|
||||
Permission.has(player, Permission.SHOP_CREATION.toString() + '.' + ID);
|
||||
}
|
||||
private static boolean canCreateShop(Player player, int ID, boolean buy, boolean sell) {
|
||||
if (Permission.has(player, Permission.SHOP_CREATION_ID + Integer.toString(ID))) return true;
|
||||
|
||||
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 canCreateShop(player, Permission.has(player, Permission.ADMIN), ID);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static String formatThirdLine(String thirdLine) {
|
||||
|
@ -1,92 +1,63 @@
|
||||
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.
|
||||
*/
|
||||
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 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.URLConnection;
|
||||
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 {
|
||||
|
||||
/**
|
||||
* Interface used to collect custom data for a plugin
|
||||
* The current revision number
|
||||
*/
|
||||
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();
|
||||
|
||||
/**
|
||||
* 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;
|
||||
private final static int REVISION = 5;
|
||||
|
||||
/**
|
||||
* The base url of the metrics domain
|
||||
@ -104,14 +75,25 @@ public class Metrics {
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -142,6 +124,33 @@ public class Metrics {
|
||||
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
|
||||
*
|
||||
@ -149,14 +158,14 @@ public class Metrics {
|
||||
* @param 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) {
|
||||
plotters = Collections.synchronizedSet(new LinkedHashSet<Plotter>());
|
||||
customData.put(plugin, plotters);
|
||||
}
|
||||
// Add the plotter to the graph o/
|
||||
graph.addPlotter(plotter);
|
||||
|
||||
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
|
||||
*/
|
||||
public void beginMeasuringPlugin(final Plugin plugin) throws IOException {
|
||||
public void beginMeasuringPlugin(final Plugin plugin) {
|
||||
// Did we opt out?
|
||||
if (configuration.getBoolean("opt-out", false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// First tell the server about us
|
||||
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
|
||||
// Begin hitting the server with glorious data
|
||||
plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable() {
|
||||
private boolean firstPost = true;
|
||||
|
||||
public void run() {
|
||||
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) {
|
||||
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
|
||||
*/
|
||||
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
|
||||
String response = "ERR No response";
|
||||
StringBuilder data = new StringBuilder(10);
|
||||
data.append(encode("guid")).append('=').append(encode(guid))
|
||||
.append(gField("version", plugin.getDescription().getVersion()))
|
||||
.append(gField("server", Bukkit.getVersion()))
|
||||
.append(gField("players", String.valueOf(Bukkit.getServer().getOnlinePlayers().length)))
|
||||
.append(gField("revision", String.valueOf(REVISION)));
|
||||
String data = encode("guid") + '=' + encode(guid)
|
||||
+ encodeDataPair("authors", authors)
|
||||
+ encodeDataPair("version", description.getVersion())
|
||||
+ encodeDataPair("server", Bukkit.getVersion())
|
||||
+ encodeDataPair("players", Integer.toString(Bukkit.getServer().getOnlinePlayers().length))
|
||||
+ encodeDataPair("revision", String.valueOf(REVISION));
|
||||
|
||||
// If we're pinging, append it
|
||||
if (isPing) {
|
||||
data.append(gField("ping", "true"));
|
||||
data += encodeDataPair("ping", "true");
|
||||
}
|
||||
|
||||
// Add any custom data (if applicable)
|
||||
Set<Plotter> plotters = customData.get(plugin);
|
||||
// Add any custom data available for the plugin
|
||||
Set<Graph> graphs = getOrCreateGraphs(plugin);
|
||||
|
||||
if (plotters != null) {
|
||||
for (Plotter plotter : plotters) {
|
||||
data.append(gField("Custom" + plotter.getColumnName(), Integer.toString(plotter.getValue())));
|
||||
// Acquire a lock on the graphs, which lets us make the assumption we also lock everything
|
||||
// inside of the graph (e.g plotters)
|
||||
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()));
|
||||
|
||||
// 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);
|
||||
|
||||
// Write the data
|
||||
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
|
||||
writer.write(data.toString());
|
||||
writer.write(data);
|
||||
writer.flush();
|
||||
|
||||
// Now read the response
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
response = reader.readLine();
|
||||
String response = reader.readLine();
|
||||
|
||||
// close resources
|
||||
writer.close();
|
||||
@ -247,9 +298,15 @@ public class Metrics {
|
||||
} else {
|
||||
// Is this the first update this hour?
|
||||
if (response.contains("OK This is your first update this hour")) {
|
||||
if (plotters != null) {
|
||||
for (Plotter plotter : plotters) {
|
||||
plotter.reset();
|
||||
synchronized (graphs) {
|
||||
Iterator<Graph> iter = graphs.iterator();
|
||||
|
||||
while (iter.hasNext()) {
|
||||
Graph graph = iter.next();
|
||||
|
||||
for (Plotter plotter : graph.getPlotters()) {
|
||||
plotter.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -258,14 +315,68 @@ public class Metrics {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a field
|
||||
* @param name Field name
|
||||
* @param data Data assigned to the field
|
||||
* @return Field
|
||||
* @throws UnsupportedEncodingException
|
||||
* Get or create the Set of graphs for a specific plugin
|
||||
*
|
||||
* @param plugin
|
||||
* @return
|
||||
*/
|
||||
private static String gField(String name, String data) throws UnsupportedEncodingException {
|
||||
return '&' + encode(name) + '=' + encode(data);
|
||||
private Set<Graph> getOrCreateGraphs(Plugin plugin) {
|
||||
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");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,17 +1,22 @@
|
||||
package com.Acrobot.ChestShop;
|
||||
|
||||
import com.nijiko.permissions.PermissionHandler;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* @author Acrobot
|
||||
*/
|
||||
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_ID("ChestShop.shop.buy."),
|
||||
|
||||
SELL_ID("ChestShop.shop.sell."),
|
||||
SELL("ChestShop.shop.sell"),
|
||||
|
||||
ADMIN("ChestShop.admin"),
|
||||
MOD("ChestShop.mod"),
|
||||
OTHER_NAME("ChestShop.name."),
|
||||
@ -24,21 +29,17 @@ public enum Permission {
|
||||
this.permission = permission;
|
||||
}
|
||||
|
||||
public static PermissionHandler permissions;
|
||||
|
||||
public static boolean has(Player player, Permission permission) {
|
||||
return has(player, permission.permission);
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
public static boolean otherName(Player p, String name){
|
||||
if (has(p, Permission.ADMIN)) return false;
|
||||
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());
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -43,10 +43,7 @@ public class restrictedSign {
|
||||
public static boolean hasPermission(Player p, String[] lines){
|
||||
if (Permission.has(p, Permission.ADMIN)) return true;
|
||||
|
||||
String world = p.getWorld().getName();
|
||||
String playerName = p.getName();
|
||||
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;
|
||||
}
|
||||
return false;
|
||||
|
87
com/Acrobot/ChestShop/Utils/WorldGuard/uWorldGuard.java
Normal file
87
com/Acrobot/ChestShop/Utils/WorldGuard/uWorldGuard.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package com.Acrobot.ChestShop.Utils;
|
||||
|
||||
import com.Acrobot.ChestShop.ChestShop;
|
||||
import org.bukkit.util.config.Configuration;
|
||||
import com.Acrobot.ChestShop.Config.ConfigObject;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@ -9,7 +9,8 @@ import java.io.File;
|
||||
* @author Acrobot
|
||||
*/
|
||||
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) {
|
||||
return config.getString(shortName, shortName);
|
||||
@ -17,16 +18,11 @@ public class uLongName {
|
||||
|
||||
public static void saveName(String name) {
|
||||
if (name.length() != 16) return;
|
||||
config.setProperty(name.substring(0, 15), name);
|
||||
reloadConfig();
|
||||
config.set(name.substring(0, 15), name);
|
||||
ConfigObject.reloadConfig(config, configFile);
|
||||
}
|
||||
|
||||
public static String stripName(String name) {
|
||||
return (name.length() > 15 ? name.substring(0, 15) : name);
|
||||
}
|
||||
|
||||
private static void reloadConfig() {
|
||||
config.save();
|
||||
config.load();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -99,7 +99,7 @@ public class BOSE6 implements Method {
|
||||
BOSEconomy = (BOSEconomy) plugin;
|
||||
}
|
||||
|
||||
public class BOSEAccount implements MethodAccount {
|
||||
public static class BOSEAccount implements MethodAccount {
|
||||
private final String name;
|
||||
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 BOSEconomy BOSEconomy;
|
||||
|
||||
|
@ -28,7 +28,7 @@ public class EE17 implements Method {
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return "2.2";
|
||||
return "2.8.2";
|
||||
}
|
||||
|
||||
public int fractionalDigits() {
|
||||
@ -102,7 +102,7 @@ public class EE17 implements Method {
|
||||
Essentials = (Essentials)plugin;
|
||||
}
|
||||
|
||||
public class EEcoAccount implements MethodAccount {
|
||||
public static class EEcoAccount implements MethodAccount {
|
||||
private String name;
|
||||
|
||||
public EEcoAccount(String name) {
|
||||
|
@ -81,7 +81,7 @@ public class MCUR implements Method {
|
||||
currencyList = (Currency) plugin;
|
||||
}
|
||||
|
||||
public class MCurrencyAccount implements MethodAccount{
|
||||
public static class MCurrencyAccount implements MethodAccount{
|
||||
private String name;
|
||||
|
||||
public MCurrencyAccount(String name) {
|
||||
|
@ -97,7 +97,7 @@ public class iCo4 implements Method {
|
||||
iConomy = (iConomy)plugin;
|
||||
}
|
||||
|
||||
public class iCoAccount implements MethodAccount {
|
||||
public static class iCoAccount implements MethodAccount {
|
||||
private Account account;
|
||||
|
||||
public iCoAccount(Account account) {
|
||||
|
@ -91,7 +91,7 @@ public class iCo5 implements Method {
|
||||
iConomy = (iConomy)plugin;
|
||||
}
|
||||
|
||||
public class iCoAccount implements MethodAccount {
|
||||
public static class iCoAccount implements MethodAccount {
|
||||
private Account account;
|
||||
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 Holdings holdings;
|
||||
|
||||
|
@ -83,7 +83,7 @@ public class iCo6 implements Method {
|
||||
iConomy = (iConomy)plugin;
|
||||
}
|
||||
|
||||
public class iCoAccount implements MethodAccount {
|
||||
public static class iCoAccount implements MethodAccount {
|
||||
private Account account;
|
||||
private Holdings holdings;
|
||||
|
||||
|
15
plugin.yml
15
plugin.yml
@ -2,7 +2,7 @@ name: ChestShop
|
||||
|
||||
main: com.Acrobot.ChestShop.ChestShop
|
||||
|
||||
version: 3.35
|
||||
version: 3.36
|
||||
|
||||
|
||||
author: Acrobot
|
||||
@ -10,7 +10,7 @@ description: >
|
||||
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]
|
||||
commands:
|
||||
iteminfo:
|
||||
@ -40,14 +40,21 @@ permissions:
|
||||
ChestShop.shop.buy: true
|
||||
ChestShop.shop.sell: 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):
|
||||
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):
|
||||
description: Allows user to buy certain (itemID) from a shop (replace (itemID) with NUMERICAL item ID)
|
||||
ChestShop.shop.sell.(itemID):
|
||||
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:
|
||||
description: Allows user to buy from a shop
|
||||
ChestShop.shop.sell:
|
||||
|
Loading…
Reference in New Issue
Block a user