From 9b28b6b232e8e9a65df06a4ef70c8105c930bca3 Mon Sep 17 00:00:00 2001 From: Zrips Date: Fri, 21 Aug 2015 16:10:08 +0300 Subject: [PATCH] Updates --- Gui/.gitignore | 3 + Gui/GuiInfoList.java | 46 + Gui/GuiTools.java | 241 +++ ItemList.yml | 702 ++++++++ .../maven/com.gamingmesh/jobs/pom.properties | 5 + META-INF/maven/com.gamingmesh/jobs/pom.xml | 129 ++ Signs.yml | 1 + Signs/.gitignore | 7 + Signs/Sign.java | 80 + Signs/SignInfo.java | 28 + Signs/SignUtil.java | 223 +++ com/gamingmesh/jobs/.gitignore | 7 + com/gamingmesh/jobs/HookEconomyTask.java | 65 + com/gamingmesh/jobs/Jobs.java | 567 +++++++ com/gamingmesh/jobs/JobsPlugin.java | 116 ++ com/gamingmesh/jobs/PermissionHandler.java | 158 ++ com/gamingmesh/jobs/PlayerManager.java | 524 ++++++ com/gamingmesh/jobs/actions/.gitignore | 6 + .../jobs/actions/BlockActionInfo.java | 31 + .../jobs/actions/CustomKillInfo.java | 42 + .../jobs/actions/EnchantActionInfo.java | 44 + .../jobs/actions/EntityActionInfo.java | 67 + .../jobs/actions/ItemActionInfo.java | 31 + .../jobs/actions/MaterialActionInfo.java | 46 + com/gamingmesh/jobs/api/.gitignore | 8 + com/gamingmesh/jobs/api/JobsJoinEvent.java | 44 + com/gamingmesh/jobs/api/JobsLeaveEvent.java | 44 + com/gamingmesh/jobs/api/JobsLevelUpEvent.java | 146 ++ com/gamingmesh/jobs/api/JobsPaymentEvent.java | 42 + com/gamingmesh/jobs/commands/.gitignore | 2 + com/gamingmesh/jobs/commands/JobCommand.java | 30 + .../jobs/commands/JobsCommands.java | 1512 +++++++++++++++++ com/gamingmesh/jobs/config/.gitignore | 5 + .../config/CommentedYamlConfiguration.java | 218 +++ com/gamingmesh/jobs/config/ConfigManager.java | 40 + com/gamingmesh/jobs/config/JobConfig.java | 426 +++++ .../jobs/config/JobsConfiguration.java | 1286 ++++++++++++++ com/gamingmesh/jobs/config/YmlMaker.java | 92 + com/gamingmesh/jobs/container/.gitignore | 20 + com/gamingmesh/jobs/container/ActionInfo.java | 25 + com/gamingmesh/jobs/container/ActionType.java | 46 + .../jobs/container/BaseActionInfo.java | 31 + com/gamingmesh/jobs/container/Convert.java | 49 + .../jobs/container/DisplayMethod.java | 41 + com/gamingmesh/jobs/container/Job.java | 346 ++++ .../jobs/container/JobCommands.java | 48 + com/gamingmesh/jobs/container/JobInfo.java | 79 + com/gamingmesh/jobs/container/JobItems.java | 69 + .../jobs/container/JobPermission.java | 42 + .../jobs/container/JobProgression.java | 188 ++ com/gamingmesh/jobs/container/JobsPlayer.java | 497 ++++++ com/gamingmesh/jobs/container/NameList.java | 50 + .../jobs/container/RestrictedArea.java | 85 + com/gamingmesh/jobs/container/Schedule.java | 190 +++ com/gamingmesh/jobs/container/Title.java | 90 + com/gamingmesh/jobs/container/TopList.java | 45 + com/gamingmesh/jobs/dao/.gitignore | 10 + com/gamingmesh/jobs/dao/JobsConnection.java | 69 + .../jobs/dao/JobsConnectionPool.java | 67 + com/gamingmesh/jobs/dao/JobsDAO.java | 651 +++++++ com/gamingmesh/jobs/dao/JobsDAOData.java | 82 + com/gamingmesh/jobs/dao/JobsDAOMySQL.java | 274 +++ com/gamingmesh/jobs/dao/JobsDAOSQLite.java | 253 +++ com/gamingmesh/jobs/dao/JobsDriver.java | 58 + com/gamingmesh/jobs/dao/JobsDrivers.java | 69 + com/gamingmesh/jobs/economy/.gitignore | 6 + .../jobs/economy/BlackholeEconomy.java | 58 + .../jobs/economy/BufferedEconomy.java | 199 +++ .../jobs/economy/BufferedPayment.java | 53 + com/gamingmesh/jobs/economy/Economy.java | 31 + com/gamingmesh/jobs/economy/PaymentData.java | 132 ++ com/gamingmesh/jobs/economy/VaultEconomy.java | 69 + com/gamingmesh/jobs/i18n/.gitignore | 1 + com/gamingmesh/jobs/i18n/Language.java | 84 + com/gamingmesh/jobs/listeners/.gitignore | 8 + .../jobs/listeners/JobsListener.java | 440 +++++ .../jobs/listeners/JobsPaymentListener.java | 997 +++++++++++ .../jobs/listeners/McMMOlistener.java | 72 + .../listeners/PistonProtectionListener.java | 121 ++ com/gamingmesh/jobs/resources/jfep/.gitignore | 10 + .../jobs/resources/jfep/ConstantNode.java | 143 ++ .../resources/jfep/EvaluationException.java | 51 + .../jobs/resources/jfep/ExpressionNode.java | 89 + .../jobs/resources/jfep/FunctionNode.java | 174 ++ .../jobs/resources/jfep/OperatorNode.java | 170 ++ .../jobs/resources/jfep/ParseError.java | 65 + .../jobs/resources/jfep/Parser.java | 486 ++++++ com/gamingmesh/jobs/resources/jfep/Sfun.java | 557 ++++++ .../jobs/resources/jfep/VariableNode.java | 121 ++ com/gamingmesh/jobs/stuff/.gitignore | 19 + com/gamingmesh/jobs/stuff/ActionBar.java | 156 ++ com/gamingmesh/jobs/stuff/ChatColor.java | 69 + com/gamingmesh/jobs/stuff/Debug.java | 18 + com/gamingmesh/jobs/stuff/FileDownloader.java | 35 + com/gamingmesh/jobs/stuff/GiveItem.java | 36 + .../jobs/stuff/JobsClassLoader.java | 45 + .../jobs/stuff/PerformCommands.java | 33 + com/gamingmesh/jobs/stuff/Perm.java | 25 + com/gamingmesh/jobs/stuff/Scboard.java | 48 + com/gamingmesh/jobs/stuff/ScheduleUtil.java | 99 ++ com/gamingmesh/jobs/stuff/TabComplete.java | 90 + com/gamingmesh/jobs/stuff/TranslateName.java | 86 + com/gamingmesh/jobs/stuff/UUIDUtil.java | 38 + com/gamingmesh/jobs/tasks/.gitignore | 3 + .../jobs/tasks/BufferedPaymentTask.java | 44 + .../jobs/tasks/BufferedPaymentThread.java | 73 + .../jobs/tasks/DatabaseSaveThread.java | 74 + jobConfig.yml | 1018 +++++++++++ locale/messages_cs.yml | 230 +++ locale/messages_de.yml | 248 +++ locale/messages_fr.yml | 238 +++ locale/messages_lt.yml | 203 +++ locale/messages_ru.yml | 252 +++ plugin.yml | 141 ++ schedule.yml | 55 + 115 files changed, 18051 insertions(+) create mode 100644 Gui/.gitignore create mode 100644 Gui/GuiInfoList.java create mode 100644 Gui/GuiTools.java create mode 100644 ItemList.yml create mode 100644 META-INF/maven/com.gamingmesh/jobs/pom.properties create mode 100644 META-INF/maven/com.gamingmesh/jobs/pom.xml create mode 100644 Signs.yml create mode 100644 Signs/.gitignore create mode 100644 Signs/Sign.java create mode 100644 Signs/SignInfo.java create mode 100644 Signs/SignUtil.java create mode 100644 com/gamingmesh/jobs/.gitignore create mode 100644 com/gamingmesh/jobs/HookEconomyTask.java create mode 100644 com/gamingmesh/jobs/Jobs.java create mode 100644 com/gamingmesh/jobs/JobsPlugin.java create mode 100644 com/gamingmesh/jobs/PermissionHandler.java create mode 100644 com/gamingmesh/jobs/PlayerManager.java create mode 100644 com/gamingmesh/jobs/actions/.gitignore create mode 100644 com/gamingmesh/jobs/actions/BlockActionInfo.java create mode 100644 com/gamingmesh/jobs/actions/CustomKillInfo.java create mode 100644 com/gamingmesh/jobs/actions/EnchantActionInfo.java create mode 100644 com/gamingmesh/jobs/actions/EntityActionInfo.java create mode 100644 com/gamingmesh/jobs/actions/ItemActionInfo.java create mode 100644 com/gamingmesh/jobs/actions/MaterialActionInfo.java create mode 100644 com/gamingmesh/jobs/api/.gitignore create mode 100644 com/gamingmesh/jobs/api/JobsJoinEvent.java create mode 100644 com/gamingmesh/jobs/api/JobsLeaveEvent.java create mode 100644 com/gamingmesh/jobs/api/JobsLevelUpEvent.java create mode 100644 com/gamingmesh/jobs/api/JobsPaymentEvent.java create mode 100644 com/gamingmesh/jobs/commands/.gitignore create mode 100644 com/gamingmesh/jobs/commands/JobCommand.java create mode 100644 com/gamingmesh/jobs/commands/JobsCommands.java create mode 100644 com/gamingmesh/jobs/config/.gitignore create mode 100644 com/gamingmesh/jobs/config/CommentedYamlConfiguration.java create mode 100644 com/gamingmesh/jobs/config/ConfigManager.java create mode 100644 com/gamingmesh/jobs/config/JobConfig.java create mode 100644 com/gamingmesh/jobs/config/JobsConfiguration.java create mode 100644 com/gamingmesh/jobs/config/YmlMaker.java create mode 100644 com/gamingmesh/jobs/container/.gitignore create mode 100644 com/gamingmesh/jobs/container/ActionInfo.java create mode 100644 com/gamingmesh/jobs/container/ActionType.java create mode 100644 com/gamingmesh/jobs/container/BaseActionInfo.java create mode 100644 com/gamingmesh/jobs/container/Convert.java create mode 100644 com/gamingmesh/jobs/container/DisplayMethod.java create mode 100644 com/gamingmesh/jobs/container/Job.java create mode 100644 com/gamingmesh/jobs/container/JobCommands.java create mode 100644 com/gamingmesh/jobs/container/JobInfo.java create mode 100644 com/gamingmesh/jobs/container/JobItems.java create mode 100644 com/gamingmesh/jobs/container/JobPermission.java create mode 100644 com/gamingmesh/jobs/container/JobProgression.java create mode 100644 com/gamingmesh/jobs/container/JobsPlayer.java create mode 100644 com/gamingmesh/jobs/container/NameList.java create mode 100644 com/gamingmesh/jobs/container/RestrictedArea.java create mode 100644 com/gamingmesh/jobs/container/Schedule.java create mode 100644 com/gamingmesh/jobs/container/Title.java create mode 100644 com/gamingmesh/jobs/container/TopList.java create mode 100644 com/gamingmesh/jobs/dao/.gitignore create mode 100644 com/gamingmesh/jobs/dao/JobsConnection.java create mode 100644 com/gamingmesh/jobs/dao/JobsConnectionPool.java create mode 100644 com/gamingmesh/jobs/dao/JobsDAO.java create mode 100644 com/gamingmesh/jobs/dao/JobsDAOData.java create mode 100644 com/gamingmesh/jobs/dao/JobsDAOMySQL.java create mode 100644 com/gamingmesh/jobs/dao/JobsDAOSQLite.java create mode 100644 com/gamingmesh/jobs/dao/JobsDriver.java create mode 100644 com/gamingmesh/jobs/dao/JobsDrivers.java create mode 100644 com/gamingmesh/jobs/economy/.gitignore create mode 100644 com/gamingmesh/jobs/economy/BlackholeEconomy.java create mode 100644 com/gamingmesh/jobs/economy/BufferedEconomy.java create mode 100644 com/gamingmesh/jobs/economy/BufferedPayment.java create mode 100644 com/gamingmesh/jobs/economy/Economy.java create mode 100644 com/gamingmesh/jobs/economy/PaymentData.java create mode 100644 com/gamingmesh/jobs/economy/VaultEconomy.java create mode 100644 com/gamingmesh/jobs/i18n/.gitignore create mode 100644 com/gamingmesh/jobs/i18n/Language.java create mode 100644 com/gamingmesh/jobs/listeners/.gitignore create mode 100644 com/gamingmesh/jobs/listeners/JobsListener.java create mode 100644 com/gamingmesh/jobs/listeners/JobsPaymentListener.java create mode 100644 com/gamingmesh/jobs/listeners/McMMOlistener.java create mode 100644 com/gamingmesh/jobs/listeners/PistonProtectionListener.java create mode 100644 com/gamingmesh/jobs/resources/jfep/.gitignore create mode 100644 com/gamingmesh/jobs/resources/jfep/ConstantNode.java create mode 100644 com/gamingmesh/jobs/resources/jfep/EvaluationException.java create mode 100644 com/gamingmesh/jobs/resources/jfep/ExpressionNode.java create mode 100644 com/gamingmesh/jobs/resources/jfep/FunctionNode.java create mode 100644 com/gamingmesh/jobs/resources/jfep/OperatorNode.java create mode 100644 com/gamingmesh/jobs/resources/jfep/ParseError.java create mode 100644 com/gamingmesh/jobs/resources/jfep/Parser.java create mode 100644 com/gamingmesh/jobs/resources/jfep/Sfun.java create mode 100644 com/gamingmesh/jobs/resources/jfep/VariableNode.java create mode 100644 com/gamingmesh/jobs/stuff/.gitignore create mode 100644 com/gamingmesh/jobs/stuff/ActionBar.java create mode 100644 com/gamingmesh/jobs/stuff/ChatColor.java create mode 100644 com/gamingmesh/jobs/stuff/Debug.java create mode 100644 com/gamingmesh/jobs/stuff/FileDownloader.java create mode 100644 com/gamingmesh/jobs/stuff/GiveItem.java create mode 100644 com/gamingmesh/jobs/stuff/JobsClassLoader.java create mode 100644 com/gamingmesh/jobs/stuff/PerformCommands.java create mode 100644 com/gamingmesh/jobs/stuff/Perm.java create mode 100644 com/gamingmesh/jobs/stuff/Scboard.java create mode 100644 com/gamingmesh/jobs/stuff/ScheduleUtil.java create mode 100644 com/gamingmesh/jobs/stuff/TabComplete.java create mode 100644 com/gamingmesh/jobs/stuff/TranslateName.java create mode 100644 com/gamingmesh/jobs/stuff/UUIDUtil.java create mode 100644 com/gamingmesh/jobs/tasks/.gitignore create mode 100644 com/gamingmesh/jobs/tasks/BufferedPaymentTask.java create mode 100644 com/gamingmesh/jobs/tasks/BufferedPaymentThread.java create mode 100644 com/gamingmesh/jobs/tasks/DatabaseSaveThread.java create mode 100644 jobConfig.yml create mode 100644 locale/messages_cs.yml create mode 100644 locale/messages_de.yml create mode 100644 locale/messages_fr.yml create mode 100644 locale/messages_lt.yml create mode 100644 locale/messages_ru.yml create mode 100644 plugin.yml create mode 100644 schedule.yml diff --git a/Gui/.gitignore b/Gui/.gitignore new file mode 100644 index 00000000..68eca3f2 --- /dev/null +++ b/Gui/.gitignore @@ -0,0 +1,3 @@ +/Gui.class +/GuiInfoList.class +/GuiTools.class diff --git a/Gui/GuiInfoList.java b/Gui/GuiInfoList.java new file mode 100644 index 00000000..851732a4 --- /dev/null +++ b/Gui/GuiInfoList.java @@ -0,0 +1,46 @@ +package Gui; + +import java.util.ArrayList; +import java.util.List; + +import com.gamingmesh.jobs.container.Job; + +public class GuiInfoList { + + String name; + List jobList = new ArrayList(); + Boolean jobInfo = false; + int backButton = 27; + + public GuiInfoList(String name) { + this.name = name; + } + + public int getbackButton() { + return this.backButton; + } + + public void setbackButton(int backButton) { + this.backButton = backButton; + } + + public String getName() { + return this.name; + } + + public List getJobList() { + return this.jobList; + } + + public void setJobList(List jobList) { + this.jobList = jobList; + } + + public void setJobInfo(Boolean jobInfo) { + this.jobInfo = jobInfo; + } + + public Boolean isJobInfo() { + return this.jobInfo; + } +} diff --git a/Gui/GuiTools.java b/Gui/GuiTools.java new file mode 100644 index 00000000..74bf47d6 --- /dev/null +++ b/Gui/GuiTools.java @@ -0,0 +1,241 @@ +package Gui; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.commands.JobsCommands; +import com.gamingmesh.jobs.config.ConfigManager; +import com.gamingmesh.jobs.container.ActionType; +import com.gamingmesh.jobs.container.Job; +import com.gamingmesh.jobs.container.JobInfo; +import com.gamingmesh.jobs.container.JobProgression; +import com.gamingmesh.jobs.container.JobsPlayer; +import com.gamingmesh.jobs.stuff.TranslateName; + +public class GuiTools { + + public static HashMap GuiList = new HashMap(); + + public static Inventory CreateJobsGUI(Player player) { + + ArrayList JobsList = new ArrayList(); + for (Job job : Jobs.getJobs()) { + if (ConfigManager.getJobsConfiguration().getHideJobsWithoutPermission()) + if (!JobsCommands.hasJobPermission(player, job)) + continue; + JobsList.add(job); + } + + GuiInfoList guiInfo = new GuiInfoList(player.getName()); + guiInfo.setJobList(JobsList); + GuiList.put(player.getName(), guiInfo); + + int GuiSize = 9; + + if (JobsList.size() > 9) + GuiSize = 18; + + if (JobsList.size() > 18) + GuiSize = 27; + + if (JobsList.size() > 27) + GuiSize = 36; + + if (JobsList.size() > 36) + GuiSize = 45; + + if (JobsList.size() > 45) + GuiSize = 54; + + JobsPlayer JPlayer = Jobs.getPlayerManager().getJobsPlayer(player); + + List pJobs = JPlayer.getJobProgression(); + + Inventory GuiInv = Bukkit.createInventory(null, GuiSize, "Pick your job!"); + + for (int i = 0; i < JobsList.size(); i++) { + + Job job = JobsList.get(i); + + ArrayList Lore = new ArrayList(); + + for (JobProgression onePJob : pJobs) { + if (onePJob.getJob().getName().equalsIgnoreCase(job.getName())) + Lore.add(ChatColor.translateAlternateColorCodes('&', "&2Working ")); + } + + int maxlevel = 0; + if (player.hasPermission("jobs." + job.getName() + ".vipmaxlevel") && job.getVipMaxLevel() != 0) + maxlevel = job.getVipMaxLevel(); + else + maxlevel = job.getMaxLevel(); + + if (maxlevel > 0) + Lore.add("Max level: " + maxlevel); + + Lore.add(job.getDescription()); + + if (job.getMaxSlots() != null) + Lore.add("Left slots: " + (job.getMaxSlots() - Jobs.getUsedSlots(job))); + + Lore.add(""); + Lore.add("Posible actions"); + for (ActionType actionType : ActionType.values()) { + List info = job.getJobInfo(actionType); + + if (info != null && !info.isEmpty()) { + Lore.add(ChatColor.translateAlternateColorCodes('&', "&e" + actionType.getName())); + } + } + + ItemStack GuiItem = job.getGuiItem(); + + ItemMeta meta = GuiItem.getItemMeta(); + meta.setDisplayName(job.getName()); + meta.setLore(Lore); + GuiItem.setItemMeta(meta); + + GuiInv.setItem(i, GuiItem); + } + return GuiInv; + } + + public static Inventory CreateJobsSubGUI(Player player, Job job) { + + Inventory tempInv = Bukkit.createInventory(null, 54, ""); + + ItemStack GuiItem = job.getGuiItem(); + JobsPlayer JPlayer = Jobs.getPlayerManager().getJobsPlayer(player); + + // money exp boost + Player dude = Bukkit.getServer().getPlayer(player.getUniqueId()); + Double MoneyBoost = Jobs.getPlayerManager().GetMoneyBoost(dude, job); + Double ExpBoost = Jobs.getPlayerManager().GetExpBoost(dude, job); + + + int level = 1; + JobProgression prog = JPlayer.getJobProgression(job); + if (prog != null) + level = prog.getLevel(); + + int numjobs = JPlayer.getJobProgression().size(); + + List items = new ArrayList(); + int i = 0; + for (ActionType actionType : ActionType.values()) { + List info = job.getJobInfo(actionType); + + if (info == null || info.isEmpty()) + continue; + + ArrayList Lore = new ArrayList(); + Lore.add(ChatColor.translateAlternateColorCodes('&', "&e" + actionType.getName())); + int y = 1; + for (int z = 0; z < info.size(); z++) { + String itemName = TranslateName.Translate(info.get(z).getName(), info.get(z)); + + double income = info.get(z).getIncome(level, numjobs); + income = income + ((income * MoneyBoost) - income) + ((income * job.getMoneyBoost()) - income); + ChatColor incomeColor = income >= 0 ? ChatColor.GREEN : ChatColor.DARK_RED; + + double xp = info.get(z).getExperience(level, numjobs); + xp = xp + ((xp * ExpBoost) - xp) + ((xp * job.getExpBoost()) - xp); + ChatColor xpColor = xp >= 0 ? ChatColor.YELLOW : ChatColor.GRAY; + + String xpString = String.format("%.2fxp", xp); + + Lore.add(ChatColor.translateAlternateColorCodes('&', "&7" + itemName + " " + xpColor + xpString + " " + incomeColor + Jobs.getEconomy().format(income))); + + if (y >= 10) { + y = 1; + + if (z == info.size() - 1) + continue; + ItemMeta meta = GuiItem.getItemMeta(); + meta.setDisplayName(job.getName()); + meta.setLore(Lore); + GuiItem.setItemMeta(meta); + //GuiInv.setItem(i, GuiItem); + tempInv.setItem(i, GuiItem); + + GuiItem = job.getGuiItem(); + Lore = new ArrayList(); + Lore.add(ChatColor.translateAlternateColorCodes('&', "&e" + actionType.getName())); + i++; + } + y++; + } + ItemMeta meta = GuiItem.getItemMeta(); + meta.setDisplayName(job.getName()); + meta.setLore(Lore); + GuiItem.setItemMeta(meta); + //GuiInv.setItem(i, GuiItem); + tempInv.setItem(i, GuiItem); + i++; + } + + for (ItemStack one : tempInv.getContents()) { + if (one != null) + items.add(one); + } + + int GuiSize = 27; + int backButton = 18; + + if (items.size() > 9) { + GuiSize = 36; + backButton = 27; + } + + if (items.size() > 18) { + GuiSize = 45; + backButton = 36; + } + + if (items.size() > 27) { + GuiSize = 54; + backButton = 45; + } + + if (items.size() > 36) { + GuiSize = 54; + backButton = 53; + } + + if (items.size() > 45) { + GuiSize = 54; + backButton = 53; + } + + Inventory GuiInv = Bukkit.createInventory(null, GuiSize, job.getName() + " Info!"); + + for (int i1 = 0; i1 < items.size(); i1++) { + GuiInv.setItem(i1, items.get(i1)); + } + + ItemStack skull = new ItemStack(Material.JACK_O_LANTERN, 1, (byte) 0); + + ItemMeta skullMeta = skull.getItemMeta(); + skullMeta.setDisplayName("<<< Back"); + + skull.setItemMeta(skullMeta); + + GuiInv.setItem(backButton, skull); + + GuiInfoList guiInfo = new GuiInfoList(player.getName()); + guiInfo.setJobInfo(true); + guiInfo.setbackButton(backButton); + GuiList.put(player.getName(), guiInfo); + + return GuiInv; + } +} diff --git a/ItemList.yml b/ItemList.yml new file mode 100644 index 00000000..6090ded4 --- /dev/null +++ b/ItemList.yml @@ -0,0 +1,702 @@ +# You can edit text between - and =, keep spaces! +# if you not sure how to edit it, dont do it at all :) +# You can use any color you want and translate to any text you want +# first 2 numbers are id with meta data, keep it as it is for block/item/mob +# Text after = are minecraft'ish name, like Stone/Granite/Diorite and so on, all of them are stone +# Ex: '5:3 - Jungle Wood Plank = planks' can be changed to '5:3 - &3Jungle &4Woody &3Planky = planks' +ItemList: + - '0 - Air = air' + - '1 - All Stone = stone' + - '1:0 - Stone = stone' + - '1:1 - Granite = stone' + - '1:2 - Polished Granite = stone' + - '1:3 - Diorite = stone' + - '1:4 - Polished Diorite = stone' + - '1:5 - Andesite = stone' + - '1:6 - Polished Andesite = stone' + - '2 - Grass = grass' + - '3 - All Dirt = dirt' + - '3:0 - Dirt = dirt' + - '3:1 - Coarse Dirt = dirt' + - '3:2 - Podzol = dirt' + - '4 - Cobblestone = cobblestone' + - '5 - All Wood Plank = planks' + - '5:0 - Oak Wood Plank = planks' + - '5:1 - Spruce Wood Plank = planks' + - '5:2 - Birch Wood Plank = planks' + - '5:3 - Jungle Wood Plank = planks' + - '5:4 - Acacia Wood Plank = planks' + - '5:5 - Dark Oak Wood Plank = planks' + - '6 - All Saplings = sapling' + - '6:0 - Oak Sapling = sapling' + - '6:1 - Spruce Sapling = sapling' + - '6:2 - Birch Sapling = sapling' + - '6:3 - Jungle Sapling = sapling' + - '6:4 - Acacia Sapling = sapling' + - '6:5 - Dark Oak Sapling = sapling' + - '7 - Bedrock = bedrock' + - '8 - Flowing Water = flowing_water' + - '9 - Still Water = water' + - '10 - Flowing Lava = flowing_lava' + - '11 - Still Lava = lava' + - '12 - All Sand = sand' + - '12:0 - Sand = sand' + - '12:1 - Red Sand = sand' + - '13 - Gravel = gravel' + - '14 - Gold Ore = gold_ore' + - '15 - Iron Ore = iron_ore' + - '16 - Coal Ore = coal_ore' + - '17 - All Wood = log' + - '17:0 - Oak Wood = log' + - '17:1 - Spruce Wood = log' + - '17:2 - Birch Wood = log' + - '17:3 - Jungle Wood = log' + - '18 - All Leaves = leaves' + - '18:0 - Oak Leaves = leaves' + - '18:1 - Spruce Leaves = leaves' + - '18:2 - Birch Leaves = leaves' + - '18:3 - Jungle Leaves = leaves' + - '19 - Sponge = sponge' + - '19:1 - Wet Sponge = sponge' + - '20 - Glass = glass' + - '21 - Lapis Lazuli Ore = lapis_ore' + - '22 - Lapis Lazuli Block = lapis_block' + - '23 - Dispenser = dispenser' + - '24 - Sandstone = sandstone' + - '24:1 - Chiseled Sandstone = sandstone' + - '24:2 - Smooth Sandstone = sandstone' + - '25 - Note Block = noteblock' + - '26 - Bed = bed' + - '27 - Powered Rail = golden_rail' + - '28 - Detector Rail = detector_rail' + - '29 - Sticky Piston = sticky_piston' + - '30 - Cobweb = web' + - '31 - Dead Shrub = tallgrass' + - '31:1 - Grass = tallgrass' + - '31:2 - Fern = tallgrass' + - '32 - Dead Shrub = deadbush' + - '33 - Piston = piston' + - '34 - Piston Head = piston_head' + - '35 - All Wool = wool' + - '35:0 - White Wool = wool' + - '35:1 - Orange Wool = wool' + - '35:2 - Magenta Wool = wool' + - '35:3 - Light Blue Wool = wool' + - '35:4 - Yellow Wool = wool' + - '35:5 - Lime Wool = wool' + - '35:6 - Pink Wool = wool' + - '35:7 - Gray Wool = wool' + - '35:8 - Light Gray Wool = wool' + - '35:9 - Cyan Wool = wool' + - '35:10 - Purple Wool = wool' + - '35:11 - Blue Wool = wool' + - '35:12 - Brown Wool = wool' + - '35:13 - Green Wool = wool' + - '35:14 - Red Wool = wool' + - '35:15 - Black Wool = wool' + - '37 - Dandelion = yellow_flower' + - '38 - All Flowers = red_flower' + - '38:0 - Poppy = red_flower' + - '38:1 - Blue Orchid = red_flower' + - '38:2 - Allium = red_flower' + - '38:3 - Azure Bluet = red_flower' + - '38:4 - Red Tulip = red_flower' + - '38:5 - Orange Tulip = red_flower' + - '38:6 - White Tulip = red_flower' + - '38:7 - Pink Tulip = red_flower' + - '38:8 - Oxeye Daisy = red_flower' + - '39 - Brown Mushroom = brown_mushroom' + - '40 - Red Mushroom = red_mushroom' + - '41 - Gold Block = gold_block' + - '42 - Iron Block = iron_block' + - '43 - All Double Slabs = double_stone_slab' + - '43:0 - Double Stone Slab = double_stone_slab' + - '43:1 - Double Sandstone Slab = double_stone_slab' + - '43:2 - Double Wooden Slab = double_stone_slab' + - '43:3 - Double Cobblestone Slab = double_stone_slab' + - '43:4 - Double Brick Slab = double_stone_slab' + - '43:5 - Double Stone Brick Slab = double_stone_slab' + - '43:6 - Double Nether Brick Slab = double_stone_slab' + - '43:7 - Double Quartz Slab = double_stone_slab' + - '44 - All Slabs = stone_slab' + - '44:0 - Stone Slab = stone_slab' + - '44:1 - Sandstone Slab = stone_slab' + - '44:2 - Wooden Slab = stone_slab' + - '44:3 - Cobblestone Slab = stone_slab' + - '44:4 - Brick Slab = stone_slab' + - '44:5 - Stone Brick Slab = stone_slab' + - '44:6 - Nether Brick Slab = stone_slab' + - '44:7 - Quartz Slab = stone_slab' + - '45 - Bricks = brick_block' + - '46 - TNT = tnt' + - '47 - Bookshelf = bookshelf' + - '48 - Moss Stone = mossy_cobblestone' + - '49 - Obsidian = obsidian' + - '50 - Torch = torch' + - '51 - Fire = fire' + - '52 - Monster Spawner = mob_spawner' + - '53 - Oak Wood Stairs = oak_stairs' + - '54 - Chest = chest' + - '55 - Redstone Wire = redstone_wire' + - '56 - Diamond Ore = diamond_ore' + - '57 - Diamond Block = diamond_block' + - '58 - Crafting Table = crafting_table' + - '59 - Wheat Crops = wheat' + - '60 - Farmland = farmland' + - '61 - Furnace = furnace' + - '62 - Burning Furnace = lit_furnace' + - '63 - Standing Sign Block = standing_sign' + - '64 - Wooden Door Block = wooden_door' + - '65 - Ladder = ladder' + - '66 - Rail = rail' + - '67 - Cobblestone Stairs = stone_stairs' + - '68 - Wall-mounted Sign Block = wall_sign' + - '69 - Lever = lever' + - '70 - Stone Pressure Plate = stone_pressure_plate' + - '71 - Iron Door Block = iron_door' + - '72 - Wooden Pressure Plate = wooden_pressure_plate' + - '73 - Redstone Ore = redstone_ore' + - '74 - Glowing Redstone Ore = lit_redstone_ore' + - '75 - Redstone Torch (off) = unlit_redstone_torch' + - '76 - Redstone Torch (on) = redstone_torch' + - '77 - Stone Button = stone_button' + - '78 - Snow = snow_layer' + - '79 - Ice = ice' + - '80 - Snow Block = snow' + - '81 - Cactus = cactus' + - '82 - Clay = clay' + - '83 - Sugar Canes = reeds' + - '84 - Jukebox = jukebox' + - '85 - Oak Fence = fence' + - '86 - Pumpkin = pumpkin' + - '87 - Netherrack = netherrack' + - '88 - Soul Sand = soul_sand' + - '89 - Glowstone = glowstone' + - '90 - Nether Portal = portal' + - '91 - Jack o''Lantern = lit_pumpkin' + - '92 - Cake Block = cake' + - '93 - Redstone Repeater Block (off) = unpowered_repeater' + - '94 - Redstone Repeater Block (on) = powered_repeater' + - '95 - All Stained Glass = stained_glass' + - '95:0 - White Stained Glass = stained_glass' + - '95:1 - Orange Stained Glass = stained_glass' + - '95:2 - Magenta Stained Glass = stained_glass' + - '95:3 - Light Blue Stained Glass = stained_glass' + - '95:4 - Yellow Stained Glass = stained_glass' + - '95:5 - Lime Stained Glass = stained_glass' + - '95:6 - Pink Stained Glass = stained_glass' + - '95:7 - Gray Stained Glass = stained_glass' + - '95:8 - Light Gray Stained Glass = stained_glass' + - '95:9 - Cyan Stained Glass = stained_glass' + - '95:10 - Purple Stained Glass = stained_glass' + - '95:11 - Blue Stained Glass = stained_glass' + - '95:12 - Brown Stained Glass = stained_glass' + - '95:13 - Green Stained Glass = stained_glass' + - '95:14 - Red Stained Glass = stained_glass' + - '95:15 - Black Stained Glass = stained_glass' + - '96 - Wooden Trapdoor = trapdoor' + - '97 - Stone Monster Egg = monster_egg' + - '97:1 - Cobblestone Monster Egg = monster_egg' + - '97:2 - Stone Brick Monster Egg = monster_egg' + - '97:3 - Mossy Stone Brick Monster Egg = monster_egg' + - '97:4 - Cracked Stone Brick Monster Egg = monster_egg' + - '97:5 - Chiseled Stone Brick Monster Egg = monster_egg' + - '98 - Stone Bricks = stonebrick' + - '98:1 - Mossy Stone Bricks = stonebrick' + - '98:2 - Cracked Stone Bricks = stonebrick' + - '98:3 - Chiseled Stone Bricks = stonebrick' + - '99 - Red Mushroom Cap = stonebrick' + - '100 - Brown Mushroom Cap = stonebrick' + - '101 - Iron Bars = iron_bars' + - '102 - Glass Pane = glass_pane' + - '103 - Melon Block = melon_block' + - '104 - Pumpkin Stem = pumpkin_stem' + - '105 - Melon Stem = melon_stem' + - '106 - Vines = vine' + - '107 - Oak Fence Gate = fence_gate' + - '108 - Brick Stairs = brick_stairs' + - '109 - Stone Brick Stairs = stone_brick_stairs' + - '110 - Mycelium = mycelium' + - '111 - Lily Pad = waterlily' + - '112 - Nether Brick = nether_brick' + - '113 - Nether Brick Fence = nether_brick_fence' + - '114 - Nether Brick Stairs = nether_brick_stairs' + - '115 - Nether Wart = nether_wart' + - '116 - Enchantment Table = enchanting_table' + - '117 - Brewing Stand = brewing_stand' + - '118 - Cauldron = cauldron' + - '119 - End Portal = end_portal' + - '120 - End Portal Frame = end_portal_frame' + - '121 - End Stone = end_stone' + - '122 - Dragon Egg = dragon_egg' + - '123 - Redstone Lamp (inactive) = redstone_lamp' + - '124 - Redstone Lamp (active) = lit_redstone_lamp' + - '125 - All Double Wood Slab = double_wooden_slab' + - '125:0 - Double Oak Wood Slab = double_wooden_slab' + - '125:1 - Double Spruce Wood Slab = double_wooden_slab' + - '125:2 - Double Birch Wood Slab = double_wooden_slab' + - '125:3 - Double Jungle Wood Slab = double_wooden_slab' + - '125:4 - Double Acacia Wood Slab = double_wooden_slab' + - '125:5 - Double Dark Oak Wood Slab = double_wooden_slab' + - '126 - All Wood Slab = wooden_slab' + - '126:0 - Oak Wood Slab = wooden_slab' + - '126:1 - Spruce Wood Slab = wooden_slab' + - '126:2 - Birch Wood Slab = wooden_slab' + - '126:3 - Jungle Wood Slab = wooden_slab' + - '126:4 - Acacia Wood Slab = wooden_slab' + - '126:5 - Dark Oak Wood Slab = wooden_slab' + - '127 - Cocoa = cocoa' + - '128 - Sandstone Stairs = sandstone_stairs' + - '129 - Emerald Ore = emerald_ore' + - '130 - Ender Chest = ender_chest' + - '131 - Tripwire Hook = tripwire_hook' + - '132 - Tripwire = tripwire_hook' + - '133 - Emerald Block = emerald_block' + - '134 - Spruce Wood Stairs = spruce_stairs' + - '135 - Birch Wood Stairs = birch_stairs' + - '136 - Jungle Wood Stairs = jungle_stairs' + - '137 - Command Block = command_block' + - '138 - Beacon = beacon' + - '139 - Cobblestone Wall = cobblestone_wall' + - '139:1 - Mossy Cobblestone Wall = cobblestone_wall' + - '140 - Flower Pot = flower_pot' + - '141 - Carrots = carrots' + - '142 - Potatoes = potatoes' + - '143 - Wooden Button = wooden_button' + - '144 - Mob Head = skull' + - '145 - Anvil = anvil' + - '146 - Trapped Chest = trapped_chest' + - '147 - Weighted Pressure Plate (light) = light_weighted_pressure_plate' + - '148 - Weighted Pressure Plate (heavy) = heavy_weighted_pressure_plate' + - '149 - Redstone Comparator (inactive) = unpowered_comparator' + - '150 - Redstone Comparator (active) = powered_comparator' + - '151 - Daylight Sensor = daylight_detector' + - '152 - Redstone Block = redstone_block' + - '153 - Nether Quartz Ore = quartz_ore' + - '154 - Hopper = hopper' + - '155 - Quartz Block = quartz_block' + - '155:1 - Chiseled Quartz Block = quartz_block' + - '155:2 - Pillar Quartz Block = quartz_block' + - '156 - Quartz Stairs = quartz_stairs' + - '157 - Activator Rail = activator_rail' + - '158 - Dropper = dropper' + - '159 - All Stained Clays = stained_hardened_clay' + - '159:0 - White Stained Clay = stained_hardened_clay' + - '159:1 - Orange Stained Clay = stained_hardened_clay' + - '159:2 - Magenta Stained Clay = stained_hardened_clay' + - '159:3 - Light Blue Stained Clay = stained_hardened_clay' + - '159:4 - Yellow Stained Clay = stained_hardened_clay' + - '159:5 - Lime Stained Clay = stained_hardened_clay' + - '159:6 - Pink Stained Clay = stained_hardened_clay' + - '159:7 - Gray Stained Clay = stained_hardened_clay' + - '159:8 - Light Gray Stained Clay = stained_hardened_clay' + - '159:9 - Cyan Stained Clay = stained_hardened_clay' + - '159:10 - Purple Stained Clay = stained_hardened_clay' + - '159:11 - Blue Stained Clay = stained_hardened_clay' + - '159:12 - Brown Stained Clay = stained_hardened_clay' + - '159:13 - Green Stained Clay = stained_hardened_clay' + - '159:14 - Red Stained Clay = stained_hardened_clay' + - '159:15 - Black Stained Clay = stained_hardened_clay' + - '160 - All Stained Glass Panes = stained_glass_pane' + - '160:0 - White Stained Glass Pane = stained_glass_pane' + - '160:1 - Orange Stained Glass Pane = stained_glass_pane' + - '160:2 - Magenta Stained Glass Pane = stained_glass_pane' + - '160:3 - Light Blue Stained Glass Pane = stained_glass_pane' + - '160:4 - Yellow Stained Glass Pane = stained_glass_pane' + - '160:5 - Lime Stained Glass Pane = stained_glass_pane' + - '160:6 - Pink Stained Glass Pane = stained_glass_pane' + - '160:7 - Gray Stained Glass Pane = stained_glass_pane' + - '160:8 - Light Gray Stained Glass Pane = stained_glass_pane' + - '160:9 - Cyan Stained Glass Pane = stained_glass_pane' + - '160:10 - Purple Stained Glass Pane = stained_glass_pane' + - '160:11 - Blue Stained Glass Pane = stained_glass_pane' + - '160:12 - Brown Stained Glass Pane = stained_glass_pane' + - '160:13 - Green Stained Glass Pane = stained_glass_pane' + - '160:14 - Red Stained Glass Pane = stained_glass_pane' + - '160:15 - Black Stained Glass Pane = stained_glass_pane' + - '161 - Acacia Or Dark Oak Leaves = leaves2' + - '161:0 - Acacia Leaves = leaves2' + - '161:1 - Dark Oak Leaves = leaves2' + - '162 - Acacia Or Dark Oak Wood = logs2' + - '162:0 - Acacia Wood = logs2' + - '162:1 - Dark Oak Wood = logs2' + - '163 - Acacia Wood Stairs = acacia_stairs' + - '164 - Dark Oak Wood Stairs = dark_oak_stairs' + - '165 - Slime Block = slime' + - '166 - Barrier = barrier' + - '167 - Iron Trapdoor = iron_trapdoor' + - '168 - All Prismarine = prismarine' + - '168:0 - Prismarine = prismarine' + - '168:1 - Prismarine Bricks = prismarine' + - '168:2 - Dark Prismarine = prismarine' + - '169 - Sea Lantern = sea_lantern' + - '170 - Hay Bale = hay_block' + - '171 - All Carpet = carpet' + - '171:0 - White Carpet = carpet' + - '171:1 - Orange Carpet = carpet' + - '171:2 - Magenta Carpet = carpet' + - '171:3 - Light Blue Carpet = carpet' + - '171:4 - Yellow Carpet = carpet' + - '171:5 - Lime Carpet = carpet' + - '171:6 - Pink Carpet = carpet' + - '171:7 - Gray Carpet = carpet' + - '171:8 - Light Gray Carpet = carpet' + - '171:9 - Cyan Carpet = carpet' + - '171:10 - Purple Carpet = carpet' + - '171:11 - Blue Carpet = carpet' + - '171:12 - Brown Carpet = carpet' + - '171:13 - Green Carpet = carpet' + - '171:14 - Red Carpet = carpet' + - '171:15 - Black Carpet = carpet' + - '172 - Hardened Clay = hardened_clay' + - '173 - Block of Coal = coal_block' + - '174 - Packed Ice = packed_ice' + - '175 - All Big Flowers = double_plant' + - '175:0 - Sunflower = double_plant' + - '175:1 - Lilac = double_plant' + - '175:2 - Double Tallgrass = double_plant' + - '175:3 - Large Fern = double_plant' + - '175:4 - Rose Bush = double_plant' + - '175:5 - Peony = double_plant' + - '176 - Free-standing Banner = standing_banner' + - '177 - Wall-mounted Banner = wall_banner' + - '178 - Inverted Daylight Sensor = daylight_detector_inverted' + - '179 - Red Sandstone = red_sandstone' + - '179:1 - Smooth Red Sandstone = red_sandstone' + - '179:2 - Chiseled Red Sandstone = red_sandstone' + - '180 - Red Sandstone Stairs = red_sandstone_stairs' + - '181 - Double Red Sandstone Slab = stone_slab2' + - '182 - Red Sandstone Slab = double_stone_slab2' + - '183 - Spruce Fence Gate = spruce_fence_gate' + - '184 - Birch Fence Gate = birch_fence_gate' + - '185 - Jungle Fence Gate = jungle_fence_gate' + - '186 - Dark Oak Fence Gate = dark_oak_fence_gate' + - '187 - Acacia Fence Gate = acacia_fence_gate' + - '188 - Spruce Fence = spruce_fence' + - '189 - Birch Fence = birch_fence' + - '190 - Jungle Fence = jungle_fence' + - '191 - Dark Oak Fence = dark_oak_fence' + - '192 - Acacia Fence = acacia_fence' + - '193 - Spure Door Block = spruce_door' + - '194 - Birch Door Block = birch_door' + - '195 - Jungle Door Block = jungle_door' + - '196 - Acacia Door Block = acacia_door' + - '197 - Dark Oak Door Block = dark_oak_door' + - '256 - Iron Shovel = iron_shovel' + - '257 - Iron Pickaxe = iron_pickaxe' + - '258 - Iron Axe = iron_axe' + - '259 - Flint and Steel = flint_and_steel' + - '260 - Apple = apple' + - '261 - Bow = bow' + - '262 - Arrow = arrow' + - '263 - Coal = coal' + - '263:1 - Charcoal = coal' + - '264 - Diamond = diamond' + - '265 - Iron Ingot = iron_ingot' + - '266 - Gold Ingot = gold_ingot' + - '267 - Iron Sword = iron_sword' + - '268 - Wooden Sword = wooden_sword' + - '269 - Wooden Shovel = wooden_shovel' + - '270 - Wooden Pickaxe = wooden_pickaxe' + - '271 - Wooden Axe = wooden_axe' + - '272 - Stone Sword = stone_sword' + - '273 - Stone Shovel = stone_shovel' + - '274 - Stone Pickaxe = stone_pickaxe' + - '275 - Stone Axe = stone_axe' + - '276 - Diamond Sword = diamond_sword' + - '277 - Diamond Shovel = diamond_shovel' + - '278 - Diamond Pickaxe = diamond_pickaxe' + - '279 - Diamond Axe = diamond_axe' + - '280 - Stick = stick' + - '281 - Bowl = bowl' + - '282 - Mushroom Stew = mushroom_stew' + - '283 - Golden Sword = golden_sword' + - '284 - Golden Shovel = golden_shovel' + - '285 - Golden Pickaxe = golden_pickaxe' + - '286 - Golden Axe = golden_axe' + - '287 - String = string' + - '288 - Feather = feather' + - '289 - Gunpowder = gunpowder' + - '290 - Wooden Hoe = wooden_hoe' + - '291 - Stone Hoe = stone_hoe' + - '292 - Iron Hoe = iron_hoe' + - '293 - Diamond Hoe = diamond_hoe' + - '294 - Golden Hoe = golden_hoe' + - '295 - Wheat Seeds = wheat_seeds' + - '296 - Wheat = wheat' + - '297 - Bread = bread' + - '298 - Leather Helmet = leather_helmet' + - '299 - Leather Tunic = leather_chestplate' + - '300 - Leather Pants = leather_leggings' + - '301 - Leather Boots = leather_boots' + - '302 - Chainmail Helmet = chainmail_helmet' + - '303 - Chainmail Chestplate = chainmail_chestplate' + - '304 - Chainmail Leggings = chainmail_leggings' + - '305 - Chainmail Boots = chainmail_boots' + - '306 - Iron Helmet = iron_helmet' + - '307 - Iron Chestplate = iron_chestplate' + - '308 - Iron Leggings = iron_leggings' + - '309 - Iron Boots = iron_boots' + - '310 - Diamond Helmet = diamond_helmet' + - '311 - Diamond Chestplate = diamond_chestplate' + - '312 - Diamond Leggings = diamond_leggings' + - '313 - Diamond Boots = diamond_boots' + - '314 - Golden Helmet = golden_helmet' + - '315 - Golden Chestplate = golden_chestplate' + - '316 - Golden Leggings = golden_leggings' + - '317 - Golden Boots = golden_boots' + - '318 - Flint = flint_and_steel' + - '319 - Raw Porkchop = porkchop' + - '320 - Cooked Porkchop = cooked_porkchop' + - '321 - Painting = painting' + - '322 - Golden Apple = golden_apple' + - '322:1 - Enchanted Golden Apple = golden_apple' + - '323 - Sign = sign' + - '324 - Wooden Door = wooden_door' + - '325 - Bucket = bucket' + - '326 - Water Bucket = water_bucket' + - '327 - Lava Bucket = lava_bucket' + - '328 - Minecart = minecart' + - '329 - Saddle = saddle' + - '330 - Iron Door = iron_door' + - '331 - Redstone = redstone' + - '332 - Snowball = snowball' + - '333 - Boat = boat' + - '334 - Leather = leather' + - '335 - Milk Bucket = milk_bucket' + - '336 - Brick = brick' + - '337 - Clay Ball = clay_ball' + - '338 - Sugar Canes = reeds' + - '339 - Paper = paper' + - '340 - Book = book' + - '341 - Slimeball = slime_ball' + - '342 - Minecart with Chest = chest_minecart' + - '343 - Minecart with Furnace = furnace_minecart' + - '344 - Egg = egg' + - '345 - Compass = compass' + - '346 - Fishing Rod = fishing_rod' + - '347 - Clock = clock' + - '348 - Glowstone Dust = glowstone_dust' + - '349 - Raw Fish = fish' + - '349:1 - Raw Salmon = fish' + - '349:2 - Clownfish = fish' + - '349:3 - Pufferfish = fish' + - '350 - Cooked Fish = cooked_fish' + - '350:1 - Cooked Salmon = cooked_fish' + - '351 - All Dyes = dye' + - '351:0 - Ink Sack = dye' + - '351:1 - Rose Red = dye' + - '351:2 - Cactus Green = dye' + - '351:3 - Coco Beans = dye' + - '351:4 - Lapis Lazuli = dye' + - '351:5 - Purple Dye = dye' + - '351:6 - Cyan Dye = dye' + - '351:7 - Light Gray Dye = dye' + - '351:8 - Gray Dye = dye' + - '351:9 - Pink Dye = dye' + - '351:10 - Lime Dye = dye' + - '351:11 - Dandelion Yellow = dye' + - '351:12 - Light Blue Dye = dye' + - '351:13 - Magenta Dye = dye' + - '351:14 - Orange Dye = dye' + - '351:15 - Bone Meal = dye' + - '352 - Bone = bone' + - '353 - Sugar = sugar' + - '354 - Cake = cake' + - '355 - Bed = bed' + - '356 - Redstone Repeater = repeater' + - '357 - Cookie = cookie' + - '358 - Map = filled_map' + - '359 - Shears = shears' + - '360 - Melon = melon' + - '361 - Pumpkin Seeds = pumpkin_seeds' + - '362 - Melon Seeds = melon_seeds' + - '363 - Raw Beef = beef' + - '364 - Steak = cooked_beef' + - '365 - Raw Chicken = chicken' + - '366 - Cooked Chicken = cooked_chicken' + - '367 - Rotten Flesh = rotten_flesh' + - '368 - Ender Pearl = ender_pearl' + - '369 - Blaze Rod = blaze_rod' + - '370 - Ghast Tear = ghast_tear' + - '371 - Gold Nugget = gold_nugget' + - '372 - Nether Wart = nether_wart' + - '373 - Potion = potion' + - '374 - Glass Bottle = glass_bottle' + - '375 - Spider Eye = spider_eye' + - '376 - Fermented Spider Eye = fermented_spider_eye' + - '377 - Blaze Powder = blaze_powder' + - '378 - Magma Cream = magma_cream' + - '379 - Brewing Stand = brewing_stand' + - '380 - Cauldron = cauldron' + - '381 - Eye of Ender = ender_eye' + - '382 - Glistering Melon = speckled_melon' + - '383:50 - Spawn Creeper = spawn_egg' + - '383:51 - Spawn Skeleton = spawn_egg' + - '383:52 - Spawn Spider = spawn_egg' + - '383:54 - Spawn Zombie = spawn_egg' + - '383:55 - Spawn Slime = spawn_egg' + - '383:56 - Spawn Ghast = spawn_egg' + - '383:57 - Spawn Pigman = spawn_egg' + - '383:58 - Spawn Enderman = spawn_egg' + - '383:59 - Spawn Cave Spider = spawn_egg' + - '383:60 - Spawn Silverfish = spawn_egg' + - '383:61 - Spawn Blaze = spawn_egg' + - '383:62 - Spawn Magma Cube = spawn_egg' + - '383:65 - Spawn Bat = spawn_egg' + - '383:66 - Spawn Witch = spawn_egg' + - '383:67 - Spawn Endermite = spawn_egg' + - '383:68 - Spawn Guardian = spawn_egg' + - '383:90 - Spawn Pig = spawn_egg' + - '383:91 - Spawn Sheep = spawn_egg' + - '383:92 - Spawn Cow = spawn_egg' + - '383:93 - Spawn Chicken = spawn_egg' + - '383:94 - Spawn Squid = spawn_egg' + - '383:95 - Spawn Wolf = spawn_egg' + - '383:96 - Spawn Mooshroom = spawn_egg' + - '383:98 - Spawn Ocelot = spawn_egg' + - '383:100 - Spawn Horse = spawn_egg' + - '383:101 - Spawn Rabbit = spawn_egg' + - '383:120 - Spawn Villager = spawn_egg' + - '384 - Bottle o'' Enchanting = experience_bottle' + - '385 - Fire Charge = fire_charge' + - '386 - Book and Quill = writable_book' + - '387 - Written Book = written_book' + - '388 - Emerald = emerald' + - '389 - Item Frame = item_frame' + - '390 - Flower Pot = flower_pot' + - '391 - Carrot = carrot' + - '392 - Potato = potato' + - '393 - Baked Potato = baked_potato' + - '394 - Poisonous Potato = poisonous_potato' + - '395 - Empty Map = map' + - '396 - Golden Carrot = golden_carrot' + - '397 - Mob Head (Skeleton) = skull' + - '397:1 - Mob Head (Wither Skeleton) = skull' + - '397:2 - Mob Head (Zombie) = skull' + - '397:3 - Mob Head (Human) = skull' + - '397:4 - Mob Head (Creeper) = skull' + - '398 - Carrot on a Stick = carrot_on_a_stick' + - '399 - Nether Star = nether_star' + - '400 - Pumpkin Pie = pumpkin_pie' + - '401 - Firework Rocket = fireworks' + - '402 - Firework Star = firework_charge' + - '403 - Enchanted Book = enchanted_book' + - '404 - Redstone Comparator = comparator' + - '405 - Nether Brick = netherbrick' + - '406 - Nether Quartz = quartz' + - '407 - Minecart with TNT = tnt_minecart' + - '408 - Minecart with Hopper = hopper_minecart' + - '409 - Prismarine Shard = prismarine_shard' + - '410 - Prismarine Crystals = prismarine_crystals' + - '411 - Raw Rabbit = rabbit' + - '412 - Cooked Rabbit = cooked_rabbit' + - '413 - Rabbit Stew = rabbit_stew' + - '414 - Rabbit''s Foot = rabbit_foot' + - '415 - Rabbit Hide = rabbit_hide' + - '416 - Armor Stand = armor_stand' + - '417 - Iron Horse Armor = iron_horse_armor' + - '418 - Golden Horse Armor = golden_horse_armor' + - '419 - Diamond Horse Armor = diamond_horse_armor' + - '420 - Lead = lead' + - '421 - Name Tag = name_tag' + - '422 - Minecart with Command Block = command_block_minecart' + - '423 - Raw Mutton = mutton' + - '424 - Cooked Mutton = cooked_mutton' + - '425 - Banner = banner' + - '427 - Spruce Door = spruce_door' + - '428 - Birch Door = birch_door' + - '429 - Jungle Door = jungle_door' + - '430 - Acacia Door = acacia_door' + - '431 - Dark Oak Door = dark_oak_door' + - '2256 - 13 Disc = record_13' + - '2257 - Cat Disc = record_cat' + - '2258 - Blocks Disc = record_blocks' + - '2259 - Chirp Disc = record_chirp' + - '2260 - Far Disc = record_far' + - '2261 - Mall Disc = record_mall' + - '2262 - Mellohi Disc = record_mellohi' + - '2263 - Stal Disc = record_stal' + - '2264 - Strad Disc = record_strad' + - '2265 - Ward Disc = record_ward' + - '2266 - 11 Disc = record_11' + - '2267 - Wait Disc = record_wait' +EntityList: + - '50 - Creeper = Creeper' + - '51 - Skeleton = Skeleton' + - '51:1 - WitherSkeleton = Skeleton' + - '52 - Spider = Spider' + - '53 - Giant = Giant' + - '54 - Zombie = Zombie' + - '54:1 - Zombie Villager = Zombie' + - '55 - Slime = Slime' + - '56 - Ghast = Ghast' + - '57 - Zombie Pigman = PigZombie' + - '58 - Enderman = Enderman' + - '59 - Cave Spider = CaveSpider' + - '60 - Silverfish = Silverfish' + - '61 - Blaze = Blaze' + - '62 - LavaSlime = LavaSlime' + - '63 - EnderDragon = EnderDragon' + - '64 - Wither = WitherBoss' + - '65 - Bat = Bat' + - '66 - Witch = Witch' + - '67 - Endermite = Endermite' + - '68 - Guardian = Guardian' + - '68:1 - Elder Guardian = Guardian' + - '90 - Pig = Pig' + - '91 - Sheep = Sheep' + - '92 - Cow = Cow' + - '93 - Chicken = Chicken' + - '94 - Squid = Squid' + - '95 - Wolf = Wolf' + - '96 - MushroomCow = MushroomCow' + - '97 - Snow Golem = SnowMan' + - '98 - Ocelot = Ozelot' + - '99 - Iron Golem = VillagerGolem' + - '100 - Horse = EntityHorse' + - '101 - Rabbit = Rabbit' + - '120 - Villager = Villager' +EnchantList: + - '0 - Protection = PROTECTION_ENVIRONMENTAL' + - '1 - Fire Protection = PROTECTION_FIRE' + - '2 - Feather Falling = PROTECTION_FALL' + - '3 - Blast Protection = PROTECTION_EXPLOSIONS' + - '4 - Projectile Protection = ROTECTION_PROJECTILE' + - '5 - Respiration = OXYGEN' + - '6 - Aqua Affinity = DIG_SPEED' + - '7 - Thorns = THORNS' + - '8 - Depth Strider = DEPTH_STRIDER' + - '16 - Sharpness = DAMAGE_ALL' + - '17 - Smite = DAMAGE_UNDEAD' + - '18 - Bane of Arthropods = DAMAGE_ARTHROPODS' + - '19 - Knockback = KNOCKBACK' + - '20 - Fire Aspect = FIRE_ASPECT' + - '21 - Looting = LOOT_BONUS_MOBS' + - '32 - Efficiency = DIG_SPEED' + - '33 - Silk Touch = SILK_TOUCH' + - '34 - Unbreaking = DURABILITY' + - '35 - Fortune = LOOT_BONUS_BLOCKS' + - '48 - Power = ARROW_DAMAGE' + - '49 - Punch = ARROW_KNOCKBACK' + - '50 - Flame = ARROW_FIRE' + - '51 - Infinity = ARROW_INFINITE' + - '61 - Luck of the Sea = LUCK' + - '62 - Lure = LURE' +ColorList: + - '0 - &fWhite = white' + - '1 - &6Orange = orange' + - '2 - &dMagenta = magenta' + - '3 - %9Light blue = lightBlue' + - '4 - &eYellow = yellow' + - '5 - &aLime = lime' + - '6 - &dPink = pink' + - '7 - &8Gray = gray' + - '8 - &7Light gray = silver' + - '9 - &3Cyan = cyan' + - '10 - &5Purple = purple' + - '11 - &1Blue = blue' + - '12 - &4Brown = brown' + - '13 - &2Green = green' + - '14 - &cRed = red' + - '15 - &0Black = black' \ No newline at end of file diff --git a/META-INF/maven/com.gamingmesh/jobs/pom.properties b/META-INF/maven/com.gamingmesh/jobs/pom.properties new file mode 100644 index 00000000..2f42ff28 --- /dev/null +++ b/META-INF/maven/com.gamingmesh/jobs/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Wed Aug 20 21:00:44 EDT 2014 +version=2.13-SNAPSHOT +groupId=com.gamingmesh +artifactId=jobs diff --git a/META-INF/maven/com.gamingmesh/jobs/pom.xml b/META-INF/maven/com.gamingmesh/jobs/pom.xml new file mode 100644 index 00000000..5565f481 --- /dev/null +++ b/META-INF/maven/com.gamingmesh/jobs/pom.xml @@ -0,0 +1,129 @@ + + 4.0.0 + com.gamingmesh + jobs + 2.13-SNAPSHOT + jar + Jobs + Jobs Plugin for the BukkitAPI + + UTF-8 + + + + snapshot + + true + + + ${project.version} + + + + ci + + 2.13.${build.number} + + + + + + bukkit-repo + http://repo.bukkit.org/content/groups/public + + + vault-repo + http://nexus.theyeticave.net/content/repositories/pub_releases + + + + + mc-release + Local Maven repository of releases + http://mc-repo.googlecode.com/svn/maven2/releases + + false + + + true + + + + + + org.bukkit + bukkit + 1.7.9-R0.2 + + + net.milkbowl.vault + VaultAPI + 1.4 + + + + clean package install + ${basedir}/src/main/java + ${project.name} + + + + . + true + ${basedir}/src/main/resources/ + + plugin.yml + + + + . + false + ${basedir}/src/main/resources/ + + i18n/* + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + + + + com.mycila.maven-license-plugin + maven-license-plugin + 1.10.b1 + + UTF-8 +
${basedir}/HEADER-GPL.txt
+ + ${basedir}/HEADER-JFEP.txt + ${basedir}/HEADER-Sfun.txt + + true + + src/main/java/** + + + Jobs Plugin for Bukkit + 2011 + Zak Ford + zak.j.ford@gmail.com + +
+ + + + check + + + +
+
+
+
\ No newline at end of file diff --git a/Signs.yml b/Signs.yml new file mode 100644 index 00000000..64c32d53 --- /dev/null +++ b/Signs.yml @@ -0,0 +1 @@ +Signs: {} \ No newline at end of file diff --git a/Signs/.gitignore b/Signs/.gitignore new file mode 100644 index 00000000..f3761824 --- /dev/null +++ b/Signs/.gitignore @@ -0,0 +1,7 @@ +/TopSignStuff.class +/Sign.class +/SignInfo.class +/SignUtil.class +/SignUtil$1.class +/SignUtil$2.class +/SignUtil$3.class diff --git a/Signs/Sign.java b/Signs/Sign.java new file mode 100644 index 00000000..d2cf0033 --- /dev/null +++ b/Signs/Sign.java @@ -0,0 +1,80 @@ +package Signs; + +public class Sign { + + int Category = 0; + String World = null; + double x = 0.01; + double y = 0.01; + double z = 0.01; + int Number = 0; + String JobName = null; + boolean special = false; + + public Sign() { + } + + public void setSpecial(boolean special) { + this.special = special; + } + + public boolean isSpecial() { + return this.special; + } + + public void setJobName(String JobName) { + this.JobName = JobName; + } + + public String GetJobName() { + return this.JobName; + } + + public void setCategory(int Category) { + this.Category = Category; + } + + public int GetCategory() { + return this.Category; + } + + public void setWorld(String World) { + this.World = World; + } + + public String GetWorld() { + return this.World; + } + + public void setX(double x) { + this.x = x; + } + + public double GetX() { + return this.x; + } + + public void setY(double y) { + this.y = y; + } + + public double GetY() { + return this.y; + } + + public void setZ(double z) { + this.z = z; + } + + public double GetZ() { + return this.z; + } + + public void setNumber(int Number) { + this.Number = Number; + } + + public int GetNumber() { + return this.Number; + } +} diff --git a/Signs/SignInfo.java b/Signs/SignInfo.java new file mode 100644 index 00000000..7987d461 --- /dev/null +++ b/Signs/SignInfo.java @@ -0,0 +1,28 @@ +package Signs; + +import java.util.ArrayList; +import java.util.List; + +public class SignInfo { + + List AllSigns = new ArrayList(); + + public SignInfo() { + } + + public void setAllSigns(List AllSigns) { + this.AllSigns = AllSigns; + } + + public List GetAllSigns() { + return this.AllSigns; + } + + public void removeSign(Sign sign) { + this.AllSigns.remove(sign); + } + + public void addSign(Sign sign) { + this.AllSigns.add(sign); + } +} diff --git a/Signs/SignUtil.java b/Signs/SignUtil.java new file mode 100644 index 00000000..36dbecce --- /dev/null +++ b/Signs/SignUtil.java @@ -0,0 +1,223 @@ +package Signs; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.Skull; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; + +import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.JobsPlugin; +import com.gamingmesh.jobs.config.CommentedYamlConfiguration; +import com.gamingmesh.jobs.config.ConfigManager; +import com.gamingmesh.jobs.container.TopList; +import com.gamingmesh.jobs.i18n.Language; + +public class SignUtil { + + public static SignInfo Signs = new SignInfo(); + + // Sign file + public static void LoadSigns() { + Thread threadd = new Thread() { + public void run() { + + Signs.GetAllSigns().clear(); + File file = new File(JobsPlugin.instance.getDataFolder(), "Signs.yml"); + YamlConfiguration f = YamlConfiguration.loadConfiguration(file); + + if (!f.isConfigurationSection("Signs")) + return; + + ConfigurationSection ConfCategory = f.getConfigurationSection("Signs"); + ArrayList categoriesList = new ArrayList(ConfCategory.getKeys(false)); + if (categoriesList.size() == 0) + return; + for (String category : categoriesList) { + ConfigurationSection NameSection = ConfCategory.getConfigurationSection(category); + Signs.Sign newTemp = new Signs.Sign(); + newTemp.setCategory(Integer.valueOf(category)); + newTemp.setWorld(NameSection.getString("World")); + newTemp.setX(NameSection.getDouble("X")); + newTemp.setY(NameSection.getDouble("Y")); + newTemp.setZ(NameSection.getDouble("Z")); + newTemp.setNumber(NameSection.getInt("Number")); + newTemp.setJobName(NameSection.getString("JobName")); + newTemp.setSpecial(NameSection.getBoolean("Special")); + Signs.addSign(newTemp); + } + return; + } + }; + threadd.start(); + } + + // Signs save file + public static void saveSigns() { + + Thread threadd = new Thread() { + public void run() { + File f = new File(JobsPlugin.instance.getDataFolder(), "Signs.yml"); + YamlConfiguration conf = YamlConfiguration.loadConfiguration(f); + + CommentedYamlConfiguration writer = new CommentedYamlConfiguration(); + conf.options().copyDefaults(true); + + writer.addComment("Signs", "DO NOT EDIT THIS FILE BY HAND!"); + + if (!conf.isConfigurationSection("Signs")) + conf.createSection("Signs"); + + for (Signs.Sign one : Signs.GetAllSigns()) { + String path = "Signs." + String.valueOf(one.GetCategory()); + writer.set(path + ".World", one.GetWorld()); + writer.set(path + ".X", one.GetX()); + writer.set(path + ".Y", one.GetY()); + writer.set(path + ".Z", one.GetZ()); + writer.set(path + ".Number", one.GetNumber()); + writer.set(path + ".JobName", one.GetJobName()); + writer.set(path + ".Special", one.isSpecial()); + } + + try { + writer.save(f); + } catch (IOException e) { + e.printStackTrace();; + } + return; + } + }; + threadd.start(); + } + + public static boolean SignUpdate(String JobName) { + List Copy = new ArrayList(Signs.GetAllSigns().size()); + for (Signs.Sign foo : Signs.GetAllSigns()) { + Copy.add(foo); + } + int timelapse = 1; + for (Signs.Sign one : Copy) { + String SignJobName = one.GetJobName(); + if (JobName.equalsIgnoreCase(SignJobName)) { + String SignsWorld = one.GetWorld(); + double SignsX = one.GetX(); + double SignsY = one.GetY(); + double SignsZ = one.GetZ(); + int number = one.GetNumber() - 1; + + List PlayerList = new ArrayList(); + if (!JobName.equalsIgnoreCase("gtoplist")) { + PlayerList = Jobs.getJobsDAO().toplist(SignJobName, number); + } else { + PlayerList = Jobs.getJobsDAO().getGlobalTopList(number); + } + if (PlayerList.size() != 0) { + World world = Bukkit.getWorld(SignsWorld); + Location nloc = new Location(world, SignsX, SignsY, SignsZ); + Block block = nloc.getBlock(); + if (!(block.getState() instanceof org.bukkit.block.Sign)) { + Signs.GetAllSigns().remove(one); + saveSigns(); + } else { + org.bukkit.block.Sign sign = (org.bukkit.block.Sign) block.getState(); + if (!one.isSpecial()) { + for (int i = 0; i < 4; i++) { + if (i >= PlayerList.size()) { + break; + } + String PlayerName = ((TopList) PlayerList.get(i)).getPlayerName(); + if (PlayerName.length() > 8) { + String PlayerNameStrip = PlayerName.split("(?<=\\G.{7})")[0]; + PlayerName = PlayerNameStrip + "~"; + } + String line = Language.getMessage("signs.List"); + line = line.replace("[number]", String.valueOf(i + number + 1)); + line = line.replace("[player]", PlayerName); + line = line.replace("[level]", String.valueOf(((TopList) PlayerList.get(i)).getLevel())); + + sign.setLine(i, line); + } + sign.update(); + UpdateHead(sign.getLocation(), ((TopList) PlayerList.get(0)).getPlayerName(), timelapse); + } else { + String PlayerName = ((TopList) PlayerList.get(0)).getPlayerName(); + if (PlayerName.length() > 18) { + String PlayerNameStrip = PlayerName.split("(?<=\\G.{13})")[0]; + PlayerName = PlayerNameStrip + "~"; + } + String line1 = Language.getMessage("signs.SpecialList." + one.GetNumber() + ".1"); + line1 = line1.replace("[number]", String.valueOf(one.GetNumber() + number + 1)); + line1 = line1.replace("[player]", PlayerName); + line1 = line1.replace("[level]", String.valueOf(((TopList) PlayerList.get(0)).getLevel())); + + sign.setLine(0, line1); + + line1 = Language.getMessage("signs.SpecialList." + one.GetNumber() + ".2"); + line1 = line1.replace("[number]", String.valueOf(one.GetNumber() + number + 1)); + line1 = line1.replace("[player]", PlayerName); + line1 = line1.replace("[level]", String.valueOf(((TopList) PlayerList.get(0)).getLevel())); + + sign.setLine(1, line1); + + line1 = Language.getMessage("signs.SpecialList." + one.GetNumber() + ".3"); + line1 = line1.replace("[number]", String.valueOf(one.GetNumber() + number + 1)); + line1 = line1.replace("[player]", PlayerName); + line1 = line1.replace("[level]", String.valueOf(((TopList) PlayerList.get(0)).getLevel())); + + sign.setLine(2, line1); + + line1 = Language.getMessage("signs.SpecialList." + one.GetNumber() + ".4"); + line1 = line1.replace("[number]", String.valueOf(one.GetNumber() + number + 1)); + line1 = line1.replace("[player]", PlayerName); + line1 = line1.replace("[level]", String.valueOf(((TopList) PlayerList.get(0)).getLevel())); + + sign.setLine(3, line1); + sign.update(); + UpdateHead(sign.getLocation(), ((TopList) PlayerList.get(0)).getPlayerName(), timelapse); + } + + timelapse++; + } + } + } + } + return true; + } + + public static void UpdateHead(final Location loc, final String Playername, final int timelapse) { + + Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(JobsPlugin.instance, new Runnable() { + public void run() { + + loc.setY(loc.getY() + 1); + + if (Playername == null) + return; + + Block block = loc.getBlock(); + + if (block == null) + return; + + if (!(block.getState() instanceof Skull)) + return; + + Skull skull = (Skull) block.getState(); + + if (skull == null) + return; + + skull.setOwner(Playername); + skull.update(); + return; + } + }, timelapse * ConfigManager.getJobsConfiguration().InfoUpdateInterval * 20L); + } +} diff --git a/com/gamingmesh/jobs/.gitignore b/com/gamingmesh/jobs/.gitignore new file mode 100644 index 00000000..f5ef64fe --- /dev/null +++ b/com/gamingmesh/jobs/.gitignore @@ -0,0 +1,7 @@ +/HookEconomyTask.class +/Jobs.class +/JobsPlugin.class +/PermissionHandler.class +/PlayerManager.class +/Jobs$1.class +/PlayerManager$1.class diff --git a/com/gamingmesh/jobs/HookEconomyTask.java b/com/gamingmesh/jobs/HookEconomyTask.java new file mode 100644 index 00000000..8200a2ae --- /dev/null +++ b/com/gamingmesh/jobs/HookEconomyTask.java @@ -0,0 +1,65 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.gamingmesh.jobs; + +import net.milkbowl.vault.economy.Economy; + +import org.bukkit.ChatColor; +import org.bukkit.Bukkit; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.RegisteredServiceProvider; + +import com.gamingmesh.jobs.economy.BlackholeEconomy; +import com.gamingmesh.jobs.economy.VaultEconomy; + +public class HookEconomyTask implements Runnable { + private JobsPlugin plugin; + + public HookEconomyTask(JobsPlugin plugin) { + this.plugin = plugin; + } + + public void run() { + Plugin eco = Bukkit.getServer().getPluginManager().getPlugin("Vault"); + if (eco != null) { + RegisteredServiceProvider provider = Bukkit.getServer().getServicesManager().getRegistration(Economy.class); + if (provider != null) { + Economy economy = provider.getProvider(); + if (economy != null) { + Jobs.setEconomy(plugin, new VaultEconomy(economy)); + String message = ChatColor.translateAlternateColorCodes('&', "&2[" + plugin.getDescription().getName() + "] Successfully linked with Vault."); + ConsoleCommandSender console = Bukkit.getServer().getConsoleSender(); + console.sendMessage(message); + return; + } + } + } + + // no Vault found + Jobs.setEconomy(plugin, new BlackholeEconomy()); + Bukkit.getServer().getLogger().severe("==================== " + plugin.getDescription().getName() + " ===================="); + Bukkit.getServer().getLogger().severe("Vault is required by this plugin for economy support!"); + Bukkit.getServer().getLogger().severe("Please install Vault first!"); + Bukkit.getServer().getLogger().severe("You can find the latest version here:"); + Bukkit.getServer().getLogger().severe("http://dev.bukkit.org/server-mods/vault/"); + Bukkit.getServer().getLogger().severe("=============================================="); + } + +} diff --git a/com/gamingmesh/jobs/Jobs.java b/com/gamingmesh/jobs/Jobs.java new file mode 100644 index 00000000..7689aef7 --- /dev/null +++ b/com/gamingmesh/jobs/Jobs.java @@ -0,0 +1,567 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.gamingmesh.jobs; + +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.WeakHashMap; +import java.util.logging.Logger; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import com.gamingmesh.jobs.config.ConfigManager; +import com.gamingmesh.jobs.container.ActionInfo; +import com.gamingmesh.jobs.container.Job; +import com.gamingmesh.jobs.container.JobItems; +import com.gamingmesh.jobs.container.JobProgression; +import com.gamingmesh.jobs.container.JobsPlayer; +import com.gamingmesh.jobs.dao.JobsDAO; +import com.gamingmesh.jobs.economy.BufferedEconomy; +import com.gamingmesh.jobs.economy.Economy; +import com.gamingmesh.jobs.economy.PaymentData; +import com.gamingmesh.jobs.i18n.Language; +import com.gamingmesh.jobs.stuff.ActionBar; +import com.gamingmesh.jobs.stuff.JobsClassLoader; +import com.gamingmesh.jobs.tasks.BufferedPaymentThread; +import com.gamingmesh.jobs.tasks.DatabaseSaveThread; + +public class Jobs { + public static Jobs instance = new Jobs(); + private static PlayerManager pManager = new PlayerManager(); + + private static Logger pLogger; + private static File dataFolder; + private static JobsClassLoader classLoader = new JobsClassLoader(instance); + private static JobsDAO dao = null; + private static List jobs = null; + private static Job noneJob = null; + private static WeakHashMap usedSlots = new WeakHashMap(); + public static WeakHashMap actionbartoggle = new WeakHashMap(); +// public static WeakHashMap GlobalBoost = new WeakHashMap(); + private static BufferedEconomy economy; + private static PermissionHandler permissionHandler; + + public static BufferedPaymentThread paymentThread = null; + private static DatabaseSaveThread saveTask = null; + + public final static HashMap paymentLimit = new HashMap(); + public final static HashMap ExpLimit = new HashMap(); + + private Jobs() { + } + + /** + * Returns player manager + * @return the player manager + */ + public static PlayerManager getPlayerManager() { + return pManager; + } + + /** + * Sets the plugin logger + */ + public static void setPluginLogger(Logger logger) { + pLogger = logger; + } + + /** + * Retrieves the plugin logger + * @return the plugin logger + */ + public static Logger getPluginLogger() { + return pLogger; + } + + /** + * Sets the data folder + * @param dir - the data folder + */ + public static void setDataFolder(File dir) { + dataFolder = dir; + } + + /** + * Retrieves the data folder + * @return data folder + */ + public static File getDataFolder() { + return dataFolder; + } + + /** + * Sets the Data Access Object + * @param dao - the DAO + */ + public static void setDAO(JobsDAO value) { + dao = value; + } + + /** + * Get the Data Access Object + * @return the DAO + */ + public static JobsDAO getJobsDAO() { + return dao; + } + + /** + * Sets the list of jobs + * @param jobs - list of jobs + */ + public static void setJobs(List list) { + jobs = list; + } + + /** + * Retrieves the list of active jobs + * @return list of jobs + */ + public static List getJobs() { + return Collections.unmodifiableList(jobs); + } + + /** + * Sets the none job + * @param noneJob - the none job + */ + public static void setNoneJob(Job job) { + noneJob = job; + } + + /** + * Retrieves the "none" job + * @return the none job + */ + public static Job getNoneJob() { + return noneJob; + } + + /** + * Function to return the job information that matches the jobName given + * @param jobName - the ame of the job given + * @return the job that matches the name + */ + public static Job getJob(String jobName) { + for (Job job : jobs) { + if (job.getName().equalsIgnoreCase(jobName)) + return job; + } + return null; + } + + /** + * Executes startup + * @throws IOException + */ + public static void startup() throws IOException { + reload(); + // add all online players + for (Player online : Bukkit.getServer().getOnlinePlayers()) { + Jobs.getPlayerManager().playerJoin(online); + } + } + + /** + * Reloads all data + * @throws IOException + */ + public static void reload() throws IOException { + if (saveTask != null) { + saveTask.shutdown(); + saveTask = null; + } + + if (paymentThread != null) { + paymentThread.shutdown(); + paymentThread = null; + } + + if (dao != null) { + dao.closeConnections(); + } + + ConfigManager.getJobsConfiguration().reload(); + Language.reload(ConfigManager.getJobsConfiguration().getLocale()); + ConfigManager.getJobConfig().reload(); + usedSlots.clear(); + for (Job job : jobs) { + usedSlots.put(job, getJobsDAO().getSlotsTaken(job)); + } + pManager.reload(); + permissionHandler.registerPermissions(); + + // set the system to auto save + if (ConfigManager.getJobsConfiguration().getSavePeriod() > 0) { + saveTask = new DatabaseSaveThread(ConfigManager.getJobsConfiguration().getSavePeriod()); + saveTask.start(); + } + + // schedule payouts to buffered payments + paymentThread = new BufferedPaymentThread(ConfigManager.getJobsConfiguration().getEconomyBatchDelay()); + paymentThread.start(); + + ConfigManager.getJobsConfiguration().loadScheduler(); + } + + /** + * Executes clean shutdown + */ + public static void shutdown() { + if (saveTask != null) + saveTask.shutdown(); + + if (paymentThread != null) + paymentThread.shutdown(); + + pManager.saveAll(); + + if (dao != null) { + dao.closeConnections(); + } + } + + /** + * Executes close connections + */ + public static void ChangeDatabase() { + if (dao != null) { + dao.closeConnections(); + } + if (ConfigManager.getJobsConfiguration().storageMethod.equals("mysql")) + ConfigManager.getJobsConfiguration().startSqlite(); + else + ConfigManager.getJobsConfiguration().startMysql(); + pManager.reload(); + } + + /** + * Function to get the number of slots used on the server for this job + * @param job - the job + * @return the number of slots + */ + public static int getUsedSlots(Job job) { + return usedSlots.get(job); + } + + /** + * Function to increase the number of used slots for a job + * @param job - the job someone is taking + */ + public static void takeSlot(Job job) { + usedSlots.put(job, usedSlots.get(job) + 1); + } + + /** + * Function to decrease the number of used slots for a job + * @param job - the job someone is leaving + */ + public static void leaveSlot(Job job) { + usedSlots.put(job, usedSlots.get(job) - 1); + } + + /** + * Returns the jobs classloader + * @return the classloader + */ + public static JobsClassLoader getJobsClassloader() { + return classLoader; + } + + /** + * Sets the permission handler + * @param h - the permission handler + */ + public static void setPermissionHandler(PermissionHandler h) { + permissionHandler = h; + } + + /** + * Gets the permission handler + * @return the permission handler + */ + public static PermissionHandler getPermissionHandler() { + return permissionHandler; + } + + /** + * Sets the economy handler + * @param eco - the economy handler + */ + public static void setEconomy(JobsPlugin plugin, Economy eco) { + economy = new BufferedEconomy(plugin, eco); + } + + /** + * Gets the economy handler + * @return the economy handler + */ + public static BufferedEconomy getEconomy() { + return economy; + } + + public static boolean isUnderLimit(OfflinePlayer player, Double amount) { + + if (player == null) + return false; + + String playername = player.getName(); + + if (!ConfigManager.getJobsConfiguration().EconomyLimitUse) + return true; + + if (!paymentLimit.containsKey(playername)) { + PaymentData data = new PaymentData(System.currentTimeMillis(), amount, 0L, false); + //data.AddNewAmount(amount); + paymentLimit.put(playername, data); + } else { + PaymentData data = paymentLimit.get(playername); + if (data.IsReachedLimit(ConfigManager.getJobsConfiguration().EconomyLimitTimeLimit, ConfigManager.getJobsConfiguration().EconomyLimitMoneyLimit)) { + if (player.isOnline() && !data.Informed) { + ((Player) player).sendMessage(Language.getMessage("command.limit.output.reachedlimit")); + ((Player) player).sendMessage(Language.getMessage("command.limit.output.reachedlimit2")); + data.Setinformed(); + } + if (data.IsAnnounceTime(ConfigManager.getJobsConfiguration().EconomyLimitAnnouncmentDelay) && player.isOnline()) { + String message = Language.getMessage("command.limit.output.lefttime").replace("%hour%", String.valueOf(data.GetLeftHour(ConfigManager.getJobsConfiguration().EconomyLimitTimeLimit))); + message = message.replace("%min%", String.valueOf(data.GetLeftMin(ConfigManager.getJobsConfiguration().EconomyLimitTimeLimit))); + message = message.replace("%sec%", String.valueOf(data.GetLeftsec(ConfigManager.getJobsConfiguration().EconomyLimitTimeLimit))); + ActionBar.send(((Player) player), ChatColor.RED + message); + } + return false; + } else + data.AddAmount(amount); + paymentLimit.put(playername, data); + } + return true; + } + + public static boolean isUnderExpLimit(final OfflinePlayer player, Double amount) { + if (player == null) + return false; + + String playername = player.getName(); + + if (!ConfigManager.getJobsConfiguration().EconomyExpLimitUse) + return true; + + if (!ExpLimit.containsKey(playername)) { + PaymentData data = new PaymentData(); + data.AddNewAmount(amount); + ExpLimit.put(playername, data); + } else { + + final PaymentData data = ExpLimit.get(playername); + if (data.IsReachedLimit(ConfigManager.getJobsConfiguration().EconomyExpTimeLimit, ConfigManager.getJobsConfiguration().EconomyExpLimit)) { + if (player.isOnline() && !data.Informed) { + ((Player) player).sendMessage(Language.getMessage("command.limit.output.reachedExplimit")); + ((Player) player).sendMessage(Language.getMessage("command.limit.output.reachedExplimit2")); + data.Setinformed(); + } + Bukkit.getScheduler().runTaskAsynchronously(JobsPlugin.instance, new Runnable() { + @Override + public void run() { + if (data.IsAnnounceTime(ConfigManager.getJobsConfiguration().EconomyLimitAnnouncmentExpDelay) && player.isOnline()) { + String message = Language.getMessage("command.limit.output.lefttime").replace("%hour%", String.valueOf(data.GetLeftHour(ConfigManager.getJobsConfiguration().EconomyExpTimeLimit))); + message = message.replace("%min%", String.valueOf(data.GetLeftMin(ConfigManager.getJobsConfiguration().EconomyExpTimeLimit))); + message = message.replace("%sec%", String.valueOf(data.GetLeftsec(ConfigManager.getJobsConfiguration().EconomyExpTimeLimit))); + ActionBar.send(((Player) player), ChatColor.RED + message); + } + } + }); + return false; + } else + data.AddAmount(amount); + ExpLimit.put(playername, data); + } + return true; + } + + /** + * Performed an action + * + * Give correct experience and income + * @param jPlayer - the player + * @param action - the action + * @param multiplier - the payment/xp multiplier + */ + @SuppressWarnings("deprecation") + public static void action(JobsPlayer jPlayer, ActionInfo info, double multiplier, ItemStack item, ItemStack[] armor) { + + if (jPlayer == null) + return; + + List progression = jPlayer.getJobProgression(); + int numjobs = progression.size(); + // no job + + if (numjobs == 0) { + Job jobNone = Jobs.getNoneJob(); + Player dude = Bukkit.getServer().getPlayer(jPlayer.getPlayerUUID()); + + if (jobNone != null) { + Double income = jobNone.getIncome(info, 1, numjobs); + if (income != null) { + + + Double amount = income + ((income * multiplier) - income) + ((income * 1.0) - income) + ((income * Jobs.getNoneJob().getMoneyBoost()) - income); + + if (ConfigManager.getJobsConfiguration().useDynamicPayment) { + double moneyBonus = (income * (jobNone.getBonus() / 100)); + amount += moneyBonus; + } + + if (!isUnderLimit(dude, amount)) + return; + + Jobs.getEconomy().pay(jPlayer, amount, 0.0); + + } + } + } else { + + for (JobProgression prog : progression) { + + int level = prog.getLevel(); + Double income = prog.getJob().getIncome(info, level, numjobs); + + if (income != null) { + Double exp = prog.getJob().getExperience(info, level, numjobs); + + if (ConfigManager.getJobsConfiguration().addXpPlayer()) { + Player player = Bukkit.getServer().getPlayer(jPlayer.getPlayerUUID()); + if (player != null) { + /* + * Minecraft experience is calculated in whole numbers only. + * Calculate the fraction of an experience point and perform a dice roll. + * That way jobs that give fractions of experience points will slowly give + * experience in the aggregate + */ + int expInt = exp.intValue(); + double remainder = exp.doubleValue() - expInt; + if (Math.abs(remainder) > Math.random()) { + if (exp.doubleValue() < 0) { + expInt--; + } else { + expInt++; + } + } + player.giveExp(expInt); + } + } + + // Item boost check + Double itemMoneyBoost = 0.0; + Double itemExpBoost = 0.0; + if (item != null) + if (item.hasItemMeta()) { + ItemMeta meta = item.getItemMeta(); + if (meta.hasDisplayName() && meta.hasLore()) + for (JobItems oneItem : prog.getJob().getItems()) { + if (oneItem.getId() != item.getTypeId()) + continue; + if (!ChatColor.translateAlternateColorCodes('&', oneItem.getName()).equalsIgnoreCase(meta.getDisplayName())) + continue; + if (!oneItem.getLore().equals(meta.getLore())) + continue; + itemMoneyBoost = ((income * oneItem.getMoneyBoost()) - income); + itemExpBoost = ((exp * oneItem.getExpBoost()) - exp); + break; + } + } + + // Armor boost check + Double armorMoneyBoost = 0.0; + Double armorExpBoost = 0.0; + if (armor != null) + for (ItemStack OneArmor : armor) { + if (OneArmor == null) + continue; + if (!OneArmor.hasItemMeta()) + continue; + ItemMeta meta = OneArmor.getItemMeta(); + if (!meta.hasDisplayName() || !meta.hasLore()) + continue; + for (JobItems oneItem : prog.getJob().getItems()) { + if (oneItem.getId() != OneArmor.getTypeId()) + continue; + if (!ChatColor.translateAlternateColorCodes('&', oneItem.getName()).equalsIgnoreCase(meta.getDisplayName())) + continue; + if (!oneItem.getLore().equals(meta.getLore())) + continue; + armorMoneyBoost += ((income * oneItem.getMoneyBoost()) - income); + armorExpBoost += ((exp * oneItem.getExpBoost()) - exp); + break; + + } + + } + + OfflinePlayer dude = jPlayer.getPlayer(); + + // Calculate income + Double amount = income + ((income * multiplier) - income) + ((income * prog.getJob().getMoneyBoost()) - income) + ((income * prog.getMoneyBoost()) - income) + itemMoneyBoost + armorMoneyBoost; + + if (ConfigManager.getJobsConfiguration().useDynamicPayment) { + double moneyBonus = (income * (prog.getJob().getBonus() / 100)); + amount += moneyBonus; + } + + // Calculate exp + double expAmount = exp + ((exp * multiplier) - exp) + ((exp * prog.getJob().getExpBoost()) - exp) + ((exp * prog.getExpBoost()) - exp) + itemExpBoost + armorExpBoost; + + if (ConfigManager.getJobsConfiguration().useDynamicPayment) { + double expBonus = (exp * (prog.getJob().getBonus() / 100)); + expAmount += expBonus; + } + + if (!isUnderLimit(dude, amount)) { + amount = 0.0000000001; + if (ConfigManager.getJobsConfiguration().EconomyExpStop) + expAmount = 0.0; + } + + if (!isUnderExpLimit(dude, expAmount)) { + expAmount = 0.0; + if (ConfigManager.getJobsConfiguration().EconomyMoneyStop) + expAmount = 0.0000000001; + } + + if (amount == 0.0000000001 && expAmount == 0.0) + continue; + + Jobs.getEconomy().pay(jPlayer, amount, expAmount); + int oldLevel = prog.getLevel(); + + if (prog.addExperience(expAmount)) + Jobs.getPlayerManager().performLevelUp(jPlayer, prog.getJob(), oldLevel); + + } + } + } + } +} diff --git a/com/gamingmesh/jobs/JobsPlugin.java b/com/gamingmesh/jobs/JobsPlugin.java new file mode 100644 index 00000000..f29b9b38 --- /dev/null +++ b/com/gamingmesh/jobs/JobsPlugin.java @@ -0,0 +1,116 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.gamingmesh.jobs; + +import java.io.IOException; + +import net.coreprotect.CoreProtect; +import net.coreprotect.CoreProtectAPI; + +import org.bukkit.Bukkit; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.ChatColor; + +import com.gamingmesh.jobs.commands.JobsCommands; +import com.gamingmesh.jobs.config.ConfigManager; +import com.gamingmesh.jobs.config.JobConfig; +import com.gamingmesh.jobs.config.JobsConfiguration; +import com.gamingmesh.jobs.listeners.JobsListener; +import com.gamingmesh.jobs.listeners.JobsPaymentListener; +import com.gamingmesh.jobs.listeners.McMMOlistener; +import com.gamingmesh.jobs.listeners.PistonProtectionListener; +import com.gamingmesh.jobs.stuff.ScheduleUtil; +import com.gamingmesh.jobs.stuff.TabComplete; +import com.gamingmesh.jobs.config.YmlMaker; + +public class JobsPlugin extends JavaPlugin { + public static Plugin instance; + public static CoreProtectAPI CPAPI; + public static boolean CPPresent = false; + + @Override + public void onEnable() { + instance = this; + YmlMaker jobConfig = new YmlMaker(this, "jobConfig.yml"); + jobConfig.saveDefaultConfig(); + + YmlMaker jobSigns = new YmlMaker(this, "Signs.yml"); + jobSigns.saveDefaultConfig(); + + YmlMaker jobSchedule = new YmlMaker(this, "schedule.yml"); + jobSchedule.saveDefaultConfig(); + + Jobs.setPermissionHandler(new PermissionHandler(this)); + + Jobs.setPluginLogger(getLogger()); + + Jobs.setDataFolder(getDataFolder()); + + ConfigManager.registerJobsConfiguration(new JobsConfiguration(this)); + ConfigManager.registerJobConfig(new JobConfig(this)); + + getCommand("jobs").setExecutor(new JobsCommands()); + + this.getCommand("jobs").setTabCompleter(new TabComplete()); + + try { + Jobs.startup(); + } catch (IOException e) { + e.printStackTrace(); + } + + // register the listeners + getServer().getPluginManager().registerEvents(new JobsListener(this), this); + getServer().getPluginManager().registerEvents(new JobsPaymentListener(this), this); + + if (McMMOlistener.CheckmcMMO()) + getServer().getPluginManager().registerEvents(new McMMOlistener(this), this); + + if (ConfigManager.getJobsConfiguration().useBlockProtection) + getServer().getPluginManager().registerEvents(new PistonProtectionListener(this), this); + + // register economy + Bukkit.getScheduler().runTask(this, new HookEconomyTask(this)); + + if (getServer().getPluginManager().getPlugin("CoreProtect") != null) { + CPPresent = true; + CPAPI = ((CoreProtect) getServer().getPluginManager().getPlugin("CoreProtect")).getAPI(); + } + + // all loaded properly. + + + if (ConfigManager.getJobsConfiguration().useGlobalBoostScheduler) + ScheduleUtil.scheduler(); + + String message = ChatColor.translateAlternateColorCodes('&', "&2Plugin has been enabled succesfully."); + ConsoleCommandSender console = Bukkit.getServer().getConsoleSender(); + console.sendMessage(message); + } + + @Override + public void onDisable() { + Jobs.shutdown(); + String message = ChatColor.translateAlternateColorCodes('&', "&2Plugin has been disabled succesfully."); + ConsoleCommandSender console = Bukkit.getServer().getConsoleSender(); + console.sendMessage(message); + } +} diff --git a/com/gamingmesh/jobs/PermissionHandler.java b/com/gamingmesh/jobs/PermissionHandler.java new file mode 100644 index 00000000..934b03e0 --- /dev/null +++ b/com/gamingmesh/jobs/PermissionHandler.java @@ -0,0 +1,158 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.gamingmesh.jobs; + +import java.util.HashMap; +import java.util.List; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.permissions.PermissionAttachmentInfo; +import org.bukkit.permissions.PermissionDefault; +import org.bukkit.plugin.PluginManager; + +import com.gamingmesh.jobs.container.Job; +import com.gamingmesh.jobs.container.JobPermission; +import com.gamingmesh.jobs.container.JobProgression; +import com.gamingmesh.jobs.container.JobsPlayer; + +public class PermissionHandler { + private JobsPlugin plugin; + + public PermissionHandler(JobsPlugin plugin) { + this.plugin = plugin; + } + + public void recalculatePermissions(JobsPlayer jPlayer) { + + if (jPlayer == null) + return; + Player player = (Player) jPlayer.getPlayer(); + + if (player == null) + return; + + boolean changed = false; + + // remove old permissions + String permName = "jobs.players." + player.getName(); + Permission permission = plugin.getServer().getPluginManager().getPermission(permName); + if (permission != null) { + plugin.getServer().getPluginManager().removePermission(permission); + changed = true; + } + + // Permissions should only apply if we have permission to use jobs in this world + if (hasWorldPermission(player, player.getWorld().getName())) { + List progression = jPlayer.getJobProgression(); + // calculate new permissions + HashMap permissions = new HashMap(); + if (progression.size() == 0) { + Job job = Jobs.getNoneJob(); + if (job != null) { + for (JobPermission perm : job.getPermissions()) { + if (perm.getLevelRequirement() <= 0) { + if (perm.getValue()) { + permissions.put(perm.getNode(), true); + } else { + /* + * If the key exists, don't put a false node in + * This is in case we already have a true node there + */ + if (!permissions.containsKey(perm.getNode())) { + permissions.put(perm.getNode(), false); + } + } + } + } + } + } else { + for (JobProgression prog : progression) { + for (JobPermission perm : prog.getJob().getPermissions()) { + if (prog.getLevel() >= perm.getLevelRequirement()) { + /* + * If the key exists, don't put a false node in + * This is in case we already have a true node there + */ + if (perm.getValue()) { + permissions.put(perm.getNode(), true); + } else { + if (!permissions.containsKey(perm.getNode())) { + permissions.put(perm.getNode(), false); + } + } + } + } + } + } + + // add new permissions (if applicable) + if (permissions.size() > 0) { + plugin.getServer().getPluginManager().addPermission(new Permission(permName, PermissionDefault.FALSE, permissions)); + changed = true; + } + } + + // If the permissions changed, recalculate them + if (!changed) + return; + + // find old attachment + PermissionAttachment attachment = null; + for (PermissionAttachmentInfo pai : player.getEffectivePermissions()) { + if (pai.getAttachment() != null && pai.getAttachment().getPlugin() instanceof JobsPlugin) { + attachment = pai.getAttachment(); + } + } + + // create if attachment doesn't exist + if (attachment == null) { + attachment = player.addAttachment(plugin); + attachment.setPermission(permName, true); + } + + // recalculate! + player.recalculatePermissions(); + } + + public void registerPermissions() { + PluginManager pm = plugin.getServer().getPluginManager(); + for (World world : plugin.getServer().getWorlds()) { + if (pm.getPermission("jobs.world." + world.getName().toLowerCase()) == null) + pm.addPermission(new Permission("jobs.world." + world.getName().toLowerCase(), PermissionDefault.TRUE)); + } + for (Job job : Jobs.getJobs()) { + if (pm.getPermission("jobs.join." + job.getName().toLowerCase()) == null) + pm.addPermission(new Permission("jobs.join." + job.getName().toLowerCase(), PermissionDefault.TRUE)); + } + } + + /** + * Check World permissions + */ + public boolean hasWorldPermission(Player player, String world) { + if (!player.hasPermission("jobs.use")) { + return false; + } else { + return player.hasPermission("jobs.world." + world.toLowerCase()); + } + } + +} diff --git a/com/gamingmesh/jobs/PlayerManager.java b/com/gamingmesh/jobs/PlayerManager.java new file mode 100644 index 00000000..2e053d4b --- /dev/null +++ b/com/gamingmesh/jobs/PlayerManager.java @@ -0,0 +1,524 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.gamingmesh.jobs; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionDefault; + +import com.gamingmesh.jobs.api.JobsJoinEvent; +import com.gamingmesh.jobs.api.JobsLeaveEvent; +import com.gamingmesh.jobs.api.JobsLevelUpEvent; +import com.gamingmesh.jobs.config.ConfigManager; +import com.gamingmesh.jobs.container.Job; +import com.gamingmesh.jobs.container.JobCommands; +import com.gamingmesh.jobs.container.JobProgression; +import com.gamingmesh.jobs.container.JobsPlayer; +import com.gamingmesh.jobs.dao.JobsDAO; +import com.gamingmesh.jobs.i18n.Language; +import com.gamingmesh.jobs.stuff.ActionBar; +import com.gamingmesh.jobs.stuff.ChatColor; +import com.gamingmesh.jobs.stuff.PerformCommands; + +public class PlayerManager { + // private Map players = Collections.synchronizedMap(new HashMap()); + private Map players = new HashMap(); + + /** + * Handles join of new player + * @param playername + */ + public void playerJoin(final Player player) { + //synchronized (players) { + Thread threadd = new Thread() { + public void run() { + JobsPlayer jPlayer = players.get(player.getName().toLowerCase()); + if (jPlayer == null) { + jPlayer = JobsPlayer.loadFromDao(Jobs.getJobsDAO(), player); + players.put(player.getName().toLowerCase(), jPlayer); + } + jPlayer.onConnect(); + jPlayer.reloadHonorific(); + Jobs.getPermissionHandler().recalculatePermissions(jPlayer); + return; + } + }; + threadd.start(); + threadd.interrupt(); + //} + } + + /** + * Handles player quit + * @param playername + */ + public void playerQuit(Player player) { + //synchronized (players) { + if (ConfigManager.getJobsConfiguration().saveOnDisconnect()) { + JobsPlayer jPlayer = players.remove(player.getName().toLowerCase()); + if (jPlayer != null) { + jPlayer.save(Jobs.getJobsDAO()); + jPlayer.onDisconnect(); + } + } else { + JobsPlayer jPlayer = players.get(player.getName().toLowerCase()); + if (jPlayer != null) { + jPlayer.onDisconnect(); + } + } + //} + } + + /** + * Save all the information of all of the players in the game + */ + public void saveAll() { + JobsDAO dao = Jobs.getJobsDAO(); + + /* + * Saving is a three step process to minimize synchronization locks when called asynchronously. + * + * 1) Safely copy list for saving. + * 2) Perform save on all players on copied list. + * 3) Garbage collect the real list to remove any offline players with saved data + */ + ArrayList list = null; + synchronized (players) { + list = new ArrayList(players.values()); + } + + for (JobsPlayer jPlayer : list) { + jPlayer.save(dao); + } + + synchronized (players) { + Iterator iter = players.values().iterator(); + while (iter.hasNext()) { + JobsPlayer jPlayer = iter.next(); + synchronized (jPlayer.saveLock) { + if (!jPlayer.isOnline() && jPlayer.isSaved()) { + iter.remove(); + } + } + } + } + } + + /** + * Get the player job info for specific player + * @param player - the player who's job you're getting + * @return the player job info of the player + */ + public JobsPlayer getJobsPlayer(Player player) { + return players.get(player.getName().toLowerCase()); + } + + /** + * Get the player job info for specific player + * @param player name - the player name who's job you're getting + * @return the player job info of the player + */ + public JobsPlayer getJobsPlayer(String playerName) { + return players.get(playerName.toLowerCase()); + } + + /** + * Get the player job info for specific player + * @param player - the player who's job you're getting + * @return the player job info of the player + */ + public JobsPlayer getJobsPlayerOffline(OfflinePlayer offlinePlayer) { + JobsPlayer jPlayer = players.get(offlinePlayer.getName().toLowerCase()); + if (jPlayer != null) + return jPlayer; + + return JobsPlayer.loadFromDao(Jobs.getJobsDAO(), offlinePlayer); + } + + /** + * Causes player to join their job + * @param jPlayer + * @param job + */ + public void joinJob(JobsPlayer jPlayer, Job job) { + synchronized (jPlayer.saveLock) { + if (jPlayer.isInJob(job)) + return; + // let the user join the job + if (!jPlayer.joinJob(job, jPlayer)) + return; + + // JobsJoin event + JobsJoinEvent jobsjoinevent = new JobsJoinEvent(jPlayer, job); + Bukkit.getServer().getPluginManager().callEvent(jobsjoinevent); + // If event is canceled, dont do anything + if (jobsjoinevent.isCancelled()) + return; + + Jobs.getJobsDAO().joinJob(jPlayer, job); + PerformCommands.PerformCommandsOnJoin(jPlayer, job); + Jobs.takeSlot(job); + Signs.SignUtil.SignUpdate(job.getName()); + Signs.SignUtil.SignUpdate("gtoplist"); + job.updateTotalPlayers(); + } + } + + /** + * Causes player to leave their job + * @param jPlayer + * @param job + */ + public void leaveJob(JobsPlayer jPlayer, Job job) { + synchronized (jPlayer.saveLock) { + if (!jPlayer.isInJob(job)) + return; + Jobs.getJobsDAO().recordToArchive(jPlayer, job); + // let the user leave the job + if (!jPlayer.leaveJob(job)) + return; + + // JobsJoin event + JobsLeaveEvent jobsleaveevent = new JobsLeaveEvent(jPlayer, job); + Bukkit.getServer().getPluginManager().callEvent(jobsleaveevent); + // If event is canceled, dont do anything + if (jobsleaveevent.isCancelled()) + return; + + Jobs.getJobsDAO().quitJob(jPlayer, job); + PerformCommands.PerformCommandsOnLeave(jPlayer, job); + Jobs.leaveSlot(job); + + Signs.SignUtil.SignUpdate(job.getName()); + Signs.SignUtil.SignUpdate("gtoplist"); + job.updateTotalPlayers(); + } + } + + /** + * Causes player to leave all their jobs + * @param jPlayer + */ + public void leaveAllJobs(JobsPlayer jPlayer) { + synchronized (jPlayer.saveLock) { + for (JobProgression job : jPlayer.getJobProgression()) { + Jobs.getJobsDAO().quitJob(jPlayer, job.getJob()); + PerformCommands.PerformCommandsOnLeave(jPlayer, job.getJob()); + Jobs.leaveSlot(job.getJob()); + + Signs.SignUtil.SignUpdate(job.getJob().getName()); + Signs.SignUtil.SignUpdate("gtoplist"); + job.getJob().updateTotalPlayers(); + } + + jPlayer.leaveAllJobs(); + } + } + + /** + * Transfers player job + * @param jPlayer + * @param oldjob - the old job + * @param newjob - the new job + */ + public void transferJob(JobsPlayer jPlayer, Job oldjob, Job newjob) { + synchronized (jPlayer.saveLock) { + if (!jPlayer.transferJob(oldjob, newjob, jPlayer)) + return; + + JobsDAO dao = Jobs.getJobsDAO(); + dao.quitJob(jPlayer, oldjob); + oldjob.updateTotalPlayers(); + dao.joinJob(jPlayer, newjob); + newjob.updateTotalPlayers(); + jPlayer.save(dao); + } + } + + /** + * Promotes player in their job + * @param jPlayer + * @param job - the job + * @param levels - number of levels to promote + */ + public void promoteJob(JobsPlayer jPlayer, Job job, int levels) { + synchronized (jPlayer.saveLock) { + jPlayer.promoteJob(job, levels, jPlayer); + jPlayer.save(Jobs.getJobsDAO()); + + Signs.SignUtil.SignUpdate(job.getName()); + Signs.SignUtil.SignUpdate("gtoplist"); + } + } + + /** + * Demote player in their job + * @param jPlayer + * @param job - the job + * @param levels - number of levels to demote + */ + public void demoteJob(JobsPlayer jPlayer, Job job, int levels) { + synchronized (jPlayer.saveLock) { + jPlayer.demoteJob(job, levels); + jPlayer.save(Jobs.getJobsDAO()); + Signs.SignUtil.SignUpdate(job.getName()); + Signs.SignUtil.SignUpdate("gtoplist"); + } + } + + /** + * Adds experience to the player + * @param jPlayer + * @param job - the job + * @param experience - experience gained + */ + public void addExperience(JobsPlayer jPlayer, Job job, double experience) { + synchronized (jPlayer.saveLock) { + JobProgression prog = jPlayer.getJobProgression(job); + if (prog == null) + return; + int oldLevel = prog.getLevel(); + if (prog.addExperience(experience)) + performLevelUp(jPlayer, job, oldLevel); + + jPlayer.save(Jobs.getJobsDAO()); + Signs.SignUtil.SignUpdate(job.getName()); + Signs.SignUtil.SignUpdate("gtoplist"); + } + } + + /** + * Removes experience to the player + * @param jPlayer + * @param job - the job + * @param experience - experience gained + */ + public void removeExperience(JobsPlayer jPlayer, Job job, double experience) { + synchronized (jPlayer.saveLock) { + JobProgression prog = jPlayer.getJobProgression(job); + if (prog == null) + return; + prog.addExperience(-experience); + + jPlayer.save(Jobs.getJobsDAO()); + Signs.SignUtil.SignUpdate(job.getName()); + Signs.SignUtil.SignUpdate("gtoplist"); + } + } + + /** + * Broadcasts level up about a player + * @param jPlayer + * @param job + * @param oldLevel + */ + public void performLevelUp(JobsPlayer jPlayer, Job job, int oldLevel) { + + Player player = (Player) jPlayer.getPlayer(); + JobProgression prog = jPlayer.getJobProgression(job); + if (prog == null) + return; + + // LevelUp event + JobsLevelUpEvent levelUpEvent = new JobsLevelUpEvent(jPlayer, job.getName(), prog.getLevel(), ConfigManager.getJobsConfiguration().getTitleForLevel(oldLevel, job.getName()), ConfigManager.getJobsConfiguration().getTitleForLevel(prog.getLevel(), job.getName()), ConfigManager.getJobsConfiguration().SoundLevelupSound.toUpperCase(), ConfigManager.getJobsConfiguration().SoundLevelupVolume, ConfigManager.getJobsConfiguration().SoundLevelupPitch, ConfigManager.getJobsConfiguration().SoundTitleChangeSound.toUpperCase(), ConfigManager.getJobsConfiguration().SoundTitleChangeVolume, ConfigManager.getJobsConfiguration().SoundTitleChangePitch); + Bukkit.getServer().getPluginManager().callEvent(levelUpEvent); + // If event is canceled, dont do anything + if (levelUpEvent.isCancelled()) + return; + + if (ConfigManager.getJobsConfiguration().SoundLevelupUse) + player.getWorld().playSound(player.getLocation(), Sound.valueOf(levelUpEvent.getSoundName()), levelUpEvent.getSoundVolume(), levelUpEvent.getSoundPitch()); + + String message; + if (ConfigManager.getJobsConfiguration().isBroadcastingLevelups()) { + message = Language.getMessage("message.levelup.broadcast"); + } else { + message = Language.getMessage("message.levelup.nobroadcast"); + } + + message = message.replace("%jobname%", job.getChatColor() + job.getName() + ChatColor.WHITE); + + if (levelUpEvent.getOldTitle() != null) { + message = message.replace("%titlename%", levelUpEvent.getOldTitleColor() + levelUpEvent.getOldTitleName() + ChatColor.WHITE); + } + if (player != null) { + message = message.replace("%playername%", player.getDisplayName()); + } else { + message = message.replace("%playername%", jPlayer.getUserName()); + } + message = message.replace("%joblevel%", "" + prog.getLevel()); + for (String line : message.split("\n")) { + if (ConfigManager.getJobsConfiguration().isBroadcastingLevelups()) { + if (ConfigManager.getJobsConfiguration().BroadcastingLevelUpLevels.contains(oldLevel + 1) || ConfigManager.getJobsConfiguration().BroadcastingLevelUpLevels.contains(0)) + Bukkit.getServer().broadcastMessage(line); + } else if (player != null) { + if (ConfigManager.getJobsConfiguration().LevelChangeActionBar) + ActionBar.send(player, line); + if (ConfigManager.getJobsConfiguration().LevelChangeChat) + player.sendMessage(line); + } + } + + if (levelUpEvent.getNewTitle() != null && !levelUpEvent.getNewTitle().equals(levelUpEvent.getOldTitle())) { + + if (ConfigManager.getJobsConfiguration().SoundTitleChangeUse) + player.getWorld().playSound(player.getLocation(), Sound.valueOf(levelUpEvent.getTitleChangeSoundName()), levelUpEvent.getTitleChangeVolume(), levelUpEvent.getTitleChangePitch()); + + // user would skill up + if (ConfigManager.getJobsConfiguration().isBroadcastingSkillups()) { + message = Language.getMessage("message.skillup.broadcast"); + } else { + message = Language.getMessage("message.skillup.nobroadcast"); + } + if (player != null) { + message = message.replace("%playername%", player.getDisplayName()); + } else { + message = message.replace("%playername%", jPlayer.getUserName()); + } + message = message.replace("%titlename%", levelUpEvent.getNewTitleColor() + levelUpEvent.getNewTitleName() + ChatColor.WHITE); + message = message.replace("%jobname%", job.getChatColor() + job.getName() + ChatColor.WHITE); + for (String line : message.split("\n")) { + if (ConfigManager.getJobsConfiguration().isBroadcastingLevelups()) { + Bukkit.getServer().broadcastMessage(line); + } else if (player != null) { + if (ConfigManager.getJobsConfiguration().TitleChangeActionBar) + ActionBar.send(player, line); + if (ConfigManager.getJobsConfiguration().TitleChangeChat) + player.sendMessage(line); + } + } + } + jPlayer.reloadHonorific(); + Jobs.getPermissionHandler().recalculatePermissions(jPlayer); + performCommandOnLevelUp(jPlayer, prog.getJob(), oldLevel); + Signs.SignUtil.SignUpdate(job.getName()); + Signs.SignUtil.SignUpdate("gtoplist"); + } + + /** + * Performs command on level up + * @param jPlayer + * @param job + * @param oldLevel + */ + public void performCommandOnLevelUp(JobsPlayer jPlayer, Job job, int oldLevel) { + int newLevel = oldLevel + 1; + Player player = Bukkit.getServer().getPlayer(jPlayer.getPlayerUUID()); + JobProgression prog = jPlayer.getJobProgression(job); + if (prog == null) + return; + for (JobCommands command : job.getCommands()) { + if (newLevel >= command.getLevelFrom() && newLevel <= command.getLevelUntil()) { + String commandString = command.getCommand(); + commandString = commandString.replace("[player]", player.getName()); + commandString = commandString.replace("[oldlevel]", String.valueOf(oldLevel)); + commandString = commandString.replace("[newlevel]", String.valueOf(newLevel)); + commandString = commandString.replace("[jobname]", job.getName()); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), commandString); + } + } + } + + /** + * Get job exp boost + * @param player + * @param job + * @return double of boost + */ + public Double GetExpBoost(Player dude, Job job) { + Double ExpBoost = 1.0; + if (dude == null || job.getName() == null) + return 1.0; + if (Perm(dude, "jobs.boost." + job.getName() + ".exp") || Perm(dude, "jobs.boost." + job.getName() + ".both") || Perm(dude, "jobs.boost.all.both") || Perm(dude, "jobs.boost.all.exp")) { + ExpBoost = ConfigManager.getJobsConfiguration().BoostExp; + } + + return ExpBoost; + } + + /** + * Get max jobs + * @param player + * @return True if he have permission + */ + public boolean getJobsLimit(Player player, Short currentCount) { + + if (Perm(player, "jobs.max.*")) + return true; + + short count = (short) ConfigManager.getJobsConfiguration().getMaxJobs(); + for (short ctr = 0; ctr < 255; ctr++) { + if (Perm(player, "jobs.max." + ctr)) + count = ctr; + if (count > currentCount) + return true; + } + return false; + } + + private boolean Perm(Player player, String permission) { + Permission p = new Permission(permission, PermissionDefault.FALSE); + return player.hasPermission(p); + } + + /** + * Get job money boost + * @param player + * @param job + * @return double of boost + */ + public Double GetMoneyBoost(Player dude, Job job) { + Double MoneyBoost = 1.0; + if (dude != null && job.getName() != null) { + if (Perm(dude, "jobs.boost." + job.getName() + ".money") || Perm(dude, "jobs.boost." + job.getName() + ".both") || Perm(dude, "jobs.boost.all.both") || Perm(dude, "jobs.boost.all.money")) { + MoneyBoost = ConfigManager.getJobsConfiguration().BoostMoney; + } + } + return MoneyBoost; + } + + /** + * Perform reload + */ + public void reload() { + synchronized (players) { + for (JobsPlayer jPlayer : players.values()) { + for (JobProgression progression : jPlayer.getJobProgression()) { + String jobName = progression.getJob().getName(); + Job job = Jobs.getJob(jobName); + if (job != null) { + progression.setJob(job); + } + } + if (jPlayer.isOnline()) { + jPlayer.reloadHonorific(); + Jobs.getPermissionHandler().recalculatePermissions(jPlayer); + } + } + } + } +} diff --git a/com/gamingmesh/jobs/actions/.gitignore b/com/gamingmesh/jobs/actions/.gitignore new file mode 100644 index 00000000..b89cf7e3 --- /dev/null +++ b/com/gamingmesh/jobs/actions/.gitignore @@ -0,0 +1,6 @@ +/BlockActionInfo.class +/EntityActionInfo.class +/ItemActionInfo.class +/MaterialActionInfo.class +/EnchantActionInfo.class +/CustomKillInfo.class diff --git a/com/gamingmesh/jobs/actions/BlockActionInfo.java b/com/gamingmesh/jobs/actions/BlockActionInfo.java new file mode 100644 index 00000000..268393a0 --- /dev/null +++ b/com/gamingmesh/jobs/actions/BlockActionInfo.java @@ -0,0 +1,31 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.gamingmesh.jobs.actions; + +import org.bukkit.block.Block; + +import com.gamingmesh.jobs.container.ActionInfo; +import com.gamingmesh.jobs.container.ActionType; + +public class BlockActionInfo extends MaterialActionInfo implements ActionInfo { + @SuppressWarnings("deprecation") + public BlockActionInfo(Block block, ActionType type) { + super(block.getType(), block.getData(), type); + } +} diff --git a/com/gamingmesh/jobs/actions/CustomKillInfo.java b/com/gamingmesh/jobs/actions/CustomKillInfo.java new file mode 100644 index 00000000..68bf76dd --- /dev/null +++ b/com/gamingmesh/jobs/actions/CustomKillInfo.java @@ -0,0 +1,42 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.gamingmesh.jobs.actions; + +import com.gamingmesh.jobs.container.ActionInfo; +import com.gamingmesh.jobs.container.ActionType; +import com.gamingmesh.jobs.container.BaseActionInfo; + +public class CustomKillInfo extends BaseActionInfo implements ActionInfo { + private String name; + + public CustomKillInfo(String name, ActionType type) { + super(type); + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getNameWithSub() { + return name; + } +} diff --git a/com/gamingmesh/jobs/actions/EnchantActionInfo.java b/com/gamingmesh/jobs/actions/EnchantActionInfo.java new file mode 100644 index 00000000..23346bee --- /dev/null +++ b/com/gamingmesh/jobs/actions/EnchantActionInfo.java @@ -0,0 +1,44 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.gamingmesh.jobs.actions; + +import com.gamingmesh.jobs.container.ActionInfo; +import com.gamingmesh.jobs.container.ActionType; +import com.gamingmesh.jobs.container.BaseActionInfo; + +public class EnchantActionInfo extends BaseActionInfo implements ActionInfo { + private String name; + private int level; + + public EnchantActionInfo(String name, int level, ActionType type) { + super(type); + this.name = name; + this.level = level; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getNameWithSub() { + return name + ":" + level; + } +} diff --git a/com/gamingmesh/jobs/actions/EntityActionInfo.java b/com/gamingmesh/jobs/actions/EntityActionInfo.java new file mode 100644 index 00000000..b16430f4 --- /dev/null +++ b/com/gamingmesh/jobs/actions/EntityActionInfo.java @@ -0,0 +1,67 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.gamingmesh.jobs.actions; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Guardian; +import org.bukkit.entity.Skeleton; +import org.bukkit.entity.Skeleton.SkeletonType; +import org.bukkit.entity.Zombie; + +import com.gamingmesh.jobs.container.ActionInfo; +import com.gamingmesh.jobs.container.ActionType; +import com.gamingmesh.jobs.container.BaseActionInfo; + +public class EntityActionInfo extends BaseActionInfo implements ActionInfo { + private Entity entity; + + public EntityActionInfo(Entity entity, ActionType type) { + super(type); + this.entity = entity; + } + + @Override + public String getName() { + if (this.entity instanceof Skeleton) { + Skeleton skeleton = (Skeleton) this.entity; + if (skeleton.getSkeletonType() == SkeletonType.WITHER) + return "WitherSkeleton"; + } + + if (this.entity instanceof Zombie) { + Zombie zombie = (Zombie) this.entity; + if (zombie.isVillager()) + return "ZombieVillager"; + } + + if (this.entity.getType().toString().toLowerCase().contains("guardian")) + if (this.entity instanceof Guardian) { + Guardian guardian = (Guardian) this.entity; + if (guardian.isElder()) + return "ElderGuardian"; + } + + return entity.getType().toString(); + } + + @Override + public String getNameWithSub() { + return getName(); + } +} diff --git a/com/gamingmesh/jobs/actions/ItemActionInfo.java b/com/gamingmesh/jobs/actions/ItemActionInfo.java new file mode 100644 index 00000000..1753ecfd --- /dev/null +++ b/com/gamingmesh/jobs/actions/ItemActionInfo.java @@ -0,0 +1,31 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.gamingmesh.jobs.actions; + +import org.bukkit.inventory.ItemStack; + +import com.gamingmesh.jobs.container.ActionInfo; +import com.gamingmesh.jobs.container.ActionType; + +public class ItemActionInfo extends MaterialActionInfo implements ActionInfo { + @SuppressWarnings("deprecation") + public ItemActionInfo(ItemStack items, ActionType type) { + super(items.getType(), items.getData().getData(), type); + } +} diff --git a/com/gamingmesh/jobs/actions/MaterialActionInfo.java b/com/gamingmesh/jobs/actions/MaterialActionInfo.java new file mode 100644 index 00000000..a688a206 --- /dev/null +++ b/com/gamingmesh/jobs/actions/MaterialActionInfo.java @@ -0,0 +1,46 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.gamingmesh.jobs.actions; + +import org.bukkit.Material; + +import com.gamingmesh.jobs.container.ActionInfo; +import com.gamingmesh.jobs.container.ActionType; +import com.gamingmesh.jobs.container.BaseActionInfo; + +public abstract class MaterialActionInfo extends BaseActionInfo implements ActionInfo { + private Material material; + private byte data; + public MaterialActionInfo(Material material, byte data, ActionType type) { + super(type); + this.material = material; + this.data = data; + } + + @Override + public String getName() { + return material.toString(); + } + + @Override + public String getNameWithSub() { + return getName()+":"+data; + } + +} diff --git a/com/gamingmesh/jobs/api/.gitignore b/com/gamingmesh/jobs/api/.gitignore new file mode 100644 index 00000000..fc96c543 --- /dev/null +++ b/com/gamingmesh/jobs/api/.gitignore @@ -0,0 +1,8 @@ +/JobsLevelUp.class +/JobsJoin.class +/JobsLeave.class +/JobsPayment.class +/JobsJoinEvent.class +/JobsLeaveEvent.class +/JobsLevelUpEvent.class +/JobsPaymentEvent.class diff --git a/com/gamingmesh/jobs/api/JobsJoinEvent.java b/com/gamingmesh/jobs/api/JobsJoinEvent.java new file mode 100644 index 00000000..5acc1968 --- /dev/null +++ b/com/gamingmesh/jobs/api/JobsJoinEvent.java @@ -0,0 +1,44 @@ +package com.gamingmesh.jobs.api; + +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import com.gamingmesh.jobs.container.Job; +import com.gamingmesh.jobs.container.JobsPlayer; + +public final class JobsJoinEvent extends Event implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private JobsPlayer player; + private Job job; + private boolean cancelled; + + public JobsJoinEvent(JobsPlayer jPlayer, Job job) { + this.player = jPlayer; + this.job = job; + } + + public JobsPlayer getPlayer() { + return this.player; + } + + public Job getJob() { + return this.job; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + cancelled = cancel; + } + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} \ No newline at end of file diff --git a/com/gamingmesh/jobs/api/JobsLeaveEvent.java b/com/gamingmesh/jobs/api/JobsLeaveEvent.java new file mode 100644 index 00000000..7ed09fbc --- /dev/null +++ b/com/gamingmesh/jobs/api/JobsLeaveEvent.java @@ -0,0 +1,44 @@ +package com.gamingmesh.jobs.api; + +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import com.gamingmesh.jobs.container.Job; +import com.gamingmesh.jobs.container.JobsPlayer; + +public final class JobsLeaveEvent extends Event implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private JobsPlayer player; + private Job job; + private boolean cancelled; + + public JobsLeaveEvent(JobsPlayer jPlayer, Job job) { + this.player = jPlayer; + this.job = job; + } + + public JobsPlayer getPlayer() { + return this.player; + } + + public Job getJob() { + return this.job; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + cancelled = cancel; + } + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} \ No newline at end of file diff --git a/com/gamingmesh/jobs/api/JobsLevelUpEvent.java b/com/gamingmesh/jobs/api/JobsLevelUpEvent.java new file mode 100644 index 00000000..acb0bd31 --- /dev/null +++ b/com/gamingmesh/jobs/api/JobsLevelUpEvent.java @@ -0,0 +1,146 @@ +package com.gamingmesh.jobs.api; + +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import com.gamingmesh.jobs.container.JobsPlayer; +import com.gamingmesh.jobs.container.Title; + +public final class JobsLevelUpEvent extends Event implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private JobsPlayer player; + private String JobName; + private Title OldTitle; + private Title NewTitle; + private int level; + private String soundLevelupSound; + private int soundLevelupVolume; + private int soundLevelupPitch; + private String soundTitleChangeSound; + private int soundTitleChangeVolume; + private int soundTitleChangePitch; + private boolean cancelled; + + public JobsLevelUpEvent(JobsPlayer jPlayer, String JobName, int level, Title OldTitle, Title NewTitle, String soundLevelupSound, Integer soundLevelupVolume, Integer soundLevelupPitch, String soundTitleChangeSound, Integer soundTitleChangeVolume, Integer soundTitleChangePitch) { + this.player = jPlayer; + this.JobName = JobName; + this.OldTitle = OldTitle; + this.NewTitle = NewTitle; + this.level = level; + this.soundLevelupSound = soundLevelupSound; + this.soundLevelupVolume = soundLevelupVolume; + this.soundLevelupPitch = soundLevelupPitch; + this.soundTitleChangeSound = soundTitleChangeSound; + this.soundTitleChangeVolume = soundTitleChangeVolume; + this.soundTitleChangePitch = soundTitleChangePitch; + } + + public JobsPlayer getPlayer() { + return this.player; + } + + public String getJobName() { + return this.JobName; + } + + public Title getOldTitle() { + return this.OldTitle; + } + + public String getOldTitleName() { + return this.OldTitle.getName(); + } + + public String getOldTitleShort() { + return this.OldTitle.getShortName(); + } + + public String getOldTitleColor() { + return this.OldTitle.getChatColor().toString(); + } + + public Title getNewTitle() { + return this.NewTitle; + } + + public String getNewTitleName() { + return this.NewTitle.getName(); + } + + public String getNewTitleShort() { + return this.NewTitle.getShortName(); + } + + public String getNewTitleColor() { + return this.NewTitle.getChatColor().toString(); + } + + public String getSoundName() { + return this.soundLevelupSound; + } + + public void setSoundName(String sound) { + this.soundLevelupSound = sound; + } + + public int getSoundVolume() { + return this.soundLevelupVolume; + } + + public void setSoundVolume(int volume) { + this.soundLevelupVolume = volume; + } + + public int getSoundPitch() { + return this.soundLevelupPitch; + } + + public void setSoundPitch(int pitch) { + this.soundLevelupPitch = pitch; + } + + public String getTitleChangeSoundName() { + return this.soundTitleChangeSound; + } + + public void setTitleChangeSoundName(String sound) { + this.soundTitleChangeSound = sound; + } + + public int getTitleChangeVolume() { + return this.soundTitleChangeVolume; + } + + public void setTitleChangeVolume(int volume) { + this.soundTitleChangeVolume = volume; + } + + public int getTitleChangePitch() { + return this.soundTitleChangePitch; + } + + public void setTitleChangePitch(int pitch) { + this.soundTitleChangePitch = pitch; + } + + public int getLevel() { + return this.level; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + cancelled = cancel; + } + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} \ No newline at end of file diff --git a/com/gamingmesh/jobs/api/JobsPaymentEvent.java b/com/gamingmesh/jobs/api/JobsPaymentEvent.java new file mode 100644 index 00000000..7ea39503 --- /dev/null +++ b/com/gamingmesh/jobs/api/JobsPaymentEvent.java @@ -0,0 +1,42 @@ +package com.gamingmesh.jobs.api; + +import org.bukkit.OfflinePlayer; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public final class JobsPaymentEvent extends Event implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private OfflinePlayer offlinePlayer; + private double money; + private boolean cancelled; + + public JobsPaymentEvent(OfflinePlayer offlinePlayer, double money) { + this.offlinePlayer = offlinePlayer; + this.money = money; + } + + public OfflinePlayer getPlayer() { + return this.offlinePlayer; + } + + public double getAmount() { + return this.money; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + cancelled = cancel; + } + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} \ No newline at end of file diff --git a/com/gamingmesh/jobs/commands/.gitignore b/com/gamingmesh/jobs/commands/.gitignore new file mode 100644 index 00000000..fbce14b1 --- /dev/null +++ b/com/gamingmesh/jobs/commands/.gitignore @@ -0,0 +1,2 @@ +/JobCommand.class +/JobsCommands.class diff --git a/com/gamingmesh/jobs/commands/JobCommand.java b/com/gamingmesh/jobs/commands/JobCommand.java new file mode 100644 index 00000000..700eba25 --- /dev/null +++ b/com/gamingmesh/jobs/commands/JobCommand.java @@ -0,0 +1,30 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.gamingmesh.jobs.commands; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +public @interface JobCommand { + +} diff --git a/com/gamingmesh/jobs/commands/JobsCommands.java b/com/gamingmesh/jobs/commands/JobsCommands.java new file mode 100644 index 00000000..fdb68106 --- /dev/null +++ b/com/gamingmesh/jobs/commands/JobsCommands.java @@ -0,0 +1,1512 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.gamingmesh.jobs.commands; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Score; +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.ScoreboardManager; + +import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.config.ConfigManager; +import com.gamingmesh.jobs.container.ActionType; +import com.gamingmesh.jobs.container.Convert; +import com.gamingmesh.jobs.container.Job; +import com.gamingmesh.jobs.container.JobInfo; +import com.gamingmesh.jobs.container.JobItems; +import com.gamingmesh.jobs.container.JobProgression; +import com.gamingmesh.jobs.container.JobsPlayer; +import com.gamingmesh.jobs.container.TopList; +import com.gamingmesh.jobs.economy.PaymentData; +import com.gamingmesh.jobs.i18n.Language; +import com.gamingmesh.jobs.stuff.ChatColor; +import com.gamingmesh.jobs.stuff.GiveItem; +import com.gamingmesh.jobs.stuff.Perm; +import com.gamingmesh.jobs.stuff.Scboard; +import com.gamingmesh.jobs.stuff.TranslateName; + +public class JobsCommands implements CommandExecutor { + private static final String label = "jobs"; + + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (args.length == 0) + return help(sender); + String cmd = args[0].toLowerCase(); + + try { + Method m = getClass().getMethod(cmd, CommandSender.class, String[].class); + if (m.isAnnotationPresent(JobCommand.class)) { + if (!hasCommandPermission(sender, cmd)) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.error.permission")); + return true; + } + String[] myArgs = reduceArgs(args); + if (myArgs.length > 0) { + if (myArgs[myArgs.length - 1].equals("?")) { + sendUsage(sender, cmd); + return true; + } + } + + return (Boolean) m.invoke(this, sender, myArgs); + } + } catch (SecurityException e) { + e.printStackTrace(); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (NoSuchMethodException e) {} + + return help(sender); + } + + private static String[] reduceArgs(String[] args) { + if (args.length <= 1) + return new String[0]; + + return Arrays.copyOfRange(args, 1, args.length); + } + + public static boolean hasCommandPermission(CommandSender sender, String cmd) { + return sender.hasPermission("jobs.command." + cmd); + } + + private String getUsage(String cmd) { + StringBuilder builder = new StringBuilder(); + builder.append(ChatColor.GREEN.toString()); + builder.append('/').append(label).append(' '); + builder.append(cmd); + builder.append(ChatColor.YELLOW); + String key = "command." + cmd + ".help.args"; + if (Language.containsKey(key)) { + builder.append(' '); + builder.append(Language.getMessage(key)); + } + return builder.toString(); + } + + public void sendUsage(CommandSender sender, String cmd) { + String message = ChatColor.YELLOW + Language.getMessage("command.help.output.usage"); + message = message.replace("%usage%", getUsage(cmd)); + sender.sendMessage(message); + sender.sendMessage(ChatColor.YELLOW + "* " + Language.getMessage("command." + cmd + ".help.info")); + } + + public void sendValidActions(CommandSender sender) { + StringBuilder builder = new StringBuilder(); + boolean first = true; + for (ActionType action : ActionType.values()) { + if (!first) + builder.append(','); + builder.append(action.getName()); + first = false; + + } + sender.sendMessage(Language.getMessage("command.info.help.actions").replace("%actions%", builder.toString())); + } + + protected boolean help(CommandSender sender) { + sender.sendMessage(Language.getMessage("command.info.help.title")); + for (Method m : getClass().getMethods()) { + if (m.isAnnotationPresent(JobCommand.class)) { + String cmd = m.getName(); + if (!hasCommandPermission(sender, cmd)) + continue; + sender.sendMessage(getUsage(cmd)); + } + } + sender.sendMessage(ChatColor.YELLOW + Language.getMessage("command.help.output.info")); + return true; + } + + @JobCommand + public boolean convert(CommandSender sender, String[] args) throws IOException { + + if (!(sender instanceof Player)) + return false; + + if (args.length > 0) { + sendUsage(sender, "convert"); + return true; + } + + Player pSender = (Player) sender; + + List list = null; + List archivelist = null; + + try { + list = Jobs.getJobsDAO().convertDatabase(pSender, "jobs"); + archivelist = Jobs.getJobsDAO().convertDatabase(pSender, "archive"); + } catch (SQLException e) { + e.printStackTrace(); + sender.sendMessage(ChatColor.RED + "Can't read data from data base, please send error log to dev's."); + return false; + } + Jobs.ChangeDatabase(); + + if (list == null & archivelist == null) + return false; + try { + Jobs.getJobsDAO().continueConvertions(list, "jobs"); + Jobs.getJobsDAO().continueConvertions(archivelist, "archive"); + } catch (SQLException e) { + e.printStackTrace(); + sender.sendMessage(ChatColor.RED + "Can't write data to data base, please send error log to dev's."); + return false; + } + + Jobs.reload(); + + String from = "MysSQL"; + String to = "SqLite"; + + if (ConfigManager.getJobsConfiguration().storageMethod.equalsIgnoreCase("sqlite")) { + from = "SqLite"; + to = "MySQL"; + } + + sender.sendMessage(ChatColor.GOLD + "Data base was converted from " + ChatColor.GREEN + from + ChatColor.GOLD + " to " + ChatColor.GREEN + to + ChatColor.GOLD + "! Now you can stop the server, change storage-method to " + ChatColor.GREEN + to + ChatColor.GOLD + " in general config file and start server again on your new database system."); + + return true; + } + + @JobCommand + public boolean join(CommandSender sender, String[] args) { + if (!(sender instanceof Player)) + return false; + + if (args.length < 1) { + sendUsage(sender, "join"); + return true; + } + + Player pSender = (Player) sender; + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(pSender); + + String jobName = args[0]; + Job job = Jobs.getJob(jobName); + if (job == null) { + // job does not exist + sender.sendMessage(ChatColor.RED + Language.getMessage("command.error.job")); + return true; + } + + if (!hasJobPermission(pSender, job)) { + // you do not have permission to join the job + sender.sendMessage(ChatColor.RED + Language.getMessage("command.error.permission")); + return true; + } + + if (jPlayer.isInJob(job)) { + // already in job message + String message = ChatColor.RED + Language.getMessage("command.join.error.alreadyin"); + message = message.replace("%jobname%", job.getChatColor() + job.getName() + ChatColor.RED); + sender.sendMessage(message); + return true; + } + + if (job.getMaxSlots() != null && Jobs.getUsedSlots(job) >= job.getMaxSlots()) { + String message = ChatColor.RED + Language.getMessage("command.join.error.fullslots"); + message = message.replace("%jobname%", job.getChatColor() + job.getName() + ChatColor.RED); + sender.sendMessage(message); + return true; + } + + int confMaxJobs = ConfigManager.getJobsConfiguration().getMaxJobs(); + short PlayerMaxJobs = (short) jPlayer.getJobProgression().size(); + if (confMaxJobs > 0 && PlayerMaxJobs >= confMaxJobs && !Jobs.getPlayerManager().getJobsLimit(pSender, PlayerMaxJobs)) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.join.error.maxjobs")); + return true; + } + + Jobs.getPlayerManager().joinJob(jPlayer, job); + + String message = Language.getMessage("command.join.success"); + message = message.replace("%jobname%", job.getChatColor() + job.getName() + ChatColor.WHITE); + sender.sendMessage(message); + return true; + } + + @JobCommand + public boolean leave(CommandSender sender, String[] args) { + if (!(sender instanceof Player)) + return false; + + if (args.length < 1) { + sendUsage(sender, "leave"); + return true; + } + + Player pSender = (Player) sender; + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(pSender); + + String jobName = args[0]; + Job job = Jobs.getJob(jobName); + if (job == null) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.error.job")); + return true; + } + + Jobs.getPlayerManager().leaveJob(jPlayer, job); + String message = Language.getMessage("command.leave.success"); + message = message.replace("%jobname%", job.getChatColor() + job.getName() + ChatColor.WHITE); + sender.sendMessage(message); + return true; + } + + @JobCommand + public boolean leaveall(CommandSender sender, String[] args) { + if (!(sender instanceof Player)) + return false; + + Player pSender = (Player) sender; + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(pSender); + + List jobs = jPlayer.getJobProgression(); + if (jobs.size() == 0) { + sender.sendMessage(Language.getMessage("command.leaveall.error.nojobs")); + return true; + } + + Jobs.getPlayerManager().leaveAllJobs(jPlayer); + sender.sendMessage(Language.getMessage("command.leaveall.success")); + return true; + } + + @JobCommand + public boolean info(CommandSender sender, String[] args) { + if (!(sender instanceof Player)) + return false; + + if (args.length < 1) { + sendUsage(sender, "info"); + sendValidActions(sender); + return true; + } + + Player pSender = (Player) sender; + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(pSender); + + String jobName = args[0]; + Job job = Jobs.getJob(jobName); + if (job == null) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.error.job")); + return true; + } + + if (ConfigManager.getJobsConfiguration().hideJobsInfoWithoutPermission) + if (!hasJobPermission(pSender, job)) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.error.permission")); + return true; + } + + String type = ""; + if (args.length >= 2) { + type = args[1]; + } + sender.sendMessage(jobInfoMessage(jPlayer, job, type).split("\n")); + return true; + } + + @JobCommand + public boolean stats(CommandSender sender, String[] args) { + JobsPlayer jPlayer = null; + if (args.length >= 1) { + if (!sender.hasPermission("jobs.command.admin.stats")) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.error.permission")); + return true; + } + @SuppressWarnings("deprecation") + OfflinePlayer offlinePlayer = Bukkit.getServer().getOfflinePlayer(args[0]); + jPlayer = Jobs.getPlayerManager().getJobsPlayerOffline(offlinePlayer); + } else if (sender instanceof Player) { + jPlayer = Jobs.getPlayerManager().getJobsPlayer((Player) sender); + } + + if (jPlayer == null) { + sendUsage(sender, "stats"); + return true; + } + + if (jPlayer.getJobProgression().size() == 0) { + sender.sendMessage(Language.getMessage("command.stats.error.nojob")); + return true; + } + + for (JobProgression jobProg : jPlayer.getJobProgression()) { + sender.sendMessage(jobStatsMessage(jobProg).split("\n")); + } + return true; + } + + @JobCommand + public boolean toggle(CommandSender sender, String[] args) { + + if (!ConfigManager.getJobsConfiguration().ToggleActionBar) { + sender.sendMessage(ChatColor.GREEN + Language.getMessage("command.toggle.output.turnedoff")); + return true; + } + + if (!(sender instanceof Player)) + return false; + if (args.length > 0) { + sendUsage(sender, "toggle"); + return true; + } + + String PlayerName = sender.getName(); + + if (PlayerName == null) { + sendUsage(sender, "toggle"); + return true; + } + + if (Jobs.actionbartoggle.containsKey(PlayerName)) + if (Jobs.actionbartoggle.get(PlayerName)) { + Jobs.actionbartoggle.put(PlayerName, false); + sender.sendMessage(ChatColor.GREEN + Language.getMessage("command.toggle.output.off")); + } else { + Jobs.actionbartoggle.put(PlayerName, true); + sender.sendMessage(ChatColor.GREEN + Language.getMessage("command.toggle.output.on")); + } + else { + Jobs.actionbartoggle.put(PlayerName, true); + sender.sendMessage(ChatColor.GREEN + Language.getMessage("command.toggle.output.on")); + } + + return true; + } + + @JobCommand + public boolean expboost(CommandSender sender, String[] args) { + //if (!(sender instanceof Player)) + // return false; + + if (args.length > 2 || args.length <= 1) { + sendUsage(sender, "expboost"); + return true; + } + + double rate = 1.0; + if (!args[1].equalsIgnoreCase("all") && !args[0].equalsIgnoreCase("reset")) + try { + rate = Double.parseDouble(args[1]); + } catch (NumberFormatException e) { + sendUsage(sender, "expboost"); + return true; + } + + String PlayerName = sender.getName(); + String jobName = args[0]; + Job job = Jobs.getJob(jobName); + + if (PlayerName == null) { + sendUsage(sender, "expboost"); + return true; + } + + if (args[0].equalsIgnoreCase("reset") && args[1].equalsIgnoreCase("all")) { + for (Job one : Jobs.getJobs()) { + one.setExpBoost(1.0); + } + sender.sendMessage(ChatColor.GREEN + Language.getMessage("command.expboost.output.allreset")); + return true; + } else if (args[0].equalsIgnoreCase("reset")) { + boolean found = false; + for (Job one : Jobs.getJobs()) { + if (one.getName().equalsIgnoreCase(args[1])) { + one.setExpBoost(1.0); + found = true; + break; + } + } + + if (found) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.expboost.output.jobsboostreset").replace("%jobname%", job.getName())); + return true; + } + } + + if (args[0].equalsIgnoreCase("all")) { + + for (Job one : Jobs.getJobs()) { + one.setExpBoost(rate); + } + + sender.sendMessage(ChatColor.GREEN + Language.getMessage("command.expboost.output.boostalladded").replace("%boost%", String.valueOf(rate))); + return true; + } else { + if (job == null) { + sender.sendMessage(ChatColor.GREEN + Language.getMessage("command.error.job")); + return true; + } + job.setExpBoost(rate); + sender.sendMessage(ChatColor.GREEN + Language.getMessage("command.expboost.output.boostadded").replace("%boost%", String.valueOf(rate)).replace("%jobname%", job.getName())); + return true; + } + } + + @JobCommand + public boolean moneyboost(CommandSender sender, String[] args) { + //if (!(sender instanceof Player)) + // return false; + + if (args.length > 2 || args.length <= 1) { + sendUsage(sender, "moneyboost"); + return true; + } + + double rate = 1.0; + if (!args[1].equalsIgnoreCase("all") && !args[0].equalsIgnoreCase("reset")) + try { + rate = Double.parseDouble(args[1]); + } catch (NumberFormatException e) { + sendUsage(sender, "moneyboost"); + return true; + } + + String PlayerName = sender.getName(); + String jobName = args[0]; + Job job = Jobs.getJob(jobName); + + if (PlayerName == null) { + sendUsage(sender, "moneyboost"); + return true; + } + + if (args[0].equalsIgnoreCase("reset") && args[1].equalsIgnoreCase("all")) { + for (Job one : Jobs.getJobs()) { + one.setMoneyBoost(1.0); + } + sender.sendMessage(ChatColor.GREEN + Language.getMessage("command.moneyboost.output.allreset")); + return true; + } else if (args[0].equalsIgnoreCase("reset")) { + boolean found = false; + for (Job one : Jobs.getJobs()) { + if (one.getName().equalsIgnoreCase(args[1])) { + one.setMoneyBoost(1.0); + found = true; + break; + } + } + + if (found) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.moneyboost.output.jobsboostreset").replace("%jobname%", job.getName())); + return true; + } + } + + if (args[0].equalsIgnoreCase("all")) { + + for (Job one : Jobs.getJobs()) { + one.setMoneyBoost(rate); + } + + sender.sendMessage(ChatColor.GREEN + Language.getMessage("command.moneyboost.output.boostalladded").replace("%boost%", String.valueOf(rate))); + return true; + } else { + if (job == null) { + sender.sendMessage(ChatColor.GREEN + Language.getMessage("command.error.job")); + return true; + } + job.setMoneyBoost(rate); + sender.sendMessage(ChatColor.GREEN + Language.getMessage("command.moneyboost.output.boostadded").replace("%boost%", String.valueOf(rate)).replace("%jobname%", job.getName())); + return true; + } + } + + @SuppressWarnings("deprecation") + @JobCommand + public boolean archive(CommandSender sender, String[] args) { + JobsPlayer jPlayer = null; + if (args.length >= 1) { + if (!sender.hasPermission("jobs.command.admin.archive")) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.error.permission")); + return true; + } + OfflinePlayer offlinePlayer = Bukkit.getServer().getOfflinePlayer(args[0]); + jPlayer = Jobs.getPlayerManager().getJobsPlayerOffline(offlinePlayer); + + } else if (sender instanceof Player) { + jPlayer = Jobs.getPlayerManager().getJobsPlayer((Player) sender); + } + + if (jPlayer == null) { + sendUsage(sender, "archive"); + return true; + } + + List AllJobs = Jobs.getJobsDAO().getJobsFromArchive(jPlayer); + + if (AllJobs.size() == 0) { + sender.sendMessage(Language.getMessage("command.archive.error.nojob")); + return true; + } + + for (String jobInfo : AllJobs) { + sender.sendMessage(jobStatsMessage(jobInfo)); + } + return true; + } + + @JobCommand + public boolean browse(CommandSender sender, String[] args) { + ArrayList lines = new ArrayList(); + for (Job job : Jobs.getJobs()) { + if (ConfigManager.getJobsConfiguration().getHideJobsWithoutPermission()) { + if (!hasJobPermission(sender, job)) + continue; + } + StringBuilder builder = new StringBuilder(); + builder.append(" "); + builder.append(job.getChatColor().toString()); + builder.append(job.getName()); + if (job.getMaxLevel() > 0) { + builder.append(ChatColor.WHITE.toString()); + builder.append(Language.getMessage("command.info.help.max")); + if (Perm.hasPermission(sender, "jobs." + job.getName() + ".vipmaxlevel") && job.getVipMaxLevel() != 0) + builder.append(job.getVipMaxLevel()); + else + builder.append(job.getMaxLevel()); + } + + if (ConfigManager.getJobsConfiguration().ShowTotalWorkers) + builder.append(Language.getMessage("command.browse.output.totalWorkers").replace("[amount]", String.valueOf(job.getTotalPlayers()))); + + if (ConfigManager.getJobsConfiguration().useDynamicPayment && ConfigManager.getJobsConfiguration().ShowPenaltyBonus) + if (job.getBonus() < 0) + builder.append(Language.getMessage("command.browse.output.penalty").replace("[amount]", String.valueOf((int) (job.getBonus() * 100) / 100.0 * -1))); + else + builder.append(Language.getMessage("command.browse.output.bonus").replace("[amount]", String.valueOf((int) (job.getBonus() * 100) / 100.0))); + + lines.add(builder.toString()); + if (!job.getDescription().isEmpty()) { + lines.add(" - " + job.getDescription()); + } + } + + if (lines.size() == 0) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.browse.error.nojobs")); + return true; + } + + // if (sender instanceof Player) { + // ((Player) sender).openInventory(GuiTools.CreateJobsGUI((Player) sender)); + // } + + sender.sendMessage(Language.getMessage("command.browse.output.header")); + for (String line : lines) { + sender.sendMessage(line); + } + sender.sendMessage(Language.getMessage("command.browse.output.footer")); + return true; + } + + @JobCommand + public boolean playerinfo(CommandSender sender, String[] args) { + if (args.length < 2) { + sendUsage(sender, "playerinfo"); + sendValidActions(sender); + return true; + } + + @SuppressWarnings("deprecation") + OfflinePlayer offlinePlayer = Bukkit.getServer().getOfflinePlayer(args[0]); + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayerOffline(offlinePlayer); + + String jobName = args[1]; + Job job = Jobs.getJob(jobName); + if (job == null) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.error.job")); + return true; + } + String type = ""; + if (args.length >= 3) { + type = args[2]; + } + sender.sendMessage(jobInfoMessage(jPlayer, job, type).split("\n")); + return true; + } + + @JobCommand + public boolean reload(CommandSender sender, String[] args) { + try { + Jobs.reload(); + sender.sendMessage(Language.getMessage("command.admin.success")); + } catch (Exception e) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.admin.error")); + + String message = org.bukkit.ChatColor.translateAlternateColorCodes('&', "&4There was an error when performing a reload: "); + ConsoleCommandSender console = Bukkit.getServer().getConsoleSender(); + console.sendMessage(message); + + //Jobs.getPluginLogger().severe("There was an error when performing a reload: "); + e.printStackTrace(); + } + return true; + } + + @JobCommand + public boolean fire(CommandSender sender, String[] args) { + if (args.length < 2) { + sendUsage(sender, "fire"); + return true; + } + + @SuppressWarnings("deprecation") + OfflinePlayer offlinePlayer = Bukkit.getServer().getOfflinePlayer(args[0]); + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayerOffline(offlinePlayer); + + Job job = Jobs.getJob(args[1]); + if (job == null) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.error.job")); + return true; + } + if (!jPlayer.isInJob(job)) { + String message = ChatColor.RED + Language.getMessage("command.fire.error.nojob"); + message = message.replace("%jobname%", job.getChatColor() + job.getName() + ChatColor.RED); + sender.sendMessage(message); + return true; + } + try { + Jobs.getPlayerManager().leaveJob(jPlayer, job); + Player player = Bukkit.getServer().getPlayer(offlinePlayer.getUniqueId()); + if (player != null) { + String message = Language.getMessage("command.fire.output.target"); + message = message.replace("%jobname%", job.getChatColor() + job.getName() + ChatColor.WHITE); + player.sendMessage(message); + } + + sender.sendMessage(Language.getMessage("command.admin.success")); + } catch (Exception e) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.admin.error")); + } + return true; + } + + @JobCommand + public boolean fireall(CommandSender sender, String[] args) { + if (args.length < 1) { + sendUsage(sender, "fireall"); + return true; + } + + @SuppressWarnings("deprecation") + OfflinePlayer offlinePlayer = Bukkit.getServer().getOfflinePlayer(args[0]); + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayerOffline(offlinePlayer); + + List jobs = jPlayer.getJobProgression(); + if (jobs.size() == 0) { + sender.sendMessage(Language.getMessage("command.fireall.error.nojobs")); + return true; + } + + try { + Jobs.getPlayerManager().leaveAllJobs(jPlayer); + Player player = Bukkit.getServer().getPlayer(offlinePlayer.getUniqueId()); + if (player != null) { + player.sendMessage(Language.getMessage("command.fireall.output.target")); + } + + sender.sendMessage(Language.getMessage("command.admin.success")); + } catch (Exception e) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.admin.error")); + } + return true; + } + + @JobCommand + public boolean employ(CommandSender sender, String[] args) { + if (args.length < 2) { + sendUsage(sender, "employ"); + return true; + } + + @SuppressWarnings("deprecation") + OfflinePlayer offlinePlayer = Bukkit.getServer().getOfflinePlayer(args[0]); + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayerOffline(offlinePlayer); + + Job job = Jobs.getJob(args[1]); + if (job == null) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.error.job")); + return true; + } + if (jPlayer.isInJob(job)) { + // already in job message + String message = ChatColor.RED + Language.getMessage("command.employ.error.alreadyin"); + message = message.replace("%jobname%", job.getChatColor() + job.getName() + ChatColor.RED); + sender.sendMessage(message); + return true; + } + try { + // check if player already has the job + Jobs.getPlayerManager().joinJob(jPlayer, job); + Player player = Bukkit.getServer().getPlayer(offlinePlayer.getUniqueId()); + if (player != null) { + String message = Language.getMessage("command.employ.output.target"); + message = message.replace("%jobname%", job.getChatColor() + job.getName() + ChatColor.WHITE); + player.sendMessage(message); + } + + sender.sendMessage(Language.getMessage("command.admin.success")); + } catch (Exception e) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.admin.error")); + } + return true; + } + + @JobCommand + public boolean promote(CommandSender sender, String[] args) { + if (args.length < 3) { + sendUsage(sender, "promote"); + return true; + } + + @SuppressWarnings("deprecation") + OfflinePlayer offlinePlayer = Bukkit.getServer().getOfflinePlayer(args[0]); + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayerOffline(offlinePlayer); + + Job job = Jobs.getJob(args[1]); + if (job == null) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.error.job")); + return true; + } + try { + // check if player already has the job + if (jPlayer.isInJob(job)) { + Integer levelsGained = Integer.parseInt(args[2]); + Jobs.getPlayerManager().promoteJob(jPlayer, job, levelsGained); + + Player player = Bukkit.getServer().getPlayer(offlinePlayer.getUniqueId()); + if (player != null) { + String message = Language.getMessage("command.promote.output.target"); + message = message.replace("%jobname%", job.getChatColor() + job.getName() + ChatColor.WHITE); + message = message.replace("%levelsgained%", Integer.valueOf(levelsGained).toString()); + player.sendMessage(message); + } + + sender.sendMessage(Language.getMessage("command.admin.success")); + } + } catch (Exception e) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.admin.error")); + } + return true; + } + + @JobCommand + public boolean demote(CommandSender sender, String[] args) { + if (args.length < 3) { + sendUsage(sender, "demote"); + return true; + } + + @SuppressWarnings("deprecation") + OfflinePlayer offlinePlayer = Bukkit.getServer().getOfflinePlayer(args[0]); + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayerOffline(offlinePlayer); + + Job job = Jobs.getJob(args[1]); + if (job == null) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.error.job")); + return true; + } + try { + // check if player already has the job + if (jPlayer.isInJob(job)) { + Integer levelsLost = Integer.parseInt(args[2]); + Jobs.getPlayerManager().demoteJob(jPlayer, job, levelsLost); + + Player player = Bukkit.getServer().getPlayer(offlinePlayer.getUniqueId()); + if (player != null) { + String message = Language.getMessage("command.demote.output.target"); + message = message.replace("%jobname%", job.getChatColor() + job.getName() + ChatColor.WHITE); + message = message.replace("%levelslost%", Integer.valueOf(levelsLost).toString()); + player.sendMessage(message); + } + + sender.sendMessage(Language.getMessage("command.admin.success")); + } + } catch (Exception e) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.admin.error")); + } + return true; + } + + @JobCommand + public boolean grantxp(CommandSender sender, String[] args) { + if (args.length < 3) { + sendUsage(sender, "grantxp"); + return true; + } + + @SuppressWarnings("deprecation") + OfflinePlayer offlinePlayer = Bukkit.getServer().getOfflinePlayer(args[0]); + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayerOffline(offlinePlayer); + + Job job = Jobs.getJob(args[1]); + if (job == null) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.error.job")); + return true; + } + double xpGained; + try { + xpGained = Double.parseDouble(args[2]); + } catch (Exception e) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.admin.error")); + return true; + } + if (xpGained <= 0) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.admin.error")); + return true; + } + // check if player already has the job + if (jPlayer.isInJob(job)) { + Jobs.getPlayerManager().addExperience(jPlayer, job, xpGained); + + Player player = Bukkit.getServer().getPlayer(offlinePlayer.getUniqueId()); + if (player != null) { + String message = Language.getMessage("command.grantxp.output.target"); + message = message.replace("%jobname%", job.getChatColor() + job.getName() + ChatColor.WHITE); + message = message.replace("%xpgained%", Double.valueOf(xpGained).toString()); + player.sendMessage(message); + } + + sender.sendMessage(Language.getMessage("command.admin.success")); + } + return true; + } + + @JobCommand + public boolean removexp(CommandSender sender, String[] args) { + if (args.length < 3) { + sendUsage(sender, "removexp"); + return true; + } + + @SuppressWarnings("deprecation") + OfflinePlayer offlinePlayer = Bukkit.getServer().getOfflinePlayer(args[0]); + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayerOffline(offlinePlayer); + + Job job = Jobs.getJob(args[1]); + if (job == null) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.error.job")); + return true; + } + double xpLost; + try { + xpLost = Double.parseDouble(args[2]); + } catch (Exception e) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.admin.error")); + return true; + } + if (xpLost <= 0) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.admin.error")); + return true; + } + // check if player already has the job + if (jPlayer.isInJob(job)) { + Jobs.getPlayerManager().removeExperience(jPlayer, job, xpLost); + + Player player = Bukkit.getServer().getPlayer(offlinePlayer.getUniqueId()); + if (player != null) { + String message = Language.getMessage("command.removexp.output.target"); + message = message.replace("%jobname%", job.getChatColor() + job.getName() + ChatColor.WHITE); + message = message.replace("%xplost%", Double.valueOf(xpLost).toString()); + player.sendMessage(message); + } + + sender.sendMessage(Language.getMessage("command.admin.success")); + } + return true; + } + + @JobCommand + public boolean transfer(CommandSender sender, String[] args) { + if (args.length < 3) { + sendUsage(sender, "transfer"); + return true; + } + + @SuppressWarnings("deprecation") + OfflinePlayer offlinePlayer = Bukkit.getServer().getOfflinePlayer(args[0]); + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayerOffline(offlinePlayer); + + Job oldjob = Jobs.getJob(args[1]); + Job newjob = Jobs.getJob(args[2]); + if (oldjob == null) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.error.job")); + return true; + } + if (newjob == null) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.error.job")); + return true; + } + try { + if (jPlayer.isInJob(oldjob) && !jPlayer.isInJob(newjob)) { + Jobs.getPlayerManager().transferJob(jPlayer, oldjob, newjob); + + Player player = Bukkit.getServer().getPlayer(offlinePlayer.getUniqueId()); + if (player != null) { + String message = Language.getMessage("command.transfer.output.target"); + message = message.replace("%oldjobname%", oldjob.getChatColor() + oldjob.getName() + ChatColor.WHITE); + message = message.replace("%newjobname%", newjob.getChatColor() + newjob.getName() + ChatColor.WHITE); + player.sendMessage(message); + } + + sender.sendMessage(Language.getMessage("command.admin.success")); + } + } catch (Exception e) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.admin.error")); + } + return true; + } + + @JobCommand + public boolean signupdate(CommandSender sender, String[] args) { + if (args.length != 1) { + sendUsage(sender, "signupdate"); + return true; + } + + Job oldjob = Jobs.getJob(args[0]); + + if (oldjob == null && !args[0].equalsIgnoreCase("gtoplist")) { + sender.sendMessage(ChatColor.RED + Language.getMessage("command.error.job")); + return true; + } + if (!args[0].equalsIgnoreCase("gtoplist")) + Signs.SignUtil.SignUpdate(oldjob.getName()); + else + Signs.SignUtil.SignUpdate("gtoplist"); + + return true; + } + + @JobCommand + public boolean gtop(CommandSender sender, String[] args) { + + if (args.length != 1 && args.length != 0) { + sendUsage(sender, "gtop"); + return true; + } + + if (!(sender instanceof Player)) + return false; + Player player = (Player) sender; + + if (args.length > 0 && args[0].equalsIgnoreCase("clear")) { + player.getScoreboard().clearSlot(DisplaySlot.SIDEBAR); + return true; + } + + int start = 0; + if (args.length == 1) + try { + start = Integer.parseInt(args[0]); + } catch (NumberFormatException e) { + return true; + } + if (start < 0) + start = 0; + + List FullList = Jobs.getJobsDAO().getGlobalTopList(start); + if (FullList.size() <= 0) { + player.sendMessage(ChatColor.RED + Language.getMessage("command.gtop.error.nojob")); + return false; + } + + if (!ConfigManager.getJobsConfiguration().ShowToplistInScoreboard) { + player.sendMessage(Language.getMessage("command.gtop.output.topline")); + int i = start; + for (TopList One : FullList) { + i++; + String PlayerName = One.getPlayerName() != null ? One.getPlayerName() : "Unknown"; + player.sendMessage(Language.getMessage("command.gtop.output.list").replace("%number%", String.valueOf(i)).replace("%playername%", PlayerName).replace("%level%", String.valueOf(One.getLevel())).replace("%exp%", String.valueOf(One.getExp()))); + } + } else { + + player.getScoreboard().clearSlot(DisplaySlot.SIDEBAR); + + ScoreboardManager manager = Bukkit.getScoreboardManager(); + Scoreboard board = manager.getNewScoreboard(); + Objective objective = board.registerNewObjective("JobsTopPlayers", "dummy"); + objective.setDisplaySlot(DisplaySlot.SIDEBAR); + objective.setDisplayName(Language.getMessage("scoreboard.gtopline")); + int i = start; + for (TopList One : FullList) { + i++; + String playername = One.getPlayerName() != null ? One.getPlayerName() : "Unknown"; + + Score score = objective.getScore(Language.getMessage("scoreboard.lines").replace("%number%", String.valueOf(i)).replace("%playername%", playername)); + score.setScore(One.getLevel()); + + } + player.setScoreboard(board); + + Scboard.addNew(player); + + //player.sendMessage(ChatColor.GOLD + Language.getMessage("scoreboard.clear")); + + int from = start; + if (start >= 15) + from = start - 15; + int until = start + 15; + + String prev = "[\"\",{\"text\":\"" + Language.getMessage("command.gtop.output.prev") + "\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/jobs gtop " + from + "\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":{\"text\":\"\",\"extra\":[{\"text\":\"" + Language.getMessage("command.gtop.output.show").replace("[from]", String.valueOf(from)).replace("[until]", String.valueOf((from + 15))) + "\"}]}}}"; + String next = " {\"text\":\"" + Language.getMessage("command.gtop.output.next") + "\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/jobs gtop " + until + "\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":{\"text\":\"\",\"extra\":[{\"text\":\"" + Language.getMessage("command.gtop.output.show").replace("[from]", String.valueOf(until + 1)).replace("[until]", String.valueOf((until + 15))) + "\"}]}}}]"; + + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + player.getName() + " " + prev + "," + next); + } + return true; + } + + @JobCommand + public boolean top(CommandSender sender, String[] args) { + + if (args.length != 1 && args.length != 2) { + sendUsage(sender, "top"); + return true; + } + + if (!(sender instanceof Player)) + return false; + Player player = (Player) sender; + + if (args[0].equalsIgnoreCase("clear")) { + player.getScoreboard().clearSlot(DisplaySlot.SIDEBAR); + return true; + } + + int start = 0; + if (args.length == 2) + try { + start = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + return true; + } + if (start < 0) + start = 0; + + List FullList = Jobs.getJobsDAO().toplist(args[0], start); + if (FullList.size() <= 0) { + player.sendMessage(ChatColor.RED + Language.getMessage("command.top.error.nojob")); + return false; + } + + Job job = Jobs.getJob(args[0]); + String jobName = args[0]; + if (job != null) + jobName = job.getName(); + + if (!ConfigManager.getJobsConfiguration().ShowToplistInScoreboard) { + player.sendMessage(Language.getMessage("command.top.output.topline").replace("%jobname%", jobName)); + int i = start; + for (TopList One : FullList) { + i++; + String PlayerName = One.getPlayerName() != null ? One.getPlayerName() : "Unknown"; + player.sendMessage(Language.getMessage("command.top.output.list").replace("%number%", String.valueOf(i)).replace("%playername%", PlayerName).replace("%level%", String.valueOf(One.getLevel())).replace("%exp%", String.valueOf(One.getExp()))); + } + } else { + + player.getScoreboard().clearSlot(DisplaySlot.SIDEBAR); + + ScoreboardManager manager = Bukkit.getScoreboardManager(); + Scoreboard board = manager.getNewScoreboard(); + Objective objective = board.registerNewObjective("JobsTopPlayers", "dummy"); + objective.setDisplaySlot(DisplaySlot.SIDEBAR); + objective.setDisplayName(Language.getMessage("scoreboard.topline").replace("%jobname%", jobName)); + int i = start; + for (TopList One : FullList) { + i++; + String playername = One.getPlayerName() != null ? One.getPlayerName() : "Unknown"; + + Score score = objective.getScore(Language.getMessage("scoreboard.lines").replace("%number%", String.valueOf(i)).replace("%playername%", playername)); + score.setScore(One.getLevel()); + + } + player.setScoreboard(board); + //player.sendMessage(ChatColor.GOLD + Language.getMessage("scoreboard.clear")); + + Scboard.addNew(player); + + int from = start; + if (start >= 15) + from = start - 15; + int until = start + 15; + + String prev = "[\"\",{\"text\":\"" + Language.getMessage("command.top.output.prev") + "\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/jobs top " + jobName + " " + from + "\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":{\"text\":\"\",\"extra\":[{\"text\":\"" + Language.getMessage("command.top.output.show").replace("[from]", String.valueOf(from)).replace("[until]", String.valueOf((from + 15))) + "\"}]}}}"; + String next = " {\"text\":\"" + Language.getMessage("command.top.output.next") + "\",\"clickEvent\":{\"action\":\"run_command\",\"value\":\"/jobs top " + jobName + " " + until + "\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":{\"text\":\"\",\"extra\":[{\"text\":\"" + Language.getMessage("command.top.output.show").replace("[from]", String.valueOf(until + 1)).replace("[until]", String.valueOf((until + 15))) + "\"}]}}}]"; + + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + player.getName() + " " + prev + "," + next); + } + return true; + } + + @JobCommand + public boolean give(CommandSender sender, String[] args) { + + if (args.length < 1 || Jobs.getJob(args[0]) == null && Jobs.getJob(args[1]) == null) { + sendUsage(sender, "give"); + return true; + } + + if (args.length == 2 && sender instanceof Player) { + Job job = Jobs.getJob(args[0]); + for (JobItems item : job.getItems()) { + if (item.getNode().equalsIgnoreCase(args[1])) { + GiveItem.GiveItemForPlayer((Player) sender, item.getId(), 0, 1, item.getName(), item.getLore(), item.getenchants()); + return true; + } + } + sender.sendMessage(Language.getMessage("command.give.output.noitem")); + return true; + } else if (args.length == 3) { + Job job = Jobs.getJob(args[1]); + Player player = Bukkit.getPlayer(args[0]); + if (player == null) { + sender.sendMessage(Language.getMessage("command.give.output.notonline").replace("%playername%", args[0])); + return true; + } + for (JobItems item : job.getItems()) { + if (item.getNode().equalsIgnoreCase(args[2])) { + GiveItem.GiveItemForPlayer(player, item.getId(), 0, 1, item.getName(), item.getLore(), item.getenchants()); + return true; + } + } + sender.sendMessage(Language.getMessage("command.give.output.noitem")); + return true; + } else { + sendUsage(sender, "give"); + return true; + } + } + + @JobCommand + public boolean limit(CommandSender sender, String[] args) { + if (args.length > 0) { + sendUsage(sender, "limit"); + return true; + } + + if (!(sender instanceof Player)) + return false; + + Player player = (Player) sender; + + if (!ConfigManager.getJobsConfiguration().EconomyLimitUse && !ConfigManager.getJobsConfiguration().EconomyExpLimitUse) { + player.sendMessage(Language.getMessage("command.limit.output.notenabled")); + return true; + } + + String playername = player.getName(); + + if (ConfigManager.getJobsConfiguration().EconomyLimitUse) + if (Jobs.paymentLimit.containsKey(playername) && Jobs.paymentLimit.get(playername).GetLeftTime(ConfigManager.getJobsConfiguration().EconomyLimitTimeLimit) > 0) { + PaymentData data = Jobs.paymentLimit.get(playername); + + String lefttimemessage = Language.getMessage("command.limit.output.lefttime").replace("%hour%", String.valueOf(data.GetLeftHour(ConfigManager.getJobsConfiguration().EconomyLimitTimeLimit))); + lefttimemessage = lefttimemessage.replace("%min%", String.valueOf(data.GetLeftMin(ConfigManager.getJobsConfiguration().EconomyLimitTimeLimit))); + lefttimemessage = lefttimemessage.replace("%sec%", String.valueOf(data.GetLeftsec(ConfigManager.getJobsConfiguration().EconomyLimitTimeLimit))); + player.sendMessage(lefttimemessage); + + String message = Language.getMessage("command.limit.output.moneylimit"); + message = message.replace("%money%", String.valueOf(data.GetAmountBylimit(ConfigManager.getJobsConfiguration().EconomyLimitMoneyLimit))); + message = message.replace("%totalmoney%", String.valueOf(ConfigManager.getJobsConfiguration().EconomyLimitMoneyLimit)); + player.sendMessage(message); + + } else { + + int lefttime1 = ConfigManager.getJobsConfiguration().EconomyLimitTimeLimit; + + int hour = 0; + int min = 0; + int sec = 0; + + if (lefttime1 >= 3600) { + hour = lefttime1 / 3600; + lefttime1 = lefttime1 - (hour * 3600); + if (lefttime1 > 60 && lefttime1 < 3600) { + min = lefttime1 / 60; + sec = lefttime1 - (min * 60); + } else if (lefttime1 < 60) + sec = lefttime1; + } else if (lefttime1 > 60 && lefttime1 < 3600) { + min = lefttime1 / 60; + lefttime1 = lefttime1 - (min * 60); + } else + sec = lefttime1; + + String message = Language.getMessage("command.limit.output.lefttime").replace("%hour%", String.valueOf(hour)); + message = message.replace("%min%", String.valueOf(min)); + message = message.replace("%sec%", String.valueOf(sec)); + player.sendMessage(message); + + message = Language.getMessage("command.limit.output.moneylimit").replace("%money%", "0.0"); + message = message.replace("%totalmoney%", String.valueOf(ConfigManager.getJobsConfiguration().EconomyLimitMoneyLimit)); + player.sendMessage(message); + } + + if (ConfigManager.getJobsConfiguration().EconomyExpLimitUse) + if (Jobs.ExpLimit.containsKey(playername) && Jobs.ExpLimit.get(playername).GetLeftTime(ConfigManager.getJobsConfiguration().EconomyExpTimeLimit) > 0) { + PaymentData data = Jobs.ExpLimit.get(playername); + + String lefttimemessage = Language.getMessage("command.limit.output.leftexptime").replace("%hour%", String.valueOf(data.GetLeftHour(ConfigManager.getJobsConfiguration().EconomyExpTimeLimit))); + lefttimemessage = lefttimemessage.replace("%min%", String.valueOf(data.GetLeftMin(ConfigManager.getJobsConfiguration().EconomyExpTimeLimit))); + lefttimemessage = lefttimemessage.replace("%sec%", String.valueOf(data.GetLeftsec(ConfigManager.getJobsConfiguration().EconomyExpTimeLimit))); + player.sendMessage(lefttimemessage); + + String message = Language.getMessage("command.limit.output.explimit"); + message = message.replace("%exp%", String.valueOf(data.GetAmountBylimit(ConfigManager.getJobsConfiguration().EconomyExpLimit))); + message = message.replace("%totalexp%", String.valueOf(ConfigManager.getJobsConfiguration().EconomyExpLimit)); + player.sendMessage(message); + + } else { + + int lefttime1 = ConfigManager.getJobsConfiguration().EconomyExpTimeLimit; + + int hour = 0; + int min = 0; + int sec = 0; + + if (lefttime1 >= 3600) { + hour = lefttime1 / 3600; + lefttime1 = lefttime1 - (hour * 3600); + if (lefttime1 > 60 && lefttime1 < 3600) { + min = lefttime1 / 60; + sec = lefttime1 - (min * 60); + } else if (lefttime1 < 60) + sec = lefttime1; + } else if (lefttime1 > 60 && lefttime1 < 3600) { + min = lefttime1 / 60; + lefttime1 = lefttime1 - (min * 60); + } else + sec = lefttime1; + + String message = Language.getMessage("command.limit.output.leftexptime").replace("%hour%", String.valueOf(hour)); + message = message.replace("%min%", String.valueOf(min)); + message = message.replace("%sec%", String.valueOf(sec)); + player.sendMessage(message); + + message = Language.getMessage("command.limit.output.explimit").replace("%exp%", "0.0"); + message = message.replace("%totalexp%", String.valueOf(ConfigManager.getJobsConfiguration().EconomyExpLimit)); + player.sendMessage(message); + } + + return true; + } + + /** + * Displays info about a job + * @param player - the player of the job + * @param job - the job we are displaying info about + * @param type - type of info + * @return the message + */ + private String jobInfoMessage(JobsPlayer player, Job job, String type) { + if (job == null) { + // job doesn't exist + return ChatColor.RED + Language.getMessage("command.error.job"); + } + + if (type == null) { + type = ""; + } else { + type = type.toLowerCase(); + } + + StringBuilder message = new StringBuilder(); + + int showAllTypes = 1; + for (ActionType actionType : ActionType.values()) { + if (type.startsWith(actionType.getName().toLowerCase())) { + showAllTypes = 0; + break; + } + } + + if (job.getExpBoost() != 1.0) + message.append(ChatColor.GOLD + Language.getMessage("command.expboost.output.infostats").replace("%boost%", String.valueOf(job.getExpBoost())) + "\n"); + + if (job.getMoneyBoost() != 1.0) + message.append(ChatColor.GOLD + Language.getMessage("command.moneyboost.output.infostats").replace("%boost%", String.valueOf(job.getMoneyBoost())) + "\n"); + + if (ConfigManager.getJobsConfiguration().useDynamicPayment) + if (job.getBonus() < 0) + message.append(ChatColor.GOLD + Language.getMessage("command.info.help.penalty").replace("[penalty]", String.valueOf((int) (job.getBonus() * 100) / 100.0 * -1)) + "\n"); + else + message.append(ChatColor.GOLD + Language.getMessage("command.info.help.bonus").replace("[bonus]", String.valueOf((int) (job.getBonus() * 100) / 100.0)) + "\n"); + + for (ActionType actionType : ActionType.values()) { + if (showAllTypes == 1 || type.startsWith(actionType.getName().toLowerCase())) { + List info = job.getJobInfo(actionType); + if (info != null && !info.isEmpty()) { + message.append(jobInfoMessage(player, job, actionType)); + } else if (showAllTypes == 0) { + String myMessage = Language.getMessage("command.info.output." + actionType.getName().toLowerCase() + ".none"); + myMessage = myMessage.replace("%jobname%", job.getChatColor() + job.getName() + ChatColor.WHITE); + message.append(myMessage); + } + } + } + return message.toString(); + } + + /** + * Displays info about a particular action + * @param player - the player of the job + * @param prog - the job we are displaying info about + * @param type - the type of action + * @return the message + */ + public static String jobInfoMessage(JobsPlayer player, Job job, ActionType type) { + + // money exp boost + Player dude = Bukkit.getServer().getPlayer(player.getPlayerUUID()); + Double MoneyBoost = Jobs.getPlayerManager().GetMoneyBoost(dude, job); + Double ExpBoost = Jobs.getPlayerManager().GetExpBoost(dude, job); + + // Global boost + Double JobGlobalBoost = job.getExpBoost(); + + Double DynamicBonus = job.getBonus(); + + StringBuilder message = new StringBuilder(); + + message.append(Language.getMessage("command.info.output." + type.getName().toLowerCase() + ".info")); + message.append(":\n"); + + int level = 1; + + JobProgression prog = player.getJobProgression(job); + if (prog != null) + level = prog.getLevel(); + int numjobs = player.getJobProgression().size(); + List jobInfo = job.getJobInfo(type); + for (JobInfo info : jobInfo) { + String materialName = info.getName().toLowerCase().replace('_', ' '); + materialName = Character.toUpperCase(materialName.charAt(0)) + materialName.substring(1); + + materialName = TranslateName.Translate(materialName, info); + + materialName = org.bukkit.ChatColor.translateAlternateColorCodes('&', materialName); + + double income = info.getIncome(level, numjobs); + + if (ConfigManager.getJobsConfiguration().useDynamicPayment) { + double moneyBonus = (income * (DynamicBonus / 100)); + income += moneyBonus; + } + + income = income + ((income * MoneyBoost) - income) + ((income * JobGlobalBoost) - income); + + ChatColor incomeColor = income >= 0 ? ChatColor.GREEN : ChatColor.DARK_RED; + + double xp = info.getExperience(level, numjobs); + + if (ConfigManager.getJobsConfiguration().useDynamicPayment) { + double expBonus = (xp * (DynamicBonus / 100)); + xp += expBonus; + } + + xp = xp + ((xp * ExpBoost) - xp) + ((xp * JobGlobalBoost) - xp); + ChatColor xpColor = xp >= 0 ? ChatColor.YELLOW : ChatColor.GRAY; + String xpString = String.format("%.2f xp", xp); + + message.append(" "); + + message.append(Language.getMessage("command.info.help.material").replace("%material%", materialName)); + message.append(" -> "); + + message.append(xpColor.toString()); + message.append(xpString); + message.append(' '); + + message.append(incomeColor.toString()); + message.append(Jobs.getEconomy().format(income)); + + message.append('\n'); + } + return message.toString(); + } + + /** + * Displays job stats about a particular player's job + * @param jobProg - the job progress of the players job + * @return the message + */ + private String jobStatsMessage(JobProgression jobProg) { + String message = Language.getMessage("command.stats.output"); + message = message.replace("%joblevel%", Integer.valueOf(jobProg.getLevel()).toString()); + message = message.replace("%jobname%", jobProg.getJob().getChatColor() + jobProg.getJob().getName() + ChatColor.WHITE); + message = message.replace("%jobxp%", Double.toString(Math.round((Double) jobProg.getExperience() * 100.0) / 100.0)); + message = message.replace("%jobmaxxp%", Integer.toString(jobProg.getMaxExperience())); + return message; + } + + /** + * Displays job stats about a particular player's job from archive + * @param jobInfo - jobinfo string line + * @return the message + */ + private String jobStatsMessage(String jobInfo) { + String[] splited = jobInfo.split(":"); + if (Jobs.getJob(splited[0]) == null) + return ""; + String message = Language.getMessage("command.archive.output"); + message = message.replace("%joblevel%", Integer.valueOf(splited[1]).toString()); + message = message.replace("%getbackjoblevel%", Integer.valueOf(splited[2]).toString()); + message = message.replace("%jobname%", Jobs.getJob(splited[0]).getChatColor() + splited[0] + ChatColor.WHITE); + message = message.replace("%jobxp%", Double.toString(Math.round((Double) Double.valueOf(splited[3]) * 100.0) / 100.0)); + return message; + } + + /** + * Check Job joining permission + */ + public static boolean hasJobPermission(Player sender, Job job) { + return hasJobPermission((CommandSender) sender, job); + } + + private static boolean hasJobPermission(CommandSender sender, Job job) { + if (!sender.hasPermission("jobs.use")) { + return false; + } else { + return sender.hasPermission("jobs.join." + job.getName().toLowerCase()); + } + } +} diff --git a/com/gamingmesh/jobs/config/.gitignore b/com/gamingmesh/jobs/config/.gitignore new file mode 100644 index 00000000..faac9c58 --- /dev/null +++ b/com/gamingmesh/jobs/config/.gitignore @@ -0,0 +1,5 @@ +/CommentedYamlConfiguration.class +/ConfigManager.class +/JobConfig.class +/JobsConfiguration.class +/YmlMaker.class diff --git a/com/gamingmesh/jobs/config/CommentedYamlConfiguration.java b/com/gamingmesh/jobs/config/CommentedYamlConfiguration.java new file mode 100644 index 00000000..452edb26 --- /dev/null +++ b/com/gamingmesh/jobs/config/CommentedYamlConfiguration.java @@ -0,0 +1,218 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.gamingmesh.jobs.config; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.HashMap; + +import org.bukkit.configuration.file.YamlConfiguration; + +import com.google.common.io.Files; + +/* + * Based on CommentedYamlConfiguration by dumptruckman + * https://github.com/dumptruckman/PluginBase/blob/master/bukkit/src/main/java/com/dumptruckman/minecraft/pluginbase/config/CommentedYamlConfiguration.java + */ + +public class CommentedYamlConfiguration extends YamlConfiguration { + private HashMap comments; + + public CommentedYamlConfiguration() { + super(); + comments = new HashMap(); + } + + @Override + public void save(String file) throws IOException { + if (file == null) { + throw new IllegalArgumentException("File cannot be null"); + } + + save(new File(file)); + } + + @Override + public void save(File file) throws IOException { + if (file == null) { + throw new IllegalArgumentException("File cannot be null"); + } + + Files.createParentDirs(file); + + String data = insertComments(saveToString()); + + //FileWriter writer = new FileWriter(file); + + PrintWriter writer = new PrintWriter(file, "UTF-8"); + + //Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8")); + + try { + writer.write(data); + } finally { + writer.close(); + } + } + + private String insertComments(String yaml) { + // if there's comments to add, we need to add comments + if (!comments.isEmpty()) { + // String array of each line in the config file + String[] yamlContents = yaml.split("[" + System.getProperty("line.separator") + "]"); + + // This will hold the entire newly formatted config + StringBuilder newContents = new StringBuilder(); + // This holds the current path the lines are at in the config + StringBuilder currentPath = new StringBuilder(); + // This tells if the specified path has already been commented + boolean commentedPath = false; + // This flags if the line is a node or unknown text. + boolean node = false; + // The depth of the path. (number of words separated by periods - 1) + int depth = 0; + + // This will cause the first line to be ignored. + boolean firstLine = true; + // Loop through the config lines + for (final String line : yamlContents) { + if (firstLine) { + firstLine = false; + if (line.startsWith("#")) { + continue; + } + } + // If the line is a node (and not something like a list value) + if (line.contains(": ") || (line.length() > 1 && line.charAt(line.length() - 1) == ':')) { + // This is a new node so we need to mark it for commenting (if there are comments) + commentedPath = false; + // This is a node so flag it as one + node = true; + + // Grab the index of the end of the node name + int index = 0; + index = line.indexOf(": "); + if (index < 0) { + index = line.length() - 1; + } + // If currentPath is empty, store the node name as the currentPath. (this is only on the first iteration, i think) + if (currentPath.toString().isEmpty()) { + currentPath = new StringBuilder(line.substring(0, index)); + } else { + // Calculate the whitespace preceding the node name + int whiteSpace = 0; + for (int n = 0; n < line.length(); n++) { + if (line.charAt(n) == ' ') { + whiteSpace++; + } else { + break; + } + } + // Find out if the current depth (whitespace * 2) is greater/lesser/equal to the previous depth + if (whiteSpace / 2 > depth) { + // Path is deeper. Add a . and the node name + currentPath.append(".").append(line.substring(whiteSpace, index)); + depth++; + } else if (whiteSpace / 2 < depth) { + // Path is shallower, calculate current depth from whitespace (whitespace / 2) and subtract that many levels from the currentPath + int newDepth = whiteSpace / 2; + for (int i = 0; i < depth - newDepth; i++) { + currentPath.replace(currentPath.lastIndexOf("."), currentPath.length(), ""); + } + // Grab the index of the final period + int lastIndex = currentPath.lastIndexOf("."); + if (lastIndex < 0) { + // if there isn't a final period, set the current path to nothing because we're at root + currentPath = new StringBuilder(); + } else { + // If there is a final period, replace everything after it with nothing + currentPath.replace(currentPath.lastIndexOf("."), currentPath.length(), "").append("."); + } + // Add the new node name to the path + currentPath.append(line.substring(whiteSpace, index)); + // Reset the depth + depth = newDepth; + } else { + // Path is same depth, replace the last path node name to the current node name + int lastIndex = currentPath.lastIndexOf("."); + if (lastIndex < 0) { + // if there isn't a final period, set the current path to nothing because we're at root + currentPath = new StringBuilder(); + } else { + // If there is a final period, replace everything after it with nothing + currentPath.replace(currentPath.lastIndexOf("."), currentPath.length(), "").append("."); + } + //currentPath = currentPath.replace(currentPath.substring(currentPath.lastIndexOf(".")), ""); + currentPath.append(line.substring(whiteSpace, index)); + } + } + } else { + node = false; + } + StringBuilder newLine = new StringBuilder(line); + if (node) { + String comment = null; + if (!commentedPath) { + // If there's a comment for the current path, retrieve it and flag that path as already commented + comment = comments.get(currentPath.toString()); + } + if (comment != null && !comment.isEmpty()) { + // Add the comment to the beginning of the current line + newLine.insert(0, System.getProperty("line.separator")).insert(0, comment); + comment = null; + commentedPath = true; + } + } + newLine.append(System.getProperty("line.separator")); + // Add the (modified) line to the total config String + newContents.append(newLine.toString()); + } + + return newContents.toString(); + } + return yaml; + } + + /** + * Adds a comment just before the specified path. The comment can be multiple lines. An empty string will indicate a blank line. + * + * @param path Configuration path to add comment. + * @param commentLines Comments to add. One String per line. + */ + public void addComment(String path, String... commentLines) { + StringBuilder commentstring = new StringBuilder(); + String leadingSpaces = ""; + for (int n = 0; n < path.length(); n++) { + if (path.charAt(n) == '.') { + leadingSpaces += " "; + } + } + for (String line : commentLines) { + if (!line.isEmpty()) { + line = leadingSpaces + "# " + line; + } + if (commentstring.length() > 0) { + commentstring.append(System.getProperty("line.separator")); + } + commentstring.append(line); + } + comments.put(path, commentstring.toString()); + } +} diff --git a/com/gamingmesh/jobs/config/ConfigManager.java b/com/gamingmesh/jobs/config/ConfigManager.java new file mode 100644 index 00000000..7f2a33e3 --- /dev/null +++ b/com/gamingmesh/jobs/config/ConfigManager.java @@ -0,0 +1,40 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.gamingmesh.jobs.config; + +public class ConfigManager { + private static JobsConfiguration config; + private static JobConfig jobConfig; + + public static JobsConfiguration getJobsConfiguration() { + return config; + } + + public static void registerJobsConfiguration(JobsConfiguration c) { + config = c; + } + + public static JobConfig getJobConfig() { + return jobConfig; + } + + public static void registerJobConfig(JobConfig c) { + jobConfig = c; + } +} diff --git a/com/gamingmesh/jobs/config/JobConfig.java b/com/gamingmesh/jobs/config/JobConfig.java new file mode 100644 index 00000000..a87168a2 --- /dev/null +++ b/com/gamingmesh/jobs/config/JobConfig.java @@ -0,0 +1,426 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.gamingmesh.jobs.config; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.StringEscapeUtils; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.EntityType; +import org.bukkit.inventory.ItemStack; + +import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.JobsPlugin; +import com.gamingmesh.jobs.container.ActionType; +import com.gamingmesh.jobs.container.DisplayMethod; +import com.gamingmesh.jobs.container.Job; +import com.gamingmesh.jobs.container.JobCommands; +import com.gamingmesh.jobs.container.JobInfo; +import com.gamingmesh.jobs.container.JobItems; +import com.gamingmesh.jobs.container.JobPermission; +import com.gamingmesh.jobs.resources.jfep.Parser; +import com.gamingmesh.jobs.stuff.ChatColor; + +public class JobConfig { + private JobsPlugin plugin; + + public JobConfig(JobsPlugin plugin) { + this.plugin = plugin; + } + + public void reload() throws IOException { + // job settings + loadJobSettings(); + } + + /** + * Method to load the jobs configuration + * + * loads from Jobs/jobConfig.yml + * @throws IOException + */ + @SuppressWarnings("deprecation") + private void loadJobSettings() throws IOException { + File f = new File(plugin.getDataFolder(), "jobConfig.yml"); + InputStreamReader s = new InputStreamReader(new FileInputStream(f), "UTF-8"); + + ArrayList jobs = new ArrayList(); + Jobs.setJobs(jobs); + Jobs.setNoneJob(null); + if (!f.exists()) { + try { + f.createNewFile(); + } catch (IOException e) { + Jobs.getPluginLogger().severe("Unable to create jobConfig.yml! No jobs were loaded!"); + s.close(); + return; + } + } + YamlConfiguration conf = new YamlConfiguration(); + conf.options().pathSeparator('/'); + try { + conf.load(s); + s.close(); + } catch (Exception e) { + Bukkit.getServer().getLogger().severe("==================== Jobs ===================="); + Bukkit.getServer().getLogger().severe("Unable to load jobConfig.yml!"); + Bukkit.getServer().getLogger().severe("Check your config for formatting issues!"); + Bukkit.getServer().getLogger().severe("No jobs were loaded!"); + Bukkit.getServer().getLogger().severe("Error: " + e.getMessage()); + Bukkit.getServer().getLogger().severe("=============================================="); + return; + } + //conf.options().header(new StringBuilder().append("Jobs configuration.").append(System.getProperty("line.separator")).append(System.getProperty("line.separator")).append("Stores information about each job.").append(System.getProperty("line.separator")).append(System.getProperty("line.separator")).append("For example configurations, visit http://dev.bukkit.org/bukkit-plugins/jobs-reborn/.").append(System.getProperty("line.separator")).toString()); + + ConfigurationSection jobsSection = conf.getConfigurationSection("Jobs"); + //if (jobsSection == null) { + // jobsSection = conf.createSection("Jobs"); + //} + for (String jobKey : jobsSection.getKeys(false)) { + ConfigurationSection jobSection = jobsSection.getConfigurationSection(jobKey); + String jobName = jobSection.getString("fullname"); + + // Translating unicode + jobName = StringEscapeUtils.unescapeJava(jobName); + + if (jobName == null) { + Jobs.getPluginLogger().warning("Job " + jobKey + " has an invalid fullname property. Skipping job!"); + continue; + } + + int maxLevel = jobSection.getInt("max-level", 0); + if (maxLevel < 0) + maxLevel = 0; + + int vipmaxLevel = jobSection.getInt("vip-max-level", 0); + if (vipmaxLevel < 0) + vipmaxLevel = 0; + + Integer maxSlots = jobSection.getInt("slots", 0); + if (maxSlots.intValue() <= 0) { + maxSlots = null; + } + + String jobShortName = jobSection.getString("shortname"); + if (jobShortName == null) { + Jobs.getPluginLogger().warning("Job " + jobKey + " is missing the shortname property. Skipping job!"); + continue; + } + + String description = org.bukkit.ChatColor.translateAlternateColorCodes('&', jobSection.getString("description", "")); + + ChatColor color = ChatColor.WHITE; + if (jobSection.contains("ChatColour")) { + color = ChatColor.matchColor(jobSection.getString("ChatColour", "")); + if (color == null) { + color = ChatColor.WHITE; + Jobs.getPluginLogger().warning("Job " + jobKey + " has an invalid ChatColour property. Defaulting to WHITE!"); + } + } + DisplayMethod displayMethod = DisplayMethod.matchMethod(jobSection.getString("chat-display", "")); + if (displayMethod == null) { + Jobs.getPluginLogger().warning("Job " + jobKey + " has an invalid chat-display property. Defaulting to None!"); + displayMethod = DisplayMethod.NONE; + } + + Parser maxExpEquation; + String maxExpEquationInput = jobSection.getString("leveling-progression-equation"); + try { + maxExpEquation = new Parser(maxExpEquationInput); + // test equation + maxExpEquation.setVariable("numjobs", 1); + maxExpEquation.setVariable("joblevel", 1); + maxExpEquation.getValue(); + } catch (Exception e) { + Jobs.getPluginLogger().warning("Job " + jobKey + " has an invalid leveling-progression-equation property. Skipping job!"); + continue; + } + + Parser incomeEquation; + String incomeEquationInput = jobSection.getString("income-progression-equation"); + try { + incomeEquation = new Parser(incomeEquationInput); + // test equation + incomeEquation.setVariable("numjobs", 1); + incomeEquation.setVariable("joblevel", 1); + incomeEquation.setVariable("baseincome", 1); + incomeEquation.getValue(); + } catch (Exception e) { + Jobs.getPluginLogger().warning("Job " + jobKey + " has an invalid income-progression-equation property. Skipping job!"); + continue; + } + + Parser expEquation; + String expEquationInput = jobSection.getString("experience-progression-equation"); + try { + expEquation = new Parser(expEquationInput); + // test equation + expEquation.setVariable("numjobs", 1); + expEquation.setVariable("joblevel", 1); + expEquation.setVariable("baseexperience", 1); + expEquation.getValue(); + } catch (Exception e) { + Jobs.getPluginLogger().warning("Job " + jobKey + " has an invalid experience-progression-equation property. Skipping job!"); + continue; + } + + // Gui item + ItemStack GUIitem = new ItemStack(Material.getMaterial(35), 1, (byte) 13); + if (jobSection.contains("Gui")) { + ConfigurationSection guiSection = jobSection.getConfigurationSection("Gui"); + if (guiSection.contains("Id") && guiSection.contains("Data") && guiSection.isInt("Id") && guiSection.isInt("Data")) { + GUIitem = new ItemStack(Material.getMaterial(guiSection.getInt("Id")), 1, (byte) guiSection.getInt("Data")); + } else + Jobs.getPluginLogger().warning("Job " + jobKey + " has an invalid Gui property. Please fix this if you want to use it!"); + } + + // Permissions + ArrayList jobPermissions = new ArrayList(); + ConfigurationSection permissionsSection = jobSection.getConfigurationSection("permissions"); + if (permissionsSection != null) { + for (String permissionKey : permissionsSection.getKeys(false)) { + ConfigurationSection permissionSection = permissionsSection.getConfigurationSection(permissionKey); + + String node = permissionKey.toLowerCase(); + if (permissionSection == null) { + Jobs.getPluginLogger().warning("Job " + jobKey + " has an invalid permission key" + permissionKey + "!"); + continue; + } + boolean value = permissionSection.getBoolean("value", true); + int levelRequirement = permissionSection.getInt("level", 0); + jobPermissions.add(new JobPermission(node, value, levelRequirement)); + } + } + + // Command on leave + List JobsCommandOnLeave = new ArrayList(); + if (jobSection.isList("cmd-on-leave")) { + JobsCommandOnLeave = jobSection.getStringList("cmd-on-leave"); + } + + // Command on join + List JobsCommandOnJoin = new ArrayList(); + if (jobSection.isList("cmd-on-join")) { + JobsCommandOnJoin = jobSection.getStringList("cmd-on-join"); + } + + // Commands + ArrayList jobCommand = new ArrayList(); + ConfigurationSection commandsSection = jobSection.getConfigurationSection("commands"); + if (commandsSection != null) { + for (String commandKey : commandsSection.getKeys(false)) { + ConfigurationSection commandSection = commandsSection.getConfigurationSection(commandKey); + + String node = commandKey.toLowerCase(); + if (commandSection == null) { + Jobs.getPluginLogger().warning("Job " + jobKey + " has an invalid command key" + commandKey + "!"); + continue; + } + String command = commandSection.getString("command"); + int levelFrom = commandSection.getInt("levelFrom"); + int levelUntil = commandSection.getInt("levelUntil"); + jobCommand.add(new JobCommands(node, command, levelFrom, levelUntil)); + } + } + + // Items + ArrayList jobItems = new ArrayList(); + ConfigurationSection itemsSection = jobSection.getConfigurationSection("items"); + if (itemsSection != null) { + for (String itemKey : itemsSection.getKeys(false)) { + ConfigurationSection itemSection = itemsSection.getConfigurationSection(itemKey); + + String node = itemKey.toLowerCase(); + if (itemSection == null) { + Jobs.getPluginLogger().warning("Job " + jobKey + " has an invalid item key " + itemKey + "!"); + continue; + } + int id = itemSection.getInt("id"); + String name = itemSection.getString("name"); + + List lore = new ArrayList(); + for (String eachLine : itemSection.getStringList("lore")) { + lore.add(org.bukkit.ChatColor.translateAlternateColorCodes('&', eachLine)); + } + + List enchants = new ArrayList(); + if (itemSection.getStringList("enchants") != null) + for (String eachLine : itemSection.getStringList("enchants")) { + enchants.add(eachLine); + } + + Double moneyBoost = itemSection.getDouble("moneyBoost"); + Double expBoost = itemSection.getDouble("expBoost"); + jobItems.add(new JobItems(node, id, name, lore, enchants, moneyBoost, expBoost)); + } + } + + Job job = new Job(jobName, jobShortName, description, color, maxExpEquation, displayMethod, maxLevel, vipmaxLevel, maxSlots, jobPermissions, jobCommand, jobItems, JobsCommandOnJoin, JobsCommandOnLeave, GUIitem); + + for (ActionType actionType : ActionType.values()) { + ConfigurationSection typeSection = jobSection.getConfigurationSection(actionType.getName()); + ArrayList jobInfo = new ArrayList(); + if (typeSection != null) { + for (String key : typeSection.getKeys(false)) { + ConfigurationSection section = typeSection.getConfigurationSection(key); + String myKey = key; + String type = null; + String subType = ""; + String meta = ""; + int id = 0; + + if (myKey.contains("-")) { + // uses subType + subType = ":" + myKey.split("-")[1]; + meta = myKey.split("-")[1]; + myKey = myKey.split("-")[0]; + } + + Material material = Material.matchMaterial(myKey); + + if (material == null) + material = Material.getMaterial(myKey.replace(" ", "_").toUpperCase()); + + if (material == null) { + // try integer method + Integer matId = null; + try { + matId = Integer.valueOf(myKey); + } catch (NumberFormatException e) {} + if (matId != null) { + material = Material.getMaterial(matId); + if (material != null) { + Jobs.getPluginLogger().warning("Job " + jobKey + " " + actionType.getName() + " is using ID: " + key + "!"); + Jobs.getPluginLogger().warning("Please use the Material name instead: " + material.toString() + "!"); + } + } + } + + if (material != null) { + // Break and Place actions MUST be blocks + if (actionType == ActionType.BREAK || actionType == ActionType.PLACE) { + if (!material.isBlock()) { + Jobs.getPluginLogger().warning("Job " + jobKey + " has an invalid " + actionType.getName() + " type property: " + key + "! Material must be a block!"); + continue; + } + } + // START HACK + /* + * Historically, GLOWING_REDSTONE_ORE would ONLY work as REDSTONE_ORE, and putting + * GLOWING_REDSTONE_ORE in the configuration would not work. Unfortunately, this is + * completely backwards and wrong. + * + * To maintain backwards compatibility, all instances of REDSTONE_ORE should normalize + * to GLOWING_REDSTONE_ORE, and warn the user to change their configuration. In the + * future this hack may be removed and anybody using REDSTONE_ORE will have their + * configurations broken. + */ + if (material == Material.REDSTONE_ORE && actionType == ActionType.BREAK) { + Jobs.getPluginLogger().warning("Job " + jobKey + " is using REDSTONE_ORE instead of GLOWING_REDSTONE_ORE."); + Jobs.getPluginLogger().warning("Automatically changing block to GLOWING_REDSTONE_ORE. Please update your configuration."); + Jobs.getPluginLogger().warning("In vanilla minecraft, REDSTONE_ORE changes to GLOWING_REDSTONE_ORE when interacted with."); + Jobs.getPluginLogger().warning("In the future, Jobs using REDSTONE_ORE instead of GLOWING_REDSTONE_ORE may fail to work correctly."); + material = Material.GLOWING_REDSTONE_ORE; + } + // END HACK + + type = material.toString(); + id = material.getId(); + } else if (actionType == ActionType.KILL || actionType == ActionType.TAME || actionType == ActionType.BREED || actionType == ActionType.MILK) { + // check entities + EntityType entity = EntityType.fromName(key); + if (entity == null) { + try { + entity = EntityType.valueOf(key.toUpperCase()); + } catch (IllegalArgumentException e) {} + } + + if (entity != null && entity.isAlive()) { + type = entity.toString(); + + id = entity.getTypeId(); + } + + // Just to recognize wither skeleton + if (key.equalsIgnoreCase("WitherSkeleton")) { + type = "WitherSkeleton"; + id = 51; + meta = "1"; + } + + // Just to recognize Zombie Villager + if (key.equalsIgnoreCase("ZombieVillager")) { + type = "ZombieVillager"; + id = 54; + meta = "1"; + } + + // Just to recognize Elder Guardian + if (key.equalsIgnoreCase("ElderGuardian")) { + type = "ElderGuardian"; + id = 68; + meta = "1"; + } + + } else if (actionType == ActionType.ENCHANT && material == null) { + Enchantment enchant = Enchantment.getByName(myKey); + if (enchant != null) + id = enchant.getId(); + type = myKey; + } else if (actionType == ActionType.CUSTOMKILL || actionType == ActionType.SHEAR) { + + type = myKey; + } + + if (type == null) { + Jobs.getPluginLogger().warning("Job " + jobKey + " has an invalid " + actionType.getName() + " type property: " + key + "!"); + continue; + } + + double income = section.getDouble("income", 0.0); + double experience = section.getDouble("experience", 0.0); + + jobInfo.add(new JobInfo(actionType, id, meta, type + subType, income, incomeEquation, experience, expEquation)); + } + } + job.setJobInfo(actionType, jobInfo); + } + + if (jobKey.equalsIgnoreCase("none")) { + Jobs.setNoneJob(job); + } else { + jobs.add(job); + } + } + //try { + // conf.save(f); + //} catch (IOException e) { + // e.printStackTrace(); + //} + } +} diff --git a/com/gamingmesh/jobs/config/JobsConfiguration.java b/com/gamingmesh/jobs/config/JobsConfiguration.java new file mode 100644 index 00000000..f06000ee --- /dev/null +++ b/com/gamingmesh/jobs/config/JobsConfiguration.java @@ -0,0 +1,1286 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.gamingmesh.jobs.config; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.configuration.Configuration; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.resources.jfep.Parser; +import com.gamingmesh.jobs.JobsPlugin; +import com.gamingmesh.jobs.container.NameList; +import com.gamingmesh.jobs.container.RestrictedArea; +import com.gamingmesh.jobs.container.Schedule; +import com.gamingmesh.jobs.container.Title; +import com.gamingmesh.jobs.dao.JobsDAOMySQL; +import com.gamingmesh.jobs.dao.JobsDAOSQLite; +import com.gamingmesh.jobs.stuff.ChatColor; + +public class JobsConfiguration { + private JobsPlugin plugin; + protected List titles = new ArrayList<Title>(); + protected ArrayList<RestrictedArea> restrictedAreas = new ArrayList<RestrictedArea>(); + public ArrayList<String> restrictedBlocks = new ArrayList<String>(); + public ArrayList<String> restrictedBlocksTimer = new ArrayList<String>(); + public ArrayList<Integer> restrictedPlaceBlocksTimer = new ArrayList<Integer>(); + public ArrayList<NameList> ListOfNames = new ArrayList<NameList>(); + public ArrayList<NameList> ListOfEntities = new ArrayList<NameList>(); + public ArrayList<NameList> ListOfEnchants = new ArrayList<NameList>(); + public ArrayList<NameList> ListOfColors = new ArrayList<NameList>(); + public List<Integer> BroadcastingLevelUpLevels = new ArrayList<Integer>(); + protected Locale locale; + protected int savePeriod; + protected boolean economyAsync; + protected boolean isBroadcastingSkillups; + protected boolean isBroadcastingLevelups; + protected boolean payInCreative; + protected boolean addXpPlayer; + protected boolean hideJobsWithoutPermission; + protected int maxJobs; + protected boolean payNearSpawner; + protected boolean modifyChat; + protected int economyBatchDelay; + protected boolean saveOnDisconnect; + public boolean EconomyLimitUse, EconomyExpLimitUse, PayForRenaming, PayForEachCraft, SignsEnabled, + SignsColorizeJobName, ShowToplistInScoreboard, useGlobalTimer, useCoreProtect, BlockPlaceUse, + EnableAnounceMessage, useBlockPiston, useSilkTouchProtection, UseCustomNames, EconomyMoneyStop, + EconomyExpStop, UseJobsBrowse; + public int EconomyLimitMoneyLimit, EconomyExpLimit; + public int EconomyLimitTimeLimit, EconomyExpTimeLimit; + public int EconomyLimitAnnouncmentDelay, EconomyLimitAnnouncmentExpDelay, globalblocktimer, CowMilkingTimer, + CoreProtectInterval, BlockPlaceInterval, InfoUpdateInterval; + public Double payNearSpawnerMultiplier, VIPpayNearSpawnerMultiplier, TreeFellerMultiplier, PetPay, VipPetPay; + public String localeString; + public boolean useBlockProtection; + public boolean useBlockTimer; + public boolean useBreederFinder, CancelCowMilking; + public boolean fixAtMaxLevel, ToggleActionBar, TitleChangeChat, TitleChangeActionBar, LevelChangeChat, + LevelChangeActionBar, SoundLevelupUse, SoundTitleChangeUse, UseServerAccount, EmptyServerAcountChat, + EmptyServerAcountActionBar, JobsToggleEnabled, ShowTotalWorkers, ShowPenaltyBonus, useDynamicPayment, + useGlobalBoostScheduler; + public Integer levelLossPercentage, SoundLevelupVolume, SoundLevelupPitch, SoundTitleChangeVolume, + SoundTitleChangePitch, ToplistInScoreboardInterval; + public double BoostExp; + public double BoostMoney; + public double DynamicPaymentMaxPenalty; + public double DynamicPaymentMaxBonus; + public double TaxesAmount; + public String SoundLevelupSound, SoundTitleChangeSound, ServerAcountName, ServertaxesAcountName; + public ArrayList<String> keys; + public String storageMethod; + public boolean hideJobsInfoWithoutPermission; + public boolean UseTaxes; + public boolean TransferToServerAccount; + public boolean TakeFromPlayersPayment; + + public Parser DynamicPaymentEquation; + + public List<Schedule> BoostSchedule = new ArrayList<Schedule>(); + + public JobsConfiguration(JobsPlugin plugin) { + super(); + this.plugin = plugin; + } + + public String Colors(String text) { + return org.bukkit.ChatColor.translateAlternateColorCodes('&', text); + } + + public String GetConfigString(String path, String text, CommentedYamlConfiguration writer, YamlConfiguration conf, Boolean colorize) { + conf.addDefault(path, text); + text = conf.getString(path); + if (colorize) + text = Colors(text); + copySetting(conf, writer, path); + return text; + } + + /** + * Get how often in minutes to save job information + * @return how often in minutes to save job information + */ + public synchronized int getSavePeriod() { + return savePeriod; + } + + /** + * Should we use asynchronous economy calls + * @return true - use async + * @return false - use sync + */ + public synchronized boolean isEconomyAsync() { + return economyAsync; + } + + /** + * Function that tells if the system is set to broadcast on skill up + * @return true - broadcast on skill up + * @return false - do not broadcast on skill up + */ + public synchronized boolean isBroadcastingSkillups() { + return isBroadcastingSkillups; + } + + /** + * Function that tells if the system is set to broadcast on level up + * @return true - broadcast on level up + * @return false - do not broadcast on level up + */ + public synchronized boolean isBroadcastingLevelups() { + return isBroadcastingLevelups; + } + + /** + * Function that tells if the player should be paid while in creative + * @return true - pay in creative + * @return false - do not pay in creative + */ + public synchronized boolean payInCreative() { + return payInCreative; + } + + /** + * Function to return the title for a given level + * @return the correct title + * @return null if no title matches + */ + public Title getTitleForLevel(int level, String jobName) { + Title title = null; + for (Title t : titles) { + if (title == null) { + if (t.getLevelReq() <= level) { + title = t; + } + } else { + if (t.getLevelReq() <= level && t.getLevelReq() > title.getLevelReq()) { + title = t; + } + } + } + return title; + } + + public synchronized boolean addXpPlayer() { + return addXpPlayer; + } + + /** + * Function to check if jobs should be hidden to players that lack permission to join the job + * @return + */ + public synchronized boolean getHideJobsWithoutPermission() { + return hideJobsWithoutPermission; + } + + /** + * Function to return the maximum number of jobs a player can join + * @return + */ + public synchronized int getMaxJobs() { + return maxJobs; + } + + /** + * Function to check if you get paid near a spawner is enabled + * @return true - you get paid + * @return false - you don't get paid + */ + public synchronized boolean payNearSpawner() { + return payNearSpawner; + } + + /** + * Gets the area multiplier for the player + * @param player + * @return - the multiplier + */ + public synchronized double getRestrictedMultiplier(Player player) { + for (RestrictedArea area : restrictedAreas) { + if (area.inRestrictedArea(player)) + return area.getMultiplier(); + } + return 1.0; + } + + public synchronized boolean getModifyChat() { + return modifyChat; + } + + public synchronized int getEconomyBatchDelay() { + return economyBatchDelay; + } + + public synchronized boolean saveOnDisconnect() { + return saveOnDisconnect; + } + + public synchronized Locale getLocale() { + return locale; + } + + public synchronized void reload() { + // general settings + loadGeneralSettings(); + // Load locale + loadLanguage(); + // title settings + loadTitleSettings(); + // restricted areas + loadRestrictedAreaSettings(); + // restricted blocks + loadRestrictedBlocks(); + // Item/Block/mobs name list + loadItemList(); + // Item/Block/mobs name list + Signs.SignUtil.LoadSigns(); + +// loadScheduler(); + } + + /** + * Method to load the general configuration + * + * loads from Jobs/generalConfig.yml + */ + private synchronized void loadGeneralSettings() { + File f = new File(plugin.getDataFolder(), "generalConfig.yml"); + YamlConfiguration config = YamlConfiguration.loadConfiguration(f); + + CommentedYamlConfiguration writer = new CommentedYamlConfiguration(); + StringBuilder header = new StringBuilder(); + header.append("General configuration."); + header.append(System.getProperty("line.separator")); + header.append(" The general configuration for the jobs plugin mostly includes how often the plugin"); + header.append(System.getProperty("line.separator")); + header.append("saves user data (when the user is in the game), the storage method, whether"); + header.append(System.getProperty("line.separator")); + header.append("to broadcast a message to the server when a user goes up a skill level."); + header.append(System.getProperty("line.separator")); + header.append(" It also allows admins to set the maximum number of jobs a player can have at"); + header.append(System.getProperty("line.separator")); + header.append("any one time."); + header.append(System.getProperty("line.separator")); + + config.options().copyDefaults(true); + + writer.options().header(header.toString()); + + writer.addComment("locale-language", "Default language.", "Example: en, ru", "File in locale folder with same name should exist. Example: messages_ru.yml"); + localeString = getString("locale-language", "en", config, writer); + try { + int i = localeString.indexOf('_'); + if (i == -1) { + locale = new Locale(localeString); + } else { + locale = new Locale(localeString.substring(0, i), localeString.substring(i + 1)); + } + } catch (IllegalArgumentException e) { + locale = Locale.getDefault(); + Jobs.getPluginLogger().warning("Invalid locale \"" + localeString + "\" defaulting to " + locale.getLanguage()); + } + + writer.addComment("storage-method", "storage method, can be MySQL, sqlite"); + storageMethod = getString("storage-method", "sqlite", config, writer); + if (storageMethod.equalsIgnoreCase("mysql")) { + startMysql(); + // } else if (storageMethod.equalsIgnoreCase("h2")) { + // File h2jar = new File(plugin.getDataFolder(), "h2.jar"); + // Jobs.getPluginLogger().warning("H2 database no longer supported! Converting to SQLite."); + // if (!h2jar.exists()) { + // Jobs.getPluginLogger().info("H2 library not found, downloading..."); + // try { + // FileDownloader.downloadFile(new URL("http://dev.bukkit.org/media/files/692/88/h2-1.3.171.jar"), h2jar); + // } catch (MalformedURLException e) { + // e.printStackTrace(); + // } catch (IOException e) { + // Jobs.getPluginLogger().severe("Could not download database library!"); + // } + // } + // if (plugin.isEnabled()) { + // try { + // Jobs.getJobsClassloader().addFile(h2jar); + // } catch (IOException e) { + // Jobs.getPluginLogger().severe("Could not load database library!"); + // } + // if (plugin.isEnabled()) { + // try { + // JobsDAOH2.convertToSQLite(); + // Jobs.setDAO(JobsDAOSQLite.initialize()); + // config.set("storage-method", "sqlite"); + // } catch (SQLException e) { + // Jobs.getPluginLogger().severe("Error when converting from H2 to SQLite!"); + // e.printStackTrace(); + // } + // } + // } + } else if (storageMethod.equalsIgnoreCase("sqlite")) { + startSqlite(); + } else { + Jobs.getPluginLogger().warning("Invalid storage method! Changing method to sqlite!"); + config.set("storage-method", "sqlite"); + Jobs.setDAO(JobsDAOSQLite.initialize()); + } + + writer.addComment("mysql-username", "Requires Mysql."); + getString("mysql-username", "root", config, writer); + getString("mysql-password", "", config, writer); + getString("mysql-hostname", "localhost:3306", config, writer); + getString("mysql-database", "minecraft", config, writer); + getString("mysql-table-prefix", "jobs_", config, writer); + + writer.addComment("save-period", "How often in minutes you want it to save. This must be a non-zero number"); + getInt("save-period", 10, config, writer); + if (config.getInt("save-period") <= 0) { + Jobs.getPluginLogger().severe("Save period must be greater than 0! Defaulting to 10 minutes!"); + config.set("save-period", 10); + } + savePeriod = config.getInt("save-period"); + + writer.addComment("save-on-disconnect", "Should player data be saved on disconnect?", "Player data is always periodically auto-saved and autosaved during a clean shutdown.", "Only enable this if you have a multi-server setup, or have a really good reason for enabling this.", "Turning this on will decrease database performance."); + saveOnDisconnect = getBoolean("save-on-disconnect", false, config, writer); + + writer.addComment("broadcast.on-skill-up.use", "Do all players get a message when somone goes up a skill level?"); + isBroadcastingSkillups = getBoolean("broadcast.on-skill-up.use", false, config, writer); + + writer.addComment("broadcast.on-level-up.use", "Do all players get a message when somone goes up a level?"); + isBroadcastingLevelups = getBoolean("broadcast.on-level-up.use", false, config, writer); + writer.addComment("broadcast.on-level-up.levels", "For what levels you want to broadcast message? Keep it at 0 if you want for all of them"); + BroadcastingLevelUpLevels = getIntArray("broadcast.on-level-up.levels", Arrays.asList(0), config, writer); + + writer.addComment("max-jobs", "Maximum number of jobs a player can join.", "Use 0 for no maximum"); + maxJobs = getInt("max-jobs", 3, config, writer); + + writer.addComment("hide-jobs-without-permission", "Hide jobs from player if they lack the permission to join the job"); + hideJobsWithoutPermission = getBoolean("hide-jobs-without-permission", false, config, writer); + + writer.addComment("hide-jobsinfo-without-permission", "Hide jobs info from player if they lack the permission to join the job"); + hideJobsInfoWithoutPermission = getBoolean("hide-jobsinfo-without-permission", false, config, writer); + + writer.addComment("enable-pay-near-spawner", "Option to allow payment to be made when killing mobs from a spawner"); + payNearSpawner = getBoolean("enable-pay-near-spawner", false, config, writer); + + writer.addComment("pay-near-spawner-multiplier", "enable-pay-near-spawner should be enabled for this to work", "0.5 means that players will get only 50% exp/money from monsters spawned from spawner"); + payNearSpawnerMultiplier = getDouble("pay-near-spawner-multiplier", 1.0, config, writer); + + writer.addComment("VIP-pay-near-spawner-multiplier", "VIP multiplier to pay for monsters from spawners, this will ignore global multiplier", "Use jobs.vipspawner permission node for this to be enabled"); + VIPpayNearSpawnerMultiplier = getDouble("VIP-pay-near-spawner-multiplier", 1.0, config, writer); + + writer.addComment("enable-pay-creative", "Option to allow payment to be made in creative mode"); + payInCreative = getBoolean("enable-pay-creative", false, config, writer); + + writer.addComment("add-xp-player", "Adds the Jobs xp recieved to the player's Minecraft XP bar"); + addXpPlayer = getBoolean("add-xp-player", false, config, writer); + + writer.addComment("modify-chat", "Modifys chat to add chat titles. If you're using a chat manager, you may add the tag {jobs} to your chat format and disable this."); + modifyChat = getBoolean("modify-chat", true, config, writer); + + writer.addComment("UseCustomNames", "Do you want to use custom item/block/mob/enchant/color names", "With this set to true names like Stone:1 will be translated to Granite", "Name list is in ItemList.yml file"); + UseCustomNames = getBoolean("UseCustomNames", true, config, writer); + + writer.addComment("economy-batch-delay", "Changes how often, in seconds, players are paid out. Default is 5 seconds.", "Setting this too low may cause tick lag. Increase this to improve economy performance (at the cost of delays in payment)"); + economyBatchDelay = getInt("economy-batch-delay", 5, config, writer); + + writer.addComment("economy-async", "Enable async economy calls.", "Disabl this if you have issues with payments or your plugin is not thread safe."); + economyAsync = getBoolean("economy-async", true, config, writer); + + writer.addComment("Economy.DynamicPayment.use", "Do you want to use dinamic payment dependent on how many players already working for jobs", "This can help automaticaly lift up payments for not so popular jobs and lower for most popular ones"); + useDynamicPayment = getBoolean("Economy.DynamicPayment.use", false, config, writer); + + String maxExpEquationInput = getString("Economy.DynamicPayment.equation", "((totalworkers / totaljobs) - jobstotalplayers)/10.0", config, writer); + try { + DynamicPaymentEquation = new Parser(maxExpEquationInput); + // test equation + DynamicPaymentEquation.setVariable("totalworkers", 100); + DynamicPaymentEquation.setVariable("totaljobs", 10); + DynamicPaymentEquation.setVariable("jobstotalplayers", 10); + DynamicPaymentEquation.getValue(); + } catch (Exception e) { + Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "Dynamic payment equation has an invalid property. Disabling feature!"); + useDynamicPayment = false; + } + + DynamicPaymentMaxPenalty = getDouble("Economy.DynamicPayment.MaxPenalty", 25.0, config, writer); + DynamicPaymentMaxBonus = getDouble("Economy.DynamicPayment.MaxBonus", 100.0, config, writer); + + writer.addComment("Economy.EnabledJobsToglle", "Do you want to enable jobs toggle by default"); + JobsToggleEnabled = getBoolean("Economy.EnabledJobsToglle", true, config, writer); + + writer.addComment("Economy.UseServerAcount", "Server economy acount", "With this enabled, players will get money from defined user (server account)", "If this acount dont have enough money to pay for players for, player will get message"); + UseServerAccount = getBoolean("Economy.UseServerAcount", false, config, writer); + writer.addComment("Economy.AcountName", "Username should be with Correct capitalization"); + ServerAcountName = getString("Economy.AcountName", "Server", config, writer); + writer.addComment("Economy.Taxes.use", "Do you want to use taxes feature for jobs payment"); + UseTaxes = getBoolean("Economy.Taxes.use", false, config, writer); + writer.addComment("Economy.Taxes.AccountName", "Username should be with Correct capitalization, it can be same as settup in server account before"); + ServertaxesAcountName = getString("Economy.Taxes.AccountName", "Server", config, writer); + writer.addComment("Economy.Taxes.Amount", "Amount in percentage"); + TaxesAmount = getDouble("Economy.Taxes.Amount", 15.0, config, writer); + writer.addComment("Economy.Taxes.TransferToServerAccount", "Do you want to transfer taxes to server account"); + TransferToServerAccount = getBoolean("Economy.Taxes.TransferToServerAccount", true, config, writer); + writer.addComment("Economy.Taxes.TakeFromPlayersPayment", "With this true, taxes will be taken from players payment and he will get less money than its shown in jobs info", "When its false player will get full payment and server account will get taxes amount to hes account"); + TakeFromPlayersPayment = getBoolean("Economy.Taxes.TakeFromPlayersPayment", false, config, writer); + + writer.addComment("Economy.Limit.Money", "Money gain limit", "With this enabled, players will be limited how much they can make in defined time", "Time in seconds: 60 = 1min, 3600 = 1 hour, 86400 = 24 hours"); + EconomyLimitUse = getBoolean("Economy.Limit.Money.Use", false, config, writer); + writer.addComment("Economy.Limit.Money.StopWithExp", "Do you want to stop money gain when exp limit reached?"); + EconomyMoneyStop = getBoolean("Economy.Limit.Money.StopWithExp", false, config, writer); + EconomyLimitMoneyLimit = getInt("Economy.Limit.Money.MoneyLimit", 500, config, writer); + writer.addComment("Economy.Limit.Money.TimeLimit", "Time in seconds: 60 = 1min, 3600 = 1 hour, 86400 = 24 hours"); + EconomyLimitTimeLimit = getInt("Economy.Limit.Money.TimeLimit", 3600, config, writer); + writer.addComment("Economy.Limit.Money.AnnouncmentDelay", "Delay between announcements about reached money limit", "Keep this from 30 to 5 min (300), as players can get annoyed of constant message displaying"); + EconomyLimitAnnouncmentDelay = getInt("Economy.Limit.Money.AnnouncmentDelay", 30, config, writer); + + writer.addComment("Economy.Limit.Exp", "Exp gain limit", "With this enabled, players will be limited how much they can get in defined time", "Time in seconds: 60 = 1min, 3600 = 1 hour, 86400 = 24 hours"); + EconomyExpLimitUse = getBoolean("Economy.Limit.Exp.Use", false, config, writer); + writer.addComment("Economy.Limit.Exp.StopWithMoney", "Do you want to stop exp gain when money limit reached?"); + EconomyExpStop = getBoolean("Economy.Limit.Exp.StopWithMoney", false, config, writer); + EconomyExpLimit = getInt("Economy.Limit.Exp.Limit", 5000, config, writer); + writer.addComment("Economy.Limit.Exp.TimeLimit", "Time in seconds: 60 = 1min, 3600 = 1 hour, 86400 = 24 hours"); + EconomyExpTimeLimit = getInt("Economy.Limit.Exp.TimeLimit", 3600, config, writer); + writer.addComment("Economy.Limit.Exp.AnnouncmentDelay", "Delay between announcements about reached Exp limit", "Keep this from 30 to 5 min (300), as players can get annoyed of constant message displaying"); + EconomyLimitAnnouncmentExpDelay = getInt("Economy.Limit.Exp.AnnouncmentDelay", 30, config, writer); + + writer.addComment("Economy.Repair.PayForRenaming", "Do you want to give money for only renaming items in anvil", "Players will get full pay as they would for remairing two items when they only renaming one", "This is not big issue, but if you want to disable it, you can"); + PayForRenaming = getBoolean("Economy.Repair.PayForRenaming", true, config, writer); + + writer.addComment("Economy.Crafting.PayForEachCraft", "With this true, player will get money for all crafted items instead of each crafting action (like with old payment mechanic)", "By default its false, as you can make ALOT of money if prices kept from old payment mechanics"); + PayForEachCraft = getBoolean("Economy.Crafting.PayForEachCraft", false, config, writer); + + writer.addComment("Economy.MilkingCow.CancelMilking", "With this true, when timer is still going, cow milking event will be canceled", "With this false, player will get bucket of milk, but still no payment"); + CancelCowMilking = getBoolean("Economy.MilkingCow.CancelMilking", false, config, writer); + writer.addComment("Economy.MilkingCow.Timer", "How ofter player can milk cows in seconds. Keep in mind that by default player can milk cow indefinetly and as often as he wants", "Set to 0 if you want to disable timer"); + CowMilkingTimer = getInt("Economy.MilkingCow.Timer", 30, config, writer) * 1000; + + writer.addComment("ExploitProtections.Coreprotect.Use", "Requires to have CoreProtect plugin and there should be block place/break logging enabled in core protect config file.", "This will prevent players from abusing by placing and breaking blocks again and again", "This will work even after server restart"); + useCoreProtect = getBoolean("ExploitProtections.Coreprotect.Use", false, config, writer); + writer.addComment("ExploitProtections.Coreprotect.TimeLimit", "Time limit in minutes to protect blocks from repeating place/breake action.", "10080 equals to 7 days, keep it in reasonable time range"); + CoreProtectInterval = getInt("ExploitProtections.Coreprotect.TimeLimit", 604800, config, writer); + + writer.addComment("ExploitProtections.Coreprotect.BlockPlace.Use", "Do you want to use block place interval protection"); + BlockPlaceUse = getBoolean("ExploitProtections.Coreprotect.BlockPlace.Use", true, config, writer); + EnableAnounceMessage = getBoolean("ExploitProtections.Coreprotect.BlockPlace.EnableAnounceMessage", true, config, writer); + writer.addComment("ExploitProtections.Coreprotect.BlockPlace.Interval", "Time interval in seconds in how fast you can place block in same place.", "Keep it on low interval, 3-5 sec will be enough to prevent fast block place in same place and dont annoy peps", "Edit block list in restrictedBlocks.yml under PlacedBlockTimer"); + BlockPlaceInterval = getInt("ExploitProtections.Coreprotect.BlockPlace.Interval", 2, config, writer); + + writer.addComment("ExploitProtections.General.PlaceAndBreakProtection", "Enable blocks protection, like ore, from exploiting by placing and destroying same block again and again.", "This works only until server restart", "Modify restrictedBlocks.yml for blocks you want to protect"); + useBlockProtection = getBoolean("ExploitProtections.General.PlaceAndBreakProtection", true, config, writer); + + writer.addComment("ExploitProtections.General.SilkTouchProtection", "Enable silk touch protection.", "With this enabled players wont get paid for breaked blocks from restrictedblocks list with silk touch tool."); + useSilkTouchProtection = getBoolean("ExploitProtections.General.SilkTouchProtection", false, config, writer); + + writer.addComment("ExploitProtections.General.StopPistonBlockMove", "Enable piston moving blocks from restrictedblocks list.", "If piston moves block then it will be like new block and BlockPlaceAndBreakProtection wont work properly", "If you using core protect and its being logging piston block moving, then you can disable this"); + useBlockPiston = getBoolean("ExploitProtections.General.StopPistonBlockMove", true, config, writer); + + writer.addComment("ExploitProtections.General.BlocksTimer", "Enable blocks timer protection.", "Only enable if you want to protect block from beying broken to fast, useful for vegetables.", "Modify restrictedBlocks.yml for blocks you want to protect"); + useBlockTimer = getBoolean("ExploitProtections.General.BlocksTimer", true, config, writer); + + writer.addComment("ExploitProtections.General.GlobalBlockTimer", "All blocks will be protected X sec after player places it on ground."); + useGlobalTimer = getBoolean("ExploitProtections.General.GlobalBlockTimer.use", false, config, writer); + globalblocktimer = getInt("ExploitProtections.General.GlobalBlockTimer.timer", 30, config, writer); + + writer.addComment("ExploitProtections.General.PetPay", "Do you want to pay when players pet kills monster/player", "Can be exploited with mob farms", "0.2 means 20% of original reward", "Optionaly you can give jobs.petpay permission node for specific players/ranks to get paid by VipPetPay multiplier"); + PetPay = getDouble("ExploitProtections.General.PetPay", 0.1, config, writer); + VipPetPay = getDouble("ExploitProtections.General.VipPetPay", 1.0, config, writer); + + writer.addComment("ExploitProtections.McMMO", "McMMO abilities"); + writer.addComment("ExploitProtections.McMMO.TreeFellerMultiplier", "Players will get part of money from cutting trees with treefeller ability enabled.", "0.2 means 20% of original price"); + TreeFellerMultiplier = getDouble("ExploitProtections.McMMO.TreeFellerMultiplier", 0.2, config, writer); + + writer.addComment("use-breeder-finder", "Breeder finder.", "If you are not using breeding payment, you can disable this to save little resources. Really little."); + useBreederFinder = getBoolean("use-breeder-finder", true, config, writer); + + writer.addComment("boost", "Money exp boost with special permision.", "You will need to add special permision for groups or players to have money/exp boost.", "Use: jobs.boost.[jobname].money or jobs.boost.[jobname].exp or jobs.boost.[jobname].both for both of them with specific jobs name.", "Use: jobs.boost.all.money or jobs.boost.all.exp or jobs.boost.all.both to get boost for all jobs", "1.25 means that player will get 25% more than others, you can set less than 1 to get less from anothers"); + BoostExp = getDouble("boost.exp", 1.25, config, writer); + BoostMoney = getDouble("boost.money", 1.25, config, writer); + + writer.addComment("old-job", "Old job save", "Players can leave job and return later with some level loss during that", "You can fix players level if hes job level is at max level"); + levelLossPercentage = getInt("old-job.level-loss-percentage", 30, config, writer); + fixAtMaxLevel = getBoolean("old-job.fix-at-max-level", true, config, writer); + + writer.addComment("ActionBars", "Action bars", "You can enable/disable togglebale message by player with /jobs toggle"); + ToggleActionBar = getBoolean("ActionBars.Toggle", true, config, writer); + + writer.addComment("ShowActionBars", "You can enable/disable message shown for players in action bar"); + TitleChangeActionBar = getBoolean("ShowActionBars.OnTitleChange", true, config, writer); + LevelChangeActionBar = getBoolean("ShowActionBars.OnLevelChange", true, config, writer); + EmptyServerAcountActionBar = getBoolean("ShowActionBars.OnEmptyServerAcount", true, config, writer); + + writer.addComment("ShowChatMessage", "Chat messages", "You can enable/disable message shown for players in chat"); + TitleChangeChat = getBoolean("ShowChatMessage.OnTitleChange", true, config, writer); + LevelChangeChat = getBoolean("ShowChatMessage.OnLevelChange", true, config, writer); + EmptyServerAcountChat = getBoolean("ShowChatMessage.OnEmptyServerAcount", true, config, writer); + + writer.addComment("Sounds", "Sounds", "Extra sounds on some events", "All sounds can be found in https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Sound.html"); + SoundLevelupUse = getBoolean("Sounds.LevelUp.use", true, config, writer); + SoundLevelupSound = getString("Sounds.LevelUp.sound", "LEVEL_UP", config, writer); + SoundLevelupVolume = getInt("Sounds.LevelUp.volume", 1, config, writer); + SoundLevelupPitch = getInt("Sounds.LevelUp.pitch", 3, config, writer); + SoundTitleChangeUse = getBoolean("Sounds.TitleChange.use", true, config, writer); + SoundTitleChangeSound = getString("Sounds.TitleChange.sound", "LEVEL_UP", config, writer); + SoundTitleChangeVolume = getInt("Sounds.TitleChange.volume", 1, config, writer); + SoundTitleChangePitch = getInt("Sounds.TitleChange.pitch", 3, config, writer); + + writer.addComment("Signs", "You can disable this to save SMALL amount of server resources"); + SignsEnabled = getBoolean("Signs.Enable", true, config, writer); + SignsColorizeJobName = getBoolean("Signs.Colors.ColorizeJobName", true, config, writer); + writer.addComment("Signs.InfoUpdateInterval", "This is interval in sec in which signs will be updated. This is not continues update, signs are updated only on levelup, job leave, job join or similar action."); + writer.addComment("Signs.InfoUpdateInterval", "This is update for same job signs, to avoid huge lag if you have bunch of same type signs. Keep it from 1 to as many sec you want"); + InfoUpdateInterval = getInt("Signs.InfoUpdateInterval", 5, config, writer); + + writer.addComment("Scoreboard.ShowToplist", "This will enables to show top list in scoreboard instead of chat"); + ShowToplistInScoreboard = getBoolean("Scoreboard.ShowToplist", true, config, writer); + writer.addComment("Scoreboard.interval", "For how long to show scoreboard"); + ToplistInScoreboardInterval = getInt("Scoreboard.interval", 10, config, writer); + + writer.addComment("JobsBrowse.ShowTotalWorkers", "Do you want to show total amount of workers for job in jobs browse window"); + ShowTotalWorkers = getBoolean("JobsBrowse.ShowTotalWorkers", true, config, writer); + writer.addComment("JobsBrowse.ShowPenaltyBonus", "Do you want to show penalty and bonus in jobs browse window. Only works if this feature is enabled"); + ShowPenaltyBonus = getBoolean("JobsBrowse.ShowPenaltyBonus", true, config, writer); + + writer.addComment("Schedule.Boost.Enable", "Do you want to enable scheduler for global boost"); + useGlobalBoostScheduler = getBoolean("Schedule.Boost.Enable", false, config, writer); + + // writer.addComment("Gui.UseJobsBrowse", "Do you want to use jobs browse gui instead of chat text"); + // UseJobsBrowse = getBoolean("Gui.UseJobsBrowse", true, config, writer); + + // Write back config + try { + writer.save(f); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public synchronized void startMysql() { + File f = new File(plugin.getDataFolder(), "generalConfig.yml"); + YamlConfiguration config = YamlConfiguration.loadConfiguration(f); + String legacyUrl = config.getString("mysql-url"); + if (legacyUrl != null) { + String jdbcString = "jdbc:mysql://"; + if (legacyUrl.toLowerCase().startsWith(jdbcString)) { + legacyUrl = legacyUrl.substring(jdbcString.length()); + String[] parts = legacyUrl.split("/"); + if (parts.length >= 2) { + config.set("mysql-hostname", parts[0]); + config.set("mysql-database", parts[1]); + } + } + } + String username = config.getString("mysql-username"); + if (username == null) { + Jobs.getPluginLogger().severe("mysql-username property invalid or missing"); + } + String password = config.getString("mysql-password"); + String hostname = config.getString("mysql-hostname"); + String database = config.getString("mysql-database"); + String prefix = config.getString("mysql-table-prefix"); + if (plugin.isEnabled()) + Jobs.setDAO(JobsDAOMySQL.initialize(hostname, database, username, password, prefix)); + } + + public synchronized void startSqlite() { + Jobs.setDAO(JobsDAOSQLite.initialize()); + } + + public synchronized void copySetting(Configuration reader, Configuration writer, String path) { + writer.set(path, reader.get(path)); + } + + /** + * Method to load the title configuration + * + * loads from Jobs/titleConfig.yml + */ + private synchronized void loadTitleSettings() { + this.titles.clear(); + File f = new File(plugin.getDataFolder(), "titleConfig.yml"); + YamlConfiguration conf = YamlConfiguration.loadConfiguration(f); + StringBuilder header = new StringBuilder().append("Title configuration").append(System.getProperty("line.separator")).append(System.getProperty("line.separator")).append("Stores the titles people gain at certain levels.").append(System.getProperty("line.separator")).append("Each title requres to have a name, short name (used when the player has more than").append(System.getProperty("line.separator")).append("1 job) the colour of the title and the level requrirement to attain the title.").append(System.getProperty("line.separator")).append(System.getProperty("line.separator")).append("It is recommended but not required to have a title at level 0.").append(System.getProperty("line.separator")).append(System.getProperty("line.separator")).append("Titles are completely optional.").append(System.getProperty("line.separator")).append("Posible variable are {level} to add current jobs level.").append(System.getProperty("line.separator")).append(System.getProperty("line.separator")).append("Titles:").append(System.getProperty("line.separator")).append(" Apprentice:").append(System.getProperty("line.separator")).append(" Name: Apprentice").append(System.getProperty("line.separator")).append(" ShortName: A").append(System.getProperty("line.separator")).append(" ChatColour: WHITE").append(System.getProperty("line.separator")).append(" levelReq: 0").append(System.getProperty("line.separator")).append(" Novice:").append(System.getProperty("line.separator")).append(" Name: Novice").append(System.getProperty("line.separator")).append(" ShortName: N").append(System.getProperty("line.separator")).append(" ChatColour: GRAY").append(System.getProperty("line.separator")).append(" levelReq: 30").append(System.getProperty("line.separator")).append(" Journeyman:").append(System.getProperty("line.separator")).append(" Name: Journeyman").append(System.getProperty("line.separator")).append(" ShortName: J").append(System.getProperty("line.separator")).append(" ChatColour: GOLD").append(System.getProperty("line.separator")).append(" levelReq: 60").append(System.getProperty("line.separator")).append(" Master:").append(System.getProperty("line.separator")).append(" Name: Master").append(System.getProperty("line.separator")).append(" ShortName: '{level} M'").append(System.getProperty("line.separator")).append(" ChatColour: BLACK").append(System.getProperty("line.separator")).append(" levelReq: 90").append(System.getProperty("line.separator")).append(System.getProperty("line.separator")); + conf.options().header(header.toString()); + conf.options().copyDefaults(true); + conf.options().indent(2); + + ConfigurationSection titleSection = conf.getConfigurationSection("Titles"); + if (titleSection == null) { + titleSection = conf.createSection("Titles"); + } + for (String titleKey : titleSection.getKeys(false)) { + String jobName = null; + String titleName = titleSection.getString(titleKey + ".Name"); + String titleShortName = titleSection.getString(titleKey + ".ShortName"); + ChatColor titleColor = ChatColor.matchColor(titleSection.getString(titleKey + ".ChatColour", "")); + int levelReq = titleSection.getInt(titleKey + ".levelReq", -1); + + if (titleSection.isString(titleKey + ".JobName")) { + jobName = titleSection.getString(titleKey + ".JobName"); + } + + if (titleName == null) { + Jobs.getPluginLogger().severe("Title " + titleKey + " has an invalid Name property. Skipping!"); + continue; + } + + if (titleShortName == null) { + Jobs.getPluginLogger().severe("Title " + titleKey + " has an invalid ShortName property. Skipping!"); + continue; + } + if (titleColor == null) { + Jobs.getPluginLogger().severe("Title " + titleKey + "has an invalid ChatColour property. Skipping!"); + continue; + } + if (levelReq <= -1) { + Jobs.getPluginLogger().severe("Title " + titleKey + " has an invalid levelReq property. Skipping!"); + continue; + } + + this.titles.add(new Title(titleName, titleShortName, titleColor, levelReq, jobName)); + } + + try { + conf.save(f); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Method to load the restricted areas configuration + * + * loads from Jobs/restrictedAreas.yml + */ + private synchronized void loadRestrictedAreaSettings() { + this.restrictedAreas.clear(); + File f = new File(plugin.getDataFolder(), "restrictedAreas.yml"); + YamlConfiguration conf = YamlConfiguration.loadConfiguration(f); + conf.options().indent(2); + conf.options().copyDefaults(true); + StringBuilder header = new StringBuilder(); + + header.append("Restricted area configuration"); + header.append(System.getProperty("line.separator")).append(System.getProperty("line.separator")).append("Configures restricted areas where you cannot get experience or money").append(System.getProperty("line.separator")).append("when performing a job.").append(System.getProperty("line.separator")).append(System.getProperty("line.separator")).append("The multiplier changes the experience/money gains in an area.").append(System.getProperty("line.separator")).append("A multiplier of 0.0 means no money or xp, while 0.5 means you will get half the normal money/exp").append(System.getProperty("line.separator")).append(System.getProperty("line.separator")).append("restrictedareas:").append(System.getProperty("line.separator")).append(" area1:").append(System.getProperty("line.separator")).append(" world: 'world'").append(System.getProperty("line.separator")).append(" multiplier: 0.0").append(System.getProperty("line.separator")).append(" point1:").append(System.getProperty("line.separator")).append(" x: 125").append(System.getProperty("line.separator")).append(" y: 0").append(System.getProperty("line.separator")).append(" z: 125").append(System.getProperty("line.separator")).append(" point2:").append(System.getProperty("line.separator")).append(" x: 150").append(System.getProperty("line.separator")).append(" y: 100").append(System.getProperty("line.separator")).append(" z: 150").append(System.getProperty("line.separator")).append(" area2:").append(System.getProperty("line.separator")).append(" world: 'world_nether'").append(System.getProperty("line.separator")).append(" multiplier: 0.0").append(System.getProperty("line.separator")).append(" point1:").append(System.getProperty("line.separator")).append(" x: -100").append(System.getProperty("line.separator")).append(" y: 0").append(System.getProperty("line.separator")).append(" z: -100").append(System.getProperty("line.separator")).append(" point2:").append(System.getProperty("line.separator")).append(" x: -150").append(System.getProperty("line.separator")).append(" y: 100").append(System.getProperty("line.separator")).append(" z: -150"); + conf.options().header(header.toString()); + ConfigurationSection areaSection = conf.getConfigurationSection("restrictedareas"); + if (areaSection != null) { + for (String areaKey : areaSection.getKeys(false)) { + String worldName = conf.getString("restrictedareas." + areaKey + ".world"); + double multiplier = conf.getDouble("restrictedareas." + areaKey + ".multiplier", 0.0); + World world = Bukkit.getServer().getWorld(worldName); + if (world == null) + continue; + Location point1 = new Location(world, conf.getDouble("restrictedareas." + areaKey + ".point1.x", 0.0), conf.getDouble("restrictedareas." + areaKey + ".point1.y", 0.0), conf.getDouble("restrictedareas." + areaKey + ".point1.z", 0.0)); + + Location point2 = new Location(world, conf.getDouble("restrictedareas." + areaKey + ".point2.x", 0.0), conf.getDouble("restrictedareas." + areaKey + ".point2.y", 0.0), conf.getDouble("restrictedareas." + areaKey + ".point2.z", 0.0)); + this.restrictedAreas.add(new RestrictedArea(point1, point2, multiplier)); + } + } + try { + conf.save(f); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Method to load the restricted areas configuration + * + * loads from Jobs/restrictedAreas.yml + */ + private synchronized void loadRestrictedBlocks() { + File f = new File(plugin.getDataFolder(), "restrictedBlocks.yml"); + YamlConfiguration config = YamlConfiguration.loadConfiguration(f); + + CommentedYamlConfiguration writer = new CommentedYamlConfiguration(); + + config.options().copyDefaults(true); + + writer.addComment("restrictedblocks", "All block to be protected from place/break exploit.", "This will prevent piston moving all blocks in list", "Dont count in vegetables or any single click break blocks"); + restrictedBlocks.add("14"); + restrictedBlocks.add("15"); + restrictedBlocks.add("16"); + restrictedBlocks.add("21"); + restrictedBlocks.add("48"); + restrictedBlocks.add("56"); + restrictedBlocks.add("73"); + restrictedBlocks.add("74"); + restrictedBlocks.add("129"); + restrictedBlocks.add("153"); + config.addDefault("restrictedblocks", restrictedBlocks); + restrictedBlocks = (ArrayList<String>) config.getStringList("restrictedblocks"); + copySetting(config, writer, "restrictedblocks"); + + writer.addComment("blockstimer", "Block protected by timer in sec", "141-60 means that carrot can be harvested after 60 sec (remember to use id's from placed objects, not from your inventory)"); + restrictedBlocksTimer.add("2-60"); + restrictedBlocksTimer.add("3-60"); + restrictedBlocksTimer.add("6-60"); + restrictedBlocksTimer.add("12-60"); + restrictedBlocksTimer.add("18-60"); + restrictedBlocksTimer.add("31-60"); + restrictedBlocksTimer.add("32-60"); + restrictedBlocksTimer.add("37-60"); + restrictedBlocksTimer.add("38-60"); + restrictedBlocksTimer.add("39-60"); + restrictedBlocksTimer.add("40-60"); + restrictedBlocksTimer.add("55-60"); + restrictedBlocksTimer.add("59-60"); + restrictedBlocksTimer.add("80-60"); + restrictedBlocksTimer.add("81-60"); + restrictedBlocksTimer.add("83-60"); + restrictedBlocksTimer.add("103-60"); + restrictedBlocksTimer.add("106-60"); + restrictedBlocksTimer.add("111-60"); + restrictedBlocksTimer.add("141-60"); + restrictedBlocksTimer.add("142-60"); + restrictedBlocksTimer.add("161-60"); + restrictedBlocksTimer.add("171-60"); + restrictedBlocksTimer.add("175-60"); + config.addDefault("blockstimer", restrictedBlocksTimer); + restrictedBlocksTimer = (ArrayList<String>) config.getStringList("blockstimer"); + copySetting(config, writer, "blockstimer"); + + writer.addComment("PlacedBlockTimer", "Block place protected by timer in sec", "For this to work CoreProtect plugin should be installed"); + restrictedPlaceBlocksTimer.add(2); + restrictedPlaceBlocksTimer.add(3); + restrictedPlaceBlocksTimer.add(6); + restrictedPlaceBlocksTimer.add(12); + restrictedPlaceBlocksTimer.add(18); + restrictedPlaceBlocksTimer.add(31); + restrictedPlaceBlocksTimer.add(32); + restrictedPlaceBlocksTimer.add(37); + restrictedPlaceBlocksTimer.add(38); + restrictedPlaceBlocksTimer.add(39); + restrictedPlaceBlocksTimer.add(40); + restrictedPlaceBlocksTimer.add(55); + restrictedPlaceBlocksTimer.add(59); + restrictedPlaceBlocksTimer.add(80); + restrictedPlaceBlocksTimer.add(81); + restrictedPlaceBlocksTimer.add(83); + restrictedPlaceBlocksTimer.add(103); + restrictedPlaceBlocksTimer.add(106); + restrictedPlaceBlocksTimer.add(111); + restrictedPlaceBlocksTimer.add(141); + restrictedPlaceBlocksTimer.add(142); + restrictedPlaceBlocksTimer.add(161); + restrictedPlaceBlocksTimer.add(171); + restrictedPlaceBlocksTimer.add(175); + config.addDefault("PlacedBlockTimer", restrictedPlaceBlocksTimer); + restrictedPlaceBlocksTimer = (ArrayList<Integer>) config.getIntegerList("PlacedBlockTimer"); + copySetting(config, writer, "PlacedBlockTimer"); + + try { + writer.save(f); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Method to load the scheduler configuration + * + * loads from Jobs/schedule.yml + */ + public void loadScheduler() { + File f = new File(plugin.getDataFolder(), "schedule.yml"); + YamlConfiguration conf = YamlConfiguration.loadConfiguration(f); + + conf.options().copyDefaults(true); + + if (!conf.contains("Boost")) + return; + + ArrayList<String> sections = new ArrayList<String>(conf.getConfigurationSection("Boost").getKeys(false)); + + for (String OneSection : sections) { + ConfigurationSection path = conf.getConfigurationSection("Boost." + OneSection); + + if (!path.contains("Enabled")) + continue; + + if (!conf.getConfigurationSection("Boost." + OneSection).getBoolean("Enabled")) + continue; + + Schedule sched = new Schedule(); + sched.setName(OneSection); + + if (!path.contains("From") || !path.getString("From").contains(":")) + continue; + + if (!path.contains("Until") || !path.getString("Until").contains(":")) + continue; + + if (!path.contains("Days") || !path.isList("Days")) + continue; + + if (!path.contains("Jobs") || !path.isList("Jobs")) + continue; + + if (!path.contains("Exp") || !path.isDouble("Exp")) + continue; + + if (!path.contains("Money") || !path.isDouble("Money")) + continue; + + if (path.contains("MessageOnStart") && path.isList("MessageOnStart")) + sched.setMessageOnStart(path.getStringList("MessageOnStart")); + + if (path.contains("BroadcastOnStart")) + sched.setBroadcastOnStart(path.getBoolean("BroadcastOnStart")); + + if (path.contains("MessageOnStop") && path.isList("MessageOnStop")) + sched.setMessageOnStop(path.getStringList("MessageOnStop")); + + if (path.contains("BroadcastOnStop")) + sched.setBroadcastOnStop(path.getBoolean("BroadcastOnStop")); + + sched.setDays(path.getStringList("Days")); + sched.setJobs(path.getStringList("Jobs")); + sched.setFrom(Integer.valueOf(path.getString("From").replace(":", ""))); + sched.setUntil(Integer.valueOf(path.getString("Until").replace(":", ""))); + + sched.setExpBoost(path.getDouble("Exp")); + sched.setMoneyBoost(path.getDouble("Money")); + + BoostSchedule.add(sched); + } + +// try { +// conf.save(f); +// } catch (IOException e) { +// e.printStackTrace(); +// } + } + + private Boolean getBoolean(String path, Boolean boo, YamlConfiguration config, CommentedYamlConfiguration writer) { + config.addDefault(path, boo); + copySetting(config, writer, path); + return config.getBoolean(path); + } + + private int getInt(String path, int boo, YamlConfiguration config, CommentedYamlConfiguration writer) { + config.addDefault(path, boo); + copySetting(config, writer, path); + return config.getInt(path); + } + + private List<Integer> getIntArray(String path, List<Integer> boo, YamlConfiguration config, CommentedYamlConfiguration writer) { + config.addDefault(path, boo); + copySetting(config, writer, path); + return config.getIntegerList(path); + } + + private String getString(String path, String boo, YamlConfiguration config, CommentedYamlConfiguration writer) { + config.addDefault(path, boo); + copySetting(config, writer, path); + return config.getString(path); + } + + private Double getDouble(String path, Double boo, YamlConfiguration config, CommentedYamlConfiguration writer) { + config.addDefault(path, boo); + copySetting(config, writer, path); + return config.getDouble(path); + } + + private synchronized void loadItemList() { + YmlMaker ItemFile = new YmlMaker((JavaPlugin) JobsPlugin.instance, "ItemList.yml"); + ItemFile.saveDefaultConfig(); + List<String> section = ItemFile.getConfig().getStringList("ItemList"); + ListOfNames.clear(); + for (String one : section) { + if (!one.contains(" - ")) + continue; + + if (!one.contains(" = ")) + continue; + + String meta = ""; + String id = one.split(" - ")[0]; + String part2 = one.split(" - ")[1]; + String part3 = ""; + + part3 = part2.split(" = ")[1]; + part2 = part2.split(" = ")[0]; + + if (id.contains(":")) { + meta = id.split(":")[1]; + id = id.split(":")[0]; + } + + ListOfNames.add(new NameList(id, meta, part2, part3)); + } + + section = ItemFile.getConfig().getStringList("EntityList"); + ListOfEntities.clear(); + for (String one : section) { + if (!one.contains(" - ")) + continue; + + if (!one.contains(" = ")) + continue; + + String meta = ""; + String id = one.split(" - ")[0]; + String part2 = one.split(" - ")[1]; + String part3 = ""; + + part3 = part2.split(" = ")[1]; + part2 = part2.split(" = ")[0]; + + if (id.contains(":")) { + meta = id.split(":")[1]; + id = id.split(":")[0]; + } + + ListOfEntities.add(new NameList(id, meta, part2, part3)); + } + + section = ItemFile.getConfig().getStringList("EnchantList"); + ListOfEnchants.clear(); + for (String one : section) { + if (!one.contains(" - ")) + continue; + + if (!one.contains(" = ")) + continue; + + String id = one.split(" - ")[0]; + String part2 = one.split(" - ")[1]; + String part3 = ""; + + part3 = part2.split(" = ")[1]; + part2 = part2.split(" = ")[0]; + + ListOfEnchants.add(new NameList(id, "", part2, part3)); + } + + section = ItemFile.getConfig().getStringList("ColorList"); + ListOfColors.clear(); + for (String one : section) { + if (!one.contains(" - ")) + continue; + + if (!one.contains(" = ")) + continue; + + String id = one.split(" - ")[0]; + String part2 = one.split(" - ")[1]; + String part3 = ""; + + part3 = part2.split(" = ")[1]; + part2 = part2.split(" = ")[0]; + + ListOfColors.add(new NameList(id, "", part2, part3)); + } + + } + + /** + * Method to load the language file configuration + * + * loads from Jobs/locale/messages_en.yml + */ + private synchronized void loadLanguage() { + + // Just copying default language files, except en, that one will be generated + List<String> languages = new ArrayList<String>(); + languages.add("lt"); + languages.add("de"); + languages.add("cs"); + languages.add("fr"); + languages.add("ru"); + + for (String lang : languages) { + YmlMaker langFile = new YmlMaker((JavaPlugin) JobsPlugin.instance, "locale" + File.separator + "messages_" + lang + ".yml"); + if (langFile != null) + langFile.saveDefaultConfig(); + } + + languages.clear(); + languages.add("en"); + + File customLocaleFile = new File(plugin.getDataFolder(), "locale" + File.separator + "messages_" + localeString + ".yml"); + if (!customLocaleFile.exists() && !localeString.equalsIgnoreCase("en")) + languages.add(localeString); + + for (String lang : languages) { + + File f = new File(plugin.getDataFolder(), "locale" + File.separator + "messages_" + lang + ".yml"); + YamlConfiguration conf = YamlConfiguration.loadConfiguration(f); + + CommentedYamlConfiguration writer = new CommentedYamlConfiguration(); + + conf.options().copyDefaults(true); + + GetConfigString("economy.error.nomoney", "Sorry, no money left in national bank!", writer, conf, true); + + GetConfigString("command.moneyboost.help.info", "Boosts Money gain for all players", writer, conf, true); + GetConfigString("command.moneyboost.help.args", "[jobname] [rate]", writer, conf, true); + GetConfigString("command.moneyboost.output.allreset", "All money boost turned off", writer, conf, true); + GetConfigString("command.moneyboost.output.jobsboostreset", "Money boost for %jobname% was turned off", writer, conf, true); + GetConfigString("command.moneyboost.output.nothingtoreset", "Nothing to reset", writer, conf, true); + GetConfigString("command.moneyboost.output.boostalladded", "Money boost of %boost% added for all jobs!", writer, conf, true); + GetConfigString("command.moneyboost.output.boostadded", "Money boost of &e%boost% &aadded for &e%jobname%!", writer, conf, true); + GetConfigString("command.moneyboost.output.infostats", "&c-----> &aMoney rate x%boost% enabled&c <-------", writer, conf, true); + + GetConfigString("command.expboost.help.info", "Boosts Exp gain for all players", writer, conf, true); + GetConfigString("command.expboost.help.args", "[jobname] [rate]", writer, conf, true); + GetConfigString("command.expboost.output.allreset", "All exp boost turned off", writer, conf, true); + GetConfigString("command.expboost.output.jobsboostreset", "Exp boost for %jobname% was turned off", writer, conf, true); + GetConfigString("command.expboost.output.nothingtoreset", "Nothing to reset", writer, conf, true); + GetConfigString("command.expboost.output.boostalladded", "Exp boost of %boost% added for all jobs!", writer, conf, true); + GetConfigString("command.expboost.output.boostadded", "Exp boost of &e%boost% &aadded for &e%jobname%!", writer, conf, true); + GetConfigString("command.expboost.output.infostats", "&c-----> &aExp rate x%boost% enabled&c <-------", writer, conf, true); + + GetConfigString("command.convert.help.info", "Converts data base system from one system to another. if you currently running sqlite, this will convert to Mysql and vise versa.", writer, conf, true); + GetConfigString("command.convert.help.args", "", writer, conf, true); + + GetConfigString("command.limit.help.info", "Shows payment limits for jobs", writer, conf, true); + GetConfigString("command.limit.help.args", "", writer, conf, true); + + GetConfigString("command.limit.output.lefttime", "&eTime left until money limit resets: &2%hour% &ehour &2%min% &emin &2%sec% &esec", writer, conf, true); + GetConfigString("command.limit.output.moneylimit", "&eMoney limit: &2%money%&e/&2%totalmoney%", writer, conf, true); + GetConfigString("command.limit.output.leftexptime", "&eTime left until Exp limit resets: &2%hour% &ehour &2%min% &emin &2%sec% &esec", writer, conf, true); + GetConfigString("command.limit.output.explimit", "&eExp limit: &2%exp%&e/&2%totalexp%", writer, conf, true); + + GetConfigString("command.limit.output.reachedlimit", "&4You have reached money limit in given time!", writer, conf, true); + GetConfigString("command.limit.output.reachedlimit2", "&eYou can check your limit with &2/jobs limit &ecommand", writer, conf, true); + GetConfigString("command.limit.output.reachedExplimit", "&4You have reached exp limit in given time!", writer, conf, true); + GetConfigString("command.limit.output.reachedExplimit2", "&eYou can check your limit with &2/jobs limit &ecommand", writer, conf, true); + + GetConfigString("command.limit.output.notenabled", "&eMoney limit is not enabled", writer, conf, true); + + GetConfigString("command.admin.error", "There was an error in the command.", writer, conf, true); + GetConfigString("command.admin.success", "Your command has been performed.", writer, conf, true); + + GetConfigString("command.error.notNumber", "&ePlease use numbers!", writer, conf, true); + GetConfigString("command.error.job", "The job you have selected does not exist!", writer, conf, true); + GetConfigString("command.error.permission", "You do not have permission to do that!", writer, conf, true); + + GetConfigString("command.help.output.info", "Type /jobs [cmd] ? for more information about a command.", writer, conf, true); + GetConfigString("command.help.output.usage", "Usage: %usage%", writer, conf, true); + + GetConfigString("command.stats.help.info", "Show the level you are in each job you are part of.", writer, conf, true); + GetConfigString("command.stats.help.args", "[playername]", writer, conf, true); + GetConfigString("command.stats.error.nojob", "Please join a job first.", writer, conf, true); + GetConfigString("command.stats.output", "lvl%joblevel% %jobname% : %jobxp%/%jobmaxxp% xp", writer, conf, true); + + GetConfigString("command.archive.help.info", "Shows all jobs saved in archive by user.", writer, conf, true); + GetConfigString("command.archive.help.args", "[playername]", writer, conf, true); + GetConfigString("command.archive.error.nojob", "There is no jobs saved.", writer, conf, true); + GetConfigString("command.archive.output", "lvl %joblevel% (%getbackjoblevel%) %jobname%", writer, conf, true); + + GetConfigString("command.give.help.info", "Gives item by jobs name and item category name. Player name is optional", writer, conf, true); + GetConfigString("command.give.help.args", "[playername] [jobname] [itemname]", writer, conf, true); + GetConfigString("command.give.output.notonline", "&4Player [%playername%] is not online!", writer, conf, true); + GetConfigString("command.give.output.noitem", "&4Cant find any item by given name!", writer, conf, true); + + GetConfigString("command.info.help.title", "&2*** &eJobs&2 ***", writer, conf, true); + GetConfigString("command.info.help.info", "Show how much each job is getting paid and for what.", writer, conf, true); + GetConfigString("command.info.help.penalty", "&eThis job have &c[penalty]% &epenalty because of too many players working in it.", writer, conf, true); + GetConfigString("command.info.help.bonus", "&eThis job have &2[bonus]% &ebonus because not enough players working in it.", writer, conf, true); + GetConfigString("command.info.help.args", "[jobname] [action]", writer, conf, true); + GetConfigString("command.info.help.actions", "&eValid actions are: &f%actions%", writer, conf, true); + GetConfigString("command.info.help.max", " - &emax level:&f ", writer, conf, true); + GetConfigString("command.info.help.material", "&7%material%", writer, conf, true); + GetConfigString("command.info.output.break.info", "Break", writer, conf, true); + GetConfigString("command.info.output.break.none", "%jobname% does not get money for breaking blocks.", writer, conf, true); + GetConfigString("command.info.output.place.info", "Place", writer, conf, true); + GetConfigString("command.info.output.place.none", "%jobname% does not get money for placing blocks.", writer, conf, true); + GetConfigString("command.info.output.kill.info", "Kill", writer, conf, true); + GetConfigString("command.info.output.kill.none", "%jobname% does not get money for killing monsters.", writer, conf, true); + GetConfigString("command.info.output.fish.info", "Fish", writer, conf, true); + GetConfigString("command.info.output.fish.none", "%jobname% does not get money from fishing.", writer, conf, true); + GetConfigString("command.info.output.craft.info", "Craft", writer, conf, true); + GetConfigString("command.info.output.craft.none", "%jobname% does not get money from crafting.", writer, conf, true); + GetConfigString("command.info.output.smelt.info", "Smelt", writer, conf, true); + GetConfigString("command.info.output.smelt.none", "%jobname% does not get money from smelting.", writer, conf, true); + GetConfigString("command.info.output.brew.info", "Brew", writer, conf, true); + GetConfigString("command.info.output.brew.none", "%jobname% does not get money from brewing.", writer, conf, true); + GetConfigString("command.info.output.enchant.info", "Enchant", writer, conf, true); + GetConfigString("command.info.output.enchant.none", "%jobname% does not get money from enchanting.", writer, conf, true); + GetConfigString("command.info.output.repair.info", "Repair", writer, conf, true); + GetConfigString("command.info.output.repair.none", "%jobname% does not get money from repairing.", writer, conf, true); + GetConfigString("command.info.output.breed.info", "Breed", writer, conf, true); + GetConfigString("command.info.output.breed.none", "%jobname% does not get money from breeding.", writer, conf, true); + GetConfigString("command.info.output.tame.info", "Tame", writer, conf, true); + GetConfigString("command.info.output.tame.none", "%jobname% does not get money from taming.", writer, conf, true); + GetConfigString("command.info.output.milk.info", "Milk", writer, conf, true); + GetConfigString("command.info.output.milk.none", "%jobname% does not get money from milking cows.", writer, conf, true); + GetConfigString("command.info.output.shear.info", "Shear", writer, conf, true); + GetConfigString("command.info.output.shear.none", "%jobname% does not get money from shearing sheeps.", writer, conf, true); + GetConfigString("command.info.output.custom-kill.info", "Custom kill", writer, conf, true); + GetConfigString("command.info.output.custom-kill.none", "%jobname% does not get money from custom player kills.", writer, conf, true); + + GetConfigString("command.playerinfo.help.info", "Show how much each job is getting paid and for what on another player.", writer, conf, true); + GetConfigString("command.playerinfo.help.args", "[playername] [jobname] [action]", writer, conf, true); + + GetConfigString("command.join.help.info", "Join the selected job.", writer, conf, true); + GetConfigString("command.join.help.args", "[jobname]", writer, conf, true); + GetConfigString("command.join.error.alreadyin", "You are already in the job %jobname%.", writer, conf, true); + GetConfigString("command.join.error.fullslots", "You cannot join the job %jobname%, there are no slots available.", writer, conf, true); + GetConfigString("command.join.error.maxjobs", "You have already joined too many jobs.", writer, conf, true); + GetConfigString("command.join.success", "You have joined the job %jobname%.", writer, conf, true); + + GetConfigString("command.leave.help.info", "Leave the selected job.", writer, conf, true); + GetConfigString("command.leave.help.args", "[jobname]", writer, conf, true); + GetConfigString("command.leave.success", "You have left the job %jobname%.", writer, conf, true); + + GetConfigString("command.leaveall.help.info", "Leave all your jobs.", writer, conf, true); + GetConfigString("command.leaveall.error.nojobs", "You do not have any jobs to leave!", writer, conf, true); + GetConfigString("command.leaveall.success", "You have left all your jobs.", writer, conf, true); + + GetConfigString("command.browse.help.info", "List the jobs available to you.", writer, conf, true); + GetConfigString("command.browse.error.nojobs", "There are no jobs you can join.", writer, conf, true); + GetConfigString("command.browse.output.header", "You are allowed to join the following jobs:", writer, conf, true); + GetConfigString("command.browse.output.footer", "For more information type in /jobs info [JobName]", writer, conf, true); + GetConfigString("command.browse.output.totalWorkers", " &7Workers: &e[amount]", writer, conf, true); + GetConfigString("command.browse.output.penalty", " &4Penalty: &c[amount]%", writer, conf, true); + GetConfigString("command.browse.output.bonus", " &2Bonus: &a[amount]%", writer, conf, true); + + GetConfigString("command.fire.help.info", "Fire the player from the job.", writer, conf, true); + GetConfigString("command.fire.help.args", "[playername] [jobname]", writer, conf, true); + GetConfigString("command.fire.error.nojob", "Player does not have the job %jobname%.", writer, conf, true); + GetConfigString("command.fire.output.target", "You have been fired from %jobname%.", writer, conf, true); + + GetConfigString("command.fireall.help.info", "Fire player from all their jobs.", writer, conf, true); + GetConfigString("command.fireall.help.args", "[playername]", writer, conf, true); + GetConfigString("command.fireall.error.nojobs", "Player does not have any jobs to be fired from!", writer, conf, true); + GetConfigString("command.fireall.output.target", "You have been fired from all your jobs.", writer, conf, true); + + GetConfigString("command.employ.help.info", "Employ the player to the job.", writer, conf, true); + GetConfigString("command.employ.help.args", "[playername] [jobname]", writer, conf, true); + GetConfigString("command.employ.error.alreadyin", "Player is already in the job %jobname%.", writer, conf, true); + GetConfigString("command.employ.output.target", "You have been employed as a %jobname%.", writer, conf, true); + + GetConfigString("command.top.help.info", "Shows top 15 players by jobs name.", writer, conf, true); + GetConfigString("command.top.help.args", "[jobname]", writer, conf, true); + GetConfigString("command.top.error.nojob", "Cant find any job with this name.", writer, conf, true); + GetConfigString("command.top.output.topline", "&aTop&e 15 &aplayers by &e%jobname% &ajob", writer, conf, true); + GetConfigString("command.top.output.list", "&e%number%&a. &e%playername% &alvl &e%level% &awith&e %exp% &aexp", writer, conf, true); + GetConfigString("command.top.output.prev", "&e<<<<< Prev page &2|", writer, conf, true); + GetConfigString("command.top.output.next", "&2|&e Next Page >>>>", writer, conf, true); + GetConfigString("command.top.output.show", "&2Show from &e[from] &2until &e[until] &2top list", writer, conf, true); + + GetConfigString("command.gtop.help.info", "Shows top 15 players by global jobs level.", writer, conf, true); + GetConfigString("command.gtop.help.args", "", writer, conf, true); + GetConfigString("command.gtop.error.nojob", "Cant find any information.", writer, conf, true); + GetConfigString("command.gtop.output.topline", "&aTop&e 15 &aplayers by global job level", writer, conf, true); + GetConfigString("command.gtop.output.list", "&e%number%&a. &e%playername% &alvl &e%level% &awith&e %exp% &aexp", writer, conf, true); + GetConfigString("command.gtop.output.prev", "&e<<<<< Prev page &2|", writer, conf, true); + GetConfigString("command.gtop.output.next", "&2|&e Next Page >>>>", writer, conf, true); + GetConfigString("command.gtop.output.show", "&2Show from &e[from] &2until &e[until] &2global top list", writer, conf, true); + + GetConfigString("command.transfer.help.info", "Transfer a player's job from an old job to a new job.", writer, conf, true); + GetConfigString("command.transfer.help.args", "[playername] [oldjob] [newjob]", writer, conf, true); + GetConfigString("command.transfer.output.target", "You have been transferred from %oldjobname% to %newjobname%.", writer, conf, true); + + GetConfigString("command.promote.help.info", "Promote the player X levels in a job.", writer, conf, true); + GetConfigString("command.promote.help.args", "[playername] [jobname] [levels]", writer, conf, true); + GetConfigString("command.promote.output.target", "You have been promoted %levelsgained% levels in %jobname%.", writer, conf, true); + + GetConfigString("command.demote.help.info", "Demote the player X levels in a job.", writer, conf, true); + GetConfigString("command.demote.help.args", "[playername] [jobname] [levels]", writer, conf, true); + GetConfigString("command.demote.output.target", "You have been demoted %levelslost% levels in %jobname%.", writer, conf, true); + + GetConfigString("command.grantxp.help.info", "Grant the player X experience in a job.", writer, conf, true); + GetConfigString("command.grantxp.help.args", "[playername] [jobname] [xp]", writer, conf, true); + GetConfigString("command.grantxp.output.target", "You have been granted %xpgained% experience in %jobname%.", writer, conf, true); + + GetConfigString("command.removexp.help.info", "Remove X experience from the player in a job.", writer, conf, true); + GetConfigString("command.removexp.help.args", "[playername] [jobname] [xp]", writer, conf, true); + GetConfigString("command.removexp.output.target", "You have lost %xplost% experience in %jobname%.", writer, conf, true); + + GetConfigString("command.signupdate.help.info", "Manualy updates sign by its name", writer, conf, true); + GetConfigString("command.signupdate.help.args", "[jobname]", writer, conf, true); + + GetConfigString("command.reload.help.info", "Reload configurations.", writer, conf, true); + + GetConfigString("message.skillup.broadcast", "%playername% has been promoted to a %titlename% %jobname%.", writer, conf, true); + GetConfigString("message.skillup.nobroadcast", "Congratulations, you have been promoted to a %titlename% %jobname%.", writer, conf, true); + + GetConfigString("message.levelup.broadcast", "%playername% is now a level %joblevel% %jobname%.", writer, conf, true); + GetConfigString("message.levelup.nobroadcast", "You are now a level %joblevel% %jobname%.", writer, conf, true); + + GetConfigString("message.cowtimer", "&eYou still need to wait &6%time% &esec to get paid for this job.", writer, conf, true); + GetConfigString("message.blocktimer", "&eYou need to wait: &3[time] &esec more to get paid for this!", writer, conf, true); + GetConfigString("message.placeblocktimer", "&eYou cant place block faster than &6[time] &esec interval in same place!", writer, conf, true); + GetConfigString("message.taxes", "&3[amount] &eserver taxes where transfered to this account", writer, conf, true); + + GetConfigString("message.boostStarted", "&eJobs boost time have been started!", writer, conf, true); + GetConfigString("message.boostStoped", "&eJobs boost time have been ended!", writer, conf, true); + + GetConfigString("command.toggle.help.info", "Toggles payment output on action bar.", writer, conf, true); + GetConfigString("command.toggle.output.turnedoff", "&4This feature are turned off!", writer, conf, true); + GetConfigString("command.toggle.output.paid", "&aYou got paid for &2[amount]&a and got &2[exp] &aexp", writer, conf, true); + GetConfigString("command.toggle.output.on", "&aToggled: &aON", writer, conf, true); + GetConfigString("command.toggle.output.off", "&aToggled: &4OFF", writer, conf, true); + + GetConfigString("message.crafting.fullinventory", "Your inventory is full!", writer, conf, true); + + GetConfigString("signs.List", "&0[number].&8[player]&7:&4[level]", writer, conf, true); + GetConfigString("signs.SpecialList.1.1", "&b** &8First &b**", writer, conf, true); + GetConfigString("signs.SpecialList.1.2", "&9[player]", writer, conf, true); + GetConfigString("signs.SpecialList.1.3", "&8[level] level", writer, conf, true); + GetConfigString("signs.SpecialList.1.4", "&b************", writer, conf, true); + GetConfigString("signs.SpecialList.2.1", "&b** &8Second &b**", writer, conf, true); + GetConfigString("signs.SpecialList.2.2", "&9[player]", writer, conf, true); + GetConfigString("signs.SpecialList.2.3", "&8[level] level", writer, conf, true); + GetConfigString("signs.SpecialList.2.4", "&b************", writer, conf, true); + GetConfigString("signs.SpecialList.3.1", "&b** &8Third &b**", writer, conf, true); + GetConfigString("signs.SpecialList.3.2", "&9[player]", writer, conf, true); + GetConfigString("signs.SpecialList.3.3", "&8[level] level", writer, conf, true); + GetConfigString("signs.SpecialList.3.4", "&b************", writer, conf, true); + GetConfigString("signs.cantcreate", "&4You can't create this sign!", writer, conf, true); + GetConfigString("signs.topline", "&2[Jobs]", writer, conf, true); + GetConfigString("signs.secondline.join", "&2Join", writer, conf, true); + GetConfigString("signs.secondline.leave", "&4Leave", writer, conf, true); + GetConfigString("signs.secondline.toggle", "&2Toggle", writer, conf, true); + GetConfigString("signs.secondline.top", "&2Top", writer, conf, true); + GetConfigString("signs.secondline.browse", "&2Browse", writer, conf, true); + GetConfigString("signs.secondline.stats", "&2Stats", writer, conf, true); + GetConfigString("signs.secondline.limit", "&2Limit", writer, conf, true); + GetConfigString("signs.secondline.info", "&2Info", writer, conf, true); + GetConfigString("signs.secondline.archive", "&2Archive", writer, conf, true); + + //GetConfigString("scoreboard.clear", "&eIf you want to remove scoreboard, type &2/jobs top clear", writer, conf, true); + GetConfigString("scoreboard.topline", "&2Top &e%jobname%", writer, conf, true); + GetConfigString("scoreboard.gtopline", "&2Global top list", writer, conf, true); + GetConfigString("scoreboard.lines", "&2%number%. &e%playername%", writer, conf, true); + + keys = new ArrayList<String>(conf.getConfigurationSection("signs.secondline").getKeys(false)); + + // Write back config + try { + writer.save(f); + } catch (IOException e) { + e.printStackTrace(); + } + } + } +} diff --git a/com/gamingmesh/jobs/config/YmlMaker.java b/com/gamingmesh/jobs/config/YmlMaker.java new file mode 100644 index 00000000..83dcbdde --- /dev/null +++ b/com/gamingmesh/jobs/config/YmlMaker.java @@ -0,0 +1,92 @@ +package com.gamingmesh.jobs.config; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.util.logging.Level; + +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.java.JavaPlugin; + +import com.gamingmesh.jobs.JobsPlugin; + +public class YmlMaker +{ + JobsPlugin Plugin; + public String fileName; + private JavaPlugin plugin; + public File ConfigFile; + private FileConfiguration Configuration; + + public YmlMaker(JobsPlugin Plugin) + { + this.Plugin = Plugin; + } + + public YmlMaker(JavaPlugin plugin, String fileName) + { + if (plugin == null) { + throw new IllegalArgumentException("plugin cannot be null"); + } + this.plugin = plugin; + this.fileName = fileName; + File dataFolder = plugin.getDataFolder(); + if (dataFolder == null) { + throw new IllegalStateException(); + } + this.ConfigFile = new File(dataFolder.toString() + File.separatorChar + this.fileName); + } + + public void reloadConfig() + { + try { + this.Configuration = YamlConfiguration.loadConfiguration(new InputStreamReader(new FileInputStream(this.ConfigFile), "UTF-8")); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + InputStream defConfigStream = this.plugin.getResource(this.fileName); + if (defConfigStream != null) + { + @SuppressWarnings("deprecation") + YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream); + this.Configuration.setDefaults(defConfig); + } + } + + public FileConfiguration getConfig() + { + if (this.Configuration == null) { + reloadConfig(); + } + return this.Configuration; + } + + public void saveConfig() + { + if ((this.Configuration == null) || (this.ConfigFile == null)) { + return; + } + try + { + getConfig().save(this.ConfigFile); + } catch (IOException ex) + { + this.plugin.getLogger().log(Level.SEVERE, "Could not save config to " + this.ConfigFile, ex); + } + } + + public void saveDefaultConfig() + { + if (!this.ConfigFile.exists()) { + this.plugin.saveResource(this.fileName, false); + } + } +} diff --git a/com/gamingmesh/jobs/container/.gitignore b/com/gamingmesh/jobs/container/.gitignore new file mode 100644 index 00000000..def6e515 --- /dev/null +++ b/com/gamingmesh/jobs/container/.gitignore @@ -0,0 +1,20 @@ +/ActionInfo.class +/ActionType.class +/BaseActionInfo.class +/DisplayMethod.class +/Job.class +/JobInfo.class +/JobPermission.class +/JobProgression.class +/JobsPlayer.class +/RestrictedArea.class +/Title.class +/JobCommands.class +/ItemData.class +/PaymentData.class +/JobItems.class +/Convert.class +/TopList.class +/JobsLeaveEvent.class +/NameList.class +/Schedule.class diff --git a/com/gamingmesh/jobs/container/ActionInfo.java b/com/gamingmesh/jobs/container/ActionInfo.java new file mode 100644 index 00000000..c742005a --- /dev/null +++ b/com/gamingmesh/jobs/container/ActionInfo.java @@ -0,0 +1,25 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.container; + +public interface ActionInfo { + public String getName(); + public String getNameWithSub(); + public ActionType getType(); +} diff --git a/com/gamingmesh/jobs/container/ActionType.java b/com/gamingmesh/jobs/container/ActionType.java new file mode 100644 index 00000000..5ab5c4be --- /dev/null +++ b/com/gamingmesh/jobs/container/ActionType.java @@ -0,0 +1,46 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.container; + +public enum ActionType { + BREAK("Break"), + PLACE("Place"), + KILL("Kill"), + FISH("Fish"), + CRAFT("Craft"), + SMELT("Smelt"), + BREW("Brew"), + ENCHANT("Enchant"), + REPAIR("Repair"), + BREED("Breed"), + TAME("Tame"), + DYE("Dye"), + SHEAR("Shear"), + MILK("Milk"), + CUSTOMKILL("custom-kill"); + + private String name; + private ActionType(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/com/gamingmesh/jobs/container/BaseActionInfo.java b/com/gamingmesh/jobs/container/BaseActionInfo.java new file mode 100644 index 00000000..83648c5d --- /dev/null +++ b/com/gamingmesh/jobs/container/BaseActionInfo.java @@ -0,0 +1,31 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.container; + +public abstract class BaseActionInfo implements ActionInfo { + private ActionType type; + public BaseActionInfo(ActionType type) { + this.type = type; + } + + @Override + public ActionType getType() { + return this.type; + } +} diff --git a/com/gamingmesh/jobs/container/Convert.java b/com/gamingmesh/jobs/container/Convert.java new file mode 100644 index 00000000..70c29cea --- /dev/null +++ b/com/gamingmesh/jobs/container/Convert.java @@ -0,0 +1,49 @@ +package com.gamingmesh.jobs.container; + +import java.util.UUID; + +public class Convert { + + int id; + String name; + UUID uuid; + String jobname; + int level; + int exp; + + public Convert(int id, String name, UUID uuid2, String jobname, int level, int exp) { + this.id = id; + this.name = name; + this.uuid = uuid2; + this.jobname = jobname; + this.level = level; + this.exp = exp; + } + + public Convert() { + } + + public int GetId() { + return this.id; + } + + public String GetName() { + return this.name; + } + + public UUID GetUuid() { + return this.uuid; + } + + public String GetJobName() { + return this.jobname; + } + + public int GetLevel() { + return this.level; + } + + public int GetExp() { + return this.exp; + } +} diff --git a/com/gamingmesh/jobs/container/DisplayMethod.java b/com/gamingmesh/jobs/container/DisplayMethod.java new file mode 100644 index 00000000..e64e00bb --- /dev/null +++ b/com/gamingmesh/jobs/container/DisplayMethod.java @@ -0,0 +1,41 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.container; + +public enum DisplayMethod { + FULL("full"), JOB("job"), TITLE("title"), NONE("none"), SHORT_FULL("shortfull"), SHORT_JOB("shortjob"), SHORT_TITLE("shortitle"); + + private String name; + + private DisplayMethod(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public static DisplayMethod matchMethod(String name) { + for (DisplayMethod method : DisplayMethod.values()) { + if (method.getName().equalsIgnoreCase(name)) + return method; + } + return null; + } +} \ No newline at end of file diff --git a/com/gamingmesh/jobs/container/Job.java b/com/gamingmesh/jobs/container/Job.java new file mode 100644 index 00000000..1ae86ca2 --- /dev/null +++ b/com/gamingmesh/jobs/container/Job.java @@ -0,0 +1,346 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.container; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +import org.bukkit.inventory.ItemStack; + +import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.config.ConfigManager; +import com.gamingmesh.jobs.resources.jfep.Parser; +import com.gamingmesh.jobs.stuff.ChatColor; + +public class Job { + // job info + private EnumMap<ActionType, List<JobInfo>> jobInfo = new EnumMap<ActionType, List<JobInfo>>(ActionType.class); + // permissions + private List<JobPermission> jobPermissions; + // commands + private List<JobCommands> jobCommands; + // items + private List<JobItems> jobItems; + // job name + private String jobName; + // job short name (for use in multiple jobs) + private String jobShortName; + // short description of the job + private String description; + // job chat colour + private ChatColor jobColour; + // job leveling equation + private Parser maxExpEquation; + // display method + private DisplayMethod displayMethod; + // max level + private int maxLevel; + // vip max level + private int vipmaxLevel = 0; + // max number of people allowed with this job on the server. + private Integer maxSlots; + // Commands to be performed on player job join + private List<String> CmdOnJoin = new ArrayList<String>(); + // Commands to be performed on player job leave + private List<String> CmdOnLeave = new ArrayList<String>(); + // Item for GUI + private ItemStack GUIitem; + + private int totalPlayers = 0; + private double bonus = 0.0; + + private double ExpBoost = 1.0; + + private double MoneyBoost = 1.0; + + /** + * Constructor + * @param jobName - the name of the job + * @param jobShortName - the shortened version of the name of the job. + * @param description - a short description of the job. + * @param jobColour - the colour of the job title as displayed in chat. + * @param maxExpEquation - the equation by which the exp needed to level up is calculated + * @param displayMethod - the display method for this job. + * @param maxLevel - the maximum level allowed (null for no max level) + * @param vipmaxLevel - the maximum vip level allowed (null for no max level) + * @param maxSlots - the maximum number of people allowed to have this job at one time (null for no limits) + * @param jobPermissions - permissions gained for having the job + * @param jobCommands - commands to perform on levelup + * @param jobItems - items with boost + * @param CmdOnJoin - commands performed on player join + * @param CmdOnLeave - commands performed on player leave + */ + public Job(String jobName, String jobShortName, String description, ChatColor jobColour, Parser maxExpEquation, DisplayMethod displayMethod, int maxLevel, int vipmaxLevel, Integer maxSlots, List<JobPermission> jobPermissions, List<JobCommands> jobCommands, List<JobItems> jobItems, List<String> CmdOnJoin, List<String> CmdOnLeave, ItemStack GUIitem) { + this.jobName = jobName; + this.jobShortName = jobShortName; + this.description = description; + this.jobColour = jobColour; + this.maxExpEquation = maxExpEquation; + this.displayMethod = displayMethod; + this.maxLevel = maxLevel; + this.vipmaxLevel = vipmaxLevel; + this.maxSlots = maxSlots; + this.jobPermissions = jobPermissions; + this.jobCommands = jobCommands; + this.jobItems = jobItems; + this.CmdOnJoin = CmdOnJoin; + this.CmdOnLeave = CmdOnLeave; + this.GUIitem = GUIitem; + } + + public void setMoneyBoost(double amount) { + this.MoneyBoost = amount; + } + + public double getMoneyBoost() { + return this.MoneyBoost; + } + + public void setExpBoost(double amount) { + this.ExpBoost = amount; + } + + public double getExpBoost() { + return this.ExpBoost; + } + + public int getTotalPlayers() { + if (this.totalPlayers == 0) { + this.totalPlayers = Jobs.getJobsDAO().getTotalPlayerAmountByJobName(this.jobName); + updateBonus(); + } + return this.totalPlayers; + } + + public void updateTotalPlayers() { + this.totalPlayers = Jobs.getJobsDAO().getTotalPlayerAmountByJobName(this.jobName); + updateBonus(); + } + + public void updateBonus() { + if (!ConfigManager.getJobsConfiguration().useDynamicPayment) + return; + Parser eq = ConfigManager.getJobsConfiguration().DynamicPaymentEquation; + eq.setVariable("totalworkers", Jobs.getJobsDAO().getTotalPlayers()); + eq.setVariable("totaljobs", Jobs.getJobs().size()); + eq.setVariable("jobstotalplayers", getTotalPlayers()); + + double now = eq.getValue(); + if (now > ConfigManager.getJobsConfiguration().DynamicPaymentMaxBonus) + now = ConfigManager.getJobsConfiguration().DynamicPaymentMaxBonus; + if (now < ConfigManager.getJobsConfiguration().DynamicPaymentMaxPenalty * -1) + now = ConfigManager.getJobsConfiguration().DynamicPaymentMaxPenalty * -1; + this.bonus = now; + } + + public double getBonus() { + if (this.bonus == 0.0) + updateBonus(); + return this.bonus; + } + + public List<String> getCmdOnJoin() { + return this.CmdOnJoin; + } + + public List<String> getCmdOnLeave() { + return this.CmdOnLeave; + } + + public ItemStack getGuiItem() { + return this.GUIitem; + } + + /** + * Sets job info for action type + * @param type - The action type + * @param info - the job info + */ + public void setJobInfo(ActionType type, List<JobInfo> info) { + jobInfo.put(type, info); + } + + /** + * Gets the job info for the particular type + * @param type - The action type + * @return Job info list + */ + + public List<JobInfo> getJobInfo(ActionType type) { + return Collections.unmodifiableList(jobInfo.get(type)); + } + + /** + * Gets the job info list + * @return Job info list + */ + + public EnumMap<ActionType, List<JobInfo>> getJobInfoList() { + return jobInfo; + } + + /** + * Function to get the income for an action + * @param action - The action info + * @param level - players job level + * @param numjobs - number of jobs for the player + * @return the income received for performing action + */ + + public Double getIncome(ActionInfo action, int level, int numjobs) { + List<JobInfo> jobInfo = getJobInfo(action.getType()); + for (JobInfo info : jobInfo) { + if (info.getName().equalsIgnoreCase(action.getName()) || info.getName().equalsIgnoreCase(action.getNameWithSub())) { + return info.getIncome(level, numjobs); + } + } + return null; + } + + /** + * Function to get the income for an action + * @param action - The action info + * @param level - players job level + * @param numjobs - number of jobs for the player + * @return the income received for performing action + */ + + public Double getExperience(ActionInfo action, int level, int numjobs) { + List<JobInfo> jobInfo = getJobInfo(action.getType()); + for (JobInfo info : jobInfo) { + if (info.getName().equalsIgnoreCase(action.getName()) || info.getName().equalsIgnoreCase(action.getNameWithSub())) + return info.getExperience(level, numjobs); + } + return null; + } + + /** + * Get the job name + * @return the job name + */ + public String getName() { + return jobName; + } + + /** + * Get the shortened version of the jobName + * @return the shortened version of the jobName + */ + public String getShortName() { + return jobShortName; + } + + /** + * Gets the description + * @return description + */ + public String getDescription() { + return description; + } + + /** + * Get the Color of the job for chat + * @return the Color of the job for chat + */ + public ChatColor getChatColor() { + return jobColour; + } + + /** + * Get the MaxExpEquation of the job + * @return the MaxExpEquation of the job + */ + public Parser getMaxExpEquation() { + return maxExpEquation; + } + + /** + * Function to return the appropriate max exp for this level + * @param level - current level + * @return the correct max exp for this level + */ + public double getMaxExp(Map<String, Double> param) { + for (Map.Entry<String, Double> temp : param.entrySet()) { + maxExpEquation.setVariable(temp.getKey(), temp.getValue()); + } + return maxExpEquation.getValue(); + } + + /** + * Function to get the display method + * @return the display method + */ + public DisplayMethod getDisplayMethod() { + return displayMethod; + } + + /** + * Function to return the maximum level + * @return the max level + * @return null - no max level + */ + public int getMaxLevel() { + return maxLevel; + } + + /** + * Function to return the maximum level + * @return the max level + * @return null - no max level + */ + public int getVipMaxLevel() { + return vipmaxLevel; + } + + /** + * Function to return the maximum slots + * @return the max slots + * @return null - no max slots + */ + public Integer getMaxSlots() { + return maxSlots; + } + + /** + * Get the permission nodes for this job + * @return Permissions for this job + */ + public List<JobPermission> getPermissions() { + return Collections.unmodifiableList(jobPermissions); + } + + /** + * Get the command nodes for this job + * @return Commands for this job + */ + public List<JobCommands> getCommands() { + return Collections.unmodifiableList(jobCommands); + } + + /** + * Get the item nodes for this job + * @return Items for this job + */ + public List<JobItems> getItems() { + return Collections.unmodifiableList(jobItems); + } +} diff --git a/com/gamingmesh/jobs/container/JobCommands.java b/com/gamingmesh/jobs/container/JobCommands.java new file mode 100644 index 00000000..b3d5e618 --- /dev/null +++ b/com/gamingmesh/jobs/container/JobCommands.java @@ -0,0 +1,48 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.container; + +public class JobCommands { + private String node; + private String command; + private int levelFrom; + private int levelUntil; + public JobCommands(String node, String command, int levelFrom, int levelUntil) { + this.node = node; + this.command = command; + this.levelFrom = levelFrom; + this.levelUntil = levelUntil; + } + + public String getNode() { + return node; + } + + public String getCommand() { + return command; + } + + public int getLevelFrom() { + return levelFrom; + } + + public int getLevelUntil() { + return levelUntil; + } +} diff --git a/com/gamingmesh/jobs/container/JobInfo.java b/com/gamingmesh/jobs/container/JobInfo.java new file mode 100644 index 00000000..ee345477 --- /dev/null +++ b/com/gamingmesh/jobs/container/JobInfo.java @@ -0,0 +1,79 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.container; + +import com.gamingmesh.jobs.resources.jfep.Parser; + +public class JobInfo { + private ActionType actionType; + private int id; + private String meta; + private String name; + private double baseIncome, baseXp; + private Parser moneyEquation, xpEquation; + + public JobInfo(ActionType actionType, int id, String meta, String name, double baseIncome, Parser moneyEquation, double baseXp, Parser xpEquation) { + this.actionType = actionType; + this.id = id; + this.meta = meta; + this.name = name; + this.baseIncome = baseIncome; + this.moneyEquation = moneyEquation; + this.baseXp = baseXp; + this.xpEquation = xpEquation; + } + + public String getName() { + return this.name; + } + + public int getId() { + return this.id; + } + + public ActionType getActionType() { + return this.actionType; + } + + public String getMeta() { + return this.meta; + } + + public double getBaseIncome() { + return this.baseIncome; + } + + public double getBaseXp() { + return this.baseXp; + } + + public double getIncome(int level, int numjobs) { + moneyEquation.setVariable("joblevel", level); + moneyEquation.setVariable("numjobs", numjobs); + moneyEquation.setVariable("baseincome", baseIncome); + return moneyEquation.getValue(); + } + + public double getExperience(int level, int numjobs) { + xpEquation.setVariable("joblevel", level); + xpEquation.setVariable("numjobs", numjobs); + xpEquation.setVariable("baseexperience", baseXp); + return xpEquation.getValue(); + } +} diff --git a/com/gamingmesh/jobs/container/JobItems.java b/com/gamingmesh/jobs/container/JobItems.java new file mode 100644 index 00000000..63472c80 --- /dev/null +++ b/com/gamingmesh/jobs/container/JobItems.java @@ -0,0 +1,69 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.container; + +import java.util.List; + +public class JobItems { + private String node; + private int id; + private String name; + private List<String> lore; + private List<String> enchants; + private Double moneyBoost; + private Double expBoost; + + public JobItems(String node, int id, String name, List<String> lore, List<String> enchants, double moneyBoost, double expBoost) { + this.node = node; + this.id = id; + this.name = name; + this.lore = lore; + this.enchants = enchants; + this.moneyBoost = moneyBoost; + this.expBoost = expBoost; + } + + public String getNode() { + return this.node; + } + + public int getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public List<String> getLore() { + return this.lore; + } + + public List<String> getenchants() { + return this.enchants; + } + + public Double getMoneyBoost() { + return this.moneyBoost; + } + + public Double getExpBoost() { + return this.expBoost; + } +} diff --git a/com/gamingmesh/jobs/container/JobPermission.java b/com/gamingmesh/jobs/container/JobPermission.java new file mode 100644 index 00000000..42828e40 --- /dev/null +++ b/com/gamingmesh/jobs/container/JobPermission.java @@ -0,0 +1,42 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.container; + +public class JobPermission { + private String node; + private boolean value; + private int levelRequirement; + public JobPermission(String node, boolean value, int levelRequirement) { + this.node = node; + this.value = value; + this.levelRequirement = levelRequirement; + } + + public String getNode() { + return node; + } + + public boolean getValue() { + return value; + } + + public int getLevelRequirement() { + return levelRequirement; + } +} diff --git a/com/gamingmesh/jobs/container/JobProgression.java b/com/gamingmesh/jobs/container/JobProgression.java new file mode 100644 index 00000000..0b39bfc2 --- /dev/null +++ b/com/gamingmesh/jobs/container/JobProgression.java @@ -0,0 +1,188 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.container; + +import java.util.HashMap; + +public class JobProgression { + private Job job; + private JobsPlayer jPlayer; + private double experience; + private int level; + private transient int maxExperience = -1; + private double MoneyBoost = -1; + private double ExpBoost = -1; + + public JobProgression(Job job, JobsPlayer jPlayer, int level, double experience, double MoneyBoost, double ExpBoost) { + this.job = job; + this.jPlayer = jPlayer; + this.experience = experience; + this.level = level; + this.MoneyBoost = MoneyBoost; + this.ExpBoost = ExpBoost; + } + + /** + * Can the job level up? + * @return true if the job can level up + * @return false if the job cannot + */ + public boolean canLevelUp() { + return experience >= maxExperience; + } + + /** + * Return the MoneyBoost + * @return the MoneyBoost + */ + public double getMoneyBoost() { + if (this.MoneyBoost == -1) + this.MoneyBoost = JobsPlayer.getMoneyBoost(this.job.getName(), this.jPlayer.getPlayer()); + return this.MoneyBoost; + } + + /** + * Return the ExpBoost + * @return the ExpBoost + */ + public double getExpBoost() { + if (this.ExpBoost == -1) + this.ExpBoost = JobsPlayer.getExpBoost(this.job.getName(), this.jPlayer.getPlayer()); + return this.ExpBoost; + } + + /** + * Return the job + * @return the job + */ + public Job getJob() { + return job; + } + + /** + * Set the job + * @param job - the new job to be set + */ + public void setJob(Job job) { + synchronized (jPlayer.saveLock) { + jPlayer.setSaved(false); + this.job = job; + reloadMaxExperienceAndCheckLevelUp(); + } + } + + /** + * Get the experience in this job + * @return the experiece in this job + */ + public double getExperience() { + return experience; + } + + /** + * Adds experience for this job + * @param experience - the experience in this job + * @return - job level up + */ + public boolean addExperience(double experience) { + synchronized (jPlayer.saveLock) { + jPlayer.setSaved(false); + this.experience += experience; + return checkLevelUp(); + } + } + + /** + * Get the maximum experience for this level + * @return the experience needed to level up + */ + public int getMaxExperience() { + return maxExperience; + } + + /** + * Get the current level of this job + * @return the level of this job + */ + public int getLevel() { + return level; + } + + /** + * Set the level of this job + * @param level - the new level for this job + */ + public void setLevel(int level) { + synchronized (jPlayer.saveLock) { + jPlayer.setSaved(false); + this.level = level; + reloadMaxExperienceAndCheckLevelUp(); + } + } + + /** + * Reloads max experience + */ + public void reloadMaxExperience() { + HashMap<String, Double> param = new HashMap<String, Double>(); + param.put("joblevel", (double) level); + param.put("numjobs", (double) jPlayer.getJobProgression().size()); + this.maxExperience = (int) job.getMaxExp(param); + } + + /** + * Performs a level up + * @returns if level up was performed + */ + private boolean checkLevelUp() { + boolean ret = false; + while (canLevelUp()) { + + int maxLevel = 0; + if (jPlayer.havePermission("jobs." + job.getName() + ".vipmaxlevel") && job.getVipMaxLevel() != 0) + maxLevel = job.getVipMaxLevel(); + else + maxLevel = job.getMaxLevel(); + + // Don't level up at max level + if (job.getMaxLevel() > 0 && level >= maxLevel) + break; + level++; + experience -= maxExperience; + ret = true; + reloadMaxExperience(); + } + + // At max level + if (experience > maxExperience) + experience = maxExperience; + return ret; + } + + /** + * Reloads max experience and checks for level up + * Do this whenever job or level changes + * @return if leveled up + */ + + private boolean reloadMaxExperienceAndCheckLevelUp() { + reloadMaxExperience(); + return checkLevelUp(); + } +} diff --git a/com/gamingmesh/jobs/container/JobsPlayer.java b/com/gamingmesh/jobs/container/JobsPlayer.java new file mode 100644 index 00000000..c67b5003 --- /dev/null +++ b/com/gamingmesh/jobs/container/JobsPlayer.java @@ -0,0 +1,497 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.container; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.config.ConfigManager; +import com.gamingmesh.jobs.dao.JobsDAO; +import com.gamingmesh.jobs.dao.JobsDAOData; +import com.gamingmesh.jobs.stuff.ChatColor; +import com.gamingmesh.jobs.stuff.Perm; + +public class JobsPlayer { + // the player the object belongs to + private String userName; + // progression of the player in each job + private UUID playerUUID; + private ArrayList<JobProgression> progression = new ArrayList<JobProgression>(); + // display honorific + private String honorific; + // player save status + private volatile boolean isSaved = true; + // player online status + private volatile boolean isOnline = false; + + private OfflinePlayer player = null; + + private double VipSpawnerMultiplier = -1; + + // save lock + public final Object saveLock = new Object(); + + private JobsPlayer(String userName, OfflinePlayer player) { + this.userName = userName; + this.player = player; + } + + public static JobsPlayer loadFromDao(JobsDAO dao, OfflinePlayer player) { + + JobsPlayer jPlayer = new JobsPlayer(player.getName(), player); + jPlayer.playerUUID = player.getUniqueId(); + List<JobsDAOData> list = dao.getAllJobs(player); + //synchronized (jPlayer.saveLock) { + jPlayer.progression.clear(); + for (JobsDAOData jobdata : list) { + if (Jobs.getJob(jobdata.getJobName()) == null) + continue; + // add the job + Job job = Jobs.getJob(jobdata.getJobName()); + if (job == null) + continue; + + // create the progression object + JobProgression jobProgression = new JobProgression(job, jPlayer, jobdata.getLevel(), jobdata.getExperience(), -1, -1); + // calculate the max level + // add the progression level. + jPlayer.progression.add(jobProgression); + + } + jPlayer.reloadMaxExperience(); + //} + return jPlayer; + } + + /** + * Get the player + * @return the player + */ + public OfflinePlayer getPlayer() { + return this.player; + } + + /** + * Get the VipSpawnerMultiplier + * @return the Multiplier + */ + public double getVipSpawnerMultiplier() { + if (!this.player.isOnline()) + return 1.0; + if (VipSpawnerMultiplier < 0) + updateVipSpawnerMultiplier(); + return this.VipSpawnerMultiplier; + } + + public void updateVipSpawnerMultiplier() { + if (Perm.hasPermission(this.player, "jobs.vipspawner")) + this.VipSpawnerMultiplier = ConfigManager.getJobsConfiguration().VIPpayNearSpawnerMultiplier; + else + this.VipSpawnerMultiplier = ConfigManager.getJobsConfiguration().payNearSpawnerMultiplier; + } + + /** + * Get the MoneyBoost + * @return the MoneyBoost + */ + public static double getMoneyBoost(String JobName, OfflinePlayer player) { + double MoneyBoost = 1.0; + if (JobName != null) { + if (Perm.hasPermission(player, "jobs.boost." + JobName + ".money") || Perm.hasPermission(player, "jobs.boost." + JobName + ".both") || Perm.hasPermission(player, "jobs.boost.all.both") || Perm.hasPermission(player, "jobs.boost.all.money")) { + MoneyBoost = ConfigManager.getJobsConfiguration().BoostMoney; + } + } + return MoneyBoost; + } + + /** + * Get the MoneyBoost + * @return the MoneyBoost + */ + public static double getExpBoost(String JobName, OfflinePlayer player) { + Double ExpBoost = 1.0; + if (player == null || JobName == null) + return 1.0; + if (Perm.hasPermission(player, "jobs.boost." + JobName + ".exp") || Perm.hasPermission(player, "jobs.boost." + JobName + ".both") || Perm.hasPermission(player, "jobs.boost.all.both") || Perm.hasPermission(player, "jobs.boost.all.exp")) { + ExpBoost = ConfigManager.getJobsConfiguration().BoostExp; + } + return ExpBoost; + } + + /** + * Reloads max experience for this job. + */ + private void reloadMaxExperience() { + for (JobProgression prog : progression) { + prog.reloadMaxExperience(); + } + } + + /** + * Get the list of job progressions + * @return the list of job progressions + */ + public List<JobProgression> getJobProgression() { + return Collections.unmodifiableList(progression); + } + + /** + * Check if have permission + * @return true if have + */ + public boolean havePermission(String perm) { + if (this.isOnline) + return ((Player) player).hasPermission(perm); + return false; + } + + /** + * Get the job progression with the certain job + * @return the job progression + */ + public JobProgression getJobProgression(Job job) { + for (JobProgression prog : progression) { + if (prog.getJob().equals(job)) + return prog; + } + return null; + } + + /** + * get the userName + * @return the userName + */ + public String getUserName() { + return userName; + } + + /** + * get the playerUUID + * @return the playerUUID + */ + public UUID getPlayerUUID() { + return playerUUID; + } + + public String getDisplayHonorific() { + return honorific; + } + + /** + * Player joins a job + * @param job - the job joined + */ + public boolean joinJob(Job job, JobsPlayer jPlayer) { + synchronized (saveLock) { + if (!isInJob(job)) { + int level = 1; + int exp = 0; + if (Jobs.getJobsDAO().checkArchive(jPlayer, job).size() > 0) { + List<Integer> info = Jobs.getJobsDAO().checkArchive(jPlayer, job); + level = info.get(0); + //exp = info.get(1); + Jobs.getJobsDAO().deleteArchive(jPlayer, job); + } + + progression.add(new JobProgression(job, this, level, exp, -1, -1)); + reloadMaxExperience(); + reloadHonorific(); + Jobs.getPermissionHandler().recalculatePermissions(this); + return true; + } + return false; + } + } + + /** + * Player leaves a job + * @param job - the job left + */ + public boolean leaveJob(Job job) { + synchronized (saveLock) { + JobProgression prog = getJobProgression(job); + if (prog != null) { + progression.remove(prog); + reloadMaxExperience(); + reloadHonorific(); + Jobs.getPermissionHandler().recalculatePermissions(this); + return true; + } + return false; + } + } + + /** + * Leave all jobs + * @return on success + */ + public boolean leaveAllJobs() { + synchronized (saveLock) { + progression.clear(); + reloadHonorific(); + Jobs.getPermissionHandler().recalculatePermissions(this);; + return true; + } + } + + /** + * Promotes player in job + * @param job - the job being promoted + * @param levels - number of levels to promote + */ + public void promoteJob(Job job, int levels, JobsPlayer player) { + synchronized (saveLock) { + JobProgression prog = getJobProgression(job); + if (prog == null) + return; + if (levels <= 0) + return; + int newLevel = prog.getLevel() + levels; + + int maxLevel = job.getMaxLevel(); + + if (player.havePermission("jobs." + job.getName() + ".vipmaxlevel") && job.getVipMaxLevel() != 0) + maxLevel = job.getVipMaxLevel(); + + if (maxLevel > 0 && newLevel > maxLevel) { + newLevel = maxLevel; + } + setLevel(job, newLevel); + } + } + + /** + * Demotes player in job + * @param job - the job being deomoted + * @param levels - number of levels to demote + */ + public void demoteJob(Job job, int levels) { + synchronized (saveLock) { + JobProgression prog = getJobProgression(job); + if (prog == null) + return; + if (levels <= 0) + return; + int newLevel = prog.getLevel() - levels; + if (newLevel < 1) { + newLevel = 1; + } + setLevel(job, newLevel); + } + } + + /** + * Sets player to a specific level + * @param job - the job + * @param level - the level + */ + private void setLevel(Job job, int level) { + synchronized (saveLock) { + JobProgression prog = getJobProgression(job); + if (prog == null) + return; + + if (level != prog.getLevel()) { + prog.setLevel(level); + reloadHonorific(); + Jobs.getPermissionHandler().recalculatePermissions(this);; + } + } + } + + /** + * Player leaves a job + * @param oldjob - the old job + * @param newjob - the new job + */ + public boolean transferJob(Job oldjob, Job newjob, JobsPlayer jPlayer) { + synchronized (saveLock) { + if (!isInJob(newjob)) { + for (JobProgression prog : progression) { + if (!prog.getJob().equals(oldjob)) + continue; + + prog.setJob(newjob); + + int maxLevel = 0; + if (jPlayer.havePermission("jobs." + newjob.getName() + ".vipmaxlevel")) + maxLevel = newjob.getVipMaxLevel(); + else + maxLevel = newjob.getMaxLevel(); + + if (newjob.getMaxLevel() > 0 && prog.getLevel() > maxLevel) { + prog.setLevel(maxLevel); + } + reloadMaxExperience(); + reloadHonorific(); + Jobs.getPermissionHandler().recalculatePermissions(this);; + return true; + } + } + return false; + } + } + + /** + * Checks if the player is in this job. + * @param job - the job + * @return true - they are in the job + * @return false - they are not in the job + */ + public boolean isInJob(Job job) { + for (JobProgression prog : progression) { + if (prog.getJob().equals(job)) + return true; + } + return false; + } + + /** + * Function that reloads your honorific + */ + public void reloadHonorific() { + StringBuilder builder = new StringBuilder(); + int numJobs = progression.size(); + boolean gotTitle = false; + + if (numJobs > 0) + for (JobProgression prog : progression) { + DisplayMethod method = prog.getJob().getDisplayMethod(); + if (method.equals(DisplayMethod.NONE)) + continue; + if (gotTitle) { + builder.append(" "); + gotTitle = false; + } + Title title = ConfigManager.getJobsConfiguration().getTitleForLevel(prog.getLevel(), prog.getJob().getName()); + + if (numJobs == 1) { + if (method.equals(DisplayMethod.FULL) || method.equals(DisplayMethod.TITLE)) { + if (title != null) { + String honorificpart = title.getChatColor() + title.getName() + ChatColor.WHITE; + if (honorificpart.contains("{level}")) + honorificpart = honorificpart.replace("{level}", String.valueOf(prog.getLevel())); + builder.append(honorificpart); + gotTitle = true; + } + } + if (method.equals(DisplayMethod.FULL) || method.equals(DisplayMethod.JOB)) { + if (gotTitle) { + builder.append(" "); + } + String honorificpart = prog.getJob().getChatColor() + prog.getJob().getName() + ChatColor.WHITE; + if (honorificpart.contains("{level}")) + honorificpart = honorificpart.replace("{level}", String.valueOf(prog.getLevel())); + builder.append(honorificpart); + gotTitle = true; + } + } + + if (numJobs > 1 && (method.equals(DisplayMethod.FULL) || method.equals(DisplayMethod.TITLE)) || method.equals(DisplayMethod.SHORT_FULL) || method.equals(DisplayMethod.SHORT_TITLE)) { + // add title to honorific + if (title != null) { + String honorificpart = title.getChatColor() + title.getShortName() + ChatColor.WHITE; + if (honorificpart.contains("{level}")) + honorificpart = honorificpart.replace("{level}", String.valueOf(prog.getLevel())); + builder.append(honorificpart); + gotTitle = true; + } + } + + if (numJobs > 1 && (method.equals(DisplayMethod.FULL) || method.equals(DisplayMethod.JOB)) || method.equals(DisplayMethod.SHORT_FULL) || method.equals(DisplayMethod.SHORT_JOB)) { + String honorificpart = prog.getJob().getChatColor() + prog.getJob().getShortName() + ChatColor.WHITE; + if (honorificpart.contains("{level}")) + honorificpart = honorificpart.replace("{level}", String.valueOf(prog.getLevel())); + builder.append(honorificpart); + gotTitle = true; + } + } + else { + Job nonejob = Jobs.getNoneJob(); + if (nonejob != null) { + DisplayMethod metod = nonejob.getDisplayMethod(); + if (metod.equals(DisplayMethod.FULL) || metod.equals(DisplayMethod.TITLE)) { + String honorificpart = Jobs.getNoneJob().getChatColor() + Jobs.getNoneJob().getName() + ChatColor.WHITE; + if (honorificpart.contains("{level}")) + honorificpart = honorificpart.replace("{level}", ""); + builder.append(honorificpart); + } + + if (metod.equals(DisplayMethod.SHORT_FULL) || metod.equals(DisplayMethod.SHORT_TITLE) || metod.equals(DisplayMethod.SHORT_JOB)) { + String honorificpart = Jobs.getNoneJob().getChatColor() + Jobs.getNoneJob().getShortName() + ChatColor.WHITE; + if (honorificpart.contains("{level}")) + honorificpart = honorificpart.replace("{level}", ""); + builder.append(honorificpart); + } + } + } + + honorific = builder.toString().trim(); + } + + /** + * Performs player save + * @param dao + */ + public void save(JobsDAO dao) { + synchronized (saveLock) { + if (!isSaved()) { + dao.save(this); + setSaved(true); + } + } + } + + /** + * Perform connect + */ + public void onConnect() { + isOnline = true; + } + + /** + * Perform disconnect + * + */ + public void onDisconnect() { + isOnline = false; + } + + /** + * Whether or not player is online + * @return true if online, otherwise false + */ + public boolean isOnline() { + return isOnline; + } + + public boolean isSaved() { + return isSaved; + } + + public void setSaved(boolean value) { + isSaved = value; + } +} diff --git a/com/gamingmesh/jobs/container/NameList.java b/com/gamingmesh/jobs/container/NameList.java new file mode 100644 index 00000000..1baf56d2 --- /dev/null +++ b/com/gamingmesh/jobs/container/NameList.java @@ -0,0 +1,50 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.container; + +public class NameList { + + String id; + String meta; + String Name; + String MinecraftName; + + public NameList(String id, String meta, String Name, String MinecraftName) { + this.id = id; + this.meta = meta; + this.Name = Name; + this.MinecraftName = MinecraftName; + } + + public String getName() { + return Name; + } + + public String getId() { + return id; + } + + public String getMeta() { + return meta; + } + + public String getMinecraftName() { + return MinecraftName; + } +} diff --git a/com/gamingmesh/jobs/container/RestrictedArea.java b/com/gamingmesh/jobs/container/RestrictedArea.java new file mode 100644 index 00000000..f4973e98 --- /dev/null +++ b/com/gamingmesh/jobs/container/RestrictedArea.java @@ -0,0 +1,85 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.container; + +import org.bukkit.Location; +import org.bukkit.entity.Player; + +/** + * Restricted Area Class + * + * Holds data pertaining to restricted areas on the server + * @author Zak Ford <zak.j.ford@gmail.com> + * + */ +public class RestrictedArea { + + private Location location1; + private Location location2; + private double multiplier; + + public RestrictedArea(Location location1, Location location2, double multiplier) { + this.location1 = location1; + this.location2 = location2; + this.multiplier = multiplier; + } + + /** + * The multipler for the restricted area + * @return - the multipler for this restricted area + */ + + public double getMultiplier() { + return this.multiplier; + } + + /** + * Function check if location is in the restricted area + * @param loc - the location to checked + * @return true - the location is inside the restricted area + * @return false - the location is outside the restricted area + */ + public boolean inRestrictedArea(Player player) { + if(isBetween(player.getLocation().getX(), this.location1.getX(), this.location2.getX()) && + isBetween(player.getLocation().getY(), this.location1.getY(), this.location2.getY()) && + isBetween(player.getLocation().getZ(), this.location1.getZ(), this.location2.getZ()) && + this.location1.getWorld().equals(player.getLocation().getWorld()) && + this.location2.getWorld().equals(player.getLocation().getWorld())) { + return true; + } + return false; + } + + /** + * Function check if number is between bounds + * @param number - the number to be checked + * @param bound1 - the first bound + * @param bound2 - the second bound + * @return true - number is between bounds + * @return false - number is out of bounds + */ + private boolean isBetween(double number, double bound1, double bound2) { + if(bound1 < bound2 && number > bound1 && number < bound2) { + return true; + } else if (bound1 > bound2 && number < bound1 && number > bound2) { + return true; + } + return false; + } +} diff --git a/com/gamingmesh/jobs/container/Schedule.java b/com/gamingmesh/jobs/container/Schedule.java new file mode 100644 index 00000000..96f39e38 --- /dev/null +++ b/com/gamingmesh/jobs/container/Schedule.java @@ -0,0 +1,190 @@ +package com.gamingmesh.jobs.container; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.gamingmesh.jobs.Jobs; + +import net.md_5.bungee.api.ChatColor; + +public class Schedule { + + int From = 0; + int Until = 235959; + + int nextFrom = 0; + int nextUntil = 235959; + + boolean nextDay = false; + + double MoneyBoost = 1.0; + double ExpBoost = 1.0; + + String Name = null; + + List<String> Days = new ArrayList<String>(Arrays.asList("all")); + List<Job> JobsList = new ArrayList<Job>(); + + List<String> MessageOnStart = new ArrayList<String>(); + List<String> MessageOnStop = new ArrayList<String>(); + + boolean started = false; + boolean stoped = true; + + boolean onStop = true; + boolean OnStart = true; + + public Schedule() { + } + + public void setBroadcastOnStop(boolean stage) { + this.onStop = stage; + } + + public boolean isBroadcastOnStop() { + return this.onStop; + } + + public void setBroadcastOnStart(boolean stage) { + this.OnStart = stage; + } + + public boolean isBroadcastOnStart() { + return this.OnStart; + } + + public void setStarted(boolean stage) { + this.started = stage; + } + + public boolean isStarted() { + return this.started; + } + + public void setStoped(boolean con) { + this.stoped = con; + } + + public boolean isStoped() { + return this.stoped; + } + + public void setMoneyBoost(double MoneyBoost) { + this.MoneyBoost = MoneyBoost; + } + + public double GetMoneyBoost() { + return this.MoneyBoost; + } + + public void setExpBoost(double ExpBoost) { + this.ExpBoost = ExpBoost; + } + + public double GetExpBoost() { + return this.ExpBoost; + } + + public void setName(String Name) { + this.Name = Name; + } + + public String GetName() { + return this.Name; + } + + public void setFrom(int From) { + this.From = From; + } + + public int GetFrom() { + return this.From; + } + + public int GetNextFrom() { + return this.nextFrom; + } + + public int GetNextUntil() { + return this.nextUntil; + } + + public boolean isNextDay() { + return this.nextDay; + } + + public void setUntil(int Until) { + this.Until = Until; + + if (this.From > this.Until) { + this.nextFrom = 0; + this.nextUntil = this.Until; + this.Until = 236000; + this.nextDay = true; + } + } + + public int GetUntil() { + return this.Until; + } + + public void setJobs(List<String> JobsNameList) { + for (int z = 0; z < JobsNameList.size(); z++) { + + if (JobsNameList.get(z).equalsIgnoreCase("all")) { + JobsList.clear(); + List<Job> jobl = Jobs.getJobs(); + if (jobl != null) + JobsList.addAll(Jobs.getJobs()); + return; + } + + Job jb = Jobs.getJob(JobsNameList.get(z)); + + if (jb == null) + continue; + + JobsList.add(jb); + } + } + + public List<Job> GetJobs() { + return this.JobsList; + } + + public void setDays(List<String> Days) { + for (int z = 0; z < Days.size(); z++) { + Days.set(z, Days.get(z).toLowerCase()); + } + this.Days = Days; + } + + public List<String> GetDays() { + return this.Days; + } + + public void setMessageOnStart(List<String> msg) { + List<String> temp = new ArrayList<String>(); + for (String one : msg) { + temp.add(ChatColor.translateAlternateColorCodes('&', one)); + } + this.MessageOnStart.addAll(temp); + } + + public List<String> GetMessageOnStart() { + return this.MessageOnStart; + } + + public void setMessageOnStop(List<String> msg) { + List<String> temp = new ArrayList<String>(); + for (String one : msg) { + temp.add(ChatColor.translateAlternateColorCodes('&', one)); + } + this.MessageOnStop.addAll(temp); + } + + public List<String> GetMessageOnStop() { + return this.MessageOnStop; + } +} diff --git a/com/gamingmesh/jobs/container/Title.java b/com/gamingmesh/jobs/container/Title.java new file mode 100644 index 00000000..467343a1 --- /dev/null +++ b/com/gamingmesh/jobs/container/Title.java @@ -0,0 +1,90 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.container; + +import com.gamingmesh.jobs.stuff.ChatColor; + +/** + * Container class for titles + * @author Alex + * + */ +public class Title { + private String name = null; + private String shortName = null; + private ChatColor color = ChatColor.WHITE; + private int levelReq = 0; + private String jobName = null; + + /** + * Constructor + * @param name - The long name of the title + * @param shortName - the short name of the title + * @param color - the ChatColor of the title + * @param levelReq - the level requirement of the title + * @param jobName - Job this title is made for + */ + public Title(String name, String shortName, ChatColor color, int levelReq, String jobName){ + this.name = name; + this.color = color; + this.levelReq = levelReq; + this.shortName = shortName; + this.jobName = jobName; + } + + /** + * Function to return the long name of the title + * @return the long name of the title + */ + public String getName(){ + return name; + } + + /** + * Function to return the job name of the title + * @return the job name of the title + */ + public String getJobName(){ + return jobName; + } + + /** + * Function to get the ChatColor of the title + * @return the chat colour o the title + */ + public ChatColor getChatColor(){ + return color; + } + + /** + * Function to get the levelRequirement of the title + * @return the level requirement for the title + */ + public int getLevelReq(){ + return levelReq; + } + + /** + * Function to get the short name of the title + * @return the short name of the title + */ + public String getShortName(){ + return shortName; + } +} diff --git a/com/gamingmesh/jobs/container/TopList.java b/com/gamingmesh/jobs/container/TopList.java new file mode 100644 index 00000000..b365b5a8 --- /dev/null +++ b/com/gamingmesh/jobs/container/TopList.java @@ -0,0 +1,45 @@ +package com.gamingmesh.jobs.container; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +import com.gamingmesh.jobs.stuff.UUIDUtil; + +public final class TopList { + private String player; + private int level; + private int exp; + private byte[] uuid; + + public TopList(String player, int level, int exp, byte[] uuid) { + this.player = player; + this.level = level; + this.exp = exp; + this.uuid = uuid; + } + + public String getPlayerName() { + if (this.player == null || this.player == "") { + Player player = Bukkit.getPlayer(UUIDUtil.fromBytes(this.uuid)); + if (player != null) + return player.getName(); + else { + OfflinePlayer Offlineplayer = Bukkit.getOfflinePlayer(UUIDUtil.fromBytes(this.uuid)); + if (Offlineplayer != null) + return Offlineplayer.getName(); + else + return "Unknown"; + } + } + return this.player; + } + + public int getLevel() { + return this.level; + } + + public int getExp() { + return this.exp; + } +} \ No newline at end of file diff --git a/com/gamingmesh/jobs/dao/.gitignore b/com/gamingmesh/jobs/dao/.gitignore new file mode 100644 index 00000000..bcd7d30a --- /dev/null +++ b/com/gamingmesh/jobs/dao/.gitignore @@ -0,0 +1,10 @@ +/JobsConnection.class +/JobsConnectionPool.class +/JobsDAO.class +/JobsDAOData.class +/JobsDAOH2$JobsDAOH2SQLiteImporter.class +/JobsDAOH2.class +/JobsDAOMySQL.class +/JobsDAOSQLite.class +/JobsDriver.class +/JobsDrivers.class diff --git a/com/gamingmesh/jobs/dao/JobsConnection.java b/com/gamingmesh/jobs/dao/JobsConnection.java new file mode 100644 index 00000000..8316e61c --- /dev/null +++ b/com/gamingmesh/jobs/dao/JobsConnection.java @@ -0,0 +1,69 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.dao; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Statement; + +public class JobsConnection { + private Connection conn; + + public JobsConnection(Connection conn) { + this.conn = conn; + } + + public synchronized boolean isClosed() { + try { + return conn.isClosed(); + } catch (SQLException e) { + // Assume it's closed + return true; + } + } + + public synchronized boolean isValid(int timeout) throws SQLException { + try { + return conn.isValid(timeout); + } catch (AbstractMethodError e) { + return true; + } + } + + public synchronized void closeConnection() throws SQLException { + conn.close(); + } + + public synchronized Statement createStatement() throws SQLException { + return conn.createStatement(); + } + + public synchronized PreparedStatement prepareStatement(String sql) throws SQLException { + return conn.prepareStatement(sql); + } + + public synchronized void setAutoCommit(Boolean mode) throws SQLException { + conn.setAutoCommit(mode); + } + + public synchronized void commit() throws SQLException { + conn.commit(); + } +} diff --git a/com/gamingmesh/jobs/dao/JobsConnectionPool.java b/com/gamingmesh/jobs/dao/JobsConnectionPool.java new file mode 100644 index 00000000..1841724e --- /dev/null +++ b/com/gamingmesh/jobs/dao/JobsConnectionPool.java @@ -0,0 +1,67 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.dao; + +import java.sql.Connection; +import java.sql.Driver; +import java.sql.DriverManager; +import java.sql.SQLException; + +import com.gamingmesh.jobs.Jobs; + +public class JobsConnectionPool { + private JobsConnection connection; + private String url; + private String username; + private String password; + public JobsConnectionPool(String driverName, String url, String username, String password) throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException { + Driver driver = (Driver) Class.forName(driverName, true, Jobs.getJobsClassloader()).newInstance(); + JobsDrivers jDriver = new JobsDrivers(driver); + DriverManager.registerDriver(jDriver); + this.url = url; + this.username = username; + this.password = password; + } + + public synchronized JobsConnection getConnection() throws SQLException { + if (connection != null && (connection.isClosed() || !connection.isValid(1))) { + try { + connection.closeConnection(); + } catch (SQLException e) {} + connection = null; + } + + if (connection == null) { + Connection conn = DriverManager.getConnection(url, username, password); + connection = new JobsConnection(conn); + } + + return connection; + } + + public synchronized void closeConnection() { + if (connection != null) { + try { + connection.closeConnection(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + } +} diff --git a/com/gamingmesh/jobs/dao/JobsDAO.java b/com/gamingmesh/jobs/dao/JobsDAO.java new file mode 100644 index 00000000..f5c92a65 --- /dev/null +++ b/com/gamingmesh/jobs/dao/JobsDAO.java @@ -0,0 +1,651 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.dao; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.config.ConfigManager; +import com.gamingmesh.jobs.container.Convert; +import com.gamingmesh.jobs.container.Job; +import com.gamingmesh.jobs.container.JobProgression; +import com.gamingmesh.jobs.container.JobsPlayer; +import com.gamingmesh.jobs.container.TopList; +import com.gamingmesh.jobs.stuff.UUIDUtil; + +/** + * Data Access Object interface for the Jobs plugin + * + * Interface that holds all methods that a DAO needs to have + * @author Alex + * + */ +public abstract class JobsDAO { + + private JobsConnectionPool pool; + private String prefix; + + protected JobsDAO(String driverName, String url, String username, String password, String prefix) { + this.prefix = prefix; + try { + pool = new JobsConnectionPool(driverName, url, username, password); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public final synchronized void setUp() throws SQLException { + setupConfig(); + int version = getSchemaVersion(); + if (version == 0) { + Jobs.getPluginLogger().severe("Could not initialize database! Could not determine schema version!"); + return; + } + + try { + if (version <= 1) + checkUpdate1(); + else if (version <= 2) + checkUpdate2(); + else if (version <= 3) + checkUpdate4(); + + version = 4; + } finally { + updateSchemaVersion(version); + } + } + + protected abstract void setupConfig() throws SQLException; + + protected abstract void checkUpdate1() throws SQLException; + + protected abstract void checkUpdate2() throws SQLException; + + protected abstract void checkUpdate4() throws SQLException; + + /** + * Gets the database prefix + * @return the prefix + */ + protected String getPrefix() { + return prefix; + } + + /** + * Get all jobs the player is part of. + * @param playerUUID - the player being searched for + * @return list of all of the names of the jobs the players are part of. + */ + public synchronized List<JobsDAOData> getAllJobs(OfflinePlayer player) { + ArrayList<JobsDAOData> jobs = new ArrayList<JobsDAOData>(); + JobsConnection conn = getConnection(); + if (conn == null) + return jobs; + try { + PreparedStatement prest = conn.prepareStatement("SELECT `player_uuid`, `job`, `level`, `experience` FROM `" + prefix + "jobs` WHERE `player_uuid` = ?;"); + prest.setBytes(1, UUIDUtil.toBytes(player.getUniqueId())); + ResultSet res = prest.executeQuery(); + while (res.next()) { + jobs.add(new JobsDAOData(player.getUniqueId(), res.getString(2), res.getInt(3), res.getInt(4))); + } + prest.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + return jobs; + } + + /** + * Get player count for a job. + * @param JobName - the job name + * @return amount of player currently working. + */ + public synchronized int getTotalPlayerAmountByJobName(String JobName) { + JobsConnection conn = getConnection(); + if (conn == null) + return 0; + int count = 0; + try { + PreparedStatement prest = conn.prepareStatement("SELECT COUNT(*) FROM `" + prefix + "jobs` WHERE `job` = ?;"); + prest.setString(1, JobName); + ResultSet res = prest.executeQuery(); + while (res.next()) { + count = res.getInt(1); + } + prest.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + return count; + } + + /** + * Get player count for a job. + * @return total amount of player currently working. + */ + public synchronized int getTotalPlayers() { + JobsConnection conn = getConnection(); + if (conn == null) + return 0; + int count = 0; + try { + PreparedStatement prest = conn.prepareStatement("SELECT COUNT(*) FROM `" + prefix + "jobs`;"); + ResultSet res = prest.executeQuery(); + while (res.next()) { + count = res.getInt(1); + } + prest.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + return count; + } + + /** + * Get all jobs the player is part of. + * @param userName - the player being searched for + * @return list of all of the names of the jobs the players are part of. + */ + public synchronized List<JobsDAOData> getAllJobsOffline(String userName) { + ArrayList<JobsDAOData> jobs = new ArrayList<JobsDAOData>(); + JobsConnection conn = getConnection(); + if (conn == null) + return jobs; + try { + PreparedStatement prest = conn.prepareStatement("SELECT `player_uuid`, `job`, `level`, `experience` FROM `" + prefix + "jobs` WHERE `username` LIKE ?;"); + prest.setString(1, userName); + ResultSet res = prest.executeQuery(); + while (res.next()) { + jobs.add(new JobsDAOData(UUIDUtil.fromBytes(res.getBytes(1)), res.getString(2), res.getInt(3), res.getInt(4))); + } + prest.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + return jobs; + } + + /** + * Join a job (create player-job entry from storage) + * @param player - player that wishes to join the job + * @param job - job that the player wishes to join + */ + public synchronized void joinJob(JobsPlayer jPlayer, Job job) { + JobsConnection conn = getConnection(); + if (conn == null) + return; + try { + int level = 1; + int exp = 0; + if (checkArchive(jPlayer, job).size() > 0) { + List<Integer> info = checkArchive(jPlayer, job); + level = info.get(0); + deleteArchive(jPlayer, job); + } + PreparedStatement prest = conn.prepareStatement("INSERT INTO `" + prefix + "jobs` (`player_uuid`, `username`, `job`, `level`, `experience`) VALUES (?, ?, ?, ?, ?);"); + prest.setBytes(1, UUIDUtil.toBytes(jPlayer.getPlayerUUID())); + prest.setString(2, jPlayer.getUserName()); + prest.setString(3, job.getName()); + prest.setInt(4, level); + prest.setInt(5, exp); + prest.execute(); + prest.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + /** + * Join a job (create player-job entry from storage) + * @param player - player that wishes to join the job + * @param job - job that the player wishes to join + * @throws SQLException + */ + public List<Convert> convertDatabase(Player Player, String table) throws SQLException { + JobsConnection conn = getConnection(); + if (conn == null) + return null; + + List<Convert> list = new ArrayList<Convert>(); + try { + PreparedStatement prest = conn.prepareStatement("SELECT * FROM `" + prefix + table + "`"); + ResultSet res = prest.executeQuery(); + while (res.next()) { + list.add(new Convert(res.getInt("id"), res.getString("username"), UUIDUtil.fromBytes(res.getBytes("player_uuid")), res.getString("job"), res.getInt("level"), res.getInt("experience"))); + } + prest.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + + try { + conn.closeConnection(); + } catch (SQLException e) { + e.printStackTrace(); + } + return list; + } + + public void continueConvertions(List<Convert> list, String table) throws SQLException { + JobsConnection conns = this.getConnection(); + if (conns == null) + return; + PreparedStatement insert = null; + int i = list.size(); + try { + + Statement statement = conns.createStatement(); + if (ConfigManager.getJobsConfiguration().storageMethod.equalsIgnoreCase("sqlite")) { + statement.executeUpdate("TRUNCATE `" + getPrefix() + table + "`"); + } else { + statement.executeUpdate("DELETE from `" + getPrefix() + table + "`"); + } + + insert = conns.prepareStatement("INSERT INTO `" + getPrefix() + table + "` (`username`,`player_uuid`, `job`, `level`, `experience`) VALUES (?, ?, ?, ?, ?);"); + conns.setAutoCommit(false); + while (i > 0) { + i--; + Convert convertData = list.get(i); + insert.setString(1, convertData.GetName()); + insert.setBytes(2, UUIDUtil.toBytes(convertData.GetUuid())); + insert.setString(3, convertData.GetJobName()); + insert.setInt(4, convertData.GetLevel()); + insert.setInt(5, convertData.GetExp()); + insert.addBatch(); + } + insert.executeBatch(); + conns.commit(); + conns.setAutoCommit(true); + } finally { + if (insert != null) { + try { + insert.close(); + } catch (SQLException e) {} + } + } + } + + /** + * Quit a job (delete player-job entry from storage) + * @param player - player that wishes to quit the job + * @param job - job that the player wishes to quit + */ + public synchronized void quitJob(JobsPlayer jPlayer, Job job) { + JobsConnection conn = getConnection(); + if (conn == null) + return; + try { + PreparedStatement prest = conn.prepareStatement("DELETE FROM `" + prefix + "jobs` WHERE `player_uuid` = ? AND `job` = ?;"); + prest.setBytes(1, UUIDUtil.toBytes(jPlayer.getPlayerUUID())); + prest.setString(2, job.getName()); + prest.execute(); + prest.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + /** + * Record job to archive + * @param player - player that wishes to quit the job + * @param job - job that the player wishes to quit + */ + public void recordToArchive(JobsPlayer jPlayer, Job job) { + JobsConnection conn = getConnection(); + if (conn == null) + return; + try { + int level = 1; + int exp = 0; + for (JobProgression progression : jPlayer.getJobProgression()) { + if (progression.getJob().getName().equalsIgnoreCase(job.getName())) { + level = progression.getLevel(); + exp = (int) progression.getExperience(); + } + } + PreparedStatement prest = conn.prepareStatement("INSERT INTO `" + prefix + "archive` (`player_uuid`, `username`, `job`, `level`, `experience`) VALUES (?, ?, ?, ?, ?);"); + prest.setBytes(1, UUIDUtil.toBytes(jPlayer.getPlayerUUID())); + prest.setString(2, jPlayer.getUserName()); + prest.setString(3, job.getName()); + prest.setInt(4, level); + prest.setInt(5, exp); + prest.execute(); + prest.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + /** + * Check job in archive + * @param player - player that wishes to quit the job + * @param job - job that the player wishes to quit + */ + public synchronized List<Integer> checkArchive(JobsPlayer jPlayer, Job job) { + JobsConnection conn = getConnection(); + if (conn == null) + return null; + try { + List<Integer> info = new ArrayList<Integer>(); + PreparedStatement prest = conn.prepareStatement("SELECT `level`, `experience` FROM `" + prefix + "archive` WHERE `player_uuid` = ? AND `job` = ?;"); + prest.setBytes(1, UUIDUtil.toBytes(jPlayer.getPlayerUUID())); + prest.setString(2, job.getName()); + ResultSet res = prest.executeQuery(); + if (res.next()) { + int level = (int) ((res.getInt(1) - (res.getInt(1) * (ConfigManager.getJobsConfiguration().levelLossPercentage / 100.0)))); + if (level < 1) + level = 1; + + int maxLevel = 0; + if (jPlayer.havePermission("jobs." + job.getName() + ".vipmaxlevel") && job.getVipMaxLevel() != 0) + maxLevel = job.getVipMaxLevel(); + else + maxLevel = job.getMaxLevel(); + + if (ConfigManager.getJobsConfiguration().fixAtMaxLevel && res.getInt(1) == maxLevel) + level = res.getInt(1); + info.add(level); + info.add(res.getInt(2)); + } + prest.close(); + return info; + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } + + public List<TopList> getGlobalTopList() { + return getGlobalTopList(0); + } + + /** + * Get all jobs from archive by player + * @param player - targeted player + * @return info - information about jobs + */ + public List<TopList> getGlobalTopList(int start) { + JobsConnection conn = getConnection(); + + List<TopList> names = new ArrayList<TopList>(); + + if (conn == null) + return null; + try { + + PreparedStatement prest = conn.prepareStatement("SELECT username, player_uuid, COUNT(*) AS amount, sum(level) AS totallvl FROM `" + prefix + "jobs` GROUP BY username ORDER BY totallvl DESC LIMIT " + start + ",20;"); + ResultSet res = prest.executeQuery(); + + while (res.next()) { + + TopList top = new TopList(res.getString("username"), res.getInt("totallvl"), 0, res.getBytes("player_uuid")); + + names.add(top); + } + + prest.close(); + return names; + } catch (SQLException e) { + e.printStackTrace(); + } + return names; + } + + /** + * Get all jobs from archive by player + * @param player - targeted player + * @return info - information about jobs + */ + public synchronized List<String> getJobsFromArchive(JobsPlayer jPlayer) { + JobsConnection conn = getConnection(); + if (conn == null) + return null; + try { + List<String> info = new ArrayList<String>(); + PreparedStatement prest = conn.prepareStatement("SELECT `job`, `level`, `experience` FROM `" + prefix + "archive` WHERE `player_uuid` = ?;"); + prest.setBytes(1, UUIDUtil.toBytes(jPlayer.getPlayerUUID())); + ResultSet res = prest.executeQuery(); + while (res.next()) { + + int level = (int) ((res.getInt(2) - (res.getInt(2) * (ConfigManager.getJobsConfiguration().levelLossPercentage / 100.0)))); + if (level < 1) + level = 1; + + int maxLevel = 0; + if (jPlayer.havePermission("jobs." + Jobs.getJob(res.getString(1)).getName() + ".vipmaxlevel")) + maxLevel = Jobs.getJob(res.getString(1)).getVipMaxLevel(); + else + maxLevel = Jobs.getJob(res.getString(1)).getMaxLevel(); + + if (ConfigManager.getJobsConfiguration().fixAtMaxLevel && res.getInt(2) == maxLevel) + level = res.getInt(2); + + info.add(res.getString(1) + ":" + res.getInt(2) + ":" + level + ":" + res.getInt(3)); + } + prest.close(); + return info; + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } + + /** + * Delete job from archive + * @param player - player that wishes to quit the job + * @param job - job that the player wishes to quit + */ + public synchronized void deleteArchive(JobsPlayer jPlayer, Job job) { + JobsConnection conn = getConnection(); + if (conn == null) + return; + try { + PreparedStatement prest = conn.prepareStatement("DELETE FROM `" + prefix + "archive` WHERE `player_uuid` = ? AND `job` = ?;"); + prest.setBytes(1, UUIDUtil.toBytes(jPlayer.getPlayerUUID())); + prest.setString(2, job.getName()); + prest.execute(); + prest.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + /** + * Save player-job information + * @param jobInfo - the information getting saved + */ + public synchronized void save(final JobsPlayer player) { + JobsConnection conn = getConnection(); + if (conn == null) + return; + try { + PreparedStatement prest = conn.prepareStatement("UPDATE `" + prefix + "jobs` SET `level` = ?, `experience` = ? WHERE `player_uuid` = ? AND `job` = ?;"); + for (JobProgression progression : player.getJobProgression()) { + prest.setInt(1, progression.getLevel()); + prest.setInt(2, (int) progression.getExperience()); + prest.setBytes(3, UUIDUtil.toBytes(player.getPlayerUUID())); + prest.setString(4, progression.getJob().getName()); + prest.execute(); + } + prest.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + /** + * Show top list + * @param toplist - toplist by jobs name + * @return + */ + public synchronized ArrayList<TopList> toplist(String jobsname, int limit) { + ArrayList<TopList> jobs = new ArrayList<TopList>(); + JobsConnection conn = getConnection(); + if (conn == null) + return jobs; + try { + PreparedStatement prest = conn.prepareStatement("SELECT `username`, `level`, `experience`,`player_uuid` FROM `" + prefix + "jobs` WHERE `job` LIKE ? ORDER BY `level` DESC, LOWER(username) ASC LIMIT " + limit + ", 15;"); + prest.setString(1, jobsname); + ResultSet res = prest.executeQuery(); + while (res.next()) { + jobs.add(new TopList(res.getString(1), res.getInt(2), res.getInt(3), res.getBytes(4))); + } + prest.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + return jobs; + } + + /** + * Get the number of players that have a particular job + * @param job - the job + * @return the number of players that have a particular job + */ + public synchronized int getSlotsTaken(Job job) { + int slot = 0; + JobsConnection conn = getConnection(); + if (conn == null) + return slot; + try { + PreparedStatement prest = conn.prepareStatement("SELECT COUNT(*) FROM `" + prefix + "jobs` WHERE `job` = ?;"); + prest.setString(1, job.getName()); + ResultSet res = prest.executeQuery(); + if (res.next()) { + slot = res.getInt(1); + } + prest.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + return slot; + } + + /** + * Gets the current schema version + * @return schema version number + */ + protected int getSchemaVersion() { + JobsConnection conn = getConnection(); + if (conn == null) + return 0; + PreparedStatement prest = null; + try { + prest = conn.prepareStatement("SELECT `value` FROM `" + prefix + "config` WHERE `key` = ?;"); + prest.setString(1, "version"); + ResultSet res = prest.executeQuery(); + if (res.next()) { + return Integer.valueOf(res.getString(1)); + } + } catch (SQLException e) { + e.printStackTrace(); + } catch (NumberFormatException e) { + e.printStackTrace(); + } finally { + if (prest != null) { + try { + prest.close(); + } catch (SQLException e) {} + } + } + + return 0; + } + + /** + * Updates schema to version number + * @param version + */ + protected void updateSchemaVersion(int version) { + updateSchemaConfig("version", Integer.toString(version)); + } + + /** + * Updates configuration value + * @param key - the configuration key + * @param value - the configuration value + */ + private void updateSchemaConfig(String key, String value) { + JobsConnection conn = getConnection(); + if (conn == null) + return; + PreparedStatement prest = null; + try { + prest = conn.prepareStatement("UPDATE `" + prefix + "config` SET `value` = ? WHERE `key` = ?;"); + prest.setString(1, value); + prest.setString(2, key); + prest.execute(); + } catch (SQLException e) { + e.printStackTrace(); + } finally { + if (prest != null) { + try { + prest.close(); + } catch (SQLException e) {} + } + } + } + + /** + * Executes an SQL query + * @param sql - The SQL + * @throws SQLException + */ + public void executeSQL(String sql) throws SQLException { + JobsConnection conn = getConnection(); + Statement stmt = conn.createStatement(); + try { + stmt.execute(sql); + } finally { + try { + stmt.close(); + } catch (SQLException e) {} + } + } + + /** + * Get a database connection + * @return JobsConnection object + * @throws SQLException + */ + protected JobsConnection getConnection() { + try { + return pool.getConnection(); + } catch (SQLException e) { + Jobs.getPluginLogger().severe("Unable to connect to the database: " + e.getMessage()); + return null; + } + } + + /** + * Close all active database handles + */ + public synchronized void closeConnections() { + pool.closeConnection(); + } +} diff --git a/com/gamingmesh/jobs/dao/JobsDAOData.java b/com/gamingmesh/jobs/dao/JobsDAOData.java new file mode 100644 index 00000000..888e43e1 --- /dev/null +++ b/com/gamingmesh/jobs/dao/JobsDAOData.java @@ -0,0 +1,82 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.dao; + +import java.util.UUID; + +/** + * Container class to hold information out of the database. + * + * Holds job name + * Experience in the job + * Level in the job + * @author Alex + * + */ +public class JobsDAOData { + private UUID playerUUID; + private String job; + private int level; + private int experience; + + /** + * Constructor class for the DAO side of things. + * @param job - the name of the job + * @param level - the level of the job + * @param experience - the experience of the job + */ + public JobsDAOData(UUID playerUUID, String job, int level, int experience) { + this.playerUUID = playerUUID; + this.job = job; + this.level = level; + this.experience = experience; + } + + /** + * Getter function for the playerUUID + * @return the job name + */ + public UUID getPlayerUUID() { + return playerUUID; + } + + /** + * Getter function for the job name + * @return the job name + */ + public String getJobName() { + return job; + } + + /** + * Getter function for the level + * @return the level in the job + */ + public int getLevel() { + return level; + } + + /** + * Getter function for the experience. + * @return the experience in the job + */ + public double getExperience() { + return (double) experience; + } +} diff --git a/com/gamingmesh/jobs/dao/JobsDAOMySQL.java b/com/gamingmesh/jobs/dao/JobsDAOMySQL.java new file mode 100644 index 00000000..d2388e6f --- /dev/null +++ b/com/gamingmesh/jobs/dao/JobsDAOMySQL.java @@ -0,0 +1,274 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.dao; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.UUID; + +import org.bukkit.Bukkit; + +import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.stuff.ChatColor; +import com.gamingmesh.jobs.stuff.UUIDUtil; + +public class JobsDAOMySQL extends JobsDAO { + private String database; + + private JobsDAOMySQL(String hostname, String database, String username, String password, String prefix) { + super("com.mysql.jdbc.Driver", "jdbc:mysql://" + hostname + "/" + database, username, password, prefix); + this.database = database; + } + + public static JobsDAOMySQL initialize(String hostname, String database, String username, String password, String prefix) { + JobsDAOMySQL dao = new JobsDAOMySQL(hostname, database, username, password, prefix); + try { + dao.setUp(); + } catch (SQLException e) { + e.printStackTrace(); + } + return dao; + } + + @Override + protected synchronized void setupConfig() throws SQLException { + JobsConnection conn = getConnection(); + if (conn == null) { + Jobs.getPluginLogger().severe("Could not run database updates! Could not connect to MySQL!"); + return; + } + PreparedStatement prest = null; + int rows = 0; + try { + // Check for config table + prest = conn.prepareStatement("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = ? AND table_name = ?;"); + prest.setString(1, database); + prest.setString(2, getPrefix() + "config"); + ResultSet res = prest.executeQuery(); + if (res.next()) { + rows = res.getInt(1); + } + } finally { + if (prest != null) { + try { + prest.close(); + } catch (SQLException e) {} + } + } + + if (rows == 0) { + PreparedStatement insert = null; + try { + executeSQL("CREATE TABLE `" + getPrefix() + "config` (`key` varchar(50) NOT NULL PRIMARY KEY, `value` varchar(100) NOT NULL);"); + + insert = conn.prepareStatement("INSERT INTO `" + getPrefix() + "config` (`key`, `value`) VALUES (?, ?);"); + insert.setString(1, "version"); + insert.setString(2, "1"); + insert.execute(); + } finally { + if (insert != null) { + try { + insert.close(); + } catch (SQLException e) {} + } + } + } + } + + @SuppressWarnings("deprecation") + @Override + protected synchronized void checkUpdate1() throws SQLException { + JobsConnection conn = getConnection(); + if (conn == null) { + Jobs.getPluginLogger().severe("Could not run database updates! Could not connect to MySQL!"); + return; + } + PreparedStatement prest = null; + int rows = 0; + try { + // Check for jobs table + prest = conn.prepareStatement("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = ? AND table_name = ?;"); + prest.setString(1, database); + prest.setString(2, getPrefix() + "jobs"); + ResultSet res = prest.executeQuery(); + if (res.next()) { + rows = res.getInt(1); + } + } finally { + if (prest != null) { + try { + prest.close(); + } catch (SQLException e) {} + } + } + + PreparedStatement pst1 = null; + PreparedStatement pst2 = null; + try { + if (rows == 0) { + executeSQL("CREATE TABLE `" + getPrefix() + "jobs` (`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY, `player_uuid` binary(16) NOT NULL, `job` varchar(20), `experience` int, `level` int);"); + } else { + Jobs.getPluginLogger().info("Converting existing usernames to Mojang UUIDs. This could take a long time!"); + + try { + // Check for jobs table id column + // This is extra check to be sure there is no column by this name already + int idrows = 0; + prest = conn.prepareStatement("SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = ? AND table_name = ? AND column_name = ?;"); + prest.setString(1, database); + prest.setString(2, getPrefix() + "jobs"); + prest.setString(3, "id"); + ResultSet res = prest.executeQuery(); + if (res.next()) { + idrows = res.getInt(1); + } + if (idrows == 0) + executeSQL("ALTER TABLE `" + getPrefix() + "jobs` ADD COLUMN `id` int NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;"); + } finally { + + } + + try { + // Check for jobs table id column + // This is extra check to be sure there is no column by this name already + int uuidrows = 0; + prest = conn.prepareStatement("SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = ? AND table_name = ? AND column_name = ?;"); + prest.setString(1, database); + prest.setString(2, getPrefix() + "jobs"); + prest.setString(3, "player_uuid"); + ResultSet res = prest.executeQuery(); + if (res.next()) { + uuidrows = res.getInt(1); + } + if (uuidrows == 0) + executeSQL("ALTER TABLE `" + getPrefix() + "jobs` ADD COLUMN `player_uuid` binary(16) DEFAULT NULL AFTER `id`;"); + } finally { + + } + + pst1 = conn.prepareStatement("SELECT DISTINCT `username` FROM `" + getPrefix() + "jobs` WHERE `player_uuid` IS NULL;"); + ResultSet rs = pst1.executeQuery(); + ArrayList<String> usernames = new ArrayList<String>(); + while (rs.next()) { + usernames.add(rs.getString(1)); + } + + pst2 = conn.prepareStatement("UPDATE `" + getPrefix() + "jobs` SET `player_uuid` = ? WHERE `username` = ?;"); + + int i = 0; + int y = 0; + for (String names : usernames) { + i++; + y++; + if (i >= 10) { + Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.DARK_GREEN + "" + y + " of " + usernames.size()); + i = 0; + } + pst2.setBytes(1, UUIDUtil.toBytes(UUID.fromString(Bukkit.getOfflinePlayer(names).getUniqueId().toString()))); + pst2.setString(2, names); + pst2.execute(); + } + + Jobs.getPluginLogger().info("Mojang UUID conversion complete!"); + } + } finally { + if (pst1 != null) { + try { + pst1.close(); + } catch (SQLException e) {} + } + if (pst2 != null) { + try { + pst2.close(); + } catch (SQLException e) {} + } + } + + checkUpdate2(); + } + + @Override + protected synchronized void checkUpdate2() throws SQLException { + JobsConnection conn = getConnection(); + if (conn == null) { + Jobs.getPluginLogger().severe("Could not run database updates! Could not connect to MySQL!"); + return; + } + PreparedStatement prest = null; + int rows = 0; + try { + // Check for jobs table + prest = conn.prepareStatement("SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = ? AND table_name = ? AND column_name = ?;"); + prest.setString(1, database); + prest.setString(2, getPrefix() + "jobs"); + prest.setString(3, "username"); + ResultSet res = prest.executeQuery(); + if (res.next()) { + rows = res.getInt(1); + } + } finally { + if (prest != null) { + try { + prest.close(); + } catch (SQLException e) {} + } + } + + try { + if (rows == 0) + executeSQL("ALTER TABLE `" + getPrefix() + "jobs` ADD COLUMN `username` varchar(20);"); + } finally { + } + checkUpdate4(); + } + + @Override + protected synchronized void checkUpdate4() throws SQLException { + JobsConnection conn = getConnection(); + if (conn == null) { + Jobs.getPluginLogger().severe("Could not run database updates! Could not connect to MySQL!"); + return; + } + PreparedStatement prest = null; + int rows = 0; + try { + // Check for jobs table + prest = conn.prepareStatement("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = ? AND table_name = ?;"); + prest.setString(1, database); + prest.setString(2, getPrefix() + "archive"); + ResultSet res = prest.executeQuery(); + if (res.next()) { + rows = res.getInt(1); + } + } finally { + if (prest != null) { + try { + prest.close(); + } catch (SQLException e) {} + } + } + + try { + if (rows == 0) + executeSQL("CREATE TABLE `" + getPrefix() + "archive` (`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY, `player_uuid` binary(16) NOT NULL, `username` varchar(20), `job` varchar(20), `experience` int, `level` int);"); + } finally {} + } +} diff --git a/com/gamingmesh/jobs/dao/JobsDAOSQLite.java b/com/gamingmesh/jobs/dao/JobsDAOSQLite.java new file mode 100644 index 00000000..9684159e --- /dev/null +++ b/com/gamingmesh/jobs/dao/JobsDAOSQLite.java @@ -0,0 +1,253 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.dao; + +import java.io.File; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.UUID; + +import org.bukkit.Bukkit; + +import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.stuff.ChatColor; +import com.gamingmesh.jobs.stuff.UUIDUtil; + +public class JobsDAOSQLite extends JobsDAO { + public static JobsDAOSQLite initialize() { + JobsDAOSQLite dao = new JobsDAOSQLite(); + File dir = Jobs.getDataFolder(); + if (!dir.exists()) + dir.mkdirs(); + try { + dao.setUp(); + } catch (SQLException e) { + e.printStackTrace(); + } + return dao; + } + + private JobsDAOSQLite() { + super("org.sqlite.JDBC", "jdbc:sqlite:" + new File(Jobs.getDataFolder(), "jobs.sqlite.db").getPath(), null, null, ""); + } + + @Override + protected synchronized void setupConfig() throws SQLException { + JobsConnection conn = getConnection(); + if (conn == null) { + Jobs.getPluginLogger().severe("Could not run database updates! Could not connect to MySQL!"); + return; + } + + PreparedStatement prest = null; + int rows = 0; + try { + // Check for config table + prest = conn.prepareStatement("SELECT COUNT(*) FROM sqlite_master WHERE name = ?;"); + prest.setString(1, getPrefix() + "config"); + ResultSet res = prest.executeQuery(); + if (res.next()) { + rows = res.getInt(1); + } + } finally { + if (prest != null) { + try { + prest.close(); + } catch (SQLException e) { + } + } + } + + if (rows == 0) { + PreparedStatement insert = null; + try { + executeSQL("CREATE TABLE `" + getPrefix() + "config` (`key` varchar(50) NOT NULL PRIMARY KEY, `value` varchar(100) NOT NULL);"); + + insert = conn.prepareStatement("INSERT INTO `" + getPrefix() + "config` (`key`, `value`) VALUES (?, ?);"); + insert.setString(1, "version"); + insert.setString(2, "1"); + insert.execute(); + } finally { + if (insert != null) { + try { + insert.close(); + } catch (SQLException e) { + } + } + } + } + } + + @SuppressWarnings("deprecation") + @Override + protected synchronized void checkUpdate1() throws SQLException { + JobsConnection conn = getConnection(); + if (conn == null) { + Jobs.getPluginLogger().severe("Could not run database updates! Could not connect to MySQL!"); + return; + } + PreparedStatement prest = null; + int rows = 0; + try { + // Check for jobs table + prest = conn.prepareStatement("SELECT COUNT(*) FROM sqlite_master WHERE name = ?;"); + prest.setString(1, getPrefix() + "jobs"); + ResultSet res = prest.executeQuery(); + if (res.next()) { + rows = res.getInt(1); + } + } finally { + if (prest != null) { + try { + prest.close(); + } catch (SQLException e) { + } + } + } + + PreparedStatement pst1 = null; + PreparedStatement pst2 = null; + try { + if (rows > 0) { + Jobs.getPluginLogger().info("Converting existing usernames to Mojang UUIDs. This could take a long time!!!"); + executeSQL("ALTER TABLE `" + getPrefix() + "jobs` RENAME TO `" + getPrefix() + "jobs_old`;"); + executeSQL("ALTER TABLE `" + getPrefix() + "jobs_old` ADD COLUMN `player_uuid` binary(16) DEFAULT NULL;"); + } + + executeSQL("CREATE TABLE `" + getPrefix() + "jobs` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `player_uuid` binary(16) NOT NULL, `job` varchar(20), `experience` int, `level` int);"); + + if (rows > 0) { + pst1 = conn.prepareStatement("SELECT DISTINCT `username` FROM `" + getPrefix() + "jobs_old` WHERE `player_uuid` IS NULL;"); + ResultSet rs = pst1.executeQuery(); + ArrayList<String> usernames = new ArrayList<String>(); + while (rs.next()) { + usernames.add(rs.getString(1)); + } + pst2 = conn.prepareStatement("UPDATE `" + getPrefix() + "jobs_old` SET `player_uuid` = ? WHERE `username` = ?;"); + int i = 0; + int y = 0; + for (String names : usernames) { + i++; + y++; + if (i >= 50) { + Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.DARK_GREEN + "" + y + " of " + usernames.size()); + i = 0; + } + pst2.setBytes(1, UUIDUtil.toBytes(UUID.fromString(Bukkit.getOfflinePlayer(names).getUniqueId().toString()))); + pst2.setString(2, names); + pst2.execute(); + } + executeSQL("INSERT INTO `" + getPrefix() + "jobs` (`player_uuid`, `job`, `experience`, `level`) SELECT `player_uuid`, `job`, `experience`, `level` FROM `" + getPrefix() + "jobs_old`;"); + } + } finally { + if (pst1 != null) { + try { + pst1.close(); + } catch (SQLException e) { + } + } + if (pst2 != null) { + try { + pst2.close(); + } catch (SQLException e) { + } + } + } + + if (rows > 0) { + executeSQL("DROP TABLE `" + getPrefix() + "jobs_old`;"); + + Jobs.getPluginLogger().info("Mojang UUID conversion complete!"); + } + checkUpdate2(); + } + + @Override + protected synchronized void checkUpdate2() throws SQLException { + JobsConnection conn = getConnection(); + if (conn == null) { + Jobs.getPluginLogger().severe("Could not run database updates! Could not connect to MySQL!"); + return; + } + PreparedStatement prest = null; + int rows = 0; + try { + // Check for jobs table + prest = conn.prepareStatement("SELECT COUNT(*) FROM sqlite_master WHERE name = ?;"); + prest.setString(1, getPrefix() + "jobs"); + ResultSet res = prest.executeQuery(); + if (res.next()) { + rows = res.getInt(1); + } + } finally { + if (prest != null) { + try { + prest.close(); + } catch (SQLException e) { + } + } + } + + try { + if (rows > 0) { + executeSQL("ALTER TABLE `" + getPrefix() + "jobs` ADD COLUMN `username` varchar(20);"); + } + + } finally { + } + checkUpdate4(); + } + + @Override + protected synchronized void checkUpdate4() throws SQLException { + JobsConnection conn = getConnection(); + if (conn == null) { + Jobs.getPluginLogger().severe("Could not run database updates! Could not connect to MySQL!"); + return; + } + PreparedStatement prest = null; + int rows = 0; + try { + // Check for jobs table + prest = conn.prepareStatement("SELECT COUNT(*) FROM sqlite_master WHERE name = ?;"); + prest.setString(1, getPrefix() + "archive"); + ResultSet res = prest.executeQuery(); + if (res.next()) { + rows = res.getInt(1); + } + } finally { + if (prest != null) { + try { + prest.close(); + } catch (SQLException e) { + } + } + } + + try { + if (rows == 0) { + executeSQL("CREATE TABLE `" + getPrefix() + "archive` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `player_uuid` binary(16) NOT NULL, `username` varchar(20), `job` varchar(20), `experience` int, `level` int);"); + } + + } finally { + } + } +} diff --git a/com/gamingmesh/jobs/dao/JobsDriver.java b/com/gamingmesh/jobs/dao/JobsDriver.java new file mode 100644 index 00000000..8139c08b --- /dev/null +++ b/com/gamingmesh/jobs/dao/JobsDriver.java @@ -0,0 +1,58 @@ +package com.gamingmesh.jobs.dao; + +import java.sql.Connection; +import java.sql.Driver; +import java.sql.DriverPropertyInfo; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.util.Properties; +import java.util.logging.Logger; + +public class JobsDriver + implements Driver +{ + private Driver driver; + + public JobsDriver(Driver driver) + { + this.driver = driver; + } + + public Connection connect(String url, Properties info) + throws SQLException + { + return this.driver.connect(url, info); + } + + public boolean acceptsURL(String url) + throws SQLException + { + return this.driver.acceptsURL(url); + } + + public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) + throws SQLException + { + return this.driver.getPropertyInfo(url, info); + } + + public int getMajorVersion() + { + return this.driver.getMajorVersion(); + } + + public int getMinorVersion() + { + return this.driver.getMinorVersion(); + } + + public boolean jdbcCompliant() + { + return this.driver.jdbcCompliant(); + } + +@Override +public Logger getParentLogger() throws SQLFeatureNotSupportedException { + return this.driver.getParentLogger(); +} +} diff --git a/com/gamingmesh/jobs/dao/JobsDrivers.java b/com/gamingmesh/jobs/dao/JobsDrivers.java new file mode 100644 index 00000000..e5d17d53 --- /dev/null +++ b/com/gamingmesh/jobs/dao/JobsDrivers.java @@ -0,0 +1,69 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.dao; + +import java.sql.Connection; +import java.sql.Driver; +import java.sql.DriverPropertyInfo; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.util.Properties; +import java.util.logging.Logger; + +public class JobsDrivers implements Driver { + private Driver driver; + public JobsDrivers(Driver driver) { + this.driver = driver; + } + + @Override + public Connection connect(String url, Properties info) throws SQLException { + return driver.connect(url, info); + } + + @Override + public boolean acceptsURL(String url) throws SQLException { + return driver.acceptsURL(url); + } + + @Override + public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { + return driver.getPropertyInfo(url, info); + } + + @Override + public int getMajorVersion() { + return driver.getMajorVersion(); + } + + @Override + public int getMinorVersion() { + return driver.getMinorVersion(); + } + + @Override + public boolean jdbcCompliant() { + return driver.jdbcCompliant(); + } + + @Override + public Logger getParentLogger() throws SQLFeatureNotSupportedException { + return driver.getParentLogger(); + } +} diff --git a/com/gamingmesh/jobs/economy/.gitignore b/com/gamingmesh/jobs/economy/.gitignore new file mode 100644 index 00000000..a1f1b23c --- /dev/null +++ b/com/gamingmesh/jobs/economy/.gitignore @@ -0,0 +1,6 @@ +/BlackholeEconomy.class +/BufferedEconomy.class +/BufferedPayment.class +/Economy.class +/VaultEconomy.class +/PaymentData.class diff --git a/com/gamingmesh/jobs/economy/BlackholeEconomy.java b/com/gamingmesh/jobs/economy/BlackholeEconomy.java new file mode 100644 index 00000000..3492aff9 --- /dev/null +++ b/com/gamingmesh/jobs/economy/BlackholeEconomy.java @@ -0,0 +1,58 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.economy; + +import org.bukkit.OfflinePlayer; + +public class BlackholeEconomy implements Economy { + @Override + public boolean depositPlayer(OfflinePlayer offlinePlayer, double money) { + return true; + } + + @Override + public boolean withdrawPlayer(OfflinePlayer offlinePlayer, double money) { + return true; + } + + @Override + public String format(double money) { + return String.format("$%.2f", money); + } + + @Override + public boolean hasMoney(OfflinePlayer offlinePlayer, double money) { + return true; + } + + @Override + public boolean hasMoney(String PlayerName, double money) { + return true; + } + + @Override + public boolean withdrawPlayer(String PlayerName, double money) { + return true; + } + + @Override + public boolean depositPlayer(String PlayerName, double money) { + return true; + } +} diff --git a/com/gamingmesh/jobs/economy/BufferedEconomy.java b/com/gamingmesh/jobs/economy/BufferedEconomy.java new file mode 100644 index 00000000..818b6bcf --- /dev/null +++ b/com/gamingmesh/jobs/economy/BufferedEconomy.java @@ -0,0 +1,199 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.economy; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.LinkedBlockingQueue; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.JobsPlugin; +import com.gamingmesh.jobs.api.JobsPaymentEvent; +import com.gamingmesh.jobs.config.ConfigManager; +import com.gamingmesh.jobs.container.JobsPlayer; +import com.gamingmesh.jobs.i18n.Language; +import com.gamingmesh.jobs.stuff.ActionBar; +import com.gamingmesh.jobs.stuff.ChatColor; +import com.gamingmesh.jobs.tasks.BufferedPaymentTask; + +public class BufferedEconomy { + private JobsPlugin plugin; + private Economy economy; + private LinkedBlockingQueue<BufferedPayment> payments = new LinkedBlockingQueue<BufferedPayment>(); + private final Map<UUID, BufferedPayment> paymentCache = Collections.synchronizedMap(new HashMap<UUID, BufferedPayment>()); + + private OfflinePlayer ServerAccount = null; + private OfflinePlayer ServerTaxesAccount = null; + + PaymentData PaymentData = new PaymentData(); + + public BufferedEconomy(JobsPlugin plugin, Economy economy) { + this.plugin = plugin; + this.economy = economy; + } + + /** + * Add payment to player's payment buffer + * @param player - player to be paid + * @param amount - amount to be paid + */ + public void pay(JobsPlayer player, double amount, double exp) { + if (amount == 0) + return; + pay(new BufferedPayment(player.getPlayer(), amount, exp)); + } + + /** + * Add payment to player's payment buffer + * @param payment - payment to be paid + */ + public void pay(BufferedPayment payment) { + payments.add(payment); + } + + public String format(double money) { + return economy.format(money); + } + + /** + * Payout all players the amount they are going to be paid + */ + @SuppressWarnings("deprecation") + public void payAll() { + if (payments.isEmpty()) + return; + + synchronized (paymentCache) { + + Double TotalAmount = 0.0; + Double TaxesAmount = 0.0; + + // combine all payments using paymentCache + while (!payments.isEmpty()) { + BufferedPayment payment = payments.remove(); + TotalAmount += payment.getAmount(); + + if (ConfigManager.getJobsConfiguration().UseTaxes) { + TaxesAmount += payment.getAmount() * (ConfigManager.getJobsConfiguration().TaxesAmount / 100.0); + } + + UUID uuid = payment.getOfflinePlayer().getUniqueId(); + if (paymentCache.containsKey(uuid)) { + BufferedPayment existing = paymentCache.get(uuid); + + double money = payment.getAmount(); + double exp = payment.getExp(); + + if (ConfigManager.getJobsConfiguration().TakeFromPlayersPayment) { + money = money - (money * (ConfigManager.getJobsConfiguration().TaxesAmount / 100.0)); + } + + existing.setAmount(existing.getAmount() + money); + existing.setExp(existing.getExp() + exp); + } else { + + double money = payment.getAmount(); + + if (ConfigManager.getJobsConfiguration().TakeFromPlayersPayment) { + payment.setAmount(money - (money * (ConfigManager.getJobsConfiguration().TaxesAmount / 100.0))); + } + + paymentCache.put(uuid, payment); + } + } + + boolean hasMoney = false; + String ServerAccountname = ConfigManager.getJobsConfiguration().ServerAcountName; + String ServerTaxesAccountname = ConfigManager.getJobsConfiguration().ServertaxesAcountName; + if (this.ServerAccount == null) + this.ServerAccount = Bukkit.getOfflinePlayer(ServerAccountname); + + if (this.ServerTaxesAccount == null) + this.ServerTaxesAccount = Bukkit.getOfflinePlayer(ServerAccountname); + + if (ConfigManager.getJobsConfiguration().UseTaxes && ConfigManager.getJobsConfiguration().TransferToServerAccount && ServerTaxesAccount != null) { + + economy.depositPlayer(ServerTaxesAccount, TaxesAmount); + + if (ServerTaxesAccount.isOnline()) { + if (!Jobs.actionbartoggle.containsKey(ServerTaxesAccountname) && ConfigManager.getJobsConfiguration().JobsToggleEnabled) + Jobs.actionbartoggle.put(ServerTaxesAccountname, true); + if (Jobs.actionbartoggle.containsKey(ServerTaxesAccountname) && Jobs.actionbartoggle.get(ServerTaxesAccountname)) { + ActionBar.send((Player) ServerTaxesAccount, Language.getMessage("message.taxes").replace("[amount]", String.valueOf((int) (TotalAmount * 100) / 100.0))); + } + } + } + + if (ConfigManager.getJobsConfiguration().UseServerAccount) { + if (economy.hasMoney(ServerAccountname, TotalAmount)) { + hasMoney = true; + economy.withdrawPlayer(ServerAccountname, TotalAmount); + } + } + + // Schedule all payments + int i = 0; + for (BufferedPayment payment : paymentCache.values()) { + i++; + + // JobsJoin event + JobsPaymentEvent JobsPaymentEvent = new JobsPaymentEvent(payment.getOfflinePlayer(), payment.getAmount()); + Bukkit.getServer().getPluginManager().callEvent(JobsPaymentEvent); + // If event is canceled, dont do anything + if (JobsPaymentEvent.isCancelled()) + continue; + + if (ConfigManager.getJobsConfiguration().isEconomyAsync()) { + if (ConfigManager.getJobsConfiguration().UseServerAccount) { + if (!hasMoney) { + ActionBar.send(payment.getOfflinePlayer().getPlayer(), ChatColor.RED + Language.getMessage("economy.error.nomoney")); + continue; + } else + Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, new BufferedPaymentTask(this, economy, payment), i); + } else + Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, new BufferedPaymentTask(this, economy, payment), i); + + // Action bar stuff + ActionBar.ShowActionBar(payment); + } else { + if (ConfigManager.getJobsConfiguration().UseServerAccount) { + if (!hasMoney) { + ActionBar.send(payment.getOfflinePlayer().getPlayer(), ChatColor.RED + Language.getMessage("economy.error.nomoney")); + continue; + } else + Bukkit.getScheduler().runTaskLater(plugin, new BufferedPaymentTask(this, economy, payment), i); + } else + Bukkit.getScheduler().runTaskLater(plugin, new BufferedPaymentTask(this, economy, payment), i); + + // Action bar stuff + ActionBar.ShowActionBar(payment); + } + } + // empty payment cache + paymentCache.clear(); + } + + } +} diff --git a/com/gamingmesh/jobs/economy/BufferedPayment.java b/com/gamingmesh/jobs/economy/BufferedPayment.java new file mode 100644 index 00000000..6efa59d1 --- /dev/null +++ b/com/gamingmesh/jobs/economy/BufferedPayment.java @@ -0,0 +1,53 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.economy; + +import org.bukkit.OfflinePlayer; + +public class BufferedPayment { + private OfflinePlayer offlinePlayer; + private double amount= 0.0; + private double exp = 0.0; + + public BufferedPayment(OfflinePlayer offlinePlayer, double amount, double exp) { + this.offlinePlayer = offlinePlayer; + this.amount = amount; + this.exp = exp; + } + + public OfflinePlayer getOfflinePlayer() { + return offlinePlayer; + } + + public double getAmount() { + return amount; + } + + public double getExp() { + return exp; + } + + public void setAmount(double amount) { + this.amount = amount; + } + + public void setExp(double exp) { + this.exp = exp; + } +} diff --git a/com/gamingmesh/jobs/economy/Economy.java b/com/gamingmesh/jobs/economy/Economy.java new file mode 100644 index 00000000..a256d42e --- /dev/null +++ b/com/gamingmesh/jobs/economy/Economy.java @@ -0,0 +1,31 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.economy; + +import org.bukkit.OfflinePlayer; + +public interface Economy { + public boolean depositPlayer(OfflinePlayer offlinePlayer, double money); + public boolean withdrawPlayer(OfflinePlayer offlinePlayer, double money); + public String format(double money); + boolean hasMoney(OfflinePlayer offlinePlayer, double money); + boolean hasMoney(String PlayerName, double money); + boolean withdrawPlayer(String PlayerName, double money); + boolean depositPlayer(String PlayerName, double money); +} diff --git a/com/gamingmesh/jobs/economy/PaymentData.java b/com/gamingmesh/jobs/economy/PaymentData.java new file mode 100644 index 00000000..8ae1ec3d --- /dev/null +++ b/com/gamingmesh/jobs/economy/PaymentData.java @@ -0,0 +1,132 @@ +package com.gamingmesh.jobs.economy; + +public class PaymentData { + + Long time = 0L; + Long lastAnnouced = 0L; + Double Payment = 0.0; + public boolean Informed = false; + + public PaymentData(Long time, Double Payment, Long lastAnnouced, boolean Informed) { + this.time = time; + this.Payment = Payment; + this.lastAnnouced = lastAnnouced; + this.Informed = Informed; + } + + public PaymentData() { + } + + public Long GetTime() { + return this.time; + } + + public Double GetAmount() { + return this.Payment; + } + + public Double GetAmountBylimit(int limit) { + if (this.Payment > limit) + return (double) limit; + return (int) (this.Payment * 100) / 100.0; + } + + public Long GetLastAnnounced() { + return this.lastAnnouced; + } + + public boolean IsAnnounceTime(int time) { + if (this.lastAnnouced + (time * 1000) > System.currentTimeMillis()) + return false; + SetAnnouncmentTime(); + return true; + } + + public void SetAnnouncmentTime() { + this.lastAnnouced = System.currentTimeMillis(); + } + + public void AddNewAmount(Double Payment) { + this.time = System.currentTimeMillis(); + this.Payment = Payment; + } + + public void Setinformed() { + this.Informed = true; + } + + public void SetNotInformed() { + this.Informed = false; + } + + public void AddAmount(Double Payment) { + this.Payment = this.Payment + Payment; + } + + public int GetLeftTime(int time) { + int left = 0; + if (this.time + (time * 1000) > System.currentTimeMillis()) + left = (int) ((this.time + (time * 1000) - System.currentTimeMillis()) / 1000); + return left; + } + + public boolean IsOverMoneyLimit(int limit) { + if (this.Payment < limit) + return false; + return true; + } + + public boolean IsOverTimeLimit(int time) { + if (this.time + (time * 1000) > System.currentTimeMillis()) + return false; + + if (this.Informed) + this.Informed = false; + this.time = System.currentTimeMillis(); + this.Payment = 0.0; + return true; + } + + public boolean IsReachedLimit(int time, int limit) { + if (IsOverMoneyLimit(limit) && !IsOverTimeLimit(time)) + return true; + return false; + } + + public int GetLeftsec(int time) { + int lefttime1 = GetLeftTime(time); + int sec = 0; + if (lefttime1 >= 3600) { + lefttime1 = lefttime1 - ((int) (lefttime1 / 3600) * 3600); + if (lefttime1 > 60 && lefttime1 < 3600) { + sec = lefttime1 - ((int) (lefttime1 / 60) * 60); + } else if (lefttime1 < 60) + sec = lefttime1; + } else if (lefttime1 > 60 && lefttime1 < 3600) { + sec = lefttime1 - ((int) (lefttime1 / 60) * 60); + } else + sec = lefttime1; + return sec; + } + + public int GetLeftMin(int time) { + int lefttime1 = GetLeftTime(time); + int min = 0; + if (lefttime1 >= 3600) { + lefttime1 = lefttime1 - ((int) (lefttime1 / 3600) * 3600); + if (lefttime1 > 60 && lefttime1 < 3600) + min = lefttime1 / 60; + } else if (lefttime1 > 60 && lefttime1 < 3600) + min = lefttime1 / 60; + return min; + } + + public int GetLeftHour(int time) { + int lefttime1 = GetLeftTime(time); + int hour = 0; + if (lefttime1 >= 3600) { + hour = lefttime1 / 3600; + } + return hour; + } +} diff --git a/com/gamingmesh/jobs/economy/VaultEconomy.java b/com/gamingmesh/jobs/economy/VaultEconomy.java new file mode 100644 index 00000000..d4f6e6de --- /dev/null +++ b/com/gamingmesh/jobs/economy/VaultEconomy.java @@ -0,0 +1,69 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.economy; + +import org.bukkit.OfflinePlayer; + +public class VaultEconomy implements Economy { + private net.milkbowl.vault.economy.Economy vault; + + public VaultEconomy(net.milkbowl.vault.economy.Economy vault) { + this.vault = vault; + } + + @Override + public boolean depositPlayer(OfflinePlayer offlinePlayer, double money) { + return vault.depositPlayer(offlinePlayer, money).transactionSuccess(); + } + + @SuppressWarnings("deprecation") + @Override + public boolean depositPlayer(String PlayerName, double money) { + return vault.depositPlayer(PlayerName, money).transactionSuccess(); + } + + @Override + public boolean withdrawPlayer(OfflinePlayer offlinePlayer, double money) { + return vault.withdrawPlayer(offlinePlayer, money).transactionSuccess(); + } + + @SuppressWarnings("deprecation") + @Override + public boolean withdrawPlayer(String PlayerName, double money) { + return vault.withdrawPlayer(PlayerName, money).transactionSuccess(); + } + + @Override + public boolean hasMoney(OfflinePlayer offlinePlayer, double money) { + if (offlinePlayer.getName() == null) + return false; + return vault.has(offlinePlayer, money); + } + + @SuppressWarnings("deprecation") + @Override + public boolean hasMoney(String PlayerName, double money) { + return vault.has(PlayerName, money); + } + + @Override + public String format(double money) { + return vault.format(money); + } +} diff --git a/com/gamingmesh/jobs/i18n/.gitignore b/com/gamingmesh/jobs/i18n/.gitignore new file mode 100644 index 00000000..9eb6489c --- /dev/null +++ b/com/gamingmesh/jobs/i18n/.gitignore @@ -0,0 +1 @@ +/Language.class diff --git a/com/gamingmesh/jobs/i18n/Language.java b/com/gamingmesh/jobs/i18n/Language.java new file mode 100644 index 00000000..49ded51b --- /dev/null +++ b/com/gamingmesh/jobs/i18n/Language.java @@ -0,0 +1,84 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.i18n; + +import java.util.Locale; +import org.bukkit.ChatColor; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.plugin.java.JavaPlugin; + +import com.gamingmesh.jobs.JobsPlugin; +import com.gamingmesh.jobs.config.ConfigManager; +import com.gamingmesh.jobs.config.YmlMaker; + +public class Language { + public static FileConfiguration enlocale; + public static FileConfiguration customlocale; + + static { + customlocale = new YmlMaker((JavaPlugin) JobsPlugin.instance, "locale/messages_" + ConfigManager.getJobsConfiguration().localeString + ".yml").getConfig(); + enlocale = new YmlMaker((JavaPlugin) JobsPlugin.instance, "locale/messages_en.yml").getConfig(); + if (customlocale == null) + customlocale = enlocale; + } + + private Language() { + } + + /** + * Reloads the config + */ + public static void reload(Locale locale) { + customlocale = new YmlMaker((JavaPlugin) JobsPlugin.instance, "locale/messages_" + ConfigManager.getJobsConfiguration().localeString + ".yml").getConfig(); + enlocale = new YmlMaker((JavaPlugin) JobsPlugin.instance, "locale/messages_en.yml").getConfig(); + if (customlocale == null) + customlocale = enlocale; + } + + /** + * Get the message with the correct key + * @param key - the key of the message + * @return the message + */ + public static String getMessage(String key) { + if (customlocale == null || !customlocale.contains(key)) + return enlocale.contains(key) == true ? ChatColor.translateAlternateColorCodes('&', enlocale.getString(key)) : "Cant find locale"; + return customlocale.contains(key) == true ? ChatColor.translateAlternateColorCodes('&', customlocale.getString(key)) : "Cant find locale"; + } + + /** + * Get the message with the correct key + * @param key - the key of the message + * @return the message + */ + public static String getDefaultMessage(String key) { + return enlocale.contains(key) == true ? ChatColor.translateAlternateColorCodes('&', enlocale.getString(key)) : "Cant find locale"; + } + + /** + * Check if key exists + * @param key - the key of the message + * @return true/false + */ + public static boolean containsKey(String key) { + if (customlocale == null || !customlocale.contains(key)) + return enlocale.contains(key); + return customlocale.contains(key); + } +} diff --git a/com/gamingmesh/jobs/listeners/.gitignore b/com/gamingmesh/jobs/listeners/.gitignore new file mode 100644 index 00000000..1348e24e --- /dev/null +++ b/com/gamingmesh/jobs/listeners/.gitignore @@ -0,0 +1,8 @@ +/JobsListener.class +/JobsPaymentListener.class +/McMMOlistener.class +/PistonProtectionListener.class +/VanillaListeners.class +/JobsPaymentListener$1.class +/JobsListener$1.class +/JobsPaymentListener$2.class diff --git a/com/gamingmesh/jobs/listeners/JobsListener.java b/com/gamingmesh/jobs/listeners/JobsListener.java new file mode 100644 index 00000000..aeadc3da --- /dev/null +++ b/com/gamingmesh/jobs/listeners/JobsListener.java @@ -0,0 +1,440 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.listeners; + +import java.util.regex.Pattern; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +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.block.SignChangeEvent; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerChangedWorldEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.world.WorldLoadEvent; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionDefault; +import org.bukkit.plugin.PluginManager; + +import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.JobsPlugin; +import com.gamingmesh.jobs.config.ConfigManager; +import com.gamingmesh.jobs.container.Job; +import com.gamingmesh.jobs.container.JobsPlayer; +import com.gamingmesh.jobs.i18n.Language; + +public class JobsListener implements Listener { + // hook to the main plugin + private JobsPlugin plugin; + + public JobsListener(JobsPlugin plugin) { + this.plugin = plugin; + } + + // @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = false) + // public void onGuiRightClick(InventoryClickEvent event) { + // if (Gui.GuiTools.GuiList.size() == 0) + // return; + // + // Player player = (Player) event.getWhoClicked(); + // + // if (!Gui.GuiTools.GuiList.containsKey(player.getName())) + // return; + // + // if (event.getClick() != ClickType.RIGHT) + // return; + // + // event.setCancelled(true); + // + // GuiInfoList joblist = Gui.GuiTools.GuiList.get(player.getName()); + // + // if (joblist.isJobInfo()) + // return; + // + // int slot = event.getRawSlot(); + // + // if (slot < joblist.getJobList().size()) { + // Bukkit.dispatchCommand(player, "jobs join " + joblist.getJobList().get(slot).getName()); + // player.getOpenInventory().getTopInventory().setContents(GuiTools.CreateJobsGUI(player).getContents()); + // } + // } + // + // @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = false) + // public void onGuiLeftClick(InventoryClickEvent event) { + // if (Gui.GuiTools.GuiList.size() == 0) + // return; + // + // Player player = (Player) event.getWhoClicked(); + // + // if (!Gui.GuiTools.GuiList.containsKey(player.getName())) + // return; + // + // event.setCancelled(true); + // + // if (event.getClick() != ClickType.LEFT) + // return; + // + // GuiInfoList joblist = Gui.GuiTools.GuiList.get(player.getName()); + // + // if (joblist.isJobInfo()) + // return; + // + // int slot = event.getRawSlot(); + // + // if (slot < joblist.getJobList().size()) { + // player.closeInventory(); + // player.openInventory(GuiTools.CreateJobsSubGUI(player, joblist.getJobList().get(slot))); + // } + // } + // + // @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = false) + // public void onGuiLeftSubClick(InventoryClickEvent event) { + // if (Gui.GuiTools.GuiList.size() == 0) + // return; + // + // Player player = (Player) event.getWhoClicked(); + // + // if (!Gui.GuiTools.GuiList.containsKey(player.getName())) + // return; + // + // event.setCancelled(true); + // + // if (event.getClick() != ClickType.LEFT) + // return; + // + // GuiInfoList joblist = Gui.GuiTools.GuiList.get(player.getName()); + // + // if (!joblist.isJobInfo()) + // return; + // + // int slot = event.getRawSlot(); + // + // if (slot == joblist.getbackButton()) { + // player.closeInventory(); + // player.openInventory(GuiTools.CreateJobsGUI(player)); + // } + // } + // + // @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = false) + // public void onGuiClose(InventoryCloseEvent event) { + // if (Gui.GuiTools.GuiList.size() == 0) + // return; + // + // Player player = (Player) event.getPlayer(); + // + // if (Gui.GuiTools.GuiList.containsKey(player.getName())) + // Gui.GuiTools.GuiList.remove(player.getName()); + // } + + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerJoin(final PlayerJoinEvent event) { + // make sure plugin is enabled + if (!plugin.isEnabled()) + return; + Jobs.getPlayerManager().playerJoin(event.getPlayer()); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerJoinMonitor(PlayerJoinEvent event) { + // make sure plugin is enabled + if (!plugin.isEnabled()) + return; + + /* + * We need to recalculate again to check for world permission and revoke permissions + * if we don't have world permission (from some other permission manager). It's + * necessary to call this twice in case somebody is relying on permissions from this + * plugin on entry to the world. + */ + final JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(event.getPlayer()); + Jobs.getPermissionHandler().recalculatePermissions(jPlayer); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerQuit(PlayerQuitEvent event) { + // make sure plugin is enabled + if (!plugin.isEnabled()) + return; + Jobs.getPlayerManager().playerQuit(event.getPlayer()); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerWorldChange(PlayerChangedWorldEvent event) { + if (!plugin.isEnabled()) + return; + + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(event.getPlayer()); + Jobs.getPermissionHandler().recalculatePermissions(jPlayer); + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onSignInteract(PlayerInteractEvent event) { + + if (!plugin.isEnabled()) + return; + + if (!ConfigManager.getJobsConfiguration().SignsEnabled) + return; + + Player player = (Player) event.getPlayer(); + if (event.getAction() != Action.RIGHT_CLICK_BLOCK) + return; + + Material material = event.getClickedBlock().getType(); + + if (material != Material.WALL_SIGN && material != Material.SIGN && material != Material.SIGN_POST) + return; + + Block block = event.getClickedBlock(); + + if (block == null) + return; + + if (!(block.getState() instanceof Sign)) + return; + + Sign sign = (Sign) block.getState(); + String FirstLine = sign.getLine(0); + + if (!FirstLine.equalsIgnoreCase(Language.getMessage("signs.topline"))) + return; + + String command = ChatColor.stripColor(sign.getLine(1)); + + for (String key : ConfigManager.getJobsConfiguration().keys) { + if (command.equalsIgnoreCase(ChatColor.stripColor(Language.getMessage("signs.secondline." + key)))) { + command = key; + break; + } + } + + Bukkit.dispatchCommand(player, "jobs " + command + " " + ChatColor.stripColor(sign.getLine(2)) + " " + ChatColor.stripColor(sign.getLine(3))); + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onSignTopListCreate(SignChangeEvent event) { + if (!plugin.isEnabled()) + return; + + if (!ConfigManager.getJobsConfiguration().SignsEnabled) + return; + + Block block = event.getBlock(); + + if (!(block.getState() instanceof Sign)) + return; + + Sign sign = (Sign) block.getState(); + + final String signtype = ChatColor.stripColor(event.getLine(1)); + + if (!ChatColor.stripColor(event.getLine(0)).equalsIgnoreCase("[Jobs]")) + return; + + if (!signtype.equalsIgnoreCase("toplist") && !signtype.equalsIgnoreCase("gtoplist")) + return; + + Player player = (Player) event.getPlayer(); + + if (!event.getPlayer().hasPermission("jobs.command.signs")) { + event.setCancelled(true); + player.sendMessage(Language.getMessage("signs.cantcreate")); + return; + } + + String jobname = ChatColor.stripColor(event.getLine(2)).toLowerCase(); + + final Job job = Jobs.getJob(jobname); + + if (job == null && !signtype.equalsIgnoreCase("gtoplist")) { + player.sendMessage(Language.getMessage("command.top.error.nojob")); + return; + } + + boolean special = false; + int Number = 0; + String numberString = ChatColor.stripColor(event.getLine(3)).toLowerCase(); + if (numberString.contains("s")) { + numberString = numberString.replace("s", ""); + special = true; + } + + try { + Number = Integer.parseInt(numberString); + } catch (NumberFormatException e) { + player.sendMessage(Language.getMessage("command.error.notNumber")); + return; + } + + Signs.Sign signInfo = new Signs.Sign(); + + Location loc = sign.getLocation(); + + int category = 1; + if (Signs.SignUtil.Signs.GetAllSigns().size() > 0) + category = Signs.SignUtil.Signs.GetAllSigns().get(Signs.SignUtil.Signs.GetAllSigns().size() - 1).GetCategory() + 1; + signInfo.setNumber(Number); + signInfo.setWorld(loc.getWorld().getName()); + signInfo.setX(loc.getX()); + signInfo.setY(loc.getY()); + signInfo.setZ(loc.getZ()); + signInfo.setCategory(category); + if (!signtype.equalsIgnoreCase("gtoplist")) + signInfo.setJobName(job.getName()); + else + signInfo.setJobName("gtoplist"); + signInfo.setSpecial(special); + + Signs.SignUtil.Signs.addSign(signInfo); + Signs.SignUtil.saveSigns(); + event.setCancelled(true); + + Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(JobsPlugin.instance, new Runnable() { + public void run() { + if (!signtype.equalsIgnoreCase("gtoplist")) + Signs.SignUtil.SignUpdate(job.getName()); + else + Signs.SignUtil.SignUpdate("gtoplist"); + return; + } + }, 1L); + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onSignChange(SignChangeEvent event) { + if (!plugin.isEnabled()) + return; + + if (!ConfigManager.getJobsConfiguration().SignsEnabled) + return; + + if (ChatColor.stripColor(event.getLine(0)).equalsIgnoreCase(ChatColor.stripColor(Language.getMessage("signs.topline"))) && !ChatColor.stripColor(event.getLine(1)).equalsIgnoreCase("toplist")) + event.setLine(0, Convert(Language.getMessage("signs.topline"))); + else + return; + + if (!event.getPlayer().hasPermission("jobs.command.signs")) { + event.setCancelled(true); + event.getPlayer().sendMessage(Language.getMessage("signs.cantcreate")); + return; + } + + String command = ChatColor.stripColor(event.getLine(1)).toLowerCase(); + + for (String key : ConfigManager.getJobsConfiguration().keys) { + if (command.equalsIgnoreCase(ChatColor.stripColor(Language.getMessage("signs.secondline." + key)))) { + event.setLine(1, Convert(Language.getMessage("signs.secondline." + key))); + break; + } + } + + Job job = Jobs.getJob(ChatColor.stripColor(event.getLine(2))); + + if (job == null) + return; + + String color = ConfigManager.getJobsConfiguration().SignsColorizeJobName ? job.getChatColor().toString() : ""; + event.setLine(2, Convert(color + job.getName())); + + } + + private String Convert(String line) { + Pattern ReplacePatern = Pattern.compile("&([0-9a-fk-or])"); + return ReplacePatern.matcher(ChatColor.translateAlternateColorCodes('&', line)).replaceAll("\u00a7$1"); + } + + // Adding to chat prefix job name + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onPlayerChat(AsyncPlayerChatEvent event) { + if (!plugin.isEnabled()) + return; + + if (!ConfigManager.getJobsConfiguration().getModifyChat()) + return; + + Player player = event.getPlayer(); + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(player); + + String honorific = jPlayer != null ? jPlayer.getDisplayHonorific() + " " : ""; + + if (honorific.equalsIgnoreCase(" ")) + honorific = ""; + + String format = event.getFormat(); + format = format.replace("%1$s", honorific + "%1$s"); + event.setFormat(format); + } + + // Changing chat prefix variable to job name + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onPlayerChatLow(AsyncPlayerChatEvent event) { + if (!plugin.isEnabled()) + return; + if (ConfigManager.getJobsConfiguration().getModifyChat()) + return; + Player player = event.getPlayer(); + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(player); + String honorific = jPlayer != null ? jPlayer.getDisplayHonorific() + " " : ""; + if (honorific.equalsIgnoreCase(" ")) + honorific = ""; + String format = event.getFormat(); + if (!format.contains("{jobs}")) + return; + format = format.replace("{jobs}", honorific); + event.setFormat(format); + } + + // Changing chat prefix variable to job name + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onPlayerChatHigh(AsyncPlayerChatEvent event) { + if (!plugin.isEnabled()) + return; + if (ConfigManager.getJobsConfiguration().getModifyChat()) + return; + Player player = event.getPlayer(); + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(player); + String honorific = jPlayer != null ? jPlayer.getDisplayHonorific() + " " : ""; + if (honorific.equalsIgnoreCase(" ")) + honorific = ""; + String format = event.getFormat(); + if (!format.contains("{jobs}")) + return; + format = format.replace("{jobs}", honorific); + event.setFormat(format); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onWorldLoad(WorldLoadEvent event) { + World world = event.getWorld(); + PluginManager pm = plugin.getServer().getPluginManager(); + if (pm.getPermission("jobs.world." + world.getName().toLowerCase()) == null) + pm.addPermission(new Permission("jobs.world." + world.getName().toLowerCase(), PermissionDefault.TRUE)); + } +} diff --git a/com/gamingmesh/jobs/listeners/JobsPaymentListener.java b/com/gamingmesh/jobs/listeners/JobsPaymentListener.java new file mode 100644 index 00000000..2d05fa60 --- /dev/null +++ b/com/gamingmesh/jobs/listeners/JobsPaymentListener.java @@ -0,0 +1,997 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.listeners; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Item; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Sheep; +import org.bukkit.entity.Tameable; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.enchantment.EnchantItemEvent; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; +import org.bukkit.event.entity.EntityTameEvent; +import org.bukkit.event.inventory.BrewEvent; +import org.bukkit.event.inventory.CraftItemEvent; +import org.bukkit.event.inventory.FurnaceSmeltEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType.SlotType; +import org.bukkit.event.player.PlayerFishEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerShearEntityEvent; +import org.bukkit.inventory.AnvilInventory; +import org.bukkit.inventory.CraftingInventory; +import org.bukkit.inventory.EnchantingInventory; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.metadata.MetadataValue; + +import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.JobsPlugin; +import com.gamingmesh.jobs.actions.BlockActionInfo; +import com.gamingmesh.jobs.actions.CustomKillInfo; +import com.gamingmesh.jobs.actions.EnchantActionInfo; +import com.gamingmesh.jobs.actions.EntityActionInfo; +import com.gamingmesh.jobs.actions.ItemActionInfo; +import com.gamingmesh.jobs.config.ConfigManager; +import com.gamingmesh.jobs.container.ActionType; +import com.gamingmesh.jobs.container.JobProgression; +import com.gamingmesh.jobs.container.JobsPlayer; +import com.gamingmesh.jobs.i18n.Language; +import com.gamingmesh.jobs.stuff.ActionBar; +import com.gamingmesh.jobs.stuff.ChatColor; +import com.gamingmesh.jobs.stuff.Perm; +import com.gmail.nossr50.api.AbilityAPI; +import com.google.common.base.Objects; + +public class JobsPaymentListener implements Listener { + private JobsPlugin plugin; + private final String furnaceOwnerMetadata = "jobsFurnaceOwner"; + public final static String brewingOwnerMetadata = "jobsBrewingOwner"; + private final String mobSpawnerMetadata = "jobsMobSpawner"; + public static final String BlockMetadata = "BlockOwner"; + public static final String VegyMetadata = "VegyTimer"; + public static final String GlobalMetadata = "GlobalTimer"; + public static final String CowMetadata = "CowTimer"; + + public JobsPaymentListener(JobsPlugin plugin) { + this.plugin = plugin; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onCowMilking(PlayerInteractEntityEvent event) { + + if (!(event.getRightClicked() instanceof LivingEntity)) + return; + Entity cow = (LivingEntity) event.getRightClicked(); + + if (cow.getType() != EntityType.COW && cow.getType() != EntityType.MUSHROOM_COW) + return; + + // make sure plugin is enabled + if (!plugin.isEnabled()) + return; + + Player player = (Player) event.getPlayer(); + + if (player == null) + return; + + if (ConfigManager.getJobsConfiguration().CowMilkingTimer > 0) + if (cow.hasMetadata(CowMetadata)) { + long time = cow.getMetadata(CowMetadata).get(0).asLong(); + if (System.currentTimeMillis() < time + ConfigManager.getJobsConfiguration().CowMilkingTimer) { + + long timer = ((ConfigManager.getJobsConfiguration().CowMilkingTimer - (System.currentTimeMillis() - time)) / 1000); + player.sendMessage(Language.getMessage("message.cowtimer").replace("%time%", String.valueOf(timer))); + + if (ConfigManager.getJobsConfiguration().CancelCowMilking) + event.setCancelled(true); + return; + } + } + + ItemStack itemInHand = player.getItemInHand(); + + if (itemInHand == null) + return; + + if (itemInHand.getType() != Material.BUCKET) + return; + + // check if in creative + if (player.getGameMode().equals(GameMode.CREATIVE) && !ConfigManager.getJobsConfiguration().payInCreative()) + return; + + if (!Jobs.getPermissionHandler().hasWorldPermission(player, player.getLocation().getWorld().getName())) + return; + + // Item in hand + ItemStack item = player.getItemInHand().hasItemMeta() ? player.getItemInHand() : null; + + // Wearing armor + ItemStack[] armor = player.getInventory().getArmorContents(); + + // restricted area multiplier + double multiplier = ConfigManager.getJobsConfiguration().getRestrictedMultiplier(player); + // pay + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(player); + if (jPlayer == null) + return; + + Jobs.action(jPlayer, new EntityActionInfo(cow, ActionType.MILK), multiplier, item, armor); + + Long Timer = System.currentTimeMillis(); + + cow.setMetadata(CowMetadata, new FixedMetadataValue(plugin, Timer)); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onEntityShear(PlayerShearEntityEvent event) { + + // Entity that died must be living + if (!(event.getEntity() instanceof Sheep)) + return; + Sheep sheep = (Sheep) event.getEntity(); + + // mob spawner, no payment or experience + if (sheep.hasMetadata(mobSpawnerMetadata)) { + sheep.removeMetadata(mobSpawnerMetadata, plugin); + return; + } + + // make sure plugin is enabled + if (!plugin.isEnabled()) + return; + + Player player = (Player) event.getPlayer(); + + if (player == null) + return; + + // check if in creative + if (player.getGameMode().equals(GameMode.CREATIVE) && !ConfigManager.getJobsConfiguration().payInCreative()) + return; + + if (!Jobs.getPermissionHandler().hasWorldPermission(player, player.getLocation().getWorld().getName())) + return; + + // Item in hand + ItemStack item = player.getItemInHand().hasItemMeta() ? player.getItemInHand() : null; + + // Wearing armor + ItemStack[] armor = player.getInventory().getArmorContents(); + + // restricted area multiplier + double multiplier = ConfigManager.getJobsConfiguration().getRestrictedMultiplier(player); + // pay + JobsPlayer jDamager = Jobs.getPlayerManager().getJobsPlayer(player); + if (jDamager == null) + return; + + Jobs.action(jDamager, new CustomKillInfo(sheep.getColor().name(), ActionType.SHEAR), multiplier, item, armor); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onBrewEvent(BrewEvent event) { + if (!plugin.isEnabled()) + return; + Block block = event.getBlock(); + if (block == null) + return; + if (!block.hasMetadata(brewingOwnerMetadata)) + return; + List<MetadataValue> data = block.getMetadata(brewingOwnerMetadata); + if (data.isEmpty()) + return; + + // only care about first + MetadataValue value = data.get(0); + String playerName = value.asString(); + + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(playerName); + + if (jPlayer == null || !jPlayer.getPlayer().isOnline()) + return; + + Player player = (Player) jPlayer.getPlayer(); + + if (!Jobs.getPermissionHandler().hasWorldPermission(player, player.getLocation().getWorld().getName())) + return; + + // Wearing armor + ItemStack[] armor = player.getInventory().getArmorContents(); + + double multiplier = ConfigManager.getJobsConfiguration().getRestrictedMultiplier(player); + + ItemStack contents = event.getContents().getIngredient(); + + if (contents == null) + return; + + Jobs.action(jPlayer, new ItemActionInfo(contents, ActionType.BREW), multiplier, null, armor); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onBlockBreak(BlockBreakEvent event) { + + // remove furnace metadata for broken block + Block block = event.getBlock(); + if (block == null) + return; + + if (block.getType().equals(Material.FURNACE) && block.hasMetadata(furnaceOwnerMetadata)) + block.removeMetadata(furnaceOwnerMetadata, plugin); + + if (ConfigManager.getJobsConfiguration().useBlockProtection) + if (block.getState().hasMetadata(BlockMetadata)) + return; + + if (JobsPlugin.CPPresent && ConfigManager.getJobsConfiguration().useCoreProtect) + if (PistonProtectionListener.CheckBlock(block)) { + List<String[]> blockLookup = JobsPlugin.CPAPI.blockLookup(block, ConfigManager.getJobsConfiguration().CoreProtectInterval); + if (blockLookup.size() > 0) + return; + } + + if (ConfigManager.getJobsConfiguration().useBlockTimer) + if (PistonProtectionListener.checkVegybreak(block, (Player) event.getPlayer())) + return; + + // make sure plugin is enabled + if (!plugin.isEnabled()) + return; + Player player = event.getPlayer(); + + if (!player.isOnline()) + return; + + // check if in creative + if (event.getPlayer().getGameMode().equals(GameMode.CREATIVE) && !ConfigManager.getJobsConfiguration().payInCreative()) + return; + + if (!Jobs.getPermissionHandler().hasWorldPermission(player, player.getLocation().getWorld().getName())) + return; + + // Global block timer + if (ConfigManager.getJobsConfiguration().useGlobalTimer) { + if (block.getState().hasMetadata(GlobalMetadata)) { + long currentTime = System.currentTimeMillis(); + long BlockTime = block.getState().getMetadata(GlobalMetadata).get(0).asLong(); + if (currentTime < BlockTime + ConfigManager.getJobsConfiguration().globalblocktimer * 1000) { + int sec = Math.round((((BlockTime + ConfigManager.getJobsConfiguration().globalblocktimer * 1000) - currentTime)) / 1000); + ActionBar.send(player, Language.getMessage("message.blocktimer").replace("[time]", String.valueOf(sec))); + return; + } + } + } + + // restricted area multiplier + double multiplier = ConfigManager.getJobsConfiguration().getRestrictedMultiplier(player); + + try { + if (McMMOlistener.mcMMOPresent) + if (AbilityAPI.treeFellerEnabled(player)) + multiplier -= (1 - ConfigManager.getJobsConfiguration().TreeFellerMultiplier); + } catch (IndexOutOfBoundsException e) {} + + // Item in hand + ItemStack item = player.getItemInHand().hasItemMeta() ? player.getItemInHand() : null; + + // Protection for block break with silktouch + if (ConfigManager.getJobsConfiguration().useSilkTouchProtection && item != null) + if (PistonProtectionListener.CheckBlock(block)) + for (Entry<Enchantment, Integer> one : item.getEnchantments().entrySet()) + if (one.getKey().getName().equalsIgnoreCase("SILK_TOUCH")) + return; + + // Wearing armor + ItemStack[] armor = player.getInventory().getArmorContents(); + + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(player); + if (jPlayer == null) + return; + + BlockActionInfo bInfo = new BlockActionInfo(block, ActionType.BREAK); + + Jobs.action(jPlayer, bInfo, multiplier, item, armor); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onBlockPlace(BlockPlaceEvent event) { + Block block = event.getBlock(); + + if (block == null) + return; + + // make sure plugin is enabled + if (!plugin.isEnabled()) + return; + + // check to make sure you can build + if (!event.canBuild()) + return; + + Player player = event.getPlayer(); + + if (!player.isOnline()) + return; + + if (JobsPlugin.CPPresent && ConfigManager.getJobsConfiguration().useCoreProtect && ConfigManager.getJobsConfiguration().BlockPlaceUse) { + if (PistonProtectionListener.CheckPlaceBlock(block)) { + List<String[]> blockLookup = JobsPlugin.CPAPI.blockLookup(block, ConfigManager.getJobsConfiguration().BlockPlaceInterval + 1); + if (blockLookup.size() > 0) { + long PlacedBlockTime = Integer.valueOf(blockLookup.get(0)[0]); + long CurrentTime = System.currentTimeMillis() / 1000; + if (PlacedBlockTime + ConfigManager.getJobsConfiguration().BlockPlaceInterval > CurrentTime) { + if (ConfigManager.getJobsConfiguration().EnableAnounceMessage) + ActionBar.send(player, Language.getMessage("message.placeblocktimer").replace("[time]", String.valueOf(ConfigManager.getJobsConfiguration().BlockPlaceInterval))); + return; + } + } + } + } + + // Block place/break protection + if (ConfigManager.getJobsConfiguration().useBlockProtection) + if (PistonProtectionListener.CheckBlock(block)) + block.getState().setMetadata(BlockMetadata, new FixedMetadataValue(plugin, true)); + + // check if in creative + if (event.getPlayer().getGameMode().equals(GameMode.CREATIVE) && !ConfigManager.getJobsConfiguration().payInCreative()) + return; + + if (!Jobs.getPermissionHandler().hasWorldPermission(player, player.getLocation().getWorld().getName())) + return; + + if (ConfigManager.getJobsConfiguration().useBlockTimer) + if (PistonProtectionListener.CheckVegy(block)) { + long time = System.currentTimeMillis(); + block.setMetadata(VegyMetadata, new FixedMetadataValue(plugin, time)); + } + + if (ConfigManager.getJobsConfiguration().useGlobalTimer) { + long time = System.currentTimeMillis(); + block.setMetadata(GlobalMetadata, new FixedMetadataValue(plugin, time)); + } + + // Wearing armor + ItemStack[] armor = player.getInventory().getArmorContents(); + + // restricted area multiplier + double multiplier = ConfigManager.getJobsConfiguration().getRestrictedMultiplier(player); + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(player); + if (jPlayer == null) + return; + Jobs.action(jPlayer, new BlockActionInfo(block, ActionType.PLACE), multiplier, null, armor); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerFish(PlayerFishEvent event) { + // make sure plugin is enabled + if (!plugin.isEnabled()) + return; + + Player player = event.getPlayer(); + + // check if in creative + if (event.getPlayer().getGameMode().equals(GameMode.CREATIVE) && !ConfigManager.getJobsConfiguration().payInCreative()) + return; + + if (!Jobs.getPermissionHandler().hasWorldPermission(player, player.getLocation().getWorld().getName())) + return; + + // restricted area multiplier + double multiplier = ConfigManager.getJobsConfiguration().getRestrictedMultiplier(player); + + // Item in hand + ItemStack item = player.getItemInHand().hasItemMeta() ? player.getItemInHand() : null; + + // Wearing armor + ItemStack[] armor = player.getInventory().getArmorContents(); + + if (event.getState().equals(PlayerFishEvent.State.CAUGHT_FISH) && event.getCaught() instanceof Item) { + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(player); + if (jPlayer == null) + return; + ItemStack items = ((Item) event.getCaught()).getItemStack(); + Jobs.action(jPlayer, new ItemActionInfo(items, ActionType.FISH), multiplier, item, armor); + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onAnimalTame(EntityTameEvent event) { + + // Entity that died must be living + if (!(event.getEntity() instanceof LivingEntity)) + return; + LivingEntity animal = (LivingEntity) event.getEntity(); + + // mob spawner, no payment or experience + if (animal.hasMetadata(mobSpawnerMetadata)) { + animal.removeMetadata(mobSpawnerMetadata, plugin); + return; + } + + // make sure plugin is enabled + if (!plugin.isEnabled()) + return; + + Player player = (Player) event.getOwner(); + + if (player == null) + return; + // check if in creative + if (player.getGameMode().equals(GameMode.CREATIVE) && !ConfigManager.getJobsConfiguration().payInCreative()) + return; + + if (!Jobs.getPermissionHandler().hasWorldPermission(player, player.getLocation().getWorld().getName())) + return; + + // Item in hand + ItemStack item = player.getItemInHand().hasItemMeta() ? player.getItemInHand() : null; + + // Wearing armor + ItemStack[] armor = player.getInventory().getArmorContents(); + + // restricted area multiplier + double multiplier = ConfigManager.getJobsConfiguration().getRestrictedMultiplier(player); + // pay + JobsPlayer jDamager = Jobs.getPlayerManager().getJobsPlayer(player); + if (jDamager == null) + return; + Jobs.action(jDamager, new EntityActionInfo(animal, ActionType.TAME), multiplier, item, armor); + + } + + @SuppressWarnings("deprecation") + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onInventoryCraft(CraftItemEvent event) { + + // make sure plugin is enabled + if (!plugin.isEnabled()) + return; + + // If event is nothing or place, do nothing + switch (event.getAction()) { + case NOTHING: + case PLACE_ONE: + case PLACE_ALL: + case PLACE_SOME: + return; + default: + break; + } + + if (!(event.getInventory() instanceof CraftingInventory) || !event.getSlotType().equals(SlotType.RESULT)) + return; + + ItemStack resultStack = event.getRecipe().getResult(); + + if (resultStack == null) + return; + + if (!(event.getWhoClicked() instanceof Player)) + return; + + Player player = (Player) event.getWhoClicked(); + + //Check if inventory is full and using shift click, possible money dupping fix + if (player.getInventory().firstEmpty() == -1 && event.isShiftClick()) { + player.sendMessage(ChatColor.RED + Language.getMessage("message.crafting.fullinventory")); + return; + } + + if (!Jobs.getPermissionHandler().hasWorldPermission(player, player.getLocation().getWorld().getName())) + return; + + if (!event.isLeftClick() && !event.isRightClick()) + return; + + // check if in creative + if (player.getGameMode().equals(GameMode.CREATIVE) && !ConfigManager.getJobsConfiguration().payInCreative()) + return; + + // Wearing armor + ItemStack[] armor = player.getInventory().getArmorContents(); + + double multiplier = ConfigManager.getJobsConfiguration().getRestrictedMultiplier(player); + + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(player); + + // Checking if item is been repaired, not crafted. Combining 2 items + ItemStack[] sourceItems = event.getInventory().getContents(); + // For dye check + List<ItemStack> DyeStack = new ArrayList<ItemStack>(); + int y = -1; + int first = 0; + int second = 0; + int third = 0; + boolean leather = false; + for (int i = 0; i < sourceItems.length; i++) { + if (sourceItems[i] == null) + continue; + if (sourceItems[i].getTypeId() > 0) { + if (sourceItems[i].getTypeId() == 351) + DyeStack.add(sourceItems[i]); + y++; + if (y == 0) + first = sourceItems[i].getTypeId(); + if (y == 1) + second = sourceItems[i].getTypeId(); + if (y == 2) + third = sourceItems[i].getTypeId(); + } + + if (sourceItems[i].getTypeId() == 299) + leather = true; + } + + if (jPlayer == null) + return; + + if (y == 2) { + if (first == second && third == second) { + Jobs.action(jPlayer, new ItemActionInfo(resultStack, ActionType.REPAIR), multiplier, null, armor); + return; + } + } + + // Check Dyes + if (y >= 2) { + if ((third == 351 || second == 351) && leather) { + Jobs.action(jPlayer, new ItemActionInfo(sourceItems[0], ActionType.DYE), multiplier, null, armor); + for (ItemStack OneDye : DyeStack) { + Jobs.action(jPlayer, new ItemActionInfo(OneDye, ActionType.DYE), multiplier, null, armor); + } + return; + } + } + + // If we need to pay only by each craft action we will skip calculation how much was crafted + if (!ConfigManager.getJobsConfiguration().PayForEachCraft) { + Jobs.action(jPlayer, new ItemActionInfo(resultStack, ActionType.CRAFT), multiplier, null, armor); + return; + } + + // Checking how much player crafted + ItemStack toCraft = event.getCurrentItem(); + ItemStack toStore = event.getCursor(); + // Make sure we are actually crafting anything + if (player != null && hasItems(toCraft)) + if (event.isShiftClick()) + schedulePostDetection(player, toCraft, jPlayer, resultStack, multiplier, armor); + else { + // The items are stored in the cursor. Make sure there's enough space. + if (isStackSumLegal(toCraft, toStore)) { + int newItemsCount = toCraft.getAmount(); + while (newItemsCount >= 0) { + newItemsCount--; + Jobs.action(jPlayer, new ItemActionInfo(resultStack, ActionType.CRAFT), multiplier, null, armor); + } + } + } + + } + + // HACK! The API doesn't allow us to easily determine the resulting number of + // crafted items, so we're forced to compare the inventory before and after. + private Integer schedulePostDetection(final HumanEntity player, final ItemStack compareItem, final JobsPlayer jPlayer, final ItemStack resultStack, final double multiplier, final ItemStack[] armor) { + final ItemStack[] preInv = player.getInventory().getContents(); + // Clone the array. The content may (was for me) be mutable. + for (int i = 0; i < preInv.length; i++) { + preInv[i] = preInv[i] != null ? preInv[i].clone() : null; + } + return Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { + @Override + public void run() { + final ItemStack[] postInv = player.getInventory().getContents(); + int newItemsCount = 0; + + for (int i = 0; i < preInv.length; i++) { + ItemStack pre = preInv[i]; + ItemStack post = postInv[i]; + + // We're only interested in filled slots that are different + if (hasSameItem(compareItem, post) && (hasSameItem(compareItem, pre) || pre == null)) { + newItemsCount += post.getAmount() - (pre != null ? pre.getAmount() : 0); + } + } + if (newItemsCount > 0) { + while (newItemsCount >= 0) { + newItemsCount--; + Jobs.action(jPlayer, new ItemActionInfo(resultStack, ActionType.CRAFT), multiplier, null, armor); + } + } + } + }, 1); + } + + private boolean hasItems(ItemStack stack) { + return stack != null && stack.getAmount() > 0; + } + + @SuppressWarnings("deprecation") + private boolean hasSameItem(ItemStack a, ItemStack b) { + if (a == null) + return b == null; + else if (b == null) + return a == null; + return a.getTypeId() == b.getTypeId() && a.getDurability() == b.getDurability() && Objects.equal(a.getData(), b.getData()) && Objects.equal(a.getEnchantments(), b.getEnchantments()); + } + + private boolean isStackSumLegal(ItemStack a, ItemStack b) { + // See if we can create a new item stack with the combined elements of a and b + if (a == null || b == null) + return true; // Treat null as an empty stack + else + return a.getAmount() + b.getAmount() <= a.getType().getMaxStackSize(); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onInventoryRepair(InventoryClickEvent event) { + // make sure plugin is enabled + if (!plugin.isEnabled()) + return; + Inventory inv = event.getInventory(); + + // If event is nothing or place, do nothing + switch (event.getAction()) { + case NOTHING: + case PLACE_ONE: + case PLACE_ALL: + case PLACE_SOME: + return; + default: + break; + } + + // must be anvil inventory + if (!(inv instanceof AnvilInventory)) + return; + + // Must be "container" slot 9 + + if (!event.getSlotType().equals(SlotType.RESULT) || event.getSlot() != 2) + return; + + if (!(event.getWhoClicked() instanceof Player)) + return; + + Player player = (Player) event.getWhoClicked(); + + ItemStack resultStack = event.getCurrentItem(); + + if (resultStack == null) + return; + + // Checking if this is only item rename + ItemStack FirstSlot = null; + try { + FirstSlot = event.getInventory().getItem(0); + } catch (NullPointerException e) { + return; + } + if (FirstSlot == null) + return; + + String OriginalName = null; + String NewName = null; + if (FirstSlot.hasItemMeta()) + if (FirstSlot.getItemMeta().getDisplayName() != null) + OriginalName = FirstSlot.getItemMeta().getDisplayName(); + if (resultStack.hasItemMeta()) + if (resultStack.getItemMeta().getDisplayName() != null) + NewName = resultStack.getItemMeta().getDisplayName(); + if (OriginalName != NewName && event.getInventory().getItem(1) == null) + if (!ConfigManager.getJobsConfiguration().PayForRenaming) + return; + + // Check for world permissions + if (!Jobs.getPermissionHandler().hasWorldPermission(player, player.getLocation().getWorld().getName())) + return; + + // check if in creative + if (player.getGameMode().equals(GameMode.CREATIVE) && !ConfigManager.getJobsConfiguration().payInCreative()) + return; + + // Wearing armor + ItemStack[] armor = player.getInventory().getArmorContents(); + + double multiplier = ConfigManager.getJobsConfiguration().getRestrictedMultiplier(player); + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(player); + if (jPlayer == null) + return; + Jobs.action(jPlayer, new ItemActionInfo(resultStack, ActionType.REPAIR), multiplier, null, armor); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onEnchantItem(EnchantItemEvent event) { + // make sure plugin is enabled + if (!plugin.isEnabled()) + return; + Inventory inv = event.getInventory(); + + if (!(inv instanceof EnchantingInventory)) + return; + + Player player = event.getEnchanter(); + + ItemStack resultStack = ((EnchantingInventory) inv).getItem(); + + if (resultStack == null) + return; + + if (!Jobs.getPermissionHandler().hasWorldPermission(player, player.getLocation().getWorld().getName())) + return; + + // check if in creative + if (player.getGameMode().equals(GameMode.CREATIVE) && !ConfigManager.getJobsConfiguration().payInCreative()) + return; + + // Wearing armor + ItemStack[] armor = player.getInventory().getArmorContents(); + + double multiplier = ConfigManager.getJobsConfiguration().getRestrictedMultiplier(player); + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(player); + + if (jPlayer == null) + return; + + Map<Enchantment, Integer> enchants = event.getEnchantsToAdd(); + for (Entry<Enchantment, Integer> oneEnchant : enchants.entrySet()) { + Jobs.action(jPlayer, new EnchantActionInfo(oneEnchant.getKey().getName(), oneEnchant.getValue(), ActionType.ENCHANT), multiplier, null, armor); + } + Jobs.action(jPlayer, new ItemActionInfo(resultStack, ActionType.ENCHANT), multiplier, null, armor); + + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onFurnaceSmelt(FurnaceSmeltEvent event) { + if (!plugin.isEnabled()) + return; + Block block = event.getBlock(); + if (block == null) + return; + + if (!block.hasMetadata(furnaceOwnerMetadata)) + return; + List<MetadataValue> data = block.getMetadata(furnaceOwnerMetadata); + if (data.isEmpty()) + return; + + // only care about first + MetadataValue value = data.get(0); + String playerName = value.asString(); + Player player = Bukkit.getServer().getPlayerExact(playerName); + if (player == null || !player.isOnline()) + return; + + if (!Jobs.getPermissionHandler().hasWorldPermission(player, player.getLocation().getWorld().getName())) + return; + + // Wearing armor + ItemStack[] armor = player.getInventory().getArmorContents(); + + double multiplier = ConfigManager.getJobsConfiguration().getRestrictedMultiplier(player); + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(player); + if (jPlayer == null) + return; + Jobs.action(jPlayer, new ItemActionInfo(event.getResult(), ActionType.SMELT), multiplier, null, armor); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onEntityDeath(EntityDeathEvent event) { + + // Entity that died must be living + if (!(event.getEntity() instanceof LivingEntity)) + return; + LivingEntity lVictim = (LivingEntity) event.getEntity(); + + //extra check for Citizens 2 sentry kills + if (lVictim.getKiller() instanceof Player) + if (lVictim.getKiller().hasMetadata("NPC")) + return; + + // mob spawner, no payment or experience + if (lVictim.hasMetadata(mobSpawnerMetadata) && !ConfigManager.getJobsConfiguration().payNearSpawner()) { + //lVictim.removeMetadata(mobSpawnerMetadata, plugin); + return; + } + + // make sure plugin is enabled + if (!plugin.isEnabled()) + return; + + Player pDamager = null; + + Double PetPayMultiplier = 1.0; + // Checking if killer is player + if (event.getEntity().getKiller() instanceof Player) + pDamager = (Player) event.getEntity().getKiller(); + // Checking if killer is tamed animal + else if (event.getEntity().getLastDamageCause() instanceof EntityDamageByEntityEvent) { + if (((EntityDamageByEntityEvent) event.getEntity().getLastDamageCause()).getDamager() instanceof Tameable) { + Tameable t = (Tameable) ((EntityDamageByEntityEvent) event.getEntity().getLastDamageCause()).getDamager(); + if (t.isTamed() && t.getOwner() instanceof Player) { + pDamager = (Player) t.getOwner(); + if (Perm.hasPermission(pDamager, "jobs.petpay")) + PetPayMultiplier = ConfigManager.getJobsConfiguration().VipPetPay; + else + PetPayMultiplier = ConfigManager.getJobsConfiguration().PetPay; + } + } + } else + return; + + if (pDamager == null) + return; + // check if in creative + if (pDamager.getGameMode().equals(GameMode.CREATIVE) && !ConfigManager.getJobsConfiguration().payInCreative()) + return; + + if (!Jobs.getPermissionHandler().hasWorldPermission(pDamager, pDamager.getLocation().getWorld().getName())) + return; + + // restricted area multiplier + double multiplier = ConfigManager.getJobsConfiguration().getRestrictedMultiplier(pDamager); + + // pay + JobsPlayer jDamager = Jobs.getPlayerManager().getJobsPlayer(pDamager); + + if (jDamager == null) + return; + + Double NearSpawnerMultiplier = 1.0; + if (lVictim.hasMetadata(mobSpawnerMetadata)) + NearSpawnerMultiplier = jDamager.getVipSpawnerMultiplier(); + + // Item in hand + ItemStack item = pDamager.getItemInHand().hasItemMeta() ? pDamager.getItemInHand() : null; + + // Wearing armor + ItemStack[] armor = pDamager.getInventory().getArmorContents(); + + // Calulating multiplaier + multiplier = multiplier * NearSpawnerMultiplier * PetPayMultiplier; + + Jobs.action(jDamager, new EntityActionInfo(lVictim, ActionType.KILL), multiplier, item, armor); + + // Payment for killing player with particular job, except NPC's + if (lVictim instanceof Player && !lVictim.hasMetadata("NPC")) { + List<JobProgression> jobs = Jobs.getPlayerManager().getJobsPlayer((Player) lVictim).getJobProgression(); + if (jobs != null) + for (JobProgression job : jobs) { + Jobs.action(jDamager, new CustomKillInfo(job.getJob().getName(), ActionType.CUSTOMKILL), multiplier, item, armor); + } + } + + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onCreatureSpawn(CreatureSpawnEvent event) { + if (event.getSpawnReason() == SpawnReason.SPAWNER) { + LivingEntity creature = (LivingEntity) event.getEntity(); + creature.setMetadata(mobSpawnerMetadata, new FixedMetadataValue(plugin, true)); + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onCreatureBreed(CreatureSpawnEvent event) { + + if (!ConfigManager.getJobsConfiguration().useBreederFinder) + return; + + SpawnReason reason = event.getSpawnReason(); + if (!reason.toString().equalsIgnoreCase("BREEDING")) + return; + + // Entity that spawn must be living + if (!(event.getEntity() instanceof LivingEntity)) + return; + + LivingEntity animal = (LivingEntity) event.getEntity(); + + // make sure plugin is enabled + if (!plugin.isEnabled()) + return; + + double closest = 30.0; + Player player = null; + Collection<? extends Player> OnlinePLayers = Bukkit.getOnlinePlayers(); + for (Player i : OnlinePLayers) { + if (i.getWorld().getName().equals(animal.getWorld().getName())) { + double dist = i.getLocation().distance(animal.getLocation()); + if (closest > dist) { + closest = dist; + player = i; + } + } + } + + if (player != null && closest < 30.0) { + // check if in creative + if (player.getGameMode().equals(GameMode.CREATIVE) && !ConfigManager.getJobsConfiguration().payInCreative()) + return; + + if (!Jobs.getPermissionHandler().hasWorldPermission(player, player.getLocation().getWorld().getName())) + return; + + // Item in hand + ItemStack item = player.getItemInHand().hasItemMeta() ? player.getItemInHand() : null; + + // Wearing armor + ItemStack[] armor = player.getInventory().getArmorContents(); + + // restricted area multiplier + double multiplier = ConfigManager.getJobsConfiguration().getRestrictedMultiplier(player); + // pay + JobsPlayer jDamager = Jobs.getPlayerManager().getJobsPlayer(player); + if (jDamager == null) + return; + Jobs.action(jDamager, new EntityActionInfo(animal, ActionType.BREED), multiplier, item, armor); + } + + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerInteract(PlayerInteractEvent event) { + if (!plugin.isEnabled()) + return; + + Block block = event.getClickedBlock(); + if (block == null) + return; + + if (block.getType().equals(Material.FURNACE)) { + if (block.hasMetadata(furnaceOwnerMetadata)) + block.removeMetadata(furnaceOwnerMetadata, plugin); + + block.setMetadata(furnaceOwnerMetadata, new FixedMetadataValue(plugin, event.getPlayer().getName())); + } else if (block.getType().equals(Material.BREWING_STAND)) { + if (block.hasMetadata(brewingOwnerMetadata)) + block.removeMetadata(brewingOwnerMetadata, plugin); + + block.setMetadata(brewingOwnerMetadata, new FixedMetadataValue(plugin, event.getPlayer().getName())); + } + } +} diff --git a/com/gamingmesh/jobs/listeners/McMMOlistener.java b/com/gamingmesh/jobs/listeners/McMMOlistener.java new file mode 100644 index 00000000..1b36f8b0 --- /dev/null +++ b/com/gamingmesh/jobs/listeners/McMMOlistener.java @@ -0,0 +1,72 @@ +package com.gamingmesh.jobs.listeners; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; + +import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.JobsPlugin; +import com.gamingmesh.jobs.actions.ItemActionInfo; +import com.gamingmesh.jobs.config.ConfigManager; +import com.gamingmesh.jobs.container.ActionType; +import com.gamingmesh.jobs.container.JobsPlayer; +import com.gmail.nossr50.events.skills.repair.McMMOPlayerRepairCheckEvent; + +public class McMMOlistener implements Listener { + + private JobsPlugin plugin; + public static boolean mcMMOPresent = false; + + public McMMOlistener(JobsPlugin plugin) { + this.plugin = plugin; + } + + @EventHandler + public void OnItemrepair(McMMOPlayerRepairCheckEvent event) { + // make sure plugin is enabled + if (!plugin.isEnabled()) + return; + + if (!(event.getPlayer() instanceof Player)) + return; + + Player player = (Player) event.getPlayer(); + + ItemStack resultStack = event.getRepairedObject(); + + if (resultStack == null) + return; + + if (!Jobs.getPermissionHandler().hasWorldPermission(player, player.getLocation().getWorld().getName())) + return; + + // check if in creative + if (player.getGameMode().equals(GameMode.CREATIVE) && !ConfigManager.getJobsConfiguration().payInCreative()) + return; + + // Wearing armor + ItemStack[] armor = player.getInventory().getArmorContents(); + + double multiplier = ConfigManager.getJobsConfiguration().getRestrictedMultiplier(player); + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(player); + Jobs.action(jPlayer, new ItemActionInfo(resultStack, ActionType.REPAIR), multiplier, null, armor); + } + + public static boolean CheckmcMMO() { + Plugin McMMO = Bukkit.getPluginManager().getPlugin("mcMMO"); + if (McMMO != null) { + mcMMOPresent = true; + Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.DARK_GREEN + "mcMMO was found - Enabling capabilities."); + return true; + } else { + Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.GOLD + "mcMMO was not found - Disabling capabilities."); + mcMMOPresent = false; + return false; + } + } +} diff --git a/com/gamingmesh/jobs/listeners/PistonProtectionListener.java b/com/gamingmesh/jobs/listeners/PistonProtectionListener.java new file mode 100644 index 00000000..1ae995ca --- /dev/null +++ b/com/gamingmesh/jobs/listeners/PistonProtectionListener.java @@ -0,0 +1,121 @@ +package com.gamingmesh.jobs.listeners; + +import java.util.List; + +import org.bukkit.block.Block; +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.BlockPistonExtendEvent; +import org.bukkit.event.block.BlockPistonRetractEvent; + +import com.gamingmesh.jobs.JobsPlugin; +import com.gamingmesh.jobs.config.ConfigManager; +import com.gamingmesh.jobs.i18n.Language; +import com.gamingmesh.jobs.stuff.ActionBar; + +public class PistonProtectionListener implements Listener { + + @SuppressWarnings("unused") + private JobsPlugin plugin; + + public PistonProtectionListener(JobsPlugin plugin) { + this.plugin = plugin; + } + + @SuppressWarnings("deprecation") + public static boolean CheckBlock(Block block) { + for (String BlockId : ConfigManager.getJobsConfiguration().restrictedBlocks) { + if (BlockId.equalsIgnoreCase(String.valueOf(block.getTypeId()))) { + return true; + } + } + return false; + } + + @SuppressWarnings("deprecation") + public static boolean CheckPlaceBlock(Block block) { + for (int BlockId : ConfigManager.getJobsConfiguration().restrictedPlaceBlocksTimer) { + if (BlockId == block.getTypeId()) { + return true; + } + } + return false; + } + + @SuppressWarnings("deprecation") + public static boolean CheckVegy(Block block) { + for (String ConfigOneBlock : ConfigManager.getJobsConfiguration().restrictedBlocksTimer) { + int ConfigPlacedBlockId = Integer.valueOf(ConfigOneBlock.split("-")[0]); + if (block.getTypeId() == ConfigPlacedBlockId) { + return true; + } + } + return false; + } + + @SuppressWarnings("deprecation") + public static boolean checkVegybreak(Block block, Player player) { + for (String ConfigOneBlock : ConfigManager.getJobsConfiguration().restrictedBlocksTimer) { + int ConfigPlacedBlockId = Integer.valueOf(ConfigOneBlock.split("-")[0]); + if (block.getTypeId() == ConfigPlacedBlockId) { + if (CheckVegyTimer(block, Integer.valueOf(ConfigOneBlock.split("-")[1]), player)) { + return true; + } + } + } + return false; + } + + public static boolean CheckVegyTimer(Block block, int time, Player player) { + long currentTime = System.currentTimeMillis(); + if (!block.hasMetadata(JobsPaymentListener.VegyMetadata)) + return false; + long BlockTime = block.getMetadata(JobsPaymentListener.VegyMetadata).get(0).asLong(); + + if (currentTime >= BlockTime + time * 1000) { + return false; + } + + int sec = Math.round((((BlockTime + time * 1000) - currentTime)) / 1000); + + ActionBar.send(player, Language.getMessage("message.blocktimer").replace("[time]", String.valueOf(sec))); + return true; + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public static void OnBlockMove(BlockPistonExtendEvent event) { + if (event.isCancelled()) + return; + + if (!ConfigManager.getJobsConfiguration().useBlockPiston) + return; + + List<Block> block = event.getBlocks(); + for (Block OneBlock : block) { + if (CheckBlock(OneBlock)) { + event.setCancelled(true); + break; + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public static void OnBlockRetractMove(BlockPistonRetractEvent event) { + + if (event.isCancelled()) + return; + + if (!ConfigManager.getJobsConfiguration().useBlockPiston) + return; + + List<Block> block = event.getBlocks(); + for (Block OneBlock : block) { + if (CheckBlock(OneBlock)) { + event.setCancelled(true); + break; + } + } + } +} diff --git a/com/gamingmesh/jobs/resources/jfep/.gitignore b/com/gamingmesh/jobs/resources/jfep/.gitignore new file mode 100644 index 00000000..6d48f229 --- /dev/null +++ b/com/gamingmesh/jobs/resources/jfep/.gitignore @@ -0,0 +1,10 @@ +/ConstantNode.class +/EvaluationException.class +/ExpressionNode.class +/FunctionNode.class +/OperatorNode.class +/ParseError.class +/Parser$Element.class +/Parser.class +/Sfun.class +/VariableNode.class diff --git a/com/gamingmesh/jobs/resources/jfep/ConstantNode.java b/com/gamingmesh/jobs/resources/jfep/ConstantNode.java new file mode 100644 index 00000000..6302e6a9 --- /dev/null +++ b/com/gamingmesh/jobs/resources/jfep/ConstantNode.java @@ -0,0 +1,143 @@ +/** + * Copyright 2006 Bertoli Marco + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gamingmesh.jobs.resources.jfep; + +/** + * <p><b>Name:</b> ConstantNode</p> + * <p><b>Description:</b> + * A constant value node + * </p> + * <p><b>Date:</b> 08/dic/06 + * <b>Time:</b> 15:35:24</p> + * @author Bertoli Marco + * @version 1.0 + */ +public class ConstantNode implements ExpressionNode { + /** List of built-in constant names */ + public static final String[] CONSTANTS = new String[] {"pi", "e"}; + /** List of built-in constant values */ + public static final double[] VALUES = new double[] {Math.PI, Math.E}; + /** Value of the constant */ + protected double constant; + /** Name of the constant. Only if it's built-in */ + protected String name; + /** An empty array with children */ + protected ExpressionNode[] children = new ExpressionNode[0]; + + /** + * Builds a constant node + * @param constant constant to be put in node + */ + public ConstantNode(double constant) { + this.constant = constant; + name = null; + } + + /** + * Builds a constant node, with an unique constant + * @param name name of the constant in the CONSTANTS array + */ + public ConstantNode(String name) { + this.name = name; + for (int i=0; i<CONSTANTS.length;i++) + if (CONSTANTS[i].equals(name)) { + constant = VALUES[i]; + return; + } + throw new IllegalArgumentException("Unrecognized constant"); + } + + /** + * Builds a constant node, with an unique constant + * @param pos position of the constant in the CONSTANTS array + * @see ConstantNode#CONSTANTS + */ + public ConstantNode(int pos) { + this.name = CONSTANTS[pos]; + this.constant = VALUES[pos]; + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#count() + */ + public int count() { + return 1; + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#getDepth() + */ + public int getDepth() { + return 1; // This is a leaf node + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#getSubtype() + */ + public String getSubtype() { + // Checks if this is integer or double + if (Math.floor(constant) == constant) + return Long.toString(Math.round(constant)); + else + return Double.toString(constant); + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#getType() + */ + public int getType() { + return ExpressionNode.CONSTANT_NODE; + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#getValue() + */ + public double getValue() { + return constant; + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#setVariable(java.lang.String, double) + */ + public void setVariable(String name, double value) { + // Nothing to be done here... + } + + /* (non-Javadoc) + * @see org.mbertoli.jfep.ExpressionNode#getChildrenNodes() + */ + public ExpressionNode[] getChildrenNodes() { + return children; + } + + /* (non-Javadoc) + * @see java.lang.Object#clone() + */ + public Object clone() { + return new ConstantNode(constant); + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + if (name == null) + return getSubtype(); + else + return name; + } +} diff --git a/com/gamingmesh/jobs/resources/jfep/EvaluationException.java b/com/gamingmesh/jobs/resources/jfep/EvaluationException.java new file mode 100644 index 00000000..3bd3186f --- /dev/null +++ b/com/gamingmesh/jobs/resources/jfep/EvaluationException.java @@ -0,0 +1,51 @@ +/** + * Copyright 2006 Bertoli Marco + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gamingmesh.jobs.resources.jfep; + +/** + * <p><b>Name:</b> EvaluationException</p> + * <p><b>Description:</b> + * This exception is thrown when a variable was not initialized and + * function was evaluated. + * </p> + * <p><b>Date:</b> 08/dic/06 + * <b>Time:</b> 19:45:36</p> + * @author Bertoli Marco + * @version 1.0 + */ +public class EvaluationException extends RuntimeException { + /** + * + */ + private static final long serialVersionUID = -1297776708634902362L; + + public EvaluationException() { + } + + public EvaluationException(String message) { + super(message); + } + + public EvaluationException(Throwable cause) { + super(cause); + } + + public EvaluationException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/com/gamingmesh/jobs/resources/jfep/ExpressionNode.java b/com/gamingmesh/jobs/resources/jfep/ExpressionNode.java new file mode 100644 index 00000000..0872be8e --- /dev/null +++ b/com/gamingmesh/jobs/resources/jfep/ExpressionNode.java @@ -0,0 +1,89 @@ +/** + * Copyright 2006 Bertoli Marco + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gamingmesh.jobs.resources.jfep; + +/** + * <p><b>Name:</b> ExpressionNode</p> + * <p><b>Description:</b> + * Common interface implemented by different nodes of an expression tree + * </p> + * <p><b>Date:</b> 08/dic/06 + * <b>Time:</b> 14:28:56</p> + * @author Bertoli Marco + * @version 1.0 + */ +public interface ExpressionNode extends Cloneable { + public static final int CONSTANT_NODE = 0; + public static final int VARIABLE_NODE = 1; + public static final int OPERATOR_NODE = 2; + public static final int FUNCTION_NODE = 3; + + /** + * Returns value of target node + * @return value of node + */ + public double getValue (); + + /** + * Sets the value for a variable + * @param name name of the variable to be set + * @param value value for the variable + */ + public void setVariable(String name, double value); + + /** + * Returns type of node + * @return CONSTANT_NODE, VARIABLE_NODE, OPERATOR_NODE, FUNCTION_NODE + */ + public int getType(); + + /** + * Returns more information on node type + * @return name of node function or operator symbol + */ + public String getSubtype(); + + /** + * Returns depth of current subtree + * @return depth of the tree + */ + public int getDepth(); + + /** + * Counts number of nodes in current subtree + * @return number of nodes (included root) + */ + public int count(); + + /** + * Returns children nodes of this node, ordered from leftmost to rightmost. + * @return an array of children nodes. If node has no child, destination array has zero size. + */ + public ExpressionNode[] getChildrenNodes(); + + /** + * Returns a string describing the entire tree + * @return string describing the entire tree + */ + public String toString(); + + /** + * Clones current node + * @return deep copy of current node + */ + public Object clone(); +} diff --git a/com/gamingmesh/jobs/resources/jfep/FunctionNode.java b/com/gamingmesh/jobs/resources/jfep/FunctionNode.java new file mode 100644 index 00000000..fdd6f761 --- /dev/null +++ b/com/gamingmesh/jobs/resources/jfep/FunctionNode.java @@ -0,0 +1,174 @@ +/** + * Copyright 2006 Bertoli Marco + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gamingmesh.jobs.resources.jfep; + +/** + * <p><b>Name:</b> FunctionNode</p> + * <p><b>Description:</b> + * This node is used to evaluate every kind of function with a single parameter, like abs(...) or sin(...) + * </p> + * <p><b>Date:</b> 08/dic/06 + * <b>Time:</b> 16:31:14</p> + * @author Bertoli Marco + * @version 1.0 + */ +public class FunctionNode implements ExpressionNode { + /** List of supported functions */ + public static final String[] FUNCTIONS = new String[] {"-", "sin", "cos", "tan", + "asin", "acos", "atan", "sinh", "cosh", "tanh", "asinh", "acosh", "atanh", + "ln", "log", "abs", "rand", "sqrt", "erf", "erfc", "gamma", "exp", "cot", "log2"}; + /** Child node */ + protected ExpressionNode child; + /** Function of this node */ + protected int function; + /** An array with children */ + protected ExpressionNode[] children; + + /** + * Creates a function node. + * @param child child node of this node + * @param function function to be evaluated. This is the index in <code>FUNCTIONS</code> array + * @see FunctionNode#FUNCTIONS + */ + public FunctionNode(ExpressionNode child, int function) { + this.child = child; + this.function = function; + children = new ExpressionNode[] {child}; + } + + /** + * Creates a function node. + * @param child child node of this node + * @param function name of function to be evaluated. + * @throws IllegalArgumentException if function is unsupported + */ + public FunctionNode(ExpressionNode child, String function) throws IllegalArgumentException { + this.child = child; + this.function = -1; + children = new ExpressionNode[] {child}; + for (int i=0; i<FUNCTIONS.length;i++) { + if (FUNCTIONS[i].equals(function)) { + this.function = i; + break; + } + } + if (this.function < 0) + throw new IllegalArgumentException("Unrecognized function"); + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#count() + */ + public int count() { + return 1 + child.count(); + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#getDepth() + */ + public int getDepth() { + return 1 + child.getDepth(); + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#getSubtype() + */ + public String getSubtype() { + return FUNCTIONS[function]; + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#getType() + */ + public int getType() { + return ExpressionNode.FUNCTION_NODE; + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#getValue() + */ + public double getValue() { + switch (function) { + case 0: return - child.getValue(); + case 1: return Math.sin(child.getValue()); + case 2: return Math.cos(child.getValue()); + case 3: return Math.tan(child.getValue()); + case 4: return Math.asin(child.getValue()); + case 5: return Math.acos(child.getValue()); + case 6: return Math.atan(child.getValue()); + case 7: return Sfun.sinh(child.getValue()); + case 8: return Sfun.cosh(child.getValue()); + case 9: return Sfun.tanh(child.getValue()); + case 10: return Sfun.asinh(child.getValue()); + case 11: return Sfun.acosh(child.getValue()); + case 12: return Sfun.atanh(child.getValue()); + case 13: return Math.log(child.getValue()); + case 14: return Math.log(child.getValue()) * 0.43429448190325182765; + case 15: return Math.abs(child.getValue()); + case 16: return Math.random() * child.getValue(); + case 17: return Math.sqrt(child.getValue()); + case 18: return Sfun.erf(child.getValue()); + case 19: return Sfun.erfc(child.getValue()); + case 20: return Sfun.gamma(child.getValue()); + case 21: return Math.exp(child.getValue()); + case 22: return Sfun.cot(child.getValue()); + case 23: return Math.log(child.getValue()) * 1.442695040888963407360; + } + // This is never reached + return 0; + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#setVariable(java.lang.String, double) + */ + public void setVariable(String name, double value) { + child.setVariable(name, value); + } + + /* (non-Javadoc) + * @see org.mbertoli.jfep.ExpressionNode#getChildrenNodes() + */ + public ExpressionNode[] getChildrenNodes() { + return children; + } + + /* (non-Javadoc) + * @see java.lang.Object#clone() + */ + public Object clone() { + ExpressionNode n_child = (ExpressionNode)child.clone(); + return new FunctionNode(n_child, function); + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + // Special case for negation function + if (function != 0) + return this.getSubtype() + "(" + child.toString() + ")"; + else { + if (child.getType() == CONSTANT_NODE || child.getType() == VARIABLE_NODE || + (child.getType() == FUNCTION_NODE && !child.getSubtype().equals(FUNCTIONS[0]))) + return FUNCTIONS[0] + child.toString(); + else + return FUNCTIONS[0] + "(" + child.toString() + ")"; + } + } + + +} diff --git a/com/gamingmesh/jobs/resources/jfep/OperatorNode.java b/com/gamingmesh/jobs/resources/jfep/OperatorNode.java new file mode 100644 index 00000000..6d5cab3e --- /dev/null +++ b/com/gamingmesh/jobs/resources/jfep/OperatorNode.java @@ -0,0 +1,170 @@ +/** + * Copyright 2006 Bertoli Marco + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gamingmesh.jobs.resources.jfep; + +/** + * <p><b>Name:</b> OperatorNode</p> + * <p><b>Description:</b> + * A Node that holds an arithmetic operation (+,-,*,/,^) + * </p> + * <p><b>Date:</b> 08/dic/06 + * <b>Time:</b> 15:59:56</p> + * @author Bertoli Marco + * @version 1.0 + */ +public class OperatorNode implements ExpressionNode { + /** List of supported operators */ + public static final char[] OPERATIONS = new char[] {'+', '-', '*', '/', '%', '^'}; + /** Children nodes */ + protected ExpressionNode left, right; // Children nodes + /** Operation of this node */ + protected char operation; + /** An array with children */ + protected ExpressionNode[] children; + + /** + * Creates a new operation node + * @param left left child + * @param right right child + * @param operation operation to be performed + * @see OperatorNode#OPERATIONS + */ + public OperatorNode(ExpressionNode left, ExpressionNode right, char operation) { + this.operation = operation; + this.left = left; + this.right = right; + children = new ExpressionNode[] {left, right}; + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#count() + */ + public int count() { + return 1 + left.count() + right.count(); + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#getDepth() + */ + public int getDepth() { + return 1 + Math.max(left.getDepth(), right.getDepth()); + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#getSubtype() + */ + public String getSubtype() { + return Character.toString(operation); + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#getType() + */ + public int getType() { + return ExpressionNode.OPERATOR_NODE; + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#getValue() + */ + public double getValue() { + switch (operation) { + case '+': return left.getValue() + right.getValue(); + case '-': return left.getValue() - right.getValue(); + case '*': return left.getValue() * right.getValue(); + case '/': return left.getValue() / right.getValue(); + case '%': return left.getValue() % right.getValue(); + case '^': return Math.pow(left.getValue(), right.getValue()); + } + // Never reached + return 0; + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#setVariable(java.lang.String, double) + */ + public void setVariable(String name, double value) { + left.setVariable(name, value); + right.setVariable(name, value); + } + + /* (non-Javadoc) + * @see org.mbertoli.jfep.ExpressionNode#getChildrenNodes() + */ + public ExpressionNode[] getChildrenNodes() { + return children; + } + + /* (non-Javadoc) + * @see java.lang.Object#clone() + */ + public Object clone() { + ExpressionNode n_left = (ExpressionNode)left.clone(); + ExpressionNode n_right = (ExpressionNode)right.clone(); + return new OperatorNode(n_left, n_right, operation); + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer str = new StringBuffer(); + if (needBrackets(left, true)) + str.append('('); + str.append(left); + if (needBrackets(left, true)) + str.append(')'); + str.append(getSubtype()); + if (needBrackets(right, false)) + str.append('('); + str.append(right); + if (needBrackets(right, false)) + str.append(')'); + return str.toString(); + } + + /** + * Helper method for toString. Determines if brackets are needed. + * @param child Child Node to analize + * @param isleft true iff given node is ledt child + * @return true iff we need to add brackets + */ + private boolean needBrackets(ExpressionNode child, boolean isleft) { + char childSubtype = child.getSubtype().charAt(0); + if (child.getType() == ExpressionNode.CONSTANT_NODE || child.getType() == ExpressionNode.VARIABLE_NODE) + return false; + if (child.getType() == ExpressionNode.FUNCTION_NODE) + return childSubtype == '-'; + + // At this point child is operational node. We must check precedences. + switch (this.getSubtype().charAt(0)) { + case '+': + return false; + case '-': + return (childSubtype == '+' || childSubtype == '-') && !isleft; + case '*': + return childSubtype == '+' || childSubtype == '-' || childSubtype == '%'; + case '/': + return !(childSubtype == '*' && isleft); + case '%': + return true; + case '^': + return true; + } + return true; // This statement will never be reached + } +} diff --git a/com/gamingmesh/jobs/resources/jfep/ParseError.java b/com/gamingmesh/jobs/resources/jfep/ParseError.java new file mode 100644 index 00000000..bd0b3431 --- /dev/null +++ b/com/gamingmesh/jobs/resources/jfep/ParseError.java @@ -0,0 +1,65 @@ +/** + * Copyright 2006 Bertoli Marco + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gamingmesh.jobs.resources.jfep; + +/** + * <p><b>Name:</b> ParseError</p> + * <p><b>Description:</b> + * Thrown if the parser encountres an irrecoverable error. + * </p> + * <p><b>Date:</b> 08/dic/06 + * <b>Time:</b> 14:12:25</p> + * @author Bertoli Marco + * @version 1.0 + */ +public class ParseError extends RuntimeException { + /** + * + */ + private static final long serialVersionUID = -3688639666380211029L; + private int position; + /** + * Basic constructor + * @param str Error description + * @param position Position that generated error in input string + */ + public ParseError (String str, int position) { + super(str); + this.position = position; + } + + /** + * Get position that generated error in input string + * @return position + */ + public int getPosition() { + return position; + } + + public ParseError(String message) { + super(message); + } + + public ParseError(Throwable cause) { + super(cause); + } + + public ParseError(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/com/gamingmesh/jobs/resources/jfep/Parser.java b/com/gamingmesh/jobs/resources/jfep/Parser.java new file mode 100644 index 00000000..0debb732 --- /dev/null +++ b/com/gamingmesh/jobs/resources/jfep/Parser.java @@ -0,0 +1,486 @@ +/** + * Copyright 2006 Bertoli Marco + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gamingmesh.jobs.resources.jfep; + +import java.util.HashSet; + + +/** + * <p><b>Name:</b> Parser</p> + * <p><b>Description:</b> + * Simple Java arithmetic expression parser and ELL(1) grammar syntactical analizer and evaluator. + * Parser supports detection of implicit multiplication when a constant is followed by a variable or function. + * </p> + * <p><b>Grammar:</b><br> + * S -> E (('+' | '-') E)*<br> + * E -> G ('*' G)*<br> + * G -> H ('/' H)*<br> + * H -> T ('%' T)*<br> + * T -> F | '-' F<br> + * F -> U ('^' U)*<br> + * U -> function '(' S ')' | number | '(' S ')' | variable<br> + * </p> + * <p><b>Date:</b> 08/dic/06 + * <b>Time:</b> 13:58:28</p> + * @author Bertoli Marco + * @version 1.0 + */ +public class Parser { + // Special tokens + private static final char TERM = '@'; // Input end character + private static final char NUM = 'n'; // number + private static final char FUNC = 'f'; // function + private static final char VAR = 'x'; // variable + private static final char OP_BRACKET = '('; // open bracket + private static final char CL_BRACKET = ')'; // closed bracket + + private char[] input; + private boolean error; + private int inp_cur; // Current input position + private Element cc; // Current character + private ExpressionNode root; // Root of expression tree + + private HashSet<String> functions; // Used functions + private HashSet<String> variables; // Used variables + + /** + * Class constructor + * @param str Input string to be analyzed + */ + public Parser(String str) { + this(str, false); + } + + /** + * Class constructor + * @param str Input string to be analyzed + * @param error if true, an exception is raised when value is get + * from a variable not initialized. If false, that variable is + * considered as zero. + */ + public Parser(String str, boolean error) { + input = convertInput(str); + root = null; + inp_cur = 0; + this.error = error; + functions = new HashSet<String>(); + variables = new HashSet<String>(); + } + + /** + * Converts input string in a character array and removes unsupported characters + * @param str input string + * @return converted string, terminated by TERM character + */ + protected char[] convertInput(String str) { + char[] input = str.toCharArray(); + char[] output = new char[input.length+1]; // One more space for terminator + int pos = 0; // Position on output + for (int i=0; i<input.length; i++) { + char c = input[i]; + if (isNumber(c) || isOperator(c) || isText(c) || isBracket(c)) + output[pos++] = c; + } + output[pos++] = TERM; + return output; + } + + /** + * Returns the tree of the function generated by the parser + * @return Node root node of parsed tree + * @throws ParseError if parsed input string was malformed + */ + public ExpressionNode getTree() throws ParseError { + if (root == null) { // Function need parsing + cc = parse(); + root = S(); + if (!isEndOfExpression(cc.getToken())) + throw new ParseError("Expecting operator or end of input", inp_cur); + return root; + } + else + return root; // Parsing was already performed before + } + + /** + * Returns if input character is a number + * @param c input character + * @return truth value + */ + private boolean isNumber(char c) { + if ((c >= '0' && c <= '9') || c == '.') + return true; + return false; + } + + /** + * Returns if imput character character is an operator + * @param c input character + * @return truth value + */ + private boolean isOperator(char c) { + for (int i=0;i<OperatorNode.OPERATIONS.length;i++) + if (c == OperatorNode.OPERATIONS[i]) + return true; + return false; + } + + /** + * Returns if input character is valid text + * @param c input character + * @return truth value + */ + private boolean isText(char c) { + return ((c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z') || + c == '_'); + } + + /** + * Returns if input character is a bracket + * @param c character + * @return truth value + */ + private boolean isBracket(char c) { + return (c == OP_BRACKET) || (c == CL_BRACKET); + } + + /** + * Returns if imput character is the last one (TERM) + * @param c input character + * @return truth value + */ + private boolean isEndOfExpression (char c) { + return c == TERM; + } + + /** + * Perform parsing of input string + * @return Element + */ + private Element parse() { + // Detects implicit multiplication + if (detectImplicitMult()) + return new Element('*'); + // Matches operators, brackets and termination character + if (isOperator(input[inp_cur]) || isBracket(input[inp_cur]) || isEndOfExpression(input[inp_cur])) + return new Element(input[inp_cur++]); + + // Matches numbers + if (isNumber(input[inp_cur])) { + int tmp = inp_cur++; + // Finds the end of number + while (isNumber(input[inp_cur])) + inp_cur++; + // Eventual exponential + if (Character.toLowerCase(input[inp_cur]) == 'e') { + if (input[inp_cur + 1] == '-' || isNumber(input[inp_cur + 1])) + inp_cur += 2; + while (isNumber(input[inp_cur])) + inp_cur++; + } + String s = new String(input, tmp, inp_cur - tmp); + double d; + try { + d = Double.valueOf(s).doubleValue(); + } + catch (NumberFormatException ex) { + throw new ParseError("Invalid number: "+s, inp_cur); + } + return new Element(NUM, d); + } + + // Matches text (functions or variables or built-in constants) + if (isText(input[inp_cur])) { + int tmp = inp_cur++; + // Finds the end of text + while (isText(input[inp_cur]) || isNumber(input[inp_cur])) + inp_cur++; + String s = new String(input, tmp, inp_cur - tmp); + + String lower = s.toLowerCase(); + // Now searches if this string is a function + for (int i=0; i<FunctionNode.FUNCTIONS.length;i++) { + if (lower.equals(FunctionNode.FUNCTIONS[i])) { + functions.add(FunctionNode.FUNCTIONS[i]); + return new Element(FUNC, i); + } + } + + // Now searches if this string is a built-in constant + for (int i=0; i<ConstantNode.CONSTANTS.length;i++) { + if (lower.equals(ConstantNode.CONSTANTS[i])) + return new Element(NUM, i); + } + + // String was not a function, so treat it as a variable + variables.add(s); + return new Element(VAR, s); + } + //At this point everything not recognized is an error + throw new ParseError("Unrecognized identifier", inp_cur); + } + + /** + * Helper method to detect implicit multiplication + * @return true only if inplicit multiplication is detected + */ + private boolean detectImplicitMult() { + if (cc != null && cc.getToken() == NUM) { + cc = null; // Otherwise we will loop forever + // Stores old pointer to restore it back + int old_input = inp_cur; + Element next = parse(); + // Restores old pointer back + inp_cur = old_input; + if (next.getToken() == VAR || next.getToken() == FUNC) + return true; + } + return false; + } + + /** + * Grammar Axiom S<br> + * S -> E (('+' | '-') E)* + * @return Node + */ + private ExpressionNode S() { + ExpressionNode current = E(); + while (cc.getToken() == '+' || cc.getToken() == '-') { + char operator = cc.getToken(); + cc = parse(); + current = new OperatorNode(current, E(), operator); + } + return current; + } + + /** + * Non-terminal E<br> + * E -> G ('*' G)*<br> + * @return Node + */ + private ExpressionNode E() { + ExpressionNode current = G(); + while (cc.getToken() == '*') { + cc = parse(); + current = new OperatorNode(current, G(), '*'); + } + return current; + } + + /** + * Non-terminal G<br> + * G -> H ('/' H)*<br> + * @return Node + */ + private ExpressionNode G() { + ExpressionNode current = H(); + while (cc.getToken() == '/') { + cc = parse(); + current = new OperatorNode(current, H(), '/'); + } + return current; + } + + /** + * Non-terminal H<br> + * H -> T ('%' T)*<br> + * @return Node + */ + private ExpressionNode H() { + ExpressionNode current = T(); + while (cc.getToken() == '%') { + cc = parse(); + current = new OperatorNode(current, T(), '%'); + } + return current; + } + + /** + * Non-terminal T<br> + * T -> F | '-' F<br> + * @return Node + */ + private ExpressionNode T() { + if (cc.getToken() == '-') { + cc = parse(); + return new FunctionNode(F(), "-"); + } + return F(); + } + + /** + * Non-terminal F<br> + * F -> U ('^' U)* + * @return Node + */ + private ExpressionNode F() { + ExpressionNode left; + left = U(); + if (cc.getToken() == '^') { + cc = parse(); + return new OperatorNode(left, F(), '^'); + } + return left; + } + + /** + * Non-terminal U<br> + * U -> function '(' S ')' | number | '(' S ')' | variable + * @return Node + */ + private ExpressionNode U() { + switch(cc.getToken()) { + case NUM: + double n = cc.number; + int constPosition = cc.position; // Position if this is a built-in constant + cc = parse(); + if (constPosition >= 0) + return new ConstantNode(constPosition); + else + return new ConstantNode(n); + case VAR : + String name = cc.name; + cc = parse(); + return new VariableNode(name, error); + case OP_BRACKET : + cc = parse(); + ExpressionNode tmp = S(); + if (cc.getToken() == CL_BRACKET) { + cc = parse(); + return tmp; + } + throw new ParseError("Semantic Error, expected '" + CL_BRACKET + "'", inp_cur); + case FUNC : + int function = cc.position; + cc = parse(); + if (cc.getToken() == OP_BRACKET) + cc = parse(); + else + throw new ParseError("Semantic Error, expected '"+OP_BRACKET+"'", inp_cur); + ExpressionNode tmp2 = S(); + if (cc.getToken() == CL_BRACKET) + cc = parse(); + else + throw new ParseError("Semantic Error, expected '" + CL_BRACKET + "'", inp_cur); + return new FunctionNode(tmp2, function); + } + throw new ParseError("Semantic Error, expected function or variable or constant or '('", inp_cur); + } + + /** + * Data structure used internally to return parsed elements. + */ + private class Element { + private char token; + public double number = Double.NaN; + public int position = -1; + public String name = null; + + public Element (char token) { + this.token = token; + } + + public Element (char token, double number) { + this.token = token; + this.number = number; + } + + public Element (char token, String name) { + this.token = token; + this.name = name; + } + + public Element (char token, int position) { + this.token = token; + this.position = position; + } + + /** + * Returns the token + * @return char + */ + public char getToken() { + return token; + } + } + + /** + * Sets the value for a given variable + * @param name name of the variable to be set (case sensitive) + * @param value value for the variable + * @throws ParseError if parsed input string was malformed + */ + public void setVariable(String name, double value) throws ParseError { + getTree(); + root.setVariable(name, value); + } + + /** + * Returns the value for evaluated expression + * @return value of expression + * @throws ParseError if parsed input string was malformed + * @throws EvaluationException if one variable was not initialized and parser was + * created with <code>error = true</code> + * @see #Parser(String, boolean) + */ + public double getValue() throws ParseError, EvaluationException { + getTree(); + return root.getValue(); + } + + /** + * Returns a string rappresentation of parsed expression with the right parentesis + * @return a string rappresentation of parsed expression with the right parentesis + * @throws ParseError if parsed input string was malformed + */ + public String getExpression() throws ParseError { + getTree(); + return root.toString(); + } + + /** + * Returns a Set of all functions parsed in input string + * @return a set with all parsed functions + * @throws ParseError if parsed input string was malformed + */ + public HashSet<String> getParsedFunctions() throws ParseError { + getTree(); + return functions; + } + + /** + * Returns a Set of all variables parsed in input string + * @return a set with all parsed variables + * @throws ParseError if parsed input string was malformed + */ + public HashSet<String> getParsedVariables() throws ParseError { + getTree(); + return variables; + } + + /** + * Returns input string, without invalid characters + * @return input string without invalid characters + */ + public String getInputString() { + StringBuffer output = new StringBuffer(); + for (int i=0; i<input.length && input[i] != TERM;i++) + output.append(input[i]); + return output.toString(); + } +} diff --git a/com/gamingmesh/jobs/resources/jfep/Sfun.java b/com/gamingmesh/jobs/resources/jfep/Sfun.java new file mode 100644 index 00000000..2817fcfa --- /dev/null +++ b/com/gamingmesh/jobs/resources/jfep/Sfun.java @@ -0,0 +1,557 @@ +/** + * ------------------------------------------------------------------------- + * $Id: Sfun.java,v 1.1.1.1 2005/06/06 07:43:35 Administrator Exp $ + * ------------------------------------------------------------------------- + * Copyright (c) 1997 - 1998 by Visual Numerics, Inc. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software is freely + * granted by Visual Numerics, Inc., provided that the copyright notice + * above and the following warranty disclaimer are preserved in human + * readable form. + * + * Because this software is licenses free of charge, it is provided + * "AS IS", with NO WARRANTY. TO THE EXTENT PERMITTED BY LAW, VNI + * DISCLAIMS LEVEL_ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + * TO ITS PERFORMANCE, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * VNI WILL NOT BE LIABLE FOR ANY DAMAGES WHATSOEVER ARISING OUT OF THE USE + * OF OR INABILITY TO USE THIS SOFTWARE, INCLUDING BUT NOT LIMITED TO DIRECT, + * INDIRECT, SPECIAL, CONSEQUENTIAL, PUNITIVE, AND EXEMPLARY DAMAGES, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * ------------------------------------------------------------------------- + */ + +package com.gamingmesh.jobs.resources.jfep; + +/** + * Collection of special functions. + */ +public class Sfun { + /** The smallest relative spacing for doubles.*/ + public final static double EPSILON_SMALL = 1.1102230246252e-16; + + /** The largest relative spacing for doubles. */ + public final static double EPSILON_LARGE = 2.2204460492503e-16; + + + // Series on [0,0.0625] + private static final double COT_COEF[] = {.240259160982956302509553617744970e+0, -.165330316015002278454746025255758e-1, -.429983919317240189356476228239895e-4, -.159283223327541046023490851122445e-6, -.619109313512934872588620579343187e-9, -.243019741507264604331702590579575e-11, -.956093675880008098427062083100000e-14, -.376353798194580580416291539706666e-16, -.148166574646746578852176794666666e-18}; + + // Series on the interval [0,1] + private static final double SINH_COEF[] = {0.1730421940471796, 0.08759422192276048, 0.00107947777456713, 0.00000637484926075, 0.00000002202366404, 0.00000000004987940, 0.00000000000007973, 0.00000000000000009}; + + // Series on [0,1] + private static final double TANH_COEF[] = {-.25828756643634710, -.11836106330053497, .009869442648006398, -.000835798662344582, .000070904321198943, -.000006016424318120, .000000510524190800, -.000000043320729077, .000000003675999055, -.000000000311928496, .000000000026468828, -.000000000002246023, .000000000000190587, -.000000000000016172, .000000000000001372, -.000000000000000116, .000000000000000009}; + + // Series on the interval [0,1] + private static final double ASINH_COEF[] = {-.12820039911738186343372127359268e+0, -.58811761189951767565211757138362e-1, .47274654322124815640725249756029e-2, -.49383631626536172101360174790273e-3, .58506207058557412287494835259321e-4, -.74669983289313681354755069217188e-5, .10011693583558199265966192015812e-5, -.13903543858708333608616472258886e-6, .19823169483172793547317360237148e-7, -.28847468417848843612747272800317e-8, .42672965467159937953457514995907e-9, -.63976084654366357868752632309681e-10, .96991686089064704147878293131179e-11, -.14844276972043770830246658365696e-11, .22903737939027447988040184378983e-12, -.35588395132732645159978942651310e-13, .55639694080056789953374539088554e-14, -.87462509599624678045666593520162e-15, .13815248844526692155868802298129e-15, -.21916688282900363984955142264149e-16, .34904658524827565638313923706880e-17}; + + // Series on the interval [0,0.25] + private static final double ATANH_COEF[] = {.9439510239319549230842892218633e-1, .4919843705578615947200034576668e-1, .2102593522455432763479327331752e-2, .1073554449776116584640731045276e-3, .5978267249293031478642787517872e-5, .3505062030889134845966834886200e-6, .2126374343765340350896219314431e-7, .1321694535715527192129801723055e-8, .8365875501178070364623604052959e-10, .5370503749311002163881434587772e-11, .3486659470157107922971245784290e-12, .2284549509603433015524024119722e-13, .1508407105944793044874229067558e-14, .1002418816804109126136995722837e-15, .6698674738165069539715526882986e-17, .4497954546494931083083327624533e-18}; + + // Series on the interval [0,1] + private static final double GAMMA_COEF[] = {.8571195590989331421920062399942e-2, .4415381324841006757191315771652e-2, .5685043681599363378632664588789e-1, -.4219835396418560501012500186624e-2, .1326808181212460220584006796352e-2, -.1893024529798880432523947023886e-3, .3606925327441245256578082217225e-4, -.6056761904460864218485548290365e-5, .1055829546302283344731823509093e-5, -.1811967365542384048291855891166e-6, .3117724964715322277790254593169e-7, -.5354219639019687140874081024347e-8, .9193275519859588946887786825940e-9, -.1577941280288339761767423273953e-9, .2707980622934954543266540433089e-10, -.4646818653825730144081661058933e-11, .7973350192007419656460767175359e-12, -.1368078209830916025799499172309e-12, .2347319486563800657233471771688e-13, -.4027432614949066932766570534699e-14, .6910051747372100912138336975257e-15, -.1185584500221992907052387126192e-15, .2034148542496373955201026051932e-16, -.3490054341717405849274012949108e-17, .5987993856485305567135051066026e-18, -.1027378057872228074490069778431e-18}; + + // Series for the interval [0,0.01] + private static final double R9LGMC_COEF[] = {.166638948045186324720572965082e0, -.138494817606756384073298605914e-4, .981082564692472942615717154749e-8, -.180912947557249419426330626672e-10, .622109804189260522712601554342e-13, -.339961500541772194430333059967e-15, .268318199848269874895753884667e-17}; + + // Series on [-0.375,0.375] + final private static double ALNRCS_COEF[] = {.103786935627437698006862677191e1, -.133643015049089180987660415531, .194082491355205633579261993748e-1, -.301075511275357776903765377766e-2, .486946147971548500904563665091e-3, -.810548818931753560668099430086e-4, .137788477995595247829382514961e-4, -.238022108943589702513699929149e-5, .41640416213865183476391859902e-6, -.73595828378075994984266837032e-7, .13117611876241674949152294345e-7, -.235467093177424251366960923302e-8, .425227732760349977756380529626e-9, -.771908941348407968261081074933e-10, .140757464813590699092153564722e-10, -.257690720580246806275370786276e-11, .473424066662944218491543950059e-12, -.872490126747426417453012632927e-13, .161246149027405514657398331191e-13, -.298756520156657730067107924168e-14, .554807012090828879830413216973e-15, -.103246191582715695951413339619e-15, .192502392030498511778785032449e-16, -.359550734652651500111897078443e-17, .672645425378768578921945742268e-18, -.126026241687352192520824256376e-18}; + + // Series on [0,1] + private static final double ERFC_COEF[] = {-.490461212346918080399845440334e-1, -.142261205103713642378247418996e0, .100355821875997955757546767129e-1, -.576876469976748476508270255092e-3, .274199312521960610344221607915e-4, -.110431755073445076041353812959e-5, .384887554203450369499613114982e-7, -.118085825338754669696317518016e-8, .323342158260509096464029309534e-10, -.799101594700454875816073747086e-12, .179907251139614556119672454866e-13, -.371863548781869263823168282095e-15, .710359900371425297116899083947e-17, -.126124551191552258324954248533e-18}; + + // Series on [0.25,1.00] + private static final double ERFC2_COEF[] = {-.69601346602309501127391508262e-1, -.411013393626208934898221208467e-1, .391449586668962688156114370524e-2, -.490639565054897916128093545077e-3, .715747900137703638076089414183e-4, -.115307163413123283380823284791e-4, .199467059020199763505231486771e-5, -.364266647159922287393611843071e-6, .694437261000501258993127721463e-7, -.137122090210436601953460514121e-7, .278838966100713713196386034809e-8, -.581416472433116155186479105032e-9, .123892049175275318118016881795e-9, -.269063914530674343239042493789e-10, .594261435084791098244470968384e-11, -.133238673575811957928775442057e-11, .30280468061771320171736972433e-12, -.696664881494103258879586758895e-13, .162085454105392296981289322763e-13, -.380993446525049199987691305773e-14, .904048781597883114936897101298e-15, -.2164006195089607347809812047e-15, .522210223399585498460798024417e-16, -.126972960236455533637241552778e-16, .310914550427619758383622741295e-17, -.766376292032038552400956671481e-18, .190081925136274520253692973329e-18}; + + // Series on [0,0.25] + private static final double ERFCC_COEF[] = {.715179310202924774503697709496e-1, -.265324343376067157558893386681e-1, .171115397792085588332699194606e-2, -.163751663458517884163746404749e-3, .198712935005520364995974806758e-4, -.284371241276655508750175183152e-5, .460616130896313036969379968464e-6, -.822775302587920842057766536366e-7, .159214187277090112989358340826e-7, -.329507136225284321486631665072e-8, .72234397604005554658126115389e-9, -.166485581339872959344695966886e-9, .401039258823766482077671768814e-10, -.100481621442573113272170176283e-10, .260827591330033380859341009439e-11, -.699111056040402486557697812476e-12, .192949233326170708624205749803e-12, -.547013118875433106490125085271e-13, .158966330976269744839084032762e-13, -.47268939801975548392036958429e-14, .14358733767849847867287399784e-14, -.444951056181735839417250062829e-15, .140481088476823343737305537466e-15, -.451381838776421089625963281623e-16, .147452154104513307787018713262e-16, -.489262140694577615436841552532e-17, .164761214141064673895301522827e-17, -.562681717632940809299928521323e-18, .194744338223207851429197867821e-18}; + + + /** + * Private contructor, so nobody can make an instance of this class. + */ + private Sfun() { + } + + /** + * Returns the inverse (arc) hyperbolic cosine of a double. + * @param x A double value. + * @return The arc hyperbolic cosine of x. + * If x is NaN or less than one, the result is NaN. + */ + static public double acosh(double x) { + double ans; + + if (Double.isNaN(x) || x < 1) { + ans = Double.NaN; + } else if (x < 94906265.62) { + // 94906265.62 = 1.0/Math.sqrt(EPSILON_SMALL) + ans = Math.log(x + Math.sqrt(x * x - 1.0)); + } else { + ans = 0.69314718055994530941723212145818 + Math.log(x); + } + return ans; + } + + /** + * Returns the inverse (arc) hyperbolic sine of a double. + * @param x A double value. + * @return The arc hyperbolic sine of x. + * If x is NaN, the result is NaN. + */ + static public double asinh(double x) { + double ans; + double y = Math.abs(x); + + if (Double.isNaN(x)) { + ans = Double.NaN; + } else if (y <= 1.05367e-08) { + // 1.05367e-08 = Math.sqrt(EPSILON_SMALL) + ans = x; + } else if (y <= 1.0) { + ans = x * (1.0 + csevl(2.0 * x * x - 1.0, ASINH_COEF)); + } else if (y < 94906265.62) { + // 94906265.62 = 1/Math.sqrt(EPSILON_SMALL) + ans = Math.log(y + Math.sqrt(y * y + 1.0)); + } else { + ans = 0.69314718055994530941723212145818 + Math.log(y); + } + if (x < 0.0) ans = -ans; + return ans; + } + + /** + * Returns the inverse (arc) hyperbolic tangent of a double. + * @param x A double value. + * @return The arc hyperbolic tangent of x. + * If x is NaN or |x|>1, the result is NaN. + */ + static public double atanh(double x) { + double y = Math.abs(x); + double ans; + + if (Double.isNaN(x)) { + ans = Double.NaN; + } else if (y < 1.82501e-08) { + // 1.82501e-08 = Math.sqrt(3.0*EPSILON_SMALL) + ans = x; + } else if (y <= 0.5) { + ans = x * (1.0 + csevl(8.0 * x * x - 1.0, ATANH_COEF)); + } else if (y < 1.0) { + ans = 0.5 * Math.log((1.0 + x) / (1.0 - x)); + } else if (y == 1.0) { + ans = x * Double.POSITIVE_INFINITY; + } else { + ans = Double.NaN; + } + return ans; + } + + /** + * Returns the hyperbolic cosine of a double. + * @param x A double value. + * @return The hyperbolic cosine of x. + * If x is NaN, the result is NaN. + */ + static public double cosh(double x) { + double ans; + double y = Math.exp(Math.abs(x)); + + if (Double.isNaN(x)) { + ans = Double.NaN; + } else if (Double.isInfinite(x)) { + ans = x; + } else if (y < 94906265.62) { + // 94906265.62 = 1.0/Math.sqrt(EPSILON_SMALL) + ans = 0.5 * (y + 1.0 / y); + } else { + ans = 0.5 * y; + } + return ans; + } + + /** + * Returns the cotangent of a double. + * @param x A double value. + * @return The cotangent of x. + * If x is NaN, the result is NaN. + */ + static public double cot(double x) { + double ans, ainty, ainty2, prodbg, y, yrem; + double pi2rec = 0.011619772367581343075535053490057; // 2/PI - 0.625 + + y = Math.abs(x); + + if (y > 4.5036e+15) { + // 4.5036e+15 = 1.0/EPSILON_LARGE + return Double.NaN; + } + + // Carefully compute + // Y * (2/PI) = (AINT(Y) + REM(Y)) * (.625 + PI2REC) + // = AINT(.625*Y) + REM(.625*Y) + Y*PI2REC = AINT(.625*Y) + Z + // = AINT(.625*Y) + AINT(Z) + REM(Z) + ainty = (int) y; + yrem = y - ainty; + prodbg = 0.625 * ainty; + ainty = (int) prodbg; + y = (prodbg - ainty) + 0.625 * yrem + y * pi2rec; + ainty2 = (int) y; + ainty = ainty + ainty2; + y = y - ainty2; + + int ifn = (int) (ainty % 2.0); + if (ifn == 1) y = 1.0 - y; + + if (y == 0.0) { + ans = Double.POSITIVE_INFINITY; + } else if (y <= 1.82501e-08) { + // 1.82501e-08 = Math.sqrt(3.0*EPSILON_SMALL) + ans = 1.0 / y; + } else if (y <= 0.25) { + ans = (0.5 + csevl(32.0 * y * y - 1.0, COT_COEF)) / y; + } else if (y <= 0.5) { + ans = (0.5 + csevl(8.0 * y * y - 1.0, COT_COEF)) / (0.5 * y); + ans = (ans * ans - 1.0) * 0.5 / ans; + } else { + ans = (0.5 + csevl(2.0 * y * y - 1.0, COT_COEF)) / (0.25 * y); + ans = (ans * ans - 1.0) * 0.5 / ans; + ans = (ans * ans - 1.0) * 0.5 / ans; + } + if (x != 0.0) ans = sign(ans, x); + if (ifn == 1) ans = -ans; + return ans; + } + + /* + * Evaluate a Chebyschev series + */ + static double csevl(double x, double coef[]) { + double b0, b1, b2, twox; + int i; + b1 = 0.0; + b0 = 0.0; + b2 = 0.0; + twox = 2.0 * x; + for (i = coef.length - 1; i >= 0; i--) { + b2 = b1; + b1 = b0; + b0 = twox * b1 - b2 + coef[i]; + } + return 0.5 * (b0 - b2); + } + + /* + * Correction term used by logBeta. + */ + private static double dlnrel(double x) { + double ans; + + if (x <= -1.0) { + ans = Double.NaN; + } else if (Math.abs(x) <= 0.375) { + ans = x * (1.0 - x * Sfun.csevl(x / .375, ALNRCS_COEF)); + } else { + ans = Math.log(1.0 + x); + } + return ans; + } + + /** + * Returns the error function of a double. + * @param x A double value. + * @return The error function of x. + */ + static public double erf(double x) { + double ans; + double y = Math.abs(x); + + if (y <= 1.49012e-08) { + // 1.49012e-08 = Math.sqrt(2*EPSILON_SMALL) + ans = 2 * x / 1.77245385090551602729816748334; + } else if (y <= 1) { + ans = x * (1 + csevl(2 * x * x - 1, ERFC_COEF)); + } else if (y < 6.013687357) { + // 6.013687357 = Math.sqrt(-Math.getLog(1.77245385090551602729816748334 * EPSILON_SMALL)) + ans = sign(1 - erfc(y), x); + } else { + ans = sign(1, x); + } + return ans; + } + + /** + * Returns the complementary error function of a double. + * @param x A double value. + * @return The complementary error function of x. + */ + static public double erfc(double x) { + double ans; + double y = Math.abs(x); + + if (x <= -6.013687357) { + // -6.013687357 = -Math.sqrt(-Math.getLog(1.77245385090551602729816748334 * EPSILON_SMALL)) + ans = 2; + } else if (y < 1.49012e-08) { + // 1.49012e-08 = Math.sqrt(2*EPSILON_SMALL) + ans = 1 - 2 * x / 1.77245385090551602729816748334; + } else { + double ysq = y * y; + if (y < 1) { + ans = 1 - x * (1 + csevl(2 * ysq - 1, ERFC_COEF)); + } else if (y <= 4.0) { + ans = Math.exp(-ysq) / y * (0.5 + csevl((8.0 / ysq - 5.0) / 3.0, ERFC2_COEF)); + if (x < 0) ans = 2.0 - ans; + if (x < 0) ans = 2.0 - ans; + if (x < 0) ans = 2.0 - ans; + } else { + ans = Math.exp(-ysq) / y * (0.5 + csevl(8.0 / ysq - 1, ERFCC_COEF)); + if (x < 0) ans = 2.0 - ans; + } + } + return ans; + } + + /** + * Returns the factorial of an integer. + * @param n An integer value. + * @return The factorial of n, n!. + * If x is negative, the result is NaN. + */ + static public double fact(int n) { + double ans = 1; + + if (Double.isNaN(n) || n < 0) { + ans = Double.NaN; + } else if (n > 170) { + // The 171! is too large to fit in a double. + ans = Double.POSITIVE_INFINITY; + } else { + for (int k = 2; k <= n; k++) + ans *= k; + } + return ans; + } + + /** + * Returns the Gamma function of a double. + * @param x A double value. + * @return The Gamma function of x. + * If x is a negative integer, the result is NaN. + */ + static public double gamma(double x) { + double ans; + double y = Math.abs(x); + + if (y <= 10.0) { + /* + * Compute gamma(x) for |x|<=10. + * First reduce the interval and find gamma(1+y) for 0 <= y < 1. + */ + int n = (int) x; + if (x < 0.0) n--; + y = x - n; + n--; + ans = 0.9375 + csevl(2.0 * y - 1.0, GAMMA_COEF); + if (n == 0) { + } else if (n < 0) { + // Compute gamma(x) for x < 1 + n = -n; + if (x == 0.0) { + ans = Double.NaN; + } else if (y < 1.0 / Double.MAX_VALUE) { + ans = Double.POSITIVE_INFINITY; + } else { + double xn = n - 2; + if (x < 0.0 && x + xn == 0.0) { + ans = Double.NaN; + } else { + for (int i = 0; i < n; i++) { + ans /= x + i; + } + } + } + } else { // gamma(x) for x >= 2.0 + for (int i = 1; i <= n; i++) { + ans *= y + i; + } + } + } else { // gamma(x) for |x| > 10 + if (x > 171.614) { + ans = Double.POSITIVE_INFINITY; + } else if (x < -170.56) { + ans = 0.0; // underflows + } else { + // 0.9189385332046727 = 0.5*getLog(2*PI) + ans = Math.exp((y - 0.5) * Math.log(y) - y + 0.9189385332046727 + r9lgmc(y)); + if (x < 0.0) { + double sinpiy = Math.sin(Math.PI * y); + if (sinpiy == 0 || Math.round(y) == y) { + ans = Double.NaN; + } else { + ans = -Math.PI / (y * sinpiy * ans); + } + } + } + } + return ans; + } + + /** + * Returns the common (base 10) logarithm of a double. + * @param x A double value. + * @return The common logarithm of x. + */ + static public double log10(double x) { + //if (Double.isNaN(x)) return Double.NaN; + return 0.43429448190325182765 * Math.log(x); + } + + /** + * Returns the logarithm of the Beta function. + * @param a A double value. + * @param b A double value. + * @return The natural logarithm of the Beta function. + */ + static public double logBeta(double a, double b) { + double corr, ans; + double p = Math.min(a, b); + double q = Math.max(a, b); + + if (p <= 0.0) { + ans = Double.NaN; + } else if (p >= 10.0) { + // P and Q are large; + corr = r9lgmc(p) + r9lgmc(q) - r9lgmc(p + q); + double temp = dlnrel(-p / (p + q)); + ans = -0.5 * Math.log(q) + 0.918938533204672741780329736406 + corr + (p - 0.5) * Math.log(p / (p + q)) + q * temp; + } else if (q >= 10.0) { + // P is small, but Q is large + corr = Sfun.r9lgmc(q) - r9lgmc(p + q); + // Check from underflow from r9lgmc + ans = logGamma(p) + corr + p - p * Math.log(p + q) + (q - 0.5) * dlnrel(-p / (p + q)); + } else { + // P and Q are small; + ans = Math.log(gamma(p) * (gamma(q) / gamma(p + q))); + } + return ans; + } + + /** + * Returns the logarithm of the Gamma function of a double. + * @param x A double value. + * @return The natural logarithm of the Gamma function of x. + * If x is a negative integer, the result is NaN. + */ + static public double logGamma(double x) { + double ans, sinpiy, y; + + y = Math.abs(x); + + if (y <= 10) { + ans = Math.log(Math.abs(gamma(x))); + } else if (x > 0) { + // A&S 6.1.40 + // 0.9189385332046727 = 0.5*getLog(2*PI) + ans = 0.9189385332046727 + (x - 0.5) * Math.log(x) - x + r9lgmc(y); + } else { + sinpiy = Math.abs(Math.sin(Math.PI * y)); + if (sinpiy == 0 || Math.round(y) == y) { + // The argument for the function can not be a negative integer. + ans = Double.NaN; + } else { + ans = 0.22579135264472743236 + (x - 0.5) * Math.log(y) - x - Math.log(sinpiy) - r9lgmc(y); + } + } + return ans; + } + + /* + * Returns the getLog gamma correction term for argument + * values greater than or equal to 10.0. + */ + static double r9lgmc(double x) { + double ans; + + if (x < 10.0) { + ans = Double.NaN; + } else if (x < 9.490626562e+07) { + // 9.490626562e+07 = 1/Math.sqrt(EPSILON_SMALL) + double y = 10.0 / x; + ans = csevl(2.0 * y * y - 1.0, R9LGMC_COEF) / x; + } else if (x < 1.39118e+11) { + // 1.39118e+11 = exp(min(getLog(amach(2) / 12.0), -getLog(12.0 * amach(1)))); + // See A&S 6.1.41 + ans = 1.0 / (12.0 * x); + } else { + ans = 0.0; // underflows + } + return ans; + } + + /* + * Returns the value of x with the sign of y. + */ + static private double sign(double x, double y) { + double abs_x = ((x < 0) ? -x : x); + return (y < 0.0) ? -abs_x : abs_x; + } + + /** + * Returns the inverse (arc) hyperbolic sine of a double. + * @param x A double value. + * @return The arc hyperbolic sine of x. + * If x is NaN or less than one, the result is NaN. + */ + static public double sinh(double x) { + double ans; + double y = Math.abs(x); + + if (Double.isNaN(x)) { + ans = Double.NaN; + } else if (Double.isInfinite(y)) { + return x; + } else if (y < 2.58096e-08) { + // 2.58096e-08 = Math.sqrt(6.0*EPSILON_SMALL) + ans = x; + } else if (y <= 1.0) { + ans = x * (1.0 + csevl(2.0 * x * x - 1.0, SINH_COEF)); + } else { + y = Math.exp(y); + if (y >= 94906265.62) { + // 94906265.62 = 1.0/Math.sqrt(EPSILON_SMALL) + ans = sign(0.5 * y, x); + } else { + ans = sign(0.5 * (y - 1.0 / y), x); + } + } + return ans; + } + + /** + * Returns the hyperbolic tangent of a double. + * @param x A double value. + * @return The hyperbolic tangent of x. + */ + static public double tanh(double x) { + double ans, y; + y = Math.abs(x); + + if (Double.isNaN(x)) { + ans = Double.NaN; + } else if (y < 1.82501e-08) { + // 1.82501e-08 = Math.sqrt(3.0*EPSILON_SMALL) + ans = x; + } else if (y <= 1.0) { + ans = x * (1.0 + csevl(2.0 * x * x - 1.0, TANH_COEF)); + } else if (y < 7.977294885) { + // 7.977294885 = -0.5*Math.getLog(EPSILON_SMALL) + y = Math.exp(y); + ans = sign((y - 1.0 / y) / (y + 1.0 / y), x); + } else { + ans = sign(1.0, x); + } + return ans; + } +} diff --git a/com/gamingmesh/jobs/resources/jfep/VariableNode.java b/com/gamingmesh/jobs/resources/jfep/VariableNode.java new file mode 100644 index 00000000..370aa297 --- /dev/null +++ b/com/gamingmesh/jobs/resources/jfep/VariableNode.java @@ -0,0 +1,121 @@ +/** + * Copyright 2006 Bertoli Marco + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gamingmesh.jobs.resources.jfep; + +/** + * <p><b>Name:</b> VariableNode</p> + * <p><b>Description:</b> + * A node holding a double variable. + * </p> + * <p><b>Date:</b> 08/dic/06 + * <b>Time:</b> 15:56:59</p> + * @author Bertoli Marco + * @version 1.0 + */ +public class VariableNode implements ExpressionNode { + /** Value of the variable */ + protected double value; + /** True if variable was not initialized */ + protected boolean error; + /** Name of the variable */ + protected String name; + /** An empty array with children */ + protected ExpressionNode[] children = new ExpressionNode[0]; + + /** + * Creates a new variable node with given name. + * @param name name of the variable + * @param error throws an exception if value is get but variable + * is not initialized. Otherwise 0.0 is returned. + */ + public VariableNode(String name, boolean error) { + this.name = name; + value = 0.0; + this.error = error; + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#count() + */ + public int count() { + return 1; + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#getDepth() + */ + public int getDepth() { + return 1; // This is a leaf node + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#getSubtype() + */ + public String getSubtype() { + return name; + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#getType() + */ + public int getType() { + return ExpressionNode.VARIABLE_NODE; + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#getValue() + */ + public double getValue() { + if (!error) + return value; + else + throw new EvaluationException("Variable '" + name + "' was not initialized."); + } + + /* (non-Javadoc) + * @see jmt.engine.math.parser.ExpressionNode#setVariable(java.lang.String, double) + */ + public void setVariable(String name, double value) { + if (this.name.equals(name)) { + this.value = value; + error = false; + } + } + + /* (non-Javadoc) + * @see org.mbertoli.jfep.ExpressionNode#getChildrenNodes() + */ + public ExpressionNode[] getChildrenNodes() { + return children; + } + + /* (non-Javadoc) + * @see java.lang.Object#clone() + */ + public Object clone() { + VariableNode node = new VariableNode(name, error); + node.value = value; + return node; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + return getSubtype(); + } +} diff --git a/com/gamingmesh/jobs/stuff/.gitignore b/com/gamingmesh/jobs/stuff/.gitignore new file mode 100644 index 00000000..e97af8cc --- /dev/null +++ b/com/gamingmesh/jobs/stuff/.gitignore @@ -0,0 +1,19 @@ +/ChatColor.class +/FileDownloader.class +/JobsClassLoader.class +/UUIDFetcher.class +/UUIDUtil.class +/UUIDConverter.class +/ActionBar.class +/GiveItem.class +/TabComplete.class +/PerformCommands.class +/TopSignStuff.class +/Gui.class +/TranslateName.class +/Debug.class +/Perm.class +/Scboard$1.class +/Scboard.class +/ScheduleUtil$1.class +/ScheduleUtil.class diff --git a/com/gamingmesh/jobs/stuff/ActionBar.java b/com/gamingmesh/jobs/stuff/ActionBar.java new file mode 100644 index 00000000..10445463 --- /dev/null +++ b/com/gamingmesh/jobs/stuff/ActionBar.java @@ -0,0 +1,156 @@ +package com.gamingmesh.jobs.stuff; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.logging.Level; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.config.ConfigManager; +import com.gamingmesh.jobs.economy.BufferedPayment; +import com.gamingmesh.jobs.i18n.Language; + +/** +* +* @author hamzaxx +*/ +public class ActionBar { + private static int cleanVersion = 182; + private static String version = ""; + private static Object packet; + private static Method getHandle; + private static Method sendPacket; + private static Field playerConnection; + private static Class<?> nmsChatSerializer; + private static Class<?> nmsIChatBaseComponent; + private static Class<?> packetType; + + static { + try { + version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; + + // Translating version to integer for simpler use + try { + cleanVersion = Integer.parseInt(version.replace("v", "").replace("V", "").replace("_", "").replace("r", "").replace("R", "")); + } catch (NumberFormatException e) { + // Fail save if it for some reason can't translate version to integer + if (version.contains("v1_7")) + cleanVersion = 170; + if (version.contains("v1_6")) + cleanVersion = 160; + if (version.contains("v1_5")) + cleanVersion = 150; + if (version.contains("v1_4")) + cleanVersion = 140; + if (version.contains("v1_8_R1")) + cleanVersion = 181; + if (version.contains("v1_8_R2")) + cleanVersion = 182; + if (version.contains("v1_8_R3")) + cleanVersion = 183; + } + + packetType = Class.forName(getPacketPlayOutChat()); + Class<?> typeCraftPlayer = Class.forName(getCraftPlayerClasspath()); + Class<?> typeNMSPlayer = Class.forName(getNMSPlayerClasspath()); + Class<?> typePlayerConnection = Class.forName(getPlayerConnectionClasspath()); + nmsChatSerializer = Class.forName(getChatSerializerClasspath()); + nmsIChatBaseComponent = Class.forName(getIChatBaseComponentClasspath()); + getHandle = typeCraftPlayer.getMethod("getHandle"); + playerConnection = typeNMSPlayer.getField("playerConnection"); + sendPacket = typePlayerConnection.getMethod("sendPacket", Class.forName(getPacketClasspath())); + + } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | NoSuchFieldException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Error {0}", ex); + } + } + + public static void ShowActionBar(BufferedPayment payment) { + String playername = payment.getOfflinePlayer().getName(); + if (!Jobs.actionbartoggle.containsKey(playername) && ConfigManager.getJobsConfiguration().JobsToggleEnabled) + Jobs.actionbartoggle.put(playername, true); + + if (playername != null && Jobs.actionbartoggle.size() > 0) + if (Jobs.actionbartoggle.containsKey(playername)) { + Boolean show = Jobs.actionbartoggle.get(playername); + Player abp = (Player) payment.getOfflinePlayer(); + if (abp != null && show) { + String Message = Language.getMessage("command.toggle.output.paid"); + Message = Message.replace("[amount]", String.valueOf((((int) (payment.getAmount() * 100)) / 100.0))); + Message = Message.replace("[exp]", String.valueOf((((int) (payment.getExp() * 100)) / 100.0))); + ActionBar.send(abp, ChatColor.GREEN + Message); + } else { + Jobs.actionbartoggle.remove(playername); + } + } + } + + public static void send(Player receivingPacket, String msg) { + try { + if (msg == null || nmsChatSerializer == null) + return; + + if (cleanVersion < 180) { + receivingPacket.sendMessage(ChatColor.translateAlternateColorCodes('&', msg)); + return; + } + + Object serialized = nmsChatSerializer.getMethod("a", String.class).invoke(null, "{\"text\": \"" + ChatColor.translateAlternateColorCodes('&', msg) + "\"}"); + if (cleanVersion > 180) { + packet = packetType.getConstructor(nmsIChatBaseComponent, byte.class).newInstance(serialized, (byte) 2); + } else { + packet = packetType.getConstructor(nmsIChatBaseComponent, int.class).newInstance(serialized, 2); + } + Object player = getHandle.invoke(receivingPacket); + Object connection = playerConnection.get(player); + sendPacket.invoke(connection, packet); + } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Error {0}", ex); + } + + try { + Object player = getHandle.invoke(receivingPacket); + Object connection = playerConnection.get(player); + sendPacket.invoke(connection, packet); + } catch (SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Error {0}", ex); + } + } + + private static String getCraftPlayerClasspath() { + return "org.bukkit.craftbukkit." + version + ".entity.CraftPlayer"; + } + + private static String getPlayerConnectionClasspath() { + return "net.minecraft.server." + version + ".PlayerConnection"; + } + + private static String getNMSPlayerClasspath() { + return "net.minecraft.server." + version + ".EntityPlayer"; + } + + private static String getPacketClasspath() { + return "net.minecraft.server." + version + ".Packet"; + } + + private static String getIChatBaseComponentClasspath() { + return "net.minecraft.server." + version + ".IChatBaseComponent"; + } + + private static String getChatSerializerClasspath() { + + if (cleanVersion < 182) { + return "net.minecraft.server." + version + ".ChatSerializer"; + } else { + return "net.minecraft.server." + version + ".IChatBaseComponent$ChatSerializer"; // 1_8_R2 moved to IChatBaseComponent + } + } + + private static String getPacketPlayOutChat() { + return "net.minecraft.server." + version + ".PacketPlayOutChat"; + } +} \ No newline at end of file diff --git a/com/gamingmesh/jobs/stuff/ChatColor.java b/com/gamingmesh/jobs/stuff/ChatColor.java new file mode 100644 index 00000000..b180cdd5 --- /dev/null +++ b/com/gamingmesh/jobs/stuff/ChatColor.java @@ -0,0 +1,69 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.stuff; + +import java.util.HashMap; +import java.util.Map; + +public enum ChatColor { + BLACK('0', 0), DARK_BLUE('1', 1), DARK_GREEN('2', 2), DARK_AQUA('3', 3), DARK_RED('4', 4), DARK_PURPLE('5', 5), GOLD('6', 6), GRAY('7', 7), DARK_GRAY('8', 8), BLUE('9', 9), GREEN('a', 10), AQUA('b', 11), RED('c', 12), LIGHT_PURPLE('d', 13), YELLOW('e', 14), WHITE('f', 15); + + private static final char COLOR_CHAR = '\u00A7'; + private final char code; + private final int intCode; + private final String toString; + private final static Map<Integer, ChatColor> intMap = new HashMap<Integer, ChatColor>(); + private final static Map<Character, ChatColor> charMap = new HashMap<Character, ChatColor>(); + private final static Map<String, ChatColor> stringMap = new HashMap<String, ChatColor>(); + + private ChatColor(char code, int intCode) { + this.code = code; + this.intCode = intCode; + this.toString = new String(new char[] { COLOR_CHAR, code }); + } + + public char getChar() { + return code; + } + + @Override + public String toString() { + return toString; + } + + public static ChatColor matchColor(char code) { + return charMap.get(code); + } + + public static ChatColor matchColor(int code) { + return intMap.get(code); + } + + public static ChatColor matchColor(String name) { + return stringMap.get(name.toLowerCase()); + } + + static { + for (ChatColor color : values()) { + intMap.put(color.intCode, color); + charMap.put(color.code, color); + stringMap.put(color.name().toLowerCase(), color); + } + } +} diff --git a/com/gamingmesh/jobs/stuff/Debug.java b/com/gamingmesh/jobs/stuff/Debug.java new file mode 100644 index 00000000..b6fbbc0f --- /dev/null +++ b/com/gamingmesh/jobs/stuff/Debug.java @@ -0,0 +1,18 @@ +package com.gamingmesh.jobs.stuff; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +public class Debug { + public static void D(String message) { + + Player player = Bukkit.getPlayer("Zrips"); + if (player == null) + return; + + player.sendMessage(ChatColor.DARK_GRAY + "[Debug] " + ChatColor.DARK_AQUA + ChatColor.translateAlternateColorCodes('&', message)); + + return; + } +} diff --git a/com/gamingmesh/jobs/stuff/FileDownloader.java b/com/gamingmesh/jobs/stuff/FileDownloader.java new file mode 100644 index 00000000..cd4158c9 --- /dev/null +++ b/com/gamingmesh/jobs/stuff/FileDownloader.java @@ -0,0 +1,35 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.stuff; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URL; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; + +public class FileDownloader { + public static void downloadFile(URL url, File file) throws IOException { + ReadableByteChannel rbc = Channels.newChannel(url.openStream()); + FileOutputStream fos = new FileOutputStream(file); + fos.getChannel().transferFrom(rbc, 0, 1 << 24); + fos.close(); + } +} diff --git a/com/gamingmesh/jobs/stuff/GiveItem.java b/com/gamingmesh/jobs/stuff/GiveItem.java new file mode 100644 index 00000000..1c1a1ac3 --- /dev/null +++ b/com/gamingmesh/jobs/stuff/GiveItem.java @@ -0,0 +1,36 @@ +package com.gamingmesh.jobs.stuff; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +public class GiveItem { + public static boolean GiveItemForPlayer(Player player, int id, int meta, int qty, String name, List<String> lore, List<String> enchants) { + @SuppressWarnings("deprecation") + ItemStack itemStack = new ItemStack(Material.getMaterial(id), qty, (short) meta); + ItemMeta ItemMeta = itemStack.getItemMeta(); + if (lore != null) { + List<String> TranslatedLore = new ArrayList<String>(); + for (String oneLore : lore) { + TranslatedLore.add(ChatColor.translateAlternateColorCodes('&', oneLore.replace("[player]", player.getName()))); + } + ItemMeta.setLore(TranslatedLore); + } + if (enchants != null) + for (String OneEnchant : enchants) { + ItemMeta.addEnchant(Enchantment.getByName(OneEnchant.split("=")[0]), Integer.parseInt(OneEnchant.split("=")[1]), true); + } + if (name != null) + ItemMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', name)); + itemStack.setItemMeta(ItemMeta); + player.getInventory().addItem(itemStack); + player.getPlayer().updateInventory(); + return true; + } +} diff --git a/com/gamingmesh/jobs/stuff/JobsClassLoader.java b/com/gamingmesh/jobs/stuff/JobsClassLoader.java new file mode 100644 index 00000000..9d66e9ab --- /dev/null +++ b/com/gamingmesh/jobs/stuff/JobsClassLoader.java @@ -0,0 +1,45 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.stuff; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; + +import com.gamingmesh.jobs.Jobs; + +public class JobsClassLoader extends URLClassLoader { + + public JobsClassLoader(Jobs core) { + super(new URL[0], core.getClass().getClassLoader()); + } + + public void addFile(File f) throws IOException { + addURL(f.toURI().toURL()); + } + + @Override + public void addURL(URL url) { + for (URL u : getURLs()) + if (url.sameFile(u)) return; + + super.addURL(url); + } +} diff --git a/com/gamingmesh/jobs/stuff/PerformCommands.java b/com/gamingmesh/jobs/stuff/PerformCommands.java new file mode 100644 index 00000000..8b7f0c05 --- /dev/null +++ b/com/gamingmesh/jobs/stuff/PerformCommands.java @@ -0,0 +1,33 @@ +package com.gamingmesh.jobs.stuff; + +import java.util.List; + +import org.bukkit.Bukkit; + +import com.gamingmesh.jobs.container.Job; +import com.gamingmesh.jobs.container.JobsPlayer; + +public class PerformCommands { + + public static void PerformCommandsOnLeave(JobsPlayer jPlayer, Job job) { + + List<String> cmds = job.getCmdOnLeave(); + if (cmds.size() == 0) + return; + + for (String one : cmds) { + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), one.replace("[name]", jPlayer.getUserName()).replace("[jobname]", job.getName())); + } + } + + public static void PerformCommandsOnJoin(JobsPlayer jPlayer, Job job) { + + List<String> cmds = job.getCmdOnJoin(); + if (cmds.size() == 0) + return; + + for (String one : cmds) { + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), one.replace("[name]", jPlayer.getUserName()).replace("[jobname]", job.getName())); + } + } +} diff --git a/com/gamingmesh/jobs/stuff/Perm.java b/com/gamingmesh/jobs/stuff/Perm.java new file mode 100644 index 00000000..a4005ce0 --- /dev/null +++ b/com/gamingmesh/jobs/stuff/Perm.java @@ -0,0 +1,25 @@ +package com.gamingmesh.jobs.stuff; + +import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionDefault; + +public class Perm { + public static boolean hasPermission(OfflinePlayer player, String permission) { + Permission p = new Permission(permission, PermissionDefault.FALSE); + return ((Player) player).hasPermission(p); + } + + public static boolean hasPermission(CommandSender player, String permission) { + if (player instanceof Player) + return hasPermission((Player) player, permission); + return true; + } + + public static boolean hasPermission(Player player, String permission) { + Permission p = new Permission(permission, PermissionDefault.FALSE); + return player.hasPermission(p); + } +} diff --git a/com/gamingmesh/jobs/stuff/Scboard.java b/com/gamingmesh/jobs/stuff/Scboard.java new file mode 100644 index 00000000..6d7b51f2 --- /dev/null +++ b/com/gamingmesh/jobs/stuff/Scboard.java @@ -0,0 +1,48 @@ +package com.gamingmesh.jobs.stuff; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map.Entry; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.DisplaySlot; + +import com.gamingmesh.jobs.JobsPlugin; +import com.gamingmesh.jobs.config.ConfigManager; + +public class Scboard { + + private static HashMap<String, Long> timerMap = new HashMap<String, Long>(); + + private static void RunScheduler() { + + Iterator<Entry<String, Long>> MeinMapIter = timerMap.entrySet().iterator(); + while (MeinMapIter.hasNext()) { + Entry<String, Long> Map = MeinMapIter.next(); + + if (System.currentTimeMillis() > Map.getValue() + (ConfigManager.getJobsConfiguration().ToplistInScoreboardInterval * 1000)) { + Player player = Bukkit.getPlayer(Map.getKey()); + if (player != null) { + player.getScoreboard().clearSlot(DisplaySlot.SIDEBAR); + } + timerMap.remove(Map.getKey()); + } + } + + if (timerMap.size() > 0) + Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(JobsPlugin.instance, new Runnable() { + public void run() { + RunScheduler(); + return; + } + }, 20L); + return; + } + + public static void addNew(Player player) { + timerMap.put(player.getName(), System.currentTimeMillis()); + RunScheduler(); + } + +} diff --git a/com/gamingmesh/jobs/stuff/ScheduleUtil.java b/com/gamingmesh/jobs/stuff/ScheduleUtil.java new file mode 100644 index 00000000..68ecd9cc --- /dev/null +++ b/com/gamingmesh/jobs/stuff/ScheduleUtil.java @@ -0,0 +1,99 @@ +package com.gamingmesh.jobs.stuff; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import org.bukkit.Bukkit; + +import com.gamingmesh.jobs.JobsPlugin; +import com.gamingmesh.jobs.config.ConfigManager; +import com.gamingmesh.jobs.container.Job; +import com.gamingmesh.jobs.container.Schedule; +import com.gamingmesh.jobs.i18n.Language; + +public class ScheduleUtil { + public static boolean scheduler() { + if (ConfigManager.getJobsConfiguration().BoostSchedule.size() > 0 && ConfigManager.getJobsConfiguration().useGlobalBoostScheduler) { + + DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); + Date date = new Date(); + + String currenttime = dateFormat.format(date); + + int Current = Integer.valueOf(currenttime.replace(":", "")).intValue(); + + String CurrentDayName = GetWeekDay(); + + for (Schedule one : ConfigManager.getJobsConfiguration().BoostSchedule) { + + int From = one.GetFrom(); + int Until = one.GetUntil(); + + List<String> days = one.GetDays(); + + if (((one.isNextDay() && (Current >= From && Current < one.GetUntil() || Current >= one.GetNextFrom() && Current < one.GetNextUntil()) && !one.isStarted()) || !one.isNextDay() && (Current >= From && Current < Until)) && (days.contains(CurrentDayName) || days.contains("all")) && !one.isStarted()) { + + if (one.isBroadcastOnStart()) + if (one.GetMessageOnStart().size() == 0) + Bukkit.broadcastMessage(Language.getMessage("message.boostStarted")); + else + for (String oneMsg : one.GetMessageOnStart()) { + Bukkit.broadcastMessage(oneMsg); + } + + for (Job onejob : one.GetJobs()) { + onejob.setExpBoost(one.GetExpBoost()); + onejob.setMoneyBoost(one.GetMoneyBoost()); + } + one.setStarted(true); + one.setStoped(false); + break; + } else if (((one.isNextDay() && Current > one.GetNextUntil() && Current < one.GetFrom() && !one.isStoped()) || !one.isNextDay() && Current > Until && ((days.contains(CurrentDayName)) || days.contains("all"))) && !one.isStoped()) { + if (one.isBroadcastOnStop()) + if (one.GetMessageOnStop().size() == 0) + Bukkit.broadcastMessage(Language.getMessage("message.boostStoped")); + else + for (String oneMsg : one.GetMessageOnStop()) { + Bukkit.broadcastMessage(oneMsg); + } + one.setStoped(true); + one.setStarted(false); + } + + } + + Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(JobsPlugin.instance, new Runnable() { + public void run() { + scheduler(); + return; + } + }, 1 * 20L); + } + return true; + } + + public static String GetWeekDay() { + Calendar c = Calendar.getInstance(); + int dayOfWeek = c.get(Calendar.DAY_OF_WEEK); + switch (dayOfWeek) { + case 2: + return "monday"; + case 3: + return "tuesday"; + case 4: + return "wednesday"; + case 5: + return "thursday"; + case 6: + return "friday"; + case 7: + return "saturday"; + case 1: + return "sunday"; + } + return "all"; + } +} diff --git a/com/gamingmesh/jobs/stuff/TabComplete.java b/com/gamingmesh/jobs/stuff/TabComplete.java new file mode 100644 index 00000000..4c027d0e --- /dev/null +++ b/com/gamingmesh/jobs/stuff/TabComplete.java @@ -0,0 +1,90 @@ +package com.gamingmesh.jobs.stuff; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; +import org.bukkit.util.StringUtil; + +import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.container.ActionType; +import com.gamingmesh.jobs.container.Job; +import com.gamingmesh.jobs.container.JobItems; +import com.gamingmesh.jobs.i18n.Language; + +public class TabComplete implements TabCompleter { + + private static final List<String> BaseCommands = new ArrayList<>(Arrays.asList("Convert", "Limit", "Join", "Transfer", "Info", "Top", "Gtop", "Reload", "Removexp", "Leaveall", "Promote", "Browse", "Playerinfo", "Fireall", "Demote", "Grantxp", "Employ", "Fire", "Give", "Leave", "Stats", "Toggle", "Boost", "Archive")); + + @Override + public List<String> onTabComplete(CommandSender sender, Command command, String label, String[] args) { + List<String> completionList = new ArrayList<>(); + + if (args.length == 1) { + String PartOfCommand = args[0]; + List<String> temp = new ArrayList<String>(); + + for (String BCmd : BaseCommands) { + if (sender.hasPermission("jobs.command." + BCmd.toLowerCase())) { + temp.add(BCmd); + } + } + StringUtil.copyPartialMatches(PartOfCommand, temp, completionList); + } + if (args.length > 1) + for (int i = 1; i <= args.length; i++) + if (args.length == i + 1) { + + String PartOfCommand = args[i]; + String CommandArgs = Language.getDefaultMessage("command." + args[0].toLowerCase() + ".help.args"); + List<String> ArgsList = new ArrayList<String>(); + + if (!CommandArgs.contains(" ")) { + ArgsList.add(CommandArgs); + } else { + ArgsList.addAll(Arrays.asList(CommandArgs.split(" "))); + } + + if (ArgsList.size() < i) + continue; + + String arg = ArgsList.get(i - 1); + List<String> temp = new ArrayList<String>(); + if (arg.equalsIgnoreCase("[jobname]") || arg.equalsIgnoreCase("[oldjob]") || arg.equalsIgnoreCase("[newjob]")) { + List<Job> Jobsai = Jobs.getJobs(); + for (Job one : Jobsai) { + temp.add(one.getName()); + } + } + + if (arg.equalsIgnoreCase("[playername]")) { + for (Player player : Bukkit.getOnlinePlayers()) { + temp.add(player.getName()); + } + } + + if (arg.equalsIgnoreCase("[action]")) { + for (ActionType action : ActionType.values()) { + temp.add(action.getName()); + } + } + + if (arg.equalsIgnoreCase("[itemname]")) { + Job Jobsai = Jobs.getJob(args[i - 1]); + if (Jobsai != null) + for (JobItems item : Jobsai.getItems()) { + temp.add(item.getNode()); + } + } + StringUtil.copyPartialMatches(PartOfCommand, temp, completionList); + } + Collections.sort(completionList); + return completionList; + } +} diff --git a/com/gamingmesh/jobs/stuff/TranslateName.java b/com/gamingmesh/jobs/stuff/TranslateName.java new file mode 100644 index 00000000..71ed6452 --- /dev/null +++ b/com/gamingmesh/jobs/stuff/TranslateName.java @@ -0,0 +1,86 @@ +package com.gamingmesh.jobs.stuff; + +import com.gamingmesh.jobs.config.ConfigManager; +import com.gamingmesh.jobs.container.JobInfo; +import com.gamingmesh.jobs.container.NameList; + +public class TranslateName { + + public static String Translate(String materialName, JobInfo info) { + + // Translating name to user friendly + if (ConfigManager.getJobsConfiguration().UseCustomNames) + switch (info.getActionType()) { + case BREAK: + case CRAFT: + case DYE: + case PLACE: + case SMELT: + case REPAIR: + case BREW: + case FISH: + for (NameList one : ConfigManager.getJobsConfiguration().ListOfNames) { + String ids = one.getId() + ":" + one.getMeta(); + if (!one.getMeta().equalsIgnoreCase("") && ids.equalsIgnoreCase(info.getId() + ":" + info.getMeta()) && !one.getId().equalsIgnoreCase("0")) { + return one.getName(); + } + } + for (NameList one : ConfigManager.getJobsConfiguration().ListOfNames) { + String ids = one.getId(); + if (ids.equalsIgnoreCase(String.valueOf(info.getId())) && !one.getId().equalsIgnoreCase("0")) { + return one.getName(); + } + } + break; + case BREED: + case KILL: + case MILK: + case TAME: + for (NameList one : ConfigManager.getJobsConfiguration().ListOfEntities) { + String ids = one.getId() + ":" + one.getMeta(); + if (!one.getMeta().equalsIgnoreCase("") && ids.equalsIgnoreCase(info.getId() + ":" + info.getMeta()) && !one.getId().equalsIgnoreCase("0")) { + return one.getName(); + } + } + for (NameList one : ConfigManager.getJobsConfiguration().ListOfEntities) { + String ids = one.getId(); + if (ids.equalsIgnoreCase(String.valueOf(info.getId())) && !one.getId().equalsIgnoreCase("0")) { + return materialName = one.getName(); + } + } + break; + case ENCHANT: + for (NameList one : ConfigManager.getJobsConfiguration().ListOfEnchants) { + String ids = one.getId(); + if (ids.equalsIgnoreCase(String.valueOf(info.getId()))) { + return one.getName() + " " + info.getMeta(); + } + } + for (NameList one : ConfigManager.getJobsConfiguration().ListOfNames) { + String ids = one.getId() + ":" + one.getMeta(); + if (!one.getMeta().equalsIgnoreCase("") && ids.equalsIgnoreCase(info.getId() + ":" + info.getMeta()) && !one.getId().equalsIgnoreCase("0")) { + return one.getName(); + } + } + for (NameList one : ConfigManager.getJobsConfiguration().ListOfNames) { + String ids = one.getId(); + if (ids.equalsIgnoreCase(String.valueOf(info.getId())) && !one.getId().equalsIgnoreCase("0")) { + return one.getName(); + } + } + break; + case CUSTOMKILL: + break; + case SHEAR: + for (NameList one : ConfigManager.getJobsConfiguration().ListOfColors) { + String ids = one.getMinecraftName(); + if (ids.equalsIgnoreCase(String.valueOf(info.getName()))) { + return one.getName(); + } + } + break; + } + + return materialName; + } +} diff --git a/com/gamingmesh/jobs/stuff/UUIDUtil.java b/com/gamingmesh/jobs/stuff/UUIDUtil.java new file mode 100644 index 00000000..d4dc4dc8 --- /dev/null +++ b/com/gamingmesh/jobs/stuff/UUIDUtil.java @@ -0,0 +1,38 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.stuff; + +import java.nio.ByteBuffer; +import java.util.UUID; + +public class UUIDUtil { + public static byte[] toBytes(UUID uuid) { + ByteBuffer bb = ByteBuffer.allocate(16); + bb.putLong(uuid.getMostSignificantBits()); + bb.putLong(uuid.getLeastSignificantBits()); + return bb.array(); + } + + public static UUID fromBytes(byte[] array) { + ByteBuffer bb = ByteBuffer.wrap(array); + long most = bb.getLong(); + long least = bb.getLong(); + return new UUID(most, least); + } +} diff --git a/com/gamingmesh/jobs/tasks/.gitignore b/com/gamingmesh/jobs/tasks/.gitignore new file mode 100644 index 00000000..33a552d6 --- /dev/null +++ b/com/gamingmesh/jobs/tasks/.gitignore @@ -0,0 +1,3 @@ +/BufferedPaymentTask.class +/BufferedPaymentThread.class +/DatabaseSaveThread.class diff --git a/com/gamingmesh/jobs/tasks/BufferedPaymentTask.java b/com/gamingmesh/jobs/tasks/BufferedPaymentTask.java new file mode 100644 index 00000000..3a858eb7 --- /dev/null +++ b/com/gamingmesh/jobs/tasks/BufferedPaymentTask.java @@ -0,0 +1,44 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.tasks; + +import com.gamingmesh.jobs.economy.BufferedEconomy; +import com.gamingmesh.jobs.economy.BufferedPayment; +import com.gamingmesh.jobs.economy.Economy; + +public class BufferedPaymentTask implements Runnable { + private BufferedEconomy bufferedEconomy; + private Economy economy; + private BufferedPayment payment; + public BufferedPaymentTask(BufferedEconomy bufferedEconomy, Economy economy, BufferedPayment payment) { + this.bufferedEconomy = bufferedEconomy; + this.economy = economy; + this.payment = payment; + } + @Override + public void run() { + if (payment.getAmount() > 0) { + economy.depositPlayer(payment.getOfflinePlayer(), payment.getAmount()); + } else { + if (!economy.withdrawPlayer(payment.getOfflinePlayer(), -payment.getAmount())) { + bufferedEconomy.pay(payment); + } + } + } +} diff --git a/com/gamingmesh/jobs/tasks/BufferedPaymentThread.java b/com/gamingmesh/jobs/tasks/BufferedPaymentThread.java new file mode 100644 index 00000000..5289939f --- /dev/null +++ b/com/gamingmesh/jobs/tasks/BufferedPaymentThread.java @@ -0,0 +1,73 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.tasks; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.ConsoleCommandSender; + +import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.economy.BufferedEconomy; + +public class BufferedPaymentThread extends Thread { + private volatile boolean running = true; + private int sleep; + + public BufferedPaymentThread(int duration) { + super("Jobs-BufferedPaymentThread"); + this.sleep = duration * 1000; + } + + @Override + public void run() { + + String message = ChatColor.translateAlternateColorCodes('&', "&2Started buffered payment thread."); + ConsoleCommandSender console = Bukkit.getServer().getConsoleSender(); + console.sendMessage(message); + + //Jobs.getPluginLogger().info("Started buffered payment thread"); + while (running) { + try { + sleep(sleep); + } catch (InterruptedException e) { + this.running = false; + continue; + } + try { + BufferedEconomy economy = Jobs.getEconomy(); + if (economy != null) + economy.payAll(); + } catch (Throwable t) { + t.printStackTrace(); + message = ChatColor.translateAlternateColorCodes('&', "&cException in BufferedPaymentThread, stopping economy payments!"); + console.sendMessage(message); + //Jobs.getPluginLogger().severe("Exception in BufferedPaymentThread, stopping economy payments!"); + running = false; + } + } + message = ChatColor.translateAlternateColorCodes('&', "&6Buffered payment thread shutdown."); + console.sendMessage(message); + //Jobs.getPluginLogger().info("Buffered payment thread shutdown"); + } + + public void shutdown() { + this.running = false; + interrupt(); + } +} diff --git a/com/gamingmesh/jobs/tasks/DatabaseSaveThread.java b/com/gamingmesh/jobs/tasks/DatabaseSaveThread.java new file mode 100644 index 00000000..2a5930e9 --- /dev/null +++ b/com/gamingmesh/jobs/tasks/DatabaseSaveThread.java @@ -0,0 +1,74 @@ +/** + * Jobs Plugin for Bukkit + * Copyright (C) 2011 Zak Ford <zak.j.ford@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package com.gamingmesh.jobs.tasks; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.ConsoleCommandSender; + +import com.gamingmesh.jobs.Jobs; + +public class DatabaseSaveThread extends Thread { + + private volatile boolean running = true; + private int sleep; + + public DatabaseSaveThread(int duration) { + super("Jobs-DatabaseSaveTask"); + this.sleep = duration * 60000; + } + + @Override + public void run() { + //Jobs.getPluginLogger().info("Started database save task"); + + String message = ChatColor.translateAlternateColorCodes('&', "&2Started database save task."); + ConsoleCommandSender console = Bukkit.getServer().getConsoleSender(); + console.sendMessage(message); + + while (running) { + try { + sleep(sleep); + } catch (InterruptedException e) { + this.running = false; + continue; + } + try { + Jobs.getPlayerManager().saveAll(); + } catch (Throwable t) { + t.printStackTrace(); + //Jobs.getPluginLogger().severe("Exception in DatabaseSaveTask, stopping auto save!"); + message = ChatColor.translateAlternateColorCodes('&', "&cException in DatabaseSaveTask, stopping auto save!"); + console.sendMessage(message); + running = false; + } + } + + message = ChatColor.translateAlternateColorCodes('&', "&6Database save task shutdown!"); + console.sendMessage(message); + + //Jobs.getPluginLogger().info("Database save task shutdown"); + + } + + public void shutdown() { + this.running = false; + interrupt(); + } +} diff --git a/jobConfig.yml b/jobConfig.yml new file mode 100644 index 00000000..93efd231 --- /dev/null +++ b/jobConfig.yml @@ -0,0 +1,1018 @@ +# Jobs configuration. +# +# Stores information about each job. +# +# NOTE: When having multiple jobs, both jobs will give the income payout to the player +# even if they give the pay for one action (make the configurations with this in mind) +# and each job will get the respective experience. +# +# e.g If player has 2 jobs where job1 gives 10 income and experience for killing a player +# and job2 gives 5 income and experience for killing a player. When the user kills a player +# they will get 15 income and job1 will gain 10 experience and job2 will gain 5 experience. + +Jobs: + # must be one word + Woodcutter: + # full name of the job (displayed when browsing a job, used when joining and leaving) + # also can be used as a prefix for the user's name if the option is enabled. + # Shown as a prefix only when the user has 1 job. + # + # NOTE: Must be 1 word + fullname: Woodcutter + # Shortened version of the name of the job. Used as a prefix when the user has more + # than 1 job + shortname: W + description: Earns money felling and planting trees + # The colour of the name, for a full list of supported colours, go to the message config. + ChatColour: GREEN + # Option to let you choose what kind of prefix this job adds to your name. + # options are: full, title, job, shortfull, shorttitle, shortjob and none + chat-display: full + # [OPTIONAL] - the maximum level of this class + #max-level: 10 + # [OPTIONAL] - the maximum level of this class with specific permission + # use jobs.[jobsname].vipmaxlevel + #vip-max-level: 20 + # [OPTIONAL] - the maximum number of users on the server that can have this job at + # any one time (includes offline players). + #slots: 1 + # Equation used for calculating how much experience is needed to go to the next level. + # Available parameters: + # numjobs - the number of jobs the player has + # joblevel - the level the player has attained in the job. + # NOTE: Please take care of the brackets when modifying this equation. + leveling-progression-equation: 100*((1.13+(0.01*(numjobs-1)))^(joblevel-1)) + # Equation used for calculating how much income is given per action for the job level. + # Available parameters: + # baseincome - the income for the action at level 1 (as set in the configuration). + # joblevel - the level the player has attained in the job. + # NOTE: Please take care of the brackets when modifying this equation. + income-progression-equation: baseincome*((1.05)^(joblevel-1)) + # Equation used for calculating how much experience is given per action for the job level. + # Available parameters: + # baseexperience - the experience for the action at level 1 (as set in the configuration). + # joblevel - the level the player has attained in the job. + # NOTE: Please take care of the brackets when modifying this equation. + experience-progression-equation: baseexperience*((1.05)^(joblevel-1)) + ######################################################################## + # Section used to configure what items the job gets paid for, how much + # they get paid and how much experience they gain. + # + # For break and place, the block name or id is used. + # You can select a sub-type by using a '-' between the id and the bit + # value for the sub-type. e.g LOG-0 = usual log, LOG-2 = birch log + # 17-2 = birch log. + # + # If no sub-type is give, the payout will be for all sub-types. + # + # To get a list of all available block types, check the + # bukkit JavaDocs for a complete list of block types + # https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html + # + # For kill tags (Kill and custom-kill), the name is the name of the + # mob. + # Available mobs: + # Bat + # Blaze + # Cave_spider + # Chicken + # Cow + # Creeper + # Ender_dragon + # Enderman + # Endermite + # Ghast + # Giant + # Guardian + # Horse + # Iron_golem + # Magma_cube + # Mushroom_cow + # Ocelot + # Pig + # Player + # Rabbit + # Sheep + # Silverfish + # Skeleton + # Slime + # Snowman + # Spider + # Squid + # Villager + # Witch + # Wither + # Wolf + # Zombie + # + # NOTE: mob names are case sensitive. + # + # For custom-kill, it is the name of the job (also case sensitive). + # + # NOTE: If a job has both the pay for killing a player and for killing a + # specific class, they will get both payments. + ######################################################################## + # payment for breaking a block + Break: + # block name/id (with optional sub-type) + LOG: + # base income + income: 5.0 + # base experience + experience: 5.0 + # payment for placing a block + Place: + SAPLING: + income: 1.0 + experience: 1.0 + WOOD: + income: 2.0 + experience: 2.0 + # killing a mob + Kill: + # mob name + Player: + # base income + income: 7.5 + # base experience + experience: 7.5 + # Killing player with certain job + custom-kill: + Woodcutter: + income: 10.0 + experience: 10.0 + # Tamig animals + Tame: + Wolf: + income: 2.0 + experience: 5.0 + # Breeding animals + Breed: + Wolf: + income: 2.0 + experience: 5.0 + # Milking cows, only one option is available + Milk: + Cow: + income: 2.0 + experience: 5.0 + Mushroomcow: + income: 5.0 + experience: 10.0 + # Shear sheeps by its color + Shear: + Black: + income: 2.0 + experience: 5.0 + Blue: + income: 2.0 + experience: 5.0 + Brown: + income: 2.0 + experience: 5.0 + Cyan: + income: 2.0 + experience: 5.0 + Gray: + income: 2.0 + experience: 5.0 + Green: + income: 2.0 + experience: 5.0 + Light_blue: + income: 2.0 + experience: 5.0 + Lime: + income: 2.0 + experience: 5.0 + Magenta: + income: 2.0 + experience: 5.0 + Orange: + income: 2.0 + experience: 5.0 + Pink: + income: 2.0 + experience: 5.0 + Purple: + income: 2.0 + experience: 5.0 + Red: + income: 2.0 + experience: 5.0 + Silver: + income: 2.0 + experience: 5.0 + White: + income: 2.0 + experience: 5.0 + Yellow: + income: 2.0 + experience: 5.0 + # dyeing armor + Dye: + LEATHER_BOOTS: + income: 1.0 + experience: 1.0 + LEATHER_CHESTPLATE: + income: 1.0 + experience: 1.0 + LEATHER_HELMET: + income: 1.0 + experience: 1.0 + LEATHER_LEGGINGS: + income: 1.0 + experience: 1.0 + 351: + income: 1.0 + experience: 1.0 + # Catching fish + Fish: + '349': + income: 20.0 + experience: 25.0 + # Repairing items + Repair: + WOOD_SWORD: + income: 1.0 + experience: 1.0 + IRON_SWORD: + income: 2.0 + experience: 2.0 + # Crafting items + Craft: + WOOD_SWORD: + income: 1.5 + experience: 3.0 + LEATHER_BOOTS: + income: 1.0 + experience: 6.0 + # Smelting ores + Smelt: + IRON_INGOT: + income: 2.0 + experience: 8.0 + GOLD_INGOT: + income: 4.5 + experience: 12 + # Enchanting items + Enchant: + # You can set item for which player will get money + WOOD_SWORD: + income: 1.5 + experience: 3.0 + LEATHER_BOOTS: + income: 1.0 + experience: 6.0 + # Or/and you can give money for each enchantment they got + DIG_SPEED-1: + income: 3.0 + experience: 10.0 + DIG_SPEED-2: + income: 6.0 + experience: 20.0 + # Brewing potions + Brew: + NETHER_STALK: + income: 5.0 + experience: 3.0 + REDSTONE: + income: 5.0 + experience: 3.0 + # permissions granted for joining class + permissions: + # example node + aaaaaatest.node: + # true to give, false to revoke + value: true + # minimum level needed to grant permission. Use 0 for all levels + level: 0 + aaaaaatest.node2: + value: true + # Permission granted when reaching level 10 + level: 10 + # Commands executed when player reached level + commands: + # command name, just to have better idea what this do + fly: + # Command its self, this will be executed from console, so all commands should work + # Possible variables are: [player] [jobname] [oldlevel] [newlevel] + command: manuaddp [player] essentials.fly + # When to execute this command first time + levelFrom: 100 + # Until when to do this command + # This can be set to same level as levelFrom, so this command will be executed only once + levelUntil: 100 + kit: + command: manuaddp [player] essentials.kits.woodcutter + levelFrom: 150 + levelUntil: 150 + # Getting more money when equiped with specific weapon/tool ar wearing armor + items: + # Just name, dont have any impact + firstOne: + # Tool/Weapon id. Works for block Break, Fish, Animal tame, Breed, Monster/Player kill. + id: 278 + # Items name, should be with color codes + name: '&8Miner Pickaxe' + # Item lore, again should come with color codes + lore: + - '&eBobs pick' + - '&710% bonus XP' + # Item enchantments, all enchantment names can be found https://hub.spigotmc.org/javadocs/spigot/org/bukkit/enchantments/Enchantment.html + enchants: + - DAMAGE_ALL=1 + - FIRE_ASPECT=1 + # Money boost: 1.1 is equals 10% more income when 0.9 is equals 10% less from base income + moneyBoost: 1.1 + # Exp boost + expBoost: 1.1 + helmet: + # Armor id. This one works with all jobs + id: 310 + name: '&8Armor' + lore: + - '&eBobs armor' + - '&710% bonus XP' + moneyBoost: 1.1 + expBoost: 1.1 + cmd-on-join: + - 'msg [name] Thx for joining this job!' + - 'msg [name] Now start working and get money from [jobname] job!' + cmd-on-leave: + - 'msg [name] You have left this awesome [jobname] job' + - 'msg [name] See you soon!' + Miner: + fullname: Miner + shortname: M + description: Earns money mining minerals and ores. + ChatColour: DARK_GRAY + chat-display: full + #max-level: 10 + #slots: 10 + leveling-progression-equation: 100*((1.13+(0.01*(numjobs-1)))^(joblevel-1)) + income-progression-equation: baseincome*((1.05)^(joblevel-1)) + experience-progression-equation: baseexperience*((1.05)^(joblevel-1)) + Break: + STONE: + income: 2.0 + experience: 2.0 + COAL_ORE: + income: 3.0 + experience: 3.0 + GLOWING_REDSTONE_ORE: + income: 3.0 + experience: 3.0 + IRON_ORE: + income: 4.0 + experience: 4.0 + GOLD_ORE: + income: 5.0 + experience: 5.0 + LAPIS_ORE: + income: 5.0 + experience: 5.0 + DIAMOND_ORE: + income: 6.0 + experience: 6.0 + OBSIDIAN: + income: 7.5 + experience: 7.5 + MOSSY_COBBLESTONE: + income: 6.0 + experience: 6.0 + Place: + RAILS: + income: 2.0 + experience: 2.0 + IRON_ORE: + income: -5.0 + experience: -5.0 + GOLD_ORE: + income: -6.0 + experience: -6.0 + Kill: + Player: + income: 7.5 + experience: 7.5 + Builder: + fullname: Builder + shortname: B + description: Earns money for building structures. + ChatColour: WHITE + chat-display: full + #max-level: 10 + #slots: 10 + leveling-progression-equation: 100*((1.13+(0.01*(numjobs-1)))^(joblevel-1)) + income-progression-equation: baseincome*((1.05)^(joblevel-1)) + experience-progression-equation: baseexperience*((1.05)^(joblevel-1)) + Place: + COBBLESTONE: + income: 1.0 + experience: 1.0 + WOOD: + income: 1.5 + experience: 1.5 + FENCE: + income: 1.5 + experience: 1.5 + WOOL: + income: 1.5 + experience: 1.5 + STONE: + income: 2.25 + experience: 2.25 + GLOWSTONE: + income: 3.0 + experience: 3.0 + SANDSTONE: + income: 2.0 + experience: 2.0 + GLASS: + income: 3.0 + experience: 3.0 + BRICK: + income: 4.0 + experience: 4.0 + LAPIS_BLOCK: + income: 5.0 + experience: 5.0 + DOUBLE_STEP: + income: 2.0 + experience: 2.0 + STEP: + income: 2.0 + experience: 2.0 + BOOKSHELF: + income: 3.0 + experience: 3.0 + WOOD_STAIRS: + income: 2.0 + experience: 2.0 + COBBLESTONE_STAIRS: + income: 2.0 + experience: 2.0 + MOSSY_COBBLESTONE: + income: 5.0 + experience: 5.0 + DIAMOND_BLOCK: + income: 5.0 + experience: 5.0 + GOLD_BLOCK: + income: 5.0 + experience: 5.0 + Kill: + Player: + income: 7.5 + experience: 7.5 + Digger: + fullname: Digger + shortname: D + description: Earns money for terraforming the world. + ChatColour: GOLD + chat-display: full + #max-level: 10 + #slots: 10 + leveling-progression-equation: 100*((1.13+(0.01*(numjobs-1)))^(joblevel-1)) + income-progression-equation: baseincome*((1.05)^(joblevel-1)) + experience-progression-equation: baseexperience*((1.05)^(joblevel-1)) + Break: + DIRT: + income: 2.0 + experience: 2.0 + GRASS: + income: 2.0 + experience: 2.0 + GRAVEL: + income: 2.0 + experience: 2.0 + SAND: + income: 2.0 + experience: 2.0 + CLAY: + income: 2.0 + experience: 2.0 + Kill: + Player: + income: 7.5 + experience: 7.5 + custom-kill: + Digger: + income: 10.0 + experience: 10.0 + Farmer: + fullname: Farmer + shortname: Fa + description: Earns money farming crops. + ChatColour: BLUE + chat-display: full + #max-level: 10 + #slots: 10 + leveling-progression-equation: 100*((1.13+(0.01*(numjobs-1)))^(joblevel-1)) + income-progression-equation: baseincome*((1.05)^(joblevel-1)) + experience-progression-equation: baseexperience*((1.05)^(joblevel-1)) + Break: + CROPS-7: + income: 4.0 + experience: 4.0 + SUGAR_CANE_BLOCK: + income: 4.0 + experience: 4.0 + Tame: + Wolf: + income: 5.0 + experience: 5.0 + Breed: + Wolf: + income: 5.0 + experience: 5.0 + Place: + CROPS-0: + income: 3.0 + experience: 3.0 + SUGAR_CANE_BLOCK: + income: 1.0 + experience: 1.0 + Kill: + Player: + income: 7.5 + experience: 7.5 + Hunter: + fullname: Hunter + shortname: H + description: Earns money killing animals and monsters. + ChatColour: RED + chat-display: full + #max-level: 10 + #slots: 10 + leveling-progression-equation: 100*((1.13+(0.01*(numjobs-1)))^(joblevel-1)) + income-progression-equation: baseincome*((1.05)^(joblevel-1)) + experience-progression-equation: baseexperience*((1.05)^(joblevel-1)) + Kill: + Chicken: + income: 2.5 + experience: 2.5 + Cow: + income: 2.5 + experience: 2.5 + Pig: + income: 2.5 + experience: 2.5 + Sheep: + income: 2.5 + experience: 2.5 + Wolf: + income: 5.0 + experience: 5.0 + Creeper: + income: 10.0 + experience: 10.0 + Skeleton: + income: 10.0 + experience: 10.0 + WitherSkeleton: + income: 10.0 + experience: 10.0 + Spider: + income: 10.0 + experience: 10.0 + Zombie: + income: 10.0 + experience: 10.0 + Player: + income: 7.5 + experience: 7.5 + Fisherman: + fullname: Fisherman + shortname: Fi + description: Earns money from fishing. + ChatColour: AQUA + chat-display: full + #max-level: 10 + #slots: 10 + leveling-progression-equation: 100*((1.13+(0.01*(numjobs-1)))^(joblevel-1)) + income-progression-equation: baseincome*((1.05)^(joblevel-1)) + experience-progression-equation: baseexperience*((1.05)^(joblevel-1)) + Fish: + RAW_FISH: + income: 4.0 + experience: 4.0 + Kill: + Player: + income: 7.5 + experience: 7.5 + Weaponsmith: + fullname: Weaponsmith + shortname: W + description: Earns money from crafting and repairing weapons. + ChatColour: DARK_PURPLE + chat-display: full + #max-level: 10 + #slots: 10 + leveling-progression-equation: 100*((1.13+(0.01*(numjobs-1)))^(joblevel-1)) + income-progression-equation: baseincome*((1.05)^(joblevel-1)) + experience-progression-equation: baseexperience*((1.05)^(joblevel-1)) + Craft: + WOOD_SWORD: + income: 1.0 + experience: 1.0 + IRON_SWORD: + income: 2.0 + experience: 2.0 + GOLD_SWORD: + income: 3.0 + experience: 3.0 + DIAMOND_SWORD: + income: 4.0 + experience: 4.0 + Repair: + WOOD_SWORD: + income: 1.0 + experience: 1.0 + IRON_SWORD: + income: 2.0 + experience: 2.0 + GOLD_SWORD: + income: 3.0 + experience: 3.0 + DIAMOND_SWORD: + income: 4.0 + experience: 4.0 + Smelt: + IRON_INGOT: + income: 2.0 + experience: 2.0 + GOLD_INGOT: + income: 2.0 + experience: 2.0 + Brewer: + fullname: Brewer + shortname: Br + description: Earns money brewing potions. + ChatColour: LIGHT_PURPLE + chat-display: full + leveling-progression-equation: 100*((1.13+(0.01*(numjobs-1)))^(joblevel-1)) + income-progression-equation: baseincome*((1.05)^(joblevel-1)) + experience-progression-equation: baseexperience*((1.05)^(joblevel-1)) + Brew: + NETHER_STALK: + income: 1.0 + experience: 1.0 + REDSTONE: + income: 2.0 + experience: 2.0 + GLOWSTONE_DUST: + income: 2.0 + experience: 2.0 + SPIDER_EYE: + income: 2.0 + experience: 2.0 + FERMENTED_SPIDER_EYE: + income: 2.0 + experience: 2.0 + BLAZE_POWDER: + income: 2.0 + experience: 2.0 + SUGAR: + income: 2.0 + experience: 2.0 + SPECKLED_MELON: + income: 4.0 + experience: 4.0 + MAGMA_CREAM: + income: 4.0 + experience: 4.0 + GHAST_TEAR: + income: 4.0 + experience: 4.0 + Enchanter: + fullname: Enchanter + shortname: E + description: Earns money enchanting weapons. + ChatColour: DARK_BLUE + chat-display: full + #max-level: 10 + #slots: 10 + leveling-progression-equation: 100*((1.13+(0.01*(numjobs-1)))^(joblevel-1)) + income-progression-equation: baseincome*((1.05)^(joblevel-1)) + experience-progression-equation: baseexperience*((1.05)^(joblevel-1)) + Enchant: + WOOD_SWORD: + income: 1.5 + experience: 3.0 + LEATHER_BOOTS: + income: 1.0 + experience: 6.0 + LEATHER_CHESTPLATE: + income: 2.0 + experience: 6.0 + LEATHER_HELMET: + income: 1.0 + experience: 6.0 + LEATHER_LEGGINGS: + income: 2.0 + experience: 6.0 + IRON_SWORD: + income: 3.0 + experience: 6.0 + IRON_BOOTS: + income: 2.5 + experience: 9.0 + IRON_CHESTPLATE: + income: 4.5 + experience: 9.0 + IRON_HELMET: + income: 2.5 + experience: 9.0 + IRON_LEGGINGS: + income: 4.5 + experience: 9.0 + GOLD_SWORD: + income: 4.5 + experience: 15.0 + GOLD_BOOTS: + income: 2.5 + experience: 15.0 + GOLD_CHESTPLATE: + income: 5.5 + experience: 15.0 + GOLD_HELMET: + income: 2.5 + experience: 15.0 + GOLD_LEGGINGS: + income: 5.5 + experience: 15.0 + DIAMOND_SWORD: + income: 9.0 + experience: 30.0 + DIAMOND_SPADE: + income: 5.0 + experience: 30.0 + DIAMOND_PICKAXE: + income: 10.0 + experience: 30.0 + DIAMOND_AXE: + income: 10.0 + experience: 30.0 + DIAMOND_HELMET: + income: 6.0 + experience: 30.0 + DIAMOND_CHESTPLATE: + income: 12.0 + experience: 50.0 + DIAMOND_LEGGINGS: + income: 12.0 + experience: 50.0 + DIAMOND_BOOTS: + income: 6.0 + experience: 30.0 + ARROW_DAMAGE-1: + income: 3.0 + experience: 10.0 + ARROW_DAMAGE-2: + income: 6.0 + experience: 20.0 + ARROW_DAMAGE-3: + income: 9.0 + experience: 30.0 + ARROW_DAMAGE-4: + income: 12.0 + experience: 40.0 + ARROW_DAMAGE-5: + income: 15.0 + experience: 50.0 + ARROW_FIRE: + income: 10.0 + experience: 30.0 + ARROW_INFINITE: + income: 20.0 + experience: 50.0 + ARROW_KNOCKBACK-1: + income: 3.0 + experience: 10.0 + ARROW_KNOCKBACK-2: + income: 6.0 + experience: 20.0 + DAMAGE_ALL-1: + income: 10.0 + experience: 10.0 + DAMAGE_ALL-2: + income: 20.0 + experience: 20.0 + DAMAGE_ALL-3: + income: 30.0 + experience: 30.0 + DAMAGE_ALL-4: + income: 40.0 + experience: 40.0 + DAMAGE_ALL-5: + income: 50.0 + experience: 50.0 + DAMAGE_ARTHROPODS-1: + income: 3.0 + experience: 10.0 + DAMAGE_ARTHROPODS-2: + income: 6.0 + experience: 20.0 + DAMAGE_ARTHROPODS-3: + income: 9.0 + experience: 30.0 + DAMAGE_ARTHROPODS-4: + income: 12.0 + experience: 40.0 + DAMAGE_ARTHROPODS-5: + income: 15.0 + experience: 50.0 + DAMAGE_UNDEAD-1: + income: 3.0 + experience: 10.0 + DAMAGE_UNDEAD-2: + income: 6.0 + experience: 20.0 + DAMAGE_UNDEAD-3: + income: 9.0 + experience: 30.0 + DAMAGE_UNDEAD-4: + income: 12.0 + experience: 40.0 + DAMAGE_UNDEAD-5: + income: 15.0 + experience: 50.0 + DEPTH_STRIDER-1: + income: 3.0 + experience: 10.0 + DEPTH_STRIDER-2: + income: 6.0 + experience: 20.0 + DEPTH_STRIDER-3: + income: 9.0 + experience: 30.0 + DIG_SPEED-1: + income: 3.0 + experience: 10.0 + DIG_SPEED-2: + income: 6.0 + experience: 20.0 + DIG_SPEED-3: + income: 9.0 + experience: 30.0 + DIG_SPEED-4: + income: 12.0 + experience: 40.0 + DIG_SPEED-5: + income: 15.0 + experience: 50.0 + DURABILITY-1: + income: 3.0 + experience: 10.0 + DURABILITY-2: + income: 6.0 + experience: 20.0 + DURABILITY-3: + income: 9.0 + experience: 30.0 + FIRE_ASPECT-1: + income: 3.0 + experience: 10.0 + FIRE_ASPECT-2: + income: 6.0 + experience: 20.0 + KNOCKBACK-1: + income: 3.0 + experience: 10.0 + KNOCKBACK-2: + income: 6.0 + experience: 20.0 + LOOT_BONUS_BLOCKS-1: + income: 20.0 + experience: 100.0 + LOOT_BONUS_BLOCKS-2: + income: 40.0 + experience: 200.0 + LOOT_BONUS_BLOCKS-3: + income: 80.0 + experience: 300.0 + LOOT_BONUS_MOBS-1: + income: 5.0 + experience: 20.0 + LOOT_BONUS_MOBS-2: + income: 12.0 + experience: 40.0 + LOOT_BONUS_MOBS-3: + income: 15.0 + experience: 60.0 + LUCK-1: + income: 15.0 + experience: 10.0 + LUCK-2: + income: 25.0 + experience: 20.0 + LUCK-3: + income: 35.0 + experience: 30.0 + LURE-1: + income: 10.0 + experience: 10.0 + LURE-2: + income: 20.0 + experience: 20.0 + LURE-3: + income: 30.0 + experience: 30.0 + OXYGEN-1: + income: 3.0 + experience: 10.0 + OXYGEN-2: + income: 6.0 + experience: 20.0 + OXYGEN-3: + income: 9.0 + experience: 30.0 + PROTECTION_ENVIRONMENTAL-1: + income: 5.0 + experience: 10.0 + PROTECTION_ENVIRONMENTAL-2: + income: 10.0 + experience: 20.0 + PROTECTION_ENVIRONMENTAL-3: + income: 15.0 + experience: 30.0 + PROTECTION_ENVIRONMENTAL-4: + income: 20.0 + experience: 40.0 + PROTECTION_EXPLOSIONS-1: + income: 5.0 + experience: 10.0 + PROTECTION_EXPLOSIONS-2: + income: 10.0 + experience: 20.0 + PROTECTION_EXPLOSIONS-3: + income: 15.0 + experience: 30.0 + PROTECTION_EXPLOSIONS-4: + income: 20.0 + experience: 40.0 + PROTECTION_FALL-1: + income: 3.0 + experience: 10.0 + PROTECTION_FALL-2: + income: 6.0 + experience: 20.0 + PROTECTION_FALL-3: + income: 9.0 + experience: 30.0 + PROTECTION_FALL-4: + income: 12.0 + experience: 40.0 + PROTECTION_FIRE-1: + income: 5.0 + experience: 10.0 + PROTECTION_FIRE-2: + income: 10.0 + experience: 20.0 + PROTECTION_FIRE-3: + income: 15.0 + experience: 30.0 + PROTECTION_FIRE-4: + income: 20.0 + experience: 40.0 + PROTECTION_PROJECTILE-1: + income: 10.0 + experience: 10.0 + PROTECTION_PROJECTILE-2: + income: 20.0 + experience: 20.0 + PROTECTION_PROJECTILE-3: + income: 30.0 + experience: 30.0 + PROTECTION_PROJECTILE-4: + income: 40.0 + experience: 40.0 + SILK_TOUCH: + income: 100.0 + experience: 300.0 + THORNS-1: + income: 4.0 + experience: 10.0 + THORNS-2: + income: 8.0 + experience: 20.0 + THORNS-3: + income: 12.0 + experience: 30.0 + WATER_WORKER: + income: 30.0 + experience: 100.0 + None: + fullname: None + shortname: N + ChatColour: WHITE + chat-display: none + #max-level: 10 + #slots: 10 + leveling-progression-equation: 100*((1.13+(0.01*(numjobs-1)))^(joblevel-1)) + income-progression-equation: baseincome*((1.05)^(joblevel-1)) + experience-progression-equation: baseexperience*((1.05)^(joblevel-1)) + Kill: + Player: + income: 7.5 \ No newline at end of file diff --git a/locale/messages_cs.yml b/locale/messages_cs.yml new file mode 100644 index 00000000..4d534b4a --- /dev/null +++ b/locale/messages_cs.yml @@ -0,0 +1,230 @@ +economy: + error: + nomoney: Nezbyly zadne penize v bance! +command: + boost: + help: + info: Zvysuje Exp/penezni zisk pro vsechny hrace. + args: '[JmenoPrace] [Hodnota]' + output: + allreset: Vsechny exp/penezni boosty byly vypnuty. + jobsboostreset: Boost pro %jobname% byl vypnut. + nothingtoreset: Neni nic, co by se dalo resetovat. + boostalladded: Boost hodnoty %boost% byl zvysen pro vsechny prace. + boostadded: Boost hodnoty &e%boost% &abyl zvysen pro praci &e%jobname%! + infostats: '&c-----> &aExp/penezni zisk x%boost% je zapnut&c <-------' + convert: + help: + info: Prevede data z jednoho zpusobu databaze na jiny. Pokud prve pouzivate SQLite, bude preveden na MySQL a naopak. + args: '' + limit: + help: + info: Vypise limit plateb pro prce. + args: '' + output: + lefttime: '&eZbyvajici cas do restartovani limitu penez: &2%hour% &ehour &2%min% &emin &2%sec% + &esec' + moneylimit: '&eLimit penez: &2%money%&e/&2%totalmoney%' + reachedlimit: '&4Dosahl jsi limitu penez v danem case!' + reachedlimit2: '&eMuzes zjistit svuj limit pomoci &2/jobs limit &eprikazu' + notenabled: '&eLimit penez neni zapnuty.' + admin: + error: Doslo k chybe v prikazu. + success: Prikaz byl vykonan. + error: + job: Prace kterou jsis vybral neexistuje. + permission: Nemas povoleni na tuto akci. + help: + output: + info: Napis /jobs [cmd] ? pro vice informaci o prikazu. + usage: 'Pouziti: %usage%' + stats: + help: + info: Vypise level v pracich ve kterych jses/byl jsi zamestnany. + args: '[JmenoHrace]' + error: + nojob: Prosim, nejdrive se pripoj do prace. + output: 'lvl%joblevel% %jobname% : %jobxp%/%jobmaxxp% xp' + archive: + help: + info: Vypise vsechny prace ulozene v archivu podle uzivatele. + args: '[JmenoHrace]' + error: + nojob: Nejsou zadne ulozene prace. + output: lvl %joblevel% (%getbackjoblevel%) %jobname% + give: + help: + info: D item podle nzvu prce a nzvu kategorie. Jmeno Hrace neni povinny udaj. + args: '[JmenoHrace] [JmenoPrace] [JmenoItemu]' + output: + notonline: '&4Hrac [%playername%] neni online!' + noitem: '&4Nelze najit nejaky item s timto jmenem!' + info: + help: + title: '&2*** &ePrace&2 ***' + info: Vypise, jak moc a za co vydelava nejaka prace. + args: '[JmenoPrace] [akce]' + actions: '&ePlatne akce jsou: &f%actions%' + max: ' - &emax level:&f ' + material: '&7%material%' + output: + break: + info: Kopani + none: '%jobname% nevydelava penize za kopani blocku.' + place: + info: Staveni + none: '%jobname% nevydelava penize za staveni blocku.' + kill: + info: Zabijeni + none: '%jobname% nevydelava penize za zabijeni monster.' + fish: + info: Rybareni + none: '%jobname% nevydelava penize za rybaren ryb.' + craft: + info: Craft + none: '%jobname% nevydelava penize za craften vec.' + smelt: + info: Peceni + none: '%jobname% nevydelava penize za pecen v peci.' + brew: + info: Vareni + none: '%jobname% nevydelava penize za vareni lektvaru.' + enchant: + info: Ocarovani + none: '%jobname% nevydelava penize za ocarovvn/enchant itemu.' + repair: + info: Opravovani + none: '%jobname% nevydelava penize za opravovn predmetu.' + breed: + info: Farmareni + none: '%jobname% nevydelava penize za farmareni.' + tame: + info: Ochocovani + none: '%jobname% nevydelava penize za ochocovani zvirat.' + playerinfo: + help: + info: Vypise, jako moc v jake praci a za co, vydelava nejaky hrac. + args: '[JmenoHrace] [JmenoPrace] [akce]' + join: + help: + info: Zamestnat se od prace. + args: '[JmenoPrace]' + error: + alreadyin: Uz pracujes jako %jobname%. + fullslots: Nemuzes se pripojit do prace %jobname%, nejsou zde zadna volna mista. + maxjobs: Jiz ms prlis mnoho prac. + success: Zamestnal ses jako %jobname%. + leave: + help: + info: Opustit vybranou praci. + args: '[JmenoPrace]' + success: Opustil jsi praci %jobname%. + leaveall: + help: + info: Opustit vsechny svoje prace + error: + nojobs: Nemas zadne prace, ktere by jsi mohl opustit. + success: Opustil jsi vechny sve prace. + browse: + help: + info: List prac dostupnch pro tebe + error: + nojobs: Nejsou zadne prace, ve kterych by jsi mohl byt zamestnan. + output: + header: 'Mas povoleni na zamestnani v dannych pracch:' + footer: Pro vce info napis /jobs info [JmenoPrace] + fire: + help: + info: Vykopnout hrace z danne prace. + args: '[JmenoHrace] [JmenoPrace]' + error: + nojob: Hrac neni zamestnan jako %jobname%. + output: + target: Byl jsi vyhozen z prace %jobname%. + fireall: + help: + info: Vykopnout hrace ze vsech prac. + args: '[JmenoHrace]' + error: + nojobs: Hrac nema zadne prace, ze kterych by mohl byt vykopnut. + output: + target: Byl jsi vykopnut se vsech prac. + employ: + help: + info: Zamestnat hrace do prace. + args: '[JmenoHrace] [JmenoPrace]' + error: + alreadyin: Hrac jiz je v praci %jobname%. + output: + target: Byl jsi zamestnan jako %jobname%. + top: + help: + info: Zobrazi Top 10 hracu podle prace. + args: '[JmenoPrace]' + error: + nojob: Nelze najit zadnou praci s timto jmenem. + output: + topline: '&aTop&e 10 &ahrac podle &e%jobname% &ajob' + list: '&e%number%&a. &e%playername% &alvl &e%level% &awith&e %exp% &aexp' + transfer: + help: + info: Prevede hrcovu prci ze star prce do nov. + args: '[JmenoHrace] [StaraPrace] [NovaPrace]' + output: + target: You have been transferred from %oldjobname% to %newjobname%. + promote: + help: + info: Prida hracovi X zkusenosti do danne prace. + args: '[JmenoHrace] [JmenoPrace] [levely]' + output: + target: Bylo ti pridano %levelsgained% levelu v praci %jobname%. + demote: + help: + info: Odebere hracovi X zkusenosti z danne prace. + args: '[JmenoHrace] [JmenoPrace] [levely]' + output: + target: Bylo ti odebrano %levelslost% levelu v praci %jobname%. + grantxp: + help: + info: Prida hracovi X zkusenosti do prace. + args: '[JmenoHrace] [JmenoPrace] [xp]' + output: + target: Dostal jsi %xpgained% zkusenosti v praci %jobname%. + removexp: + help: + info: Odstrani hracovi X zkusenostiz danne prace. + args: '[JmenoHrace] [JmenoPrace] [xp]' + output: + target: Ztratil jsi %xplost% zkusenosti v praci %jobname%. + reload: + help: + info: Reloadne configurace. + toggle: + help: + info: Prepina vystup plateb na panelu akci. + output: + paid: '&aDostal jsi penize za: &2[amount]' + 'on': '&aZmeneno: &aON' + 'off': '&aZmeneno: &4OFF' +message: + skillup: + broadcast: '%playername% byl povisen na %titlename% %jobname%.' + nobroadcast: Gratulujeme, byl jsi povysen na %titlename% %jobname%. + levelup: + broadcast: 'Hrac %playername% ziskal level %joblevel% v praci %jobname%.' + nobroadcast: Ziskal jsi level %joblevel% v praci %jobname%. + crafting: + fullinventory: Mas plny inventar! +signs: + cantcreate: '&4Nemuzes vytvorit tuto cedulku!' + topline: '&e[Jobs]' + secondline: + join: '&2Join' + leave: '&4Leave' + toggle: '&eToggle' + top: '&eTop' + browse: '&eBrowse' + stats: '&eStats' + limit: '&eLimit' + info: '&eInfo' + archive: '&eArchive' \ No newline at end of file diff --git a/locale/messages_de.yml b/locale/messages_de.yml new file mode 100644 index 00000000..07089ba3 --- /dev/null +++ b/locale/messages_de.yml @@ -0,0 +1,248 @@ +economy: + error: + nomoney: Die Bank hat kein Geld mehr! +command: + boost: + help: + info: Erhöht Exp/Geld für alle Spieler + args: '[Jobname] [Faktor]' + output: + allreset: Alle exp-/Geld-Boosts deaktiviert + jobsboostreset: Boost für %jobname% deaktiviert + nothingtoreset: Es gibt nichts zum zurücksetzen + boostalladded: Ein Boost von %boost% allen Jobs hinzugefügt! + boostadded: Ein Boost von &e%boost% &ahinzugefügt für &e%jobname%! + infostats: '&c-----> &äxp-/Geld-Faktor x%boost% aktiviert&c <-------' + convert: + help: + info: Konvertiert das Datenbanksystem vom einen zum anderen. Benutzt du momentan sqlite, wird zu MySQL konvertiert und andersherum. + args: '' + limit: + help: + info: Zeigt die Lohngrenze für Jobs an. + args: '' + output: + lefttime: '&eZeit bis zum Limit-Reset: &2%hour% &eStunde, &2%min% &eMinuten, &2%sec% + &eSekunden' + moneylimit: '&eLohngrenze: &2%money%&e/&2%totalmoney%' + reachedlimit: '&4Du hast zurzeit die Lohngrenze erreicht.' + reachedlimit2: '&eDu kannst das Limit mit &2/jobs limit &eeinsehen.' + notenabled: '&eLohngrenze ist nicht aktiviert.' + admin: + error: Fehlerhafter Befehl. + success: Befehl ausgeführt. + error: + job: Dieser Job existiert nicht! + permission: Du hast dafür keine Berechtigungen! + help: + output: + info: Gib /jobs [Befehl] ? ein für mehr Informationen über einen Befehl. + usage: 'Verwendung: %usage%' + stats: + help: + info: Zeigt die Level deiner Jobs an. + args: '[Spielername]' + error: + nojob: Du hast zurzeit keinen Job. + output: 'Level %joblevel% %jobname% : %jobxp%/%jobmaxxp% XP' + archive: + help: + info: Zeigt alle im Archiv gespeicherten Jobs des Spielers an. + args: '[Spielername]' + error: + nojob: Keine gespeicherten Jobs des Spielers vorhanden. + output: Level %joblevel% %jobname% + give: + help: + info: Vergibt je nach Job Items. Spielername ist optional. + args: '[Spielername] [Jobname] [Item]' + output: + notonline: '&4[%playername%] ist nicht online!' + noitem: '&4Kein so benanntes Item vorhanden!' + info: + help: + title: '&2*** &eJobs&2 ***' + info: Zeigt an, wie ein Job für was bezahlt wird. + args: '[Jobname] [Tätigkeit]' + actions: '&eGültige Tätigkeiten sind: &f%actions%' + max: ' - &eMaximale Level:&f ' + material: '&7%material%' + output: + break: + info: Zerstören + none: '%jobname% bekommt kein Geld für das Zerstören von Blöcken.' + place: + info: Platzieren + none: '%jobname% bekommt kein Geld für das Setzen von Blöcken.' + kill: + info: Töten + none: '%jobname% bekommt kein Geld für das Töten.' + fish: + info: Fischen + none: '%jobname% bekommt kein Geld für das Fischen.' + craft: + info: Craften + none: '%jobname% bekommt kein Geld für das Craften.' + smelt: + info: Schmelzen/Kochen + none: '%jobname% bekommt kein Geld für das Schmelzen.' + brew: + info: Brauen + none: '%jobname% bekommt kein Geld für das Brauen.' + enchant: + info: Verzaubern + none: '%jobname% bekommt kein Geld für das Verzaubern.' + repair: + info: Reparieren + none: '%jobname% bekommt kein Geld für das Reparieren.' + breed: + info: Züchten + none: '%jobname% bekommt kein Geld für das Züchten.' + tame: + info: Zähmen + none: '%jobname% bekommt kein Geld für das Zähmen.' + milk: + info: Melken + none: '%jobname% bekommt kein Geld für das Melken.' + shear: + info: Scheren + none: '%jobname% bekommt kein Geld für das Scheren.' + custom-kill: + info: Spieler töten + none: '%jobname% bekommt kein Geld für das Töten von Spielern.' + playerinfo: + help: + info: Zeigt an, wie der Job eines Spielers für was bezahlt wird. + args: '[Spielername] [Jobname] [Tätigkeit]' + join: + help: + info: Ausgewählten Job erlernen. + args: '[Jobname]' + error: + alreadyin: Du bist bereits %jobname%. + fullslots: Du kannst kein %jobname% werden, keine freie Arbeitsstelle vorhanden. + maxjobs: Du hast das Maximum an Jobs bereits erreicht. + success: Du bist nun %jobname%. + leave: + help: + info: Ausgewählten Job verlernen. + args: '[Jobname]' + success: Du bist nun kein %jobname% mehr. + leaveall: + help: + info: Alle Jobs verlernen. + error: + nojobs: Du bist schon arbeitslos! + success: Du bist nun arbeitslos. + browse: + help: + info: Zeigt alle verfügbaren Jobs an. + error: + nojobs: Es gibt keine Jobs für dich. + output: + header: 'Derzeit sind folgende Jobs verfügbar:' + footer: Für mehr Informationen, gebe /jobs info [Jobname] ein. + fire: + help: + info: Einen Spieler feuern. + args: '[Spielername] [Jobname]' + error: + nojob: Der Spieler ist kein %jobname%. + output: + target: Du wurdest als %jobname% gefeuert. + fireall: + help: + info: Einen Spieler in allen Jobs feuern. + args: '[Spielername]' + error: + nojobs: Der Spieler ist bereits arbeitslos! + output: + target: Du wurdest in allen Jobs gefeuert. + employ: + help: + info: Einen Spieler in einem Job anstellen. + args: '[Spielername] [Jobname]' + error: + alreadyin: Spieler ist bereits %jobname%. + output: + target: Du wurdest als %jobname% eingestellt. + top: + help: + info: Zeigt die Top 10 eines Jobs. + args: '[jobname]' + error: + nojob: Diesen Job gibt es nicht. + output: + topline: '&aTop&e 10 &e%jobname%&a ' + list: '&e%number%&a. &e%playername% &aLevel &e%level% &amit&e %exp% &aXP' + transfer: + help: + info: Einen Job vom alten zu einem neün Job übertragen. + args: '[Spielername] [AlterJob] [NeürJob]' + output: + target: Du wurdest vom %oldjobname% zum %newjobname%. + promote: + help: + info: Einen Spieler um X Level befördern. + args: '[Spiername] [Jobname] [Level]' + output: + target: Du wurdest um %levelsgained% Level als %jobname% befördert. + demote: + help: + info: Einen Spieler um X Level degradieren. + args: '[Spielername] [Jobname] [Level]' + output: + target: Du wurdest um %levelslost% Levels als %jobname% degradiert. + grantxp: + help: + info: Einem Spieler X XP geben. + args: '[Spielername] [Jobname] [Exp]' + output: + target: Du hast %xpgained% XP als %jobname% erhalten. + removexp: + help: + info: Einem Spieler X XP nehmen. + args: '[Spielername] [Jobname] [xp]' + output: + target: Du hast %xplost% XP als %jobname% verloren. + reload: + help: + info: Konfiguration neu laden. + toggle: + help: + info: Schaltet Mitteilungen über Bezahlungen in der action bar ein/aus. + output: + turnedoff: '&4Dieses Feature ist deaktiviert!' + paid: '&aGeldgutschrift: &2[amount]' + 'on': '&aStatus: &aAN' + 'off': '&aStatus: &4AUS' +message: + skillup: + broadcast: '%playername% ist zum %titlename% %jobname% aufgestiegen.' + nobroadcast: Gratulation, du bist zum %titlename% %jobname% aufgestiegen. + levelup: + broadcast: '%playername%, der %jobname%&r, ist nun Level &e%joblevel%&r.' + nobroadcast: Du bist nun %jobname%, Level %joblevel%. + cowtimer: '&eDu musst &6%time% &eSekunden warten um wieder etwas für das Melken zu verdienen!' + blocktimer: '&eDu musst &3[time] &eSekunden warten um wieder etwas für das Abbauen zu verdienen!' + placeblocktimer: '&eDu musst &6[time] &eSekunden warten um wieder etwas für das Setzen zu +verdienen!' + crafting: + fullinventory: Dein Inventar ist voll! +signs: + cantcreate: '&4Du kannst dieses Schild nicht erstellen!' + topline: '&e[Jobs]' + secondline: + join: '&2Beitreten' + leave: '&4Verlassen' + toggle: '&eWechseln' + top: '&eTop10 anzeigen' + browse: '&eJobliste anzeigen' + stats: '&eStatistik anzeigen' + limit: '&eLimit anzeigen' + info: '&eInfo anzeigen' + archive: '&eArchiv anzeigen' +scoreboard: + clear: '&eGib &2/jobs top clear &eein, um die Anzeige auszublenden.' + topline: '&2Die besten &e%jobname%' + lines: '&2%number%. &e%playername%' \ No newline at end of file diff --git a/locale/messages_fr.yml b/locale/messages_fr.yml new file mode 100644 index 00000000..82d3fcec --- /dev/null +++ b/locale/messages_fr.yml @@ -0,0 +1,238 @@ +economy: + error: + nomoney: 'Il n''y a plus d''argent dans la banque nationale !' +command: + boost: + help: + info: Boost les gains d''Exp/Argent pour tous les joueurs + args: '[jobname] [rate]' + output: + allreset: 'Tous les boosts d''Exp/Argent ont t dsactivs.' + jobsboostreset: 'Le boost pour %jobname% a t dsactiv.' + nothingtoreset: 'Il n''y a rien dsactiver.' + boostalladded: 'Boost de %boost% ajout tous les mtiers !' + boostadded: 'Boost de &e%boost% &aajout pour &e%jobname% !' + infostats: '&c-----> &aTaux d''Exp/argent de x%boost% activ&c <-------' + convert: + help: + info: 'Convertit le systme de la base de donnes. Si vous utilisez SQLite, cela sera converti MySQL et vice-versa.' + args: '' + limit: + help: + info: 'Montre les limites des mtiers' + args: '' + output: + lefttime: '&eTemps restant avant la fin de la limite : &2%hour% &eheure(s) &2%min% &emin &2%sec% + &esec' + moneylimit: '&eLimite : &2%money%&e/&2%totalmoney%' + reachedlimit: '&4You have reached money limit in given time!' + reachedlimit2: '&eVous pouvez vrifier votre limite avec &2/jobs limit &ecommand' + notenabled: '&eLa limite n''est pas active.' + admin: + error: Erreur dans la commande. + success: Votre commande a t excute. + error: + job: 'Le mtier que vous avez selectionn n''existe pas !' + permission: 'Vous n''avez pas la permission !' + help: + output: + info: 'Tapez /jobs [cmd] ? pour plus d''information sur une commande.' + usage: 'Utilisation: %usage%' + stats: + help: + info: 'Donne votre niveau dans chacun de vos mtiers.' + args: '[playername]' + error: + nojob: 'Vous n''avez pas de mtier.' + output: 'lvl%joblevel% %jobname% : %jobxp%/%jobmaxxp% xp' + archive: + help: + info: 'Donne tous les mtiers en archive par joueur.' + args: '[playername]' + error: + nojob: 'Il n''y a aucun mtier en archive.' + output: lvl %joblevel% (%getbackjoblevel%) %jobname% + give: + help: + info: 'Donne un objet par nom de mtier et nom de catgorie d''objet. Le pseudo est facultatif.' + args: '[playername] [jobname] [itemname]' + output: + notonline: '&4[%playername%] est hors-ligne !' + noitem: '&4Ce nom ne correspond aucun objet !' + info: + help: + title: '&2*** &eJobs&2 ***' + info: Donne combien est pay chaque mtier et pour quoi. + args: '[jobname] [action]' + actions: '&eLes actions possibles sont: &f%actions%' + max: ' - &eniveau max:&f ' + material: '&7%material%' + output: + break: + info: Casser + none: '%jobname% ne donne rien en cassant des blocs.' + place: + info: Placer + none: '%jobname% ne donne rien en plaant des blocs.' + kill: + info: Tuer + none: '%jobname% ne donne rien en tuant.' + fish: + info: Pcher + none: '%jobname% ne donne rien en pchant.' + craft: + info: Crafter + none: '%jobname% ne donne rien en craftant.' + smelt: + info: Cuire + none: '%jobname% ne donne rien en faisant cuire.' + brew: + info: Infuser + none: '%jobname% ne donne rien en faisant infuser.' + enchant: + info: Enchanter + none: '%jobname% ne donne rien en enchantant.' + repair: + info: Rparer + none: '%jobname% ne donne rien en rparant.' + breed: + info: Nourrir + none: '%jobname% ne donne rien en nourrissant.' + tame: + info: Apprivoiser + none: '%jobname% ne donne rien en apprivoisant.' + custom-kill: + info: Tuer + none: '%jobname% ne donne rien en tuant des joueurs particuliers.' + playerinfo: + help: + info: Donne combien est pay chaque mtier et pour quoi pour un autre joueur. + args: '[playername] [jobname] [action]' + join: + help: + info: Exercer le mtier. + args: '[jobname]' + error: + alreadyin: Vous exercez dj le mtier de %jobname%. + fullslots: 'Vous ne pouvez pas devenir %jobname%, il n''y a plus de place disponible.' + maxjobs: 'Vous exercez dj trop de mtiers.' + success: 'Vous exercez maintenant le mtier de %jobname%.' + leave: + help: + info: Quitter le mtier. + args: '[jobname]' + success: 'Vous n''exercez plus le mtier de %jobname%.' + leaveall: + help: + info: Quitter tous vos mtiers. + error: + nojobs: Vous n'exercez aucun mtier ! + success: Vous avez quitt tous vos mtiers. + browse: + help: + info: Donne les mtiers que vous pourriez exercer. + error: + nojobs: Vous ne pouvez exercer aucun autre mtier. + output: + header: 'Vous pouvez exercer les mtiers suivants :' + footer: Pour plus d'informations, tapez /jobs info [JobName] + fire: + help: + info: Renvoie le joueur de son mtier. + args: '[playername] [jobname]' + error: + nojob: Ce joueur n'exerce pas le mtier de %jobname%. + output: + target: Vous avez t renvoy de %jobname%. + fireall: + help: + info: Renvoie le joueur de tous ses mtiers. + args: '[playername]' + error: + nojobs: Le joueur n'a aucun mtier ! + output: + target: Vous avez t renvoy de tous vos mtiers. + employ: + help: + info: Embauche le joueur dans le mtier. + args: '[playername] [jobname]' + error: + alreadyin: Ce joueur exerce dj le mtier de %jobname%. + output: + target: Vous avez t embauch pour tre %jobname%. + top: + help: + info: Donne le top 10 des joueurs par mtier. + args: '[jobname]' + error: + nojob: Aucun mtier ne porte ce nom. + output: + topline: '&aTop&e 10 &ades joueurs &e%jobname%' + list: '&e%number%&a. &e%playername% &alvl &e%level% &aavec&e %exp% &aexp' + transfer: + help: + info: Transfre un joueur d'un mtier un autre. + args: '[playername] [oldjob] [newjob]' + output: + target: Vous avez t transfr de %oldjobname% %newjobname%. + promote: + help: + info: Promeut le joueur de X niveaux dans un mtier. + args: '[playername] [jobname] [levels]' + output: + target: Vous avez t promu de %levelsgained% niveaux en %jobname%. + demote: + help: + info: Rtrograde le joueur de X niveaux dans un mtier. + args: '[playername] [jobname] [levels]' + output: + target: Vous avez t rtrograd de %levelslost% niveaux en %jobname%. + grantxp: + help: + info: Donne X points d'exprience au joueur dans un mtier. + args: '[playername] [jobname] [xp]' + output: + target: Vous avez gagn %xpgained% points d'exprience en %jobname%. + removexp: + help: + info: Enlve X points d'exprience au joueur dans un mtier. + args: '[playername] [jobname] [xp]' + output: + target: Vous avez perdu %xplost% points d'exprience en %jobname%. + reload: + help: + info: Recharge la configuration. + toggle: + help: + info: Toggles payment output on action bar. + output: + turnedoff: '&4Cette option est dsactive !' + paid: '&aVous avez t pay pour : &2[amount]' + 'on': '&aToggled: &aON' + 'off': '&aToggled: &4OFF' +message: + skillup: + broadcast: '%playername% a t promu %titlename% %jobname%.' + nobroadcast: Flicitations, vous avez t promu %titlename% %jobname%. + levelup: + broadcast: '%playername% est maintenant au niveau %joblevel% %jobname%.' + nobroadcast: Vous tes maintenant au niveau %joblevel% %jobname%. + crafting: + fullinventory: Votre inventaire est plein ! +signs: + cantcreate: '&4Vous ne pouvez pas crer ce panneau !' + topline: '&e[Jobs]' + secondline: + join: '&2Rejoindre' + leave: '&4Quitter' + toggle: '&eToggle' + top: '&eTop' + browse: '&eListe' + stats: '&eStats' + limit: '&eLimite' + info: '&eInfo' + archive: '&eArchive' +scoreboard: + clear: '&eSi vous voulez enlever le scoreboard, tapez &2/jobs top clear' + topline: '&2Top &e%jobname%' + lines: '&2%number%. &e%playername%' \ No newline at end of file diff --git a/locale/messages_lt.yml b/locale/messages_lt.yml new file mode 100644 index 00000000..aec6f1db --- /dev/null +++ b/locale/messages_lt.yml @@ -0,0 +1,203 @@ +economy: + error: + nomoney: Atsiprašome, nacionalinis bankas nebeturi pinigu! +command: + boost: + help: + info: Boosts Exp/money gain for all players + args: '[jobname] [rate]' + output: + allreset: All exp/money boost turned off + jobsboostreset: Boost for %jobname% was turned off + nothingtoreset: Nothing to reset + boostalladded: Boost of %boost% added for all jobs! + boostadded: Boost of &e%boost% &aadded for &e%jobname%! + infostats: '&c-----> &aExp/money rate x%boost% enabled&c <-------' + limit: + help: + info: Shows payment limits for jobs + args: '' + output: + lefttime: '&eLikes laikas iki nusiresetinimo: &2%hour% &evalandos &2%min% &emin &2%sec% + &esek' + moneylimit: '&ePinigu limitas: &2%money%&e/&2%totalmoney%' + reachedlimit: '&4You have reached money limit in given time!' + reachedlimit2: '&eYou can check your limit with &2/jobs limit &ecommand' + notenabled: '&eMoney limit is not enabled' + admin: + error: There was an error in the command. + success: Your command has been performed. + error: + job: The job you have selected does not exist! + permission: You do not have permission to do that! + help: + output: + info: Rasyk &2/jobs [cmd] ? &edel detalesnes informacijos. + usage: 'Naudojimas: %usage%' + stats: + help: + info: Parodyti visu i kuriuos esate isidarbine darbu informacija. + args: '[playername]' + error: + nojob: Prasome isidarbinti visu pirma. + output: 'lvl%joblevel% %jobname% : %jobxp%/%jobmaxxp% xp' + archive: + help: + info: Shows all jobs saved in archive by user. + args: '[playername]' + error: + nojob: There is no jobs saved. + output: lvl %joblevel% (%getbackjoblevel%) %jobname% + info: + help: + title: '&2*** &eDarbas&2 ***' + info: Parodo kiek gali uzdirbti is kiekvieno darbo uz tamtikra veikla. + args: '[jobname] [action]' + output: + break: + info: Sudauzyti + none: '%jobname% does not get money for breaking blocks.' + place: + info: Padeti + none: '%jobname% does not get money for placing blocks.' + kill: + info: Uzmusti + none: '%jobname% does not get money for killing monsters.' + fish: + info: Suzvejoti + none: '%jobname% does not get money from fishing.' + craft: + info: Pagaminti + none: '%jobname% does not get money from crafting.' + smelt: + info: Islidyti + none: '%jobname% does not get money from smelting.' + brew: + info: Isvirti + none: '%jobname% does not get money from brewing.' + enchant: + info: Patobulinti + none: '%jobname% does not get money from enchanting.' + repair: + info: Sutaisyti + none: '%jobname% does not get money from repairing.' + breed: + info: Veisti + none: '%jobname% does not get money from breeding.' + tame: + info: Prijaukinti + none: '%jobname% does not get money from taming.' + playerinfo: + help: + info: Parodo kiek kitas zaidejas uzdirba is tam tikru darbu. + args: '[playername] [jobname] [action]' + join: + help: + info: Isidarbinti i pasirinkta darba. + args: '[jobname]' + error: + alreadyin: Jus jau esate isidarbines i %jobname%. + fullslots: Tu negali isidarbinti %jobname%, turi maksimalu darbu skaiciu. + maxjobs: Tu jau istojai i maksimaliai leistinus darbus. + success: Tu istojai i %jobname%. + leave: + help: + info: Iseiti is pasirinkto darbo. + args: '[jobname]' + success: Tu isejai is %jobname%. + leaveall: + help: + info: Iseiti is visu darbu. + error: + nojobs: Tu negali iseiti is darbo kol nesi isidarbines! + success: Tu isejai is visu darbu. + browse: + help: + info: Darbu sarasas i kuriuos gali istoti. + error: + nojobs: Nera darbu + output: + header: 'Tu gali isidarbinti i situos darbus:' + footer: Del daugiau informacijos rasyk /jobs info [JobName] + fire: + help: + info: Fire the player from the job. + args: '[playername] [jobname]' + error: + nojob: Player does not have the job %jobname%. + output: + target: Tu buvai atleistas is %jobname%. + fireall: + help: + info: Fire player from all their jobs. + args: '[playername]' + error: + nojobs: Player does not have any jobs to be fired from! + output: + target: Tu buvai atleistas is visu darbu. + employ: + help: + info: Employ the player to the job. + args: '[playername] [jobname]' + error: + alreadyin: Player is already in the job %jobname%. + output: + target: Tu buvai idarbintas i %jobname%. + top: + help: + info: Parodo top 10 zaidejus pagal darbo pavadinima. + args: '[jobname]' + error: + nojob: Nebuvo rastas joks darbas su tokiu pavadinimu. + output: + topline: '&aTop&e 10 &azaidejai pagal &e%jobname% &adarba' + list: '&e%number%&a. &e%playername% &alvl &e%level% &awith&e %exp% &aexp' + transfer: + help: + info: Transfer a player's job from an old job to a new job. + args: '[playername] [oldjob] [newjob]' + output: + target: Tu buvai perkeltas is %oldjobname% i %newjobname%. + promote: + help: + info: Promote the player X levels in a job. + args: '[playername] [jobname] [levels]' + output: + target: Tu gavai %levelsgained% lygiu %jobname% darbe. + demote: + help: + info: Demote the player X levels in a job. + args: '[playername] [jobname] [levels]' + output: + target: You have been demoted %levelslost% levels in %jobname%. + grantxp: + help: + info: Grant the player X experience in a job. + args: '[playername] [jobname] [xp]' + output: + target: You have been granted %xpgained% experience in %jobname%. + removexp: + help: + info: Remove X experience from the player in a job. + args: '[playername] [jobname] [xp]' + output: + target: You have lost %xplost% experience in %jobname%. + reload: + help: + info: Reload configurations. + toggle: + help: + info: Perjungia mokejimu rodima veiksmu lenteleje. + output: + paid: '&aTau buvo sumoketa: &2[amount]' + 'on': '&aIjungta: &aTaip' + 'off': '&aIjungta: &4Ne' +message: + skillup: + broadcast: '%playername% has been promoted to a %titlename% %jobname%.' + nobroadcast: Sveikiname, buvote paaukstintas iki %titlename% %jobname%. + levelup: + broadcast: '%playername% is now a level %joblevel% %jobname%.' + nobroadcast: Tu pasiekiai %joblevel% lygi %jobname% darbe. + crafting: + fullinventory: Your inventory is full! diff --git a/locale/messages_ru.yml b/locale/messages_ru.yml new file mode 100644 index 00000000..f7b4e681 --- /dev/null +++ b/locale/messages_ru.yml @@ -0,0 +1,252 @@ +economy: + error: + nomoney: Простите, не осталось денег в банке! +command: + boost: + help: + info: Ускоряет получение Опыта/Денег для всех игроков + args: '[jobname] [rate]' + output: + allreset: Все ускорения выключены + jobsboostreset: Ускорение для %jobname% выключено + nothingtoreset: Нечего сбрасывать + boostalladded: Ускорение в %boost% добавлено для всех работ! + boostadded: Ускорение в &e%boost% &aдобавлено для &e%jobname%! + infostats: '&c-----> &aУскорение в x%boost% включено&c <-------' + convert: + help: + info: Converts data base system from one system to another. if you currently running sqlite, this will convert to Mysql and vise versa. + args: '' + limit: + help: + info: Показывает лимит оплаты для работы + args: '' + output: + lefttime: '&eОсталось времени до сброса лимита: &2%hour% &ehour &2%min% &emin &2%sec% + &esec' + moneylimit: '&eЛимит денег: &2%money%&e/&2%totalmoney%' + leftexptime: '&eОсталось времени до сброса XP лимита: &2%hour% &ehour &2%min% &emin + &2%sec% &esec' + explimit: '&eЛимит опыта: &2%exp%&e/&2%totalexp%' + reachedlimit: '&4Вы достигли получаемый предел денег!' + reachedlimit2: '&eПроверить лимит командой &2/jobs limit' + reachedExplimit: '&4Вы достигли получаемый предел опыта!' + reachedExplimit2: '&eПроверить лимит командой &2/jobs limit' + notenabled: '&eЛимит денег не включён' + admin: + error: Ошибка в команде. + success: Команда выполнена. + error: + job: Данной работы не существует! + permission: Не прав на выполнение этой команды! + help: + output: + info: Используйте /jobs [cmd] ? Для более точной информации. + usage: 'Использование: %usage%' + stats: + help: + info: Показывет Ваш уровень работы. + args: '[playername]' + error: + nojob: Сначало устройтесь на работы. + output: 'Уровень%joblevel% %jobname% : %jobxp%/%jobmaxxp% опыта' + archive: + help: + info: Показывает все работы, сохраненные в архиве пользователем. + args: '[playername]' + error: + nojob: Нет сохранёный работ. + output: Уровень %joblevel% (%getbackjoblevel%) %jobname% + give: + help: + info: Gives item by jobs name and item category name. Player name is optional + args: '[playername] [jobname] [itemname]' + output: + notonline: '&Игрок [%playername%] не на сервере!' + noitem: '&4Нет предмета с таким именем!' + info: + help: + title: '&2*** &eJobs&2 ***' + info: Показывает, насколько каждая работа выгодна и что надо делать. + args: '[jobname] [action]' + actions: '&eДопустимые действия: &f%actions%' + max: ' - &eмаксимальный уровень:&f ' + material: '&7%material%' + output: + break: + info: Ломать + none: '%jobname% не получает денег за ломание блоков.' + place: + info: Ставить + none: '%jobname% не получает денег за placing blocks.' + kill: + info: Убивать + none: '%jobname% не получает денег за killing monsters.' + fish: + info: Ловить + none: '%jobname% не получает денег за рыбалку.' + craft: + info: Крафтить + none: '%jobname% не получает денег за крафт.' + smelt: + info: Плавить + none: '%jobname% не получает денег за пережаривание.' + brew: + info: Варить + none: '%jobname% не получает денег за зельеварение.' + enchant: + info: Чаровать + none: '%jobname% не получает денег за зачарование.' + repair: + info: Ченить + none: '%jobname% не получает денег за починку.' + breed: + info: Размножать + none: '%jobname% не получает денег за размножение.' + tame: + info: Приручать + none: '%jobname% не получает денег за приручание.' + milk: + info: Доить + none: '%jobname% не получает денег за доение.' + shear: + info: Стричь + none: '%jobname% не получаеть денег за стрижку овец.' + custom-kill: + info: Custom kill + none: '%jobname% не получает денег за убийство игрока.' + playerinfo: + help: + info: Показать, насколько каждая работа выгодная и за что. + args: '[playername] [jobname] [action]' + join: + help: + info: Присоеденится к этой работе. + args: '[jobname]' + error: + alreadyin: Ты уже устроен на работу %jobname%. + fullslots: Не возможно устроиться на %jobname%, нет свободных мест. + maxjobs: Слишком много работ. + success: Вы устроились на %jobname%. + leave: + help: + info: Уволиться с работы. + args: '[jobname]' + success: Вы уволились с %jobname%. + leaveall: + help: + info: Уволиться со всех работ. + error: + nojobs: Нет работ с которых можно уволится! + success: Вы уволились со всех работ. + browse: + help: + info: Доступные работы. + error: + nojobs: Нет доступных работ. + output: + header: 'Доступные работы:' + footer: Для информации введите /jobs info [JobName] + fire: + help: + info: Уволить игрока с работы. + args: '[playername] [jobname]' + error: + nojob: Игрок не устроен на эту работу %jobname%. + output: + target: Вы были уволены из %jobname%. + fireall: + help: + info: Уволить игрока со всех работ. + args: '[playername]' + error: + nojobs: У игрока нет работ! + output: + target: Вы были уволены со всех работ. + employ: + help: + info: Принять игрока на работу. + args: '[playername] [jobname]' + error: + alreadyin: Игрок уже устроен на %jobname%. + output: + target: Вы были устроены на %jobname%. + top: + help: + info: Показывает топ игроков. + args: '[jobname]' + error: + nojob: Нет такой работы. + output: + topline: '&aТоп&e 10 &aигроков' + list: '&e%number%&a. &e%playername% &aУровень &e%level% &aс&e %exp% &aопыта' + transfer: + help: + info: Перевести игрока со старой работы на новую. + args: '[playername] [oldjob] [newjob]' + output: + target: Вы были переведены из %oldjobname% на %newjobname%. + promote: + help: + info: Продвинуть игрока на X уровней. + args: '[playername] [jobname] [levels]' + output: + target: Вы были продвинуты на %levelsgained% уровней в %jobname%. + demote: + help: + info: Понизить игрока на X уровней. + args: '[playername] [jobname] [levels]' + output: + target: Вы были понижены на %levelslost% уровней в %jobname%. + grantxp: + help: + info: Дать игроку опыта в работе. + args: '[playername] [jobname] [xp]' + output: + target: Вам дали %xpgained% опыта в %jobname%. + removexp: + help: + info: Убрать опыт работы у игрока. + args: '[playername] [jobname] [xp]' + output: + target: Вы потеряли %xplost% опыта в %jobname%. + reload: + help: + info: Reload configurations. + toggle: + help: + info: Включить вывод платижей в ActionBar. + output: + turnedoff: '&4Данная функция выключена!' + paid: '&aВы заплатили за: &2[amount]' + 'on': '&aВключено: &aON' + 'off': '&aВыключено: &4OFF' +message: + skillup: + broadcast: '%playername% повысился в %titlename% %jobname%.' + nobroadcast: Поздравляем, вы были повышены в %titlename% %jobname%. + levelup: + broadcast: '%playername% имеет повышение уровеня в %joblevel% %jobname%.' + nobroadcast: Вы имеете повышеный уровень в %joblevel% %jobname%. + cowtimer: '&eВы должны подождать &6%time% &eсекунд что бы получить денег за эту работу.' + blocktimer: '&eВы должны подождать: &3[time] &eсек ещё чтобы получить деньги!' + placeblocktimer: '&eВы не можете ставить блоки быстрее чем &6[time] &eсекунд в одном месте' + crafting: + fullinventory: Инвентарь полный! +signs: + cantcreate: '&4Вы не можете создать табличку!' + topline: '&e[Jobs]' + secondline: + join: '&2Join' + leave: '&4Leave' + toggle: '&eToggle' + top: '&eTop' + browse: '&eBrowse' + stats: '&eStats' + limit: '&eLimit' + info: '&eInfo' + archive: '&eArchive' +scoreboard: + clear: '&eIf you want to remove scoreboard, type &2/jobs top clear' + topline: '&2Top &e%jobname%' + lines: '&2%number%. &e%playername%' diff --git a/plugin.yml b/plugin.yml new file mode 100644 index 00000000..d34b303e --- /dev/null +++ b/plugin.yml @@ -0,0 +1,141 @@ +name: Jobs +description: Jobs Plugin for the BukkitAPI +main: com.gamingmesh.jobs.JobsPlugin +version: 2.47.0 +author: phrstbrn +softdepend: [Vault] +commands: + jobs: + description: Jobs + usage: /jobs +permissions: + jobs.*: + description: Grants access to all Jobs commands + children: + jobs.admin: true + jobs.admin: + description: Grants permissions as an admin + default: false + children: + jobs.use: true + jobs.command.*: true + jobs.use: + description: Grants ability to use this plugin + default: true + jobs.command.*: + description: Grants player access to all commands + default: false + children: + jobs.command.browse: true + jobs.command.stats: true + jobs.command.admin.stats: true + jobs.command.admin.archive: true + jobs.command.archive: true + jobs.command.join: true + jobs.command.leave: true + jobs.command.leaveall: true + jobs.command.info: true + jobs.command.playerinfo: true + jobs.command.fire: true + jobs.command.fireall: true + jobs.command.employ: true + jobs.command.promote: true + jobs.command.demote: true + jobs.command.grantxp: true + jobs.command.removexp: true + jobs.command.transfer: true + jobs.command.reload: true + jobs.command.help: true + jobs.command.top: true + jobs.command.gtop: true + jobs.command.toggle: true + jobs.command.limit: true + jobs.command.give: true + jobs.command.signs: true + jobs.command.signupdate: true + jobs.command.moneyboost: true + jobs.command.expboost: true + jobs.command.browse: + description: Grants access to the browse command + default: true + jobs.command.top: + description: Grants access to the top command + default: true + jobs.command.gtop: + description: Grants access to the gtop command + default: true + jobs.command.stats: + description: Grants access to the stats command + default: true + jobs.command.archive: + description: Grants access to the archive command + default: true + jobs.command.admin.archive: + description: Grants access to the archive command on other players + default: true + jobs.command.admin.stats: + description: Grants access to the stats command on other players + default: true + jobs.command.join: + description: Grants access to the join command + default: true + jobs.command.leave: + description: Grants access to the leave command + default: true + jobs.command.leaveall: + description: Grants access to the leaveall command + default: true + jobs.command.info: + description: Grants access to the info command + default: true + jobs.command.playerinfo: + description: Grants access to the playerinfo command + default: op + jobs.command.fire: + description: Grants access to the fire command + default: op + jobs.command.fireall: + description: Grants access to the fireall command + default: op + jobs.command.employ: + description: Grants access to the employ command + default: op + jobs.command.promote: + description: Grants access to the promote command + default: op + jobs.command.demote: + description: Grants access to the demote command + default: op + jobs.command.grantxp: + description: Grants access to the grantxp command + default: op + jobs.command.removexp: + description: Grants access to the removexp command + default: op + jobs.command.transfer: + description: Grants access to the transfer command + default: op + jobs.command.reload: + description: Grants access to the reload command + default: op + jobs.command.signupdate: + description: Grants access to the reload command + default: op + jobs.command.give: + description: Grants access to the give command + default: op + jobs.command.expboost: + description: Grants access to the expboost command + default: op + jobs.command.moneyboost: + description: Grants access to the moneyboost command + default: op + jobs.command.help: + description: Grants access to the help command + default: true + jobs.command.toggle: + description: Grants access to the toggle command + default: true + jobs.command.limit: + description: Grants access to the limit command + default: true \ No newline at end of file diff --git a/schedule.yml b/schedule.yml new file mode 100644 index 00000000..1a80541a --- /dev/null +++ b/schedule.yml @@ -0,0 +1,55 @@ +# Enabled - with this false this schedule will be ignored +# From and Until is in 24 hours format with : signs to separate minutes and seconds +# Exp and Money determines how big is boost, to reset it. keep it at 1.0. so if you use 2.0 that means all money/exp is doubled +# Days variables: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday, All +# Jobs can be any of your settup job or use All to give for all jobs at once +# BroadcastOnStart or BroadcastOnStop - set it false to disable message when boost starts/stops +# MessageOnStart or MessageOnStop - optional messages, if not given, then message from locale file will be shown + +Boost: + NightBoost: + Enabled: false + From: '23:00:00' + Until: '07:00:00' + Exp: 2.0 + Money: 2.0 + Days: + - All + Jobs: + - All + BroadcastOnStart: true + MessageOnStart: + - '&e***********************************************' + - '&e* All jobs got 2x rate for exp and money!' + - '&e* For limited time only!' + - '&e***********************************************' + BroadcastOnStop: true + MessageOnStop: + - '&e***********************************************' + - '&e* Boost time for jobs have beed stoped' + - '&e* All rates reseted to original ones' + - '&e***********************************************' + ShortMoneyBoost: + Enabled: false + From: '07:00:00' + Until: '08:00:00' + Exp: 1.0 + Money: 2.0 + Days: + - Sunday + - Saturday + Jobs: + - Miner + - Woodcutter + BroadcastOnStart: true + MessageOnStart: + - '&e***********************************************' + - '&e* Miner and Woodcutter got 2x rate for money!' + - '&e* Until 8AM!' + - '&e***********************************************' + BroadcastOnStop: true + MessageOnStop: + - '&e***********************************************' + - '&e* Boost time for Miner and Woodcutter have beed stoped' + - '&e* Money rates reseted to original ones' + - '&e***********************************************' \ No newline at end of file