SHARE
TWEET

Untitled

a guest May 25th, 2019 95 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package net.minelounge.economy;
  2.  
  3. import net.milkbowl.vault.economy.Economy;
  4. import org.bukkit.Bukkit;
  5. import org.bukkit.ChatColor;
  6. import org.bukkit.Location;
  7. import org.bukkit.Material;
  8. import org.bukkit.block.Block;
  9. import org.bukkit.block.Sign;
  10. import org.bukkit.command.Command;
  11. import org.bukkit.command.CommandExecutor;
  12. import org.bukkit.command.CommandSender;
  13. import org.bukkit.configuration.ConfigurationSection;
  14. import org.bukkit.configuration.file.FileConfiguration;
  15. import org.bukkit.configuration.file.YamlConfiguration;
  16. import org.bukkit.entity.EntityType;
  17. import org.bukkit.event.EventHandler;
  18. import org.bukkit.event.Listener;
  19. import org.bukkit.event.entity.EntityDeathEvent;
  20. import org.bukkit.event.entity.EntityDropItemEvent;
  21. import org.bukkit.inventory.ItemStack;
  22. import org.bukkit.plugin.RegisteredServiceProvider;
  23. import org.bukkit.plugin.java.JavaPlugin;
  24. import org.bukkit.scheduler.BukkitRunnable;
  25.  
  26. import java.io.*;
  27. import java.util.*;
  28.  
  29. public class GoldEconomyPlugin extends JavaPlugin {
  30.  
  31.     private HashMap<Material,Set<Location>> trackedSigns = new HashMap<Material,Set<Location>>();
  32.     private HashMap<Material, Integer> startingPrices = new HashMap<Material,Integer>();
  33.     private HashMap<Material, Integer> itemStock = new HashMap<Material, Integer>();
  34.  
  35.     //private Set<StockEvent> stockEvents;
  36.  
  37.     private FileConfiguration signConfig;
  38.     private FileConfiguration stocksConfig;
  39.     private File signsFile;
  40.     private File stocksFile;
  41.     private double goldPrice = 1000;
  42.     private final int defaultGoldStock = 8000;
  43.     private final long appreciationInterval = 24 * 60 * 60; //seconds
  44.     private final long stockEventTimeLength = 1000L * 60L * 60L * 24L * 30L * 3L; // every 90 days
  45.     private final int validationThreshold = 100; // If prices move more than this, something went wrong, so reset stock values
  46.     private final double sellModifier = 0.4;
  47.     private MarketFormula marketFormula;
  48.  
  49.  
  50.     private final boolean updateStocksEverySign = true;
  51.     private Economy economy;
  52.     private Random random;
  53.     private final double goldChance = 0.1;
  54.  
  55.     public void onEnable(){
  56.         marketFormula = new SimpleMarketFormula();
  57.         economy = setupEconomy();
  58.         random = new Random();
  59.  
  60.         getCommand("resetstocks").setExecutor(new CommandExecutor() {
  61.             @Override
  62.             public boolean onCommand(CommandSender sender, Command command, String s, String[] strings) {
  63.                 if (!sender.hasPermission("goldeconomy.op")){
  64.                     return false;
  65.                 }
  66.  
  67.                 itemStock.clear();
  68.                 if (stocksFile != null){
  69.                     try{
  70.                         stocksFile.delete();
  71.                         stocksFile.createNewFile();
  72.                     }catch(Exception e){
  73.                         e.printStackTrace();
  74.                     }
  75.                 }
  76.  
  77.                 sender.sendMessage(ChatColor.GREEN + "Reset all stocks!");
  78.                 return true;
  79.             }
  80.         });
  81.         getConfig().addDefault("gold-price", 1000);
  82.         getConfig().addDefault("gold-item", Material.GOLD_INGOT.name());
  83.         getConfig().addDefault("last-appreciation", 0L);
  84.         saveConfig();
  85.  
  86.         goldPrice = getConfig().getInt("gold-price");
  87.         if (getConfig().getLong("last-appreciation") < (System.currentTimeMillis() - (appreciationInterval * 1000))){
  88.             goldPrice = marketFormula.appreciateGold(goldPrice);
  89.             getConfig().set("gold-price", goldPrice);
  90.             getConfig().set("last-appreciation", System.currentTimeMillis());
  91.             saveConfig();
  92.         }
  93.  
  94.         trackedSigns = new HashMap<Material, Set<Location>>();
  95.         signsFile = new File(getDataFolder(), "signs.yml");
  96.         signConfig = new YamlConfiguration();
  97.         try{
  98.             if (!signsFile.exists()){
  99.                 signsFile.createNewFile();
  100.             }
  101.             signConfig.load(signsFile);
  102.         }catch(Exception e){
  103.             e.printStackTrace();
  104.             getServer().getPluginManager().disablePlugin(this);
  105.         }
  106.  
  107.         for (String key : signConfig.getKeys(false)){
  108.             String name = signConfig.getString(key+".name");
  109.             String mat = signConfig.getString(key+".material");
  110.             Material material = Material.valueOf(mat);
  111.             int startingPrice = signConfig.getInt(key+".starting_price");
  112.             double x = signConfig.getDouble(key+".x");
  113.             double y = signConfig.getDouble(key+".y");
  114.             double z = signConfig.getDouble(key+".z");
  115.             String world = signConfig.getString(key+".world");
  116.  
  117.             Location l = new Location(Bukkit.getWorld(world), x, y, z);
  118.             if (!trackedSigns.containsKey(material)) trackedSigns.put(material, new HashSet<Location>());
  119.             trackedSigns.get(material).add(l);
  120.             if (startingPrices.containsValue(material)){
  121.                 if (startingPrices.get(material) != startingPrice){
  122.                     Bukkit.getLogger().warning("Conflicting starting prices for "+mat + " found!");
  123.                 }
  124.             }
  125.             startingPrices.put(material, startingPrice);
  126.         }
  127.         //stockEvents = new HashSet<StockEvent>();
  128.         /*stocksFile = new File(getDataFolder(), "stock-events.txt");
  129.         try{
  130.             if (!stocksFile.exists()){
  131.                 stocksFile.createNewFile();
  132.             }
  133.  
  134.             BufferedReader read = new BufferedReader(new FileReader(stocksFile));
  135.             String line = read.readLine();
  136.             // LINE: Material_name stock
  137.             while (line != null){
  138.                 //parse line
  139.                 String[] parts = line.split(" ");
  140.                 Material m  = Material.valueOf(parts[0]);
  141.                 if (m == null) {
  142.                     Bukkit.getLogger().warning("Could not read material "+parts[0]);
  143.                     line = read.readLine();
  144.                     continue;
  145.                 }
  146.                 int amount = Integer.valueOf(parts[1]);
  147.                 long time = Long.valueOf(parts[2]);
  148.                 if (System.currentTimeMillis() - time > stockEventTimeLength){
  149.                     line = read.readLine();
  150.                     continue;
  151.                 }
  152.  
  153.                 int curr = Integer.valueOf(parts[3]);
  154.                 StockEvent event = new StockEvent(m, amount, time, curr);
  155.                 if (amount > 0) addStock(m, amount);
  156.                 else if (amount < 0) removeStock(m, -amount);
  157.  
  158.                 stockEvents.add(event);
  159.                 //don't really need to handle if amount = 0
  160.  
  161.                 line = read.readLine();
  162.             }
  163.             read.close();
  164.         }catch(Exception e){
  165.             e.printStackTrace();
  166.         }*/
  167.         //TODO get stocks from file
  168.         stocksFile = new File(getDataFolder(), "stocks.yml");
  169.         try{
  170.             if (!stocksFile.exists()){
  171.                 stocksFile.createNewFile();
  172.             }
  173.             stocksConfig = new YamlConfiguration();
  174.             stocksConfig.load(stocksFile);
  175.  
  176.             for (String key : stocksConfig.getKeys(false)){
  177.                 itemStock.put(Material.getMaterial(key), stocksConfig.getInt(key));
  178.             }
  179.         }catch(Exception e){
  180.             e.printStackTrace();
  181.         }
  182.         if (!itemStock.containsKey(Material.GOLD_INGOT)){
  183.             itemStock.put(Material.GOLD_INGOT, defaultGoldStock);
  184.         }
  185.  
  186.         getServer().getPluginManager().registerEvents(new GoldSignListener(this, economy), this);
  187.         getServer().getPluginManager().registerEvents(new Listener() {
  188.             @EventHandler
  189.             public void drop(EntityDeathEvent event){
  190.                 if (event.getEntityType() == EntityType.PIG_ZOMBIE){
  191.                     for (ItemStack is : event.getDrops().toArray(new ItemStack[0])){
  192.                         if (is.getType() == Material.GOLD_NUGGET || is.getType() == Material.GOLD_INGOT){
  193.                             if (random.nextDouble() > goldChance){
  194.                                 event.getDrops().remove(is);
  195.                             }
  196.                         }
  197.                     }
  198.                 }
  199.             }
  200.         }, this);
  201.         new BukkitRunnable(){
  202.             public void run(){
  203.                 if (trackedSigns.size() == 0) return;
  204.                 List<Material> keys = new ArrayList<Material>(trackedSigns.keySet());
  205.  
  206.                 Material m = keys.get(random.nextInt(keys.size()));
  207.  
  208.                 updateSigns(m);
  209.             }
  210.         }.runTaskTimer(this, 100L, 100L);
  211.  
  212.     }
  213.  
  214.     public void onDisable(){
  215.         //save tracked signs
  216.         FileConfiguration y = new YamlConfiguration();
  217.         for (Set<Location> set : trackedSigns.values()){
  218.             for (Location l : set){
  219.                 if (l == null) continue;
  220.                 Block b = l.getBlock();
  221.                 if (b.getType() != Material.OAK_SIGN  && b.getType() != Material.OAK_WALL_SIGN) continue;
  222.                 Sign s = (Sign)b.getState();
  223.                 Material m = Material.matchMaterial(s.getLine(2));
  224.                 if (m == null) continue;
  225.                 ConfigurationSection section = y.createSection(String.valueOf(l.hashCode()));
  226.                 section.set("name", m.name());
  227.                 section.set("material", m.name());
  228.                 section.set("starting_price", startingPrices.get(m));
  229.                 section.set("x", l.getX());
  230.                 section.set("y", l.getY());
  231.                 section.set("z", l.getZ());
  232.                 section.set("world", l.getWorld().getName());
  233.             }
  234.         }
  235.         try{
  236.             y.save(signsFile);
  237.         }catch(Exception e){
  238.             Bukkit.getLogger().warning("Could not save market signs!");
  239.             e.printStackTrace();
  240.         }
  241.  
  242.         if (stocksConfig == null){
  243.             stocksConfig = new YamlConfiguration();
  244.         }
  245.         for (Map.Entry<Material, Integer> stock : itemStock.entrySet()){
  246.             stocksConfig.set(stock.getKey().toString(), stock.getValue());
  247.         }
  248.         try{
  249.             stocksConfig.save(stocksFile);
  250.         }catch(Exception e){
  251.             e.printStackTrace();
  252.         }
  253.         /*stocksFile.delete();
  254.         try{
  255.             stocksFile.createNewFile();
  256.             PrintWriter writer = new PrintWriter(new FileWriter(stocksFile));
  257.             for (StockEvent event : stockEvents){
  258.                 writer.println(event.getMaterial().toString() + " "+event.getAmount() + " "+event.getTimestamp() + " "+event.getCurrStock());
  259.             }
  260.             writer.close();
  261.  
  262.         }catch(Exception e){
  263.             e.printStackTrace();
  264.         }
  265.  
  266.  
  267. */
  268.     }
  269.     public void trackSign(Location location, Material material, int price, int amount, boolean isBuy){
  270.         if (!trackedSigns.containsKey(material)) {
  271.             trackedSigns.put(material, new HashSet<Location>());
  272.         }
  273.  
  274.         trackedSigns.get(material).add(location);
  275.         if (!hasStock(material) || updateStocksEverySign || !Craftable.isCraftable(material)){
  276.             hardSetStockByPrice(material, price, amount, !isBuy);
  277.         }
  278.     }
  279.  
  280.     public void hardSetStockByPrice(Material material, int price, int amount, boolean sell){
  281.         int stock = 1;
  282.         if (sell){
  283.             stock = (int) Math.floor(goldPrice * getGoldStock() * amount/ (price / sellModifier)) ;
  284.             startingPrices.put(material, (int) ((price / amount) / sellModifier));
  285.         }
  286.         else{
  287.             stock = (int) Math.floor(goldPrice * getGoldStock() * amount / price) ;
  288.             startingPrices.put(material, (price / amount));
  289.         }
  290.         setStock(material, stock);
  291.         //writeStockEvent(material, stock - getStock(material), getStock(material));
  292.     }
  293.  
  294.     public void softTrackSign(Location location, Material material){
  295.         if (!trackedSigns.containsKey(material)) {
  296.             trackedSigns.put(material, new HashSet<Location>());
  297.         }
  298.         trackedSigns.get(material).add(location);
  299.     }
  300.     public boolean isTracked(Location location, Material material){
  301.         if (!trackedSigns.containsKey(material)) return false;
  302.         return trackedSigns.get(material).contains(location);
  303.     }
  304.  
  305.     public void untrackSign(Location location, Material material){
  306.         if (trackedSigns.containsKey(material)){
  307.             trackedSigns.get(material).remove(location);
  308.         }
  309.         if (trackedSigns.get(material).isEmpty()) {
  310.             trackedSigns.remove(material);
  311.             startingPrices.remove(material);
  312.             if(hasStock(material)) {
  313.                itemStock.remove(material);
  314.             }
  315.             /*for (StockEvent event : new HashSet<StockEvent>(stockEvents)){
  316.                 if (event.getMaterial() == material){
  317.                     stockEvents.remove(event);
  318.                 }
  319.             }*/
  320.         }
  321.     }
  322.  
  323.     public int getPrice(Material item, int amount){
  324.         if (Craftable.isCraftable(item)) return getCraftablePrice(amount, item);
  325.         return getStock(item) * amount;
  326.     }
  327.  
  328.     public int getCraftablePrice(int amount, Material material){
  329.         int out = 0;
  330.         Craftable recipe = Craftable.getCraftable(material);
  331.         for (ItemStack i : recipe.getConstituents()){
  332.             out += getPrice(i.getType(), i.getAmount());
  333.         }
  334.         return out * amount / recipe.getAmountOut();
  335.     }
  336.  
  337.     public int getGoldStock(){
  338.         return getStock(Material.GOLD_INGOT);
  339.     }
  340.     private Economy setupEconomy() {
  341.         if (getServer().getPluginManager().getPlugin("Vault") == null) {
  342.             return null;
  343.         }
  344.         RegisteredServiceProvider<Economy> rsp = getServer().getServicesManager().getRegistration(Economy.class);
  345.         if (rsp == null) {
  346.             return null;
  347.         }
  348.         return rsp.getProvider();
  349.     }
  350.  
  351.     /*public void makeImbalance(Material material, int amount){
  352.         if (!itemImbalances.containsKey(material)){
  353.             itemImbalances.put(material, amount);
  354.         }
  355.         else{
  356.             itemImbalances.put(material, itemImbalances.get(material) + amount);
  357.         }
  358.     }
  359.  
  360.     public int getImbalance(Material material){
  361.         if (!itemImbalances.containsKey(material)) return 1;
  362.         return itemImbalances.get(material);
  363.     }*/
  364.  
  365.     public int getStock(Material material){
  366.         if (material == Material.GOLD_INGOT){
  367.             if (itemStock.containsKey(material)){
  368.                 if (itemStock.get(material) < defaultGoldStock) {
  369.                     itemStock.put(Material.GOLD_INGOT, defaultGoldStock);
  370.                     return defaultGoldStock;
  371.                 }
  372.             }
  373.             else{
  374.                 itemStock.put(Material.GOLD_INGOT, defaultGoldStock);
  375.                 return defaultGoldStock;
  376.             }
  377.         }
  378.         if (itemStock.containsKey(material)) return itemStock.get(material);
  379.         return -1;
  380.     }
  381.  
  382.     public void addStock(Material material, int amount){
  383.         if (!itemStock.containsKey(material)) itemStock.put(material, amount);
  384.         else itemStock.put(material, itemStock.get(material) + amount); //sets amount to whatever is on the sell sign if the first sign created is a sell sign.
  385.     }
  386.  
  387.     public void removeStock(Material material, int amount){
  388.         if (!itemStock.containsKey(material)) return;
  389.         itemStock.put(material, Math.max(1, itemStock.get(material) - amount));
  390.     }
  391.  
  392.     public void setStock(Material material, int amount){
  393.         itemStock.put(material, amount);
  394.     }
  395.  
  396.     public boolean hasStock(Material material){
  397.         return itemStock.containsKey(material);
  398.     }
  399.  
  400.     public void updateSigns(Material material){
  401.         if (!trackedSigns.containsKey(material)) return;
  402.  
  403.         for (Location l : trackedSigns.get(material)){
  404.             Material sType = l.getBlock().getType();
  405.             if (sType != Material.OAK_SIGN && sType != Material.OAK_WALL_SIGN) return;
  406.             Sign sign = (Sign)l.getBlock().getState();
  407.  
  408.             int amount = Integer.valueOf(sign.getLine(1));
  409.             int price;
  410.  
  411.             if (!itemStock.containsKey(material) && !Craftable.isCraftable(material)){
  412.                 int oldPrice = Integer.valueOf(sign.getLine(3).substring(1));
  413.                 hardSetStockByPrice(material, oldPrice, amount, sign.getLine(0).contains("Sell"));
  414.             }
  415.             price = marketFormula.changePriceOnTransaction(getStock(material), getStock(Material.GOLD_INGOT), goldPrice, amount);
  416.             if (Craftable.isCraftable(material)){
  417.                 price = getCraftablePrice(amount, material);
  418.             }
  419.             if (sign.getLine(0).contains("Buy") || material == Material.GOLD_INGOT){
  420.                 sign.setLine(3, "$"+price);
  421.             }
  422.             else if (sign.getLine(0).contains("Sell")){
  423.                 sign.setLine(3, "$"+(int)Math.floor(price * sellModifier));
  424.             }
  425.             sign.update(true);
  426.         }
  427.     }
  428.  
  429.     /*public void writeStockEvent(Material material, int amount, int curr){
  430.         stockEvents.add(new StockEvent(material, amount, System.currentTimeMillis(), curr));
  431.     }*/
  432.  
  433.     public void validateStocks(Material m, int amount, int signPrice, boolean isBuy){
  434.         int stock = getStock(m);
  435.  
  436.         int price;
  437.         if (isBuy){
  438.             price = signPrice;
  439.         }
  440.         else {
  441.             price = (int)Math.floor(signPrice / sellModifier);
  442.         }
  443.         if (Math.abs((marketFormula.changePriceOnTransaction(stock, getGoldStock(), goldPrice, amount) - price)) < validationThreshold){
  444.             return;
  445.         }
  446.         //Bukkit.broadcastMessage(""+stock);
  447.         hardSetStockByPrice(m, signPrice, amount, !isBuy);
  448.  
  449.     }
  450.  
  451.     public MarketFormula getFormula(){
  452.         return marketFormula;
  453.     }
  454.  
  455.     public double getGoldPrice(){
  456.         return goldPrice;
  457.     }
  458.  
  459.     public double getSellModifier(){
  460.         return sellModifier;
  461.     }
  462. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top