mirror of
https://github.com/Xiao-MoMi/Custom-Crops.git
synced 2025-12-22 16:39:36 +00:00
1.5.19-PRE1
This commit is contained in:
@@ -336,7 +336,7 @@ public class ConfigReader {
|
||||
}
|
||||
});
|
||||
}
|
||||
AdventureManager.consoleMessage("<gradient:#ff206c:#fdee55>[CustomCrops] </gradient><white>" + SPRINKLERS.size()/2 + "<color:#FFEBCD> srpinklers loaded!");
|
||||
AdventureManager.consoleMessage("<gradient:#ff206c:#fdee55>[CustomCrops] </gradient><white>" + SPRINKLERS.size()/2 + "<color:#FFEBCD> sprinklers loaded!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -505,10 +505,22 @@ public class ConfigReader {
|
||||
});
|
||||
cropInstance.setRequirements(requirements);
|
||||
}
|
||||
if (config.contains("crops." + key + ".grow-chance")){
|
||||
cropInstance.setGrowChance(config.getDouble("crops." + key + ".grow-chance"));
|
||||
}else {
|
||||
cropInstance.setGrowChance(1);
|
||||
}
|
||||
if (Config.quality){
|
||||
cropInstance.setQuality_1(config.getString("crops." + key + ".quality.1"));
|
||||
cropInstance.setQuality_2(config.getString("crops." + key + ".quality.2"));
|
||||
cropInstance.setQuality_3(config.getString("crops." + key + ".quality.3"));
|
||||
if (config.contains("crops." + key + ".drop-ia-loots")){
|
||||
cropInstance.setDropIALoot(config.getBoolean("crops." + key + ".drop-ia-loots"));
|
||||
}else {
|
||||
cropInstance.setDropIALoot(false);
|
||||
}
|
||||
}else {
|
||||
cropInstance.setDropIALoot(false);
|
||||
}
|
||||
CROPS.put(key, cropInstance);
|
||||
});
|
||||
|
||||
@@ -42,11 +42,18 @@ public final class CustomCrops extends JavaPlugin {
|
||||
|
||||
public static JavaPlugin instance;
|
||||
public static BukkitAudiences adventure;
|
||||
|
||||
private CropTimer cropTimer;
|
||||
private CropManager cropManager;
|
||||
private SprinklerManager sprinklerManager;
|
||||
private SeasonManager seasonManager;
|
||||
private PotManager potManager;
|
||||
private Placeholders placeholders;
|
||||
|
||||
public CropManager getCropManager() { return this.cropManager; }
|
||||
public SprinklerManager getSprinklerManager() { return sprinklerManager; }
|
||||
public SeasonManager getSeasonManager() { return seasonManager; }
|
||||
public PotManager getPotManager() { return potManager; }
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
@@ -56,40 +63,83 @@ public final class CustomCrops extends JavaPlugin {
|
||||
|
||||
AdventureManager.consoleMessage("<gradient:#ff206c:#fdee55>[CustomCrops] </gradient><color:#FFEBCD>Running on " + Bukkit.getVersion());
|
||||
|
||||
//加载配置文件
|
||||
ConfigReader.ReloadConfig();
|
||||
|
||||
//PAPI
|
||||
if(Bukkit.getPluginManager().getPlugin("PlaceHolderAPI") != null){
|
||||
new Placeholders().register();
|
||||
placeholders = new Placeholders();
|
||||
placeholders.register();
|
||||
AdventureManager.consoleMessage("<gradient:#ff206c:#fdee55>[CustomCrops] </gradient><gold>PlaceHolderAPI <color:#FFEBCD>Hooked!");
|
||||
}
|
||||
|
||||
//指令注册
|
||||
Objects.requireNonNull(Bukkit.getPluginCommand("customcrops")).setExecutor(new Executor(this));
|
||||
Objects.requireNonNull(Bukkit.getPluginCommand("customcrops")).setTabCompleter(new Completer());
|
||||
|
||||
//注册事件
|
||||
Bukkit.getPluginManager().registerEvents(new ItemSpawn(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new RightClick(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new BreakBlock(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new InteractEntity(this), this);
|
||||
|
||||
//开始计时器
|
||||
this.cropTimer = new CropTimer(this);
|
||||
|
||||
//载入数据
|
||||
if (ConfigReader.Season.enable){
|
||||
this.seasonManager = new SeasonManager(this);
|
||||
this.seasonManager = new SeasonManager();
|
||||
this.seasonManager.loadData();
|
||||
}
|
||||
this.cropManager = new CropManager(this);
|
||||
this.cropManager = new CropManager();
|
||||
this.cropManager.loadData();
|
||||
this.sprinklerManager = new SprinklerManager(this);
|
||||
this.sprinklerManager = new SprinklerManager();
|
||||
this.sprinklerManager.loadData();
|
||||
this.potManager = new PotManager(this);
|
||||
this.potManager = new PotManager();
|
||||
this.potManager.loadData();
|
||||
this.cropTimer = new CropTimer(this);
|
||||
|
||||
checkIAConfig();
|
||||
|
||||
AdventureManager.consoleMessage("<gradient:#ff206c:#fdee55>[CustomCrops] </gradient><color:#F5DEB3>Plugin Enabled!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
|
||||
HoloUtil.cache.keySet().forEach(location -> HoloUtil.cache.get(location).remove());
|
||||
|
||||
if (this.cropManager != null){
|
||||
this.cropManager.cleanData();
|
||||
this.cropManager.saveData();
|
||||
this.cropManager = null;
|
||||
}
|
||||
if (this.potManager != null){
|
||||
this.potManager.saveData();
|
||||
this.potManager = null;
|
||||
}
|
||||
if (this.sprinklerManager != null){
|
||||
this.sprinklerManager.cleanData();
|
||||
this.sprinklerManager.saveData();
|
||||
this.sprinklerManager = null;
|
||||
}
|
||||
if (ConfigReader.Season.enable && !ConfigReader.Season.seasonChange && this.seasonManager != null){
|
||||
this.seasonManager.saveData();
|
||||
this.seasonManager = null;
|
||||
}
|
||||
if (this.placeholders != null){
|
||||
placeholders.unregister();
|
||||
placeholders = null;
|
||||
}
|
||||
|
||||
getLogger().info("Backing Up...");
|
||||
BackUp.backUpData();
|
||||
getLogger().info("Done.");
|
||||
|
||||
if (cropTimer != null) {
|
||||
this.cropTimer.stopTimer(cropTimer.getTaskID());
|
||||
}
|
||||
if (adventure != null) {
|
||||
adventure.close();
|
||||
}
|
||||
if (instance != null) {
|
||||
instance = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void checkIAConfig(){
|
||||
FileConfiguration fileConfiguration = Bukkit.getPluginManager().getPlugin("ItemsAdder").getConfig();
|
||||
if (fileConfiguration.getBoolean("blocks.disable-REAL_WIRE")){
|
||||
fileConfiguration.set("blocks.disable-REAL_WIRE", false);
|
||||
@@ -100,46 +150,6 @@ public final class CustomCrops extends JavaPlugin {
|
||||
}
|
||||
AdventureManager.consoleMessage("<gradient:#ff206c:#fdee55>[CustomCrops] </gradient><red>Detected that you might have not set \"disable-REAL_WIRE\" false in ItemsAdder's config!");
|
||||
AdventureManager.consoleMessage("<gradient:#ff206c:#fdee55>[CustomCrops] </gradient><red>You need a restart to apply that config :)");
|
||||
}else {
|
||||
AdventureManager.consoleMessage("<gradient:#ff206c:#fdee55>[CustomCrops] </gradient><color:#F5DEB3>Plugin Enabled!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
|
||||
//保存数据
|
||||
this.cropManager.cleanData();
|
||||
this.cropManager.saveData();
|
||||
this.sprinklerManager.cleanData();
|
||||
this.sprinklerManager.saveData();
|
||||
this.potManager.saveData();
|
||||
if (ConfigReader.Season.enable && !ConfigReader.Season.seasonChange){
|
||||
this.seasonManager.saveData();
|
||||
}
|
||||
|
||||
//备份数据
|
||||
getLogger().info("Back Up...");
|
||||
BackUp.backUpData();
|
||||
getLogger().info("Done.");
|
||||
|
||||
//清除悬浮展示实体
|
||||
HoloUtil.cache.keySet().forEach(location -> {
|
||||
HoloUtil.cache.get(location).remove();
|
||||
});
|
||||
|
||||
//关闭计时器
|
||||
if (cropTimer != null) {
|
||||
this.cropTimer.stopTimer(cropTimer.getTaskID());
|
||||
}
|
||||
|
||||
if (adventure != null) {
|
||||
adventure.close();
|
||||
}
|
||||
}
|
||||
|
||||
public CropManager getCropManager() { return this.cropManager; }
|
||||
public SprinklerManager getSprinklerManager() { return sprinklerManager; }
|
||||
public SeasonManager getSeasonManager() { return seasonManager; }
|
||||
public PotManager getPotManager() { return potManager; }
|
||||
}
|
||||
|
||||
@@ -40,12 +40,12 @@ public class Executor implements CommandExecutor {
|
||||
@Override
|
||||
@ParametersAreNonnullByDefault
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
//权限不足
|
||||
|
||||
if (!(sender.hasPermission("customcrops.admin") || sender.isOp())){
|
||||
AdventureManager.playerMessage((Player) sender, ConfigReader.Message.prefix + ConfigReader.Message.noPerm);
|
||||
return true;
|
||||
}
|
||||
//参数不足
|
||||
|
||||
if (args.length < 1) {
|
||||
lackArgs(sender);
|
||||
return true;
|
||||
@@ -182,6 +182,10 @@ public class Executor implements CommandExecutor {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 缺少参数的提示语
|
||||
* @param sender 发送者
|
||||
*/
|
||||
private void lackArgs(CommandSender sender){
|
||||
if (sender instanceof Player){
|
||||
AdventureManager.playerMessage((Player) sender,ConfigReader.Message.prefix + ConfigReader.Message.lackArgs);
|
||||
@@ -190,6 +194,10 @@ public class Executor implements CommandExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 强制保存的提示语
|
||||
* @param sender 发送者
|
||||
*/
|
||||
private void forceSave(CommandSender sender){
|
||||
if (sender instanceof Player player){
|
||||
AdventureManager.playerMessage(player,ConfigReader.Message.prefix + ConfigReader.Message.forceSave);
|
||||
|
||||
@@ -45,16 +45,16 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
public class CropManager {
|
||||
|
||||
private YamlConfiguration data;
|
||||
private final CustomCrops plugin;
|
||||
public static ConcurrentHashMap<Location, String> Cache = new ConcurrentHashMap<>();
|
||||
private BukkitScheduler bukkitScheduler;
|
||||
private final BukkitScheduler bukkitScheduler;
|
||||
|
||||
public CropManager(CustomCrops plugin){
|
||||
this.plugin = plugin;
|
||||
public CropManager(){
|
||||
this.bukkitScheduler = Bukkit.getScheduler();
|
||||
}
|
||||
|
||||
//载入数据
|
||||
/**
|
||||
* 载入数据
|
||||
*/
|
||||
public void loadData() {
|
||||
File file = new File(CustomCrops.instance.getDataFolder(), "data" + File.separator + "crop.yml");
|
||||
if(!file.exists()){
|
||||
@@ -69,7 +69,9 @@ public class CropManager {
|
||||
this.data = YamlConfiguration.loadConfiguration(file);
|
||||
}
|
||||
|
||||
//保存数据
|
||||
/**
|
||||
* 保存数据
|
||||
*/
|
||||
public void saveData() {
|
||||
File file = new File(CustomCrops.instance.getDataFolder(), "data" + File.separator + "crop.yml");
|
||||
try{
|
||||
@@ -80,7 +82,9 @@ public class CropManager {
|
||||
}
|
||||
}
|
||||
|
||||
//将缓存内新数据更新到data内
|
||||
/**
|
||||
* 将hashmap中的数据保存到data中
|
||||
*/
|
||||
public void updateData(){
|
||||
Cache.forEach((location, String) -> {
|
||||
int x = location.getBlockX();
|
||||
@@ -90,7 +94,9 @@ public class CropManager {
|
||||
Cache.clear();
|
||||
}
|
||||
|
||||
//隐藏指令,清除无用数据
|
||||
/**
|
||||
* 清除无用数据
|
||||
*/
|
||||
public void cleanData(){
|
||||
data.getKeys(false).forEach(world -> {
|
||||
data.getConfigurationSection(world).getKeys(false).forEach(chunk ->{
|
||||
@@ -101,7 +107,10 @@ public class CropManager {
|
||||
});
|
||||
}
|
||||
|
||||
//农作物生长
|
||||
/**
|
||||
* 农作物生长
|
||||
* @param worldName 进行生长判定的世界名
|
||||
*/
|
||||
public void cropGrow(String worldName){
|
||||
|
||||
Long time1 = System.currentTimeMillis();
|
||||
@@ -155,7 +164,7 @@ public class CropManager {
|
||||
}
|
||||
}
|
||||
int nextStage = Integer.parseInt(cropNameList[2]) + 1;
|
||||
if (CustomBlock.getInstance(StringUtils.chop(namespacedID) + nextStage) != null) {
|
||||
if (CustomBlock.getInstance(StringUtils.chop(namespacedID) + nextStage) != null && cropInstance.getGrowChance() > Math.random()) {
|
||||
Fertilizer fertilizer = PotManager.Cache.get(SimpleLocation.fromLocation(potLocation));
|
||||
if (fertilizer != null){
|
||||
int times = fertilizer.getTimes();
|
||||
@@ -229,7 +238,10 @@ public class CropManager {
|
||||
}
|
||||
}
|
||||
|
||||
//农作物生长
|
||||
/**
|
||||
* 全部世界农作物生长
|
||||
* 对于使用动态加载世界的服务器有效
|
||||
*/
|
||||
public void cropGrowAll(){
|
||||
Long time1 = System.currentTimeMillis();
|
||||
updateData();
|
||||
@@ -271,7 +283,6 @@ public class CropManager {
|
||||
CropInstance cropInstance = ConfigReader.CROPS.get(cropNameList[0]);
|
||||
int random = new Random().nextInt(ConfigReader.Config.timeToGrow);
|
||||
if (potNamespacedID.equals(ConfigReader.Basic.watered_pot)){
|
||||
//如果启用季节限制且农作物有季节需求
|
||||
if (ConfigReader.Season.enable && cropInstance.getSeasons() != null){
|
||||
if (isWrongSeason(seedLocation, cropInstance.getSeasons(), worldName)){
|
||||
data.set(stringBuilder.toString(), null);
|
||||
@@ -283,7 +294,7 @@ public class CropManager {
|
||||
}
|
||||
}
|
||||
int nextStage = Integer.parseInt(cropNameList[2]) + 1;
|
||||
if (CustomBlock.getInstance(StringUtils.chop(namespacedID) + nextStage) != null) {
|
||||
if (CustomBlock.getInstance(StringUtils.chop(namespacedID) + nextStage) != null && cropInstance.getGrowChance() > Math.random()) {
|
||||
Fertilizer fertilizer = PotManager.Cache.get(SimpleLocation.fromLocation(potLocation));
|
||||
if (fertilizer != null){
|
||||
int times = fertilizer.getTimes();
|
||||
@@ -358,6 +369,12 @@ public class CropManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判定季节
|
||||
* @param worldName 世界名
|
||||
* @param seasons 农作物能生长的季节
|
||||
* @param seedLocation 农作物的位置
|
||||
*/
|
||||
private boolean isWrongSeason(Location seedLocation, List<String> seasons, String worldName){
|
||||
if(ConfigReader.Season.greenhouse){
|
||||
for(int i = 1; i <= ConfigReader.Season.range; i++){
|
||||
@@ -385,19 +402,36 @@ public class CropManager {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生长一个阶段(消耗水)
|
||||
* @param potLocation 种植盆位置
|
||||
* @param seedLocation 农作物位置
|
||||
* @param namespacedID 农作物下一阶段的ID
|
||||
* @param nextStage 农作物下一阶段的阶段数
|
||||
* @param random 随机生长时间
|
||||
*/
|
||||
private void addStage(Location potLocation, Location seedLocation, String namespacedID, int nextStage, int random){
|
||||
String stage = StringUtils.chop(namespacedID) + nextStage;
|
||||
bukkitScheduler.runTaskLater(CustomCrops.instance, () ->{
|
||||
CustomBlock.remove(potLocation);
|
||||
CustomBlock.place(ConfigReader.Basic.pot, potLocation);
|
||||
CustomBlock.remove(seedLocation);
|
||||
CustomBlock.place(StringUtils.chop(namespacedID) + nextStage, seedLocation);
|
||||
CustomBlock.place(stage, seedLocation);
|
||||
}, random);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生长一个阶段(不消耗水)
|
||||
* @param seedLocation 农作物位置
|
||||
* @param namespacedID 农作物下一阶段的ID
|
||||
* @param nextStage 农作物下一阶段的阶段数
|
||||
* @param random 随机生长时间
|
||||
*/
|
||||
private void addStage(Location seedLocation, String namespacedID, int nextStage, int random){
|
||||
String stage = StringUtils.chop(namespacedID) + nextStage;
|
||||
bukkitScheduler.runTaskLater(CustomCrops.instance, () ->{
|
||||
CustomBlock.remove(seedLocation);
|
||||
CustomBlock.place(StringUtils.chop(namespacedID) + nextStage, seedLocation);
|
||||
CustomBlock.place(stage, seedLocation);
|
||||
}, random);
|
||||
}
|
||||
}
|
||||
@@ -37,13 +37,11 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class PotManager {
|
||||
|
||||
private CustomCrops plugin;
|
||||
public static ConcurrentHashMap<SimpleLocation, Fertilizer> Cache = new ConcurrentHashMap<>();
|
||||
|
||||
public PotManager(CustomCrops plugin){
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* 载入数据
|
||||
*/
|
||||
public void loadData(){
|
||||
File file = new File(CustomCrops.instance.getDataFolder(), "data" + File.separator + "pot.yml");
|
||||
if(!file.exists()){
|
||||
@@ -65,13 +63,10 @@ public class PotManager {
|
||||
if (fertilizer == null) return;
|
||||
if (fertilizer instanceof SpeedGrow speedGrow){
|
||||
Cache.put(new SimpleLocation(worldName, Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2])), new SpeedGrow(name, (int) map.get("times"), speedGrow.getChance(), speedGrow.isBefore()));
|
||||
//Cache.put(new Location(Bukkit.getWorld(worldName), Double.parseDouble(split[0]), Double.parseDouble(split[1]), Double.parseDouble(split[2])), new SpeedGrow(name, (int) map.get("times"), speedGrow.getChance(), speedGrow.isBefore()));
|
||||
}else if (fertilizer instanceof QualityCrop qualityCrop){
|
||||
Cache.put(new SimpleLocation(worldName, Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2])), new QualityCrop(name, (int) map.get("times"), qualityCrop.getChance(), qualityCrop.isBefore()));
|
||||
//Cache.put(new Location(Bukkit.getWorld(worldName), Double.parseDouble(split[0]), Double.parseDouble(split[1]), Double.parseDouble(split[2])), new QualityCrop(name, (int) map.get("times"), qualityCrop.getChance(), qualityCrop.isBefore()));
|
||||
}else if (fertilizer instanceof RetainingSoil retainingSoil){
|
||||
Cache.put(new SimpleLocation(worldName, Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2])), new RetainingSoil(name, (int) map.get("times"), retainingSoil.getChance(), retainingSoil.isBefore()));
|
||||
//Cache.put(new Location(Bukkit.getWorld(worldName), Double.parseDouble(split[0]), Double.parseDouble(split[1]), Double.parseDouble(split[2])), new RetainingSoil(name, (int) map.get("times"), retainingSoil.getChance(), retainingSoil.isBefore()));
|
||||
}else {
|
||||
AdventureManager.consoleMessage("<red>[CustomCrops] 未知肥料类型错误!</red>");
|
||||
}
|
||||
@@ -80,6 +75,9 @@ public class PotManager {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存数据
|
||||
*/
|
||||
public void saveData(){
|
||||
File file = new File(CustomCrops.instance.getDataFolder(), "data" + File.separator + "pot.yml");
|
||||
YamlConfiguration data = new YamlConfiguration();
|
||||
|
||||
@@ -30,10 +30,14 @@ import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
|
||||
public record SeasonManager(CustomCrops plugin) {
|
||||
public class SeasonManager{
|
||||
|
||||
public static HashMap<String, String> SEASON = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 读取文件中的季节
|
||||
* @param file 季节数据文件
|
||||
*/
|
||||
private YamlConfiguration readData(File file) {
|
||||
if (!file.exists()) {
|
||||
try {
|
||||
@@ -47,6 +51,9 @@ public record SeasonManager(CustomCrops plugin) {
|
||||
return YamlConfiguration.loadConfiguration(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* 载入数据
|
||||
*/
|
||||
public void loadData() {
|
||||
SEASON.clear();
|
||||
YamlConfiguration data = readData(new File(CustomCrops.instance.getDataFolder(), "data" + File.separator + "season.yml"));
|
||||
@@ -68,8 +75,11 @@ public record SeasonManager(CustomCrops plugin) {
|
||||
ConfigReader.Config.worlds.forEach(this::getSeason);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算某个世界的季节
|
||||
* @param world 世界
|
||||
*/
|
||||
public void getSeason(World world) {
|
||||
|
||||
int season = (int) ((world.getFullTime() / 24000L) % (ConfigReader.Season.duration * 4)) / ConfigReader.Season.duration;
|
||||
switch (season) {
|
||||
case 0 -> SEASON.put(world.getName(), "spring");
|
||||
@@ -80,6 +90,9 @@ public record SeasonManager(CustomCrops plugin) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存数据
|
||||
*/
|
||||
public void saveData() {
|
||||
SEASON.forEach((key, value) -> {
|
||||
File file = new File(CustomCrops.instance.getDataFolder(), "data" + File.separator + "season.yml");
|
||||
@@ -94,6 +107,11 @@ public record SeasonManager(CustomCrops plugin) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置季节
|
||||
* @param worldName 世界名
|
||||
* @param season 季节
|
||||
*/
|
||||
public boolean setSeason(String worldName, String season){
|
||||
if (!ConfigReader.Config.worldNames.contains(worldName)){
|
||||
return false;
|
||||
|
||||
@@ -39,13 +39,11 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
public class SprinklerManager {
|
||||
|
||||
public YamlConfiguration data;
|
||||
private final CustomCrops plugin;
|
||||
public static ConcurrentHashMap<Location, Sprinkler> Cache = new ConcurrentHashMap<>();
|
||||
|
||||
public SprinklerManager(CustomCrops plugin){
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* 载入数据
|
||||
*/
|
||||
public void loadData() {
|
||||
File file = new File(CustomCrops.instance.getDataFolder(), "data" + File.separator + "sprinkler.yml");
|
||||
if(!file.exists()){
|
||||
@@ -60,6 +58,9 @@ public class SprinklerManager {
|
||||
this.data = YamlConfiguration.loadConfiguration(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存数据
|
||||
*/
|
||||
public void saveData(){
|
||||
File file = new File(CustomCrops.instance.getDataFolder(), "data" + File.separator + "sprinkler.yml");
|
||||
try{
|
||||
@@ -70,6 +71,9 @@ public class SprinklerManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理无用数据
|
||||
*/
|
||||
public void cleanData(){
|
||||
data.getKeys(false).forEach(world -> {
|
||||
data.getConfigurationSection(world).getKeys(false).forEach(chunk ->{
|
||||
@@ -80,6 +84,9 @@ public class SprinklerManager {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 将hashmap中的数据保存到data中
|
||||
*/
|
||||
public void updateData(){
|
||||
Cache.forEach((location, sprinklerData) -> {
|
||||
String world = location.getWorld().getName();
|
||||
@@ -92,6 +99,10 @@ public class SprinklerManager {
|
||||
Cache.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定世界的洒水器工作
|
||||
* @param worldName 世界名
|
||||
*/
|
||||
public void sprinklerWork(String worldName){
|
||||
Long time1 = System.currentTimeMillis();
|
||||
updateData();
|
||||
@@ -146,6 +157,9 @@ public class SprinklerManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 所有世界的洒水器工作
|
||||
*/
|
||||
public void sprinklerWorkAll(){
|
||||
Long time1 = System.currentTimeMillis();
|
||||
updateData();
|
||||
@@ -202,6 +216,10 @@ public class SprinklerManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转干为湿
|
||||
* @param potLoc 种植盆的位置
|
||||
*/
|
||||
private void waterPot(Location potLoc) {
|
||||
CustomBlock cb = CustomBlock.byAlreadyPlaced(potLoc.getBlock());
|
||||
if(cb != null){
|
||||
|
||||
@@ -33,43 +33,18 @@ public class QualityCrop implements Fertilizer{
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public String getKey() {return this.key;}
|
||||
@Override
|
||||
public int getTimes() {
|
||||
return this.times;
|
||||
}
|
||||
|
||||
public int getTimes() {return this.times;}
|
||||
@Override
|
||||
public void setTimes(int times) {
|
||||
this.times = times;
|
||||
}
|
||||
|
||||
public void setTimes(int times) {this.times = times;}
|
||||
@Override
|
||||
public boolean isBefore() {
|
||||
return this.before;
|
||||
}
|
||||
|
||||
public boolean isBefore() {return this.before;}
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
public String getName() {return this.name;}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setChance(int[] chance) {
|
||||
this.chance = chance;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public int[] getChance() {
|
||||
return chance;
|
||||
}
|
||||
public void setName(String name) {this.name = name;}
|
||||
public void setChance(int[] chance) {this.chance = chance;}
|
||||
public void setKey(String key) {this.key = key;}
|
||||
public int[] getChance() {return chance;}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ public class RetainingSoil implements Fertilizer{
|
||||
private double chance;
|
||||
private String key;
|
||||
private int times;
|
||||
private boolean before;
|
||||
private final boolean before;
|
||||
public String name;
|
||||
|
||||
public RetainingSoil(String key, int times, double chance, boolean before){
|
||||
@@ -33,43 +33,18 @@ public class RetainingSoil implements Fertilizer{
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public String getKey() {return this.key;}
|
||||
@Override
|
||||
public int getTimes() {
|
||||
return this.times;
|
||||
}
|
||||
|
||||
public int getTimes() {return this.times;}
|
||||
@Override
|
||||
public void setTimes(int times) {
|
||||
this.times = times;
|
||||
}
|
||||
|
||||
public void setTimes(int times) {this.times = times;}
|
||||
@Override
|
||||
public boolean isBefore() {
|
||||
return this.before;
|
||||
}
|
||||
|
||||
public boolean isBefore() {return this.before;}
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
public String getName() {return this.name;}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setChance(double chance) {
|
||||
this.chance = chance;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public double getChance() {
|
||||
return chance;
|
||||
}
|
||||
public void setName(String name) {this.name = name;}
|
||||
public void setChance(double chance) {this.chance = chance;}
|
||||
public void setKey(String key) {this.key = key;}
|
||||
public double getChance() {return chance;}
|
||||
}
|
||||
|
||||
@@ -33,43 +33,18 @@ public class SpeedGrow implements Fertilizer{
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public String getKey() {return this.key;}
|
||||
@Override
|
||||
public int getTimes() {
|
||||
return this.times;
|
||||
}
|
||||
|
||||
public int getTimes() {return this.times;}
|
||||
@Override
|
||||
public void setTimes(int times) {
|
||||
this.times = times;
|
||||
}
|
||||
|
||||
public void setTimes(int times) {this.times = times;}
|
||||
@Override
|
||||
public boolean isBefore() {
|
||||
return this.before;
|
||||
}
|
||||
|
||||
public boolean isBefore() {return this.before;}
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
public String getName() {return this.name;}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public double getChance() {
|
||||
return chance;
|
||||
}
|
||||
|
||||
public void setChance(double chance) {
|
||||
this.chance = chance;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
public void setName(String name) {this.name = name;}
|
||||
public double getChance() {return chance;}
|
||||
public void setChance(double chance) {this.chance = chance;}
|
||||
public void setKey(String key) {this.key = key;}
|
||||
}
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
/*
|
||||
* This file is part of helper, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.helper;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
|
||||
import net.momirealms.customcrops.CustomCrops;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Resolves {@link MavenLibrary} annotations for a class, and loads the dependency
|
||||
* into the classloader.
|
||||
*/
|
||||
@NonnullByDefault
|
||||
public final class LibraryLoader {
|
||||
|
||||
@SuppressWarnings("Guava")
|
||||
private static final Supplier<URLClassLoaderAccess> URL_INJECTOR = Suppliers.memoize(() -> URLClassLoaderAccess.create((URLClassLoader) CustomCrops.instance.getClass().getClassLoader()));
|
||||
|
||||
/**
|
||||
* Resolves all {@link MavenLibrary} annotations on the given object.
|
||||
*
|
||||
* @param object the object to load libraries for.
|
||||
*/
|
||||
public static void loadAll(Object object) {
|
||||
loadAll(object.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves all {@link MavenLibrary} annotations on the given class.
|
||||
*
|
||||
* @param clazz the class to load libraries for.
|
||||
*/
|
||||
public static void loadAll(Class<?> clazz) {
|
||||
MavenLibrary[] libs = clazz.getDeclaredAnnotationsByType(MavenLibrary.class);
|
||||
if (libs == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (MavenLibrary lib : libs) {
|
||||
load(lib.groupId(), lib.artifactId(), lib.version(), lib.repo().url());
|
||||
}
|
||||
}
|
||||
|
||||
public static void load(String groupId, String artifactId, String version, String repoUrl) {
|
||||
load(new Dependency(groupId, artifactId, version, repoUrl));
|
||||
}
|
||||
|
||||
public static void load(Dependency d) {
|
||||
//Log.info(String.format("Loading dependency %s:%s:%s from %s", d.getGroupId(), d.getArtifactId(), d.getVersion(), d.getRepoUrl()));
|
||||
String name = d.getArtifactId() + "-" + d.getVersion();
|
||||
|
||||
File saveLocation = new File(getLibFolder(d), name + ".jar");
|
||||
if (!saveLocation.exists()) {
|
||||
|
||||
try {
|
||||
Log.info("Dependency '" + name + "' is not already in the libraries folder. Attempting to download...");
|
||||
URL url = d.getUrl();
|
||||
|
||||
try (InputStream is = url.openStream()) {
|
||||
Files.copy(is, saveLocation.toPath());
|
||||
Log.info("Dependency '" + name + "' successfully downloaded.");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (!saveLocation.exists()) {
|
||||
throw new RuntimeException("Unable to download dependency: " + d.toString());
|
||||
}
|
||||
|
||||
try {
|
||||
URL_INJECTOR.get().addURL(saveLocation.toURI().toURL());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to load dependency: " + saveLocation.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private static File getLibFolder(Dependency dependency) {
|
||||
File pluginDataFolder = CustomCrops.instance.getDataFolder();
|
||||
File serverDir = pluginDataFolder.getParentFile().getParentFile();
|
||||
|
||||
File helperDir = new File(serverDir, "libraries");
|
||||
String[] split = StringUtils.split(dependency.getGroupId(), ".");
|
||||
File jarDir = new File(helperDir, split[0] + File.separator + split[1] + File.separator + dependency.artifactId + File.separator + dependency.version );
|
||||
jarDir.mkdirs();
|
||||
return jarDir;
|
||||
}
|
||||
|
||||
@NonnullByDefault
|
||||
public static final class Dependency {
|
||||
private final String groupId;
|
||||
private final String artifactId;
|
||||
private final String version;
|
||||
private final String repoUrl;
|
||||
|
||||
public Dependency(String groupId, String artifactId, String version, String repoUrl) {
|
||||
this.groupId = Objects.requireNonNull(groupId, "groupId");
|
||||
this.artifactId = Objects.requireNonNull(artifactId, "artifactId");
|
||||
this.version = Objects.requireNonNull(version, "version");
|
||||
this.repoUrl = Objects.requireNonNull(repoUrl, "repoUrl");
|
||||
}
|
||||
|
||||
public String getGroupId() {
|
||||
return this.groupId;
|
||||
}
|
||||
|
||||
public String getArtifactId() {
|
||||
return this.artifactId;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
public String getRepoUrl() {
|
||||
return this.repoUrl;
|
||||
}
|
||||
|
||||
public URL getUrl() throws MalformedURLException {
|
||||
String repo = this.repoUrl;
|
||||
if (!repo.endsWith("/")) {
|
||||
repo += "/";
|
||||
}
|
||||
repo += "%s/%s/%s/%s-%s.jar";
|
||||
|
||||
String url = String.format(repo, this.groupId.replace(".", "/"), this.artifactId, this.version, this.artifactId, this.version);
|
||||
return new URL(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) return true;
|
||||
if (!(o instanceof Dependency)) return false;
|
||||
final Dependency other = (Dependency) o;
|
||||
return this.getGroupId().equals(other.getGroupId()) &&
|
||||
this.getArtifactId().equals(other.getArtifactId()) &&
|
||||
this.getVersion().equals(other.getVersion()) &&
|
||||
this.getRepoUrl().equals(other.getRepoUrl());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int PRIME = 59;
|
||||
int result = 1;
|
||||
result = result * PRIME + this.getGroupId().hashCode();
|
||||
result = result * PRIME + this.getArtifactId().hashCode();
|
||||
result = result * PRIME + this.getVersion().hashCode();
|
||||
result = result * PRIME + this.getRepoUrl().hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LibraryLoader.Dependency(" +
|
||||
"groupId=" + this.getGroupId() + ", " +
|
||||
"artifactId=" + this.getArtifactId() + ", " +
|
||||
"version=" + this.getVersion() + ", " +
|
||||
"repoUrl=" + this.getRepoUrl() + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* This file is part of helper, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.helper;
|
||||
|
||||
import net.momirealms.customcrops.CustomCrops;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Utility for quickly accessing a logger instance without using {@link Bukkit#getLogger()}
|
||||
*/
|
||||
public final class Log {
|
||||
|
||||
public static void info(@Nonnull String s) {
|
||||
CustomCrops.instance.getLogger().info(s);
|
||||
}
|
||||
|
||||
public static void warn(@Nonnull String s) {
|
||||
CustomCrops.instance.getLogger().warning(s);
|
||||
}
|
||||
|
||||
public static void severe(@Nonnull String s) {
|
||||
CustomCrops.instance.getLogger().severe(s);
|
||||
}
|
||||
|
||||
public static void warn(@Nonnull String s, Throwable t) {
|
||||
CustomCrops.instance.getLogger().log(Level.WARNING, s, t);
|
||||
}
|
||||
|
||||
public static void severe(@Nonnull String s, Throwable t) {
|
||||
CustomCrops.instance.getLogger().log(Level.SEVERE, s, t);
|
||||
}
|
||||
|
||||
private Log() {
|
||||
throw new UnsupportedOperationException("This class cannot be instantiated");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* This file is part of helper, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.helper;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Annotation to indicate the required libraries for a class.
|
||||
*/
|
||||
@Documented
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface MavenLibraries {
|
||||
|
||||
@Nonnull
|
||||
MavenLibrary[] value() default {};
|
||||
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* This file is part of helper, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.helper;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Repeatable;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Annotation to indicate a required library for a class.
|
||||
*/
|
||||
@Documented
|
||||
@Repeatable(MavenLibraries.class)
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface MavenLibrary {
|
||||
|
||||
/**
|
||||
* The group id of the library
|
||||
*
|
||||
* @return the group id of the library
|
||||
*/
|
||||
@Nonnull
|
||||
String groupId();
|
||||
|
||||
/**
|
||||
* The artifact id of the library
|
||||
*
|
||||
* @return the artifact id of the library
|
||||
*/
|
||||
@Nonnull
|
||||
String artifactId();
|
||||
|
||||
/**
|
||||
* The version of the library
|
||||
*
|
||||
* @return the version of the library
|
||||
*/
|
||||
@Nonnull
|
||||
String version();
|
||||
|
||||
/**
|
||||
* The repo where the library can be obtained from
|
||||
*
|
||||
* @return the repo where the library can be obtained from
|
||||
*/
|
||||
@Nonnull
|
||||
Repository repo() default @Repository(url = "https://repo1.maven.org/maven2");
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* This file is part of helper, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.helper;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.meta.TypeQualifierDefault;
|
||||
|
||||
@Nonnull
|
||||
@Documented
|
||||
@TypeQualifierDefault({
|
||||
ElementType.FIELD,
|
||||
ElementType.METHOD,
|
||||
ElementType.PARAMETER
|
||||
})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface NonnullByDefault {
|
||||
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* This file is part of helper, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.helper;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Represents a maven repository.
|
||||
*/
|
||||
@Documented
|
||||
@Target(ElementType.LOCAL_VARIABLE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Repository {
|
||||
|
||||
/**
|
||||
* Gets the base url of the repository.
|
||||
*
|
||||
* @return the base url of the repository
|
||||
*/
|
||||
@Nonnull
|
||||
String url();
|
||||
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* This file is part of helper, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.helper;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Provides access to {@link URLClassLoader}#addURL.
|
||||
*/
|
||||
public abstract class URLClassLoaderAccess {
|
||||
|
||||
/**
|
||||
* Creates a {@link URLClassLoaderAccess} for the given class loader.
|
||||
*
|
||||
* @param classLoader the class loader
|
||||
* @return the access object
|
||||
*/
|
||||
static URLClassLoaderAccess create(URLClassLoader classLoader) {
|
||||
if (Unsafe.isSupported()) {
|
||||
return new Unsafe(classLoader);
|
||||
} else {
|
||||
return Noop.INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
private final URLClassLoader classLoader;
|
||||
|
||||
protected URLClassLoaderAccess(URLClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds the given URL to the class loader.
|
||||
*
|
||||
* @param url the URL to add
|
||||
*/
|
||||
public abstract void addURL(@Nonnull URL url);
|
||||
|
||||
/**
|
||||
* Accesses using sun.misc.Unsafe, supported on Java 9+.
|
||||
*
|
||||
* @author Vaishnav Anil (https://github.com/slimjar/slimjar)
|
||||
*/
|
||||
private static class Unsafe extends URLClassLoaderAccess {
|
||||
private static final sun.misc.Unsafe UNSAFE;
|
||||
|
||||
static {
|
||||
sun.misc.Unsafe unsafe;
|
||||
try {
|
||||
Field unsafeField = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
|
||||
unsafeField.setAccessible(true);
|
||||
unsafe = (sun.misc.Unsafe) unsafeField.get(null);
|
||||
} catch (Throwable t) {
|
||||
unsafe = null;
|
||||
}
|
||||
UNSAFE = unsafe;
|
||||
}
|
||||
|
||||
private static boolean isSupported() {
|
||||
return UNSAFE != null;
|
||||
}
|
||||
|
||||
private final Collection<URL> unopenedURLs;
|
||||
private final Collection<URL> pathURLs;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Unsafe(URLClassLoader classLoader) {
|
||||
super(classLoader);
|
||||
|
||||
Collection<URL> unopenedURLs;
|
||||
Collection<URL> pathURLs;
|
||||
try {
|
||||
Object ucp = fetchField(URLClassLoader.class, classLoader, "ucp");
|
||||
unopenedURLs = (Collection<URL>) fetchField(ucp.getClass(), ucp, "unopenedUrls");
|
||||
pathURLs = (Collection<URL>) fetchField(ucp.getClass(), ucp, "path");
|
||||
} catch (Throwable e) {
|
||||
unopenedURLs = null;
|
||||
pathURLs = null;
|
||||
}
|
||||
this.unopenedURLs = unopenedURLs;
|
||||
this.pathURLs = pathURLs;
|
||||
}
|
||||
|
||||
private static Object fetchField(final Class<?> clazz, final Object object, final String name) throws NoSuchFieldException {
|
||||
Field field = clazz.getDeclaredField(name);
|
||||
long offset = UNSAFE.objectFieldOffset(field);
|
||||
return UNSAFE.getObject(object, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addURL(@Nonnull URL url) {
|
||||
this.unopenedURLs.add(url);
|
||||
this.pathURLs.add(url);
|
||||
}
|
||||
}
|
||||
|
||||
private static class Noop extends URLClassLoaderAccess {
|
||||
private static final Noop INSTANCE = new Noop();
|
||||
|
||||
private Noop() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addURL(@Nonnull URL url) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* 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
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.integrations.skill;
|
||||
|
||||
import com.archyx.aureliumskills.api.AureliumAPI;
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* 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
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.integrations.skill;
|
||||
|
||||
import net.Indyuce.mmocore.experience.EXPSource;
|
||||
|
||||
@@ -1,7 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* 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
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.integrations.skill;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface SkillXP {
|
||||
void addXp(Player player, double amount);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* 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
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.integrations.skill;
|
||||
|
||||
import com.gmail.nossr50.api.ExperienceAPI;
|
||||
|
||||
@@ -115,7 +115,6 @@ public class BreakBlock implements Listener {
|
||||
normalDrop(cropInstance, random, itemLoc, world);
|
||||
return null;
|
||||
});
|
||||
|
||||
}
|
||||
} else {
|
||||
Bukkit.getScheduler().callSyncMethod(CustomCrops.instance, ()-> {
|
||||
@@ -124,7 +123,6 @@ public class BreakBlock implements Listener {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
else if(namespacedId.equalsIgnoreCase(ConfigReader.Basic.watered_pot) || namespacedId.equalsIgnoreCase(ConfigReader.Basic.pot)){
|
||||
@@ -138,9 +136,8 @@ public class BreakBlock implements Listener {
|
||||
if(CustomBlock.byAlreadyPlaced(blockUp) != null){
|
||||
CustomBlock customBlock = CustomBlock.byAlreadyPlaced(blockUp);
|
||||
String cropNamespacedId = customBlock.getNamespacedID();
|
||||
if(cropNamespacedId.contains("_stage_")){
|
||||
if(cropNamespacedId.contains("_stage_") && !cropNamespacedId.equals(ConfigReader.Basic.dead)){
|
||||
CustomBlock.remove(location);
|
||||
if (cropNamespacedId.equals(ConfigReader.Basic.dead)) return;
|
||||
if (ConfigReader.Config.quality){
|
||||
String[] cropNameList = StringUtils.split(StringUtils.split(cropNamespacedId, ":")[1], "_");
|
||||
int nextStage = Integer.parseInt(cropNameList[2]) + 1;
|
||||
@@ -183,6 +180,13 @@ public class BreakBlock implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 没有品质肥料下的普通掉落
|
||||
* @param cropInstance 农作物
|
||||
* @param random 随机农作物数量
|
||||
* @param itemLoc 掉落物位置
|
||||
* @param world 世界
|
||||
*/
|
||||
static void normalDrop(CropInstance cropInstance, int random, Location itemLoc, World world) {
|
||||
for (int i = 0; i < random; i++){
|
||||
double ran = Math.random();
|
||||
|
||||
@@ -31,7 +31,6 @@ import net.momirealms.customcrops.utils.Sprinkler;
|
||||
import net.momirealms.customcrops.utils.WateringCan;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -160,6 +159,15 @@ public class InteractEntity implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取某个洒水器的水量
|
||||
* @param location 洒水器位置
|
||||
* @param world 世界
|
||||
* @param x 坐标
|
||||
* @param z 坐标
|
||||
* @param sprinkler 洒水器类型
|
||||
* @return 水量
|
||||
*/
|
||||
private int getCurrentWater(Location location, String world, int x, int z, Sprinkler sprinkler) {
|
||||
int currentWater;
|
||||
if (sprinkler != null){
|
||||
|
||||
@@ -70,8 +70,7 @@ public class RightClick implements Listener {
|
||||
Action action = event.getAction();
|
||||
if (action == Action.RIGHT_CLICK_AIR || action == Action.RIGHT_CLICK_BLOCK){
|
||||
ItemStack itemStack = event.getItem();
|
||||
if (itemStack != null){
|
||||
if (itemStack.getType() == Material.AIR) return;
|
||||
if (itemStack != null && itemStack.getType() != Material.AIR){
|
||||
NBTItem nbtItem = new NBTItem(itemStack);
|
||||
NBTCompound nbtCompound = nbtItem.getCompound("itemsadder");
|
||||
if (nbtCompound != null){
|
||||
@@ -145,9 +144,8 @@ public class RightClick implements Listener {
|
||||
}
|
||||
return;
|
||||
}
|
||||
Optional<WateringCan> can = Optional.ofNullable(ConfigReader.CANS.get(id));
|
||||
if (can.isPresent()){
|
||||
WateringCan wateringCan = can.get();
|
||||
WateringCan wateringCan = ConfigReader.CANS.get(id);
|
||||
if (wateringCan != null){
|
||||
int water = nbtItem.getInteger("WaterAmount");
|
||||
List<Block> lineOfSight = player.getLineOfSight(null, 5);
|
||||
for (Block block : lineOfSight) {
|
||||
@@ -226,9 +224,8 @@ public class RightClick implements Listener {
|
||||
}
|
||||
return;
|
||||
}
|
||||
Optional<Fertilizer> fertilize = Optional.ofNullable(ConfigReader.FERTILIZERS.get(id));
|
||||
if (fertilize.isPresent() && action == Action.RIGHT_CLICK_BLOCK){
|
||||
Fertilizer fertilizerConfig = fertilize.get();
|
||||
Fertilizer fertilizerConfig = ConfigReader.FERTILIZERS.get(id);
|
||||
if (fertilizerConfig != null && action == Action.RIGHT_CLICK_BLOCK){
|
||||
Block block = event.getClickedBlock();
|
||||
CustomBlock customBlock = CustomBlock.byAlreadyPlaced(block);
|
||||
if (customBlock == null) return;
|
||||
@@ -264,8 +261,8 @@ public class RightClick implements Listener {
|
||||
}
|
||||
return;
|
||||
}
|
||||
Optional<Sprinkler> sprinkler = Optional.ofNullable(ConfigReader.SPRINKLERS.get(id));
|
||||
if (sprinkler.isPresent() && action == Action.RIGHT_CLICK_BLOCK && event.getBlockFace() == BlockFace.UP){
|
||||
Sprinkler sprinkler = ConfigReader.SPRINKLERS.get(id);
|
||||
if (sprinkler != null && action == Action.RIGHT_CLICK_BLOCK && event.getBlockFace() == BlockFace.UP){
|
||||
Location location = event.getClickedBlock().getLocation();
|
||||
for (Integration integration : ConfigReader.Config.integration){
|
||||
if (!integration.canPlace(location, player)) return;
|
||||
@@ -277,10 +274,10 @@ public class RightClick implements Listener {
|
||||
AdventureManager.playerMessage(player, ConfigReader.Message.prefix + ConfigReader.Message.sprinkler_limit.replace("{max}", String.valueOf(ConfigReader.Config.sprinklerLimit)));
|
||||
return;
|
||||
}
|
||||
Sprinkler sprinklerData = new Sprinkler(sprinkler.get().getRange(), 0);
|
||||
Sprinkler sprinklerData = new Sprinkler(sprinkler.getRange(), 0);
|
||||
itemStack.setAmount(itemStack.getAmount() - 1);
|
||||
SprinklerManager.Cache.put(location.add(0,1,0), sprinklerData);
|
||||
IAFurniture.placeFurniture(sprinkler.get().getNamespacedID_2(),location);
|
||||
IAFurniture.placeFurniture(sprinkler.getNamespacedID_2(),location);
|
||||
AdventureManager.playerSound(player, ConfigReader.Sounds.placeSprinklerSource, ConfigReader.Sounds.placeSprinklerKey);
|
||||
return;
|
||||
}
|
||||
@@ -318,17 +315,27 @@ public class RightClick implements Listener {
|
||||
}
|
||||
}
|
||||
else if(ConfigReader.Config.rightClickHarvest && !ConfigReader.Config.needEmptyHand){
|
||||
rightClickHarvest(event, player);
|
||||
Block block = event.getClickedBlock();
|
||||
if (block != null){
|
||||
rightClickHarvest(block, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ConfigReader.Config.rightClickHarvest && action == Action.RIGHT_CLICK_BLOCK) {
|
||||
rightClickHarvest(event, player);
|
||||
Block block = event.getClickedBlock();
|
||||
if (block != null){
|
||||
rightClickHarvest(block, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void rightClickHarvest(PlayerInteractEvent event, Player player) {
|
||||
Block block = event.getClickedBlock();
|
||||
/**
|
||||
* 右键收获判定
|
||||
* @param block 农作物方块
|
||||
* @param player 玩家
|
||||
*/
|
||||
private void rightClickHarvest(Block block, Player player) {
|
||||
Location location = block.getLocation();
|
||||
CustomBlock customBlock = CustomBlock.byAlreadyPlaced(block);
|
||||
if (customBlock == null) return;
|
||||
@@ -357,6 +364,11 @@ public class RightClick implements Listener {
|
||||
if (ConfigReader.Config.skillXP != null && cropInstance.getSkillXP() != 0){
|
||||
ConfigReader.Config.skillXP.addXp(player, cropInstance.getSkillXP());
|
||||
}
|
||||
if (cropInstance.doesDropIALoot()){
|
||||
customBlock.getLoot().forEach(itemStack -> {
|
||||
location.getWorld().dropItem(location.clone().add(0.5,0.2,0.5), itemStack);
|
||||
});
|
||||
}
|
||||
if (fertilizer != null){
|
||||
if (fertilizer instanceof QualityCrop qualityCrop){
|
||||
int[] weights = qualityCrop.getChance();
|
||||
@@ -398,6 +410,11 @@ public class RightClick implements Listener {
|
||||
coolDown.remove(event.getPlayer());
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加肥料
|
||||
* @param fertilizerConfig 肥料配置
|
||||
* @param location 种植盆位置
|
||||
*/
|
||||
private void addFertilizer(Fertilizer fertilizerConfig, Location location) {
|
||||
if (fertilizerConfig instanceof QualityCrop config){
|
||||
QualityCrop qualityCrop = new QualityCrop(config.getKey(), config.getTimes(), config.getChance(), config.isBefore());
|
||||
@@ -411,6 +428,13 @@ public class RightClick implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 水壶浇水判定
|
||||
* @param width 宽度
|
||||
* @param length 长度
|
||||
* @param location 位置
|
||||
* @param yaw 视角
|
||||
*/
|
||||
private void waterPot(int width, int length, Location location, float yaw){
|
||||
if (ConfigReader.Config.hasParticle){
|
||||
location.getWorld().spawnParticle(Particle.WATER_SPLASH, location.clone().add(0.5,1.2,0.5),15,0.1,0.1, 0.1);
|
||||
|
||||
@@ -31,6 +31,10 @@ import java.time.Duration;
|
||||
|
||||
public class AdventureManager {
|
||||
|
||||
/**
|
||||
* 发送控制台信息
|
||||
* @param s 文本
|
||||
*/
|
||||
public static void consoleMessage(String s) {
|
||||
Audience au = CustomCrops.adventure.sender(Bukkit.getConsoleSender());
|
||||
MiniMessage mm = MiniMessage.miniMessage();
|
||||
@@ -38,6 +42,11 @@ public class AdventureManager {
|
||||
au.sendMessage(parsed);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送玩家信息
|
||||
* @param player 玩家
|
||||
* @param s 文本
|
||||
*/
|
||||
public static void playerMessage(Player player, String s) {
|
||||
Audience au = CustomCrops.adventure.player(player);
|
||||
MiniMessage mm = MiniMessage.miniMessage();
|
||||
@@ -45,6 +54,15 @@ public class AdventureManager {
|
||||
au.sendMessage(parsed);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送玩家标题
|
||||
* @param player 玩家
|
||||
* @param s1 主标题
|
||||
* @param s2 副标题
|
||||
* @param in 淡入时间
|
||||
* @param duration 停留时间
|
||||
* @param out 淡出时间
|
||||
*/
|
||||
public static void playerTitle(Player player, String s1, String s2, int in, int duration, int out) {
|
||||
Audience au = CustomCrops.adventure.player(player);
|
||||
MiniMessage mm = MiniMessage.miniMessage();
|
||||
@@ -53,12 +71,23 @@ public class AdventureManager {
|
||||
au.showTitle(title);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送动作消息
|
||||
* @param player 玩家
|
||||
* @param s 文本
|
||||
*/
|
||||
public static void playerActionbar(Player player, String s) {
|
||||
Audience au = CustomCrops.adventure.player(player);
|
||||
MiniMessage mm = MiniMessage.miniMessage();
|
||||
au.sendActionBar(mm.deserialize(s));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送声音
|
||||
* @param player 玩家
|
||||
* @param source 来源
|
||||
* @param key 键
|
||||
*/
|
||||
public static void playerSound(Player player, Sound.Source source, Key key) {
|
||||
Sound sound = Sound.sound(key, source, 1, 1);
|
||||
Audience au = CustomCrops.adventure.player(player);
|
||||
|
||||
@@ -30,6 +30,9 @@ import java.util.List;
|
||||
|
||||
public class BackUp {
|
||||
|
||||
/**
|
||||
* 备份全部文件
|
||||
*/
|
||||
public static void backUpData(){
|
||||
|
||||
List<String> files = Arrays.asList("crop","sprinkler","pot","season");
|
||||
@@ -49,6 +52,12 @@ public class BackUp {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制某个文件
|
||||
* @param file_from 源文件
|
||||
* @param file_to 目标文件
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
private static void backUp(File file_from, File file_to) throws IOException {
|
||||
if(!file_to.exists()){
|
||||
file_to.getParentFile().mkdirs();
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
package net.momirealms.customcrops.utils;
|
||||
|
||||
import net.momirealms.customcrops.integrations.skill.SkillXP;
|
||||
import net.momirealms.customcrops.requirements.Requirement;
|
||||
|
||||
import java.util.List;
|
||||
@@ -35,7 +34,9 @@ public class CropInstance {
|
||||
private String quality_2;
|
||||
private String quality_3;
|
||||
private double skillXP;
|
||||
private boolean dropIALoot;
|
||||
private List<String> commands;
|
||||
private double growChance;
|
||||
|
||||
public CropInstance(int min, int max){
|
||||
this.min = min;
|
||||
@@ -58,6 +59,8 @@ public class CropInstance {
|
||||
public int getMin() { return min; }
|
||||
public List<String> getCommands() { return commands; }
|
||||
public double getSkillXP() {return skillXP;}
|
||||
public boolean doesDropIALoot() {return dropIALoot;}
|
||||
public double getGrowChance() {return growChance;}
|
||||
|
||||
public void setReturnStage(String stage){ this.returnStage = stage; }
|
||||
public void setGiant(String giant) { this.giant = giant; }
|
||||
@@ -69,4 +72,6 @@ public class CropInstance {
|
||||
public void setQuality_3(String quality_3) { this.quality_3 = quality_3; }
|
||||
public void setCommands(List<String> commands) { this.commands = commands; }
|
||||
public void setSkillXP(double skillXP) {this.skillXP = skillXP;}
|
||||
public void setDropIALoot(boolean dropIALoot) {this.dropIALoot = dropIALoot;}
|
||||
public void setGrowChance(double growChance) {this.growChance = growChance;}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,13 @@ public class HoloUtil {
|
||||
|
||||
public static HashMap<Location, Entity> cache = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 对指定玩家展示在指定位置的盔甲架
|
||||
* @param text 文本
|
||||
* @param player 玩家
|
||||
* @param location 位置
|
||||
* @param duration 持续时间
|
||||
*/
|
||||
public static void showHolo(String text, Player player, Location location, int duration){
|
||||
|
||||
ArmorStand entity = location.getWorld().spawn(location, ArmorStand.class, a -> {
|
||||
|
||||
@@ -26,10 +26,21 @@ import org.bukkit.entity.Entity;
|
||||
|
||||
public class IAFurniture {
|
||||
|
||||
/**
|
||||
* 在指定位置放置家具
|
||||
* @param name 物品名
|
||||
* @param location 位置
|
||||
*/
|
||||
public static void placeFurniture(String name, Location location){
|
||||
CustomFurniture.spawn(name, location.getBlock());
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断指定位置的盔甲架是不是洒水器
|
||||
* @param location 位置
|
||||
* @param world 世界
|
||||
* @return 是/否
|
||||
*/
|
||||
public static boolean getFromLocation(Location location, World world){
|
||||
for(Entity entity : world.getNearbyEntities(location,0,0,0)){
|
||||
if(entity instanceof ArmorStand armorStand){
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) <2022> <XiaoMoMi>
|
||||
*
|
||||
* 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
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.utils;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NBTItem;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class NBTUtil {
|
||||
|
||||
private final Map<?,?> nbt;
|
||||
private final NBTItem nbtItem;
|
||||
|
||||
public NBTUtil(Map<?,?> nbt, ItemStack itemStack){
|
||||
this.nbt = nbt;
|
||||
this.nbtItem = new NBTItem(itemStack);
|
||||
}
|
||||
|
||||
public NBTItem getNBTItem(){
|
||||
nbt.keySet().forEach(key -> {
|
||||
if (nbt.get(key) instanceof Map<?,?> map){
|
||||
nbtItem.addCompound((String) key);
|
||||
setTags(map, nbtItem.getCompound((String) key));
|
||||
}else {
|
||||
setNbt(nbtItem, (String) key, nbt.get(key));
|
||||
}
|
||||
});
|
||||
return this.nbtItem;
|
||||
}
|
||||
|
||||
private void setTags(Map<?,?> map, NBTCompound nbtCompound){
|
||||
map.keySet().forEach(key -> {
|
||||
if (map.get(key) instanceof Map map2){
|
||||
nbtCompound.addCompound((String) key);
|
||||
setTags(map2, nbtCompound.getCompound((String) key));
|
||||
}else {
|
||||
setNbt(nbtCompound, (String) key, map.get(key));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setNbt(NBTCompound nbtCompound, String key, Object value){
|
||||
if (value instanceof String string){
|
||||
if (string.startsWith("(Int) ")){
|
||||
nbtCompound.setInteger(key, Integer.valueOf(string.substring(6)));
|
||||
}else if (string.startsWith("(String) ")){
|
||||
nbtCompound.setString(key, string.substring(9));
|
||||
}else if (string.startsWith("(Long) ")){
|
||||
nbtCompound.setLong(key, Long.valueOf(string.substring(7)));
|
||||
}else if (string.startsWith("(Float) ")){
|
||||
nbtCompound.setFloat(key, Float.valueOf(string.substring(8)));
|
||||
} else if (string.startsWith("(Double) ")){
|
||||
nbtCompound.setDouble(key, Double.valueOf(string.substring(9)));
|
||||
}else if (string.startsWith("(Short) ")){
|
||||
nbtCompound.setShort(key, Short.valueOf(string.substring(8)));
|
||||
}else if (string.startsWith("(Boolean) ")){
|
||||
nbtCompound.setBoolean(key, Boolean.valueOf(string.substring(10)));
|
||||
}else if (string.startsWith("(UUID) ")){
|
||||
nbtCompound.setUUID(key, UUID.fromString(string.substring(7)));
|
||||
}else if (string.startsWith("(Byte) ")){
|
||||
nbtCompound.setByte(key, Byte.valueOf(string.substring(7)));
|
||||
}else {
|
||||
nbtCompound.setString(key, string);
|
||||
}
|
||||
}else {
|
||||
try {
|
||||
nbtCompound.setInteger(key, (Integer) value);
|
||||
}catch (ClassCastException e){
|
||||
e.printStackTrace();
|
||||
AdventureManager.consoleMessage("<red>[CustomCrops] 非Int类型数字必须加上强制转换标识!</red>");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,25 +35,19 @@ public class SimpleLocation {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将Location转换为SimpleLocation
|
||||
* @param location Location
|
||||
* @return SimpleLocation
|
||||
*/
|
||||
public static SimpleLocation fromLocation(Location location){
|
||||
return new SimpleLocation(location.getWorld().getName(), location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public String getWorldName() {
|
||||
return worldName;
|
||||
}
|
||||
public int getX() {return x;}
|
||||
public int getZ() {return z;}
|
||||
public int getY() {return y;}
|
||||
public String getWorldName() {return worldName;}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
@@ -29,29 +29,13 @@ public class Sprinkler {
|
||||
this.range = range;
|
||||
}
|
||||
|
||||
public int getWater() {
|
||||
return water;
|
||||
}
|
||||
public String getNamespacedID_1() {
|
||||
return namespacedID_1;
|
||||
}
|
||||
public String getNamespacedID_2() {
|
||||
return namespacedID_2;
|
||||
}
|
||||
public int getRange() {
|
||||
return range;
|
||||
}
|
||||
public int getWater() {return water;}
|
||||
public String getNamespacedID_1() {return namespacedID_1;}
|
||||
public String getNamespacedID_2() {return namespacedID_2;}
|
||||
public int getRange() {return range;}
|
||||
|
||||
public void setRange(int range) {
|
||||
this.range = range;
|
||||
}
|
||||
public void setNamespacedID_2(String namespacedID_2) {
|
||||
this.namespacedID_2 = namespacedID_2;
|
||||
}
|
||||
public void setNamespacedID_1(String namespacedID_1) {
|
||||
this.namespacedID_1 = namespacedID_1;
|
||||
}
|
||||
public void setWater(int water) {
|
||||
this.water = water;
|
||||
}
|
||||
public void setRange(int range) {this.range = range;}
|
||||
public void setNamespacedID_2(String namespacedID_2) {this.namespacedID_2 = namespacedID_2;}
|
||||
public void setNamespacedID_1(String namespacedID_1) {this.namespacedID_1 = namespacedID_1;}
|
||||
public void setWater(int water) {this.water = water;}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user