Advertisement
Guest User

Untitled

a guest
May 25th, 2019
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.81 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement