diff --git a/README.md b/README.md index 581810e..e2e8119 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # InterestingFish -**Compatible with Minecraft 1.13+ (Tested on Minecraft 1.18)** +**Compatible with Minecraft 1.17+ (Tested on Minecraft 1.18)** This is a continuation / maintained version of the original plugin created by lazertester from Shotbow network. The original has not been updated since 2013. diff --git a/build.gradle.kts b/build.gradle.kts index 9f1b0d4..fcc8bac 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,8 +1,9 @@ -import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - id("java") - id("com.github.johnrengelman.shadow") version "7.1.0" + kotlin("jvm") version "1.6.10" + id("org.jlleitschuh.gradle.ktlint") version "10.2.1" + id("com.github.johnrengelman.shadow") version "7.1.2" } group = "net.shotbow" @@ -10,7 +11,7 @@ version = "1.18" java { toolchain { - languageVersion.set(JavaLanguageVersion.of(8)) + languageVersion.set(JavaLanguageVersion.of(11)) } } @@ -21,14 +22,21 @@ repositories { } dependencies { - compileOnly(group = "org.spigotmc", name = "spigot-api", version = "1.13-R0.1-SNAPSHOT") - implementation(group = "net.kyori", name = "adventure-platform-bukkit", version = "4.0.1") - implementation(group = "net.kyori", name = "adventure-text-minimessage", version = "4.1.0-SNAPSHOT") + compileOnly(group = "org.spigotmc", name = "spigot-api", version = "1.17.1-R0.1-SNAPSHOT") + implementation(group = "net.kyori", name = "adventure-platform-bukkit", version = "4.1.0") + implementation(group = "net.kyori", name = "adventure-text-minimessage", version = "4.10.1") + implementation(group = "com.uchuhimo", name = "konf", version = "1.1.2") + runtimeOnly(kotlin("reflect")) } defaultTasks("clean", "build") tasks { + wrapper { + gradleVersion = "7.4.1" + distributionType = Wrapper.DistributionType.ALL + } + processResources { val placeholders = mapOf( "name" to project.name, @@ -45,16 +53,23 @@ tasks { } shadowJar { + dependencies { + include(dependency("net.kyori:.*")) + } + + relocate("net.kyori", "${project.group}.${project.name.toLowerCase()}.libraries.net.kyori") + minimize() archiveFileName.set("${project.name}.jar") } - register("configureShadowRelocation") { - target = shadowJar.get() - prefix = "${project.group}.${project.name.toLowerCase()}.libraries" + build { + dependsOn(shadowJar) } - build { - dependsOn(shadowJar).dependsOn("configureShadowRelocation") + withType { + kotlinOptions { + jvmTarget = "11" + } } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index fbce071..d7e66b5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew.bat b/gradlew.bat index 107acd3..ac1b06f 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,89 +1,89 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/main/java/net/shotbow/interestingfish/FishInfoFactory.java b/src/main/java/net/shotbow/interestingfish/FishInfoFactory.java deleted file mode 100644 index f0f462f..0000000 --- a/src/main/java/net/shotbow/interestingfish/FishInfoFactory.java +++ /dev/null @@ -1,72 +0,0 @@ -package net.shotbow.interestingfish; - -import net.kyori.adventure.text.minimessage.MiniMessage; -import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; -import net.shotbow.interestingfish.config.InterestingConfig; -import net.shotbow.interestingfish.objects.Breed; -import net.shotbow.interestingfish.objects.Descriptor; -import net.shotbow.interestingfish.objects.FishInfo; -import org.bukkit.ChatColor; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Random; - -/** - * User: Austin - * Date: 5/18/13 - * Time: 1:21 AM - * (c) lazertester - */ -public class FishInfoFactory { - - private final List weightedDescriptors = new ArrayList<>(); - private final HashMap descriptorIndex = new HashMap<>(); - - private final List weightedBreeds = new ArrayList<>(); - private final HashMap breedIndex = new HashMap<>(); - - private final Random random = new Random(); - private final InterestingConfig config; - - private final MiniMessage miniMessage = MiniMessage.get(); - private final LegacyComponentSerializer legacyHexSerializer = LegacyComponentSerializer.builder().hexColors().useUnusualXRepeatedCharacterHexFormat().build(); - - public FishInfoFactory(InterestingConfig config) { - this.config = config; - for (Descriptor descriptor : config.getDescriptors()) { - descriptorIndex.put(descriptor.getText(), descriptor); - for (int i = 0; i <= descriptor.getRollWeight(); i++) - weightedDescriptors.add(descriptor.getText()); - } - for (Breed breed : config.getBreeds()) { - breedIndex.put(breed.getText(), breed); - for (int i = 0; i <= breed.getRollWeight(); i++) - weightedBreeds.add(breed.getText()); - } - InterestingFish.log(descriptorIndex.size() + " Descriptors & " + breedIndex.size() + " Breeds loaded"); - - } - - public FishInfo makeNewFishInfo() { - StringBuilder nameBuilder = new StringBuilder(); - double weight = config.baseWeight; - if (random.nextInt(100) < config.percentDescriptorChance) { - Descriptor descriptor = descriptorIndex.get(weightedDescriptors.get(random.nextInt(weightedDescriptors.size()))); - nameBuilder.append(parseColors(descriptor.getText())).append(ChatColor.RESET).append(" "); - weight += descriptor.getMinWeightModifier() + random.nextDouble() * descriptor.getMaxWeightModifier() - descriptor.getMinWeightModifier(); - } - Breed breed = breedIndex.get(weightedBreeds.get(random.nextInt(weightedBreeds.size()))); - weight += breed.getMinWeightModifier() + random.nextDouble() * breed.getMaxWeightModifier() - breed.getMinWeightModifier(); - nameBuilder.append(parseColors(breed.getText())); - if (weight < config.minWeight) - weight = config.minWeight; - return new FishInfo(nameBuilder.toString(), weight); - } - - public String parseColors(String text) { - return legacyHexSerializer.serialize(miniMessage.parse(text.replace('&', ChatColor.COLOR_CHAR))); - } - -} diff --git a/src/main/java/net/shotbow/interestingfish/InterestingFish.java b/src/main/java/net/shotbow/interestingfish/InterestingFish.java deleted file mode 100644 index 67bac62..0000000 --- a/src/main/java/net/shotbow/interestingfish/InterestingFish.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.shotbow.interestingfish; - -import net.shotbow.interestingfish.config.InterestingConfig; -import net.shotbow.interestingfish.listeners.FishListener; -import net.shotbow.interestingfish.listeners.InteractListener; -import org.bukkit.Bukkit; -import org.bukkit.plugin.java.JavaPlugin; - -/** - * User: Austin - * Date: 5/18/13 - * Time: 12:43 AM - * (c) lazertester - */ -public class InterestingFish extends JavaPlugin { - - public static void log(String message) { - Bukkit.getLogger().info("[InterestingFish] " + message); - } - - public void onEnable() { - InterestingConfig config = new InterestingConfig(getDataFolder().getPath()); - config.initialize(); - final FishInfoFactory fishInfoFactory = new FishInfoFactory(config); - Bukkit.getPluginManager().registerEvents(new FishListener(fishInfoFactory, config), this); - Bukkit.getPluginManager().registerEvents(new InteractListener(config), this); - log("InterestingFish is enabled!"); - } -} diff --git a/src/main/java/net/shotbow/interestingfish/config/ConfigObject.java b/src/main/java/net/shotbow/interestingfish/config/ConfigObject.java deleted file mode 100644 index e0b2109..0000000 --- a/src/main/java/net/shotbow/interestingfish/config/ConfigObject.java +++ /dev/null @@ -1,85 +0,0 @@ -package net.shotbow.interestingfish.config; - -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.Yaml; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.LinkedHashMap; -import java.util.Map; - -// Shamelessly stolen and adapted from md_5's BungeeCord project, -// https://github.com/ElasticPortalSuite/BungeeCord -// cause he is a badass. -public abstract class ConfigObject { - private final transient File file; - private transient Yaml yaml; - private transient Map config; - - protected ConfigObject(String path, String fileName) { - new File(path).mkdir(); - file = new File(path, fileName); - } - - public void initialize() { - DumperOptions options = new DumperOptions(); - options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); - yaml = new Yaml(options); - - try { - InputStream is = new FileInputStream(file); - config = yaml.load(is); - } catch (IOException ignored) { - } - - if (config == null) { - config = new LinkedHashMap<>(); - } - for (Field field : getClass().getDeclaredFields()) { - if (!Modifier.isTransient(field.getModifiers())) { - String name = field.getName(); - Object value = get(name); - setField(field, value); - } - } - } - - protected void setField(Field field, Object value) { - try { - field.set(this, value); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - } - - private Object get(String path) { - if (!config.containsKey(path)) { - save(); - } - return config.get(path); - } - - public void save() { - - for (Field field : getClass().getDeclaredFields()) { - if (!Modifier.isTransient(field.getModifiers())) { - String name = field.getName(); - try { - config.put(name, field.get(this)); - } catch (IllegalAccessException ignored) { - } - } - } - try { - FileWriter wr = new FileWriter(file); - yaml.dump(config, wr); - } catch (IOException ignored) { - } - } - -} diff --git a/src/main/java/net/shotbow/interestingfish/config/InterestingConfig.java b/src/main/java/net/shotbow/interestingfish/config/InterestingConfig.java deleted file mode 100644 index 473c60d..0000000 --- a/src/main/java/net/shotbow/interestingfish/config/InterestingConfig.java +++ /dev/null @@ -1,113 +0,0 @@ -package net.shotbow.interestingfish.config; - -import net.shotbow.interestingfish.InterestingFish; -import net.shotbow.interestingfish.objects.Breed; -import net.shotbow.interestingfish.objects.Descriptor; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -/** - * User: Austin - * Date: 5/18/13 - * Time: 1:10 AM - * (c) lazertester - */ -public class InterestingConfig extends ConfigObject { - - public double baseWeight = .5; - public double minWeight = .01; - public double percentDescriptorChance = 75.0; - public double percentBreedsChance = 100.0; - public boolean requireLuckEnchant = false; - public boolean excludeLuckEnchant = false; - public boolean showItemFrameInfo = true; - public String weightLabel = "Weight: "; - public String weightUnit = "lbs"; - public String caughtByLabel = "Caught by: "; - public boolean caughtByNickname = false; - public String dateLabel = ""; - public String dateFormat = "M/d/yy h:mm aa"; - public List> descriptorList = new ArrayList>() {{ - add(new HashMap() {{ - put("minWeightModifier", 5.0); - put("maxWeightModifier", 20.0); - put("rollWeight", 1); - put("text", "Big"); - }}); - add(new HashMap() {{ - put("minWeightModifier", -20.0); - put("maxWeightModifier", 0.0); - put("rollWeight", 1); - put("text", "Tiny"); - }}); - add(new HashMap() {{ - put("minWeightModifier", 1.0); - put("maxWeightModifier", 100.0); - put("rollWeight", 1); - put("text", "Kyori"); - }}); - add(new HashMap() {{ - put("minWeightModifier", 1.0); - put("maxWeightModifier", 100.0); - put("rollWeight", 1); - put("text", "Rainbow"); - }}); - add(new HashMap() {{ - put("minWeightModifier", 1.0); - put("maxWeightModifier", 100.0); - put("rollWeight", 1); - put("text", "Adventurous"); - }}); - }}; - public List> breedsList = new ArrayList>() {{ - add(new HashMap() {{ - put("minWeightModifier", 1.0); - put("maxWeightModifier", 20.0); - put("rollWeight", 1); - put("text", "Trout"); - }}); - add(new HashMap() {{ - put("minWeightModifier", 20.0); - put("maxWeightModifier", 50.0); - put("rollWeight", 1); - put("text", "Tuna"); - }}); - }}; - - public InterestingConfig(String path) { - super(path, "config.yml"); - } - - public void initialize() { - super.initialize(); - InterestingFish.log("Initialized with " + descriptorList.size() + " descriptors"); - } - - public Iterable getDescriptors() { - List descriptors = new ArrayList<>(); - for (HashMap map : descriptorList) { - Descriptor descriptor = new Descriptor(); - descriptor.setText((String) map.get("text")); - descriptor.setMinWeightModifier((Double) map.get("minWeightModifier")); - descriptor.setMaxWeightModifier((Double) map.get("maxWeightModifier")); - descriptor.setRollWeight((Integer) map.get("rollWeight")); - descriptors.add(descriptor); - } - return descriptors; - } - - public Iterable getBreeds() { - List breeds = new ArrayList<>(); - for (HashMap map : breedsList) { - Breed breed = new Breed(); - breed.setText((String) map.get("text")); - breed.setMinWeightModifier((Double) map.get("minWeightModifier")); - breed.setMaxWeightModifier((Double) map.get("maxWeightModifier")); - breed.setRollWeight((Integer) map.get("rollWeight")); - breeds.add(breed); - } - return breeds; - } -} diff --git a/src/main/java/net/shotbow/interestingfish/listeners/FishListener.java b/src/main/java/net/shotbow/interestingfish/listeners/FishListener.java deleted file mode 100644 index 92b3577..0000000 --- a/src/main/java/net/shotbow/interestingfish/listeners/FishListener.java +++ /dev/null @@ -1,61 +0,0 @@ -package net.shotbow.interestingfish.listeners; - -import net.shotbow.interestingfish.FishInfoFactory; -import net.shotbow.interestingfish.config.InterestingConfig; -import net.shotbow.interestingfish.objects.FishInfo; -import net.shotbow.interestingfish.utility.ItemUtility; -import org.bukkit.Tag; -import org.bukkit.entity.Item; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerFishEvent; -import org.bukkit.inventory.ItemStack; - -import java.text.DecimalFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.Random; - -/** - * User: Austin - * Date: 5/18/13 - * Time: 1:34 AM - * (c) lazertester - */ -public class FishListener implements Listener { - - private final SimpleDateFormat dateFormat; - private final DecimalFormat decimalFormat = new DecimalFormat("0.00"); - private final FishInfoFactory fishInfoFactory; - private final InterestingConfig config; - private final Random random = new Random(); - - public FishListener(FishInfoFactory fishInfoFactory, InterestingConfig config) { - this.fishInfoFactory = fishInfoFactory; - this.config = config; - dateFormat = new SimpleDateFormat(config.dateFormat); - } - - @EventHandler - public void onFish(PlayerFishEvent e) { - if (e.getCaught() instanceof Item && Tag.ITEMS_FISHES.isTagged(((Item) e.getCaught()).getItemStack().getType())) { - if (!e.getPlayer().hasPermission("interestingfish.catch")) - return; - if (config.requireLuckEnchant && !ItemUtility.fishingRodHasLuck(e.getPlayer().getInventory()) || - config.excludeLuckEnchant && ItemUtility.fishingRodHasLuck(e.getPlayer().getInventory())) - return; - if (random.nextInt(100) < config.percentBreedsChance) { - final String name = config.caughtByNickname ? e.getPlayer().getDisplayName() : e.getPlayer().getName(); - final FishInfo fishInfo = fishInfoFactory.makeNewFishInfo(); - final ItemStack fish = ((Item) e.getCaught()).getItemStack(); - ItemUtility.renameItem(fish, fishInfo.getName()); - ItemUtility.setLore(fish, new ArrayList() {{ - add(fishInfoFactory.parseColors(config.weightLabel + decimalFormat.format(fishInfo.getWeight()) + config.weightUnit)); - add(fishInfoFactory.parseColors(config.caughtByLabel + name)); - add(fishInfoFactory.parseColors(config.dateLabel + dateFormat.format(new Date()))); - }}); - } - } - } -} diff --git a/src/main/java/net/shotbow/interestingfish/listeners/InteractListener.java b/src/main/java/net/shotbow/interestingfish/listeners/InteractListener.java deleted file mode 100644 index a526700..0000000 --- a/src/main/java/net/shotbow/interestingfish/listeners/InteractListener.java +++ /dev/null @@ -1,46 +0,0 @@ -package net.shotbow.interestingfish.listeners; - -import net.shotbow.interestingfish.config.InterestingConfig; -import org.bukkit.Tag; -import org.bukkit.entity.ItemFrame; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerInteractEntityEvent; -import org.bukkit.inventory.ItemStack; - -/** - * User: Austin - * Date: 5/18/13 - * Time: 1:47 AM - * (c) lazertester - */ -public class InteractListener implements Listener { - - private final InterestingConfig config; - - public InteractListener(InterestingConfig config) { - this.config = config; - } - - @EventHandler - public void onFish(PlayerInteractEntityEvent e) { - if (config.showItemFrameInfo && e.getRightClicked() instanceof ItemFrame) { - final ItemStack item = ((ItemFrame) e.getRightClicked()).getItem(); - if (item != null && Tag.ITEMS_FISHES.isTagged(item.getType()) && !e.getPlayer().isSneaking()) { - e.setCancelled(true); - final Player player = e.getPlayer(); - if (item.hasItemMeta()) { - if (item.getItemMeta().hasDisplayName()) { - player.sendMessage(item.getItemMeta().getDisplayName()); - } - if (item.getItemMeta().hasLore()) { - for (String lore : item.getItemMeta().getLore()) { - player.sendMessage(lore); - } - } - } - } - } - } -} diff --git a/src/main/java/net/shotbow/interestingfish/objects/Breed.java b/src/main/java/net/shotbow/interestingfish/objects/Breed.java deleted file mode 100644 index 3cddf96..0000000 --- a/src/main/java/net/shotbow/interestingfish/objects/Breed.java +++ /dev/null @@ -1,51 +0,0 @@ -package net.shotbow.interestingfish.objects; - -import java.io.Serializable; - -/** - * User: Austin - * Date: 5/18/13 - * Time: 1:06 AM - * (c) lazertester - */ -public class Breed implements Serializable { - - private static final long serialVersionUID = 1; - - private String text; - private double minWeightModifier; - private double maxWeightModifier; - private int rollWeight; - - public String getText() { - return text; - } - - public void setText(String text) { - this.text = text; - } - - public double getMinWeightModifier() { - return minWeightModifier; - } - - public void setMinWeightModifier(double minWeightModifier) { - this.minWeightModifier = minWeightModifier; - } - - public double getMaxWeightModifier() { - return maxWeightModifier; - } - - public void setMaxWeightModifier(double maxWeightModifier) { - this.maxWeightModifier = maxWeightModifier; - } - - public int getRollWeight() { - return rollWeight; - } - - public void setRollWeight(int rollWeight) { - this.rollWeight = rollWeight; - } -} diff --git a/src/main/java/net/shotbow/interestingfish/objects/Descriptor.java b/src/main/java/net/shotbow/interestingfish/objects/Descriptor.java deleted file mode 100644 index a9a6c53..0000000 --- a/src/main/java/net/shotbow/interestingfish/objects/Descriptor.java +++ /dev/null @@ -1,51 +0,0 @@ -package net.shotbow.interestingfish.objects; - -import java.io.Serializable; - -/** - * User: Austin - * Date: 5/18/13 - * Time: 1:06 AM - * (c) lazertester - */ -public class Descriptor implements Serializable { - - private static final long serialVersionUID = 1; - - private String text; - private double minWeightModifier; - private double maxWeightModifier; - private int rollWeight; - - public String getText() { - return text; - } - - public void setText(String text) { - this.text = text; - } - - public double getMinWeightModifier() { - return minWeightModifier; - } - - public void setMinWeightModifier(double minWeightModifier) { - this.minWeightModifier = minWeightModifier; - } - - public double getMaxWeightModifier() { - return maxWeightModifier; - } - - public void setMaxWeightModifier(double maxWeightModifier) { - this.maxWeightModifier = maxWeightModifier; - } - - public int getRollWeight() { - return rollWeight; - } - - public void setRollWeight(int rollWeight) { - this.rollWeight = rollWeight; - } -} diff --git a/src/main/java/net/shotbow/interestingfish/objects/FishInfo.java b/src/main/java/net/shotbow/interestingfish/objects/FishInfo.java deleted file mode 100644 index 1ef7e6c..0000000 --- a/src/main/java/net/shotbow/interestingfish/objects/FishInfo.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.shotbow.interestingfish.objects; - -/** - * User: Austin - * Date: 5/18/13 - * Time: 1:27 AM - * (c) lazertester - */ -public class FishInfo { - private final String name; - private final double weight; - - public FishInfo(String name, double weight) { - this.name = name; - this.weight = weight; - } - - public String getName() { - return name; - } - - public double getWeight() { - return weight; - } -} diff --git a/src/main/java/net/shotbow/interestingfish/utility/ItemUtility.java b/src/main/java/net/shotbow/interestingfish/utility/ItemUtility.java deleted file mode 100644 index 34f1ee2..0000000 --- a/src/main/java/net/shotbow/interestingfish/utility/ItemUtility.java +++ /dev/null @@ -1,44 +0,0 @@ -package net.shotbow.interestingfish.utility; - -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.List; - -/** - * User: Austin - * Date: 2/22/13 - * Time: 9:44 PM - * (c) lazertester - */ -public class ItemUtility { - - public static void renameItem(ItemStack item, String newName) { - final ItemMeta itemMeta = item.getItemMeta(); - itemMeta.setDisplayName(ChatColor.RESET + newName); - item.setItemMeta(itemMeta); - } - - public static void setLore(ItemStack item, List lore) { - ItemMeta meta = item.getItemMeta(); - meta.setLore(lore); - item.setItemMeta(meta); - } - - public static boolean fishingRodHasLuck(PlayerInventory inventory) { - ItemStack item = inventory.getItemInMainHand(); - if (item.getType() != Material.FISHING_ROD) { - item = inventory.getItemInOffHand(); - } - if (item.getType() == Material.FISHING_ROD) { - if (item.hasItemMeta()) { - return item.getItemMeta().hasEnchant(Enchantment.LUCK); - } - } - return false; - } -} diff --git a/src/main/kotlin/net/shotbow/interestingfish/FishInfoFactory.kt b/src/main/kotlin/net/shotbow/interestingfish/FishInfoFactory.kt new file mode 100644 index 0000000..f3e92ad --- /dev/null +++ b/src/main/kotlin/net/shotbow/interestingfish/FishInfoFactory.kt @@ -0,0 +1,42 @@ +package net.shotbow.interestingfish + +import net.kyori.adventure.text.minimessage.MiniMessage +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer +import net.shotbow.interestingfish.config.InterestingConfig +import net.shotbow.interestingfish.models.Breed +import net.shotbow.interestingfish.models.Descriptor +import net.shotbow.interestingfish.models.FishInfo +import net.shotbow.interestingfish.models.FishModifier +import org.bukkit.ChatColor +import kotlin.random.Random + +class FishInfoFactory(private val config: InterestingConfig) { + private val weightedDescriptors: Array = config.descriptorList.toWeightedArray() + private val weightedBreeds: Array = config.breedsList.toWeightedArray() + + fun makeNewFishInfo(): FishInfo { + val breed = weightedBreeds.random() + var weight = config.baseWeight + breed.weight + var name = breed.text.withColors() + + if (Random.nextInt(100) < config.percentDescriptorChance) { + val descriptor = weightedDescriptors.random() + + name = "${descriptor.text.withColors()}${ChatColor.RESET} $name" + weight += descriptor.weight + } + + return FishInfo(name, weight.coerceAtLeast(config.minWeight)) + } + + companion object { + private val legacyHexSerializer = + LegacyComponentSerializer.builder().hexColors().useUnusualXRepeatedCharacterHexFormat().build() + + fun String.withColors() = + legacyHexSerializer.serialize(MiniMessage.miniMessage().deserialize(replace('&', ChatColor.COLOR_CHAR))) + + fun Iterable.toWeightedArray() = + flatMap { modifier -> Array(modifier.rollWeight) { modifier }.toList() }.toTypedArray() + } +} diff --git a/src/main/kotlin/net/shotbow/interestingfish/InterestingFish.kt b/src/main/kotlin/net/shotbow/interestingfish/InterestingFish.kt new file mode 100644 index 0000000..bc6cd1a --- /dev/null +++ b/src/main/kotlin/net/shotbow/interestingfish/InterestingFish.kt @@ -0,0 +1,31 @@ +package net.shotbow.interestingfish + +import com.uchuhimo.konf.Config +import com.uchuhimo.konf.source.yaml +import com.uchuhimo.konf.toValue +import net.shotbow.interestingfish.config.InterestingConfig +import net.shotbow.interestingfish.listeners.FishListener +import net.shotbow.interestingfish.listeners.InteractListener +import org.bukkit.Bukkit +import org.bukkit.plugin.java.JavaPlugin +import java.io.File + +class InterestingFish : JavaPlugin() { + override fun onEnable() { + saveDefaultConfig() // make sure we have at least a default config file + + val config = Config().from.yaml.file(File(dataFolder, "config.yml")).toValue() + log(config.toString()) + val fishInfoFactory = FishInfoFactory(config) + + Bukkit.getPluginManager().registerEvents(FishListener(fishInfoFactory, config), this) + Bukkit.getPluginManager().registerEvents(InteractListener(config), this) + log("InterestingFish is enabled!") + } + + companion object { + fun log(message: String) { + Bukkit.getLogger().info("[InterestingFish] $message") + } + } +} diff --git a/src/main/kotlin/net/shotbow/interestingfish/config/InterestingConfig.kt b/src/main/kotlin/net/shotbow/interestingfish/config/InterestingConfig.kt new file mode 100644 index 0000000..55681b5 --- /dev/null +++ b/src/main/kotlin/net/shotbow/interestingfish/config/InterestingConfig.kt @@ -0,0 +1,66 @@ +package net.shotbow.interestingfish.config + +import net.shotbow.interestingfish.models.Breed +import net.shotbow.interestingfish.models.Descriptor + +data class InterestingConfig( + val baseWeight: Double = .5, + val minWeight: Double = .01, + val percentDescriptorChance: Double = 75.0, + val percentBreedsChance: Double = 100.0, + val requireLuckEnchant: Boolean = false, + val excludeLuckEnchant: Boolean = false, + val showItemFrameInfo: Boolean = true, + val weightLabel: String = "Weight: ", + val weightUnit: String = "lbs", + val caughtByLabel: String = "Caught by: ", + val caughtByNickname: Boolean = false, + val dateLabel: String = "", + val dateFormat: String = "M/d/yy h:mm aa", + val descriptorList: List = listOf( + Descriptor( + text = "Big", + minWeightModifier = 5.0, + maxWeightModifier = 20.0, + rollWeight = 1 + ), + Descriptor( + text = "Tiny", + minWeightModifier = -20.0, + maxWeightModifier = 0.0, + rollWeight = 1 + ), + Descriptor( + text = "Kyori", + minWeightModifier = 1.0, + maxWeightModifier = 100.0, + rollWeight = 1 + ), + Descriptor( + text = "Rainbow", + minWeightModifier = 1.0, + maxWeightModifier = 100.0, + rollWeight = 1 + ), + Descriptor( + text = "Adventurous", + minWeightModifier = 1.0, + maxWeightModifier = 100.0, + rollWeight = 1 + ), + ), + val breedsList: List = listOf( + Breed( + text = "Trout", + minWeightModifier = 1.0, + maxWeightModifier = 20.0, + rollWeight = 1 + ), + Breed( + text = "Tuna", + minWeightModifier = 20.0, + maxWeightModifier = 50.0, + rollWeight = 1 + ) + ) +) diff --git a/src/main/kotlin/net/shotbow/interestingfish/listeners/FishListener.kt b/src/main/kotlin/net/shotbow/interestingfish/listeners/FishListener.kt new file mode 100644 index 0000000..6d55c20 --- /dev/null +++ b/src/main/kotlin/net/shotbow/interestingfish/listeners/FishListener.kt @@ -0,0 +1,54 @@ +package net.shotbow.interestingfish.listeners + +import net.shotbow.interestingfish.FishInfoFactory +import net.shotbow.interestingfish.FishInfoFactory.Companion.withColors +import net.shotbow.interestingfish.config.InterestingConfig +import net.shotbow.interestingfish.util.ItemUtility +import net.shotbow.interestingfish.util.ItemUtility.isFish +import net.shotbow.interestingfish.util.ItemUtility.meta +import org.bukkit.entity.Item +import org.bukkit.event.EventHandler +import org.bukkit.event.Listener +import org.bukkit.event.player.PlayerFishEvent +import java.text.DecimalFormat +import java.text.SimpleDateFormat +import java.time.OffsetDateTime +import java.util.Random + +class FishListener( + private val fishInfoFactory: FishInfoFactory, + private val config: InterestingConfig +) : Listener { + private val dateFormat: SimpleDateFormat = SimpleDateFormat(config.dateFormat) + private val decimalFormat = DecimalFormat("0.00") + private val random = Random() + + @EventHandler + fun onFish(e: PlayerFishEvent) { + val caught = e.caught + if (caught is Item && caught.itemStack.isFish()) { + if ( + !e.player.hasPermission("interestingfish.catch") || + config.requireLuckEnchant && !ItemUtility.fishingRodHasLuck(e.player.inventory) || + config.excludeLuckEnchant && ItemUtility.fishingRodHasLuck(e.player.inventory) + ) { + return + } + + if (random.nextInt(100) < config.percentBreedsChance) { + val name = if (config.caughtByNickname) e.player.displayName else e.player.name + val (name1, weight) = fishInfoFactory.makeNewFishInfo() + val fish = caught.itemStack + + fish.meta { + setDisplayName(name1) + lore = listOf( + (config.weightLabel + decimalFormat.format(weight) + config.weightUnit).withColors(), + (config.caughtByLabel + name).withColors(), + (config.dateLabel + dateFormat.format(OffsetDateTime.now())).withColors() + ) + } + } + } + } +} diff --git a/src/main/kotlin/net/shotbow/interestingfish/listeners/InteractListener.kt b/src/main/kotlin/net/shotbow/interestingfish/listeners/InteractListener.kt new file mode 100644 index 0000000..ce51061 --- /dev/null +++ b/src/main/kotlin/net/shotbow/interestingfish/listeners/InteractListener.kt @@ -0,0 +1,34 @@ +package net.shotbow.interestingfish.listeners + +import net.shotbow.interestingfish.config.InterestingConfig +import net.shotbow.interestingfish.util.ItemUtility.isFish +import org.bukkit.entity.ItemFrame +import org.bukkit.event.EventHandler +import org.bukkit.event.Listener +import org.bukkit.event.player.PlayerInteractEntityEvent + +class InteractListener(private val config: InterestingConfig) : Listener { + @EventHandler + fun onFish(e: PlayerInteractEntityEvent) { + val rightClicked = e.rightClicked + + if (config.showItemFrameInfo && rightClicked is ItemFrame) { + val item = rightClicked.item + if (item.isFish() && !e.player.isSneaking) { + e.isCancelled = true + + if (item.hasItemMeta()) { + val itemMeta = item.itemMeta!! + if (itemMeta.hasDisplayName()) { + e.player.sendMessage(itemMeta.displayName) + } + if (itemMeta.hasLore()) { + for (lore in itemMeta.lore!!) { + e.player.sendMessage(lore) + } + } + } + } + } + } +} diff --git a/src/main/kotlin/net/shotbow/interestingfish/models/FishInfo.kt b/src/main/kotlin/net/shotbow/interestingfish/models/FishInfo.kt new file mode 100644 index 0000000..277da3a --- /dev/null +++ b/src/main/kotlin/net/shotbow/interestingfish/models/FishInfo.kt @@ -0,0 +1,3 @@ +package net.shotbow.interestingfish.models + +data class FishInfo(val name: String, val weight: Double) diff --git a/src/main/kotlin/net/shotbow/interestingfish/models/FishModifier.kt b/src/main/kotlin/net/shotbow/interestingfish/models/FishModifier.kt new file mode 100644 index 0000000..bd2efc3 --- /dev/null +++ b/src/main/kotlin/net/shotbow/interestingfish/models/FishModifier.kt @@ -0,0 +1,22 @@ +package net.shotbow.interestingfish.models + +import java.io.Serializable +import kotlin.random.Random + +typealias Breed = FishModifier +typealias Descriptor = FishModifier + +data class FishModifier( + val text: String, + val minWeightModifier: Double, + val maxWeightModifier: Double, + val rollWeight: Int +) : Serializable { + + val weight: Double + get() = minWeightModifier + Random.nextDouble() * maxWeightModifier - minWeightModifier + + companion object { + private const val serialVersionUID: Long = 1 + } +} diff --git a/src/main/kotlin/net/shotbow/interestingfish/util/ItemUtility.kt b/src/main/kotlin/net/shotbow/interestingfish/util/ItemUtility.kt new file mode 100644 index 0000000..f5cd419 --- /dev/null +++ b/src/main/kotlin/net/shotbow/interestingfish/util/ItemUtility.kt @@ -0,0 +1,23 @@ +package net.shotbow.interestingfish.util + +import org.bukkit.Material +import org.bukkit.Tag +import org.bukkit.enchantments.Enchantment +import org.bukkit.inventory.ItemStack +import org.bukkit.inventory.PlayerInventory +import org.bukkit.inventory.meta.ItemMeta + +object ItemUtility { + fun ItemStack.meta(updates: ItemMeta.() -> Unit) { + itemMeta = itemMeta!!.also(updates) + } + + fun ItemStack.isFish() = Tag.ITEMS_FISHES.isTagged(type) + + fun fishingRodHasLuck(inventory: PlayerInventory): Boolean = + inventory.itemInEitherHand(Material.FISHING_ROD) + ?.let { it.hasItemMeta() && it.itemMeta!!.hasEnchant(Enchantment.LUCK) } ?: false + + private fun PlayerInventory.itemInEitherHand(material: Material) = + itemInMainHand.takeIf { it.type == material } ?: itemInOffHand.takeIf { it.type == material } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..048ea9f --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,43 @@ +baseWeight: 0.5 +minWeight: 0.01 +percentDescriptorChance: 75.0 +percentBreedsChance: 100.0 +requireLuckEnchant: false +excludeLuckEnchant: false +showItemFrameInfo: true +weightLabel: 'Weight: ' +weightUnit: lbs +caughtByLabel: 'Caught by: ' +caughtByNickname: false +dateLabel: +dateFormat: M/d/yy h:mm aa +descriptorList: +- minWeightModifier: 5.0 + maxWeightModifier: 20.0 + rollWeight: 1 + text: Big +- minWeightModifier: -20.0 + maxWeightModifier: 0.0 + rollWeight: 1 + text: Tiny +- minWeightModifier: 1.0 + maxWeightModifier: 100.0 + rollWeight: 1 + text: Kyori +- minWeightModifier: 1.0 + maxWeightModifier: 100.0 + rollWeight: 1 + text: Rainbow +- minWeightModifier: 1.0 + maxWeightModifier: 100.0 + rollWeight: 1 + text: Adventurous +breedsList: +- minWeightModifier: 1.0 + maxWeightModifier: 20.0 + rollWeight: 1 + text: Trout +- minWeightModifier: 20.0 + maxWeightModifier: 50.0 + rollWeight: 1 + text: Tuna diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 6ee9f95..09303a5 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,10 +1,14 @@ name: "${name}" main: "${group}.interestingfish.${name}" version: "${version}" -api-version: "1.13" +api-version: "1.17" authors: ["lazertester", "Puremin0rez"] website: "https://github.com/Puremin0rez/InterestingFish" -description: "Allow your players to catch fish with style - adds fancy names, weights and catch information to caught fish. " +description: "Allow your players to catch fish with style - adds fancy names, weights and catch information to caught fish." +libraries: + - com.uchuhimo:konf:1.1.2 + - org.jetbrains.kotlin:kotlin-reflect:1.5.21 + - org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.21 permissions: interestingfish.catch: description: Controls a players ability to catch a fish and have it be interesting.