From 270b7ce5b84e67762a57e0fba02cac0eb32012e4 Mon Sep 17 00:00:00 2001 From: Xiao-MoMi <70987828+Xiao-MoMi@users.noreply.github.com> Date: Thu, 26 May 2022 00:28:41 +0800 Subject: [PATCH] =?UTF-8?q?1.3.0=20=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../customcrops/CommandHandler.java | 3 + .../customcrops/Crops/CropGrow.java | 165 ++- .../customcrops/Crops/CropTimer.java | 2 +- .../customcrops/Crops/SprinklerWork.java | 42 +- .../customcrops/Crops/TimeCheck.java | 45 +- .../customcrops/DataManager/BackUp.java | 5 + .../customcrops/DataManager/CropManager.java | 34 +- .../DataManager/MaxCropsPerChunk.java | 12 +- .../DataManager/MaxSprinklersPerChunk.java | 12 +- .../DataManager/SprinklerManager.java | 9 +- .../Integrations/IntegrationCheck.java | 46 + .../Integrations/ResidenceIntegrations.java | 4 - .../Integrations/WorldGuardIntegrations.java | 10 +- .../customcrops/Libs/minedown/MineDown.java | 499 ------- .../Libs/minedown/MineDownParser.java | 1241 ----------------- .../Libs/minedown/MineDownStringifier.java | 423 ------ .../customcrops/Libs/minedown/Replacer.java | 471 ------- .../customcrops/Libs/minedown/Util.java | 590 -------- .../listener/BreakCustomBlock.java | 24 +- .../customcrops/listener/BreakFurniture.java | 16 +- .../customcrops/listener/RightClickBlock.java | 159 +-- .../listener/RightClickCustomBlock.java | 371 ++--- src/main/resources/config.yml | 15 +- src/main/resources/plugin.yml | 2 +- 24 files changed, 559 insertions(+), 3641 deletions(-) create mode 100644 src/main/java/net/momirealms/customcrops/Integrations/IntegrationCheck.java delete mode 100644 src/main/java/net/momirealms/customcrops/Libs/minedown/MineDown.java delete mode 100644 src/main/java/net/momirealms/customcrops/Libs/minedown/MineDownParser.java delete mode 100644 src/main/java/net/momirealms/customcrops/Libs/minedown/MineDownStringifier.java delete mode 100644 src/main/java/net/momirealms/customcrops/Libs/minedown/Replacer.java delete mode 100644 src/main/java/net/momirealms/customcrops/Libs/minedown/Util.java diff --git a/src/main/java/net/momirealms/customcrops/CommandHandler.java b/src/main/java/net/momirealms/customcrops/CommandHandler.java index 62ecd5e..8d1e597 100644 --- a/src/main/java/net/momirealms/customcrops/CommandHandler.java +++ b/src/main/java/net/momirealms/customcrops/CommandHandler.java @@ -100,6 +100,9 @@ public class CommandHandler implements CommandExecutor { MessageManager.consoleMessage(config.getString("messages.prefix") + config.getString("messages.nextseason"), Bukkit.getConsoleSender()); } } + if(args[0].equalsIgnoreCase("test")){ + CropManager.testData_2(); + } return false; } } diff --git a/src/main/java/net/momirealms/customcrops/Crops/CropGrow.java b/src/main/java/net/momirealms/customcrops/Crops/CropGrow.java index 88362ac..b2b1a42 100644 --- a/src/main/java/net/momirealms/customcrops/Crops/CropGrow.java +++ b/src/main/java/net/momirealms/customcrops/Crops/CropGrow.java @@ -3,106 +3,133 @@ package net.momirealms.customcrops.Crops; import dev.lone.itemsadder.api.CustomBlock; import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.DataManager.CropManager; +import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; +import org.bukkit.block.Block; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.scheduler.BukkitScheduler; import java.io.File; import java.util.Objects; public class CropGrow { public static void cropGrow(){ + FileConfiguration config = CustomCrops.instance.getConfig(); File file = new File(CustomCrops.instance.getDataFolder(), "crop-data.yml"); FileConfiguration data; data = YamlConfiguration.loadConfiguration(file); + boolean enable_season = config.getBoolean("enable-season"); boolean enable_greenhouse = config.getBoolean("config.enable-greenhouse"); int range = config.getInt("config.greenhouse-range"); + double growChance = config.getDouble("config.grow-success-chance"); String glass = config.getString("config.greenhouse-glass"); - config.getStringList("config.whitelist-worlds").forEach(worldName -> CropManager.getCrops(Objects.requireNonNull(Bukkit.getWorld(worldName))).forEach(seedLocation -> { + String wateredPot = config.getString("config.watered-pot"); + String pot = config.getString("config.pot"); + String deadCrop = config.getString("config.dead-crop"); + String current = config.getString("current-season"); + BukkitScheduler bukkitScheduler = Bukkit.getScheduler(); + + config.getStringList("config.whitelist-worlds").forEach(worldName -> { + World world = Bukkit.getWorld(worldName); - Location potLocation = seedLocation.clone().subtract(0,1,0); - String[] seasons = Objects.requireNonNull(data.getString(worldName + "." + seedLocation.getBlockX() + "," + seedLocation.getBlockY() + "," + seedLocation.getBlockZ())).split(","); - if (CustomBlock.byAlreadyPlaced(world.getBlockAt(potLocation)) != null && CustomBlock.byAlreadyPlaced(world.getBlockAt(seedLocation)) != null){ - if (CustomBlock.byAlreadyPlaced((world.getBlockAt(potLocation))).getNamespacedID().equalsIgnoreCase(config.getString("config.watered-pot")) && CustomBlock.byAlreadyPlaced(world.getBlockAt(seedLocation)).getNamespacedID().contains("stage")){ - if (CustomBlock.byAlreadyPlaced(world.getBlockAt(seedLocation)).getNamespacedID().equalsIgnoreCase(config.getString("config.dead-crop"))){ - return; - } - String namespace = CustomBlock.byAlreadyPlaced(world.getBlockAt(seedLocation)).getNamespacedID().split(":")[0]; - String[] cropNameList = CustomBlock.byAlreadyPlaced(world.getBlockAt(seedLocation)).getNamespacedID().split(":")[1].split("_"); - Label_out: - if(enable_season){ - if(enable_greenhouse){ - for(int i = 1; i <= range; i++){ - Location tempLocation = seedLocation.clone().add(0,i,0); - if (CustomBlock.byAlreadyPlaced(world.getBlockAt(tempLocation)) != null){ - if(CustomBlock.byAlreadyPlaced(world.getBlockAt(tempLocation)).getNamespacedID().equalsIgnoreCase(glass)){ - break Label_out; - } - } - } - } - boolean wrongSeason = true; - for(String season : seasons){ - if(Objects.equals(season, config.getString("current-season"))){ - wrongSeason = false; - } - } - if(wrongSeason){ - Bukkit.getScheduler().callSyncMethod(CustomCrops.instance, () -> { - CustomBlock.remove(seedLocation); - CustomBlock.place(config.getString("config.dead-crop"),seedLocation); - return null; - }); + CropManager.getCrops(Bukkit.getWorld(worldName)).forEach(seedLocation -> { + + Location potLocation = seedLocation.clone().subtract(0,1,0); + Block seedBlock = world.getBlockAt(seedLocation); + Block potBlock = world.getBlockAt(potLocation); + + String[] seasons = StringUtils.split(data.getString(worldName + "." + seedLocation.getBlockX() + "," + seedLocation.getBlockY() + "," + seedLocation.getBlockZ()),","); + + if (CustomBlock.byAlreadyPlaced(potBlock) != null && CustomBlock.byAlreadyPlaced(seedBlock) != null){ + + String seedNamespace = CustomBlock.byAlreadyPlaced(seedBlock).getNamespacedID(); + + if (CustomBlock.byAlreadyPlaced(potBlock).getNamespacedID().equalsIgnoreCase(wateredPot) && seedNamespace.contains("stage")){ + if (seedNamespace.equalsIgnoreCase(deadCrop)){ return; } - } - int nextStage = Integer.parseInt(cropNameList[2]) + 1; - if (CustomBlock.getInstance( namespace +":"+cropNameList[0] + "_stage_" + nextStage) != null) { - Bukkit.getScheduler().callSyncMethod(CustomCrops.instance, () ->{ - CustomBlock.remove(potLocation); - CustomBlock.place(config.getString("config.pot"),potLocation); - if(Math.random()< config.getDouble("config.grow-success-chance")){ - CustomBlock.remove(seedLocation); - CustomBlock.place(namespace + ":" + cropNameList[0] + "_stage_" + nextStage,seedLocation); - } - return null; - }); - } - }else if(CustomBlock.byAlreadyPlaced((world.getBlockAt(potLocation))).getNamespacedID().equalsIgnoreCase(config.getString("config.pot")) && CustomBlock.byAlreadyPlaced(world.getBlockAt(seedLocation)).getNamespacedID().contains("stage")){ - if (CustomBlock.byAlreadyPlaced(world.getBlockAt(seedLocation)).getNamespacedID().equalsIgnoreCase(config.getString("config.dead-crop"))){ - return; - } - if(enable_season) { - if(enable_greenhouse){ - for(int i = 1; i <= range; i++){ - Location tempLocation = seedLocation.clone().add(0,i,0); - if (CustomBlock.byAlreadyPlaced(world.getBlockAt(tempLocation)) != null){ - if(CustomBlock.byAlreadyPlaced(world.getBlockAt(tempLocation)).getNamespacedID().equalsIgnoreCase(config.getString("config.greenhouse-glass"))){ - return; + + String[] split = StringUtils.split(seedNamespace,":"); + String[] cropNameList = StringUtils.split(split[1],"_"); + + Label_out: + if(enable_season){ + if(enable_greenhouse){ + for(int i = 1; i <= range; i++){ + Location tempLocation = seedLocation.clone().add(0,i,0); + if (CustomBlock.byAlreadyPlaced(world.getBlockAt(tempLocation)) != null){ + if(CustomBlock.byAlreadyPlaced(world.getBlockAt(tempLocation)).getNamespacedID().equalsIgnoreCase(glass)){ + break Label_out; + } } } } - } - boolean wrongSeason = true; - for (String season : seasons) { - if (Objects.equals(season, config.getString("current-season"))) { - wrongSeason = false; + boolean wrongSeason = true; + for(String season : seasons){ + if (Objects.equals(season, current)) { + wrongSeason = false; + break; + } + } + if(wrongSeason){ + bukkitScheduler.callSyncMethod(CustomCrops.instance, () -> { + CustomBlock.remove(seedLocation); + CustomBlock.place(deadCrop,seedLocation); + return null; + }); + return; } } - if (wrongSeason) { - Bukkit.getScheduler().callSyncMethod(CustomCrops.instance, () -> { - CustomBlock.remove(seedLocation); - CustomBlock.place(config.getString("config.dead-crop"), seedLocation); + int nextStage = Integer.parseInt(cropNameList[2]) + 1; + if (CustomBlock.getInstance( split[0] +":"+cropNameList[0] + "_stage_" + nextStage) != null) { + bukkitScheduler.callSyncMethod(CustomCrops.instance, () ->{ + CustomBlock.remove(potLocation); + CustomBlock.place(pot,potLocation); + if(Math.random()< growChance){ + CustomBlock.remove(seedLocation); + CustomBlock.place(split[0] + ":" + cropNameList[0] + "_stage_" + nextStage,seedLocation); + } return null; }); } + }else if(CustomBlock.byAlreadyPlaced(potBlock).getNamespacedID().equalsIgnoreCase(pot) && seedNamespace.contains("stage")){ + if (seedNamespace.equalsIgnoreCase(deadCrop)){ + return; + } + if(enable_season) { + if(enable_greenhouse){ + for(int i = 1; i <= range; i++){ + Location tempLocation = seedLocation.clone().add(0,i,0); + if (CustomBlock.byAlreadyPlaced(world.getBlockAt(tempLocation)) != null){ + if(CustomBlock.byAlreadyPlaced(world.getBlockAt(tempLocation)).getNamespacedID().equalsIgnoreCase(glass)){ + return; + } + } + } + } + boolean wrongSeason = true; + for (String season : seasons) { + if (Objects.equals(season, current)) { + wrongSeason = false; + break; + } + } + if (wrongSeason) { + bukkitScheduler.callSyncMethod(CustomCrops.instance, () -> { + CustomBlock.remove(seedLocation); + CustomBlock.place(deadCrop, seedLocation); + return null; + }); + } + } } } - } - })); + }); + }); } } diff --git a/src/main/java/net/momirealms/customcrops/Crops/CropTimer.java b/src/main/java/net/momirealms/customcrops/Crops/CropTimer.java index a18db56..1aa50c6 100644 --- a/src/main/java/net/momirealms/customcrops/Crops/CropTimer.java +++ b/src/main/java/net/momirealms/customcrops/Crops/CropTimer.java @@ -15,7 +15,7 @@ public class CropTimer { public CropTimer() { TimeCheck tc = new TimeCheck(); - BukkitTask task = tc.runTaskTimerAsynchronously(CustomCrops.instance, 1,1); + BukkitTask task = tc.runTaskTimer(CustomCrops.instance, 1,1); this.taskID = task.getTaskId(); } diff --git a/src/main/java/net/momirealms/customcrops/Crops/SprinklerWork.java b/src/main/java/net/momirealms/customcrops/Crops/SprinklerWork.java index 196a0b5..cbfe38e 100644 --- a/src/main/java/net/momirealms/customcrops/Crops/SprinklerWork.java +++ b/src/main/java/net/momirealms/customcrops/Crops/SprinklerWork.java @@ -15,30 +15,38 @@ import java.io.File; import java.util.Objects; public class SprinklerWork { + public static void sprinklerWork(){ - FileConfiguration config = CustomCrops.instance.getConfig(); + File file = new File(CustomCrops.instance.getDataFolder(), "sprinkler-data.yml"); FileConfiguration data; data = YamlConfiguration.loadConfiguration(file); - config.getStringList("config.whitelist-worlds").forEach(worldName -> SprinklerManager.getSprinklers(Objects.requireNonNull(Bukkit.getWorld(worldName))).forEach(location -> { + + FileConfiguration config = CustomCrops.instance.getConfig(); + + config.getStringList("config.whitelist-worlds").forEach(worldName -> { + World world = Bukkit.getWorld(worldName); - String type = Objects.requireNonNull(data.getString(worldName + "." + location.getBlockX() + "," + location.getBlockY() + "," + location.getBlockZ())); - if(type.equals("s1")){ - for(int i = -1; i <= 1;i++){ - for (int j = -1; j <= 1; j++){ - Location tempLoc = location.clone().add(i,-1,j); - waterPot(tempLoc, world, config); + SprinklerManager.getSprinklers(Bukkit.getWorld(worldName)).forEach(location -> { + + String type = Objects.requireNonNull(data.getString(worldName + "." + location.getBlockX() + "," + location.getBlockY() + "," + location.getBlockZ())); + if(type.equals("s1")){ + for(int i = -1; i <= 1;i++){ + for (int j = -1; j <= 1; j++){ + Location tempLoc = location.clone().add(i,-1,j); + waterPot(tempLoc, world, config); + } + } + }else if(type.equals("s2")){ + for(int i = -2; i <= 2;i++){ + for (int j = -2; j <= 2; j++){ + Location tempLoc = location.clone().add(i,-1,j); + waterPot(tempLoc, world, config); + } } } - }else if(type.equals("s2")){ - for(int i = -2; i <= 2;i++){ - for (int j = -2; j <= 2; j++){ - Location tempLoc = location.clone().add(i,-1,j); - waterPot(tempLoc, world, config); - } - } - } - })); + }); + }); } private static void waterPot(Location tempLoc, World world, FileConfiguration config) { if(CustomBlock.byAlreadyPlaced(world.getBlockAt(tempLoc)) != null){ diff --git a/src/main/java/net/momirealms/customcrops/Crops/TimeCheck.java b/src/main/java/net/momirealms/customcrops/Crops/TimeCheck.java index 7c45fce..d3eddc1 100644 --- a/src/main/java/net/momirealms/customcrops/Crops/TimeCheck.java +++ b/src/main/java/net/momirealms/customcrops/Crops/TimeCheck.java @@ -3,9 +3,11 @@ package net.momirealms.customcrops.Crops; import net.momirealms.customcrops.CustomCrops; import net.momirealms.customcrops.DataManager.CropManager; import net.momirealms.customcrops.DataManager.SprinklerManager; +import net.momirealms.customcrops.MessageManager; import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitScheduler; import java.util.List; import java.util.Objects; @@ -15,6 +17,7 @@ public class TimeCheck extends BukkitRunnable { FileConfiguration config = CustomCrops.instance.getConfig(); List cropGrowTimeList = config.getLongList("config.grow-time"); List sprinklerWorkTimeList = config.getLongList("config.sprinkler-time"); + BukkitScheduler bukkitScheduler = Bukkit.getScheduler(); @Override public void run() { @@ -23,26 +26,40 @@ public class TimeCheck extends BukkitRunnable { cropGrowTimeList.forEach(cropGrowTime -> { if(time == cropGrowTime){ - CropManager.cleanLoadedCache(); - } - if(time == (cropGrowTime + 50)){ - CropManager.saveData(); - } - if(time == (cropGrowTime + 100)){ - CropGrow.cropGrow(); + bukkitScheduler.runTaskAsynchronously(CustomCrops.instance,()->{ + long start1 = System.currentTimeMillis(); + CropManager.cleanLoadedCache(); + long finish1 = System.currentTimeMillis(); + MessageManager.consoleMessage("&#ccfbff-#ef96c5&[CustomCrops|性能监测] &f农作物缓存清理耗时&a" + String.valueOf(finish1-start1) + "&fms(异步)",Bukkit.getConsoleSender()); + long start2 = System.currentTimeMillis(); + CropManager.saveData(); + long finish2 = System.currentTimeMillis(); + MessageManager.consoleMessage("&#ccfbff-#ef96c5&[CustomCrops|性能监测] &f农作物数据保存耗时&a" + String.valueOf(finish2-start2) + "&fms(异步)",Bukkit.getConsoleSender()); + long start3 = System.currentTimeMillis(); + CropGrow.cropGrow(); + long finish3 = System.currentTimeMillis(); + MessageManager.consoleMessage("&#ccfbff-#ef96c5&[CustomCrops|性能监测] &f农作物生长耗时&a" + String.valueOf(finish3-start3) + "&fms(部分异步)",Bukkit.getConsoleSender()); + }); } }); sprinklerWorkTimeList.forEach(sprinklerTime -> { if(time == sprinklerTime){ - SprinklerManager.cleanCache(); - } - if(time == (sprinklerTime + 50)){ - SprinklerManager.saveData(); - } - if(time == (sprinklerTime + 100)){ - SprinklerWork.sprinklerWork(); + bukkitScheduler.runTaskAsynchronously(CustomCrops.instance,()->{ + long start1 = System.currentTimeMillis(); + SprinklerManager.cleanCache(); + long finish1 = System.currentTimeMillis(); + MessageManager.consoleMessage("&#ccfbff-#ef96c5&[CustomCrops|性能监测] &f洒水器缓存清理耗时&a" + String.valueOf(finish1-start1) + "&fms(部分异步)",Bukkit.getConsoleSender()); + long start2 = System.currentTimeMillis(); + SprinklerManager.saveData(); + long finish2 = System.currentTimeMillis(); + MessageManager.consoleMessage("&#ccfbff-#ef96c5&[CustomCrops|性能监测] &f洒水器数据保存耗时&a" + String.valueOf(finish2-start2) + "&fms(异步)",Bukkit.getConsoleSender()); + long start3 = System.currentTimeMillis(); + SprinklerWork.sprinklerWork(); + long finish3 = System.currentTimeMillis(); + MessageManager.consoleMessage("&#ccfbff-#ef96c5&[CustomCrops|性能监测] &f洒水器工作耗时&a" + String.valueOf(finish3-start3) + "&fms(部分异步)",Bukkit.getConsoleSender()); + }); } }); } diff --git a/src/main/java/net/momirealms/customcrops/DataManager/BackUp.java b/src/main/java/net/momirealms/customcrops/DataManager/BackUp.java index c1c5d35..3ed8120 100644 --- a/src/main/java/net/momirealms/customcrops/DataManager/BackUp.java +++ b/src/main/java/net/momirealms/customcrops/DataManager/BackUp.java @@ -10,6 +10,7 @@ import java.text.SimpleDateFormat; import java.util.Date; public class BackUp { + public static void backUpData(){ Date date = new Date(); @@ -22,6 +23,10 @@ public class BackUp { try { BackUp.backUp(crop_data,cropBackUp); + } catch (IOException e) { + e.printStackTrace(); + } + try { BackUp.backUp(sprinkler_data,sprinklerBackUp); } catch (IOException e) { e.printStackTrace(); diff --git a/src/main/java/net/momirealms/customcrops/DataManager/CropManager.java b/src/main/java/net/momirealms/customcrops/DataManager/CropManager.java index 99efa5d..a929741 100644 --- a/src/main/java/net/momirealms/customcrops/DataManager/CropManager.java +++ b/src/main/java/net/momirealms/customcrops/DataManager/CropManager.java @@ -1,6 +1,7 @@ package net.momirealms.customcrops.DataManager; import net.momirealms.customcrops.CustomCrops; +import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; @@ -11,10 +12,31 @@ import org.bukkit.configuration.file.YamlConfiguration; import java.io.File; import java.io.IOException; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; public class CropManager { - public static HashMap instances; + public static ConcurrentHashMap instances; + + //4W性能测试 + public static void testData_1(){ + for(int i = -100; i < 100; i++){ + for(int j = -100; j < 100; j++){ + Location tempLoc = new Location(Bukkit.getWorld("world"),i,100,j); + String name = "spring"; + instances.put(tempLoc, name); + } + } + } + //20W性能测试 + public static void testData_2(){ + for(int i = -100000; i < 100000; i++){ + Location tempLoc = new Location(Bukkit.getWorld("world"),i,100,i); + String name = "spring"; + instances.put(tempLoc, name); + } + } + //开服的时候将文件的数据读入 public CropManager(FileConfiguration data) { FileConfiguration config = CustomCrops.instance.getConfig(); @@ -22,7 +44,7 @@ public class CropManager { data = YamlConfiguration.loadConfiguration(file); try { for (String world : config.getStringList("config.whitelist-worlds")) { - CropManager.instances = new HashMap(); + CropManager.instances = new ConcurrentHashMap(); if(data.getConfigurationSection(world) != null){ for (String coordinate : data.getConfigurationSection(world).getKeys(false)) { Location tempLocation = new Location(Bukkit.getWorld(world), (double)Integer.parseInt(coordinate.split(",")[0]), (double)Integer.parseInt(coordinate.split(",")[1]), (double)Integer.parseInt(coordinate.split(",")[2])); @@ -33,7 +55,7 @@ public class CropManager { } } catch (Exception e) { - CropManager.instances = new HashMap(); + CropManager.instances = new ConcurrentHashMap(); e.printStackTrace(); } saveData(); @@ -74,7 +96,7 @@ public class CropManager { } } else { - CropManager.instances = new HashMap(); + CropManager.instances = new ConcurrentHashMap(); Bukkit.getConsoleSender().sendMessage("错误:空数据"); } try { @@ -88,7 +110,7 @@ public class CropManager { public static void putInstance(Location location, String season) { CropManager.instances.put(location, season); } - public HashMap getMap() { + public ConcurrentHashMap getMap() { return CropManager.instances; } @@ -102,7 +124,7 @@ public class CropManager { if(data.contains(worldName)){ World world = Bukkit.getWorld(worldName); data.getConfigurationSection(worldName).getKeys(false).forEach(key ->{ - String[] string_list = key.split(","); + String[] string_list = StringUtils.split(key,","); if (world.isChunkLoaded(Integer.parseInt(string_list[0])/16, Integer.parseInt(string_list[2])/16)){ Location tempLoc = new Location(world,Double.parseDouble(string_list[0]),Double.parseDouble(string_list[1]),Double.parseDouble(string_list[2])); if(world.getBlockAt(tempLoc).getType() != Material.TRIPWIRE){ diff --git a/src/main/java/net/momirealms/customcrops/DataManager/MaxCropsPerChunk.java b/src/main/java/net/momirealms/customcrops/DataManager/MaxCropsPerChunk.java index 5f9b540..0b7167a 100644 --- a/src/main/java/net/momirealms/customcrops/DataManager/MaxCropsPerChunk.java +++ b/src/main/java/net/momirealms/customcrops/DataManager/MaxCropsPerChunk.java @@ -3,12 +3,15 @@ package net.momirealms.customcrops.DataManager; import dev.lone.itemsadder.api.CustomBlock; import net.momirealms.customcrops.CustomCrops; import org.bukkit.Location; +import org.bukkit.block.Block; import org.bukkit.configuration.file.FileConfiguration; public class MaxCropsPerChunk { + static FileConfiguration config = CustomCrops.instance.getConfig(); + public static boolean maxCropsPerChunk(Location location){ - FileConfiguration config = CustomCrops.instance.getConfig(); + if(!config.getBoolean("config.enable-limit")){ return false; } @@ -23,11 +26,12 @@ public class MaxCropsPerChunk { Label_out: for (int i = 0; i < 16; ++i) { for (int j = 0; j < 16; ++j) { - final Location square = chunkLocation.clone().add((double)i, 0.0, (double)j); + Location square = chunkLocation.clone().add(i, 0.0, j); for (int k = minY; k <= maxY; ++k) { square.add(0.0, 1.0, 0.0); - if(CustomBlock.byAlreadyPlaced(location.getWorld().getBlockAt(square))!= null){ - if (CustomBlock.byAlreadyPlaced(location.getWorld().getBlockAt(square)).getNamespacedID().contains("stage")) { + Block b = location.getWorld().getBlockAt(square); + if(CustomBlock.byAlreadyPlaced(b)!= null){ + if (CustomBlock.byAlreadyPlaced(b).getNamespacedID().contains("stage")) { if (n++ > maxAmount) { break Label_out; } diff --git a/src/main/java/net/momirealms/customcrops/DataManager/MaxSprinklersPerChunk.java b/src/main/java/net/momirealms/customcrops/DataManager/MaxSprinklersPerChunk.java index 37db937..b7a3228 100644 --- a/src/main/java/net/momirealms/customcrops/DataManager/MaxSprinklersPerChunk.java +++ b/src/main/java/net/momirealms/customcrops/DataManager/MaxSprinklersPerChunk.java @@ -7,8 +7,11 @@ import org.bukkit.World; import org.bukkit.configuration.file.FileConfiguration; public class MaxSprinklersPerChunk { + + static FileConfiguration config = CustomCrops.instance.getConfig(); + public static boolean maxSprinklersPerChunk(Location location){ - FileConfiguration config = CustomCrops.instance.getConfig(); + if(!config.getBoolean("config.enable-limit")){ return false; } @@ -24,10 +27,10 @@ public class MaxSprinklersPerChunk { Label_out: for (int i = 0; i < 16; ++i) { for (int j = 0; j < 16; ++j) { - final Location square = chunkLocation.clone().add((double)i, 0.0, (double)j); + Location square = chunkLocation.clone().add(i+0.5, 0.5, j+0.5); for (int k = minY; k <= maxY; ++k) { square.add(0.0, 1.0, 0.0); - if(IAFurniture.getFromLocation(square.clone().add(0.5,0.5,0.5), world)){ + if(IAFurniture.getFromLocation(square, world)){ if (n++ > maxAmount) { break Label_out; } @@ -37,4 +40,7 @@ public class MaxSprinklersPerChunk { } return n > maxAmount; } + public static boolean alreadyPlaced(Location location){ + return IAFurniture.getFromLocation(location.clone().add(0.5, 1.5, 0.5), location.getWorld()); + } } diff --git a/src/main/java/net/momirealms/customcrops/DataManager/SprinklerManager.java b/src/main/java/net/momirealms/customcrops/DataManager/SprinklerManager.java index e7679f1..8bb2d9d 100644 --- a/src/main/java/net/momirealms/customcrops/DataManager/SprinklerManager.java +++ b/src/main/java/net/momirealms/customcrops/DataManager/SprinklerManager.java @@ -11,10 +11,11 @@ import org.bukkit.configuration.file.YamlConfiguration; import java.io.File; import java.io.IOException; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; public class SprinklerManager { - public static HashMap instances; + public static ConcurrentHashMap instances; //开服的时候将文件的数据读入 public SprinklerManager(FileConfiguration data) { @@ -23,7 +24,7 @@ public class SprinklerManager { data = YamlConfiguration.loadConfiguration(file); try { for (String world : config.getStringList("config.whitelist-worlds")) { - SprinklerManager.instances = new HashMap(); + SprinklerManager.instances = new ConcurrentHashMap(); if(data.getConfigurationSection(world) != null){ for (String coordinate : data.getConfigurationSection(world).getKeys(false)) { Location tempLocation = new Location(Bukkit.getWorld(world), Integer.parseInt(coordinate.split(",")[0]), Integer.parseInt(coordinate.split(",")[1]), Integer.parseInt(coordinate.split(",")[2])); @@ -34,7 +35,7 @@ public class SprinklerManager { } } catch (Exception e) { - SprinklerManager.instances = new HashMap(); + SprinklerManager.instances = new ConcurrentHashMap(); e.printStackTrace(); } saveData(); @@ -76,7 +77,7 @@ public class SprinklerManager { } } else { - SprinklerManager.instances = new HashMap(); + SprinklerManager.instances = new ConcurrentHashMap(); Bukkit.getConsoleSender().sendMessage("错误:空数据"); } try { diff --git a/src/main/java/net/momirealms/customcrops/Integrations/IntegrationCheck.java b/src/main/java/net/momirealms/customcrops/Integrations/IntegrationCheck.java new file mode 100644 index 0000000..b45cb50 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/Integrations/IntegrationCheck.java @@ -0,0 +1,46 @@ +package net.momirealms.customcrops.Integrations; + +import net.momirealms.customcrops.CustomCrops; +import org.bukkit.Location; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; + +public class IntegrationCheck { + + static FileConfiguration config = CustomCrops.instance.getConfig(); + + //收获权限检测 + public static boolean HarvestCheck(Location location, Player player){ + if(config.getBoolean("config.integration.kingdomsX")){ + if(KingdomsXIntegrations.checkKDBuild(location,player)){ + return true; + } + } + if(config.getBoolean("config.integration.residence")){ + if(ResidenceIntegrations.checkResHarvest(location,player)){ + return true; + } + } + if(config.getBoolean("config.integration.worldguard")){ + return WorldGuardIntegrations.checkWGHarvest(location, player); + } + return false; + } + //种植等权限检测 + public static boolean PlaceCheck(Location location, Player player){ + if(config.getBoolean("config.integration.kingdomsX")){ + if(KingdomsXIntegrations.checkKDBuild(location,player)){ + return true; + } + } + if(config.getBoolean("config.integration.residence")){ + if(ResidenceIntegrations.checkResBuild(location,player)){ + return true; + } + } + if(config.getBoolean("config.integration.worldguard")){ + return WorldGuardIntegrations.checkWGBuild(location, player); + } + return false; + } +} diff --git a/src/main/java/net/momirealms/customcrops/Integrations/ResidenceIntegrations.java b/src/main/java/net/momirealms/customcrops/Integrations/ResidenceIntegrations.java index 489d819..0638847 100644 --- a/src/main/java/net/momirealms/customcrops/Integrations/ResidenceIntegrations.java +++ b/src/main/java/net/momirealms/customcrops/Integrations/ResidenceIntegrations.java @@ -13,9 +13,7 @@ public class ResidenceIntegrations { ClaimedResidence res = com.bekvon.bukkit.residence.Residence.getInstance().getResidenceManager().getByLoc(location); if(res!=null){ ResidencePermissions perms = res.getPermissions(); - String playerName = player.getName(); boolean hasPermission = perms.playerHas(player, Flags.build, true); - ///perms.playerHas(playerName, "build", true); return !hasPermission; } return false; @@ -25,9 +23,7 @@ public class ResidenceIntegrations { ClaimedResidence res = com.bekvon.bukkit.residence.Residence.getInstance().getResidenceManager().getByLoc(location); if(res!=null){ ResidencePermissions perms = res.getPermissions(); - String playerName = player.getName(); boolean hasPermission = perms.playerHas(player, Flags.harvest, true); - //boolean hasPermission = perms.playerHas(playerName, "harvest", true); return !hasPermission; } return false; diff --git a/src/main/java/net/momirealms/customcrops/Integrations/WorldGuardIntegrations.java b/src/main/java/net/momirealms/customcrops/Integrations/WorldGuardIntegrations.java index e6e4fcb..663fb45 100644 --- a/src/main/java/net/momirealms/customcrops/Integrations/WorldGuardIntegrations.java +++ b/src/main/java/net/momirealms/customcrops/Integrations/WorldGuardIntegrations.java @@ -17,10 +17,7 @@ public class WorldGuardIntegrations { RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer(); RegionQuery query = container.createQuery(); - if (!query.testState(BukkitAdapter.adapt(loc), localPlayer, Flags.BUILD)) { - return true; - } - return false; + return !query.testState(BukkitAdapter.adapt(loc), localPlayer, Flags.BUILD); } public static boolean checkWGHarvest(Location loc,Player player){ @@ -28,9 +25,6 @@ public class WorldGuardIntegrations { RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer(); RegionQuery query = container.createQuery(); - if (!query.testState(BukkitAdapter.adapt(loc), localPlayer, Flags.BLOCK_BREAK)) { - return true; - } - return false; + return !query.testState(BukkitAdapter.adapt(loc), localPlayer, Flags.BLOCK_BREAK); } } diff --git a/src/main/java/net/momirealms/customcrops/Libs/minedown/MineDown.java b/src/main/java/net/momirealms/customcrops/Libs/minedown/MineDown.java deleted file mode 100644 index 1e0847a..0000000 --- a/src/main/java/net/momirealms/customcrops/Libs/minedown/MineDown.java +++ /dev/null @@ -1,499 +0,0 @@ -package net.momirealms.customcrops.Libs.minedown; - -/* - * Copyright (c) 2017 Max Lee (https://github.com/Phoenix616) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import net.md_5.bungee.api.ChatColor; -import net.md_5.bungee.api.chat.BaseComponent; -import net.md_5.bungee.api.chat.ClickEvent; -import net.md_5.bungee.api.chat.HoverEvent; - -import java.util.Map; - -/** - *

MineDown

- * A MarkDown inspired markup for Minecraft chat components - *

- * This lets you convert string messages into chat components by using a custom mark up syntax - * which is loosely based on MarkDown while still supporting legacy formatting codes. - * - * - * - * - * - * - * - * - * - * - * - * - *
Inline Formatting
Color legacy &6Text {@link ChatColor} codes
Color &gold&Text {@link ChatColor} codes
RGB Hex Color &ff00ff&Text Full hexadecimal format
RGB Hex Color &f0f&Text Short format (equivalent to long one)
Bold **Text**
Italic ##Text##
Underlined __Text__
Strikethrough ~~Text~~
Obfuscated ??Text??
- * - *

Events

- * You can define click and hover events with the commonly used MarkDown link syntax. - *

- * - * - * - * - * - * - * - *
Simple Syntax
General syntax [Text](text-color text-formatting... link hover text)
Simple Link [Text](https://example.com)
Simple Command [Text](/command to run)
Link + Hover [Text](https://example.com Hover Text)
Text formatting + Link + Hover [Text](blue underline https://example.com Hover Text)
- *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
Advanced Syntax
General syntax [Text](action=value) {@link ClickEvent.Action}, {@link HoverEvent.Action}
Link [Text](open_url=https://example.com)
Color [Text](color=red)
RGB Hex Color [Text](color=#ff00ff) Full hexadecimal format
RGB Hex Color [Text](color=#f0f) Short format (equivalent to long one)
Formatting [Text](format=underline,bold)
Font [Text](format=underline,bold)
Run Command [Text](run_command=/command string)
Suggest Command [Text](suggest_command=/command)
Simple Hover [Text](hover=Hover Text)
Hover Text [Text](show_text=Hover Text)
Hover Entity Info [Text](show_entity=uuid:pig Name)
Hover Item Info [Text](show_item=stone*2 nbt...)
- *

- * All advanced settings can be chained/included in a event definition. - * You can't however add multiple different colors or click and hover actions! - */ -public class MineDown { - public static final String FONT_PREFIX = "font="; - public static final String COLOR_PREFIX = "color="; - public static final String FORMAT_PREFIX = "format="; - public static final String HOVER_PREFIX = "hover="; - public static final String INSERTION_PREFIX = "insert="; - - private String message; - private final Replacer replacer = new Replacer(); - private final MineDownParser parser = new MineDownParser(); - private BaseComponent[] baseComponents = null; - private boolean replaceFirst = Boolean.getBoolean("de.themoep.minedown.replacefirst"); - - /** - * Create a new MineDown builder with a certain message - * @param message The message to parse - */ - public MineDown(String message) { - this.message = message; - } - - /** - * Parse a MineDown string to components - * @param message The message to translate - * @param replacements Optional placeholder replacements - * @return The parsed components - */ - public static BaseComponent[] parse(String message, String... replacements) { - return new MineDown(message).replace(replacements).toComponent(); - } - - /** - * Convert components to a MineDown string - * @param components The components to convert - * @return The components represented as a MineDown string - */ - public static String stringify(BaseComponent[] components) { - return new MineDownStringifier().stringify(components); - } - - /** - * Parse and convert the message to the component - * @return The parsed component message - */ - public BaseComponent[] toComponent() { - if (baseComponents() == null) { - if (replaceFirst()) { - Replacer componentReplacer = new Replacer(); - for (Map.Entry entry : replacer().componentReplacements().entrySet()) { - componentReplacer.replace(entry.getKey(), stringify(entry.getValue())); - } - baseComponents = parser().parse(componentReplacer.replaceIn(replacer().replaceIn(message()))).create(); - } else { - baseComponents = replacer().replaceIn(parser().parse(message()).create()); - } - } - return baseComponents(); - } - - /** - * Remove a cached component and re-parse the next time {@link #toComponent} is called - */ - private void reset() { - baseComponents = null; - } - - /** - * Set whether or not replacements should be replaced before or after the components are created. - * When replacing first it will not replace any placeholders with component replacement values! - * Default is after. (replaceFirst = false) - * @param replaceFirst Whether or not to replace first or parse first - * @return The MineDown instance - */ - public MineDown replaceFirst(boolean replaceFirst) { - reset(); - this.replaceFirst = replaceFirst; - return this; - } - - /** - * Get whether or not replacements should be replaced before or after the components are created. - * When replacing first it will not replace any placeholders with component replacement values! - * Default is after. (replaceFirst = false) - * @return Whether or not to replace first or parse first - */ - public boolean replaceFirst() { - return replaceFirst; - } - - /** - * Add an array with placeholders and values that should get replaced in the message - * @param replacements The replacements, nth element is the placeholder, n+1th the value - * @return The MineDown instance - */ - public MineDown replace(String... replacements) { - reset(); - replacer().replace(replacements); - return this; - } - - /** - * Add a map with placeholders and values that should get replaced in the message - * @param replacements The replacements mapped placeholder to value - * @return The MineDown instance - */ - public MineDown replace(Map replacements) { - reset(); - replacer().replace(replacements); - return this; - } - - /** - * Add a placeholder to component mapping that should get replaced in the message - * @param placeholder The placeholder to replace - * @param replacement The replacement components - * @return The Replacer instance - */ - public MineDown replace(String placeholder, BaseComponent... replacement) { - reset(); - replacer().replace(placeholder,replacement); - return this; - } - - /** - * Set the placeholder indicator for both prefix and suffix - * @param placeholderIndicator The character to use as a placeholder indicator - * @return The MineDown instance - */ - public MineDown placeholderIndicator(String placeholderIndicator) { - placeholderPrefix(placeholderIndicator); - placeholderSuffix(placeholderIndicator); - return this; - } - - /** - * Set the placeholder indicator's prefix character - * @param placeholderPrefix The character to use as the placeholder indicator's prefix - * @return The MineDown instance - */ - public MineDown placeholderPrefix(String placeholderPrefix) { - reset(); - replacer().placeholderPrefix(placeholderPrefix); - return this; - } - - /** - * Get the placeholder indicator's prefix character - * @return The placeholder indicator's prefix character - */ - public String placeholderPrefix() { - return replacer().placeholderPrefix(); - } - - /** - * Set the placeholder indicator's suffix character - * @param placeholderSuffix The character to use as the placeholder indicator's suffix - * @return The MineDown instance - */ - public MineDown placeholderSuffix(String placeholderSuffix) { - reset(); - replacer().placeholderSuffix(placeholderSuffix); - return this; - } - - /** - * Get the placeholder indicator's suffix character - * @return The placeholder indicator's suffix character - */ - public String placeholderSuffix() { - return replacer().placeholderSuffix(); - } - - /** - * Set whether or not the case of the placeholder should be ignored when replacing - * @param ignorePlaceholderCase Whether or not to ignore the case of the placeholders - * @return The MineDown instance - */ - public MineDown ignorePlaceholderCase(boolean ignorePlaceholderCase) { - reset(); - replacer().ignorePlaceholderCase(ignorePlaceholderCase); - return this; - } - - /** - * Get whether or not the case of the placeholder should be ignored when replacing - * @return Whether or not to ignore the case of the placeholders - */ - public boolean ignorePlaceholderCase() { - return replacer().ignorePlaceholderCase(); - } - - /** - * Enable or disable the translation of legacy color codes - * @param translateLegacyColors Whether or not to translate legacy color codes (Default: true) - * @return The MineDown instance - * @deprecated Use {@link #enable(MineDownParser.Option)} and {@link #disable(MineDownParser.Option)} - */ - @Deprecated - public MineDown translateLegacyColors(boolean translateLegacyColors) { - reset(); - parser().translateLegacyColors(translateLegacyColors); - return this; - } - - /** - * Detect urls in strings and add events to them? (Default: true) - * @param enabled Whether or not to detect URLs and add events to them - * @return The MineDown instance - */ - public MineDown urlDetection(boolean enabled) { - reset(); - parser().urlDetection(enabled); - return this; - } - - /** - * Automatically add http to values of open_url when there doesn't exist any? (Default: true) - * @param enabled Whether or not to automatically add http when missing - * @return The MineDown instance - */ - public MineDown autoAddUrlPrefix(boolean enabled) { - reset(); - parser().autoAddUrlPrefix(enabled); - return this; - } - - /** - * The text to display when hovering over an URL - * @param text The text to display when hovering over an URL - * @return The MineDown instance - */ - public MineDown urlHoverText(String text) { - reset(); - parser().urlHoverText(text); - return this; - } - - /** - * Set the max width the hover text should have. - * Minecraft itself will wrap after 60 characters. - * Won't apply if the text already includes new lines. - * @param hoverTextWidth The url hover text length - * @return The MineDown instance - */ - public MineDown hoverTextWidth(int hoverTextWidth) { - reset(); - parser().hoverTextWidth(hoverTextWidth); - return this; - } - - /** - * Enable an option. Unfilter it if you filtered it before. - * @param option The option to enable - * @return The MineDown instance - */ - public MineDown enable(MineDownParser.Option option) { - reset(); - parser().enable(option); - return this; - } - - /** - * Disable an option. Disabling an option will stop the parser from replacing - * this option's chars in the string. Use {@link #filter(MineDownParser.Option)} to completely - * remove the characters used by this option from the message instead. - * @param option The option to disable - * @return The MineDown instance - */ - public MineDown disable(MineDownParser.Option option) { - reset(); - parser().disable(option); - return this; - } - - /** - * Filter an option. This completely removes the characters of this option from - * the string ignoring whether the option is enabled or not. - * @param option The option to add to the filter - * @return The MineDown instance - */ - public MineDown filter(MineDownParser.Option option) { - reset(); - parser().filter(option); - return this; - } - - /** - * Unfilter an option. Does not enable it! - * @param option The option to remove from the filter - * @return The MineDown instance - */ - public MineDown unfilter(MineDownParser.Option option) { - reset(); - parser().unfilter(option); - return this; - } - - /** - * Set a special character to replace color codes by if translating legacy colors is enabled. - * @param colorChar The character to use as a special color code. (Default: ampersand &) - * @return The MineDown instance - */ - public MineDown colorChar(char colorChar) { - reset(); - parser().colorChar(colorChar); - return this; - } - - /** - * Get the set message that is to be parsed - * @return The to be parsed message - */ - public String message() { - return this.message; - } - - /** - * Set the message that is to be parsed - * @param message The message to be parsed - * @return The MineDown instance - */ - public MineDown message(String message) { - this.message = message; - reset(); - return this; - } - - /** - * Get the replacer instance that is currently used - * @return The currently used replacer instance - */ - public Replacer replacer() { - return this.replacer; - } - - /** - * Get the parser instance that is currently used - * @return The currently used parser instance - */ - public MineDownParser parser() { - return this.parser; - } - - protected BaseComponent[] baseComponents() { - return this.baseComponents; - } - - /** - * Copy all MineDown settings to a new instance - * @return The new MineDown instance with all settings copied - */ - public MineDown copy() { - return new MineDown(message()).copy(this); - } - - /** - * Copy all MineDown settings from another one - * @param from The MineDown to copy from - * @return This MineDown instance - */ - public MineDown copy(MineDown from) { - replacer().copy(from.replacer()); - parser().copy(from.parser()); - return this; - } - - /** - * Get the string that represents the format in MineDown - * @param format The format - * @return The MineDown string or an empty one if it's not a format - */ - public static String getFormatString(ChatColor format) { - if (format == ChatColor.BOLD) { - return "**"; - } else if (format == ChatColor.ITALIC) { - return "##"; - } else if (format == ChatColor.UNDERLINE) { - return "__"; - } else if (format == ChatColor.STRIKETHROUGH) { - return "~~"; - } else if (format == ChatColor.MAGIC) { - return "??"; - } - return ""; - } - - /** - * Get the ChatColor format from a MineDown string - * @param c The character - * @return The ChatColor of that format or null it none was found - */ - public static ChatColor getFormatFromChar(char c) { - switch (c) { - case '~': - return ChatColor.STRIKETHROUGH; - case '_': - return ChatColor.UNDERLINE; - case '*': - return ChatColor.BOLD; - case '#': - return ChatColor.ITALIC; - case '?': - return ChatColor.MAGIC; - } - return null; - } - - /** - * Escape all MineDown formatting in a string. This will escape backslashes too! - * @param string The string to escape in - * @return The string with formatting escaped - */ - public static String escape(String string) { - return new MineDown(string).parser().escape(string); - } -} diff --git a/src/main/java/net/momirealms/customcrops/Libs/minedown/MineDownParser.java b/src/main/java/net/momirealms/customcrops/Libs/minedown/MineDownParser.java deleted file mode 100644 index 5751122..0000000 --- a/src/main/java/net/momirealms/customcrops/Libs/minedown/MineDownParser.java +++ /dev/null @@ -1,1241 +0,0 @@ -package net.momirealms.customcrops.Libs.minedown; - -/* - * Copyright (c) 2017 Max Lee (https://github.com/Phoenix616) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import net.md_5.bungee.api.ChatColor; -import net.md_5.bungee.api.chat.BaseComponent; -import net.md_5.bungee.api.chat.ClickEvent; -import net.md_5.bungee.api.chat.ComponentBuilder; -import net.md_5.bungee.api.chat.HoverEvent; -import net.md_5.bungee.api.chat.ItemTag; -import net.md_5.bungee.api.chat.TextComponent; -import net.md_5.bungee.api.chat.hover.content.Entity; -import net.md_5.bungee.api.chat.hover.content.Item; -import net.md_5.bungee.api.chat.hover.content.Text; - -import java.awt.Color; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collections; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.PrimitiveIterator; -import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -import static net.momirealms.customcrops.Libs.minedown.MineDown.COLOR_PREFIX; -import static net.momirealms.customcrops.Libs.minedown.MineDown.FONT_PREFIX; -import static net.momirealms.customcrops.Libs.minedown.MineDown.FORMAT_PREFIX; -import static net.momirealms.customcrops.Libs.minedown.MineDown.HOVER_PREFIX; -import static net.momirealms.customcrops.Libs.minedown.MineDown.INSERTION_PREFIX; - -public class MineDownParser { - private static final String RAINBOW = "rainbow"; - - private static final boolean HAS_APPEND_SUPPORT = Util.hasMethod(ComponentBuilder.class, "append", BaseComponent[].class); - private static final boolean HAS_RGB_SUPPORT = Util.hasMethod(ChatColor.class, "of", String.class); - private static final boolean HAS_FONT_SUPPORT = Util.hasMethod(ComponentBuilder.class, "font", String.class); - private static final boolean HAS_INSERTION_SUPPORT = Util.hasMethod(ComponentBuilder.class, "insertion", String.class); - private static final boolean HAS_HOVER_CONTENT_SUPPORT = Util.hasMethod(HoverEvent.class, "getContents"); - - /** - * The character to use as a special color code. (Default: ampersand &) - */ - private char colorChar = '&'; - - /** - * All enabled options - */ - private Set